Vim 向后删除连续空格或连续非空格直到行首

Vim 向后删除连续空格或连续非空格直到行首,vim,vim-plugin,Vim,Vim Plugin,Vim经常创建包含大量连续空格的行,所以我很惊讶在前一个单词结束之前没有一种简单的方法可以向后删除。我错过了什么明显的东西吗 hello this is a line | 请返回此处: hello this is a line| hello this is a | 或光标前有非空白: hello this is a line| 请返回此处: hello this is a line| hello this is a | 这样我就可以在插入模式下映射一个键,然后返回删除单词

Vim经常创建包含大量连续空格的行,所以我很惊讶在前一个单词结束之前没有一种简单的方法可以向后删除。我错过了什么明显的东西吗

hello this is a line       |
请返回此处:

hello this is a line|
hello this is a |
或光标前有非空白:

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>'

而不是

this is a |
如果您想编写更复杂一点的vimscript,您当然可以解决这个问题,但如果只占用一个空间,这几乎不值得

操作员挂起的映射所移动的内容也会根据
'selection'
的值发生微妙的变化,如果这让您感到困扰的话

编辑:这就是我如何创建所需的精确解决方案的方法 这不会自行删除,而是与任何vim命令组合,例如
d
y
c
运算符,只要传递正确的参数,它就可以在所有模式下工作。要复制askers答案中使用的映射,请执行以下操作:

inoremap <silent> <c-b> <c-o>d:<c-u>call <SID>Backup(1)<cr>
inoremap d:呼叫备份(1)
以下是
e

nnoremap e:呼叫备份(0)
onoremap e:呼叫备份(1)
xnoremap e:呼叫备份(2)
注意:映射必须与要使用
s:
的函数在同一脚本中定义,否则将其删除

编辑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>

对于第一种情况,您可以在正常模式下使用
dTe
。对于第二种情况,请在正常模式下尝试
db
,或在插入模式下尝试
Ctrl-W
dTe
在光标左侧有空格时对我没有任何作用。光标不移动。
dTe
应向后删除光标中的所有字符(包括空格),直到字母
e
。帮助页面是
:help T
。哦,对不起,对了。我正在寻找一个可以不经思考地重复的命令,所以不管前一个单词中的字符是什么。因此,我在一个随机字符串上测试,在我的例子中没有e,这就是为什么它没有做任何事情。我希望能够重复击键,直到它到达行的开头。“Vim经常创建带有大量连续空格的行”什么?这不是你所说的我想要的,但感谢你的努力。实际上,我只是发布了一个我需要的答案。@RiazRizvi没问题,这些答案大部分来自我的vimrc。如果你感兴趣的话,我会编辑来展示我如何实现完整的解决方案,它的优点是可以与任何vim命令一起使用。它比我的答案更优雅,所以如果它有效的话,我会给你。但是我不知道如何使用它,当我使用inoremap映射复制.vimrc中的函数时,我在尝试调用它时遇到了一个错误:
未知函数2\u Backup
。顺便说一句,我在这上面花了太多的时间,所以我将在几个小时内结束它。糟糕,我键入的函数名错误,它应该以
s:
作为前缀(现已修复)。映射上的
s:
对于它的工作来说是不必要的,您可以删除
,而不是添加
s:
,它会工作的,它们只提供了一个封装。请参见
:h
:hs:
Hmm,此函数吃光标前面的单词,因此在我的答案示例的第二行,它吃光标前面的k。我会接受我的答案,不过还是要感谢你的努力。
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>
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>
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)