如何理解这个 Vim 脚本?

10
以下是从vim插件中获取的vim脚本: vim的语法有些奇怪: 1. !exists("*s:SetVals"),为什么s:前面有个星号? 2. function!,为什么有一个感叹号字符? 3. &iskeyword,这是一个变量吗?如果是,它在哪里定义? 4. s:和g:是什么,它们之间有什么区别? 5. 为什么应该使用let?例如let &dictionary = g:pydiction_location,我能否将其更改为&dictionary = g:pydiction_location?

if !exists("*s:SetVals")

  function! s:SetVals()
      " Save and change any config values we need.

      " Temporarily change isk to treat periods and opening 
      " parenthesis as part of a keyword -- so we can complete
      " python modules and functions:
      let s:pydiction_save_isk = &iskeyword
      setlocal iskeyword +=.,(

      " Save any current dictionaries the user has set:
      let s:pydiction_save_dictions = &dictionary
      " Temporarily use only pydiction's dictionary:
      let &dictionary = g:pydiction_location

      " Save the ins-completion options the user has set:
      let s:pydiction_save_cot = &completeopt
      " Have the completion menu show up for one or more matches:
      let &completeopt = "menu,menuone"

      " Set the popup menu height:
      let s:pydiction_save_pumheight = &pumheight
      if !exists('g:pydiction_menu_height')
          let g:pydiction_menu_height = 15
      endif
      let &pumheight = g:pydiction_menu_height

      return ''
  endfunction     

endif


@AshwiniChaudhary 因为这个脚本调用了Python :) - hugemeow
2
它可能是Ruby、Perl或Lua,但与你的问题无关。 - romainl
1
(edited out the python tag) - jedwards
@romainl 你的意思是 Vim 脚本可以调用使用不同编程语言实现的函数吗? - hugemeow
@jedwards 我想知道Vim脚本如何调用Python... - hugemeow
显示剩余2条评论
3个回答

23
1. !exists("*s:SetVals")中的星号是exists函数的特殊语法,它表示我们正在检查是否存在名为SetVals的函数。选项iskeyword可以通过exists("&iskeyword")检查,ex命令echo可以通过exists(":echo")检查。可参考:h exists(
2. 感叹号表示如果函数已存在,则要替换该函数。可参考:h user-functions
3. 这是vim选项。您可以使用:set iskeyword?检查是否设置了它。
4. 这些定义了以下符号的作用域。 s:表示该符号局限于脚本,而g:则表示该符号将是全局的。 可参考:h internal-variabless:请参考:h script-variable
5. 在Vim中,let用于声明变量并分配值。例如let &dictionary = g:pydiction_location表示将g:pydiction_location的值分配给&dictionary变量。不能将其更改为&dictionary = g:pydiction_location

Vimscript是一种需要使用关键字声明变量的语言。我认为除了使用 let,没有比这更简单的声明变量的方式了。


1
“定义作用域”的说法是正确的,但“变量符号只能在当前脚本中使用”的说法是错误的:因为有s:——作用域字典——您可以自由地将其传递到其他地方以授予对脚本局部变量的访问权限。 - ZyX
1
5.:变量不需要使用关键字声明(例如:call extend(g:, {'var': 'val'}) 创建了 g:var 变量,没有使用 let),只有一种语句类型:一个看起来像 [range][command][!][argument[s]][comment] 的命令(所有元素都是可选的,某些命令要求范围、感叹号、参数的缺失或不支持将注释作为参数的一部分,没有命令的范围是“转到范围内的最后一行”),没有 OP 所要求的“赋值”语句,因为它不符合这个语法。 - ZyX

6

我可以回答其中的一些问题,但我将从你最近的问题所启发的一般性评论开始。

大多数问题的答案在Vim的详尽文档中都有清晰地说明。如果你真的想使用Vim,那么你必须知道如何使用它。首先输入:help并仔细阅读。这是值得的。相信我。

你可以在:help expression中找到所有这些子问题的答案。

  • !exists("*s:SetVals"),为什么s:前面有一个星号标记?

    请参见:help exists()

  • function!,为什么有一个!字符?

    没有感叹号,如果您重新源化脚本,Vim不会替换先前的定义。

  • &iskeyword,这是一个变量吗?如果是,它在哪里定义?

    这是在脚本中测试vim选项值的方法。请参见:help iskeyword

  • s:g:是什么?它们之间有什么区别?

    这些是命名空间。请参见:help internal-variables

  • 为什么应该使用let?例如,让&dictionary = g:pydiction_location,我可以将其更改为&dictionary = g:pydiction_location吗?

    不,你不能,:let是定义或更新变量的方法。习惯它。


3

请查看:help eval.txt,其中描述了大部分vimscript语法。


你怎么知道这个文件包含大部分 Vim 脚本的规范,有没有内置工具可以搜索所有 Vim 的内置文档? - hugemeow
2
@hugemeow 请查看:h :helpgrep:helpgrep是用于搜索所有文档文件的命令。 - ZyX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接