102 votes

Comment changer rapidement les noms de variables dans Vim ?

J'utilise Vim pour lire un grand nombre de codes C et Perl contenant de nombreux noms de variables à une seule lettre.

Il serait agréable de disposer d'une commande permettant de changer le nom d'une variable en quelque chose de plus significatif pendant que je suis en train de lire le code, afin de pouvoir lire le reste du code plus rapidement.

Existe-t-il une commande dans Vim qui me permettrait de faire cela rapidement ?

Je ne pense pas que les regex fonctionneraient car :

  1. le même nom d'une seule lettre peut avoir des objectifs différents dans des blocs de cadrage différents ; et

  2. la même combinaison de lettres peut faire partie d'un autre nom de variable plus long, d'une chaîne littérale ou d'un commentaire.

Existe-t-il des solutions connues ?

209voto

Mykola Golubyev Points 21210

Voici comment renommer une variable qui est définie dans la portée actuelle {} .

Déplacez votre curseur sur la variable d'utilisation. Appuyez sur gd . Ce qui signifie - déplacer le curseur sur la définition. Maintenant, appuyez sur [{ - cela vous amènera au début de la portée. Appuyez sur V - activera la sélection de la ligne visuelle. Appuyez sur % - sautera à l'opposé } sélectionne ainsi l'ensemble du champ d'application. Appuyez sur :s/ - début de la commande de substitution. <C-R>/ - insérera le motif qui correspond au nom de la variable (le nom sur lequel vous étiez avant d'appuyer sur gd ). /newname/gc<CR> - lancera une recherche et un remplacement avec confirmation pour chaque correspondance.

Maintenant, vous devez enregistrer une macros ou mieux encore - mapper une touche.

Voici les mappings finaux :

" For local replace
nnoremap gr gd[{V%::s/<C-R>///gc<left><left><left>

" For global replace
nnoremap gR gD:%s/<C-R>///gc<left><left><left>

Mettez cela à votre .vimrc ou simplement exécuter. Après cette pression gr sur la variable locale vous amènera à :s où vous devez simplement entrer new_variable_name et appuyez sur Enter .

40 votes

+1 pour avoir appris plus de 5 nouvelles astuces Vim que j'aurais dû connaître avant. Merci

0 votes

Vraiment utile, +1 surtout qu'il peut être "étendu" à d'autres langues facilement.

6 votes

Note : gd ne fonctionne pas pour localiser la variable dans la portée immédiate de la définition en mode Javascript dans macvim. Il m'amène à la première utilisation du nom de la variable dans une fonction du fichier :( Si vous êtes dans une certaine portée et que vous voulez sélectionner cette portée, "va{" - "visual select around {" - est la solution, je pense.

10voto

JaredPar Points 333733

A priori, il n'y a pas de support de refactoring dans VIM. Lorsque je procède à un renommage dans l'intention de procéder à un remaniement, je prends généralement les précautions suivantes :

  1. Limitez la portée du changement en utilisant des marques.
  2. Lors de la saisie de la regex, mettez le nom entre parenthèses avec \< et >. Cela permet de faire correspondre un mot entier, ce qui réduit le nombre de renommages incorrects.
  3. Ne faites pas un remplacement multiligne pour réduire les chances d'un mauvais remplacement.
  4. Regardez attentivement le code diff si c'est autre chose qu'une petite modification.

Mon changement final ressemble à quelque chose comme ceci

:'a,'bs/\<foo\>/bar

J'aimerais bien me tromper en disant qu'il n'existe pas d'outil de refactoring pour VIM, mais je ne l'ai pas vu.

0 votes

En Perl, vous pouvez également ajouter le type au motif de recherche, c'est-à-dire $ pour les scalaires, @ pour les tableaux et % pour les hachages.

0 votes

@Nathan : malheureusement, c'est un peu plus difficile en Perl (5.X), car le sigle des tableaux et des hachages change avec l'usage : %hash -> hachage complet, $hash{key} -> valeur unique, @hash{qw/a b/} tranche de hachage.

9voto

Mike Points 31

Mettez ceci dans votre .vimrc

" Function to rename the variable under the cursor
function! Rnvar()
  let word_to_replace = expand("<cword>")
  let replacement = input("new name: ")
  execute '%s/\(\W\)' . word_to_replace . '\(\W\)/\1' . replacement . '\2/gc'
endfunction

Appelez-le avec :call Rnvar()

expand("<cword>") obtient le mot sous le curseur. La chaîne de recherche utilise % pour le champ d'application des fichiers, et l'option \(\W\) les motifs recherchent les caractères non-mots à la limite du mot à remplacer, et les enregistrent dans des variables \1 et \2 afin d'être réinséré dans le modèle de remplacement.

4voto

Adnan Points 1623

Vous pourriez utiliser le modificateur "c" dans la recherche et le remplacement global qui vous demanderait une confirmation pour chaque remplacement. Cela prendrait plus de temps, mais cela pourrait fonctionner pour un fichier de code non volumineux :

%s/\$var/\$foo/gc

Le c est pour confirmer.

0 votes

Le i signifie "ignorer la casse". Vous voulez c, confirmer chaque changement.

0 votes

Oups Désolé pour ça J'ai corrigé la réponse

0 votes

Réponse toujours pas complètement corrigée ;)

0voto

Kim Reece Points 1046

En c, vous pourrez peut-être faire quelques progrès en utilisant cscope. Il tente de comprendre la syntaxe, et aurait donc une chance de savoir quand la lettre est une variable.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X