Comment remplacer les onglets par des espaces?


85

Est-il possible de convertir des tabulations en espaces tout en maintenant l'alignement du texte?

Simplement remplacer ne fonctionne que utilement quand il n'y a pas de personnages principaux.


Si vous avez installé vim-faq , vous pouvez y obtenir une réponse hors ligne: :h vim-faqet effectuer une recherche /tab characters. Le tag difficile à mémoriser est :h faq-14.16.
Hotschke le

Réponses:


98

Vous pouvez utiliser la :retabcommande. De :help :retab

Remplacez toutes les séquences d'espaces contenant un <Tab>avec de nouvelles chaînes d'espaces en utilisant la nouvelle valeur de tabulation donnée. Si vous ne spécifiez pas de nouvelle taille de tabulation ou si elle est égale à zéro, Vim utilise la valeur actuelle de 'tabstop'. [...] Avec 'expandtab'on, Vim remplace tous les onglets avec le nombre d'espaces approprié.

Notez que la commande accepte une plage, vous pouvez donc effectuer une sélection visuelle et uniquement :retables lignes sélectionnées.


Cool! Fonctionne vite et simple!
DenisKolodin

2
que diriez-vous de donner un exemple?
Petr

23

Vous pouvez utiliser :retab, comme indiqué, cependant, cela changera tous les onglets en espaces, et pas seulement les onglets au début de la ligne.

Donc ceci (où est un caractère de tabulation):

if :; do
⇥echo "⇥hello"
end

se change en (où est un espace):

if :; do
␣␣echo "␣␣hello"
end

Cela peut produire des effets secondaires inattendus dans certains scénarios, et c'est encore plus un problème lorsque vous modifiez des espaces en onglets!

J'ai donc écrit une petite fonction pour ne changer que les tabulations / espaces au début de la ligne:

" :retab changes *everything*, not just start of lines
fun! Retab(expandtab)
    let l:spaces = repeat(' ', &tabstop)

    " Replace tabs with spaces
    if a:expandtab
        silent! execute '%substitute#^\%(' . l:spaces . '\)\+#\=repeat("\t", len(submatch(0)) / &tabstop)#e'
    " Replace spaces with tabs
    else
        silent! execute '%substitute#^\%(\t\)\+#\=repeat("' . l:spaces . '", len(submatch(0)))#e'
    endif
endfun

Avec cette version, vous devez spécifier manuellement expandtabdans l'appel de fonction (c'est- :call Retab(1)à- dire pour changer les tabulations en espaces), mais vous pouvez également le modifier pour qu'il prenne la valeur actuelle de &expandtab(comme il le fait déjà avec &tabstop) comme :retabtout le monde. (Je préfère préférer le spécifier manuellement).


6
Il existe également une réponse sur le SO qui ne couvre que le changement de ligne en début de ligne. Il convient de faire le lien en raison de la clarté de cette explication.
Jalanb

Quelqu'un pourrait -il expliquer ce que fait la lettre aen if a:expandtabmoyenne?
john cj

En outre, il semble que les conditions soient inversées (une blague: D?). Si vous avez set expandtabdans votre fichier .vimrc, puis autocmd BufWritePre * :call Retab(&expandtab)- l'indentation sera modifiée en onglets, au lieu d'espaces.
john cj

11

Vim fournit une !retabcommande qui remplacera toutes les séquences de <Tab>nouvelles chaînes par des espaces en utilisant la nouvelle valeur de tabstop (par exemple :set tabstop=2) donnée, mais tous les onglets à l'intérieur des chaînes peuvent être modifiés (par exemple, dans un programme C, vous devez utiliser \tpour éviter cela)!

Donc, vous pouvez également changer tous les onglets en espaces en utilisant la commande suivante:

:%s/\t/  /g

ou comme suggéré par @Shahbaz :

:%s/^\t\+/ g

Ainsi, seuls les onglets utilisés dans l'indentation sont convertis.

Explication:

  • %représente l'intégralité du tampon / fichier ( :help :%)
  • ssignifie substitute ( :help sub-replace-special)
  • \t, ou ^Ireprésente un onglet
  • - utilisez autant d'espaces que nécessaire par onglet
  • g - signifie global et convertira plusieurs occurrences d'onglets dans la même ligne

Ensuite , pour corriger indentation du fichier entier, vous pouvez essayer: gg=G. Vérifiez: Réindentez le code mal mis en retrait pour plus de détails.

Pour utiliser des espaces par défaut au lieu d'onglets, vous devez ajouter les paramètres suivants dans votre .vimrcfichier:

set tabstop=2     " (ts) width (in spaces) that a <tab> is displayed as
set expandtab     " (et) expand tabs to spaces (use :retab to redo entire file)
set shiftwidth=2  " (sw) width (in spaces) used in each step of autoindent (aswell as << and >>)

La solution alternative consiste à utiliser tidy


Apparenté, relié, connexe:


1
Je voudrais au moins faire en %s/^\t\+/ gsorte que seuls les onglets utilisés dans l'indentation soient convertis. En outre, gg=Gpourrait être catastrophique avec des langages comme Python.
Shahbaz

3

Essayez d'utiliser:

expand -t 4 input_filename output_filename

expandest un outil de ligne de commande permettant de convertir des tabulations en espaces que vous pouvez exécuter à partir d'un shell ou avec :!expand.

Il est dans POSIX , il devrait donc être disponible sur la plupart des systèmes. unexpandva faire l'inverse, au fait.


2
C'est quoi expand?
Muru

Expand est une commande de terminal intégrée permettant de copier le caractère de tabulation dans des espaces. Veuillez trouver une description détaillée dans le lien suivant. computerhope.com/unix/uexpand.htm
Ankit Shah

2
Si ce sont des commandes externes, vous devriez le mentionner.
Muru

Description supplémentaire ajoutée. S'il vous plaît examiner
Ankit Shah

5
Vous pouvez aussi simplement faire à l' :%!expand -t 4intérieur de vim. Mieux encore, vous pouvez également utiliser l'option de largeur de décalage actuelle: :exe '%!expand -t ' . &shiftwidth
EvergreenTree

1

Par souci d'exhaustivité, vous =pouvez également utiliser cette option après avoir spécifié que les tabulations sont remplacées par des espaces. En mode normal, vous pouvez le faire en tapant :set expandtab. Ensuite, =pourrait être utilisé de deux manières:

  • En mode visuel, un seul =corrige les indentations des blocs de code sélectionnés.
  • En mode normal, gg=Gcorrige le fichier entier, ggdéplace le curseur au début du fichier, =est ensuite appliqué et Gdéplace le curseur à la fin du fichier.

Référence: lien


Cela suppose que vim puisse recalculer correctement l'indentation actuelle (ce qui n'est peut-être pas le cas) - également pour les fichiers non structurés ou le code écrit dans un éditeur différent avec des règles d'indentation légèrement différentes.
ideasman42

Merci @ ideasman42; J'ai ajouté à la réponse pour être plus complet.
Samuel Li
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.