我编写了这个脚本,用一个空格替换了光标周围的许多空格.但是当我在光标周围没有空格的情况下使用它时,这不起作用.在我看来,Vim并没有取代零宽度匹配.
function JustOneSpace() let save_cursor = getpos(".") let pos = searchpos(' \+','bc') s/\s*\%#\s*/ /e let save_cursor[2] = pos[1] + 1 call setpos('.',save_cursor) endfunction nmap <space> :call JustOneSpace()<cr>
以下是一些示例(pipe | is cursor):
这条线
hello | world
变
hello |world
但这一行
hello wo|rld
没有成为
hello wo |rld
function JustOneSpace() let save_cursor = getpos(".") let pos = searchpos(' *',save_cursor) endfunction
这条线
hello |world
变
hello w|orld
问题是游标移动到下一个角色.它应该留在同一个地方.
任何指针和/或提示?
解决方法
我认为你的脚本唯一的问题是位置保存看起来不正确.你基本上可以做你想做的事情:
:s/\s*\%#\s*/ /e
这与您问题中的(正确)代码相同.您可以简单地将其映射为:
:nmap <space> :s/\s*\%#\s*/ /e<CR>
如果你想保存位置,它会变得有点复杂.可能最好的选择是使用这样的东西:
function! JustOneSpace() " Get the current contents of the current line let current_line = getline(".") " Get the current cursor position let cursor_position = getpos(".") " Generate a match using the column number of the current cursor position let matchRE = '\(\s*\)\%' . cursor_position[2] . 'c\s*' " Find the number of spaces that precede the cursor let isolate_preceding_spacesRE = '^.\{-}' . matchRE . '.*$' let preceding_spaces = substitute(current_line,isolate_preceding_spacesRE,'\1',"") " Modify the line by replacing with one space let modified_line = substitute(current_line,matchRE," ","") " Modify the cursor position to handle the change in string length let cursor_position[2] -= len(preceding_spaces) - 1 " Set the line in the window call setline(".",modified_line) " Reset the cursor position call setpos(".",cursor_position) endfunction
其中大部分是注释,但关键是你要查看替换前后行的长度,并相应地决定新的光标位置.如果您愿意,可以通过比较len(getline(“.”))之前和之后的方法来完成此操作.
编辑
如果希望光标在空格字符后面结束,请修改该行:
let cursor_position[2] -= len(current_line) - len(modified_line)
它看起来像这样:
let cursor_position[2] -= (len(current_line) - len(modified_line)) - 1
编辑(2)
我已经更改了上面的脚本来考虑你的注释,使得光标位置仅通过光标位置之前的空格数来调整.这是通过创建第二个正则表达式来完成的,该表达式从行中提取光标之前的空格(以及其他任何内容),然后通过空格数调整光标位置.