Vim

Published: 11-07-2015

Updated: 16-11-2018

By: Maxime de Roucy

tags: vim

Pense-bête vim.

help

On peut naviguer dans l’aide à l’aide de la sourie, ou du clavier.

direction

.vimrc

Mon fichier ~/.vimrc.

" gestion du dossier ~/.vim/template
augroup templates
	" delete all others autocmd in this group
	autocmd!
	" read in template files
	autocmd BufNewFile *.* silent! execute '0read ~/.vim/templates/skeleton.'.expand("<afile>:e")

	" parse special text in the templates after the read
	autocmd BufNewFile * %substitute#\[:VIM_EVAL:\]\(.\{-\}\)\[:END_EVAL:\]#\=eval(submatch(1))#ge
	" goto first line
	autocmd BufNewFile * 1
augroup END

" insert the current date in the "lastmod" metadata in .md files
fun LastMod()
	if line("$") > 10
		let l = 10
	else
		let l = line("$")
	endif
	exe "1," . l . "g/lastmod = /s/\".*\"/\"" . strftime("%Y-%m-%d") . "\""
endfun
autocmd BufWritePre,FileWritePre *.md kw|call LastMod()|'w
" kw : marque la position courante (enregistré sous le nom « w »)
" 'w : retourne à « w »

" b: variable local to the current buffer
" v: variable global, predefined by Vim
function! MarkdownLevel()
	if getline(v:lnum) =~ '^```'
		if b:md_codeblock == 0
			let b:md_codeblock = 1
		else
			let b:md_codeblock = 0
		endif
	endif

	if b:md_codeblock == 1
		return "="
	elseif getline(v:lnum) =~ '^# .*$'
		return ">1"
	elseif getline(v:lnum) =~ '^## .*$'
		return ">2"
	elseif getline(v:lnum) =~ '^### .*$'
		return ">3"
	elseif getline(v:lnum) =~ '^#### .*$'
		return ">4"
	elseif getline(v:lnum) =~ '^##### .*$'
		return ">5"
	elseif getline(v:lnum) =~ '^###### .*$'
		return ">6"
	endif

	return "="
endfunction
autocmd FileType markdown let b:md_codeblock = 0
autocmd FileType markdown setlocal foldexpr=MarkdownLevel()
" Attention au CPU
" http://vim.wikia.com/wiki/Keep_folds_closed_while_inserting_text
autocmd FileType markdown nnoremap f :setlocal foldmethod=expr<CR>
autocmd FileType markdown nnoremap F :setlocal foldmethod=manual<CR>

autocmd FileType markdown set linebreak

" json
autocmd FileType json set tabstop=4 shiftwidth=4

" yaml
autocmd filetype yaml set tabstop=2 shiftwidth=2 expandtab

" in insert mode
" «  → «~
inoremap « « 
"  » → ~»
inoremap »  »
" :) → ☺
iabbrev :) ☺

" http://www.polarhome.com/vim/manual/v57/options.html#%27timeoutlen%27
"set timeoutlen=1000
"set ttimeoutlen=0

""" neovim
set clipboard+=unnamedplus

Liens utils pour la compréension :

Commenter un bloque de text

  1. Ctrl+v
  2. selection du bloc de text à commenter
  3. Shift+i
  4. ajout de la marque de commentaire (eg. #, //, "…)
  5. Escape

commande shell

Éxecution d’une commande à partir de vim :

:shell
lance un shell et revient à vim lorsque celui-ci s’arrête
:! macommande
lance « macommande » directement dans vim

affichage de caractère non imprimable

Une autre méthode pour faire ressortir les espace insécable est décrite dans la section highlight espace insécable.

Pour afficher des caractère non imprimable j’utilise l’option list, même si d’autre solutions sont disponibles.

list à l’avantage d’être facilement activable ou désactivable via :set list!.

Il affiche tous les caractères non imprimable avec des ^. Par exemple une tabulation sera affichée ^I.

On peut changer l’affichage de certains éléments avec l’option « listchars ». Par exemple :

set listchars=eol:$,tab:>-,trail:→,nbsp:~,extends:>,precedes:<

Par défaut listchars=eol:$ mais les tabulation sont affiché avec ^I. Pour désactiver l’affichage des tabulation on peut utiliser tab:\ \ (« tab » attend 2 caractères).

highlight espace insécable

Source : Highlight non-breaking space in VIM, different behavior between command and .vimrc

:syntax match ErrorMsg " "

Dans un vimrc :

autocmd VimEnter,BufWinEnter * syntax match ErrorMsg " "

Ajout d’espace avant et après des guillemets

Pour ça j’utilise inoremap. « i » pour indiqué que le mapping ne se fait qu’en mode « INSERTION ». « noremap » qui permet de mapper un caractère avec une séquence.

« noremap » à la différence de « map » empèche le mapping récursif. C’est important ici car j’utilise le charactère « dans la séquence mappée sur «.

" in insert mode
" « → «~
inoremap « «  
" » → ~»
inoremap »  »

Abbreviation

À chaque fois que je tape « :) » je veux que vim remplace cette chaine de caractère par « ☺ ». Pour ça j’utilise les abréviations.

" :) → ☺
iabbrev :) ☺

« iabbrev » permet de ne rendre l’abréviation opérante que dans le mode « INSERTION ». Pour que ça fonctionne il faut que je tape [non-alpha]:)[non-alpha]. Pour empécher l’abréviation il suffit de tapper « Ctrl-V » avant le deuxième caractère non alphanumérique.

indentation

Source: How to Write a Vim Indent Script: A Pascal Example

La fonction d’indentation suivante permet d’indenter (avec des espaces) un fichier de configuration keepalived.

function! KeepalivedIndent()
    " if we are at the first line → indentation level = 0
    if v:lnum == 0
        return 0
    endif

    " search the indentation level of the first previous non blank line
    let nline = prevnonblank(v:lnum - 1)
    let indent_nb_space = indent(nline)

    " if the current line end with } → decrement the indentation level
    if getline(v:lnum) =~ '}$'
        return indent_nb_space - &shiftwidth

    " if the first previous non blank line end with { → increment the indentation level
    elseif getline(nline) =~ '{$'
        return indent_nb_space + &shiftwidth
    endif

    return indent_nb_space
endfunction

Pour activer cette fonction d’indentation : set indentexpr=KeepalivedIndent()

alignement

Source : Simple text alignment

Aligne le premier caractère « = » des lignes 2 à 3 sur la column 10.

:2,3norm 0f=10i<Space><ctrl-v><Esc>d10|

<Space><ctrl-v><Esc> ne sont pas à écrire tel quel, mais sont les touches à entrer (eg. <Space> → appuie sur la barre d’espace).

Explication :

Avant :

aa = b
a = b
aaaaa = b

Après :

aa = b
a         = b
aaaaa     = b

Autre exemple : :%norm 60|f$10i ^[d67|

Avant :

ipt -s "${client}"            -p tcp -m multiport --dports 80,443 $accept # toto
ipt -s "${client}" -d 1.2.3.4 -p tcp -m multiport --dports 10022 $accept # titi
ipt -s "${client}" -d 1.2.3.5 -p tcp -m multiport --dports 2222 $accept # tata

Apres :

ipt -s "${client}"            -p tcp -m multiport --dports 80,443 $accept # toto
ipt -s "${client}" -d 1.2.3.4 -p tcp -m multiport --dports 10022  $accept # titi
ipt -s "${client}" -d 1.2.3.5 -p tcp -m multiport --dports 2222   $accept # tata

modeline

Source : Modeline magic

Un « modeline » est un commentaire qui doit être placé en première ou dernière ligne d’un fichier. Il contient des commandes vim qui seront executé à l’ouverture du fichier si l’option « modeline » est activé dans vim.

L’option « modeline » est activé par default par la plupart des distribution, si vim est en mode « nocompatible » et que l’utilisateur courant n’est pas root.

Exemples :

# vim: set expandtab tabstop=4 shiftwidth=4 :
# vim: set noexpandtab :

macro

Source : Vim - un pas en avant

Les macro permette d’enregistrer une suite d’action et la rejoué facilement.

ruler

Le ruler est l’élément qui affiche le numéro de ligne et de colonne en bas à droite de la fenêtre.

:set ruler

commande en vrac

:r monfichier
ajout du contenu d’un fichier à l’emplacement du curseur
:e monfichier
quite le fichier courant et ouvre « monfichier »
:vsplit monfichier
ouvre monfichier dans un nouveaux panneaux
:echo glob($VIMRUNTIME . '/syntax/*.vim')
list tous les « filetype » disponible
Crtl+L
redessine l’écran
:set diffopt+=iwhite
dans vimdiff (vim -d), indique qu’il ne faut pas prendre en compte les différences d’espacement
:echo @%
print le nom du fichier en train d’être édité. % est un registre contenant le nom du fichier, @ permet d’accéder au contenu d’un registre comme si s’était une variable
:w ! sudo tee %
enregistre le fichier courant en temps que root
vi"
sélectionne tout les caractère présent entre le précédent " et le " suivant, les " n’étant pas inclue (on peut remplacer " par ', `…), cf. visual operators
f"
aller au " suivant (" peut être remplacer par n’importe quel caractère)
t"
aller au caractère précédent le " suivant (un caractère avant f")
dt"
supprime tout jusqu’au " suivant, non inclue
'.
aller au début de la dernière ligne édité (. est un marqueur)
`.
aller au dernier endroit édité (. est un marqueur)
:g/toto/d
supprime les ligne contenant le pattern “toto”