Skip to content

Instantly share code, notes, and snippets.

@romainl
Last active April 9, 2022 11:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save romainl/edd054cf7c07436c2c0c35cc61a184e6 to your computer and use it in GitHub Desktop.
Save romainl/edd054cf7c07436c2c0c35cc61a184e6 to your computer and use it in GitHub Desktop.
Quelques notes prises au fur et mesure de mon apprentissage, de fin 2009 à fin 2011.

1

Déplacer le curseur

H : en haut de l’écran

M : au milieu de l’écran

L : en bas de l’écran

Déplacer l’écran pour que la ligne actuelle se retrouve

zt : en haut de l’écran

zz : au milieu de l’écran

zb : en bas de l’écran

2

Si les lignes d’une fonction sont mal indentées, utiliser

>iB

ou

>aB

pour inclure les {}

Genre 3 touches au lieu de je sais pas combien. Wow !

3

:bd

pour fermer un buffer sans fermer la fenêtre de MacVim.

4

/ pour chercher vers le bas

? pour chercher vers le haut

5

Pour aller plus loin avec les mouvements, i (in) et a (around ?) fonctionnent en conjonction avec v (visual), y (yank), d (delete) et c (change).

vit pour sélectionner le contenu d’un tag HTML

vat pour le sélectionner en entier, afin de le déplacer par exemple

dit pour effacer le contenu d’un tag HTML

dat pour l’effacer en entier

cit pour effacer le contenu d’un tag HTML et passer en mode -- INSERT --

cat pour l’effacer en entier et passer en mode -- INSERT --

yit pour copier le contenu d’un tag HTML

yat pour le copier en entier

Ça fonctionne aussi avec ces délimiteurs :

'
"
<
(
[
{

C’est de la magie !

6

En mode -- NORMAL --, taper <C-w>f avec le curseur sur un nom de fichier pour l’ouvrir dans un split.

gf pour l’ouvrir en place.

7

<C-w><C-w>

permet de sauter de split en split.

Aussi, pour inverser leur ordre :

<C-w>r

8

<p>texte</p>
<p>texte</p>
<p>texte</p>

On sélectionne toutes les lignes puis on tape

:s/^/\r

pour obtenir

<p>texte</p>

<p>texte</p>

<p>texte</p>

10

:hide

ferme la fenêtre active.

:only

ferme toutes les fenêtres sauf la fenêtre active.

Dans les deux cas les buffers sont seulement cachés, ils restent en mémoire et on peut toujours y accéder avec :b or :sb.

11

<C-x><C-l>

permet de compléter une ligne !

12

On connaît

0 : aller au tout début de la ligne

^ : aller au premier caractère visible de la ligne

$ : aller au dernier caractère de la ligne

Mais on aime aussi avoir les lignes longues qui « wrappent » alors on utilise

g0
g^
g$

à la place. Ha oui ! Il y a aussi

gm

pour aller au milieu de la ligne.

13

Uiliser

:r /chemin/vers/un/fichier

pour coller contenu du fichier sous le curseur et

:r! commande

pour coller la sortie de la commande sous le curseur.

14

On peut utiliser

n{o/O}<Esc>

pour insérer n lignes vides après/avant la ligne actuelle, exemple :

1 une ligne de texte
2 une autre ligne de texte
3 
4 
5 
6 

Nous voulons 3 ligne vides en dessous de la première donc nous tapons :

5o<Esc>

et nous obtenons :

1 une ligne de texte
2
3 
4 
5 une autre ligne de texte
6

15

Quelques tips en vrac, en commençant par le mode « normal » :

<C-^>

permet de passer rapidement au dernier buffer visité.

<C-w>n

pour créer un split horizontal vide, et

<C-w>v

pour créer un split vertical vide.

En mode « insert » :

<C-w>

pour effacer le dernier mot tapé.

16

Pour mieux y voir, on peut taper :

zt

pour placer la ligne actuelle en haut de la fenêtre,

zz

pour placer la ligne actuelle en haut de la fenêtre ou

zb

pour placer la ligne actuelle en bas de la fenêtre.

17

Surround est incroyablement utile :

cst permet de remplacer une paire de tags :

<p>t|ext</p>

cst<div>

<div>text</div>

dst permet d’effacer une paire de tags :

<strong>sh|out!</strong>

dst

shout!

ysiw() permet de mettre le mot sous le curseur entre parenthèses.

etc.

18

Sur mon clavier AZERTY (Mac), le raccourci <C-]> est impossible à taper comme tel.

C’est <C-$> — la dernière touche de la ligne AZERTY — qu’il faut employer à la place.

19

LustyExplorer, Command-T est CtrlP sont cool pour naviguer dans les buffers (entre autres), mais on peut s’en approcher avec une commande native : :b — raccourci de :buffer — qui utilise un système de « tab-completion » intelligent.

Nous avons 4 buffers :

1  Emmanuelle.txt
2  Romain.txt
3  Wanda.txt
4  Merlin.txt

et nous sommes dans le buffer n°4.

Taper :b 2 nous amène au buffer n°2.

Mais on peut taper

:b em<Tab>

(la complétion n’est pas sensible à la casse) pour accéder au buffer n°1 ou

:b nd<Tab>

(n’importe quel bout du nom du buffer) pour aller au buffer n°3.

Pas mal.

Encore mieux avec set switchbuf=useopen,usetab qui permet de sauter directement au buffer sans le re-ouvrir dans la fenêtre actuelle.

On peut aller plus loin en utilisant ce raccourci trouvé sur /r/vim :

nnoremap <leader>ls :ls<CR>:sb<Space>

qui permet d’ouvrir une liste de buffers et de choisir très très vite sa cible.

20

On peut utiliser

<C-r><C-w>

pour placer le mot sous le curseur dans la ligne de commande.

21

Un que je viens d’apprendre en répondant à un commentaire sur SO :

:put=''

permet d’ajouter une ligne vide après la ligne actuelle sans passer en mode insert et son pendant :

:put!=''

permet d’ajouter une ligne vide avant la ligne actuelle.

22

Dans la fenêtre quickfix,

<C-w><CR>

permet d’ouvrir le fichier selectionné dans une nouvelle fenêtre.

23

En mode normal, taper <S-s> pour commencer à entrer du texte au bon niveau d’indentation.

24

Le motif

:%s/four/4/g

fonctionne pour four mais aussi pour carrefour.

:%s/\<four/4/g

fonctionne pour four et pas pour carrefour mais il fonctionne aussi pour fournil.

:%s/\<four\>/4/g

fonctionne uniquement pour four, hourra !

25

Supposons le texte :

<limit GET POST PUT>
order deny,allow
deny from 202.54.122.33
deny from 8.70.44.53
deny from .spammers.com
allow from all
</limit>

La commande

:g/deny /d

efface toutes les lignes contenant le motif deny (avec une espace), ce qui donne :

<limit GET POST PUT>
order deny,allow
allow from all
</limit>

La commande

:v/deny /d

efface toutes les lignes ne contenant pas le motif deny (avec une espace), ce qui donne :

deny from 202.54.122.33
deny from 8.70.44.53
deny from .spammers.com

La commande

:g/deny /m7

coupe toutes les lignes contenant le motif deny (avec une espace) et les place après la ligne 7, ce qui donne :

<limit GET POST PUT>
order deny,allow
allow from all
</limit>
deny from 202.54.122.33
deny from 8.70.44.53
deny from .spammers.com

La commande

:g/deny /t7

copie toutes les lignes contenant le motif deny (avec une espace) et les place après la ligne 7, ce qui donne :

<limit GET POST PUT>
order deny,allow
deny from 202.54.122.33
deny from 8.70.44.53
deny from .spammers.com
allow from all
</limit>
deny from .spammers.com
deny from 8.70.44.53
deny from 202.54.122.33

26

Pour transformer ceci :

betty bravo
cindy charlie
deana delta

en cela :

$mynames['betty'] = 'bravo';
$mynames['cindy'] = 'charlie';
$mynames['deana'] = 'delta';

On peut utiliser (entre autres) un unique chercher/remplacer :

:'<,'>s/^\(.*\) \(.*\)$/$myname['\1'] = '\2';

Où l’on capture deux morceaux de textes situés :

  • entre le début de la ligne (^) et l’espace du milieu ()

  • entre l’espace du milieu et la fin de la ligne($)

pour le remplacer par :

$mynames[' + \1 + '] = ' + \2 + ';

\1 représente le premier morceau et \2 le deuxième morceau.

27

Il existe plusieurs moyens de voir la signature d’une fonction:

  • en utilisant un plugin dédié (echofunc, etc.),

  • en utilisant cette fonctionnalité fournie par un plugin plus large (taglist, tagbar),

  • en utilisant les fonctionnalités natives de Vim.

Quel que soit le problème, je penche en général pour la solution la plus « lo-tech » qui consiste, en l’occurrence, à utiliser une fonctionalité native.

Il suffit de placer le curseur sur le nom de la fonction sur laquelle on veut des infos, puis de taper <C-w>}. Vim ouvre pour nous une fenêtre de type preview affichant la declaration de la fonction.

Le fait que la fenêtre soit de type preview a son importance car on peut la garder ouverte (elle ne prend pas beaucoup de place) et chaque <C-w>} subsequent re-utilisera cette fenêtre.

28

Chercher le tag myAwesomeFunc :

:tselect /my<CR>

ouvre une liste comportant tous les tags correspondants au motif. Chaque tag et numéroté, il suffit de taper son numéro puis <CR> pour ouvrir le fichier à la bonne ligne.

On peut aussi utiliser

:tag /my<Tab>

pour activer le “wildmenu” et sélectionner le tag avec les flèches du clavier et <CR>.

29

Plus de rigolade avec :global :

Supposons le texte :

papa aime le jazz
papa aime faire du vélo
papa aime sa femme
papa aime sa famille
papa aime les lasagnes
papa aime le jus d’orange

on peut le transformer en :

papa aime le jazz
papa aime faire du vélo
papa adore sa femme
papa adore sa famille
papa aime les lasagnes
papa aime le jus d’orange

avec :

:g/ sa /s/aime/adore<CR>

30

Je me suis aperçu de deux choses :

La première est que certaines idées reçues sur Vim (et la CLI en général) peuvent paraître fondées :

  • on tape beaucoup,

  • on utilise un « language » complexe,

  • on perd du temps à réfléchir avant d’agir

La deuxième est que la grammaire et le vocabulaire de Vim deviennent vite naturels. Par exemple, quand il m’arrive de poster des réponses sur Stackoverflow, je tape les commandes sans avoir besoin d’essayer dans Vim : le problème se déplie dans ma tête et la solution arrive toute seule. Une suite de caractère telle que :'<,'>norm vits<a href="#"><CR> qui peut sembler inextricable

31

/<\w*\s

permet de sauter au tag suivant.

32

zM pour fermer tous les folds

zR pour ouvrir tous les folds

zm et zr pour manipuler foldlevel

zj et zk pour sauter de fold en fold

33

Il est possible de limiter une série de substitutions à un certain bloc sans le resélectionner à chaque fois.

Il suffit de le replier et d’exécuter les substitutions avec le curseur sur le fold.

Mieux, si on ajoute le c de “confirmation” à la fin de la substitution, le fold et ouvert provisoirement et se referme automatiquement dès qu’on a fini.

34

Je devrai explorer :redir :

:redir @+><CR>
:version<CR>
:redir END

permet de placer la sortie de :version dans le clipboard. Pratique.

35

Deux variantes du tip #33

:folddoc[lose] s/foo/bar

permet d’exécuter une commande sur chaque ligne contenue dans chaque fold fermé.

:folddoo[pen] s/bar/baz

permet d’exécuter une commande sur toutes les lignes n’appartenant pas à des folds fermés.

36

Petites notes en passant au sujet de ctags/cscope.

  • ctags

    • générer un index :

      :!ctags -R .
      
    • sauter à la définition de foo() :

      :tag foo
      
    • lister les définitions possibles de foo() :

      :ts foo
      
    • sauter à la définition de la fonction sous le curseur :

      <C-]>
      g<C-]> " pour une liste comme :ts
      
  • cscope

    • générer un index :

      :!cscope -b
      :!cscope -b *.js " forcer JavaScript
      :cs add cscope.out
      
    • lister les définitions possibles de foo() :

      :cs find d foo
      :cstag foo
      
    • sauter à la définition de la fonction sous le curseur :

      set cscopetag
      <C-]>
      g<C-]> " pour une liste comme :ts
      
    • utiliser hors de Vim :

      $ cscope
      <Tab> pour sauter de la liste au menu
      <C-c> pour rendre insensible à la casse
      

37

Il m’est apparu qu’on pouvait utiliser autre chose que des numéros de lignes ou un delta avec la command :m[ove].

  • classique :

    :m+1
    :m-20
    :m14
    
  • nouveau (pour moi) :

    :m/foo
    :m?bar
    ma
    :m'a
    

Oh yeah!

38

Mélangeons quelques tips pour faire un peu de refactoring vite-fait.

Nous avons le curseur sur la definition et nous trouvons que toutes ces variables dispersées dans cette longue méthode… ça fait pas joli. Ça serait cool de les remonter au début du bloc. OK.

On commence par descendre d’une ligne et poser une marque à l’endroit où on veut déplacer nos variables :

jma

Puis on sélectionne tout le bloc que l’on veut nettoyer :

V]}

Et on déplace chaque ligne contenant var en haut de la méthode :

:'<,'>g/var/m'a

Nice.


My Vim-related gists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment