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