Réindenter du code mal mis en retrait

39

J'aime la fonctionnalité smart-indent de Vim, elle me permet de créer des blocs de code bien indentés.

Je copie / colle régulièrement du code dans des tampons, mais ce code est souvent mal formaté.

L'idéal serait de "re-traiter" le code via le système smart-indent.

Une telle chose est possible?

Par exemple, comment "corrigeriez-vous" le code suivant (un extrait d'un bloc plus important - je ne veux pas corriger chaque ligne manuellement ...):

    else 
                {
                        m[c] = 5;
                Finished = true;
std::cout<<"(ID,R,E)"<<"-->"<<"("<<g[c]<<","<<r[c]<<","<<E1 <<")"<< std::endl;
std::cout << "\n"<<"finish-->" << r[c] << "\t" <<"E1-->"<< E1 <<"\n" ;
                }
        }
Rolfl
la source
1
Parlez-vous du code qui était à l'origine mal mis en retrait ou du code correctement mis en retrait et qui change lorsque vous le collez dans Vim?
jamessan
Le code collé est mal mis en retrait pour commencer. Permettez-moi d'inclure un exemple ....
rolfl

Réponses:

48

Je fais cela de deux manières.

Pâte ajustée à l'indentation

Premièrement, si le code dans la mémoire tampon est formaté, mais à un niveau d'indentation différent, je l'utilise à la ]pplace de p, qui colle le code tel quel, mais avec l'indentation décalée de sorte que la première ligne collée ait la même profondeur que la ligne I 'lun.

Source EG copiée dans le tampon

while (1) {
    dostuff();
}

EG résultat de le coller avec ]p

int myfunc() {
    int i = 5; /* Cursor on this line before paste */
    while (1) {
        dostuff();
    }
 }

vim met le moment au même niveau d'indentation que int i. Ceci est rapide, mais ne fonctionne que si le code copié est correctement mis en retrait en lui-même.

Reformater après la pâte

L' =opérateur de vim reformate le code en fonction des règles de formatage configurées. Pour de courts extraits de collage, je passe en mode visuel avec v, sélectionne les lignes que je viens de coller, puis appuie sur =pour les reformater.

Pour les pâtes plus volumineuses, je profite du fait que le curseur se place sur la première ligne collée et que vim indique quelque chose comme "84 lignes supplémentaires". Je peux ensuite entrer 84==pour redistribuer ces 84 lignes (bien sûr, remplacez 84 par le nombre de lignes que vous collez réellement).

Les références

:help ]p pour pâte à retrait ajustée

:help =couvre ={motion}, [count]==et {Visual}=pour filtrer à travers des règles de retrait personnalisées ou intégrées

John O'M.
la source
6
Vous pouvez bien sélectionner le code que vous avez collé en mode visuel en utilisant `[v`]
craigp
1
@Badger Juste pour clarifier, est-ce que backtick-brack-v-backtick-brack?
phatskat
1
yup .. la textarea a paniqué à propos des backticks, donc je ne pouvais pas le mettre dans un bloc de code: P
craigp
L'opérateur = de vim reformate le code en fonction des règles de formatage configurées que je donnerais à +100 si je le pouvais. J'aurais pu économiser des jours.
Wossname
1
J'utilise <control + R> "pour coller, de sorte que je n'ai pas à quitter le mode insertion. Quel est l'équivalent] p pour <control + R>"?
A --- B
15

La =commande peut être utilisée pour se réindentir.

Comme la plupart des commandes en mode normal, il peut être appliqué à un mouvement afin que vous puissiez réindentir le code que vous venez de coller avec =']. Cela permet de revenir de la position actuelle du curseur à la ']marque, qui est la dernière ligne du collage.

= peut également être utilisé en mode visuel.

Une autre commande utile consiste ]pà coller au même niveau de retrait que la ligne en cours. Cela peut aider à coller du texte correctement mis en retrait, bien qu'à une profondeur de retrait différente, conformément au texte environnant.

Jamessan
la source
7

Utiliser =ap (mnémonique est 'formater un paragraphe') aura pour tentative de vim de formater automatiquement le paragraphe actuel.

Si vous voulez porter une attention particulière à ce que vous reformatez éventuellement, vous trouverez peut-être plus simple et plus rapide de vapsélectionner visuellement le paragraphe actuel (en vous donnant une indication visuelle de ce qui est en train d'être reformaté), suivi de =. Je trouve cela utile dans les fichiers où je sais que vim ne sera pas reformaté correctement et que je ne souhaite pas formater par erreur d'autres lignes.

Davidlowryduda
la source
4

Pour réindentir un fichier déjà dans le tampon, utilisez gg=G: Voir Correction d'un retrait

Pour réindentir une partie d'un fichier, différentes limites peuvent être appliquées au =filtre (par exemple, ==corrige uniquement la ligne en cours).

Pour que l'indentation reste inchangée lors du collage de texte, vous pouvez :set pasteéviter que vim n'indente automatiquement le texte que vous venez de coller. Après avoir collé des éléments, vous pouvez revenir en arrière set :nopastelorsque vous avez terminé. Voir vimdoc ici .

Si vous vous trouvez fréquemment en train de coller des choses, ce serait une bonne idée d'utiliser cette astuce sur VimWiki et de configurer une clé pour l'activation / désactivation du mode "coller" en ajoutant ces lignes à votre .vimrc:

nnoremap <F2> :set invpaste paste?<CR>
set pastetoggle=<F2>
set showmode

Vous pouvez ensuite appuyer <F2>pour basculer en mode Coller. vim affichera les mots "PASTE" dans la ligne d’état lorsque le mode coller est actif.

Bhargav Bhat
la source
2
Cette question ne concerne pas le collage de code avec indentation, mais la correction de code mal indenté.
Rolfl
4
Je n'ai pas vu le commentaire que vous avez posté. Cependant, vous pouvez toujours utiliser gg=Gpour réindentifier le fichier entier.
Bhargav Bhat
@ rolfl C’est là que je commence habituellement dans de tels cas:, gg=Gpuis examinez les parties qui se vimsont trompées.
Muru
Si vous souhaitez plus de contrôle (ou réduire les tracas répétés), envisagez d'ajouter une commande automatique pour appeler un outil de formatage de code, comme astylelorsque vous enregistrez un tampon. Voir cette question sur SO pour les détails.
Bhargav Bhat
2

Pour réindenter automatiquement le bloc entier d'un bloc entre crochets ou entre crochets, placez votre curseur sur la même ligne où se trouve un crochet et essayez =%. Pour changer la largeur de votre équipe, utilisez par exemple :set sw=2.

Si cela ne fonctionne pas comme prévu, pour réduire le retrait manuellement ( dépassé ), essayez de <%répéter avec .(si nécessaire). Utilisez >%pour le contraire.

Alors:

else
       {
         // some code
       }

devient:

else
{
  // some code
}

Pour un code spécifique, pour réindenter une ou plusieurs lignes automatiquement, essayez:

  • == ré-indenter la ligne courante
  • 5== re-indenter 5 lignes

Pour augmenter / diminuer le retrait manuellement d'une ligne ou de quelques lignes, essayez:

  • << pour désindenter la ligne courante par des espaces de shiftwidth
  • 5<< désindenter 5 lignes par espaces shiftwidth
  • >> indenter la ligne actuelle par des espaces de shiftwidth
  • 5>> pour mettre en retrait 5 lignes par des espaces de shiftwidth
  • . à répéter si nécessaire

Vous pouvez également effectuer une indentation en mode visuel ( v) en sélectionnant du texte et en appuyant sur =(indentation automatique), <(deindentation) ou >(indentation).

Une autre astuce consiste à indentation correcte du fichier entier par: gg=G.

Si vous avez des tabulations au lieu d'espaces, utilisez: :retabqui remplacera tous les tabulations par des espaces (voir: Comment remplacer des tabulations par des espaces? ).


Pour les méthodes externes, vous pouvez essayer:

  • pythonTidy pour reformater le code Python, par exemple:

    :%!pythonTidy
    

En relation:

Kenorb
la source
1

J'ai récemment installé vim-pasta ( https://github.com/sickill/vim-pasta ), et cela semble améliorer l'indentation du code lorsque je le colle. Le fichier README contient également de bonnes discussions sur diverses stratégies de collage de code.

Rob Warner
la source
1

Il y a déjà beaucoup de choses couvertes dans les réponses existantes. J'aime juste ajouter un mappage que j'utilise très souvent pour l'indentation.

nnoremap <Leader>i  mzgg=G`z

J'ai vu quelque vimrc avec ce mappé à ===.

Quoi qu’il en soit, c’est un excellent mapping et je l’utilise presque à chaque fois, surtout lors du collage de code copié ailleurs.

Ou mieux encore, mettez ceci de manière à autocmdce que Vim l'indente juste avant d'écrire les modifications sur le disque.

Durga Swaroop
la source