Vimscript-技巧积累
获取当前文件 basename
1 |
|
这里查看 :h fnamemodify
函数的文档.
fnamemodify 函数
fnamemodify
可以读作 “file name modify”, 即用于修改文件名, 函数声明为:
1 |
|
- 根据指定的
{mods}
来修改{fname}
{mods}
相关内容可看 :h filename-modifiers
文档, 这里简单列出几个常用, 多个目录可以组合, 但要满足一定要求, 假设当前目录为 /home/mool/vim
, 文件名为 src/version.c
:
fnamemodify('src/version.c', ':p')
, “path”, 返回/home/mool/vim/src/version.c
, 即完整的路径fnamemodify('src/version.c', ':h')
, “head”, 返回src
, 即文件名的第一个部分, 若文件名为version.c
, 则返回.
即当前目录fnamemodify('src/version.c', ':t')
, “tail”, 返回version.c
, 即文件名的最后一部分fnamemodify('src/version.c', ':r')
, “root”, 返回src/version
, 即文件名去掉后缀的部分
切换 window
1 |
|
强制关闭所有缓冲区
1 |
|
变量作用域
VimScript 中的变量作用域是通过 “前缀” 分隔的, 具体如下:
- nothing, 即没有前缀, 如
let test = "test"
, 这样的变量若在函数中创建则为 local to function, 不然就是全局变量 b:
, buffer variable, 对当前 buffer 有效 (似乎对新建的 buffer 无效?)1
2
3
4let b:hello = "world"
new
echo b:hello
" 会报错, 因为 new 创建了新 bufferw:
, window variable, 对当前 window 有效 (似乎对新建的 window 无效?)1
2
3
4let w:hello = "world"
split
echo w:hello
" 会报错, 因为 split 创建了新 windowt:
, tabpage variable, 对当前 tab page 有效 (似乎对新建的 tabpage 无效?)1
2
3
4let t:hello = "world"
tabnew
echo t:hello
" 会报错, 因为 tabnew 创建了新 tabg:
, global, 全局变量1
2
3
4
5
6
7function! Test()
let g:ll = "hello"
endfunction
call Test()
echo g:ll
" 输出 hello, 毕竟是全局变量l:
, local, 函数内局部变量 (在函数内不加前缀也默认是局部变量)1
2
3
4
5
6
7function! Test()
let l:ll = "hello"
endfunction
call Test()
echo l:ll
" 会报错, 毕竟访问不了局部变量s
, script variable, 对当前 Vim Script 文件有效1
2
3
4
5
6
7
8" in ~/.vim/plugin/01_test.vim
let g:text1 = "global variable in 01_test.vim"
let s:text1 = "script variable in 01_test.vim"
" in ~/.vim/plugin/02_test.vim
echo g:text1
echo s:text1
" 之后打开 vim 看a:
, function argument, 只在函数内有效1
2
3
4function! Test(hello, world)
echo a:hello . " " . a:world
endfunction
" 在函数内部调用函数形参需要用 a: 前缀v:
, vim variable, Vim 预定义的全局变量, 可以在:h v:
中查看详细列表1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17" Vim 版本
echo v:version
" Vim 启用时的命令行参数
echo v:argv
" 最近捕获到的错误信息
try
throw "oops"
catch /.*/
echo "caught " .. v:exception
endtry
" viminfo 里的文件
echo v:oldfiles
" 用 ! 运行 shell 命令的报错信息
echo v:shell_error
设置 statusline
可以先查看 :h laststatus
和 :h statusline
.
laststatus
选项设置是否显示 statusline, 可以设置三个值:
- 0
: 不显示 statusline
- 1
: 当开启至少两个 window 时显示
- 2
: always 显示 statusline
而 statusline
选项定义了 status line 显示的内容, 默认为空, 模板字符串以 %
开头, 若想使用 %
字符, 应写为 %%
, 总体的形式为:
%-0{minwid}.{maxwid}{item}
, 这里除%
和{item}
外都为可选%
表明后面为模板字符串-
表明 status line 左对齐0
表明会在数字项的显示前面添加零, 以确保它的总长度达到指定的宽度minwid
指定 item 的最短宽度maxwid
指定 item 的最大宽度item
可以在:h statusline
中详细查看, 这里给出几个常见的f
, 当前 buffer 中的文件名F
, 当前 buffer 中文件的绝对路径m
, 用[+]
和[-]
显示当前 buffer 是否更改y
, 显示文件类型
示例:
1 |
|
若想用一个函数的返回值 (返回模板字符串), 前缀应为: %!
, 如:
:set statusline=%!MyStatusLine()
可以设置 g:statusline_winid
变量指定该 status line 作用于哪个 window.
1 |
|
如果设置后 status line 没更新, 可手动更新:
1 |
|
跳转到 help manual 中的标签
用 Ctrl+]
.
v:statusmsg 变量
其会保存上一次的 status message. 比如在 hello.sh
文件中进行保存操作, 其会输出如 “hello.sh 117L, 4700B written” 这个信息, 其就会被保存在 v:statusmsg
这个变量中.
verbose 命令
:verbose
命令用于显示当前正在执行的某个命令的详细信息,包括该命令是如何被触发的.
可以通过设置 verbose
这个 option 来开启,
在设置 verbosefile
选项后, verbose
的输出内容会输出到指定文件中 (默认关闭文件时才会写入).
跳转
回到上一次跳转的位置:使用 Ctrl + O
或者 :jumplist -
命令。
回到下一次跳转的位置:使用 Ctrl + I
或者 :jumplist +
命令。
Ctrl + ]
可以跳转到光标所在位置的定义或引用,而 Ctrl + T
则用于返回到之前的位置
使用技巧
change list 和 jump list
g;
可以回到上次被修改的位置.
g,
到下一处被修改的位置.
同时都可以加量词, 如 2g;
查看 change list: :changes
查看 jump list: :jumps
ctrl+o
跳转到前一个 jump.
ctrl+i
跳转到后一个 jump.
应用正则表达式
使用 match()
, matchstr()
等函数.
光标的位置
使用 getcurpos()
.
用 Vimscript 插入文本
结合 execute
, normal
命令, 如:
1 |
|
将一个字符串重复 N 次
使用 repeat()
, 如:
1 |
|
使用正则表达式的捕获
如:
1 |
|
捕获用的括号需要转义为 \( \)
.
对一个变量使用 substitute
使用 substitute()
, 具体看 :h substitute()
.
这里面的捕获型要写成 \\1
编写统计汉字
将一串字符分隔为一个一个的字符
1 |
|
其返回值是列表, 每一个元素是一个字符.
求一个字符的 utf-8 的 number
1 |
|
其返回值是一个数字.
总流程
1 |
|
这里定义 unicode 大于 0x2000
的为汉字.
获得一个目录下的所有文件
使用 globpath()
函数。注意该函数返回的是 string 而不是 list.
如获得当前目录下的所有文件:
1 |
|
且为全路径.
关于 normal d
单纯的:
1 |
|
并不会删除文本,只是将其剪切到 "
寄存器中,需要删除文本,用:
1 |
|
用 source 命令加载一个存储在变量中的文件名
结合 exec
命令和 expand()
函数, 如:
1 |
|
即可.
关于函数的参数
使用如:
1 |
|
注意, 在定义函数时没有加 a:
, 而在使用函数时用了 a:
.
关于 list 列表赋值
如:
1 |
|
注意这里的 \
, 不加反斜线就会报错.
获取列表的长度
使用 len()
命令行参数
位于列表 v:argv
中.
打开光标下的 url
使用 gx
选中行的范围表示
'<
表示选中的第一行.
'>
表示选中的最后一行.
'<'>
表示选中的所有行.
判断是否位于折叠之中
在 Vim 中,可以使用 foldclosed() 函数和 foldclosedend() 函数来判断光标是否位于一个折叠中。
foldclosed() 函数返回当前行所在的折叠的开始行号(如果当前行不在任何折叠中,则返回 -1)。
foldclosedend() 函数返回当前行所在的折叠的结束行号(如果当前行不在任何折叠中,则返回 -1)。
可以将这两个函数结合使用,来判断光标是否位于一个折叠中。如果 foldclosed()
和 foldclosedend()
函数都返回大于等于 0 的值,则说明当前行位于一个折叠中。