vim-fold-cycle icon indicating copy to clipboard operation
vim-fold-cycle copied to clipboard

Add option to enhance recursive `zC` to all nested folds

Open kiryph opened this issue 8 years ago • 9 comments

Vim's default behaviour for zC and zA when closing is that it only closes folds under the cursorline which is always only one line. This is identical to zc and za. Only when using visual selection the recursive nature of zC can be used.

IMHO I would expect a different behavior more similar to your plugin except that zC means always closing of the fold of the current cursor and all folds contained in this fold. zA should follow this pattern when closing except it inverts the current fold and all nested folds.

I suspect this should be quite close what your plugin does and could easily be added.

A similar discussion about my intention can be found here: http://vim.1045645.n5.nabble.com/Folding-recursively-levels-td4848210.html

Update For consistency one could also change zO and as a second option also change visual mode behaviour

Vim help would look like without visual mode description:

...
							*zO*
zO		Open all folds under the cursor recursively.  Folds that are
                contained in the fold of the cursor line are also changed.
...
							*zC*
zC		Close all folds under the cursor recursively.  Folds that are
                contained in the fold of the cursor line are also changed.
...
							*zA*
zA		Toggle the fold status of the fold under the cursor and
                all folds contained in this fold.
...

kiryph avatar Mar 21 '17 13:03 kiryph

I've added some <Plug> mappings, that I think do what your asking for. Here's what you can put in your vimrc to try them out.

    nmap zO <Plug>(fold-cycle-open-all)
    nmap zC <Plug>(fold-cycle-close-all)
    nmap zA <Plug>(fold-cycle-toggle-all)

Let me know how these work out for you. I'm the least confident in the behavior of the zA mapping out of the 3.

arecarn avatar Apr 12 '17 04:04 arecarn

Thank you very much. zO and zC work as expected.

I am also not confident about zA in general.

Does your implementation try to toggle all contained folds (my current expectation)?

Consider this file:

A (open) {{{1
   B1 (open) {{{2
     in B1
   B2 (closed) {{{2
     in B2
# vim: fdm=marker

Close B2 with zc and then move the cursor on A. Pressing zA should close B1 and A but open B2, right? However, opening A again with zo shows that all nested folds are closed.

kiryph avatar Apr 12 '17 09:04 kiryph

There is another issue: FastFold and these mappings remap zA, zC and zO. According to https://github.com/Konfekt/FastFold/issues/14 FastFold does not support custom fold mappings and this has to be done by oneself which they claim is not straightforward.

Do you have further insight how one could achieve this?

kiryph avatar Apr 12 '17 09:04 kiryph

Thanks for the idea for zC and zO, they are a great addition to this plugin.

Unfortunately my heart isn't in it to try to implement this behavior for zA, or make the plugin play nice with FastFold. I just don't see either being straight forward, or useful enough to motivate me, to work on them.

arecarn avatar Apr 14 '17 04:04 arecarn

I understand. However, I am already quite happy with zC and zO (excited if it would work together with FastFold :smiley: ). Thanks again.

Doc

Do you like to add some documentation (doc/fold-cycle.txt, README.md) about <Plug>(fold-cycle-[open,close,toggle]-all)?

I add here examples where the supercharged versions work differently compared to the builtin ones.

Demo file

A {{{1
  in A
  B1 {{{2
    in B1
  B2 {{{2
    in B2
# vim: fdm=marker

zC Initial configuration all folds open (A, B1, B2) and cursor on line 1.

  1. Built-in Behavior Pressing zC closes ONLY fold A which is the same as zc. Note, if you would close the top fold with zc, you can fold all with VzC.

  2. Supercharged Behavior Pressing zC closes ALL folds A, B1, B2.

zO Initial configuration fold A is open but B1 and B2 are closed. Again cursor on line 1.

  1. Built-in Behavior Pressing zO does nothing. Note, if you would again close the top fold with zc, you can open ALL nested folds with zO.

  2. Supercharged Behavior Pressing zO opens ALL folds A, B1, B2.

zA

zA can be used if you do not want to use zC and zO but a single command to decide based on the current fold whether you want to open or close recursively all folds.

But you still need other commands to open folds individually to profit from several fold levels.

Originally, I used the spacebar to toggle folds:

nnoremap <silent> <Space> @=(foldlevel('.')?'za':"\<Space>")<CR>

from http://vim.wikia.com/wiki/Folding

However, I now use the spacebar as my leaderkey and use mostly the following default fold commands:

  • zo/zc to open/close a single fold (formerly I used here the spacebar),
  • zO/zC to open/close folds recursively; now with your plugin!
  • zR/zM to open/close all folds in the file.

I rarely feel the need for changing the level in the file with zr/zm.

If I would still have my old configuration, I could imagine following extended spacebar behavior:

  1. spacebar toggle current single fold
  2. ctrl-spacebar toggle current folds recursively (your zA)
  3. ctrl-shift-spacebar toggle all folds of the file.

But I now made the mental shift to use two kinds of commands open and close and stick to the vim way.

I think your plugin with the cyclic recursive behavior and the suggested mappings <CR> and <Backspace> are really good but as I said I managed to get used to the vim way.

kiryph avatar Apr 16 '17 09:04 kiryph

@arecarn May I ask you for an extension of the behavior of zC (<Plug>(fold-cycle-close-all))?

A {{{1
   B1 {{{2
     in B1
   B2 {{{2
     in B2
     C1 {{{3
       in C1
     C2 {{{3
       CURSOR in C2
       D1 {{{4
         in D1
       D2 {{{4
         in D2
         E1 {{{5
           in E1
         E2 {{{5
           in E2

# vim: fdm=marker

I press zC and it closes C2, D1, D2, E1, E2:

A {{{1
   B1 {{{2
     in B1
   B2 {{{2
     in B2
     C1 {{{3
       in C1
+---- 12 lines: C2 --------------------------------------------------------------------------

Now, I can use zc to close each parent fold individually. But as you might expect, I would like to change the behaviour of zC whether it is on an open or closed fold. So when I am in the situation that the current fold is closed, I would like to fold all parent folds (B2 and A) to get:

+-- 19 lines: A -----------------------------------------------------------------------------

kiryph avatar Apr 16 '17 15:04 kiryph

Following does what I want

nnoremap <silent><expr> zC foldclosed('.')==-1?
			\ ':<C-u>call fold_cycle#close_all()<CR>':
			\ 'zC'

kiryph avatar Apr 16 '17 16:04 kiryph

BTW I think for zO following is just fine:

nnoremap zO zvzczO

Update My (hopefully final) mappings for zC and zO look like

nnoremap <silent><expr> zO foldclosed('.')==-1?
			\ 'zczO':
			\ 'zv'
nnoremap <silent><expr> zC foldclosed('.')==-1?
			\ ':<C-u>call fold_cycle#close_all()<CR>':
			\ 'zC'

(both have a two-step behavior)

kiryph avatar Apr 16 '17 17:04 kiryph

I'll reopen this a reminder to take a look at this.

arecarn avatar Apr 18 '17 17:04 arecarn