
文档【免费下载链接】awesome-cheatsheets超级速查表 - 编程语言、框架和开发工具的速查表单个文件包含一切你需要知道的东西 :zap:项目地址https://gitcode.com/gh_mirrors/awe/awesome-cheatsheets点击查看免费下载本文以开源速查表仓库 awesome-cheatsheets 中的 languages/vimscript.md 为核心骨架系统讲解 VimScriptVim 脚本语言的变量与作用域、数据类型、字符串比较、控制流、函数定义以及用字典模拟面向对象等核心知识点。无论你是想读懂别人的.vimrc配置还是准备编写自己的 Vim 插件读完本文你都能掌握 VimScript 的语法主干并学会借助 Vim 内建帮助系统:h与交互式命令快速验证和调试脚本。学习环境准备内建帮助与交互式调试Vim 拥有非常丰富的内建文档系统任何关键词都可以通过:h 关键词查阅。例如后续章节中出现的let、function、deepcopy()、ignorecase等都可以直接输入:h let、:h function、:h deepcopy查看官方解释。与本篇文档配套的 editors/vim.txt 速查表也专门列出了两条与脚本相关的入口:h eval脚本编写帮助VimScript 的完整语法手册:h function-list查看 VimScript 内建函数列表。此外如果想在编写过程中随时尝试各种 VimScript 表达式可以在 NORMAL 模式下使用gQ命令进入 VimScript 的交互式环境调试命令边写边验证效率远高于反复编辑配置文件后重启 Vim。最后注意一个约定下文例子中出现的形如符号的记号表示正式使用时应该被完全替换成真实的内容包括左右两边的尖括号在内而单独的和在 VimScript 中则被用作比较运算符二者含义不同阅读时需加以区分。变量声明、删除与作用域变量的创建与删除let命令用来对变量进行初始化或者赋值unlet命令用来删除一个变量unlet!命令同样可以删除变量但会忽略诸如变量不存在之类的错误提示。也就是说当你无法确定某个变量是否已经定义、又希望安全地清理它时应该使用带感叹号的unlet!避免脚本因报错而中断。作用域默认规则与显式前缀默认情况下如果一个变量在函数体以外初始化它的作用域是全局变量如果它是在函数体以内初始化的它的作用域是局部变量。同时你可以通过在变量名前加冒号前缀明确地指明变量所属的作用域g:var - 全局 a:var - 函数参数 l:var - 函数局部变量 b:var - buffer 局部变量 w:var - window 局部变量 t:var - tab 局部变量 s:var - 当前脚本内可见的局部变量 v:var - Vim 预定义的内部变量各作用域的实际含义如下g:全局变量任何脚本、任何函数中都可以访问a:函数参数只能在函数内部使用用于读取调用者传入的实参详见函数一节l:函数局部变量只能在声明它的函数内部使用b:buffer 局部变量每个缓冲区各自独立常用于保存与当前文件相关的状态w:window 局部变量每个窗口各自独立常用于分屏场景下的窗口级状态t:tab 局部变量每个标签页各自独立s:脚本局部变量仅对当前脚本文件可见是避免命名冲突、实现插件内部私有状态的关键手段v:Vim 预定义变量由 Vim 自身维护例如v:true、v:false、v:count、v:version等。环境变量与选项的读写除了上述普通变量VimScript 还提供了两种特殊形式的读写接口通过$name的模式读取或改写环境变量例如let $PATH $PATH . :/usr/local/bin可以在脚本中动态修改 PATH通过option的方式读写Vim 内部设置值例如let ignorecase 1等价于执行:set ignorecase。这一点与 editors/vim.txt 中大量:set常用设置命令是相通的速查表里列出的:set number、:set ignorecase、:set hlsearch等在脚本中都可以写作number、ignorecase、hlsearch的形式参与表达式运算例如按需保存和恢复用户的设置。数据类型与真值语义Number32 位有符号整数-123 0x10 0177支持十进制、十六进制0x前缀和八进制0前缀三种写法取值上限为 32 位有符号整数。Float浮点数需要编译 Vim 时带有float特性支持否则浮点字面量会出错123.456 1.15e-6 -1.1e3支持科学计数法写法。StringNULL 结尾的 8 位无符号字符串ab\txx\-- x-za,c双引号字符串支持转义序列如\t、\单引号字符串则不进行转义且内部的单引号通过连续两个单引号表示字面单引号。Funcref函数引用函数引用类型的变量名必须以大写字母开头可以通过function()内建函数取得某个函数的引用再像调用普通函数一样调用它:let Myfunc function(strlen) :echo Myfunc(foobar) Call strlen on foobar. 6List有序列表列表可以嵌套支持正负索引负数表示从末尾倒数索引越界会报错但可以用get()提供默认值:let mylist [1, 2, [a, b]] :echo mylist[0] 1 :echo mylist[2][0] a :echo mylist[-2] 2 :echo mylist[999] E684: list index out of range: 999 :echo get(mylist, 999, THERE IS NO 1000th ELEMENT) THERE IS NO 1000th ELEMENT上面的例子说明mylist[-2]取倒数第二个元素即2而访问越界索引会抛出E684错误因此在不确定索引是否合法时优先使用get(list, index, default)三参数形式它会安全地返回默认值而不是报错。Dictionary无序的 Key/Value 容器字典通过花括号字面量创建键既可以是字符串也可以是数字取值既可以用中括号dict[key]也可以用点号dict.key数字键用dict.999这种形式:let mydict {blue: #0000ff, foo: {999: baz}} :echo mydict[blue] #0000ff :echo mydict.foo {999: baz} :echo mydict.foo.999 baz :let mydict.blue BLUE :echo mydict.blue BLUE字典的赋值同样支持点号语法let mydict.blue BLUE会直接修改对应键的值。真值语义没有布尔类型VimScript没有布尔类型整数0被当作假false其他整数被当作真true。字符串在比较真假前会被转换成整数大部分字符串都会被转化为 0只有以非零数字开头的字符串才会转化为非零:echo 1 . foo 1foo :echo 1 1 2 :function! TrueFalse(arg) : return a:arg? true : false :endfunction :echo TrueFalse(foobar) false :echo TrueFalse(1000) true :echo TrueFalse(x1000) false :echo TrueFalse(1000x) true :echo TrueFalse(0) false从结果可以清楚看到foobar、x1000、0都转换为 0假而1000、1000x因为以非零数字开头转换为非零真。上面的1 . foo与1 1还顺便演示了 VimScript 的动态弱类型特性字符串连接运算符.会把数字隐式转换为字符串算术运算符会把数字字符串隐式转换为整数参与运算。补充一点可以调用type(varname)获取变量的类型编号从 Vim 8.1 开始VimScript 已经包含真正的 Boolean 类型并提供v:true、v:false两个预定义值供需要明确布尔语义的场合使用。字符串比较与连接字符串比较运算符及其含义如下stringstring字符串相等string!string字符串不等string~pattern匹配 pattern正则string!~pattern不匹配 pattern正则operator#匹配大小写operator?不匹配大小写忽略大小写注意设置选项ignorecase会影响和!的默认比较结果。为了不受该选项影响可以在比较符号后添加?或#来明确指定是否忽略大小写——#表示严格区分大小写?表示忽略大小写。这正是 editors/vim.txt 中:set ignorecase/:set noignorecase与脚本逻辑联动的地方交互式搜索可能开着ignorecase但脚本内部的关键比较应使用~#这类带修饰符的形式来保证行为确定。字符串连接使用.运算符示例:function! TrueFalse(arg) : return a:arg? true : false :endfunction :echo TrueFalse(X start ~ X$) false :echo TrueFalse(end X ~ X$) true :echo TrueFalse(end x ~# X$) false~右侧是正则表达式模式end X ~ X$匹配成功返回真而end x ~# X$由于使用了区分大小写的~#小写x无法匹配大写X返回假。这组对比直观展示了正则匹配与大小写修饰符的组合用法。控制流条件、循环与异常条件判断if expression ... elseif expression ... else ... endif注意关键字是elseif一个词而不是其他语言常见的else ifendif结束整个条件块。普通循环for var in list continue break endfor循环体内可以使用continue跳过本轮、break跳出循环。复杂循环迭代解构当列表元素本身是列表时可以用for [var1, var2] in ...的形式在循环头直接解构多个变量for [var1, var2] in [[1, 2], [3, 4]] on 1st loop, var1 1 and var2 2 on 2nd loop, var1 3 and var2 4 endfor这一特性在处理成对数据如键值对、坐标点时非常实用。While 循环while expression endwhile异常捕获try ... catch pattern (optional) HIGHLY recommended to catch specific error. finally ... endtrycatch后的pattern是可选的错误匹配模式官方建议尽量捕获具体的错误类型例如catch /E684/而不是笼统地吞掉所有异常finally块无论是否发生异常都会执行适合做资源清理。三者共同构成完整的异常处理链路try ... catch ... finally ... endtry。函数定义、调用与范围操作使用function关键字定义一个函数使用function!覆盖一个函数已有的定义在重复执行配置时不会报错。函数和变量一样也有作用范围的约束并且函数名必须以大写字母开头function! Name(arg1, arg2, etc) function body endfunctiondelfunction function删除一个函数call function调用一个函数。函数调用前的call语句是必须的除非该调用出现在一个表达式里例如let x Myfunc(1)就不需要call。例如强制创建一个全局函数使用感叹号参数使用...这种不定长的参数形式时a:1表示...部分的第一个参数a:2表示第二个如此类推a:0用来表示...部分一共有多少个参数function! g:Foobar(arg1, arg2, ...) let first_argument a:arg1 let index 1 let variable_arg_1 a:{index} same as a:1 return variable_arg_1 endfunction注意a:{index}这种用变量作键名的取参方式当索引存在变量中时可以用大括号表达式动态取到a:1、a:2等参数这为编写参数数量不确定的通用函数提供了灵活性。按文本范围调用函数有一种特殊的调用函数的方式可以指明该函数作用的文本区域是从当前缓冲区的第几行到第几行。按照1,3call Foobar()的格式调用一个函数的话该函数会在当前文件的第一行到第三行每一行各执行一遍在这个例子中该函数总共被执行了三次。如果你在函数声明的参数列表后添加一个range关键字那函数就只会被调用一次此时两个名为a:firstline和a:lastline的特殊变量可以用于函数内部表示本次调用覆盖的文本起止行号。例如强制创建一个名为RangeSize的函数用来显示被调用时的文本范围function! b:RangeSize() range echo a:lastline - a:firstline endfunction这是 Vim 中函数化处理文本块如对指定行区间做格式化、统计或批量改写的标准手段也是:h function中 range 特性的典型应用。用字典模拟面向对象Vim 没有原生的类支持但是可以用字典模拟基本的类。为了定义类的方法可以在函数声明时使用dict关键字将调用它的字典在函数体内暴露为self关键字let MyClass {foo: Foo} function MyClass.printFoo() dict echo self.foo endfunction这里的function MyClass.printFoo()直接把函数挂到了字典上dict关键字使得函数体内的self指向MyClass这个字典本身。类的实现更类似于singleton单例为了在 VimScript 中创建类的实例我们对字典使用deepcopy()方法进行深拷贝从而得到互不影响的独立副本:let myinstance deepcopy(MyClass) :call myinstance.printFoo() Foo :let myinstance.foo Bar :call myinstance.printFoo() Bar可以看到拷贝出的myinstance能正常调用方法输出Foo修改myinstance.foo后再次调用输出变为Bar而原始的MyClass不受影响——这正是实例化语义的体现。之所以必须用deepcopy()而不是直接赋值是因为字典在 VimScript 中属于引用类型直接赋值只会让多个实例共享同一份数据失去类的隔离效果。实战把 VimScript 与 Ex 命令结合起来脚本语言最终要服务于 Vim 的实际编辑工作流。结合仓库中配套的 editors/vim.txt 速查表以下几类高频用法是理解 VimScript 之后值得立刻上手的实战方向表达式与寄存器插入模式下可用CTRL-R 后跟表达式插入计算结果CTRL-R :插入上一条命令行命令CTRL-R /插入上一次搜索关键字见 editors/vim.txt这些能力本质上都是对 VimScript 表达式求值的应用。在脚本中调用外部命令:call system(ls)调用外部命令但不显示返回内容可以配合let output system(...)把结果读进变量做进一步处理:%!prog可以把当前缓冲区整体交给外部程序过滤例如:%!python -m json.tool格式化 JSON与脚本函数结合可构建出强大的文本处理管线。全局命令批量处理:g/^\s*$/d删除所有空行、:g/green/d删除所有包含 green 的行、:v/green/d删除所有不包含 green 的行见 editors/vim.txt这些基于模式的批量操作在脚本中同样可以作为命令字符串动态构造执行。写入与保存技巧:w !sudo tee %在权限不足时以 sudo 方式保存当前文件:r !dir把外部命令输出捕获并插入到光标后见 editors/vim.txt。映射规范按键映射时应默认使用noremap非递归映射只有特别需要时才使用map见 editors/vim.txt这是防止映射递归展开、避免插件互相干扰的重要工程实践。后续学习路线本篇速查表翻译自 Andrew Scala 的《Five Minute Vimscript》目标是让你用最短的时间建立 VimScript 的整体认知。掌握本文的变量、数据类型、控制流、函数与字典伪面向对象之后原文档还推荐了以下方向的进阶资源可自行检索恕不附外部链接Vim 中文帮助文档usr_41 编写 Vim 脚本与 API 列表系统讲解脚本编写与内建函数 API配合:h eval使用效果最佳《Vim 脚本指北》面向实践的 VimScript 学习指南覆盖更多进阶语法与惯用法《Vim 脚本开发规范》社区总结的命名、格式与最佳实践规范适合准备长期维护插件或.vimrc的读者。此外editors/vim.txt 速查表末尾的 Tips 部分也提供了不少与脚本行为直接相关的经验例如c d x命令会自动填充寄存器1到9y命令会填充0寄存器这些寄存器在脚本中同样可以程序化访问。建议读者一边阅读本文一边打开 Vim 用gQ交互式环境逐条验证示例再对照官方:h eval文档深入细节即可快速完成从看得懂到写得出的跨越。赞分享文档【免费下载链接】awesome-cheatsheets超级速查表 - 编程语言、框架和开发工具的速查表单个文件包含一切你需要知道的东西 :zap:项目地址https://gitcode.com/gh_mirrors/awe/awesome-cheatsheets点击查看免费下载相关推荐Python 核心语法速查基于 awesome-cheatsheets 的完整语言手册Python 核心语法速查基于 awesome cheatsheets 的完整语言手册 本文以 awesome cheatsheets https://lin文档教程ReSub精准更新秘籍key订阅机制如何避免组件无效重渲染ReSub精准更新秘籍key订阅机制如何避免组件无效重渲染 ReSub 是一个专为 React 打造的 自动订阅autosubscriptions数据流Java 核心语法与面向对象编程速查指南awesome-cheatsheets Java 篇Java 核心语法与面向对象编程速查指南awesome cheatsheets Java 篇 本指南完整整理并深度讲解 awesome cheatsheet文档教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考