跳转至内容

学习 vi 编辑器/Vim/VimL 脚本语言

来自维基教科书,开放书籍,开放世界

学习 vi 编辑器: 熟悉基本任务简化工作高级任务细节Vi 克隆 (Vim基本导航模式技巧和窍门程序员必知增强 VimVim 在 Windows 上VimL 脚本语言, Vile, BB vi)vi 参考

Vim 脚本(也称为 Vimscript 或 VimL)是一种功能齐全的脚本语言,这意味着它可以解决几乎任何文本处理问题。

要设置变量,请使用

let variable = expression

要设置内置设置,您有两个选择

set setting = expression     " (use the regular command for changing a setting)
let &setting = "expression"  " (treat the setting as a special kind of variable)

数据类型

[编辑 | 编辑源代码]

有五种数据类型

一个 32 位有符号整数。

字符串

[编辑 | 编辑源代码]

一个以 NULL 结尾的 8 位无符号字符(字节)字符串。字符串可以通过 ‘'’ 或 ‘"’ 引号创建。当使用双引号 ‘"’ 引起来的字符串时,文本会被解释,例如 "\n" 会变成换行符,而用单引号 ‘'’ 引起来的字符串则不会被解释,例如 '\n' 就是一个反斜杠和一个 n。以下两个字符串是相同的

let String_1 = "C:\\WinNT"
let String_2 = 'C:\WinNT'

任何其他数据类型都可以使用 string () 函数转换为字符串。

函数引用

[编辑 | 编辑源代码]

对函数的引用。函数引用可以通过使用 function 函数从字符串创建。

let Function_1 = function ("MyFunc")

一个有序的项目序列。

let List_1 = [
    \ "a",
    \ "b",
    \ "c"]

可以使用 split 函数从字符串创建列表。

let List_2 = split ("a b c")

一个关联的无序数组:每个条目都有一个键和一个值。

let Dictionary_1 = {
    \ 1: 'one', 
    \ 2: 'two',
    \ 3: 'three'}

VIM 通过将 函数引用字典 结合到一个对象中来支持面向对象编程。

let mydict = {
    \'data': [0, 1, 2, 3]}

function mydict.len () dict
   return len (self.data)
endfunction mydict.len

有关更多信息,请参见 面向对象编程

控制结构

[编辑 | 编辑源代码]

控制结构的存在是 vi 的 ex 命令和 vim 的脚本语言之间的主要区别。它们使一个简单的命令集 (vi) 与一个功能齐全的脚本语言 (vim) 之间有所区别。

if condition
    operations
elseif condition
    operations 
else
    operations 
endif
while condition
    operations
endwhile

for 循环从 vim 7 开始可用。它们遍历列表或目录结构。

for var in list
    operations
endfor
try
    operations
catch /pattern/
    error handling operations
finally
    clean-up operations
endtry

子程序

[编辑 | 编辑源代码]

简单子程序

[编辑 | 编辑源代码]

就像大多数 Shell 语言 一样,所有子程序都存储在单独的文件中,您可以使用 sourceruntime 命令加载它们。区别在于搜索路径的使用。 runtime 使用搜索路径并允许使用通配符来查找子程序,而 source 需要完整路径。以下命令执行相同的操作 - 假设“~/vimfiles”是您的运行时搜索路径的一部分

runtime setup.vim
source  ~/vimfiles/setup.vim

对于这两个命令,都需要添加 .vim 扩展名。由于 runtime 支持搜索路径和通配符,因此可能存在多个匹配项。如果您希望 runtime 加载所有匹配项 - 而不仅仅是第一个匹配项 - 请使用 runtime!

function f ( parameter )
    operations
endfunction

vim 7 中新增了函数的自动加载选项。如果将函数命名为 Filename#FunctionnameDirectory#Filename#Functionname,则该函数将在首次调用时自动加载。包含函数的文件必须放置在“autoload”运行时目录之一中,并命名为“Filename.vim”或“Directory/Filename.vim”。此选项对于您不始终需要在 面向对象编程 中启用的函数特别有用。

command Command Command

命令通常用作函数和子程序的快捷方式

command C -nargs=* call F ( <f-args> )
command C source ~/vimfiles/s.vim

面向对象编程

[编辑 | 编辑源代码]

vim 7 现在允许 面向对象编程。但是,为了使其真正实现,您需要组合几个功能,即 字典Funcrefs 和新的 函数自动加载

以下示例类取自 vim 的 gnat 编译器插件。实际的函数实现已删除,因为它们不需要理解该概念。如果您想查看完整版本,可以从 vim.org 网站 下载该插件。

分步演练

[编辑 | 编辑源代码]

我们将新类添加到自动加载脚本中。这样,该类仅在需要时可用

if exists ("g:loaded_gnat_autoload") || version < 700
    finish
else
   let g:loaded_gnat_autoload=1

我们定义的每个函数都需要使用“dict”属性定义。除此之外,它们只是正常的脚本函数。

   function gnat#Make () dict
      ...
      return
   endfunction gnat#Make

   function gnat#Pretty () dict
      ...
      return
   endfunction gnat#Pretty

   function gnat#Find () dict
      ...
      return
   endfunction gnat#Find

   function gnat#Tags () dict
      ...
      return
   endfunction gnat#Tags

   function gnat#Set_Project_File (...) dict
      ...
      return
   endfunction gnat#Set_Project_File

   function gnat#Get_Command (Command) dict
      ...
      return ...
   endfunction gnat#Get_Command

最重要的步骤是对象的组成。在大多数面向对象语言中,这会自动发生 - 但在 vim 中,我们必须自己完成。为了获得最佳灵活性,建议使用所谓的构造函数。构造函数未用“dict”标记

   function gnat#New ()

构造函数创建一个字典,该字典将所有对象函数分配给字典的一个元素

      let Retval = {
	 \ 'Make'	      : function ('gnat#Make'),
	 \ 'Pretty'	      : function ('gnat#Pretty'),
	 \ 'Find'	      : function ('gnat#Find'),
	 \ 'Tags'	      : function ('gnat#Tags'),
	 \ 'Set_Project_File' : function ('gnat#Set_Project_File'),
	 \ 'Get_Command'      : function ('gnat#Get_Command'),
	 \ 'Project_File'     : '',

我们现在可以可选地将数据条目添加到我们的对象中

	 \ 'Make_Command'     : '"gnat make -P " . self.Project_File . "  -F -gnatef  "',
	 \ 'Pretty_Command'   : '"gnat pretty -P " . self.Project_File . " "',
	 \ 'Find_Program'     : '"gnat find -P " . self.Project_File . " -F "',
	 \ 'Tags_Command'     : '"gnat xref -P " . self.Project_File . " -v  *.AD*"',
	 \ 'Error_Format'     : '%f:%l:%c: %trror: %m,'   .
			      \ '%f:%l:%c: %tarning: %m,' .
			      \ '%f:%l:%c: (%ttyle) %m'}

如果需要,也可以对对象进行额外的修改。在这个阶段,您已经可以使用面向对象的方式

      if argc() == 1 && fnamemodify(argv (0), ':e') == 'gpr'
	 call Retval.Set_Project_File(argv(0))
      elseif  strlen(v:servername) > 0
	 call Retval.Set_Project_File(v:servername . '.gpr')
      endif

构造函数的最后一个操作是返回新创建的对象。

      return Retval
   endfunction gnat#New

还可以定义额外的非 dict 函数。这些函数等效于其他面向对象语言的“静态”或“类”方法。

   function gnat#Insert_Tags_Header()
      ...
      return
   endfunction gnat#Insert_Tags_Header

   finish
endif


学习 vi 编辑器: 熟悉基本任务简化工作高级任务细节Vi 克隆 (Vim基本导航模式技巧和窍门程序员必知增强 VimVim 在 Windows 上VimL 脚本语言, Vile, BB vi)vi 参考

华夏公益教科书