【发布时间】:2014-04-14 04:48:06
【问题描述】:
我想创建一个 VIM 插入模式完成弹出菜单,最好是直接通过 python vim 模块,也可以在必要时调用 vim 命令。根据我的要求,如果可以的话,我需要知道什么?
要求
- 根据输入修改菜单。使用 easymotion 插件重新着色和替换选定字符,或者完全替换内容,这可能会导致大小发生变化。
- 可自定义的导航绑定,例如:
- j/k 用于垂直导航(部分重绘)
- h/l 用于类别导航/细化(完全重绘)
- 其他作为类别/关系快捷方式(完整)
- 其他作为源循环 (full)
- easymotion 样式绑定(部分)
- 其他相关功能(无)
- 可选地,代替上述绑定,模糊过滤模式(捕获所有输入)(完整)
- 在菜单被销毁时运行操作的挂钩
- 如果选择了菜单项,则能够替换前一个单词(在正常模式下很容易完成......但是,有没有比调用 :norm 更好的方法?)
再一次,我需要知道这是否可行。如果是这样,请提供有关所需功能、API 或函数的特定文档。好吧,足以让我开始。
如果重要的话,我还不确定界面细节,但菜单本身可能需要很大才能容纳内容。
编辑:
我什么都没试过;相反,我问的是我应该阅读或知道什么来实现我需要的特定于 vim 的功能。我现在只有 python 代码,它接受一个句子和那个句子中的一个词,确定 POS,词形还原,并提供同义词。
现在应该清楚了,这是一个 vim 插件,提供了类似词库的功能,增强了 vim 的内置 CTRL_X-CTRL_T 功能。不幸的是,同义词是一个复杂的层次结构,例如参见thesaurus.com 或wordnet。下面是同义词选择过程的树。为了提供有用的词库功能,我需要在插入模式完成弹出菜单中导航此树。通过自动推断词性,可以跳过第一步,当然,最初合并并显示所有意义同义词而不考虑关系是有意义的。但是,要确定 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 -> ...
插入完成弹出菜单非常棒,因为它们保留了上下文:周围的文本不会改变,保持(大部分)可见,并且不会调整窗口大小。我可以在一个单独的缓冲区中提供我需要的功能(例如一个联合插件),但是我宁愿不这样做。
看完:h complete-functions:
如果refresh="alway",complete-functions 将在每次更改前导文本时重新调用。目的是优化匹配,但是这对于同义词匹配没有什么意义,其中单词已经完成,而是将被替换。除此之外,插入完成弹出菜单仅提供最少的键映射:<CTRL-H>、CTRL-L>、<CTRL-Y>、<CTRL-E> 等。可以使用 pumvisible() 添加其他映射,但是此类映射会影响所有弹出菜单,因此不适用。当然我可以使用<expr> 来检查诸如g:popup-menu-is-thesaurus 之类的全局变量,但是这种方法基本上是一堆黑客。例如,要在菜单中显示一个新类别,我可以这样做:
:call Thesaurus#BindKey("h","w:Thesaurus#CategoryUp")
:call Thesaurus#BindKey("i","w:Thesaurus#InsertMode")
与:
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
* 很明显我对 VimL 不是很好。另外,我使用v:char 正确吗?
当然,我不知道如何在选择条目后替换前一个单词,因为启用模糊匹配的唯一方法是让 a:base 为空。
Edit2: 我到底是如何触发我的完成功能的,最好是通过标准词库风格的完成快捷方式i_CTRL-X_CTRL-T?我不想丢失我的自定义完成(omni 和用户定义的完成),并且由于弹出窗口显示在当前缓冲区中,与 FuzzyFinder 不同,我无法覆盖omnifunc。
也许理想的方法是完全控制菜单绘制功能以从头开始构建弹出窗口,并使用 tinymode、tinykeymap 或 submode 等插件伪造一个新的插入完成弹出菜单模式。
【问题讨论】:
-
你读了什么?你尝试了什么?它是如何失败的?
-
你心目中的补全是什么?例子?也许某些东西已经存在。
标签: python vim vim-plugin