Wie kann ich ein Autocmd ausführen, wenn ich Vim ohne Datei, nicht vorhandene Datei oder leere Datei starte (aber nicht, wenn ich mit einer vorhandenen Datei beginne)?

11

Ich möchte ein Autocmd in den folgenden Szenarien ausführen, wenn ich Vim starte:

  • Ohne Dateinamen angegeben.
  • Wenn die Datei neu ist.
  • Wenn die Datei vorhanden ist, aber vollständig leer ist.

In allen drei oben genannten Fällen möchte ich ein Autocmd ausführen. Insbesondere möchte ich den Einfügemodus nur für die oben genannten Szenarien automatisch starten (und nicht, wenn ich eine Datei öffne, die bereits vorhanden und nicht leer ist).


AKTUALISIEREN:

Ich habe versucht, Folgendes in mein zu platzieren _vimrc, aber kein Glück (und ich bin mir nicht sicher, ob es in vim eine Funktion gibt, die die Anzahl der Zeichen in einer Datei zählt (um festzustellen, ob sie Null ist), bevor ich sie öffne:

if @% == "" || filereadable(@%)
  autocmd BufRead,BufNewFile * startinsert
endif
John Sonderson
quelle
Nein, dies ist kein Duplikat. Ich möchte, dass vi NUR für die drei Szenarien, die ich erwähnt habe, im Einfügemodus startet.
John Sonderson
3
Okay, ich bin traurig, aber es sah wirklich aus wie ein Duplikat. ;-) Ich habe deine Frage etwas bearbeitet, um die Unterschiede klarer zu machen.
Martin Tournoij
2
@JohnSonderson Der erste Link zeigt Ihnen, wie Sie feststellen können, ob kein Dateiname angegeben ist. Der zweite Link kann mithilfe von normalanstelle von angepasst werden exec.
Muru
1
Die vimrc-Datei wird nur einmal gelesen : wenn Vim gestartet wird . Der Inhalt von autocmd wird jedes Mal ausgeführt, wenn es ausgelöst wird. Die ifAnweisung sollte sich also nicht um das Autocmd befinden, wenn sie sich im Autocmd befinden sollte, sodass sie jedes Mal ausgeführt wird , wenn das Autocmd ausgelöst wird.
Martin Tournoij

Antworten:

10

Dies funktioniert für alle 3 Ihrer Fälle bei mir:

function InsertIfEmpty()
    if @% == ""
        " No filename for current buffer
        startinsert
    elseif filereadable(@%) == 0
        " File doesn't exist yet
        startinsert
    elseif line('$') == 1 && col('$') == 1
        " File is empty
        startinsert
    endif
endfunction

au VimEnter * call InsertIfEmpty()

Diese können wahrscheinlich nur zur letzten Überprüfung auf eine leere Datei zusammengefasst werden, da kein Dateiname oder eine nicht vorhandene Datei normalerweise als leere Puffer gestartet wird. Es ist jedoch wahrscheinlich möglich, dass ein anderes Plugin in einem der ersten beiden Fälle einige Dinge vorab füllt (wie einige Vorlagen-Plugins). Überprüfen Sie daher am besten alle drei.

Der erste Test, den Sie bereits hatten.

Der zweite Test muss filereadablegegen den Wert Null prüfen (existiert nicht), um zu entscheiden, ob er neu ist (im Gegensatz zu dem, was Sie hatten).

Der letzte Test prüft, ob die Nummer der letzten Zeile in der Datei 1 ist (was auch die erste Zeile ist, was bedeutet, dass es nur eine Zeile gibt) und die Spaltennummer des Zeilenende (Spalte nach dem letzten Zeichen in) Die Zeile) ist 1, was bedeuten würde, dass 0 Zeichen vorhanden sind. Wenn nur 1 Zeile mit 0 Zeichen enthalten ist, muss die Datei leer sein.

Ein letzter Hinweis: Die Art und Weise, wie Sie Ihre Aussagen in der Frage haben, kann zu überraschenden Ergebnissen führen. Sie stellen nämlich ein, BufReadund zwar BufNewFilenur, wenn die Bedingungen beim Start erfüllt sind, diese Auto-Befehle jedoch für den Rest Ihrer Sitzung vorhanden sind. Wenn Sie also mit einer leeren Datei beginnen, die diese Befehle festlegt, wird jede nachfolgende geöffnete Datei (neu oder nicht, leer oder nicht) im Einfügemodus gestartet.

Der automatische Befehl VimEnterwird am Ende des Starts von Vim und nur einmal für die gesamte Sitzung ausgeführt. Auf diese Weise werden Ihre Tests nur ausgeführt, wenn Sie Vim starten, und nicht zu einem anderen Zeitpunkt.

John O'M.
quelle