Sekmeler boşluklarla nasıl değiştirilir?


85

Metin hizalamasını korurken sekmeleri boşluklara dönüştürmek mümkün mü?

Basitçe değiştirmek, yalnızca baş karakterlerden oluşmadığında işe yarar.


Eğer vim-faq kurduysanız , orada çevrimdışı bir cevap alabilirsiniz: :h vim-faqve arama /tab characters. Ezberlemek etiketi zor :h faq-14.16.
Hotschke

Yanıtlar:


98

:retabKomutu kullanabilirsiniz . itibaren :help :retab

<Tab>Verilen yeni tabstop değerini kullanarak yeni beyaz boşluk dizileri içeren tüm beyaz boşluk dizilerini değiştirin . Yeni bir tabstop boyutu belirtmezseniz veya sıfırsa, Vim, şu anki değerini kullanır 'tabstop'. [...] Açık olduğunda 'expandtab', Vim tüm sekmeleri uygun sayıda boşlukla değiştirir.

Komutun bir aralığı kabul ettiğini unutmayın, böylece görsel bir seçim yapıp ardından sadece :retabseçilen satırları yapabilirsiniz.


Güzel! Hızlı ve basit çalışıyor!
DenisKolodin

2
örnek vermeye ne dersiniz?
Petr,

23

:retabAncak belirtildiği gibi kullanabilirsiniz , bu sadece satırın başındaki sekmeleri değil tüm sekmeleri boşluk olarak değiştirir.

Yani bu ( bir sekme karakteri):

if :; do
⇥echo "⇥hello"
end

olarak değiştirilir ( boşluk karakteri nerede ):

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

Bu, bazı senaryolarda beklenmeyen yan etkiler yaratabilir ve boşlukları sekmelere değiştirirken daha da büyük bir sorun yaratır!

Bu yüzden satırın başında sadece sekmeleri / boşlukları değiştirmek için küçük bir fonksiyon yazdım :

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

Bu sürümle, expandtabişlev çağrısında manuel olarak belirtmeniz gerekir (yani :call Retab(1), sekmeleri boşluklara dönüştürmek için), ancak aynı şekilde &expandtabolduğu gibi (zaten &tabstopolduğu gibi) geçerli değerini alacak şekilde de değiştirebilirsiniz :retab. (Manuel olarak belirtmeyi tercih ediyorum).


6
Ayrıca, SO satırında sadece satır başında yeniden başlatmayı kapsayan bir cevap vardır . Bu açıklamanın netliği nedeniyle bağlanmaya değer.
jalanb

Biri harfi ne yaptığını açıklayabilir misiniz ayılında if a:expandtabortalama?
john cj

Ayrıca, koşullar tersine çevrilmiş gibi görünüyor (şaka: D?). Eğer varsa set expandtabsizin .vimrc ve daha sonra autocmd BufWritePre * :call Retab(&expandtab)- girinti yerine boşluk, sekmeler için değiştirilecektir.
john cj

11

Vim, verilen yeni tabstop (eg ) değerini kullanarak !retabtüm dizileri <Tab>yeni beyaz boşluk dizileriyle değiştirecek komut sağlar :set tabstop=2, ancak dizelerin içindeki tüm sekmeler değiştirilebilir (örneğin, bir C programında \tbunu önlemek için kullanmalısınız )!

Alternatif olarak, aşağıdaki komutu kullanarak tüm sekmeleri boşluklara çevirebilirsiniz:

:%s/\t/  /g

veya @Shahbaz tarafından önerildiği gibi :

:%s/^\t\+/ g

Böylece sadece girintide kullanılan sekmeler dönüştürülür.

Açıklama:

  • %tamponun tamamını gösterir ( :help :%)
  • syerine geçen ( :help sub-replace-special) anlamına gelir
  • \t, veya ^Isekme için duruyor
  • - bir sekme için istediğiniz kadar boşluk kullanın
  • g - global anlamına gelir ve aynı satırdaki birden fazla sekme oluşumunu dönüştürür

Sonra tüm dosyanın girinti düzeltmek için, sen deneyebilirsiniz: gg=G. Kontrol Et: Daha fazla ayrıntı için hatalı girintili kodu tekrar girin .

Boşlukları sekmeler yerine varsayılan olarak kullanmak için, aşağıdaki ayarları .vimrcdosyanıza eklemeniz gerekir :

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

Alternatif çözüm kullanmaktır tidy


İlgili:


1
En azından %s/^\t\+/ gsadece girintide kullanılan sekmelerin dönüştürülmesi için yapardım . Ayrıca, gg=Gpython gibi dillerle yıkıcı olabilir.
Shahbaz

3

Kullanmayı deneyin:

expand -t 4 input_filename output_filename

expandsekmeleri kabuktan çalıştırabileceğiniz boşluklara dönüştüren bir komut satırı aracıdır :!expand.

Bu var POSIX'deki çoğu sistemlerde mevcut olmalıdır böylece. unexpandBu arada, tersini yapacak.


2
Nedir expand?
muru

Genişlet, sekme karakterini boşluklara kopyalamak için yerleşik bir terminal komutudur. Lütfen aşağıdaki bağlantıda ayrıntılı bir tanım bulun. computerhope.com/unix/uexpand.htm
Ankit Shah

2
Bunlar harici komutlarsa, bundan bahsetmelisiniz.
muru

Ek açıklama eklendi. Lütfen gözden
geçirin

5
Ayrıca sadece :%!expand -t 4vim içinde yapabilirsin . Daha da iyisi, mevcut kaydırma genişliği seçeneğini de kullanabilirsiniz: :exe '%!expand -t ' . &shiftwidth
EvergreenTree

1

Bütünlüğü sağlamak için, =sekmelerin boşluklarla değiştirilir belirttiğiniz sonra da, girintileri düzeltmek için kullanılabilir. Normal modda, yazarak yapabilirsiniz :set expandtab. Sonra =iki şekilde kullanılabilir:

  • Görsel modda, tek bir =seçilen kod bloklarının girintilerini düzeltir.
  • Normal modda, gg=Gtüm dosyayı, şike yapacak gg, ardından dosyanın başına imleci hareket =uygulanır ve Gdosyanın sonuna imleci hareket ettirir.

Referans: link


Bu, vim'in geçerli girintiyi doğru şekilde hesaplayabildiğini varsayar (durum böyle olmayabilir) - yapılandırılmamış dosyalar için veya farklı bir düzenleyicide yazılmış kod için biraz farklı girinti kuralları.
ideasman42

Teşekkürler @ ideasman42; Daha eksiksiz olmak için cevaba ekledim.
Samuel Li,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.