【问题标题】:How to efficiently undo an autocomplete in vim如何有效地撤消vim中的自动完成
【发布时间】:2013-08-01 22:44:48
【问题描述】:

现在我正在使用 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,它会退出菜单而不插入任何其他内容。但由于最长已开启,它会停止自动完成,但会留下最长的常见匹配项。

肯定有更好的方法来做到这一点。

【问题讨论】:

    标签: vim autocomplete vim-plugin


    【解决方案1】:

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

    但是我想简单地接受最长的匹配并编辑单词并不难。您还可以使用<c-g>u 将撤消块分解为您的<tab> 映射。尽管这可能会比您想要的更多地破坏历史。

    【讨论】:

    • 谢谢。我没有尝试。但我承认,我很困惑。阅读文档,我根本不将“当前匹配”解释为最初插入的、最长的文本。特别是当 似乎表明它应该是撤消完成的那个。我是不是读错了文档?
    • 我理解您为什么对 <c-e> 感到困惑,但是您需要进一步阅读:结束完成,回到选择匹配之前的内容(输入的内容或最长的公共字符串) .
    【解决方案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>
    ...
    

    【讨论】:

      【解决方案3】:

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

      &lt;C-n&gt; 自动完成是我使用的。您可能需要将其更改为 &lt;Tab&gt; 视情况而定。)

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

      【讨论】:

        猜你喜欢
        • 2023-03-30
        • 1970-01-01
        • 2010-12-06
        • 1970-01-01
        • 2012-11-19
        • 2016-07-22
        • 2015-03-09
        • 2011-07-22
        • 2011-10-22
        相关资源
        最近更新 更多