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.


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()

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.


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.


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.