Como substituir abas por espaços?


85

É possível converter guias em espaços, mantendo o alinhamento do texto?

Simplesmente substituir apenas funciona de maneira útil quando não há caracteres iniciais.


Se você instalou o vim-faq , poderá obter uma resposta offline lá: :h vim-faqe pesquisar /tab characters. A tag difícil de memorizar é :h faq-14.16.
Hotschke

Respostas:


98

Você pode usar o :retabcomando De :help :retab

Substitua todas as seqüências de espaço em branco que contêm a <Tab>por novas cadeias de espaço em branco usando o novo valor de tabstop fornecido. Se você não especificar um novo tamanho de tabstop ou for zero, o Vim utilizará o valor atual de 'tabstop'. [...] Com 'expandtab'ativado, o Vim substitui todas as guias pelo número apropriado de espaços.

Observe que o comando aceita um intervalo, para que você possa fazer uma seleção visual e, em seguida, apenas :retabas linhas selecionadas.


Legal! Funciona rápido e simples!
DenisKolodin

2
Que tal dar um exemplo?
Petr

23

Você pode usar :retab, como indicado, no entanto, isso mudará todas as guias para espaços, não apenas as guias no início da linha

Portanto, este (onde está um caractere de tabulação):

if :; do
⇥echo "⇥hello"
end

é alterado para (onde está um caractere de espaço):

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

Isso pode produzir efeitos colaterais inesperados em alguns cenários, e é ainda mais um problema ao alterar espaços para guias!

Então, escrevi uma pequena função para alterar apenas tabulações / espaços no início da linha:

" :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

Com esta versão, você deve especificar manualmente expandtabna chamada de função (ou seja, :call Retab(1)alterar guias para espaços), mas também pode modificá-la para obter o valor atual de &expandtab(como já acontece com &tabstop) da mesma forma que :retabfaz. (Eu prefiro especificá-lo manualmente).


6
Há também uma resposta no SO que abrange a retabitação apenas no início da linha. Vale a pena ligar por causa da clareza dessa explicação.
jalanb

Alguém poderia explicar o que faz carta aem if a:expandtabmédia?
john cj

Além disso, parece que as condições estão invertidas (uma piada: D?). Se você tiver set expandtabno .vimrc e no autocmd BufWritePre * :call Retab(&expandtab)- o recuo será alterado para tabulações, em vez de espaços.
john cj

11

O Vim fornece um !retabcomando que substituirá todas as seqüências <Tab>por novas strings de espaço em branco usando o novo valor tabstop (por exemplo :set tabstop=2) fornecido, mas todas as guias dentro das strings podem ser modificadas (por exemplo, em um programa C, você deve usar \tpara evitar isso)!

Portanto, como alternativa, você pode alterar todas as guias em espaços usando o seguinte comando:

:%s/\t/  /g

ou como sugerido por @Shahbaz :

:%s/^\t\+/ g

Portanto, apenas as guias usadas no recuo são convertidas.

Explicação:

  • %representa todo o buffer / arquivo ( :help :%)
  • ssignifica substituto ( :help sub-replace-special)
  • \t, ou ^Isignifica guia
  • - use quantos espaços você precisar por uma guia
  • g - significa global e converterá várias ocorrências de guias na mesma linha

Em seguida, para corrigir o recuo de todo o arquivo, você pode tentar: gg=G. Verificação: Re-recuando código mal recuado para obter mais detalhes.

Para usar espaços por padrão, em vez de guias, você precisa adicionar as seguintes configurações ao seu .vimrcarquivo:

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 >>)

Solução alternativa é usar tidy


Relacionado:


1
Eu faria pelo menos %s/^\t\+/ gpara que apenas as guias usadas no recuo sejam convertidas. Além disso, gg=Gpode ser catastrófico com linguagens como python.
Shahbaz

3

Tente usar:

expand -t 4 input_filename output_filename

expandé uma ferramenta de linha de comando para converter guias em espaços, que você pode executar a partir de um shell ou com :!expand.

Está no POSIX, portanto deve estar disponível na maioria dos sistemas. unexpandfará o inverso, a propósito.


2
O que é expand?
Muni

Expandir é um comando de terminal embutido para copiar caracteres de tabulação para espaços. Encontre uma descrição detalhada no link a seguir. computerhope.com/unix/uexpand.htm
Ankit Shah

2
Se estes são comandos externos, você deve mencionar isso.
Muni

Descrição adicional adicionada. Por favor, revise
Ankit Shah

5
Você também pode fazer :%!expand -t 4dentro do vim. Melhor ainda, você também pode usar a opção de largura atual mudança: :exe '%!expand -t ' . &shiftwidth
EvergreenTree

1

Para completar, =também pode ser usado para corrigir recuos, depois de especificar que as guias são substituídas por espaços. No modo normal, você pode fazer isso digitando :set expandtab. Então =poderia ser usado de duas maneiras:

  • No modo Visual, um único =corrigia recuos dos blocos de código selecionados.
  • No modo normal, gg=Gconsertaria o arquivo inteiro, onde ggmove o cursor para o início do arquivo, depois =é aplicado e Gmove o cursor para o final do arquivo.

Referência: link


Isso pressupõe que o vim possa recalcular o recuo atual corretamente (pode não ser o caso) - também para arquivos não estruturados ou código gravado em um editor diferente com regras de recuo ligeiramente diferentes.
Ideasman42

Obrigado @ ideasman42; Eu adicionei à resposta para ser mais completo.
Samuel Li
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.