Vim技能修炼教程(13) - 变量
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) - 变量的更多相关文章
- Vim技能修炼教程(2) - 语法高亮速成
语法高亮速成 我们继续在人间修行Vim技能之旅.上一次我们学习了如何通过vundle安装插件,这次我们迅速向写插件的方向挺进. 我们先学习一个最简单的语法高亮插件的写法. 语法高亮基本上是由三部分组成 ...
- Vim技能修炼教程(1) - 使用vundle管理插件
世界上有两个伟大的编辑器:一个是emacs,一个是vi.它们从诞生以来,一直在Unix/Linux世界得到最广泛的支持. 尽管过了几十年,在Windows平台上和跨平台上有层出不穷的后起之秀不断挑战它 ...
- Vim技能修炼教程(10) - 代码跳转
程序员功能 前面我们用了5讲的篇幅来讲基本编辑的基本功:第4讲是基本操作,第5讲是操作符,第6讲行编辑ex命令,第7讲可视模式,第8讲多窗口,第9讲缓冲区和标签页. 从这一讲开始,我们从通用功能向程序 ...
- Vim技能修炼教程(8) - 多窗口
多窗口 如果一个vim只能开一个窗口,那肯定是有点low.尤其是写代码的时候,打开多个文件是经常的需求. 速成教程 横着切成两个 :split 文件名 上下切换窗口 Ctrl-W加上上下键,可以实现上 ...
- Vim技能修炼教程(6) - 行编辑器
在很久很久以前,计算机的运算能力还很弱,终端与主机的通信也不好.在没有显示器的时代,只能通过电传打字机跟主机通信.那时候只有行编辑器,编辑的时候只能在一行中进行.需要显示哪一行,就把哪一行或者哪几行打 ...
- Vim技能修炼教程(3) - 语法高亮进阶
语法高亮进阶 首先我们复习一下上节学到的三个命令: * syntax match用于定义正则表达式和规则的对应 * highlight default定义配色方案 * highlight link将正 ...
- Vim技能修炼教程(17) - 编译自己的Vim
编译自己的Vim 前面我们已经对Vim有比较丰富的了解了.我们也知道Vim有很多编译时的选项,很多功能依赖于这些编译选项.其中最重要的就是脚本语言的支持,很多发行版本是不全的.为了支持我们所需要的功能 ...
- Vim技能修炼教程(16) - 浮点数计算函数
浮点数计算函数 这一节的所有函数,只有在vim编译时支持了+float时才有效. 三角函数 sin() : sine正弦函数 cos() : cosine余弦函数 tan() : tangent正切函 ...
- Vim技能修炼教程(15) - 时间和日期相关函数
Vimscript武器库 前面我们走马观花地将Vimscript的大致语法过了一遍.下面我们开始深入看一下Vimscript都给我们准备了哪些武器.如果只用这些武器就够了,那么就太好了,只用Vimsc ...
随机推荐
- 20145310 《Java程序设计》第9周学习总结
20145310 <Java程序设计>第9周学习总结 教材学习内容总结 本周主要进行第十六章和第十七章的学习. JDBC全名Java DataBase Connectivity,是java ...
- Seccon2017-pwn500-video_player
感觉这个题目并不值500分,有些地方比较牵强,漏洞也比较明显,解题方法有多种,出题者把堆的布局随机化了,不过使用fastbin doublefree的话,可以完全忽视被打乱的堆. from pwn i ...
- ubuntu16.04下安装mysql详细步骤
1.如果要搭建服务器先去购买一个云主机,比如阿里云.京东云.新网等等都有卖.这里推荐使用京东云服务器,因为最近在搞活动.一元可体验两个月(可能现在活动已经过了,但在京东云里有免费领一个月的,学生机也有 ...
- Docker pull网络错误
[root@Oracle ~]# docker search centos Error response from daemon: Get https://index.docker.io/v1/sea ...
- asp.net core开发注意事项
1.类库的创建尽量选择.net standard. 如果选择.net core 则.net framework不能调用该类库, .net core和.net framework都可以调用.net st ...
- Memcached stats sizes 命令
Memcached stats sizes 命令用于显示所有item的大小和个数. 该信息返回两列,第一列是 item 的大小,第二列是 item 的个数. 语法: stats sizes 命令的基本 ...
- Nginx 从0开始学
作为一个 nginx 的初学者记录一下从零起步的点滴. 基本概念 Nginx 最常的用途是提供反向代理服务,那么什么反向代理呢?正向代理相信很多大陆同胞都在这片神奇的土地上用过了,原理大致如下图: 代 ...
- GTID主从 与 传统主从复制
一.主从复制 1.)普通主从复制: 普通主从复制主要是基于二进制日志文件位置的复制,因此主必须启动二进制日志记录并建立唯一的服务器ID,复制组中的每个服务器都必须配置唯一的服务器ID.如果您省略ser ...
- 由angular命令行工具(angular-cli)生成的目录和文件
e2e目录:是端到端的测试目录,包含基本的测试桩.是用来做自动测试的. src:应用源代码目录.我们写的所有代码都应该在这里面. app:包括应用的组件和模块.我们自己写的绝大部分代码都是写在这个目录 ...
- 英语词根与单词的说文解字---词根示例1、第10页 st(at)
英语词根与单词的说文解字---词根示例1.第10页 st(at) 一.总结 一句话总结: 站 state,establish,constitution 英 [ɪ'stæblɪʃ; e-] 美 [ɪˈ ...