1

Setting foldlevel when folding is active displays all folds up to that level and closes the rest.* I would like to do something similar for only part of the file, perhaps all material below the current fold or all material in a range.

Consider this file:

Tippy Top
    chapter
        section
            subsection
    chapter 2
        section 2.1
            sub 2.1.1

where the leading white space is tabs and :setlocal foldmethod=indent is in effect.

I would like to go to Tippy Top and do something like :expandToLevel 1 and see only the 2 chapter headings.

I can use zC to close everything, but zo simply restores the previous view, with lower level headings like subsection expanded if they were expanded earlier.

I've tried using :foldclose, repetition counts, highlighting a visual region, za, foldnestmax, but none achieve the behavior I want.

So far, to get expansion to a certain level only, I use one of 2 methods:

  1. Use :set foldlevel to get what I want in my current area, thereby wiping out whatever custom folds I've done elsewhere.
  2. Manually close the folds I want closed, e.g., zc on chapter and chapter 2.

The first loses what I've done in the rest of the document and the second is slow and tedious when there are more then a few entries.

I notice that the C function foldUpdateIEMS() and related functions take a range of lines. I'm not sure what the function does, but something like that doesn't seem to be exposed to vim scripts.

Apr 25 update: got vim running in a debugger and put a breakpoint on foldUpdateIEMS(). It fired when loading the file, but not when I :set foldlevel=2. So it does not seem to be directly involved in opening and closing folds. It does seem to define the folds.

My interest in these functions comes from vimoutliner, which uses foldmethod=expr. But I simplified to a plain text file with tab indentation to focus on the essential issues.

*As a side issue, when I set foldlevel=1 with the test file above I only see chapter, not chapter 2. I don't know why.

Ross Boylan
  • 21
  • 1
  • 5
  • Your simplification actually diverts from the essential issue, which is that `vimoutliner` uses `foldmethod=expr` precisely because it is the method that puts you in control and lets you decide what is folded or not and when. – romainl Apr 23 '22 at 06:27
  • @romainl The essential issue is the one I stated: how to control folding in part of the document. The fact that `vimoutliner` defines folds with something more elaborate than tabs (and mostly it uses tabs) is a detail. Particularly given that the authors of vimoutliner, not me, are the ones in control of that expression, and that even were I in control I see no obvious way to make it respond to the selective folding mentioned above. – Ross Boylan Apr 23 '22 at 08:10
  • No, it's not a detail. Here is your answer, again, but spelled differently: write the code that folds things the way you want, assign it to `foldexpr`, and `set foldmethod=expr`. You can't obtain the result you want with the other folding methods. – romainl Apr 23 '22 at 09:24
  • Well, "You can't obtain the result you want with the other folding methods" actually is an answer to my original question, if not the answer I was hoping for. But I have no idea how one would write a foldexpr that would achieve the results I want. At a basic level, I thought foldexpr is to identify folds, not to decide whether they should be open or closed. Care to elaborate? – Ross Boylan Apr 26 '22 at 04:00
  • `:help fold-expr` is code you write that dynamically determines the `foldlevel` of a line. If something in Vim can give you the level of control over folds you are after, it must be it. – romainl Apr 26 '22 at 06:24

1 Answers1

0

I would like to go to Tippy Top and do something like :expandToLevel 1 and see only the 2 chapter headings.

:set foldlevel=1

does just that:

fold

or you could do 2zm (you may need :set folminlines=0). I don't like to count so I would simply do something like zM to close everything, and then zr to open one level.

romainl
  • 186,200
  • 21
  • 280
  • 313
  • `:set foldlevel`, `zm`, and `zr` operate globally. I want something like that, but only operating on part of the document. My example doesn't have any other parts and so one can get away with global manipulations, but I'm looking for a more focused alternative. – Ross Boylan Apr 23 '22 at 08:00
  • If your example doesn't accurately reflects your actual need, then you should consider updating it so that it does. – romainl Apr 23 '22 at 09:47