Vi veya vim kullanarak satır numaralarıyla belirtilen birden çok kod satırını yorumlama


20

Bu Yığın Taşması sorusundanvi / vimsatır numaralarının belirli bir aralığını yorumlamak mümkün olduğunu öğrendim . Örneğin, aşağıdaki bash betiğine sahip olduğumu varsayalım:

#!/bin/bash

This
is
my
very
very
great
script

Şimdi (sözcükleri içeren 8 arasındaki hat numaralarını 6 dışarı yorum yapmak istediğinizi varsayalım very, veryve greatkullanarak) #açıklama karakterini. vi/ İçinde vim, sadece :6,8s/^/#aşağıdakileri elde etmek için yazabilirim :

#!/bin/bash

This
is
my
#very
#very
#great
script

6'dan 8'e kadar olan satırları yorumlar.

Benim sorum bu olacak benzer bir astar yazmanız mümkündür olduğunu kaldırmak# 8 (dosyada ama başka yorumladı hatları) üzerinden hatları 6 dan açıklama karakterini?

Bunu söyledikten, ben aslında kullanıyorum olmadığı konusunda bazı tartışmalar olduğunu fark viya vim. Uygulamada, script.shkomutla bir dosya açıyorum vi script.sh. Ayrıca, komutu which viyazdığımda da elde ederim /usr/bin/vi. Bununla birlikte, basitçe yazıp vibastığımda Enter, bunu elde ederim:

~                              VIM - Vi IMproved
~
~                               version 7.2.330
~                           by Bram Moolenaar et al.
~                 Vim is open source and freely distributable
~
~                           Sponsor Vim development!
~                type  :help sponsor<Enter>    for information
~
~                type  :q<Enter>               to exit
~                type  :help<Enter>  or  <F1>  for on-line help
~                type  :help version7<Enter>   for version info

ki bu aslında kullandığımı gösteriyor vim. Bilgisayarımdan SSH kullanarak uzak bir Ubuntu Linux kümesine erişiyorum. Bir Ubuntu Linux GUI kullanmıyorum.

Yanıtlar:


22

Kullanabilirsiniz:

:6,8s/^#//

Ancak Görsel Seçimi Engelle modunu kullanmak çok daha kolaydır: 6. satırın başına Ctrl-vgidin , düğmesine basın , 8. satıra gidin ve düğmesine basın x.

Ayrıca "NERD Commenter" eklentisi de var.


2
NERD Commenterbence buraya gitmenin yolu! Bunun için +1
user1146332

7

Ben kullanarak soru belirliyorsa biliyor viya vimelle dosyayı açmak zorunda kalmadan bu iş için birkaç seçenek daha ama burada şunlardır:

  • Perl

    perl -ne 'if($. <=8 && $. >= 6){s/^\s*#//;}print' foo.sh 
    
  • Perl sürümü> = 5.10

    perl -ne '$. ~~ [6..8] && s/^\s*#//;print' foo.sh 
    

    Bu, dosyanın içeriğini yazdırır, başka birine ( > new_file.sh) yönlendirebilir veya idosyayı yerinde düzenlemek için kullanabilirsiniz :

    perl -i -ne '$. ~~ [6..8] && s/^\s*#//;print' foo.sh 
    
  • sed

    sed '6,8 s/^ *#//' foo.sh
    

    Yine, bunun orijinal dosyayı yerinde düzenlemesini sağlamak için şunu kullanın i:

    sed -i '6,8 s/^ *#//' foo.sh
    
  • awk/ gawketc:

    gawk '(NR<=8 && NR>= 6){sub("^ *#","")}{print}' foo.sh
    
  • Saf bash:

    c=1; while read line; do 
      if [ $c -ge 6 ] && [ $c -le 8 ]; then 
         echo "${line/\#/}"
      else 
         echo $line 
      fi
      let c++; done < foo.sh
    

1
Bu, "dosyayı manuel olarak açmak zorunda" meselesi değildir, çünkü genellikle düzenleme sırasında görsel incelemeye hangi satırların yorumlanacağına siz karar verirsiniz :) Ama elbette, bu tamlık için iyi bir cevaptır.
Paulo Almeida

2
@PauloAlmeida elbette haklısın. OP'nin satır numaralarını bildiği için yararlı olabileceğini düşündüm (çünkü bunları yorumlamak için kullanılan ilk komut nedeniyle) ve her durumda gösterdiğim araçlar çeşitli sorunlara uygulanabilir.
terdon

4

vivimçoğu GNU / Linux dağıtımında sembolik bir bağlantı vimolduğundan yazarken gerçekten kullanıyorsunuz vi.

Yorumları kaldırmak için şunu yazabilirsiniz: :6,8s/^#//veya  simgeden :6,8s/^\s*#//önce bazı önde gelen boşlukları atabilirsiniz #.


1
Çok teşekkürler. Yazım hataları olabilir gibi görünüyor. Belki olmalı :6,8s/^#//ve 6,8s/^\s*#//?
Andrew

3

Muhtemelen kullanıyorsunuz vim.tiny. Her durumda, ilk yorumları şu şekilde kaldırabilirsiniz:

:6,8s/^#//

Tabii ki, bunları farklı bir şekilde eklerseniz (örneğin, fazladan bir boşlukla), orada başka ne varsa kaldırmanız gerekebilir. Tam vim ile, sütunları görsel olarak seçmek ve karakter eklemek / silmek aynı şeyi yapmanın daha kolay bir yoludur.


3

Şahsen favori yolum görsel blok modunu kullanmak

ctrl+ vgörsel blok moduna girmek için ok tuşlarını veya hjkl tuşlarını kullanarak satırları seçin ve xveya tuşuna basın del.

Onları geri mi istiyorsun?

ctrl+ vseçimi yapın, sonra I(büyük harf i)#Esc


3

AFAIK, vi genellikle günümüzde bir vim symlink'idir (deneyin which viveya type viardından simgeleri izleyin). Belki, hatta /usr/bin/vi-> /etc/alternatives/vi-> /usr/bin/vim.basic.

Şahsen, birden fazla yorum satırını kaldırmak için dikey bir blok seçip CtrlVsilmeyi tercih ederim . Birden satıra bir açıklama sembolü eklenecek gerekiyorsa, olabilir CtrlV, o zaman ShiftI, yazın #ve Escve bir açıklama birden fazla satır eklenecektir.


2

Yukarıdaki cevaplar,

:6,8s/^#//

mükemmel bir çözümdür, ancak yazması biraz zahmetlidir. Bu, içindeki yeni komutlar tanımlanarak basitleştirilebilir ~/.vimrc.

command -range=% C :<line1>,<line2>s/^/#/
command -range=% D :<line1>,<line2>s/^#//

Ve sadece yazabilirsiniz

:6,8C
:6,8D

komutu yerleştirmek / silmek için.

Görsel moddan hoşlanıyorsanız, haritalar tanımlayabilirsiniz

map <F7> :s/^/#/<CR>
map <F8> :s/^#//<CR>

Eğer sadece görsel modda ve basında bir satır aralığı seçmek zorunda tür F7ve F8sırasıyla yorumlar koymak ve kaldırmak için.


1

tpopeDenilen bu hayat değiştiren eklenti varvim-commentary

https://github.com/tpope/vim-commentary

Bu eklenti şunları sağlar :

  • Akıl sağlığı
  • Girintili yorumlar
  • Boş / gereksiz satırları yorumlamaz

Kullanımı :

  • Vundle (veya sanırım Patojen) ile kurun.
  • Metninizi vurgulayın ve simgesine basın :.:<,'>
  • Buraya Commentary yazın :<,'>Commentaryve enter tuşuna basın.
  • Bom. Yaptığın tomurcuk.

1

Bu cevap bir yapıştırmak için doğru kodu göstermek burada 1'e) 'dir .vimrcalmak için vim 7.4+açıklamak için 1 görsel modunda kısayol ve 2) ile girinti düzeyini korurken uncommenting / yorumlama bloğunu yapmak.

İşte kod:

let b:commentChar='//'
autocmd BufNewFile,BufReadPost *.[ch]    let b:commentChar='//'
autocmd BufNewFile,BufReadPost *.cpp    let b:commentChar='//'
autocmd BufNewFile,BufReadPost *.py    let b:commentChar='#'
autocmd BufNewFile,BufReadPost *.*sh    let b:commentChar='#'
function! Docomment ()
  "make comments on all the lines we've grabbed
  execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e'
endfunction
function! Uncomment ()
  "uncomment on all our lines
  execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e'
endfunction
function! Comment ()
  "does the first line begin with a comment?
  let l:line=getpos("'<")[1]
  "if there's a match
  if match(getline(l:line), '^\s*'.b:commentChar)>-1
    call Uncomment()
  else
    call Docomment()
  endif
endfunction
vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>

Nasıl çalışır:

  • let b:commentChar='//': Bu vim'de bir değişken oluşturur. bburada, bu durumda, şu anda açılmış bir dosyayı, yani tampon içerdiği kapsamı, ifade eder. Yorum karakterleriniz dizelerdir ve tırnak işaretleri içine alınmalıdır; tırnak işaretleri, yorumlar arasında geçiş yapılırken değiştirilecek öğenin bir parçası değildir.

  • autocmd BufNewFile,BufReadPost *...: Otomatik komutlar farklı şeyleri tetikler, bu durumda bunlar yeni bir dosya veya okuma dosyası belirli bir uzantıyla sona erdiğinde tetiklenir. Tetiklendiğinde, commentChardosya türüne bağlı olarak değiştirmemizi sağlayan aşağıdaki komutu yürütün . Bunu yapmanın başka yolları da var, ama acemiler için daha kafa karıştırıcılar (benim gibi).

  • function! Docomment(): Fonksiyonlar ile başlayan tarafından ilan edilir functionve ile biten endfunction. İşlevler büyük harfle başlamalıdır. !Bu fonksiyon olarak tanımlanan önceki işlevleri üzerine yazar olmasını sağlar Docomment()bu sürümü ile Docomment(). Olmadan, !hatalar vardı, ama bunun nedeni vim komut satırı üzerinden yeni işlevler tanımlamak olabilir.

  • execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e': Execute komutu çağırır. Bu durumda, tüm arabellek veya vurgulanan bölüm substitutegibi bir aralık alabilen (varsayılan olarak bu geçerli satırdır) yürütüyoruz . bir satırın başlangıcına ve ardından herhangi bir miktarda boşlukla eşleşecek şekilde regex olur ve bu satır daha sonra (nedeniyle ) eklenir . Beri burada, dize birleştirme için kullanılan kutu tırnak sarılmış edilemez. bağımsız değişkenlerle eşleşen karakterden (bu örnekte ve ) a ile başlayarak kaçmanıza olanak tanır . Bundan sonra, dizgimizin sonuna ,%'<,'>^\s*&.escape()escape()commentChar\/\substituteebayrağı. Bu bayrak sessizce başarısız olmamıza izin verir, yani belirli bir hatta bir eşleşme bulamazsak, bağırmayacağız. Bir bütün olarak, bu satır bir yorum karakteri ve ardından ilk metinden hemen önce boşluk bırakmamızı sağlar, yani girinti seviyemizi koruruz.

  • execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e': Bu bizim son muazzam uzun komutumuza benzer. Bu benzersiz \volan, bizim (), kaçmak zorunda kalmamızı 1sağlayan ve bizim ile yaptığımız grubu ifade eden var (). Temel olarak, herhangi bir miktarda boşlukla başlayan bir çizgiyi ve ardından yorum karakterimizi ve ardından herhangi bir boşluk alanını eşleştiriyoruz ve yalnızca ilk boşluk kümesini koruyoruz. Yine, ebu satırda bir yorum karakteri yoksa sessizce başarısız olalım.

  • let l:line=getpos("'<")[1]: Bu, yorum karakterimizde yaptığımız gibi bir değişkeni ayarlar, ancak lyerel kapsamı ifade eder (bu işleve yerel). getpos()bu durumda vurgulamanın başlangıcını [1]ve sütun numarası gibi diğer şeyleri değil, yalnızca satır numarasını önemsediğimiz anlamına gelir.

  • if match(getline(l:line), '^\s*'.b:commentChar)>-1: nasıl ifçalıştığını biliyorsun . match()ilk şeyin ikinci şeyi içerip içermediğini kontrol eder, bu yüzden vurgulamaya başladığımız satırı yakalarız ve boşlukla başlayıp yorum karakterinizle başlayıp başlamadığını kontrol ederiz. match()bunun doğru olduğu ve -1eşleşme bulunmayan dizini döndürür . Yana ifdeğerlendirir tüm sıfırdan farklı sayılar gerçek olamayacak kadar, bunun daha -1 büyük olup olmadığını görmek için bizim çıkış karşılaştırmak gerekir. vimYanlışsa 0, doğru ise 1 ile karşılaştırma, ifdoğru değerlendirmek için görmek isteyen budur .

  • vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>: vnoremapaşağıdaki komutu görsel modda eşlemek anlamına gelir, ancak yinelemeli olarak eşlemeyin (yani başka şekillerde kullanabilecek diğer komutları değiştirmeyin). Temel olarak, bir vim acemi iseniz, her zaman bir noremapşeyleri kırmadığınızdan emin olmak için kullanın . <silent>"Kelimelerinizi istemiyorum, sadece eylemleriniz" anlamına gelir ve komut satırına hiçbir şey yazdırmamasını söyler. <C-r>eşleme yaptığımız şeydir, bu durumda ctrl + r (bu durumda normal modda "yeniden yapmak" için normalde Cr'i kullanabileceğinizi unutmayın). C-ubiraz kafa karıştırıcıdır, ancak temel olarak görsel vurgulamanın izini kaybetmemenizi sağlar ( bu cevaba göre komutunuzun '<,'>istediğimiz şeyle başlamasını sağlar ).callburada vim'e adlandırdığımız işlevi yürütmesini söyler <cr>ve enterdüğmeye basmayı ifade eder . İşlevi gerçekten çağırmak için bir kez vurmak zorundayız (aksi takdirde call function()komut satırına yeni yazdık ve yerine geçmek için yerine basmamız gerekiyor (neden olduğundan emin değilim, ama her neyse).

Her neyse, umarım bu yardımcı olur. Bu vurgulanan şey alacak v, Vya da C-v, ilk satır yorumladı check eğer, evet eğer, tüm vurgulanan satırları uncomment çalışın ve eğer, her bir satırın açıklama karakterlerin bir kat daha ekleyin. İstediğim davranış bu; Sadece bloktaki her satırın yorumlanıp yorumlanmadığını değiştirmek istemedim, bu yüzden konu hakkında birden fazla soru sorduktan sonra benim için mükemmel çalışıyor .

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.