Jaki jest szybki sposób komentowania / usuwania komentarzy w Vimie?


1167

Mam plik kodu Ruby otwarty w vi, istnieją linie skomentowane za pomocą #:

class Search < ActiveRecord::Migration
  def self.up
    # create_table :searches do |t|
    #   t.integer :user_id
    #   t.string :name
    #   t.string :all_of
    #   t.string :any_of
    #   t.string :none_of
    #   t.string :exact_phrase
    # 
    #   t.timestamps
    # end
  end

  def self.down
    # drop_table :searches
  end
end

Powiedz, że chcę odkomentować wszystkie wiersze w pierwszej def ... endsekcji. Jak skutecznie to zrobić w Vimie?

Zasadniczo szukam łatwego i płynnego sposobu komentowania i komentowania linii. Tutaj mam do czynienia z kodem Ruby, ale może to być JavaScript ( //) lub Haml ( -#).


20
Zaakceptowana odpowiedź powinna zostać zmieniona na jedną z odpowiedzi, która zawiera szczegółowe instrukcje, jak wykonać komentowanie / odkomentowanie bloków bez użycia wtyczki. Prąd odpowiedź akceptowana jest w zasadzie tylko link do wtyczki firm trzecich.
faintsignal

Najwyżej oceniana odpowiedź nie wspomina o żadnych wtyczkach, @rationalis twój komentarz jest mylący, czy możesz go poprawić lub usunąć, dziękuję.
bonobo

Odpowiedzi:


180

Używam skryptu komentującego NERD . Pozwala łatwo komentować, odkomentować lub przełączać komentarze w kodzie.

Jak wspomniano w komentarzach :

dla każdego, kto jest zdezorientowany użytkowaniem, domyślnym liderem jest „\”, więc 10 \ cc skomentuje dziesięć linii, a 10 \ cu odkomentuje te dziesięć linii


Ciekawy! Czytam Dokument i stwierdzam, że jest „seksowny komentarz” - wystarczy użyć „\ cs”. W przypadku Ruby będzie używać =begini =endkomentować wiele wierszy zamiast znaczników skrótu.
Hegwin,

Myślę, że nie jest to najszybszy sposób na wykonanie tego z vimem, ponieważ wymaga zainstalowania wtyczki. Również najlepsza odpowiedź otrzymała już więcej głosów, ale nie została oznaczona jako rozwiązanie.
whirmill

136
Nie zatrzymuj się tutaj. Większość głosowanych odpowiedzi znajduje się poniżej bez żadnych wtyczek. stackoverflow.com/a/15588798/2117868 i stackoverflow.com/a/1676690/2117868
kuttumiah

@whirmill Myślę, że „najlepszy” naprawdę zależy od przypadku użycia. Tryb wizualnego blokowania jest szybszy, jeśli chcę raz zamienić komentarze. Ale jeśli nie mam nic przeciwko instalowaniu wtyczki i chcę wykonać jak najmniejszą liczbę naciśnięć klawiszy, aby przełączać komentarze i nie muszę rozróżniać operacji między dodawaniem lub usuwaniem komentarzy - może to być „najlepsza odpowiedź”.
Carolus,

@Carolus Zgodziłbym się z tobą, gdyby pytanie zaczęło się od „jaki jest najlepszy sposób” zamiast „jaki jest szybki sposób”.
Whirmill

2539

Do tych zadań używam większości bloków czasowych .

Umieść kursor na pierwszym #znaku, naciśnij CtrlV(lub CtrlQgVim) i idź w dół, aż do ostatniego komentarza, i naciśnij x, aby usunąć wszystkie #znaki w pionie.

Komentowanie bloku tekstu jest prawie takie samo:

  1. Najpierw przejdź do pierwszego wiersza, który chcesz skomentować, naciśnij CtrlV. Spowoduje to przejście edytora do VISUAL BLOCKtrybu.
  2. Następnie za pomocą klawisza strzałki i wybierz do ostatniej linii
  3. Teraz naciśnij ShiftI, co przełączy edytor w INSERTtryb, a następnie naciśnij #. Spowoduje to dodanie skrótu do pierwszego wiersza.
  4. Następnie naciśnij Esc(daj mu sekundę), a wstawi #znak we wszystkich innych wybranych wierszach.

W przypadku uproszczonej wersji vima dostarczanej domyślnie z debian / ubuntu, wpisz : s/^/#zamiast tego trzeci krok (wszelkie pozostałe podświetlenia pierwszego znaku każdej linii można usunąć za pomocą :nohl).

Oto dwa małe nagrania ekranowe w celach wizualnych.

Komentarz: Komentarz

Odkomentowanie: Brak komentarza


87
Domyślnie jest to CTRL + V. Wersja gvim dla Windows używa Ctrl + Q, ponieważ Ctrl + V jest już używany do wklejania.
R. Martinho Fernandes,

8
@amindfv Ctrl + V, n (gdzie n to liczba wierszy - 1), j, n(gdzie n liczba liczba długości sekwencji znaków komentarza - 1), l, x.
michael.bartnett,

27
Jak byś to zrobił za pomocą „//”?
AustinT

74
Możesz kliknąć Esc dwa razy, aby nie czekać na sekundę;)
Ahmed Hegazy

44
To nie działało dla mnie. Shift-przeszedłem do prostego trybu wstawiania.
Geremia

826

Aby skomentować bloki w vimie:

  • naciśnij Esc(aby wyjść z trybu edycji lub innego)
  • hit ctrl+ v(tryb blokowania wizualnego)
  • użyj klawiszy strzałek / , aby wybrać żądane linie (nie podświetli wszystkiego - jest OK!)
  • Shift+ i(kapitał I)
  • wstaw żądany tekst, np %
  • naciśnij EscEsc

Aby anulować komentarz do bloków w vimie:

  • naciśnij Esc(aby wyjść z trybu edycji lub innego)
  • trafienie ctrl+ v(tryb blokowania wizualnego)
  • użyj klawiszy strzałek / , aby wybrać linie do anulowania komentarza.

    Jeśli chcesz wybrać wiele znaków, użyj jednego lub połącz te metody:

    • użyj klawiszy strzałek w lewo / w prawo, aby zaznaczyć więcej tekstu
    • aby wybrać fragmenty tekstu użyj shift+ / klawisza strzałki
    • możesz wielokrotnie naciskać poniższe klawisze usuwania, jak zwykły przycisk usuwania

  • naciśnij dlub, xaby usunąć znaki, w razie potrzeby wielokrotnie

33
@amelia: Skrót do komentowania nie działa dla mnie. Shift + i przenosi mnie do trybu wstawiania. Czy to zależy od wersji vima?
user3527975,

7
Dlaczego zajmuje to sekundę?
Conor Patrick

24
Jedyny problem, jaki mam z tą odpowiedzią, to to, że mówi ci ona o używaniu klawiszy strzałek .
cozyconemotel

6
Zamiast tego wciśnij Esc dwa razy. :)
Aaron Alphonsus

21
Na początku włączanie komentarzy nie działało dla mnie, ale po przeczytaniu, że znów działało dobrze: 1. upewnij się, że używasz Ctrl-V, a nie V do zaznaczenia 2. podczas wstawiania pojawi się, gdy modyfikujesz tylko jedną linię 3. wszystkie wstawki zdarzają się, gdy w końcu
naciśniesz

333

Czasami jestem zamknięty w zdalnym polu, w którym moje wtyczki i .vimrc nie mogą mi pomóc, a czasem NerdCommenter źle to robi (np. JavaScript osadzony w HTML).

W takich przypadkach alternatywną technologią jest wbudowane normpolecenie, które po prostu uruchamia dowolne polecenia vim w każdej linii w określonym zakresie. Na przykład:

Komentowanie z # :

1. visually select the text rows (using V as usual)
2. :norm i#

To wstawia „#” na początku każdej linii. Zauważ, że kiedy piszesz: zakres zostanie wypełniony, więc naprawdę będzie wyglądał:'<,'>norm i#

Odkomentowanie # :

1. visually select the text as before (or type gv to re-select the previous selection)
2. :norm x

Usuwa to pierwszy znak każdej linii. Gdybym użył komentarza 2-znakowego, takiego jak //, po prostu zrobiłbym, :norm xxaby usunąć oba znaki.

Jeśli komentarze są wcięte jak w pytaniu PO, możesz zakotwiczyć swoje usunięcie w następujący sposób:

:norm ^x

co oznacza „przejdź do pierwszego spacji, a następnie usuń jeden znak”. Zauważ, że w przeciwieństwie do zaznaczania bloków, ta technika działa nawet jeśli komentarze mają nierówne wcięcia!

Uwaga : Ponieważ normdosłownie wykonuje się zwykłe polecenia vima, nie jesteś ograniczony do komentarzy, możesz również dokonać złożonej edycji każdej linii. Jeśli potrzebujesz znaku zmiany znaczenia jako części sekwencji poleceń, wpisz ctrl-v, a następnie naciśnij klawisz Escape (lub nawet łatwiej, po prostu zapisz szybkie makro, a następnie użyj normy, aby wykonać to makro w każdej linii).

Uwaga 2 : Możesz oczywiście dodać mapowanie, jeśli normczęsto używasz . Np. Wstawienie następującego wiersza w ~ / .vimrc pozwala na pisanie ctrl-nzamiast :normpo dokonaniu wyboru wizualnego

vnoremap <C-n> :norm

Uwaga 3 : Vim Bare-Bones czasami nie manorm skompilowanej komendy, więc pamiętaj, aby użyć rozbudowanej wersji, tj. Zazwyczaj / usr / bin / vim, a nie / bin / vi

(Podziękowania dla @Manbroski i @rakslice za ulepszenia zawarte w tej odpowiedzi)


Myślałem, że tak trzeba, dopóki nie przewinąłem, by przeczytać tę odpowiedź stackoverflow.com/a/1676690/850996 Wybór bloku za pomocą CTRL + V (w przeciwieństwie do wyboru linii za pomocą SHIFT + V) daje znacznie lepszą kontrolę nad tym, gdzie komentarz wstawianie znaków ma miejsce.
Shyam Habarakada

2
@Shyam Technika ctrl-v w połączeniu ze specjalnymi poleceniami tylko do wyboru bloku jest tym, co zaleca większość pozostałych odpowiedzi; jednak osobiście uważam, że technika „norm”, którą opisałem, jest łatwiejsza, ponieważ nie wprowadza żadnej nowej składni oprócz samego polecenia norm, więc mogę ponownie wykorzystać to, co już wiem o vimie.
Magnus

2
Przy odkomentowaniu wciętego bloku warto powiedzieć :norm ^x. Ta metoda ma tę zaletę, że pracuje z zaznaczeniami regionu (np. vi{Wybiera wewnątrz nawiasów klamrowych). Takie selektory obiektów tekstowych nie działają Visual Block.
ivan-k

1
Ach, właśnie się zorientowałem - na centos 6 /bin/vijest vim 7.2, ale jest to inna wersja /usr/bin/vimi ma takie funkcje wyłączone.
rakslice

3
To zdecydowanie najlepsza odpowiedź. Zwłaszcza w połączeniu z, vipaby zaznaczyć cały akapit.
Meh

121

Mam w swoim .vimrc:

" Commenting blocks of code.
autocmd FileType c,cpp,java,scala let b:comment_leader = '// '
autocmd FileType sh,ruby,python   let b:comment_leader = '# '
autocmd FileType conf,fstab       let b:comment_leader = '# '
autocmd FileType tex              let b:comment_leader = '% '
autocmd FileType mail             let b:comment_leader = '> '
autocmd FileType vim              let b:comment_leader = '" '
noremap <silent> ,cc :<C-B>silent <C-E>s/^/<C-R>=escape(b:comment_leader,'\/')<CR>/<CR>:nohlsearch<CR>
noremap <silent> ,cu :<C-B>silent <C-E>s/^\V<C-R>=escape(b:comment_leader,'\/')<CR>//e<CR>:nohlsearch<CR>

Teraz możesz wpisać, ,ccaby skomentować linię i ,cuusunąć komentarz z linii (działa zarówno w trybie normalnym, jak i wizualnym).

(Ukradłem go z jakiejś strony internetowej wiele lat temu, więc nie mogę już całkowicie wyjaśnić, jak to działa :). Jest komentarz, w którym jest wyjaśniony.)


jakiego skrótu powinienem użyć? Nie mogę się upewnić na podstawie samego kodu vim!
gideon

w trybie normalnym lub wizualnym użyj „, cc” (sekwencja 3 znaków), aby skomentować bieżącą linię, i „, cu”, aby anulować komentarz do bieżącej linii.
Dan.

8
lubię to :)! dzięki! Na marginesie nie trudno mi to wytłumaczyć. a) remapuje polecenie (nie rekurencyjnie [zobacz to] ( stackoverflow.com/questions/3776117/… ), więc teraz, gdy naciśniesz, cc: ... wykonanie zostanie wykonane. b) teraz jest to w zasadzie sed (s) / what / towhat / where) zmiana komendy ^ (początek wiersza) na poprawnie ustawiony znak komentarza na podstawie typu pliku, który otworzyłeś c) jak dla cichych rzeczy po prostu tłumią wyjście z komend. d): nohlsearch zatrzymuje podświetlanie wyszukiwania sed
ramrunner,

14
Uwaga: nie jest to właściwy sposób ładowania komend automatycznych. Powinny one znajdować się w grupie aug, w przeciwnym razie będą dodawane, aby vim wiele razy i powodować spowolnienie. Zobacz: learnvimscriptthehardway.stevelosh.com/chapters/14.html . Dodałem odpowiedź na to pytanie.

Miły. To jest faktyczna odpowiedź na pytanie, w jaki sposób (od) komentować, kiedy masz wybór bloku.
Erwin Rooijakkers

119

Określ, które wiersze mają zostać skomentowane w vimie:

Ujawnij numery linii:

:set number

następnie

:5,17s/^/#/     this will comment out line 5-17

albo to:

:%s/^/#/        will comment out all lines in file

11
Ponieważ zmieniasz tylko pierwszy znak każdej linii, nie potrzebujesz litery „g” na końcu
Magnus

1
Niektóre vimty na osadzonych urządzeniach (np. Openwrt) nie mają trybu wizualnego .. To jest cholernie niesamowite :)
cholernie kim0

czy możesz mi wytłumaczyć dlaczego :%s/^/#/g skomentuje wszystkie linie? Zastanawiałem się, jaki jest znak procentu%
Bin

18
Aby odkomentować te linie, możesz napisać: 5,17s / ^ # /
Iraklis Moutidis

Świetny! Naprawdę dobrze działa z zaznaczaniem bloków, takim jak: va{lub z varruby.
Artur Małecki

58

Oto jak to robię:

  1. Przejdź do pierwszego znaku w pierwszym wierszu, który chcesz skomentować.

  2. Naciśnij Ctrl+ qw GVIM lub Ctrl+ vw VIM, a następnie zejdź w dół, aby wybrać pierwszy znak w liniach, aby skomentować.

  3. Następnie naciśnij ci dodaj znak komentarza.

Odkomentowanie działa w ten sam sposób, wystarczy wpisać spację zamiast znaku komentarza.


44
cusuwa również pierwszy znak. Odpowiedź CMS ma rację, tzn. Naciśnięcie, Inastępnie wpisanie znaku (znaków) komentarza, a następnie Esc(tak jest w Windows vim)
Samaursa

6
Działa to, z tym wyjątkiem, że w kroku trzecim należy nacisnąć „r”, a nie „c”.
David Baucum,

alternatywnie możesz nacisnąć ESCdwa razy po naciśnięciu ci to powinno załatwić
sprawę

Wszystkie te opcje niszczą pierwszy znak w linii.
Josiah

36

Wymyśliłem prosty dodatek do mojego pliku .vimrc, który działa całkiem dobrze i można go łatwo rozszerzyć. Po prostu dodajesz nowy typ pliku do mapy comment_map i jej lidera komentarzy.

Dodałem mapowanie do trybów normalnego i wizualnego, ale możesz mapować dowolnie. Wolę mieć tylko funkcję „przełączania”. Jeden nosi wiele mapowań itp.

let s:comment_map = { 
    \   "c": '\/\/',
    \   "cpp": '\/\/',
    \   "go": '\/\/',
    \   "java": '\/\/',
    \   "javascript": '\/\/',
    \   "lua": '--',
    \   "scala": '\/\/',
    \   "php": '\/\/',
    \   "python": '#',
    \   "ruby": '#',
    \   "rust": '\/\/',
    \   "sh": '#',
    \   "desktop": '#',
    \   "fstab": '#',
    \   "conf": '#',
    \   "profile": '#',
    \   "bashrc": '#',
    \   "bash_profile": '#',
    \   "mail": '>',
    \   "eml": '>',
    \   "bat": 'REM',
    \   "ahk": ';',
    \   "vim": '"',
    \   "tex": '%',
    \ }

function! ToggleComment()
    if has_key(s:comment_map, &filetype)
        let comment_leader = s:comment_map[&filetype]
        if getline('.') =~ "^\\s*" . comment_leader . " " 
            " Uncomment the line
            execute "silent s/^\\(\\s*\\)" . comment_leader . " /\\1/"
        else 
            if getline('.') =~ "^\\s*" . comment_leader
                " Uncomment the line
                execute "silent s/^\\(\\s*\\)" . comment_leader . "/\\1/"
            else
                " Comment the line
                execute "silent s/^\\(\\s*\\)/\\1" . comment_leader . " /"
            end
        end
    else
        echo "No comment leader found for filetype"
    end
endfunction


nnoremap <leader><Space> :call ToggleComment()<cr>
vnoremap <leader><Space> :call ToggleComment()<cr>

Uwaga:

Nie używam żadnych wywołań zwrotnych ani przechwytywania typów plików / ładowania, ponieważ uważam, że spowalniają one uruchamianie Vima bardziej niż .vimrcfunkcja statyczna / mapa, ale to tylko moje preferencje. Starałem się również zachować prostotę i wydajność. Jeśli korzystasz z komend automatycznych, musisz je umieścić w grupie komend automatycznych, w przeciwnym razie wywołania zwrotne zostaną dodane do typu pliku wiele razy dla każdego załadowanego pliku i spowodują znaczne pogorszenie wydajności.


1
Jestem całkowicie nowy w vimie, jaki przycisk powinienem nacisnąć, aby przełączyć funkcję mapowania? Co to za <leader><Space>deklaracja na dole?
Jens Kohl

2
Możesz zastąpić <lider> kluczem takim jak <,>. Następnie naciśniesz, SPACJA, a to przełączy stan komentarza linii. Lider jest tym, kim jest Twój lider, domyślnym <leaderem> Vima jest \, ale możesz ustawić własne, np. „Pozwól mapleader = ',” ”

Świetna odpowiedź, jednak jedna irytacja, komentowanie bloków, które już mają kilka komentarzy, zamieni komentarz na wiersze bez komentarza. QtCreator np. Usuwa komentarze tylko wtedy, gdy wszystkie niepuste linie mają wiodące komentarze, w przeciwnym razie dodaj komentarz wiodący.
ideasman42

1
Zrobiłem nieco inną wersję za pomocą \zsi \zeregex trick, kod stał się trochę mniejszy. widać to tutaj
SergioAraujo

33

Przełącz komentarze

Jeśli wszystko, czego potrzebujesz, to przełączać komentarze , wolę iść z commentary.vim by tpope .

wprowadź opis zdjęcia tutaj

Instalacja

Patogen:

cd ~/.vim/bundle
git clone git://github.com/tpope/vim-commentary.git

wtyczka vim:

Plug 'tpope/vim-commentary'

Vundle:

Plugin 'tpope/vim-commentary'

Dalsze dostosowanie

Dodaj to do pliku .vimrc: noremap <leader>/ :Commentary<cr>

Możesz teraz przełączać komentarze, naciskając Leader+ /, podobnie jak Sublime i Atom.


dzięki! czy w przyszłości będzie wspierać komentowanie css wewnątrz html?
Dan Oak

25

Użyj Control-V, aby wybrać prostokąty tekstu: przejdź do pierwszego #znaku, wpisz Ctrl+ V, przesuń raz w prawo, a następnie w dół, aż do końca komentarzy. Teraz wpisz x: usuwasz wszystkie #znaki, po których następuje jedna spacja.


18

Oto sekcja mojego .vimrc:

"insert and remove comments in visual and normal mode
vmap ,ic :s/^/#/g<CR>:let @/ = ""<CR>
map  ,ic :s/^/#/g<CR>:let @/ = ""<CR>
vmap ,rc :s/^#//g<CR>:let @/ = ""<CR>
map  ,rc :s/^#//g<CR>:let @/ = ""<CR>

W trybie normalnym i wizualnym pozwala mi to naciskać, ,icaby wstawiać komentarze i ,rcusuwać komentarze.


Jest to bardzo pomocne dla początkującego, jak nauczyć się pisać własne .vimrc.
najfajniejsza

3
mapobejmuje tryby normalny i wizualny, więc nie potrzebujesz vmaplinii
doubleDown

Lepsze miejsce jest after/ftplugin/ruby.vim.
Santosh Kumar

również użyć <leader>ici<leader>rc
Hans Kristian

15

Używam vim 7.4 i to działa dla mnie.
Zakładając, że komentujemy / odkomentujemy 3 linie.

Skomentować:

Jeśli linia ma kartę / miejsce na początku:
ctrl + Vczym jjjnastępnie shift + I (cappital i)następnie //wtedy esc esc
, gdy linia ma kartę / miejsce na początku, nadal można wykonać powyżej lub zamiana na c:
ctrl + Vwtedy jjjnastępnie cnastępnie //następnie esc esc

odkomentować:

jeśli linie nie mają na początku tabulacji / spacji:
ctrl + Vwtedy, jjjto ll (lower cap L)wtedyc

gdy linie mają kartę / miejsce na początku, to jedna przestrzeń nad i esc
ctrl + Vwtedy jjjpotem ll (lower cap L)potem cpotem spacepotemesc



9

Mając 30 odpowiedzi przede mną, postaram się podać jeszcze łatwiejsze rozwiązanie: wstawić #na początku wiersza. Następnie przejdź w dół linii i naciśnij kropkę ( .). Aby powtórzyć, czy j, ., j, ., itd ... odkomentowac, usunąć #(można uderzyć xnad #), a nie na odwrót użyciu k, .itp ...


1
To bardzo prosta odpowiedź, którą nawet początkujący może zrozumieć i używać. Jednak działa dość wolno na dużych ilościach komentarzy. Aby obejść ten problem, możesz napisać I#<Esc>jdo bufora - powiedzmy c- a następnie zrobić 10@c, lub dowolną liczbę linii, która ci odpowiada.
Daerdemandt,

9

Jak usunąć komentarz z następujących trzech wierszy w vi:

#code code
#code
#code code code

Umieść kursor nad lewym górnym #symbolem i naciśnij CtrlV. To przełącza cię w tryb wizualnego blokowania. Naciśnij strzałkę w dół lub Jtrzy razy, aby wybrać wszystkie trzy linie. Następnie naciśnij D. Wszystkie komentarze znikają. Aby cofnąć, naciśnij U.

Jak skomentować następujące trzy wiersze w vi:

code code
code
code code code

Umieść kursor nad lewym górnym znakiem, naciśnij CtrlV. To przełącza cię w tryb wizualnego blokowania. Naciśnij lub Jtrzy razy, aby wybrać wszystkie trzy linie. Następnie naciśnij:

I//Esc

To stolica I, // i Escape.

Po naciśnięciu ESCwszystkie wybrane wiersze otrzymają określony symbol komentarza.


1
jeśli przegapisz skrót „lewy górny”, możesz nacisnąć o , aby przesunąć kursor na „drugą stronę” w trybie wizualnym.
dylnmc

Myślę, że najlepiej tego użyć. Nie potrzebujesz żadnych stron trzecich, po prostu użyj natywnego vima
Ardi Nusawan,

najlepsza odpowiedź, prosta i bez stron trzecich
aze

8

Tak, na to pytanie są już 33 (najczęściej powtarzalne) odpowiedzi.

Oto inne podejście do komentowania linii w Vimie: ruchy . Podstawowym pomysłem jest komentowanie lub odkomentowanie wierszy za pomocą tej samej metody, co przeciąganie akapitu przez wpisywanie yiplub usuwanie 2 wierszy przez wpisywanie dj.

Takie podejście pozwoli Ci robić takie rzeczy jak:

  • ccjskomentować następne 2 wiersze i cukodkomentować je;

  • cci{komentować blok i cui{odkomentować;

  • ccipskomentować cały akapit i cuipodkomentować.

  • ccGkomentować wszystko aż do ostatniego wiersza i cuggodkomentować wszystko aż do pierwszego wiersza.

Wszystko czego potrzebujesz to 2 funkcje działające na ruchy i 2 odwzorowania dla każdej funkcji. Po pierwsze, mapowania:

nnoremap <silent> cc  :set opfunc=CommentOut<cr>g@
vnoremap <silent> cc  :<c-u>call  CommentOut(visualmode(), 1)<cr>
nnoremap <silent> cu  :set opfunc=Uncomment<cr>g@
vnoremap <silent> cu  :<c-u>call  Uncomment(visualmode(), 1)<cr>

(Zobacz instrukcję obsługi g@operatora i operatorfunczmiennej).

A teraz funkcje:

function! CommentOut(type, ...)
  if a:0
    silent exe "normal!  :'<,'>s/^/#/\<cr>`<"
  else
    silent exe "normal!  :'[,']s/^/#/\<cr>'["
  endif
endfunction

function! Uncomment(type, ...)
  if a:0
    silent exe "normal!  :'<,'>s/^\\(\\s*\\)#/\\1/\<cr>`<"
  else
    silent exe "normal!  :'[,']s/^\\(\\s*\\)#/\\1/\<cr>`["
  endif
endfunction

Zmodyfikuj powyższe wyrażenia regularne, aby odpowiadały Twojemu gustowi co do tego, gdzie #powinny być:


„Całkowicie nowe [...] ruchy” wydają się nieco przesadzone: wtyczki t_comment i vim-commentary, które poprzedzają tę odpowiedź, umożliwiają komentowanie za pomocą ruchów.
Bogaty

Dobry towar! Pozytywne. (Myślę też, że mógłbym zacząć korzystać z tego podejścia zamiast wtyczki, której wcześniej używałem, więc dziękuję za napisanie go!)
Rich

7

Jeśli znasz już numery linii, to n,ms/# //zadziała.


tak naprawdę powinno to być: n, ms / ^ \ s. # // Ponieważ możesz mieć wiodącą białą spację i możesz nie podążać za hashem jednym
Skip Huffman

7

Zaznaczam pierwszą i ostatnią linię (ma i mb), a następnie robię: „a,” bs / ^ # //


6

Korzystam z EnhancedCommentify . Komentuje wszystko, czego potrzebowałem (języki programowania, skrypty, pliki konfiguracyjne). Używam go z powiązaniami w trybie wizualnym. Po prostu wybierz tekst, który chcesz skomentować i naciśnij co / cc / cd.

vmap co :call EnhancedCommentify('','guess')<CR>
vmap cc :call EnhancedCommentify('','comment')<CR>
vmap cd :call EnhancedCommentify('','decomment')<CR> 

5

Połączyłem odpowiedź Phila i jqno i zamieściłem komentarze ze spacjami:

autocmd FileType c,cpp,java,scala let b:comment_leader = '//'
autocmd FileType sh,ruby,python   let b:comment_leader = '#'
autocmd FileType conf,fstab       let b:comment_leader = '#'
autocmd FileType tex              let b:comment_leader = '%'
autocmd FileType mail             let b:comment_leader = '>'
autocmd FileType vim              let b:comment_leader = '"'
function! CommentToggle()
    execute ':silent! s/\([^ ]\)/' . b:comment_leader . ' \1/'
    execute ':silent! s/^\( *\)' . b:comment_leader . ' \?' . b:comment_leader . ' \?/\1/'
endfunction
map <F7> :call CommentToggle()<CR>

5

Istnieje ta wtyczka zmieniająca życie o tpopenazwievim-commentary

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

Ta wtyczka zapewnia :

  • Zdrowie psychiczne
  • Właściwie wcięte komentarze
  • Nie komentuje pustych / niepotrzebnych wierszy

Zastosowanie :

  • Zainstaluj przez Vundle (lub, jak sądzę, Pathogen).
  • Podświetl swój tekst i naciśnij, :który pokaże się jako:<,'>
  • Wpisz tutaj komentarz :<,'>Commentaryi naciśnij Enter.
  • Bum. Twoja skończona bud.

vim-commentary(podobnie jak wszystkie wtyczki tpope) ma tę zaletę, że jest idiomatyczny vim. gc= „idź komentować”, gcap= „idź komentować akapit” itp.
goldenratio

Czy to może być właśnie edycja odpowiedzi Tima Pope'a autorstwa Jima Stewarta?
jdk1.0

5

Ta odpowiedź jest najbardziej przydatna, jeśli nie możesz zainstalować wtyczek, ale nadal chcesz, aby znaki komentarzy były zgodne z istniejącymi poziomami wcięcia.

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 przyjąć zakres (domyślnie jest to bieżąca linia), 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 naszegosubstitute ł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 nam, że nie musimy uciekać (), 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 wszystkie wartości niezerowe, aby były 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ą, i to właśnie 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).call tutaj, 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 go nacisnąć 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. Zajmie to wszystko podświetlone v, Vlub C-vsprawdzić, czy pierwsza linia jest komentowane, jeśli tak, spróbuj odkomentowaniu wszystkie zaznaczone linie, a jeśli nie, należy dodać dodatkową warstwę znaków Komentarz 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.



3

Możesz użyć komentarza vim przez tpope ( https://github.com/tpope/vim-commentary ), możesz użyć go w następujący sposób:

Wejdź do trybu wizualnego, naciskając

'v'

Następnie naciśnij

'j' repeatedly or e.g 4j to select 4 row

Teraz wystarczy wybrać klawisze:

'gc'

Spowoduje to skomentowanie wszystkich zaznaczeń, aby odkomentować ponowne przeczytanie kluczy:

'gc'

3

Oto podstawową, wkładka opiera się na C-v, a następnie Imetodą opisaną powyżej.

To polecenie ( :Comment) dodaje wybrany ciąg na początku dowolnych wybranych wierszy.

command! -range -nargs=1 Comment :execute "'<,'>normal! <C-v>0I" . <f-args> . "<Esc><Esc>"

Dodaj ten wiersz do swojego, .vimrcaby utworzyć polecenie, które akceptuje pojedynczy argument i umieszcza argument na początku każdego wiersza w bieżącym zaznaczeniu.

Np. Jeśli zaznaczono następujący tekst:

1
2

i uruchomisz to: :Comment //wynikiem będzie:

//1
//2

3

Zaczynając od pomysłów zawartych w odpowiedziach, uruchomiłem własną funkcję komentowania. Włącza i wyłącza komentarze. Może obsługiwać takie rzeczy, jak //print('blue'); //this thing is bluei przełącza pierwszy komentarz. Ponadto dodaje komentarze i pojedynczą spację tam, gdzie znajduje się pierwsza inna biała spacja, a nie na samym początku linii. Dodatkowo nie kopiuje niepotrzebnie białych znaków, ale używa zoomów (: h \ zs dla pomocy), aby uniknąć tej dodatkowej pracy podczas komentowania i wcięcia. Mam nadzieję, że pomaga to minimalistom. Sugestie są mile widziane.

" these lines are needed for ToggleComment()
autocmd FileType c,cpp,java      let b:comment_leader = '//'
autocmd FileType arduino         let b:comment_leader = '//'
autocmd FileType sh,ruby,python  let b:comment_leader = '#'
autocmd FileType zsh             let b:comment_leader = '#'
autocmd FileType conf,fstab      let b:comment_leader = '#'
autocmd FileType matlab,tex      let b:comment_leader = '%'
autocmd FileType vim             let b:comment_leader = '"'

" l:pos   --> cursor position
" l:space --> how many spaces we will use b:comment_leader + ' '

function! ToggleComment()
    if exists('b:comment_leader')
        let l:pos = col('.')
        let l:space = ( &ft =~ '\v(c|cpp|java|arduino)' ? '3' : '2' )
        if getline('.') =~ '\v(\s*|\t*)' .b:comment_leader
            let l:space -= ( getline('.') =~ '\v.*\zs' . b:comment_leader . '(\s+|\t+)@!' ?  1 : 0 )
            execute 'silent s,\v^(\s*|\t*)\zs' .b:comment_leader.'[ ]?,,g'
            let l:pos -= l:space
        else
            exec 'normal! 0i' .b:comment_leader .' '
            let l:pos += l:space
        endif
        call cursor(line("."), l:pos)
    else
        echo 'no comment leader found for filetype'
    end
endfunction

nnoremap <Leader>t :call ToggleComment()<CR>
inoremap <Leader>t <C-o>:call ToggleComment()<CR>
xnoremap <Leader>t :'<,'>call ToggleComment()<CR>

1
Zrobiłem nieco inną wersję twojego rozwiązania, które przywraca również pozycję kursora, chciałbym poznać Twoją opinię na ten temat. w serwisie github
SergioAraujo

Fajne. Możesz edytować mój post i dodać swoje rozwiązanie (ze względu na podobieństwo)!
Mike

Zmieniło się, aby uniknąć odwrotnego ukośnika c, cpp, java i używania innego separatora w podstawieniach, aby uniknąć E488. Zmienia się także odstępy dla java, cpp, ponieważ komentarze mają trzy znaki, // plus spację, odbywa się to przez l: space.
SergioAraujo

3

Używam comments.vim z Jasmeet Singh Anand (znaleziony na vim.org),

Działa z C, C ++, Java, PHP [2345], proc, CSS, HTML, htm, XML, XHTML, vim, vimrc, SQL, sh, ksh, csh, Perl, tex, fortran, ml, caml, ocaml, pliki vhdl, haskel i normal

Komentuje i usuwa komentarze z wierszy w różnych plikach źródłowych zarówno w trybie normalnym, jak i wizualnym

Stosowanie:

  • CtrlCaby skomentować pojedynczą linię
  • CtrlXaby anulować komentarz do jednej linii
  • ShiftVi wybierz wiele linii, a następnie CtrlCskomentuj wybrane wiele linii
  • ShiftVi wybierz wiele linii, a następnie CtrlXcofnij komentarz do wybranych wielu linii

3

Najszybszą i najbardziej intuicyjną metodą ze wszystkich jest ponowne mapowanie w )celu komentowania linii w dół, a następnie w (celu odkomentowania. Spróbuj, a nie wrócisz.

W Ruby lub Bash , z wcięciami 2 spacji:

map ) I# <Esc>j
map ( k^2x

W C / C ++ lub PHP , z wcięciami 4 spacji:

map ) I//  <Esc>j
map ( k^4x

Wadami są to, że przegrywasz (i )przesuwasz zdanie (ale dasmożesz je tam wypełnić), a od czasu do czasu powrócisz do wybierania i zastępowania lub CtrlVdo obsługi długich odcinków. Ale to dość rzadkie.

A w stylu C najlepiej radzić sobie z długimi komentarzami:

set cindent
set formatoptions=tcqr

... Który łączy się dobrze z V[move]gqponownym zawijaniem słów.


2

Ten prosty fragment pochodzi z mojego .vimrc:

function! CommentToggle()
    execute ':silent! s/\([^ ]\)/\/\/ \1/'
    execute ':silent! s/^\( *\)\/\/ \/\/ /\1/'
endfunction

map <F7> :call CommentToggle()<CR>

To jest dla // - Komentarze, ale możesz łatwo dostosować go do innych postaci. Możesz użyć autocmd, aby ustawić lidera zgodnie z sugestią jqno.

Jest to bardzo prosty i wydajny sposób naturalnie pracujący z zasięgami i trybem wizualnym.


2

Lubię /* ... */(komentarze C ansi), więc oto moja sztuczka dla ciebie. Oczywiście możesz go dostosować do użycia w różnych przypadkach.


Komentuj za pomocą / * ... * /

Wybierz tekst (przejdź do początku, uruchom blok wizualny, przeskocz za pomocą }):

<c-V>}

Wpisz polecenie, które ma zostać zastosowane w zaznaczeniu

:norm i/* <c-v><esc>$a */

Polecenie będzie wyglądać następująco: :'<,'>norm i /* ^[$a */

Aby uzyskać szczegółowe informacje, patrz (i *).


Odkomentuj / * ... * /

Wybierz tekst (jak poprzednio lub w inny sposób):

<c-V>}

Wpisz polecenie, które ma zostać zastosowane w zaznaczeniu

:norm :s-\s*/\*\s*-<c-v><enter>$bbld$

Polecenie będzie wyglądać następująco: :'<,'>norm :s-\s*/\*\s*-^M$bbld$

Zobacz szczegóły (ii *).


Wynik

Efektem są komentarze wiersz po wierszu:

Comment block
Comment block
Comment block

Staje się (i odwrotnie):

/* Comment block */
/* Comment block */
/* Comment block */

Lepiej jest zapisać go jako część maplub @regw swoim .vimrc, ponieważ jest dużo do pisania. Jeśli wolisz pojedynczy /*i */cały blok, użyj:

Komentuj za pomocą jednego / * * / całego bloku

Zapisz go w rejestrze, nagrywając np. qcNa początku akapitu, aby skomentować:

v}di/*  */<esc>hhhp

i nie zapomnij qponownie, aby zakończyć rejestrację.

Zobacz szczegóły (iii *).


Odkomentuj pojedynczy / * * / z bloku

Zapisz go w rejestrze, mówią @u. Umieść kursor w dowolnym miejscu bloku i:

?/\*<enter>xx/\*/<enter>xx

Zapisz rejestr, kończąc qpolecenie.

Szczegóły znajdują się w (iv *).


Wynik

Efekt to pojedynczy komentarz dla wielu linii:

Comment block
Comment block
Comment block

Staje się (i odwrotnie):

/* Comment block
Comment block
Comment block */

Objaśnienia

(i *) Działa przy użyciu, normktóry stosuje to samo polecenie wielokrotnie w każdej wybranej linii. Polecenie po prostu wstaw a /*, znajduje koniec tej linii i kończy się wstawiając a*/

:norm i/* <c-v><esc>$a */

(ii *) Służy również normdo powtarzania wyszukiwania / zamiany w każdej linii. Wyszukaj spaces /* spacesi zamień na nic. Następnie znajduje koniec linii, cofnij dwa słowa, popraw literę, usuń do końca.

:norm :s-\s*/\*\s*-<c-v><enter>$bbld$

(iii *) Wybiera akapit poprzez v}, usuń go, wstaw komentarz otwieraj i zamykaj, przejdź do jego środka i wklej usunięty blok.

v}di/*  */<esc>hhhp

(iv *) Gdziekolwiek pośrodku, znajduje wstecz a /*, usuwa je; znajduje do przodu a */, usuwa go.

?/\*<enter>xx/\*/<enter>xx
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.