Vim 经常创建具有大量连续空格的行,所以我很惊讶没有一种简单的方法可以向后删除,直到上一个单词的末尾。我错过了一些明显的东西吗?
hello this is a line |
删除回此处:
hello this is a line|
或光标前的非空格:
hello this is a line|
删除回此处:
hello this is a |
这样我就可以在插入模式下映射键,然后返回删除单词或非单词。
虽然 vim 没有附带这样的命令,但它附带的命令非常接近您想要的命令:ge
和gE
,请在帮助中查找它们。幸运的是,这意味着将它们包装在以下正常、可视和运算符挂起的映射中是微不足道的:
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 命令(例如d
、y
、c
运算符(组成,只要您传递正确的参数,就可以在所有模式下工作。要复制提问者答案中使用的映射,请执行以下操作:
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)