Vim技能修炼教程(12) - Vim的脚本语言支持

时间:2022-03-25 14:00:15

Vim的脚本语言支持

本节开始,我们正式接触vimscript这门古老的脚本语言。
首先要说明,vim支持的扩展语言很多,比如python, python3, ruby, lua,tcl等常见脚本语言都有很好的支持。既可以支持脚本内嵌在.vimrc中,也可以执行python等脚本语言的文件。
运行:version命令就可以看到当前的vim发行版本持哪些扩展语言:

VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Jun 22 2017 03:02:45)
MacOS X (unix) version
Included patches: 1-648
Compiled by travis@Traviss-Mac-712.local
Huge version with MacVim GUI. Features included (+) or not (-):
+acl +cmdline_compl +digraphs +folding +lambda +mouse +multi_lang +profile +statusline +timers +wildignore
+arabic +cmdline_hist +dnd -footer +langmap +mouseshape -mzscheme +python/dyn -sun_workshop +title +wildmenu
+autocmd +cmdline_info -ebcdic +fork() +libcall +mouse_dec +netbeans_intg +python3/dyn +syntax +toolbar +windows
+balloon_eval +comments +emacs_tags +fullscreen +linebreak -mouse_gpm +num64 +quickfix +tag_binary +transparency +writebackup
+browse +conceal +eval -gettext +lispindent -mouse_jsbterm +odbeditor +reltime +tag_old_static +user_commands -X11
++builtin_terms +cryptv +ex_extra -hangul_input +listcmds +mouse_netterm +packages +rightleft -tag_any_white +vertsplit -xfontset
+byte_offset +cscope +extra_search +iconv +localmap +mouse_sgr +path_extra +ruby/dyn -tcl +virtualedit +xim
+channel +cursorbind +farsi +insert_expand +lua/dyn -mouse_sysmouse +perl/dyn +scrollbind +termguicolors +visual -xpm
+cindent +cursorshape +file_in_path +job +menu +mouse_urxvt +persistent_undo +signs +terminfo +visualextra -xsmp
+clientserver +dialog_con_gui +find_in_path +jumplist +mksession +mouse_xterm +postscript +smartindent +termresponse +viminfo -xterm_clipboard
+clipboard +diff +float +keymap +modify_fname +multi_byte +printer +startuptime +textobjects +vreplace -xterm_save

比如我用的macVim,就支持python, python3, ruby, lua, perl等但是不支持tcl.

但是,不管是什么样的vim版本,都一定支持vimscript。我们先看看各种语言的用法,最后还是得学习vimscript

Python语言编写vim插件

:python命令的用法

单行语句可以使用 :python {单行语句}的格式
多行语句使用

:python << EOF
多行python语句
EOF

也可以将python代码写到文件,然后通过:pyfile命令来加载。

首先需要引入vim包:

        :python import vim

执行ex命令

通过vim.command函数执行ex命令:

        :py vim.command(cmd)            # execute an Ex command

例:

:py vim.command(":normal! 2j")

这个大家已经很熟悉了,模拟正常模式下的2个j.

窗口相关

  • vim.current.window: 获取当前窗口
  • vim.windows[n]:获取第n个窗口
        :py w = vim.windows[n]          # gets window "n"
:py cw = vim.current.window # gets the current window

获取窗口对象之后,就可以针对窗口进行操作:
* height属性是窗口高度
* width: 宽度
* cursor属性设置光标在窗口中位置
* buffer: 窗口中的缓冲区

        :py w.height = lines            # sets the window height
:py w.cursor = (row, col) # sets the window cursor position
:py pos = w.cursor # gets a tuple (row, col)

缓冲区相关

所有的文本都是跟缓冲区相关的。

  • vim.current.buffer可获取当前缓冲区
  • vim.buffers[n] : 获取第n号缓冲区
        :py b = vim.buffers[n]          # gets buffer "n"
:py cb = vim.current.buffer # gets the current buffer

获取缓冲区之后,我们就可以对文本进行操作了。

  • name: 缓冲区名字,一般就跟文件名一样
  • append: 添加行
  • mark: 标记一块
  • range: 获取一个范围

缓冲区获取以后,就可以当成数组一样的访问,去处理其中的文本。
如下面的例子:

        :py name = b.name               # gets the buffer file name
:py line = b[n] # gets a line from the buffer
:py lines = b[n:m] # gets a list of lines
:py num = len(b) # gets the number of lines
:py b[n] = str # sets a line in the buffer
:py b[n:m] = [str1, str2, str3] # sets a number of lines at once
:py del b[n] # deletes a line
:py del b[n:m] # deletes a number of lines
:py b.append("bottom") # add a line at the bottom
:py n = len(b) # number of lines
:py (row,col) = b.mark('a') # named mark
:py r = b.range(1,5) # a sub-range of the buffer

current对象

对于大部分情况,我们所操作的都是当前对象:
* vim.current.line: 当前行
* vim.current.buffer 当前缓冲区
* vim.current.window 当前窗口
* vim.currrent.range 当前选中的范围

python3

python 3.x的支持是另外一个不同的模块。其用法和python基本一致。

ruby语言编写vim插件

来上个例子:

  :ruby print VIM::Window.count 

执行ex命令

        VIM.command(cmd)                      # execute an Ex command

窗口相关

        num = VIM::Window.count               # gets the number of windows
w = VIM::Window[n] # gets window "n"
cw = VIM::Window.current # gets the current window
w.height = lines # sets the window height
w.cursor = [row, col] # sets the window cursor position
pos = w.cursor # gets an array [row, col]

缓冲区相关

        num = VIM::Buffer.count               # gets the number of buffers
b = VIM::Buffer[n] # gets buffer "n"
cb = VIM::Buffer.current # gets the current buffer
name = b.name # gets the buffer file name
line = b[n] # gets a line from the buffer
num = b.count # gets the number of lines
b[n] = str # sets a line in the buffer
b.delete(n) # deletes a line
b.append(n, str) # appends a line after n
line = VIM::Buffer.current.line # gets the current line
num = VIM::Buffer.current.line_number # gets the current line number
VIM::Buffer.current.line = "test" # sets the current line number