删除行首之前的向后连续空格或连续非空格



Vim 经常创建具有大量连续空格的行,所以我很惊讶没有一种简单的方法可以向后删除,直到上一个单词的末尾。我错过了一些明显的东西吗?

hello this is a line       |

删除回此处:

hello this is a line|

或光标前的非空格:

hello this is a line|

删除回此处:

hello this is a |

这样我就可以在插入模式下映射键,然后返回删除单词或非单词。

虽然 vim 没有附带这样的命令,但它附带的命令非常接近您想要的命令:gegE,请在帮助中查找它们。幸运的是,这意味着将它们包装在以下正常、可视和运算符挂起的映射中是微不足道的:

noremap <expr> <leader>e 'h'.v:count1.'gel'
noremap <expr> <leader>E 'h'.v:count1.'gEl'
onoremap <expr> <silent> <leader>e ':<c-u>normal! vh'.v:count1.'gel<cr>'
onoremap <expr> <silent> <leader>E ':<c-u>normal! vh'.v:count1.'gEl<cr>'

显然,将它们映射到您想要的任何东西,我个人将第一个映射到<BS>.e和E的区别在于它们分别调用ge(移动word(和gE(移动WORD(。有关含义的详细信息,请参阅:h word:h WORD

这些并不是您所要求的:当我们开始时,它们不会根据我们所处的位置进行调整,因此例如,使用此运算符删除将更改

this is a line|

this is a|

而不是

this is a |

如果你想写一个更复杂的vimscript,你当然可以解决这个问题,但如果一个空间,这几乎不值得。

操作员等待地图移动的内容也会根据'selection'的值而微妙地改变,如果这困扰您。

编辑:这就是我将如何创建所要求的确切解决方案

function! s:Backup(mode)
let str  = a:mode == 2 ? 'g' : ''
let str .= a:mode ? 'v' : ''
let at_end = col('.') >= col('$') - 1
let str .= getline('.') =~ '%'.(col('.') - !at_end).'cS' ? 'b' : 'gel'
let str .= !at_end && a:mode == 1 ? 'oho' : ''
execute 'normal!' str
endfunction

它不会自行删除,而是与任何 vim 命令(例如dyc运算符(组成,只要您传递正确的参数,就可以在所有模式下工作。要复制提问者答案中使用的映射,请执行以下操作:

inoremap <silent> <c-b> <c-o>d:<c-u>call <SID>Backup(1)<cr>

以下是<leader>e上正常、可视、操作员挂起模式的绑定

nnoremap <silent> <leader>e :<c-u>call <SID>Backup(0)<cr>
onoremap <silent> <leader>e :<c-u>call <SID>Backup(1)<cr>
xnoremap <silent> <leader>e :<c-u>call <SID>Backup(2)<cr>

注意:映射必须在与函数相同的脚本中定义,以使用s:<SID>,否则删除它们。

编辑 2:修复了函数名称:/
编辑 3:调整为修复不在行尾的操作。显然,vim 认为光标在行尾追加时与插入时位于不同位置。

好的,这个函数可以满足我的需要:

function! BackspaceContiguousInsertMode()
python << EOF
import vim  
try:
line = vim.current.line
row, deleteto = vim.current.window.cursor
if deleteto==0:
vim.current.line = ""
vim.command("startinsert")
elif line[deleteto] == " ":
deletefrom=deleteto
while deletefrom-1>0 and vim.current.line[deletefrom-1] == " ":
deletefrom=deletefrom-1
vim.current.line=line[:deletefrom] + line[deleteto+1:]
if len(line)-1 == deleteto:
vim.current.window.cursor = (row,deletefrom+1)
vim.command("startinsert!")
else:
vim.current.window.cursor = (row,deletefrom)
vim.command("startinsert")
else:
eol=deleteto+1 >= len(line)
if not eol and line[deleteto+1] != " ":
trailingline = line[deleteto+1:]
vim.current.line=line[:deleteto+1] + " " + trailingline
vim.command("normal diw")
leadingto=len(vim.current.line)-len(trailingline)-1
vim.current.line=vim.current.line[:leadingto] + trailingline
vim.command("startinsert")
elif eol:    
vim.command("normal diw")
vim.command("startinsert!")
else: 
vim.command("normal diw")
vim.command("startinsert")
except Exception as e:
print("Error: {}".format(e))
EOF
endfunction
inoremap <C-b> <Esc>:call BackspaceContiguousInsertMode()<CR>

在插入模式(我想从中调用它(中,我可以按<C-b>将每个单词块或空格块删除到行首。给定以下行,每次我按<C-b>时都会发生这种情况:

alskdjf       a;sjdf a kjkdjd        |kja sdf
alskdjf       a;sjdf a kjkdjd|kja sdf
alskdjf       a;sjdf a |kja sdf
alskdjf       a;sjdf a|kja sdf
alskdjf       a;sjdf |kja sdf
alskdjf       a;sjdf|kja sdf
alskdjf       a;|kja sdf
alskdjf       a|kja sdf
alskdjf       |kja sdf
alskdjf|kja sdf
|kja sdf
|... (stays on the same line)

最新更新