VIM / Python插入模式完成弹出菜单

时间:2014-04-14 04:48:07

标签: python vim vim-plugin

我想创建一个VIM插入模式完成弹出菜单,最好直接通过python vim模块,但如果需要也可以通过调用vim命令。根据我的要求,如果可行,我需要知道什么?

要求

  • 根据输入修改菜单。重新着色和替换选择字符ala easymotion插件,或者完全替换内容,可能会导致尺寸发生变化。
  • 可自定义的导航绑定,例如:
    • j / k用于垂直导航(部分重绘
    • h / l用于类别导航/细化(完全重绘
    • 其他人作为类别/关系快捷方式(完整
    • 其他人作为源循环(完整
    • easymotion风格的绑定(部分
    • 其他相关功能( none
    • 可选地,代替上述绑定,模糊过滤模式(捕获所有输入)(完整
  • 在菜单销毁时挂钩以执行操作
  • 如果选择了菜单项,则可以替换上一个单词(在正常模式下轻松完成......但是,有没有比调用更好的方法:norm?)

再一次,我需要知道这是否可行。如果是,请提供有关所需功能,API或功能的特定文档。好吧,足以让我开始。

如果重要的话,我还不确定接口细节,但菜单本身可能需要非常大才能容纳内容。

编辑:

我没有尝试任何东西;相反,我问我应该阅读或知​​道什么来实现我需要的vim特定功能。我现在所拥有的只是python代码,它接受句子和句子中的一个单词,确定POS,对单词进行lemmatises,并提供同义词。

现在应该很清楚,这是一个vim插件,提供类似于词典的功能,增强了vim的内置CTRL_X-CTRL_T功能。不幸的是,synonymy是一个复杂的层次结构,例如,请参阅thesaurus.comwordnet。以下是同义词选择过程的树。为了提供有用的同义词库功能,我需要在insert-mode-completion弹出菜单中导航这个树。通过自动推断POS,可以跳过第一步,当然,无论关系如何,最初合并和显示所有有义同义词都是有意义的。但是,要确定POS我需要访问整个句子,我仍然需要能够导航感觉选择菜单。我还希望能够为当前突出显示的弹出菜单条目提供临时缓冲区详细说明单词定义和示例句子。因此需要钩子;在销毁菜单时销毁缓冲区。我所描述的所有其他键绑定都是方便的,例如,按关系过滤,打开信息暂存缓冲区或切换POS。

POS  Sense      Relationship      Synonym
N -> Sense 1 -> Relationship 1 -> Synonym 1
                                  Synonym 2
                                  ...
                                  Synonym n
             -> Relationship 2 -> Synonym 1
                                  ...
                                  Synonym n
             -> Relationship 3 -> Synonym 1
                                  ...
                                  Synonym n
     Sense 2 -> Relationship 1 -> ...
     Sense 3 -> Relationship 2 -> ...
V -> Sense 1 -> ...
A -> ...

插入完成弹出菜单非常棒,因为它们保留了上下文:周围文本不会更改,保持(大部分)可见,并且窗口不会调整大小。我可以在一个单独的缓冲区(例如unite插件)中提供我需要的功能,但我宁愿不这样做。

阅读:h complete-functions后:

如果refresh="alway",则每次更改前导文字时都会重新调用complete-functions。目的是优化匹配,但这对同义词匹配没有什么意义,其中单词已经完成,而只是被替换。除此之外,插入完成弹出菜单仅提供最小的键映射:<CTRL-H>CTRL-L><CTRL-Y><CTRL-E>等。可以使用{{1}添加其他映射但是,这样的映射会影响所有弹出菜单,因此不适用。当然,我可以使用pumvisible()来检查全局变量,例如<expr>,但这种方法基本上是一堆黑客。例如,要在菜单中显示新类别,我可以执行以下操作:

g:popup-menu-is-thesaurus

使用:

:call Thesaurus#BindKey("h","w:Thesaurus#CategoryUp")
:call Thesaurus#BindKey("i","w:Thesaurus#InsertMode")

* 显然我对VimL不太满意。另外,我正确使用function! Thesaurus#BindKey(key, function) inoremap <expr> a:key a:function endfunction function! Thesaurus#CategoryUp() if !b:popup-menu-is-thesaurus return v:char let b:thesaurus-category-index -= 1 endfunction function! Thesaurus#InsertMode() if !b:popup-menu-is-thesaurus return v:char let b:thesaurus-mode = "insert" endfunction function! Thesaurus#CompleteFunc(findstart, base) if a:findstart ... else if b:thesaurus-mode = "insert" return Thesaurus#FuzzyMatch(base) else return Thesaurus#Redraw() endif endif endfunction function! Thesaurus#Redraw() ... endfunction 吗?

当然,我不知道如果选择一个条目后如何替换上一个单词,因为启用模糊匹配的唯一方法是让v:char为空。

Edit2:我是如何通过标准的同义词库式完成快捷方式a:base触发完成功能的?我不想丢失我的自定义完成(omni和用户定义的完成),并且由于弹出窗口显示在当前缓冲区中,与i_CTRL-X_CTRL-T不同,我无法覆盖omnifunc。

也许理想的方法是完全控制菜单绘制功能,从头开始构建弹出窗口,并使用诸如tinymode,tinykeymap或submode等插件伪造一个新的插入完成弹出菜单模式。

1 个答案:

答案 0 :(得分:2)

请注意,插入模式完成弹出菜单适用于完成匹配,例如键入foobar并触发完成时提供foomaticfoo没有包含任意操作的通用插入模式菜单,实现此类操作可能是一个坏主意。也就是说,一些插件(例如 FuzzyFinder )错误 - 使用动态选择选择器的插入模式完成菜单(在暂存缓冲区中,因此在那里丢弃完成的内容)。

您将在:help complete-function找到完整的规范和示例。如果这不能让您满意/留下未解决的问题,那么这肯定表明您正在尝试将其用于不适合的事情。

  

根据输入修改菜单。

使用每个键入的键,您的'completefunc'将被重新调用,并且它可以提供(减少的)一组匹配。

  

可自定义的导航装订

糟糕的主意。用户应为所有完成次数(使用带有:imap <expr>条件的pumvisible())自定义此内容。

  

在销毁菜单时挂钩以执行操作

CompleteDone事件已添加到最近的Vim版本中,但通常唯一的操作应该是&#34;插入匹配&#34;,这将自动完成。

  

如果选择了菜单项,则可以替换上一个单词

在第一次调用'completefunc'时,您的函数可以指定基本列,即完成匹配的位置将开始。