vim:完成取决于以前的字符

时间:2013-09-03 21:29:52

标签: vim

我想创建一个映射,它将根据光标前面的字符更改ins-completion。如果字符是{,那么我想要标记完成,如果它:我希望正常完成(取决于完整选项),并且字符是反斜杠加一些单词(\w+ )我想要字典完成。我在ftplugin/tex/latex_settings.vim文件中有以下内容:

setlocal dictionary=$DOTVIM/ftplugin/tex/tex_dictionary
setlocal complete=.,k
setlocal tags=./bibtags;

function! MyLatexComplete()
    let character = strpart(getline('.'), col('.') - 1, col('.'))

    if character == '{'
        return "\<C-X>\<C-]>"
    elseif character == ':'
        return "\<C-X>\<C-N>"
    else
        return "\<C-X>\<C-K>"
    endif
endfunction

inoremap <C-n> <c-r>=MyLatexComplete()<CR>

这不起作用,我不知道如何修复它。

编辑:这似乎有效,但我想要一个检查\ w +(反斜杠加任何单词)的条件和最后一个给出消息“找不到匹配”的条件。

function! MyLatexComplete()
    let line = getline('.')
    let pos = col('.') - 1

    " Citations (comma for multiple ones)
    if line[pos - 1] == '{' || line[pos - 1] == ','
        return "\<C-X>\<C-]>"
    " Sections, equations, etc
    elseif line[pos - 1] == ':'
        return "\<C-X>\<C-N>"
    else
    " Commands (such as \delta)
        return "\<C-X>\<C-K>"
    endif
endfunction

2 个答案:

答案 0 :(得分:3)

在你原来的功能中你有错误:

  1. strpart()获取字符串,偏移量和长度参数,同时提供了两个偏移量。
  2. col('.')是一个字符过去行尾。即len(getline('.'))==col('.')+1表示strpart(getline('.'), col('.')-1)始终为空。
  3. 您已在第二个版本中解决了这些问题。但是如果你想要\command的条件检查,你不仅需要最后一个字符。因此我建议匹配切片

    let line=getline('.')[:col('.')-2]
    if line[-1:] is# '{' || line[-1:] is# ','
       return "\<C-X>\<C-]>"
    elseif line[-1:] is# ':'
       return "\<C-X>\<C-N>"
    elseif line =~# '\v\\\w+$'
       return "\<C-X>\<C-K>"
    else
       echohl ErrorMsg
           echomsg 'Do not know how to complete: use after {, comma or \command'
       echohl None
       return ''
    endif
    

    。注意一些事情:

    1. 如果未附加==#,请勿使用?进行字符串比较。在这种情况下这无关紧要,但你应该自己动手。 ==#==?都忽略了'ignorecase'设置的值(第一个行为就像设置了'noignorecase'一样,第二个好像设置了'ignorecase')。我使用更严格的is#a is# b就像type(a)==type(b) && a ==# b
    2. =~相同:使用=~#
    3. 由于向后兼容性,string[-1]string[any_negative_integer])始终为空。因此,我必须使用line[-1:]

    4. 绝不使用普通:echoerr。它是不稳定的:你无法确定这是否会破坏执行缺陷(:echoerr如果放在:try块内则会中断执行,否则不会这样做。 echohl ErrorMsg|echomsg …|echohl None永远不会中断执行,throw …try|echoerr …|endtry始终会中断。

答案 1 :(得分:1)

要查看前面的LaTeX命令,您可以在line变量上使用以下正则表达式:

line =~ '\\\w\+$'

(正如您所看到的,正则表达式类似于您猜测的Perl表达式,但需要对某些字符进行转义)。

要回显"No match found"消息,您可以返回适当的:echoerr命令:

return "\<C-o>:echoerr 'No match found'\<CR>"

但这有side劫持插入模式的副作用......也许只是将没有匹配作为空字符串返回更清晰?

所以你的最终功能看起来像这样:

function! MyLatexComplete()
    let line = getline('.')
    let pos = col('.') - 1

    " Citations (comma for multiple ones)
    if line[pos - 1] == '{' || line[pos - 1] == ','
        return "\<C-X>\<C-]>"
    " Sections, equations, etc
    elseif line[pos - 1] == ':'
        return "\<C-X>\<C-N>"
    elseif line =~ '\\\w\+$'
    " Commands (such as \delta)
        return "\<C-X>\<C-K>"
    else
    " Echo an error:
        return "\<C-o>:echoe 'No match found'\<CR>"
    endif
endfunction