删除向后连续的空格或连续的非空格直到行的开头

时间:2018-05-19 20:23:32

标签: vim vim-plugin

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

hello this is a line       |

删除回到这里:

hello this is a line|

或非空格位于光标之前:

hello this is a line|

删除回到这里:

hello this is a |

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

2 个答案:

答案 0 :(得分:0)

虽然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).'c\S' ? 'b' : 'gel'
  let str .= !at_end && a:mode == 1 ? 'oho' : ''

  execute 'normal!' str
endfunction

这不会自行删除,但会与任何vim命令合并,例如dyc运算符,并且只能在所有模式下工作你传递了正确的参数。要复制在askers中使用的映射,请回答:

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>

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

编辑2:修正了功能名称:/
编辑3:调整为在不在行尾时修复操作。显然vim认为光标在插入行末时附加在不同的位置。

答案 1 :(得分:0)

好的,这个功能可以满足我的需求:

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)