6

现在我正在使用 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. 点击TabShift+Tab足够的时间回到我的初始状态。但是如果有很多相似的词,尤其是长度不同的词,那就很烦人了。
  2. 不管需要多少次都按退格键,或者其他一些天真的删除。但这些肯定是不必要的击键。
  3. 点击Esc+u进行撤消,但这会撤消我的整个单词(如果我快速输入,则会撤消更多)。这是完全不能接受的。之后,我需要重新进入插入模式并重新输入。总的。
  4. 点击Ctrl+U撤消而不离开插入模式。但这也有去除太多的趋势。
  5. 点击Ctrl+W删除最后一个单词。虽然我可以在不退出插入模式的情况下执行此操作,但我仍然需要重新输入。这是迄今为止我发现的最好的。

如果我没有longest启用,那么我可以使用Ctrl+ E,它会退出菜单而不插入任何其他内容。但由于最长是打开的,它会停止自动完成,但会留下最长的常见匹配项。

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

4

3 回答 3

2

There are 2 native ways to do this in vim. If you know right way that the item is not in the completion menu you can use <c-y>. <c-y> accepts the current match which if you didn't move though any completions will send you back to only the text you inserted. (Second way) However if you did move through the completion menu you can move though until you get back to the original text.

However I imagine it isn't too hard to simply accept the longest matching and edit the word. You could also use <c-g>u to break up the undo block by working it into your <tab> mapping. Although that may break the history up more than you want.

于 2013-08-01T15:57:46.267 回答
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>
...
于 2013-08-01T06:59:44.540 回答
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>"
于 2018-04-26T00:24:24.337 回答