Jak skomentować zestaw linii wybranych w trybie wizualnym?

35

Jak skomentować wiele wybranych linii w trybie wizualnym? Jak sprawić, by był specyficzny dla języka?

Na przykład, jeśli wybrane zostaną pierwsze 4 linie:

def foo(a,b):
    for each in (a,b):
        print each
    return a+b
print "2"

Działanie polecenia / makra powinno spowodować (w pythonie):

#def foo(a,b):
#    for each in (a,b):
#        print each
#    return a+b
print "2"
John HK
źródło

Odpowiedzi:

31

Jeśli chcesz komentować konkretny język, potrzebujesz wtyczki takiej jak nerdcommenter .

Alternatywnie, chociaż nie odpowiada na twoje aktualne pytanie, możesz użyć wbudowanych działań vima i swojej znajomości znaków komentarza w każdym języku ...

Opcja nr 1: V-bloki

  1. :1 Enter (Przejdź do wiersza 1)
  2. Ctrl-V (tryb V-Block)
  3. jjj (W dół o 3 linie więcej)
  4. Shift-I (Wejdź w tryb wstawiania przed blokiem)
  5. # (Wstaw „#”)
  6. Esc (Powrót do trybu normalnego)

Opcja nr 2: Zmiana

:1,4s/^/#/

Awaria:

  1. : Następuje polecenie Ex
  2. 1,4 na liniach od 1 do 4
  3. s zastąpić
  4. /separator dla kawałków polecenia podstawienia.
    (Możesz także użyć innej postaci, np. :)
  5. ^ początek linii
  6. / separator
  7. # znak komentarza dla Pythona
  8. / separator końcowy

Opcja nr 3: Powtórz zastosowanie makra ( źródło )

  1. :1 Enter (Przejdź do wiersza 1)
  2. qa(Rozpocznij nagrywanie przy rejestracji a)
  3. Shift-I (Wejdź w tryb wstawiania na początku wiersza
  4. # (Dodaj „#” na początku wiersza)
  5. Esc (Powrót do trybu normalnego)
  6. q (Zatrzymaj nagrywanie)

  7. :2,4 normal @a(ponownie uruchom zarejestrowane makro, aby zarejestrować się ana liniach od 2 do 4)

    LUB

    możesz wybrać linie w trybie wizualnym i nacisnąć, :aby automatycznie wypełnić linię Ex :'<,'>(zakres od początku do końca zaznaczenia wizualnego), a następnie wpisać normal @ai nacisnąć Enter( źródło ).

Teraz, ilekroć chcesz skomentować niektóre linie, po prostu uruchom ponownie zarejestrowane makro, aby zarejestrować się ana tych liniach:

:9,22 normal @a (comment out lines 9-22)
bsmith89
źródło
1
Opcja 4: Wtyczka
ankieta Cody
Nie rozumiem, dlaczego używasz makra do pojedynczego polecenia, skoro możesz to zrobić :9,22 normal I#zgodnie z moją odpowiedzią.
Ben
Dlaczego miałbyś używać: 1 <enter>, kiedy możesz używać gg?
Tanath,
@Tanath Komentowanie od pierwszego wiersza było specyficzne dla tego przykładu. Gdyby autor chciał skomentować z linii od 9 do 22, nie byłby w stanie użyć gg.
bsmith89,
@ Ben Nie wiedziałem nic o normalpoleceniu przed napisaniem tej odpowiedzi. Masz rację; :9,22 normal I#będzie również działać.
bsmith89,
26

Korzystając z trybu Visual Block ( CtrlV), wybierz początek linii. Następnie naciśnij I#(to duża litera I), aby wstawić znak skrótu w każdej z tych linii. Następnie naciśnij, Escaby powrócić z trybu wstawiania do trybu normalnego.

200_sukces
źródło
Nie działa mi. Wstawia komentarz tylko w pierwszym wierszu.
gon1332
Pchasz ctrl? Ponieważ ctrl+vto coś innego niż sprawiedliwy v.
Cody Poll
@CodyPoll Wiem. Wszystko jest w porządku I. Kiedy nacisnę I, #zostanie umieszczony tylko przed pierwszą linią.
gon1332
@CodyPoll Ok .. Byłem tylko hospitalizowany. Nie naciskałem Escpo opisanej procedurze.
gon1332
@ gon1332, o ile wiem, że musisz nacisnąć Escna końcu.
Gonçalo Ribeiro,
18

Jeśli potrzebujesz szybkiego rozwiązania dla dowolnego języka, w którym aktualnie się znajdujesz, a tekst jest już zaznaczony w trybie wizualnym, to

:norm 0i#

wykonuje pracę. (Dla każdego wiersza, w trybie normalnym, przejdź do pierwszej kolumny i wstaw #. Użycie :norm I#spowoduje wstawienie go przed pierwszym znakiem spacji, który może nie być tym, czego chcesz.) Użycie :norm i#będzie również działać, ponieważ :normzaczyna się na początku linia, ale jest mniej wyraźna i mniej wyraźna, jeśli o tym nie wiesz.

Oczywiście, jeśli zamierzasz to robić często, będziesz chciał skonfigurować mapowanie lub poszukać wtyczki.

wchargin
źródło
1
0 nie jest potrzebne, ponieważ domyślnie normalpolecenie jest wykonywane kursorem na początku wiersza.
nitishch
1
Oczywiście za pomocą tego polecenia można poprzedzić numery wierszy,%, znaki. Przykład: 1,5norm i # (lub): 'a,' bnorm i # (lub): 10% norma i #
SibiCoder
9

Wykonanie tego automatycznie wymagałoby dodania do vimrcpliku ( źródła ) czegoś takiego :

au FileType haskell,vhdl,ada let b:comment_leader = '-- '
au FileType vim let b:comment_leader = '" '
au FileType c,cpp,java let b:comment_leader = '// '
au FileType sh,make let b:comment_leader = '# '
au FileType tex let b:comment_leader = '% '
noremap <silent> ,c :<C-B>sil <C-E>s/^/<C-R>=escape(b:comment_leader,'\/')<CR>/<CR>:noh<CR>
noremap <silent> ,u :<C-B>sil <C-E>s/^\V<C-R>=escape(b:comment_leader,'\/')<CR>//e<CR>:noh<CR>

Używanie ,cdo komentowania regionu i ,uodkomentowania regionu. To ręcznie ustawia symbole komentarzy dla różnych języków.

Drugą opcją jest użycie wtyczki, takiej jak tcomment , vim-commentary lub comments.vim . Sam używam tcommentu. Proszę przeczytać instrukcje użytkowania i instalacji na ich stronach, ponieważ uważam, że jest to poza tematem pytania.

Sugeruję użycie wtyczki (jednej z powyższych linków), ponieważ jest to o wiele łatwiejsze niż utrzymanie fragmentu kodu w vimrcpliku.

Edycja: Usunąłem sposób ręczny, ponieważ pytanie zostało zmienione, a poprawny sposób odpowiedział również 200_success.

tokoyami
źródło
Dodatkowa sugestia wtyczki: Komentator
dał
Uwaga: obsługuje to tylko komentarze linii. Na przykład ANSI C nie rozpoznaje //(tylko /* */).
wchargin
Chociaż podoba mi się to podejście, czy istnieje sposób, aby przełączać komentarze?
ideasman42
1
@ ideasman42 Trzeba by zamiast tego zrobić funkcję i sprawdzić, czy bieżąca linia zaczyna się od komentarza, a następnie w zależności od tego wywołania jednego z :spoleceń pokazanych we fragmencie odpowiedzi. Sam czek byłby podobny getline('.') =~ "^" . escape(b:comment_leader, '\/'). Jeśli to prawdziwa niepomoc, skomentuj. Nie jest to testowane i powinno służyć jedynie jako przykład.
tokoyami
5

Używam scrooloose / nerdcommenter do tego.

Dzięki tej wtyczce możesz wizualnie wybrać swoje linie i nacisnąć leader+, caby przełączać komentarze. W zależności od typu pliku do komentowania będą używane różne symbole.

OrangeTux
źródło
5

Po wybraniu linii wystarczy wpisać

:norm I#

:automatycznie umieści '<,'>w linii poleceń, która jest zakresem od początku twojego wyboru do końca; normwykonuje polecenie w trybie normalnym i będzie działać w tym zakresie; I#to polecenie trybu normalnego, które wstawia „#” na początku wiersza.

Ben
źródło
4

Jestem za to wielkim fanem TComment ; nie tylko mogę tworzyć style komentarzy specyficzne dla typu pliku, ale nawet określać blok vs wiersz dla języków, które obsługują komentarze blokowe.

    gc{motion}   :: Toggle comments (for small comments within one line 
                    the &filetype_inline style will be used, if 
                    defined)
    gcc          :: Toggle comment for the current line

Explicit commenting/uncommenting:

    g<{motion}   :: Uncomment region
    g<c          :: Uncomment the current line
    g<b          :: Uncomment the current region as block

    g>{motion}   :: Comment region
    g>c          :: Comment the current line
    g>b          :: Comment the current region as block

In visual mode:

    gc           :: Toggle comments
    gC           :: Comment selected text
Collin Grady
źródło
Dzięki za odpowiedź! Czy mógłbyś to rozwinąć? Podawanie odpowiedzi na wtyczki jest w porządku, ale w tej chwili jest to tylko link do wtyczki. W odpowiedzi oczekuje się przynajmniej podstawowego opisu tego, co robi i jak go używać. zobacz także ten meta post .
Martin Tournoij
Głupio jest kopiować / wklejać skróty klawiszowe, ale proszę bardzo; Już opisałem, co robi.
Collin Grady,
3

Uważam, że wtyczka vim-commentary jest zdecydowanie najłatwiejszym sposobem na zrobienie tego. Wybierz zakres linii, a następnie po prostu naciśnij gc. Użyje odpowiedniego znaku komentarza dla otwartego typu pliku. Jest nawet możliwe bez wizualnej selekcji, aby odkomentować sąsiednie komentowane linie za pomocą gculub gcgc.

Andrew Ferrier
źródło
2

Zakładając, że chcesz dodać prefiks do 5 linii na początku linii, możesz użyć Wyszukaj i zamień :

:.,+5s/^/prefix_/g

lub na końcu linii:

:.,+5s/$/suffix_/g

Lub użyj trybu wizualnego ( Ctrl+ v), aby zaznaczyć pionowy blok tekstu, a następnie wejdź w tryb wstawiania ( I) i wpisz coś, a następnie naciśnij, Escaby potwierdzić i zastosować zmiany w innych wierszach.

Związane z:

kenorb
źródło
2

Ta odpowiedź jest tutaj, aby 1) pokazują prawidłowy kod aby wkleić do .vimrcdostać vim 7.4+zrobić blok komentując / odkomentowanie utrzymując poziom wcięcia z 1 skrót w trybie wizualnym i 2), aby ją wyjaśnić.

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

Jak to działa:

  • let b:commentChar='//': To tworzy zmienną w vimie. btutaj odnosi się do zakresu, w tym przypadku jest zawarte w buforze, co oznacza, że obecnie otwarty plik. Znaki komentarza są ciągami znaków i muszą być zawinięte w cytaty, cytaty nie są częścią tego, co zostanie zastąpione podczas przełączania komentarzy.

  • autocmd BufNewFile,BufReadPost *...: Komendy automatyczne uruchamiają różne rzeczy, w tym przypadku są one uruchamiane, gdy nowy plik lub plik odczytu kończy się określonym rozszerzeniem. Po uruchomieniu wykonaj następujące polecenie, które pozwala nam zmienić commentCharzależnie od rodzaju pliku. Są na to inne sposoby, ale są bardziej mylące dla nowicjuszy (takich jak ja).

  • function! Docomment(): Funkcje są deklarowane, zaczynając od functioni kończąc na endfunction. Funkcje muszą zaczynać się od dużej. to !gwarantuje, że funkcja ta zastępuje wszystkie poprzednie funkcje zdefiniowane jak Docomment()z tą wersją Docomment(). Bez tego !miałem błędy, ale mogło to wynikać z tego, że definiowałem nowe funkcje za pomocą wiersza poleceń vim.

  • execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e': Wykonaj wywołuje polecenie. W tym przypadku wykonujemy substitute, który może przyjmować zakres (domyślnie jest to bieżący wiersz), na przykład %dla całego bufora lub '<,'>podświetlonej sekcji. ^\s*jest wyrażeniem regularnym pasującym do początku linii, po której następuje dowolna ilość białych znaków, które są następnie dodawane do (z powodu &). .Tutaj służy do łańcuchów znaków, gdyż escape()nie może być owinięty w cudzysłowach. escape()pozwala na ucieczkę znaku, commentCharktóry pasuje do argumentów (w tym przypadku \i /), poprzedzając je znakiem \. Następnie ponownie łączymy się z końcem naszego substitutełańcucha, który maeflaga. Ta flaga pozwala nam po cichu zawieść, co oznacza, że ​​jeśli nie znajdziemy dopasowania w danej linii, nie będziemy o tym krzyczeć. Jako całość, ten wiersz pozwala nam wstawić znak komentarza, po którym następuje spacja tuż przed pierwszym tekstem, co oznacza, że ​​utrzymujemy poziom wcięcia.

  • execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e': Jest to podobne do naszego ostatniego wielkiego długiego polecenia. Unikatowe dla tego, co mamy \v, zapewnia, że ​​nie musimy uciekać przed naszym (), i 1które odnosi się do grupy, którą stworzyliśmy z naszą (). Zasadniczo dopasowujemy linię zaczynającą się od dowolnej ilości białych znaków, a następnie nasz znak komentarza, po którym następuje dowolna ilość białych znaków, i zachowujemy tylko pierwszy zestaw białych znaków. Ponownie, epo cichu zawiedźmy, jeśli nie mamy znaku komentarza w tym wierszu.

  • let l:line=getpos("'<")[1]: ustawia zmienną podobnie jak w przypadku naszego znaku komentarza, ale lodnosi się do zasięgu lokalnego (lokalnego dla tej funkcji). getpos()otrzymuje pozycję, w tym przypadku, początku naszego wyróżnienia i [1]oznacza, że ​​dbamy tylko o numer linii, a nie o inne rzeczy, takie jak numer kolumny.

  • if match(getline(l:line), '^\s*'.b:commentChar)>-1: wiesz jak ifdziała. match()sprawdza, czy pierwsza rzecz zawiera drugą rzecz, więc chwytamy linię, od której zaczęliśmy wyróżnianie, i sprawdzamy, czy zaczyna się od białych znaków, po których następuje znak komentarza. match()zwraca indeks, w którym jest to prawda, i -1jeśli nie znaleziono żadnych dopasowań. Ponieważ ifocenia, że ​​wszystkie niezerowe liczby są prawdziwe, musimy porównać nasze dane wyjściowe, aby zobaczyć, czy są większe niż -1. Porównanie vimzwraca 0, jeśli jest fałszem, i 1, jeśli jest prawdą, co ifchce zobaczyć, aby poprawnie ocenić.

  • vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>: vnoremapoznacza odwzoruj następujące polecenie w trybie wizualnym, ale nie mapuj go rekurencyjnie (co oznacza, że ​​nie zmieniaj żadnych innych poleceń, które mogłyby być użyte w inny sposób). Zasadniczo, jeśli jesteś początkującym vimem, zawsze używaj, noremapaby upewnić się, że nie psujesz rzeczy. <silent>oznacza „Nie chcę twoich słów, tylko twoje działania” i mówi, aby nie drukował niczego w wierszu poleceń. <C-r>to jest to, co mapujemy, czyli ctrl + r w tym przypadku (zwróć uwagę, że nadal możesz używać Cr normalnie do „ponawiania” w trybie normalnym z tym mapowaniem). C-ujest trochę mylące, ale zasadniczo zapewnia, że ​​nie stracisz kontroli nad wizualnym podświetlaniem (zgodnie z tą odpowiedzią powoduje, że twoje polecenie zaczyna od '<,'>tego, czego chcemy).calltutaj po prostu każe vimowi wykonać funkcję, którą nazwaliśmy, i <cr>odnosi się do naciśnięcia enterprzycisku. Musimy go nacisnąć raz, aby faktycznie wywołać tę funkcję (w przeciwnym razie właśnie wpisaliśmy call function()wiersz poleceń i musimy nacisnąć go ponownie, aby nasze substytuty przeszły przez całą drogę (nie do końca pewni dlaczego, ale cokolwiek).

W każdym razie mam nadzieję, że to pomaga. Spowoduje to, że wszystko wyróżnione za pomocą v, Vlub C-vsprawdzi, czy pierwszy wiersz jest skomentowany, jeśli tak, spróbuj usunąć zaznaczenie wszystkich wyróżnionych linii, a jeśli nie, dodaj dodatkową warstwę znaków komentarza do każdej linii. To jest moje pożądane zachowanie; Nie chciałem tylko, aby przełączało się, czy każda linia w bloku była komentowana, czy nie, więc działa to idealnie dla mnie po zadaniu wielu pytań na ten temat.

jeremysprofile
źródło