我有一个小映射AltUp,AltDown可以将文本上下移动一行。我决定应该使这些映射成为“折叠感知”,以便将文本向上移动一行会将其移过一个封闭的折叠。但是当我玩弄这些映射时,vim 会破坏我的折叠。
映射:
映射通过调用:move
函数来工作。to 的参数:move
是绝对行号,文本应移动到该行号之下。
nnoremap <A-Down> :call MoveDown_n()<CR>
nnoremap <A-Up> :call MoveUp_n()<CR>
function! MoveUp_n() range
let pos = getpos(".")
normal k
let line_pos = line(".") - 1
call setpos(".", pos)
execute "m".line_pos
endfunction
function! MoveDown_n() range
let pos = getpos(".")
normal jj
let line_pos = line(".") - 1
call setpos(".", pos)
execute "m".line_pos
endfunction
测试文件:
vim: foldmethod=marker
fold A {{{
some
text
here
}}}
fold B {{{
some
text
here
}}}
fold C {{{
some
text
here
}}}
fold D {{{
some
text
here
}}}
问题:
当我加载测试文件(所有折叠都关闭)并将光标放在其中一个折叠上时,首先AltUp和AltDown键似乎像预期的那样移动折叠。但是,如果您继续将折叠彼此移动得足够多,那么:
- 没有明显原因,折叠开始变得未展开(“损坏”)。
- 你不能关闭这些折叠,因为 vim 无法检测到那里有折叠。
- 保存并重新编辑文件 (
:e
) 似乎可以修复折叠问题。
有时它会在第一个乐章中发生,有时则不会。我什至有过测试用例,其中折叠边界会被错误地检测到,而不是根本没有被检测到。例如,Vim 认为的折叠从中间行开始text
。
--- 编辑 ---
更多测试:
移动折叠 A 似乎会导致大部分问题。如果你不碰折叠 A,我认为你可以移动折叠 B、C 和 D 而不会遇到问题。
如果将折叠 A 向上移动两次(见注 1),它将破坏折叠 B、C 和 D。如果将折叠 A 向下移动一次(见注 2),它将破坏折叠 B。
(注 1)将光标放在折叠 A(第 5 行)上,然后执行:move3
,:move2
或执行:move-2
,然后kj
,然后:move-2
。
(注2)将光标放在折叠A(第5行)然后做:move14
我注意到的是,在任何:move
操作之后,光标都会放在折叠的最后一行的第一列。但是:move-2
,即使在执行第二个命令之前将光标重置到折叠 A 的第一行,在折叠 A 上执行两次命令也会损坏折叠 B、C 和:move-2
D。
如果重要:在 Windows 上使用 gvim 7.3