【发布时间】:2013-05-11 15:42:23
【问题描述】:
我有一个 AltUp 和 AltDown 的小映射,可以将文本上下移动一行.我决定这些映射应该是“折叠感知”的,以便将文本向上移动一行会将其移动超过一个封闭的折叠。但是当我玩弄这些映射时,vim 会破坏我的折叠。
映射:
映射通过调用:move 函数来工作。 :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 和 Alt 向下 键似乎可以像预期的那样移动折叠。但是,如果您继续将褶皱彼此移动得足够多,那么:
- 折叠开始变得未展开(“损坏”),原因不明。
- 您无法关闭这些折叠,因为 vim 无法检测到那里有折叠。
- 保存并重新编辑文件 (
:e) 似乎可以修复折叠问题。
有时它会在第一个乐章中发生,有时则不会。我什至有过测试用例,其中折叠边界会被错误地检测到,而不是根本没有被检测到。例如,Vim 认为的折叠以中间行 text 开头。
--- 编辑 ---
更多测试:
移动折叠 A 似乎会导致大多数问题。如果你不碰折叠 A,我认为你可以移动折叠 B、C 和 D 而不会遇到问题。
如果你将折叠 A 向上移动两次(见注 1),它将破坏折叠 B、C 和 D。如果你将折叠 A 向下移动一次(见注 2),它将破坏折叠 B。
(note-1) 将光标放在折叠 A(第 5 行)上,然后执行 :move3、:move2 或执行 :move-2,然后执行 kj,然后执行 :move-2。
(注 2)将光标放在折叠 A(第 5 行)然后执行 :move14
我注意到,在任何:move 操作之后,光标都会放在折叠的最后一行的第一列。但是在折叠 A 上执行两次命令 :move-2 会损坏折叠 B、C 和 D,即使您在执行第二个 :move-2 命令之前将光标重置到折叠 A 的第一行也是如此。
如果重要:在 Windows 上使用 gvim 7.3
【问题讨论】:
-
我不确定您的脚本要做什么。
m只移动一行,但您试图同时移动多行(所有折叠都应该移动,而不仅仅是“当前”行) -
当光标位于闭合折叠处时,对于大多数命令,vim 将对折叠的所有行进行操作。
-
@Ein 我玩了一下这个。对我来说看起来像一个 Vim 错误。我建议尽可能删除您的示例并在vim_dev mailing list 上提交错误报告。