Référence rapide

Aide-mémoire Vimscript

Un guide de référence complet pour Vimscript : variables, fonctions, commandes personnalisées, structures de données, raccourcis et coloration.

· Publié le

Vimscript est le langage de script intégré pour personnaliser et étendre l'éditeur de texte Vim.

Premiers pas

let name = "John"
echo "Hello, " . name

Vous pouvez enregistrer ce code dans un fichier (script.vim) et le charger avec (:source script.vim), ou exécuter directement des commandes via :let et :echo.

Apprendre par l'exemple

function! SuperTab()
  let l:part = strpart(getline('.'), col('.') - 2, 1)
  if (l:part =~ '^\W\?$')
    return "\<Tab>"
  else
    return "\<C-n>"
  endif
endfunction

imap <Tab> <C-R>=SuperTab()<CR>

Variables

Définition

let var = "hello"

Préfixes de portée des variables

let g:ack_options = '-s -H'    " g: global
let s:ack_program = 'ack'      " s: local (to script)
let l:foo = 'bar'              " l: local (to function)
let a:arg = 'baz'              " a: function argument

Le préfixe s: peut aussi être utilisé pour les fonctions locales au script. Voir :help local-variables.

Autres portées

let w:foo = 'bar'    " w: window local
let b:state = 'on'   " b: buffer local
let t:state = 'off'  " t: tab page local
echo v:version       " v: vim internal variable
let @/ = ''          " @  register
echo $PATH           " $  environment variable

Options Vim

echo 'tabstop is ' . &tabstop
if &insertmode
echo &g:option
echo &l:option

Préfixez les noms d'options par & pour les lire ou les modifier dans des expressions.

Opérateurs arithmétiques et de chaînes

a + b             " Numbers only!
'hello ' . name   " String concatenation
let var -= 2
let var += 5
let var .= 'string'

Chaînes de caractères (Strings)

Syntaxe des chaînes

let str = "String"
let str = "String with \n newline"

let literal = 'literal, no \ escaping'
let literal = 'that''s enough'

echo "result = " . res

Fonctions sur les chaînes

strlen(str)
len(str)
strchars(str)

split("one two three")       "=> ['one', 'two', 'three']
split("one.two.three", '.')  "=> ['one', 'two', 'three']

join(['a', 'b'], ',')        "=> 'a,b'

tolower('Hello')
toupper('Hello')

Fonctions

Définition de fonction

function! s:Initialize(cmd, args)
  echo "Command: " . a:cmd
  return 1
endfunction

Remplacement de fonctions

function! MyFunc()
  echo "Function defined or replaced"
endfunction

L'utilisation de function! (avec !) remplace sans erreur toute fonction précédemment définie avec le même nom.

Espaces de noms & Chargement automatique (Autoload)

function! myplugin#hello()
  " autoload/myplugin.vim
endfunction

Appel de fonctions

call s:Initialize()
call s:Initialize("hello", 123)

Récupération des valeurs de retour

let result = s:Initialize()

Arrêt immédiat en cas d'erreur (Abort)

function! MyFunction() abort
endfunction

Arguments variadiques

function! Infect(...)
  echo a:0
  echo a:1
  echo a:2

  for item in a:000
    echon ' ' . item
  endfor
endfunction

call Infect('jake', 'bella')

Boucles & Contrôle de flux

Boucles (Loops)

for s in list
  echo s
  continue
  break
endfor
while x < 5
  let x += 1
endwhile

Commandes personnalisées (Custom Commands)

Définition de commandes

command! Save :set fo=want tw=80 nowrap

Les commandes utilisateur doivent commencer par une majuscule. Le point d'exclamation ! permet de remplacer une commande existante.

Appel de fonctions dans les commandes

command! Save call <SID>Foo()

function! s:Foo()
endfunction

Arguments de commandes

command! -nargs=? Save call script#foo(<args>)
Spécification d'argument Description
-nargs=0 0 argument (par défaut)
-nargs=1 Exactement 1 argument (peut contenir des espaces)
-nargs=? 0 ou 1 argument
-nargs=* 0 ou plusieurs arguments séparés par des espaces
-nargs=+ 1 ou plusieurs arguments séparés par des espaces

Conditions (Conditionals)

If / Elseif / Else

let char = getchar()
if char == "\<LeftMouse>"
elseif char == "\<RightMouse>"
else
endif

Évaluation booléenne (Truthiness)

if 1       "=> True
if 0       "=> False
if "1"     "=> True
if "456"   "=> True
if "xfz"   "=> False

Vimscript ne possède pas de type booléen autonome : 0 est faux et tout entier non nul est vrai.

Opérateurs de comparaison

if 3 > 2
if a && b
if (a && b) || (c && d)
if !c

Sensibilité à la casse des chaînes

if name ==# 'John'     " case-sensitive
if name ==? 'John'     " case-insensitive
if name == 'John'      " &ignorecase

Comparaison d'identité

if a is b
if a isnot b

Vérifie si a et b référencent exactement la même instance de données.

Correspondances par expressions régulières

"hello" =~ 'xx*'
"hello" !~ 'xx*'
"hello" =~ '\v<\d+>'

\v active la syntaxe 'very magic', permettant les caractères spéciaux sans échappement lourd.

Instructions sur une seule ligne

if empty(a:path) | return [] | endif
let status = a ? b : c

Utilisez | pour enchaîner plusieurs instructions sur une même ligne.

Structures de données

Listes (Lists)

let mylist = [1, "two", 3, "four"]

let first = mylist[0]
let last  = mylist[-1]

let second = get(mylist, 1)
let fallback = get(mylist, 10, "NONE")

Opérations sur les listes

len(mylist)
empty(mylist)

let sortedlist = sort(copy(mylist))

let shortlist = mylist[2:-1]
let shortlist = mylist[2:]
let single = mylist[2:2]

let longlist = mylist + [5, 6]
let mylist += [7, 8]
call add(mylist, 9)

Méthodes fonctionnelles de listes

call map(files, "bufname(v:val)")
call filter(files, 'v:val != ""')

Dictionnaires (Dictionaries)

let colors = {
  \ "apple": "red",
  \ "banana": "yellow"
}

echo colors["apple"]
echo get(colors, "apple")

Opérations sur les dictionnaires

call remove(colors, "apple")

if has_key(dict, 'foo')
if empty(dict)
let k = keys(dict)
let v = values(dict)
let n = len(dict)

echo max(dict)
echo min(dict)

call extend(s:fruits, { "cherry": "red" })
for key in keys(mydict)
  echo key . ': ' . mydict[key]
endfor

Les préfixes de portée (s:, g:, l:, b:) sont eux-mêmes accessibles sous forme de dictionnaires :

let script_keys = keys(s:)

Nombres & Arithmétique

let int = 1000
let hex = 0xff
let oct = 0755
let fl = 100.1
let sci = 5.4e4
3 / 2     "=> 1
3 / 2.0   "=> 1.5
sqrt(100)
floor(3.5)
ceil(3.3)
abs(-3.4)

Spécificités de Vim

Exécution dynamique de commandes (execute)

execute "vsplit"
execute "edit " . fnameescape(filename)

Touches en mode normal (normal)

normal G
normal! G

execute "normal! gg/foo\<cr>dd"

Expansion des noms de fichiers

echo expand("%")      " path/file.txt
echo expand("%:t")    " file.txt
echo expand("%:p:h")  " /home/user/path
echo expand("%:r")    " path/file
echo expand("%:e")    " txt

Contrôle des sorties et messages

silent g/pattern/p

echo 'Simple text'
echomsg 'Persistent text recorded in :messages'
echoerr 'Error message'

echohl WarningMsg | echomsg "=> Warning!" | echohl None

Options de configuration

set number
set nonumber
set number!
set numberwidth=5
set guioptions+=e

Introspection & Détection de fonctionnalités

has("clipboard")
executable("python3")
globpath(&rtp, "syntax/c.vim")

exists("$ENV")
exists(":command")
exists("variable")
exists("+option")

Mappages de touches (Key Mappings)

Modes

[nvixso](nore)map

Options de mappage courantes

Option (Flag) Signification
<buffer> Local au buffer courant uniquement
<silent> Ne pas afficher la commande dans la barre d'état
<nowait> Déclencher immédiatement sans attendre

Coloration syntaxique & Masquage (Conceal)

Groupes de surbrillance

hi Comment term=bold gui=bold ctermfg=4 guifg=#80a0ff
hi def link markdownH1 htmlH1

Détection du type de fichier

augroup filetypedetect
  au! BufNewFile,BufRead *.json setf javascript
augroup END

au Filetype markdown setlocal spell

Masquage de texte (Conceal)

set conceallevel=2
syn match newLine "<br>" conceal cchar=}
hi newLine guifg=green

Gardes d'inclusion

if exists('g:loaded_myplugin')
  finish
endif
let g:loaded_myplugin = 1

Sujets associés