VimScript变量

上节我们介绍了Python和Ruby来编写Vim插件的方式。

不过,Python和Ruby并不是所有的Vim都支持的功能,如果以最小依赖的原则来说,还是原汁原味的Vimscripts是放置四海Vim而皆灵的方式。当代码规模变大时,Python,Ruby,Perl这些语言的引入将带来较高的效率。但是Vimscripts仍然是最基本的Vim语言,值得我们首先学好。

变量

做为一种脚本语言,Vimscript当然是支持变量的。

不过Vimscript的特色是,显式指定作用域。也就是说,一个变量,需要在名字前加作用域前缀。

这些作用域前缀有:

* b: 缓冲区级作用域

* w: 窗口级作用域

* t: 标签页级作用域

* g: 全局变量

* l: 函数内局部变量

* s: vim脚本文件级作用域

* a: 函数参数

* v: Vim专用的全局变量

如果未指定前缀,定义于函数内部的默认为l:,而定义于函数之外的默认为g:.

Vimscript通过:let命令来为变量赋值,赋值之前不需要定义。

访问属性和寄存器

Vimscript通过&属性名的方式来访问属性,也就是除了:set之外,我们也可以通过:let为变量赋值。

同变量一样,属性也有作用域,可以通过&l:属性来只改本地属性。相当于我们使用了:setlocal命令。

:let还可以通过@来访问寄存器。

还记得吗?d,c,y等命令支持将删除或复制的内容放到寄存器中,如果未指定,则放入”“寄存器中。”0到”9中最储历史值。还有”a到”z一共26个命名寄存器。

数据类型

首先是数据类型,Vimscript提供下面9种基本数据类型:

* Number: 32位带符号整数. 如果支持+num64,就是64位带符号整数。支持十六进制,二进制和八进制。

* Float: 浮点数。只有编译时支持+float才有。

* String: 字符串。

* List: 有序列表。

* Dictionary: 哈希表。

* Funcref: 函数引用。

* 特殊值

* v:false

* v:true

* v:none

* v:null

* Job: 任务相关

* Channel: 通道相关

一个变量的类型可以通过type()函数查看。

数字和字符串

在Vimscript中,字符串和数字之间会进行自动转换。我们看下官方的几个例子:

  • String “456” –> Number 456
  • String “6bar” –> Number 6
  • String “foo” –> Number 0
  • String “0xf1” –> Number 241
  • String “0100” –> Number 64
  • String “0b101” –> Number 5
  • String “-8” –> Number -8
  • String “+8” –> Number 0

“foo”被转换成0,和”+8”被转换成0这两条case要特殊注意。

另外,八进制”0100”的情况也要特别注意。

为了避免出现八进制转换的问题,我们可以使用str2nr函数来做显示转换。因为str2nr默认是10进制的。

echo 0100

的结果为64

echo str2nr("0100")

的值为100.

真值和假值

在Vimscript中,0表示假值,其余数值均表示真值。假值也可以用v:false表示,真值为v:true.

比如”foo”的值为假,因为”foo”转换成整数的值是0.

列表类型

Vimscript的列表可以混杂各种元素。

例:

:let b:list1 = [1, 4.1e+3, "Hello",[1,2]]

列表可以用下标访问。比如b:list1[0].

列表的下标从0开始计数。而[-1]表示最后一个元素。

如果要给列表元素一个不存在时的默认值的话,可以使用get()函数。

例:

        :echo get(mylist, idx)
        :echo get(mylist, idx, "NONE")

两个列表可以通过+号来连接成一个列表:

        :let longlist = mylist + [5, 6]
        :let mylist += [7, 8]

子列表

Vimscript取子列表跟其它脚本语言很像,用[起始位置:结束位置]来进行切片。

        :let shortlist = mylist[2:-1]   " get List [3, "four"]

如果是从第一个元素开始,或者到最后一个元素结束,都可以省略:

        :let endlist = mylist[2:]       " from item 2 to the end: [3, "four"]
        :let shortlist = mylist[2:2]    " List with one item: [3]
        :let otherlist = mylist[:]      " make a copy of the List

如果越界了,也不会产生错误,到最后一个元素结束了就是了么。

        :let mylist = [0, 1, 2, 3]
        :echo mylist[2:8]               " result: [2, 3]

列表的赋值和拷贝

如果将一个列表赋给另一个变量,不会复制列表,只是传递引用。

如果想要复制一份列表的话,需要使用copy函数。

例:

        :let aa = [[1, 'a'], 2, 3]
        :let bb = copy(aa)
        :call add(aa, 4)
        :let aa[0][1] = 'aaa'
        :echo aa
        [[1, aaa], 2, 3, 4]
        :echo bb
        [[1, aaa], 2, 3]

但是请注意,copy只是浅copy,如果有子列表,是只复制引用的。如果真的要大搬家,需要使用deepcopy()函数。

列表的比较

  • is: 比较两个变量是否引用同一列表
  • ==:比较两个列表的值是否相等

另外需要注意的是,对于变量,会自动将字符串转成数字,但是对于列表中的元素,没有这种自动转换。

        echo 4 == "4"
        1
        echo [4] == ["4"]
        0

列表的多变量赋值

如果要引用列表中的值,可以同时将其赋给多个变量。

例:

        :let [var1, var2; rest] = mylist

等价于:

        :let var1 = mylist[0]
        :let var2 = mylist[1]
        :let rest = mylist[2:]

这个对于函数返回值之类的是个利好。

列表的修改

对于可以定位的值,直接通过:let赋值的方式修改。

对于插入,添加,删除等,使用相关函数来进行操作:

        :call insert(list, 'a')         " prepend item 'a'
        :call insert(list, 'a', 3)      " insert item 'a' before list[3]
        :call add(list, "new")          " append String item
        :call add(list, [1, 2])         " append a List as one new item
        :call extend(list, [1, 2])      " extend the list with two more items
        :let i = remove(list, 3)        " remove item 3
        :let l = remove(list, 3, -1)    " remove items 3 to last item
        :call filter(list, 'v:val !~ "x"')  " remove items with an 'x'

列表还可以排序、反转和排重:

        :call sort(list)                " sort a list alphabetically
        :call reverse(list)             " reverse the order of items
        :call uniq(sort(list))          " sort and remove duplicates

使用for循环来处理列表

for循环是处理列表的最简用手段:

        :for item in mylist
        :   call Doit(item)
        :endfor

for循环支持解构式的赋值:

        :for [i, j; rest] in listlist
        :   call Doit(i, j)
        :   if !empty(rest)
        :      echo "remainder: " . string(rest)
        :   endif
        :endfor

列表常用函数

  • empty函数:判空
  • len函数:计算列表元素个数
  • max函数:求列表最大元素
  • min函数:求列表最小元素
  • count函数:计算元素在列表中出现的次数
  • index函数:求元素第一次出现的位置
  • split函数:将字符串拆分成列表
  • join函数:将列表连接成一个字符串

字典

Vimscript的字典功能,其实就是哈希表。

例:

        :let mydict = {1: 'one', 2: 'two', 3: 'three'}
        :let emptydict = {}

访问字典可以使用[]:

        :let val = mydict["one"]
        :let mydict["four"] = 4

在没有歧义的情况下,也可以使用.:

        :let val = mydict.one
        :let mydict.four = 4

字典遍历

可以通过遍历keys列表和values列表的方式来遍历字典。

例:

        :for key in keys(mydict)
        :   echo key . ': ' . mydict[key]
        :endfor
        :for v in values(mydict)
        :   echo "value: " . v
        :endfor

还可以遍历前先排一次序:

        :for key in sort(keys(mydict))

也可以将key和value打包在一起,使用item函数遍历:

        :for [key, value] in items(mydict)
        :   echo key . ': ' . value
        :endfor

字典的复制

字典的复制也同样要使用copy和deepcopy函数。

字典的增删改查

字典的修改和增加都很简单,直接赋值就是了:

        :let dict[4] = "four"
        :let dict['one'] = item

Vim技能修炼教程(13) - 变量的更多相关文章

  1. Vim技能修炼教程(2) - 语法高亮速成

    语法高亮速成 我们继续在人间修行Vim技能之旅.上一次我们学习了如何通过vundle安装插件,这次我们迅速向写插件的方向挺进. 我们先学习一个最简单的语法高亮插件的写法. 语法高亮基本上是由三部分组成 ...

  2. Vim技能修炼教程(1) - 使用vundle管理插件

    世界上有两个伟大的编辑器:一个是emacs,一个是vi.它们从诞生以来,一直在Unix/Linux世界得到最广泛的支持. 尽管过了几十年,在Windows平台上和跨平台上有层出不穷的后起之秀不断挑战它 ...

  3. Vim技能修炼教程(10) - 代码跳转

    程序员功能 前面我们用了5讲的篇幅来讲基本编辑的基本功:第4讲是基本操作,第5讲是操作符,第6讲行编辑ex命令,第7讲可视模式,第8讲多窗口,第9讲缓冲区和标签页. 从这一讲开始,我们从通用功能向程序 ...

  4. Vim技能修炼教程(8) - 多窗口

    多窗口 如果一个vim只能开一个窗口,那肯定是有点low.尤其是写代码的时候,打开多个文件是经常的需求. 速成教程 横着切成两个 :split 文件名 上下切换窗口 Ctrl-W加上上下键,可以实现上 ...

  5. Vim技能修炼教程(6) - 行编辑器

    在很久很久以前,计算机的运算能力还很弱,终端与主机的通信也不好.在没有显示器的时代,只能通过电传打字机跟主机通信.那时候只有行编辑器,编辑的时候只能在一行中进行.需要显示哪一行,就把哪一行或者哪几行打 ...

  6. Vim技能修炼教程(3) - 语法高亮进阶

    语法高亮进阶 首先我们复习一下上节学到的三个命令: * syntax match用于定义正则表达式和规则的对应 * highlight default定义配色方案 * highlight link将正 ...

  7. Vim技能修炼教程(17) - 编译自己的Vim

    编译自己的Vim 前面我们已经对Vim有比较丰富的了解了.我们也知道Vim有很多编译时的选项,很多功能依赖于这些编译选项.其中最重要的就是脚本语言的支持,很多发行版本是不全的.为了支持我们所需要的功能 ...

  8. Vim技能修炼教程(16) - 浮点数计算函数

    浮点数计算函数 这一节的所有函数,只有在vim编译时支持了+float时才有效. 三角函数 sin() : sine正弦函数 cos() : cosine余弦函数 tan() : tangent正切函 ...

  9. Vim技能修炼教程(15) - 时间和日期相关函数

    Vimscript武器库 前面我们走马观花地将Vimscript的大致语法过了一遍.下面我们开始深入看一下Vimscript都给我们准备了哪些武器.如果只用这些武器就够了,那么就太好了,只用Vimsc ...

随机推荐

  1. 20145310 《Java程序设计》第9周学习总结

    20145310 <Java程序设计>第9周学习总结 教材学习内容总结 本周主要进行第十六章和第十七章的学习. JDBC全名Java DataBase Connectivity,是java ...

  2. Seccon2017-pwn500-video_player

    感觉这个题目并不值500分,有些地方比较牵强,漏洞也比较明显,解题方法有多种,出题者把堆的布局随机化了,不过使用fastbin doublefree的话,可以完全忽视被打乱的堆. from pwn i ...

  3. ubuntu16.04下安装mysql详细步骤

    1.如果要搭建服务器先去购买一个云主机,比如阿里云.京东云.新网等等都有卖.这里推荐使用京东云服务器,因为最近在搞活动.一元可体验两个月(可能现在活动已经过了,但在京东云里有免费领一个月的,学生机也有 ...

  4. Docker pull网络错误

    [root@Oracle ~]# docker search centos Error response from daemon: Get https://index.docker.io/v1/sea ...

  5. asp.net core开发注意事项

    1.类库的创建尽量选择.net standard. 如果选择.net core 则.net framework不能调用该类库, .net core和.net framework都可以调用.net st ...

  6. Memcached stats sizes 命令

    Memcached stats sizes 命令用于显示所有item的大小和个数. 该信息返回两列,第一列是 item 的大小,第二列是 item 的个数. 语法: stats sizes 命令的基本 ...

  7. Nginx 从0开始学

    作为一个 nginx 的初学者记录一下从零起步的点滴. 基本概念 Nginx 最常的用途是提供反向代理服务,那么什么反向代理呢?正向代理相信很多大陆同胞都在这片神奇的土地上用过了,原理大致如下图: 代 ...

  8. GTID主从 与 传统主从复制

    一.主从复制 1.)普通主从复制: 普通主从复制主要是基于二进制日志文件位置的复制,因此主必须启动二进制日志记录并建立唯一的服务器ID,复制组中的每个服务器都必须配置唯一的服务器ID.如果您省略ser ...

  9. 由angular命令行工具(angular-cli)生成的目录和文件

    e2e目录:是端到端的测试目录,包含基本的测试桩.是用来做自动测试的. src:应用源代码目录.我们写的所有代码都应该在这里面. app:包括应用的组件和模块.我们自己写的绝大部分代码都是写在这个目录 ...

  10. 英语词根与单词的说文解字---词根示例1、第10页 st(at)

    英语词根与单词的说文解字---词根示例1.第10页 st(at) 一.总结 一句话总结: 站 state,establish,constitution 英 [ɪ'stæblɪʃ; e-]  美 [ɪˈ ...