Bir dosyadaki tüm satırlardan sondaki boşlukları soyunmanın en basit yolu nedir?


139

Satır sonunda izleyen boşluk olan dosyalarla karşılaşmak için metin dosyalarını programlarken veya açarken oldukça yaygındır. vim trailseçeneğindeki listcharsseçeneği ayarlayıp ardından açarak bunu göstermenin bir yolunu bulur list.

Bununla birlikte, bir dosyanın tümünde (takip eden bir eklenti olmadan) küresel olarak bu beyaz boşlukları ortadan kaldırmanın en kolay yolu nedir?



İşte konuyla ilgili bir doktor girişi .
Filipp W.

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

Yanıtlar:


72

Sondaki tüm boşlukları sıyırmak için bir tuş takımı kullanın

Düzenlediğim bazı sayfaların gerçekte beyaz boşluklara (örn. Markdown) ihtiyaç duyduğu ve diğerlerinin ihtiyaç duymadığı F5için, otomatik olmadan yapmanın önemsiz olması için bir kilitleme ayarlıyorum . Bunu yapmak için, aşağıdaki kodu (vim.wikia'dan) veya bir miktarını şuna ekle .vimrc:

"Remove all trailing whitespace by pressing F5
nnoremap <F5> :let _s=@/<Bar>:%s/\s\+$//e<Bar>:let @/=_s<Bar><CR>
  • nnoremap <F5>F5Normal modda tuşun tekrarlı olmayan bir eşlemesi yapar.
  • :let _s=@/Son arama terimini (makrodan gelen @/) değişkende saklar_s
  • <Bar>|Komutları ayırmak için bir boru sembolü olarak işlev görür , ancak |bu bağlamda bir komutu sonlandırır, <Bar>bunun yerine kullanılmalıdır.
  • :%s/\s\+$//eizleyen boşlukları arar ve arabellekte her yerde siler (bu ifadenin ayrıntılı bir dökümü için CarpetSmoker'in cevabına bakınız )
  • let @/=_sson arama teriminizi makroya geri yükler @/, böylece bir dahaki sefere ulaşmanız uygun olur n.
  • <CR> haritalamayı bitirir

... ya da daha seçici olun

İzleyen tüm boşlukları sıyırmak istemediğiniz durumlar varsa, daha seçici olmak için bir desen kullanabilirsiniz. Örneğin, aşağıdaki kod izleyen boşlukları yalnızca bir noktalı virgülden sonra gelirse (burada bağlı F8) nasıl çıkardığımı gösterir .

nnoremap <F8> :let _s=@/<Bar>:%s/;\s\+$/;/e<Bar>:let @/=_s<Bar><CR>

Benim gibi, noktalı virgül sonlandırmalı programlama ifadeleri arasında serpiştirilmiş markdown benzeri heredocs içeren bazı dosyalarınız varsa, bu kullanışlıdır .


6
:keeppatternsGeçersiz kılmayı önlemeye çalışın @/. Ve ayrıca bir göz atın :keepjumps.
Bohr

@Bohr Hangi vim sürümünü kullanıyorsunuz? Denedim :help keeppatternve hiçbir şey alamadım.
Christopher Bottom

@ChristopherBottoms En az sürüm 7.4.155 .
Bohr

@Bohr. Teşekkürler! Geliyorum hala 7.4.0 kullanıyordum. En son sürümü yükledim ve kullanıma hazır.
Christopher Bottoms

2
Bu komutu bir fonksiyona sararak aynı etkiyi elde edersiniz, çünkü son arama terimi otomatik olarak geri yüklenir :-) Bu şekilde :nohlikisini de kesmek zorunda kalmazsınız , eğer bir şeye dikkat çekerseniz, vurgulamaya devam eder o (güncellenmiş cevabımı gör).
Martin Tournoij

175

"En basit" yol, sadece kullanmaktır :substitute:

:%s/\s\+$//e
  • :%stüm arabellek olan :substitutearalığın üzerinden geçmek için %.
  • \s t tüm boşluk karakterleriyle eşleşin.
  • \+ 1 veya daha fazla kez tekrarlamak için
  • $ çizginin sonundaki demirlemek için.
  • e(Dosya sonlarındaki boşluk olmadan zaten ie) hiçbir eşleşme varsa bayrak bir hata vermemek için.

Ancak, bu iki yan etkiye neden olduğu için muhtemelen "en iyi" yol değildir:

  1. imleci son eşleşmeye taşır;
  2. komutu tarihe ve arama geçmişine ekler;
  3. son arama terimini sıfırlar.

Her iki öğeyi de bir işleve dönüştürerek düzeltebilirsiniz:

fun! TrimWhitespace()
    let l:save = winsaveview()
    keeppatterns %s/\s\+$//e
    call winrestview(l:save)
endfun

Ve sonra gibi kullanın:

:call TrimWhitespace()
  1. winsaveview()İmleç pozisyonunu içeren kıvrımları, vb atlar akım "görüntüleme", kurtaracak winrestview()sonunda kaydedilen değişkenden bu geri yükleyecektir.
  2. :keeppatternsEngelleyen \s\+$arama geçmişinde eklenmesini deseni.
  3. Son kullanılan arama terimi, bir işlevden ayrıldıktan sonra otomatik olarak geri yüklenir, bu nedenle bunun için başka bir şey yapmamız gerekmez.

Bu :callher zaman yazmak için biraz sinir bozucu olduğundan , bir komut tanımlayabilirsiniz:

command! TrimWhitespace call TrimWhitespace()

Hangi olmadan kullanılabilir :call:

:TrimWitespace

Ve elbette onu bir anahtara bağlayabilirsiniz:

:noremap <Leader>w :call TrimWhitespace()<CR>

Bazı insanlar diske bir dosya yazmadan önce bunu otomatik olarak yapmaktan hoşlanır, şöyle:

autocmd BufWritePre * :call TrimWhitespace()

Hoşuma gitmiyor, çünkü bazı biçimler izleyen boşluklar (Markdown gibi) gerektirir ve bazı durumlarda da kodunuzda izleyen boşluklar (hatta bir e-postayı biçimlendirme ve --<Space>imzanın başlangıcını belirtmek için işaretçiyi kullanma) isteyebilirsiniz ).


Utanmaz fiş modu: bir süre önce tüm projenin boşluklarını bir kerede temizlemek için küçük bir Python senaryosu yazdım .


1
Önceki konuma geçmek için bir işlev oluşturmak istemiyorsanız ​`​, değiştirme bittikten sonra iki kez basabilirsiniz . Bu, böyle bir oneliner yaratma olasılığını açar:%s/\s\+$//e | exe "normal ``"
Neaţu Ovidiu Gabriel

1
@ NeaţuOvidiuGabriel, elbette oneliner çalıştırıldıktan sonra çift backtick aynı şekilde çalışmayacaktır. ;)
Joker

Benzer: stackoverflow.com/a/1618401 . Ama Martin'in kodunu daha çok seviyorum.
john cj

11

Tüm sondaki boşlukları silmek için (her satırın sonunda), aşağıdaki komutu kullanabilirsiniz:

:%s/ \+$//

Sekmeleri eklemek için \sboşluk kullanın .


Komut satırından:

$ ex +'%s/\s\+$//e' -cwq file.c

Geçerli dizindeki tüm dosyalar (tekrarlı şekilde kullanın **/*.*):

$ ex +'bufdo!%s/\s\+$//e' -cxa *.*

Python yolu:

:py import vim
:pydo vim.current.buffer[linenr - 1] = vim.current.buffer[linenr - 1].strip()

veya:

:py import vim
:py for i, l in enumerate(vim.current.buffer): vim.current.buffer[i] = l.rstrip()

Kullanarak lstrip()sol şeridin (arka) için, rstrip()sağ şerit (lider) ya da strip()her iki ucundan çıkarmak için.


Burada gereksiz beyaz alanı, size ekleyebileceğiniz bir satırın sonundan kaldıran kullanışlı bir işlevdir .vimrc:

" Removes superfluous white space from the end of a line
function! RemoveWhiteSpace()
   :%s/\s*$//g
    :'^
    "`.
endfunction

Bunun için DeleteTrailingWhitespace eklentisi de vardır.


Beyaz boşlukları vurgulama

Tüm sondaki boşlukların gittiğini kontrol etmek için, şunları kullanın:

  1. Tip / $onları bulmak için. Bazıları varsa, vim sizin için onları vurguluyor.

  2. Onları vurgulamak için renkler kullanın:

    :highlight ws ctermbg=red guibg=red
    :match ws /\s\+$/
    
  3. Görünür karakterleri kullan ( kaynak ):

    :set encoding=utf-8
    :set listchars=trail:·
    :set list
    

Ayrıca bakınız: İstenmeyen alanları vurgulayın

.vimrcİzleyen boşlukları varsayılan olarak vurgulamak için , aşağıdaki gibi ayarlarınızı yapabilirsiniz :

highlight ws ctermbg=red guibg=red
match ws /\s\+$/
autocmd BufWinEnter * match ws / \+$/

Varsayılan olarak beyaz boşlukları kaldırma

Bir dosyadaki tüm beyaz boşlukların kaydetme sırasında otomatik olarak kaldırıldığından emin olmak istiyorsanız, aşağıdaki komutu bilgisayarınıza ekleyebilirsiniz .vimrc:

autocmd BufWritePre *.c,*.php :%s/ \+$//ge

Bu, kullanıcı tarafından kaydedilen her dosyadan izleyen boşlukları soracağı için tavsiye edilmez (boşluk istendiğinde bile).


Ayrıca bakınız:


5

Christopher Bottoms'in cevabı biraz cevaplandı : Jonathan Palardy bu konuda iyi bir makale yazdı . İçinde, Preserve(command)rasgele bir komut çalıştırırken editörün durumunu (esas olarak imleç konumu ve son arama düzeni) koruyan bir işlev yazar :

function! Preserve(command)
  " Preparation: save window state
  let l:saved_winview = winsaveview()
  " Run the command:
  execute a:command
  " Clean up: restore previous window position
  call winrestview(l:saved_winview)
endfunction

Bu, çok amaçlı bir avantaja sahiptir, örneğin, bunu aşağıdakilerle eşleyerek tüm beyaz boşlukları (Jonathan'ın yaptığı gibi) değiştirmek için kullanabilirsiniz:

nnoremap <F5> :call Preserve("%s/\\s\\+$//e")<CR>

Görsel olarak seçilen çizgilerdeki izleyen boşlukları kaldırmak için görsel mod eşlemesi için de kullanabilirsiniz:

xnoremap <F5> :call Preserve("'<,'>s/\\s\\+$//e")<CR>

=Yerinizi korurken tüm belgeyi biçimlendirmek gibi başka çağrılar için de kullanabilirsiniz (bu sefer çakışmamak için farklı bir anahtar kullanın):

nnoremap <F6> :call Preserve("normal gg=G")<CR>

Sonuçta, Preserve(command)işlevi olması gereken güzel bir araç olarak buldum .


2
Bir işlevden ayrıldığınızda en son kullanılan arama terimi otomatik olarak korunmalıdır; öyleyse, onunla dalga geçmek @/gerekli olmamalıdır (bu durumda, yine de).
Martin Tournoij

3
winsaveview()ve winrestview()çok üstün.
çizgi-tom-bang

Oldukça doğru! Geri bildiriminize göre güncellendi.
Alex,

0

StripTrailingSpaces İşlevinin başka bir sürümü:

if !exists('*StripTrailingWhitespace')
    function! StripTrailingWhitespace() range
        if !&binary && &filetype != 'diff'
            call Preserve(":" . a:firstline . "," . a:lastline . "s/\\s\\+$//e")
        endif
    endfunction
endif

GERÇEKTEN BU FONKSİYONDA BİR HATA VAR (bu): “menzil” seçeneği nedeniyle mülk muhafaza edilmez. çok iyi çalıştığını söyledi, ancak yardım almak için kodu paylaşıyorum.

Gördüğünüz gibi yukarıda da görüldüğü gibi Koruma işlevini kullanır , ancak biraz farklı bir şekilde.

Buradaki fark şudur: ile bir satır aralığı veya paragraf seçebilirim vipve ardından aralık :'<,'>komut isteminde otomatik olarak görünür.

Fikir Bez Hermoso'nun görevinden geldi .

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.