Vim: Automatischer Kommentar in neuer Zeile

9

Vim fügt automatisch einen Kommentar ein, wenn ich eine neue Zeile aus einer auskommentierten Zeile beginne, da ich festgelegt habe formatoptions=tcroql. Zum Beispiel (Cursor ist *):

// this is a comment*

und nach dem Schlagen <Enter>(Einfügemodus) oder o(Normalmodus) habe ich Folgendes übrig:

// this is a comment
// *

Diese Funktion ist sehr praktisch, wenn Sie lange mehrzeilige Kommentare schreiben, aber oft möchte ich nur einen einzeiligen Kommentar. Wenn ich nun die Kommentarserie beenden möchte, habe ich mehrere Möglichkeiten:

  • schlagen <Esc>S
  • Hit <BS>dreimal

Beide bieten drei Tastenanschläge, zusammengenommen <Enter>bedeutet dies vier Tastenanschläge für eine neue Zeile, was ich für zu viel halte. Im Idealfall möchte ich nur <Enter>ein zweites Mal treffen, um zu bleiben:

// this is a comment
*

Es ist wichtig, dass die Lösung auch mit verschiedenen Einrückungsstufen funktioniert, d. H.

int main(void) {
    // this is a comment*
}

schlagen <Enter>

int main(void) {
    // this is a comment
    // *
}

schlagen <Enter>

int main(void) {
    // this is a comment
    *
}

Ich glaube, ich habe diese Funktion vor einigen Jahren in einem Texteditor gesehen, aber ich kann mich nicht erinnern, welche es war. Ist jemandem eine Lösung bekannt, die dies für mich in Vim erledigt? Hinweise in die richtige Richtung, wie ich meine eigene Lösung entwickeln kann, sind ebenfalls sehr willkommen.

Patrick Oscity
quelle
3
Sie können Strg-U im Einfügemodus verwenden, um die automatisch eingefügten Kommentarmarkierungen in einem Tastenakkord zu löschen.
Etan Reisner
1
@EtanReisner das ist eigentlich besser, aber immer noch ein Tastendruck zu viel für mich, da es so ein häufiger Anwendungsfall ist :)
Patrick Oscity
Sie haben vorgeschlagen, dass Sie erneut die Eingabetaste drücken möchten, um das gewünschte Verhalten zu erzielen, aber Strg-U ist zu viel? Sie könnten versuchen, <enter> <enter> im Einfügemodus zuzuordnen, um die Strg-u automatisch für Sie auszuführen. Dies würde jedoch zu einer Verzögerung führen, wenn Sie <enter> nur einmal drücken (ohne etwas anderes zu treffen).
Etan Reisner
Außerdem sollte es nur ausgelöst werden, wenn die kommentierte Zeile leer ist. Eine merkliche Verzögerung beim Drücken der <Eingabetaste> ist ebenfalls nicht akzeptabel.
Patrick Oscity
Es wird sich nur verzögern, wenn Sie keine anderen Tasten drücken, da vim warten muss, um sicherzustellen, dass Sie nicht noch vorhaben, eine andere Taste zu drücken. Sie könnten auch eine Funktion verwenden, um diese Prüfung durchzuführen, obwohl dies möglicherweise nicht besonders einfach ist.
Etan Reisner

Antworten:

4

Versuche dies:

function! EnterEnter()
  if getline(".") =~ '^\s*\(//\|#\|"\)\s*$'
    return "\<C-u>"
  else
    return "\<CR>"
  endif
endfunction

imap <expr> <CR> EnterEnter()
romainl
quelle
Danke sieht gut aus! Ich werde es versuchen, wenn ich nach Hause komme. Kennen Sie eine Möglichkeit, den regulären Ausdruck so zu erweitern, dass er unabhängig von der Sprache der Kommentarmarkierungen übereinstimmt? Die Informationen sollten in den Syntaxdateien enthalten sein oder so. Vielleicht kann ich die
Syntaxfunktion
Ich meine, in C sollte es mit // und / * und * (mehrzeilige Kommentare) und in Ruby # und so weiter
übereinstimmen
Offensichtlich ist diese Funktion überhaupt nicht generisch. Siehe :h 'comment'und :h format-comment'.
Romainl
Funktion geändert, um zusätzlich zum Klassiker mit #Ruby und "Vimscript zu arbeiten //. Es ist nicht wirklich Sinn machen , etwas für das zu tun , *von C-Stil mehrzeilige Kommentare , weil es muss mit dem Ende */sowieso.
Romainl
Hmm, <CR><CR>könnte vielleicht verwendet werden, um den mehrzeiligen Kommentar zu beenden ...
Romainl
3

Ich habe @ romainls Antwort auf die Arbeit mit beliebigen Sprachen erweitert, indem ich den regulären Ausdruck aus Vims generiert habe &commentstring:

function! s:IsOnlyComment(getlineArg)
  let commentRegex='^\s*'.substitute(&commentstring,'%s','\\s*','').'$'
  return strlen(matchstr(getline(a:getlineArg), commentRegex)) > 0
endfunction

function! SmartEnter()
  if s:IsOnlyComment('.')
    return "\<Esc>S"
  else
    return "\<CR>"
  endif
endfunction

inoremap <expr> <CR> SmartEnter()

Ich kann mich jedoch anscheinend überhaupt nicht neu zuordnen <CR>, dies wird einfach nicht funktionieren. Im Moment benutze ich, <CR><CR>bis dieses Problem behoben ist.

Patrick Oscity
quelle
1
Warum <Esc>S? <C-u>macht das gleiche, ohne den Einfügemodus zu verlassen. Wie auch immer, ich hatte eine benutzerdefinierte Funktion, die eine Reihe von Dingen erledigte <CR>und sie SmartEnter()erst gestern umbenannte, nachdem ich meine Antwort gepostet hatte ;-). Ich bin mir auch nicht sicher, ob &commentstringes die richtige Wahl ist, da es im Allgemeinen nur eine Form enthält und "linienweise" oder "blockweise" sein kann ( /*%s*/in C, //%sin Javascript usw.).
Romainl
2

Entfernen Sie r aus den Formatoptionen. Genau das macht diese Option. Wenn Sie es ausschalten, wird vim das nie für Sie tun, was bedeutet, dass Sie die führenden Kommentarmarkierungen hinzufügen müssen, wenn Sie sie tatsächlich möchten, aber das ist der Kompromiss.

Etan Reisner
quelle
2
Ich möchte eigentlich, dass Vim die Kommentar-Marker für mich hinzufügt. Ich liebe das. Ich möchte aber auch einen schnellen Weg, um den Kommentar zu beenden. Vielen Dank für Ihre Antwort.
Patrick Oscity
Für den normalen Modus ‚o‘ Befehl, muss man entfernen ‚r‘ ausformatoptions
Elig