我编写了这个脚本,用一个空格替换了光标周围的许多空格。但是当我在光标周围没有空格的情况下使用它时,这不起作用。在我看来,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>
以下是一些示例(管道|
是游标):
这一行
hello | world
变为
hello |world
但这一行
hello wo|rld
不会成为
hello wo |rld
更新:通过将功能更改为以下内容,它适用于上述示例。
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
这一行
hello |world
变为
hello w|orld
问题是游标移动到下一个角色。它应该留在同一个地方。
任何指针和/或提示?
答案 0 :(得分:4)
我认为你的脚本唯一的问题是位置保存似乎不正确。你基本上可以做你想做的事情:
: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)
我已经更改了上面的脚本以考虑您的注释,使得光标位置仅通过光标位置之前的空格数来调整。这是通过创建第二个正则表达式来完成的,该表达式从行中提取光标之前的空格(而不是其他任何内容),然后通过空格数调整光标位置。
答案 1 :(得分:3)
我不使用vim,但如果你想匹配零个或多个空格,你不应该使用' *'
而不是' \+'
吗?
编辑:重新定位光标定位问题:你现在正在做的是在进行替换之前在空白的开头设置位置,然后将其向前移动一个位置,使其在空格之后。请尝试在匹配的 end 中进行设置,如下所示:
search(' *', 'bce')
这样,在光标位置之前会发生任何添加或删除。在大多数编辑器中,光标位置会自动移动以跟踪此类更改。你不应该做任何getpos / setpos的东西。
答案 2 :(得分:0)
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*'
let pos = match(current_line, matchre) + 2
" 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] = pos
" Set the line in the window
call setline(".", modified_line)
" Reset the cursor position
call setpos(".", cursor_position)
endfunction
使用正常线和修改线之间的差异,我找到第一个空格的位置,该位置将与替换的正则表达式匹配。然后我将光标位置设置为该位置+ 1。
答案 3 :(得分:0)
我使用的这个简单的几乎相同:
nnoremap <leader>6 d/\S<CR>
将光标放在要删除空格的位置,并删除光标和下一个文本后的所有空格。