Learning the vi Editor/Vim/VimL Script language

Vim script (aka Vimscript, or VimL) is a full feature scripting language, meaning it can solve almost any text processing problem.

Assignment
To set a variable use:

variable = expression

To set a built-in setting you have two options:

setting = expression    " (use the regular command for changing a setting)   &setting = "expression"  " (treat the setting as a special kind of variable)

Data types
There are five datatypes:

Number
A 32 bit signed integer.

String
A NULL terminated string of 8-bit unsigned characters (bytes). Strings can be created by either ‘'’ or ‘"’ quotes. When using strings quoted with the double quote ‘"’ the text is interpreted i.e. "\n" becomes a new line while strings quoted with a single quote ‘'’ are not interpreted, i.e. '\n' means just that, a backslash and an n. The following two strings are identical:

String_1 = "C:\\WinNT" String_2 = 'C:\WinNT'

Any other datatype can be converted into a string using the  function.

Funcref
A reference to a function. A Funcref can be created from a string by the use of the function.

Function_1 = ("MyFunc")

List
An ordered sequence of items.

List_1 = [ \ "a", \ "b", \ "c"]

A list can be created from a string by the use of the function.

List_2 = ("a b c")

Dictionary
An associative, unordered array: Each entry has a key and a value.

Dictionary_1 = { \ 1: 'one', \ 2: 'two', \ 3: 'three'}

Objects
VIM also supports object oriented programming by combining and  to an Object:

mydict = { \'data': [0, 1, 2, 3]} dict (self.data)

for more information see Object oriented programming

Control Structures
The existence of control structures is the main difference between vi's ex commands and vim's scripting language. They make the difference between a simple command set (vi) and a full features script language (vim).

condition
condition operations condition operations operations

while
condition operations

for
For loops are available from vim 7 onwards. They iterate over List or Directory structures.

var list operations

exceptions
operations /pattern/ error handling operations clean-up operations

Simple Subprograms
Like most Shell-Languages all subprograms are stored in separate files which you load either with the or  command. The difference lies in the use of a search path. uses a search path and allows wildcards to find the sub-program while needs the full path. The following commands do the same - provided that "~/vimfiles" is part of your runtime search path:

setup.vim ~/vimfiles/setup.vim

For both commands need to add the  extension. Since supports both a search path and wildcards more than one match is possible. If you want to load all the matches - and not just the first hit - use.

Functions
f ( parameter ) operations

New with vim 7 is the autoload option for functions. If you name a function Filename#Functionname or Directory#Filename#Functionname then the function will be automatically loaded on first call. The file containing the function must be placed in one of the "autoload" runtime directories and be named "Filename.vim" or "Directory/Filename.vim". This option is especially useful for functions which you don't always need on in Object oriented programming.

Commands
Command Command

Command are often used as shortcut for functions and subprograms:

C -nargs=* F (  ) C ~/vimfiles/s.vim

Object oriented programming
Vim 7 now allows object oriented programming. However, in order to make it real you need to combine several features, namely Dictionaries, Funcrefs and the new function autoload.

The following example class is taken from the gnat compiler plugin for vim. The actual functions implementations have been removed as they are not needed to understand the concept. If you like to have a look at the full version you can download the plugin from vim.org site.

Step by Step walk-through
We add our new class to a autoload script. That way the class is available when and only when needed:

("g:loaded_gnat_autoload") || version < 700 g:loaded_gnat_autoload=1

Each function we define need to be defined with the "dict" attribute. Apart from that they are just normal scripting functions.

dict ...    gnat#Make dict ...    gnat#Pretty dict ...    gnat#Find dict ...    gnat#Tags (...) dict ...     (Command) dict ...       ...

The most important step is the composition of the object. In most OO languages this happens automatically - But with vim we have to do this ourselves. For best flexibility the use of a so called constructor function is suggested. The constructor is not marked with "dict":



The constructor creates a dictionary which assigns all the object functions to one element of the dictionary:

Retval = { \ 'Make'	     :  ('gnat#Make'), \ 'Pretty'	     :  ('gnat#Pretty'), \ 'Find'	     :  ('gnat#Find'), \ 'Tags'	     :  ('gnat#Tags'), \ 'Set_Project_File' : ('gnat#Set_Project_File'), \ 'Get_Command'     :  ('gnat#Get_Command'), \ 'Project_File'    : '' ,

We optionally can now add data entries to our object:

\ 'Make_Command'    : '"gnat make -P ". self.Project_File. " -F -gnatef  "', \ 'Pretty_Command'  : '"gnat pretty -P ". self.Project_File. " "', 	 \ 'Find_Program'    : '"gnat find -P ". self.Project_File. " -F "', \ 'Tags_Command'    : '"gnat xref -P ". self.Project_File. " -v *.AD*"', \ 'Error_Format'    : '%f:%l:%c: %trror: %m,'. \ '%f:%l:%c: %tarning: %m,'. \ '%f:%l:%c: (%ttyle) %m'}

If needed additional modifications to the object are also possible. At this stage you can already use the OO-way:

== 1 && ( (0), ':e') == 'gpr' (argv(0)) (v:servername) > 0 (v:servername . '.gpr')

The last operation of the constructor is the return of the newly created object. Retval

It is also possible to defined additional non dict functions. These functions are the equivalent to the "static" or "class" methods of other OO languages. ...