Folding while in insert mode?

16 views
Skip to first unread message

Benjamin R. Haskell

unread,
Feb 3, 2010, 10:12:46 AM2/3/10
to Vim
I use foldmethod=syntax, but I'm finding it distracting to see the folds
changing while editing files.

e.g., with this code already in the buffer:

sub foo {
if (1) {
if (1) {
#blah
}
}
}

Starting up, I'll see:

+-- 7 lines: sub foo {-------

But, as I insert the following before that line:

sub blah {
if (1) {
#blah
}
}

The 'sub foo' section gets folded and unfolded to various levels (as the
syntax becomes invalid/different at different points).

Does anyone have a nice way to "freeze" the folds to their initial
values while in insert mode?

--
Best,
Ben

Ben Fritz

unread,
Feb 4, 2010, 10:41:03 AM2/4/10
to vim_use

On Feb 3, 9:12 am, "Benjamin R. Haskell" <v...@benizi.com> wrote:
>
> Does anyone have a nice way to "freeze" the folds to their initial
> values while in insert mode?
>

I also find that the constantly changing folds beneath the insertion
point is annoying, especially if I have spent time carefully closing
folds below the cursor.

I have not found a decent workaround in general, though I did get
around it for opening/closing C-style comments, by mapping /* to first
insert the closing comment, then back up and insert the beginning.
This won't work for braces though, because the } will close the
current code block.

I'm thinking it may be possible to map { to insert the opening and
closing brace in one fell swoop using the expression register, but I
haven't tried it yet.

The best solution would probably be a change to the Vim source to put
off updating folds while in insert mode, especially for fdm=syntax,
but it can also be annoying for fdm=marker and probably others.

Matt Wozniski

unread,
Feb 4, 2010, 5:04:52 PM2/4/10
to vim...@googlegroups.com

Couldn't you do something like this:

au InsertEnter * let b:oldfdm = &l:fdm | setlocal fdm=manual
au InsertLeave * let &l:fdm = b:oldfdm

As far as I can see, that should get around the problem... But maybe
I'm missing something?

~Matt

Ben Fritz

unread,
Feb 4, 2010, 6:16:52 PM2/4/10
to vim_use

On Feb 4, 4:04 pm, Matt Wozniski <m...@drexel.edu> wrote:
>
> Couldn't you do something like this:
>
>     au InsertEnter * let b:oldfdm = &l:fdm | setlocal fdm=manual
>     au InsertLeave * let &l:fdm = b:oldfdm
>
> As far as I can see, that should get around the problem...  But maybe
> I'm missing something?
>

If you have manually opened/closed folds, setting the foldmethod will
re-apply the fold level. Or maybe it will set the foldlevel to zero,
I'm not sure. Regardless, your carefully configured folds are messed
up.

Matt Wozniski

unread,
Feb 4, 2010, 6:47:24 PM2/4/10
to vim...@googlegroups.com

It seems to work fine in my testing. Can you give me an example of a
place where it fails?

Benjamin R. Haskell

unread,
Feb 4, 2010, 10:54:06 PM2/4/10
to vim...@googlegroups.com

It also seems to work fine in my testing. Thanks a bundle.

I thought I recalled the behavior Ben F mentioned (auto-re-closing folds
when changing foldmethod), but I couldn't replicate it with my current
settings. I also suspected it might have something to do with using
&l:fdm instead of &fdm, but even switching to global foldmethod=syntax
(as opposed to Perl/PHP-buffer-specific local fdm's) didn't make a
difference.

--
Thanks,
Ben (H)

Ben Fritz

unread,
Feb 4, 2010, 11:28:49 PM2/4/10
to vim_use

On Feb 4, 5:47 pm, Matt Wozniski <m...@drexel.edu> wrote:
>
> It seems to work fine in my testing.  Can you give me an example of a
> place where it fails?

Hmm, I had thought I tried this before, but I see that on 7.2.348 it
works fine.

However, with the latest 7.2.356 patch, it does not work.

gvim -N -u NONE -i NONE
:set rtp-=~/vimfiles
:set rtp-=~/vimfiles/after
:filetype plugin indent on
:syntax on
:e test.c
:set fdm=syntax
:au InsertEnter * let b:oldfdm = &l:fdm | setlocal fdm=manual


:au InsertLeave * let &l:fdm = b:oldfdm

Now I go into a code block, open the fold, enter insert mode, type
some text, exit insert mode, and the fold closes up again.

Before I installed the new version, I was able to manually set the
foldmethod back and forth without affecting the fold level, I was
unable to do this with the latest version, and the autocmd method is
as above.

Ben Fritz

unread,
Feb 5, 2010, 2:35:06 PM2/5/10
to vim_use

On Feb 4, 9:41 am, Ben Fritz <fritzophre...@gmail.com> wrote:
>
> I'm thinking it may be possible to map { to insert the opening and
> closing brace in one fell swoop using the expression register, but I
> haven't tried it yet.
>

I already had some bracket-matching code already in my .vimrc, based
off:

http://vim.wikia.com/wiki/Automatically_append_closing_characters

I've modified it to also protect the folds below the insertion point.
Not very pretty, but here it is:

" autocomplete '{}' groups
---------------------------------------------
" this will usually take effect, you must press '{{' to prevent it
inoremap <silent> { x<Esc>"="{}"<CR>Pl"_s<Left>
inoremap <silent> {<CR> <ESC>"="{\n}"<CR>p=aBo
inoremap <silent> {<SPACE>
x<Esc>"="{<SPACE><SPACE>}"<CR>Pl"_s<Left><Left>
inoremap <silent> {} x<Esc>"="{}"<CR>Pl"_s
inoremap <silent> {{ {
if v:version >= 700
inoremap <expr> } strpart(getline('.'), col('.')-1, 1) == "}" ?
"\<Right>" : "}"
else
inoremap <silent> } <C-R>=strpart(getline('.'), col('.')-1, 1) ==
"}" ? "\<lt>Right>" : "}"<CR>
endif

And similar for () and [] pairs.

Works around the issue for me, anyway. Can anyone get Matt's suggested
solution working in 7.2.356 instead? It's quite a bit more elegant.

Bram Moolenaar

unread,
Feb 5, 2010, 3:29:15 PM2/5/10
to Ben Fritz, vim_use

Ben Fritz wrote:

> On Feb 4, 5:47=A0pm, Matt Wozniski <m...@drexel.edu> wrote:
> >
> > It seems to work fine in my testing. =A0Can you give me an example of a


> > place where it fails?
>
> Hmm, I had thought I tried this before, but I see that on 7.2.348 it
> works fine.
>
> However, with the latest 7.2.356 patch, it does not work.
>
> gvim -N -u NONE -i NONE
> :set rtp-=~/vimfiles
> :set rtp-=~/vimfiles/after
> :filetype plugin indent on
> :syntax on
> :e test.c
> :set fdm=syntax
> :au InsertEnter * let b:oldfdm = &l:fdm | setlocal fdm=manual
> :au InsertLeave * let &l:fdm = b:oldfdm
>
> Now I go into a code block, open the fold, enter insert mode, type
> some text, exit insert mode, and the fold closes up again.
>
> Before I installed the new version, I was able to manually set the
> foldmethod back and forth without affecting the fold level, I was
> unable to do this with the latest version, and the autocmd method is
> as above.

Lech Lorens already mentioned that this patch might reset more info than
actually needed. But it may be very difficult to only reset those folds
that differ from what was already there. It probably require a new flag
"reset level when this fold changes".

--
Some of the well know MS-Windows errors:
ESLEEP Operator fell asleep
ENOERR No error yet
EDOLLAR OS too expensive
EWINDOWS MS-Windows loaded, system in danger

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Reply all
Reply to author
Forward
0 new messages