如何在vim中有效撤消自动完成

时间:2013-08-01 06:36:24

标签: vim autocomplete vim-plugin

现在我在vim中玩自动填充功能,我已经确定supertab来处理我的完成情况。虽然它的运行非常顺利(我认为)正如它的设计一样,但我想知道如何改变它。

首先,我使用

在Ubuntu 12.04LTS上运行7.3.429
set completeopt=menuone,preview,longest

这样我就可以使用supertab进行bash类型的自动完成,并且默认完成。

假设我的文件中有以下内容:

aaabbbcccddd
aaabbccddeef
aaabbcddeeff

如果我输入aa并点击 Tab ,那么vim意识到aaabb是匹配中最长的常用字符串,因此它会插入aaabb并显示包含三个选项的菜单。如果我确实想要其中一个选项,那么一切都很好。但也许我真的想要aaaaazzzzz,但没有意识到我还没有输入它。

有没有一个好方法可以对vim说,“哦,我很抱歉!毕竟我不是故意要完成!请假装我没有。”

现在,我明白的选择是:

  1. Tab Shift + Tab 足够的时间回到我的初始状态。但如果有很多类似的词,特别是不同的长度,这很烦人。
  2. 无论多少次必要,或者其他一些天真的删除,请按退格键。但这些肯定是不必要的关键。
  3. 点击 Esc + u 进行撤消,但这会撤消我的全部信息(如果我快速输入,则会更多)。这是完全不可接受的。然后,我需要重新进入插入模式并重新输入。毛。
  4. Ctrl + U 进行撤消,无需离开插入模式。但这也有消除过多的倾向。
  5. Ctrl + W 删除最后一个单词。虽然我在不退出插入模式的情况下执行此操作,但仍需要重新键入。这是迄今为止我发现的最好的。
  6. 如果我没有启用longest,那么我可以使用 Ctrl + E ,退出菜单而不插入任何其他内容。但是,由于最长时间打开,它会停止自动完成,但会输入最长的常用匹配。

    当然必须有更好的方法来做到这一点。

3 个答案:

答案 0 :(得分:2)

这很难,但我遇到了同样的问题,并实施了一些东西。缺点是我不得不重载任何(内置和自定义)完成触发器以首先调用自定义函数,该函数将标记设置为完成的开始。然后我在插入模式下映射<Esc>(弹出菜单可见)以删除该标记之前的文本。

function! s:SetUndo()
    call setpos("'\"", getpos('.'))
    return ''
endfunction
inoremap <expr> <SID>(CompleteStart) <SID>SetUndo()
function! s:UndoLongest()
        " After a completion, the line must be the same and the column must be
        " larger than before.
        if line("'\"") == line('.') && col("'\"") < col('.')
            return "\<C-\>\<C-o>dg`\""
        endif
    endif
    return ''
endfunction
imap <expr> <Esc>      pumvisible() ? <SID>UndoLongest() : '<Esc>'

inoremap <script> <C-x><C-n> <SID>(CompleteStart)<C-x><C-n>
inoremap <script> <C-x><C-p> <SID>(CompleteStart)<C-x><C-p>
...

答案 1 :(得分:2)

在vim中有两种本地方法可以做到这一点。如果您知道项目不在完成菜单中的正确方式,则可以使用<c-y><c-y>接受当前匹配,如果您没有移动,则任何完成将仅返回您插入的文本。 (第二种方式)但是,如果您确实在完成菜单中移动,则可以移动直至返回原始文本。

但是我想,简单地接受最长的匹配并编辑单词并不难。您还可以使用<c-g>u将撤消块拆分为<tab>映射。虽然这可能比你想要的更容易打破历史。

答案 2 :(得分:0)

知道它已经有一段时间了,但这就是我设法完成它的方法。

<C-n>自动完成是我使用的。您可能需要根据具体情况将其更改为<Tab>。)

" When the auto-complete menu is not visible, make C-n start a new undo sequence
" See - https://vi.stackexchange.com/a/2377
inoremap <expr> <C-n> pumvisible() ? "<C-n>" : "<C-g>u<C-n>"

" Overload Esc to just do an undo when auto-complete menu is visible
inoremap <expr> <Esc> pumvisible() ? "<C-o>u" : "<Esc>"