Jump to content

Learning the vi Editor/Vim/VimL Script language

From Wikibooks, open books for an open world

Learning the vi Editor: Getting acquaintedBasic tasksMaking your work easierAdvanced tasksDetailsVi clones (VimBasic navigationModesTips and TricksUseful things for programmers to knowEnhancing VimVim on WindowsVimL Script language, Vile, BB vi)vi Reference

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

Statements

[edit | edit source]

Assignment

[edit | edit source]

To set a variable use:

let variable = expression

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

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

Data types

[edit | edit source]

There are five datatypes:

Number

[edit | edit source]

A 32 bit signed integer.

String

[edit | edit source]

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:

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

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

Funcref

[edit | edit source]

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

let Function_1 = function ("MyFunc")

An ordered sequence of items.

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

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

let List_2 = split ("a b c")

Dictionary

[edit | edit source]

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

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

Objects

[edit | edit source]

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

let mydict = {
    \'data': [0, 1, 2, 3]}

function mydict.len () dict
   return len (self.data)
endfunction mydict.len

for more information see Object oriented programming

Control Structures

[edit | edit source]

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

[edit | edit source]
if condition
    operations
elseif condition
    operations 
else
    operations 
endif

while

[edit | edit source]
while condition
    operations
endwhile

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

for var in list
    operations
endfor

exceptions

[edit | edit source]
try
    operations
catch /pattern/
    error handling operations
finally
    clean-up operations
endtry

Subprograms

[edit | edit source]

Simple Subprograms

[edit | edit source]

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

runtime setup.vim
source  ~/vimfiles/setup.vim

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

Functions

[edit | edit source]
function f ( parameter )
    operations
endfunction

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

[edit | edit source]
command Command Command

Command are often used as shortcut for functions and subprograms:

command C -nargs=* call F ( <f-args> )
command C source ~/vimfiles/s.vim

Object oriented programming

[edit | edit source]

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

[edit | edit source]

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

if exists ("g:loaded_gnat_autoload") || version < 700
    finish
else
   let 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.

   function gnat#Make () dict
      ...
      return
   endfunction gnat#Make

   function gnat#Pretty () dict
      ...
      return
   endfunction gnat#Pretty

   function gnat#Find () dict
      ...
      return
   endfunction gnat#Find

   function gnat#Tags () dict
      ...
      return
   endfunction gnat#Tags

   function gnat#Set_Project_File (...) dict
      ...
      return
   endfunction gnat#Set_Project_File

   function gnat#Get_Command (Command) dict
      ...
      return ...
   endfunction gnat#Get_Command

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":

   function gnat#New ()

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

      let Retval = {
	 \ 'Make'	      : function ('gnat#Make'),
	 \ 'Pretty'	      : function ('gnat#Pretty'),
	 \ 'Find'	      : function ('gnat#Find'),
	 \ 'Tags'	      : function ('gnat#Tags'),
	 \ 'Set_Project_File' : function ('gnat#Set_Project_File'),
	 \ 'Get_Command'      : function ('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:

      if argc() == 1 && fnamemodify(argv (0), ':e') == 'gpr'
	 call Retval.Set_Project_File(argv(0))
      elseif  strlen(v:servername) > 0
	 call Retval.Set_Project_File(v:servername . '.gpr')
      endif

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

      return Retval
   endfunction gnat#New

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.

   function gnat#Insert_Tags_Header()
      ...
      return
   endfunction gnat#Insert_Tags_Header

   finish
endif


Learning the vi Editor: Getting acquaintedBasic tasksMaking your work easierAdvanced tasksDetailsVi clones (VimBasic navigationModesTips and TricksUseful things for programmers to knowEnhancing VimVim on WindowsVimL Script language, Vile, BB vi)vi Reference