1

I have some text that is folded, and I would like to operate on the entire fold (e.g. with y), agnostic of what kind of fold it is and how it is defined.

Is there some general function to obtain the start and end of the current fold under the cursor?

For example, suppose I am editing an XML file with g:xml_syntax_folding = 1 set:

<outerElem>
  <innerElem id=1>
    <thing>Hello</thing>
  </innerElem>
  <innerElem id=2>
    <thing>here is</thing>
  </innerElem>
  <innerElem id=3>
    <thing>some stuff.</thing>
  </innerElem>
</outerElem>

The standard syntax folding will create one fold for the outerElem and one fold for each of the innerElems. This is what my editor would look like (with an representing the cursor) if I open the outerElem fold, but leave the innerElem folds closed:

<outerElem>
+--- 3 lines: <innerElem id=1>
+--- 3 lines: <innerElem id=2>
␣--- 3 lines: <innerElem id=3>
</outerElem>

I would like an operator (or functions I can use to write an operator) that corresponds to "the entire innerElem fold", so that I can delete/yank it, reindent it, etc. using all the usual Vim commands that accept operators.

I am aware of [z and ]z, but this requires the fold to be open already, which I do not want to have to do.

I use Neovim, so I am also open to a Neovim-only solution.

I do not want a solution that only works on XML, or on any specific kind of fold. I am only looking for a general solution that can operate on any fold, defined using any valid fold method.

Update: For now, I am going to just work with the z[, z], zj, and zk commands. I will also take a look at the auto-origami source code to see if it's possible to make a "current fold" text object :)

2
  • 1
    How close do zj and zk get to what you want?
    – B Layer
    Commented Jan 14, 2021 at 17:49
  • @BLayer I forgot about those. I can try to hack something together with them. Commented Jan 15, 2021 at 4:17

1 Answer 1

1

Two options:

  1. If the fold is closed, it works like a single line. That means all the line-wise stuff you already know works just fine (dd, yy, ==, etc.).
  2. For XML specificallyI know, you said you don't want this, but someone else might, and using the tools at hand is a good thing., you can use the it and at text-objects (:help tag-objects). So, dat, yat, =at, etc.

For folds generically, it turns out to be kind of tricky. The vim fold API consists of just these functions at time of writing

foldclosed({lnum})      Number  first line of fold at {lnum} if closed
foldclosedend({lnum})       Number  last line of fold at {lnum} if closed
foldlevel({lnum})       Number  fold level at {lnum}
foldtext()          String  line displayed for closed fold
foldtextresult({lnum})      String  text for closed fold at {lnum}

plus a few normal-mode and Ex commands (:help folds).

Even my auto-origami plugin had to do a lot of work to detect if there is a fold.

1
  • 1
    Thanks for the insight, that's too bad. It might be easiest in my case to just close the fold and then use linewise operations. But maybe there is also some generic/common functionality in auto-origami that can be useful here. Commented Jan 15, 2021 at 4:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.