Wie kann ich verhindern, dass Vim eine Datei schreibt, ohne einen Fehler auszulösen?

10

Ich versuche, den Code aus dieser Antwort zu verbessern , um vor dem Erstellen des fehlenden Verzeichnisses um Bestätigung zu bitten. Folgendes schreibe ich:

function! CreateDirectoryAskConfirmation(path)
    if !isdirectory(a:path)
        echohl Question
        echo "Create directory " . a:path . "?"
        echohl None

        let response = nr2char(getchar())
        if response ==? "y"
            call mkdir(a:path, "p")
        endif
    endif
endfunction

autocmd BufWritePre * call CreateDirectoryAskConfirmation(expand("<afile>:p:h"))

Eines fehlt mir: Wenn ich nicht yan der Eingabeaufforderung drücke, möchte ich, dass Vim den Schreibvorgang abbricht, damit ich den Fehler nicht erhalte E212: Can't open file for writingund keine andere Taste drücken muss, damit die Fehlermeldung verschwindet. Gibt es einen Weg, dies zu erreichen?

toro2k
quelle

Antworten:

9

Anstatt das BufWritePreAutocmd zu verwenden, können Sie das BufWriteCmd Autocmd verwenden von :help BufWriteCmd:

Sollte das Schreiben der Datei durchführen und bei Erfolg 'modifiziert' zurücksetzen, es sei denn, '+' befindet sich in 'cpo' und es wird in eine andere Datei cpo- + geschrieben.

Wir können einfach :writevon der Autocmd anrufen. Dies kümmert sich um die Einstellung modified.

Die Logik würde dann so geändert, dass sie aufruft, :writewenn das Verzeichnis bereits vorhanden ist, und :writenach dem Erstellen des Verzeichnisses aufgerufen wird , wenn es noch nicht vorhanden ist. Wenn Sie drücken n, tun wir nichts. Dies wird verlassen den Puffer , wie sie ist, und wird nicht wieder Satz modified, so :qwerden Sie noch einen geben E37: No write since last changeFehler.

function! CreateDirectoryAskConfirmation(path, dir)
    silent doautocmd BufWritePre

    " Directory exists, :write and return
    if isdirectory(a:dir)
        execute 'write ' . a:path
        silent doautocmd BufWritePost
        return
    endif

    " Ask for confirmation to create this directory
    echohl Question
    echo "Create directory `" . a:dir . "' [y/N]?"
    echohl None

    let response = nr2char(getchar())
    " mkdir() and :write if we want to make a directory
    if response ==? "y"
        call mkdir(a:dir, "p")
        execute 'write ' . a:path
        silent doautocmd BufWritePost
    endif
endfunction

autocmd BufWriteCmd * call CreateDirectoryAskConfirmation(expand("<amatch>:p"), expand("<amatch>:p:h"))
Martin Tournoij
quelle
2
In VimScript-Dateien ist die Führung :für Befehle niemals erforderlich.
Tommcdo
@tommcdo Danke. Aus irgendeinem Grund vergisst mein Gehirn dies manchmal> _ <
Martin Tournoij
2
@ toro2k Danke. Das wusste ich nicht. Ich habe meine Antwort bearbeitet und hinzugefügt, silentdamit Sie keine Nachricht erhalten, wenn Sie diese nicht verwenden autogroup. Ich habe auch ein anderes Problem behoben, das mir aufgefallen ist: :w another_namehat nicht funktioniert (funktioniert nicht).
Martin Tournoij
2
@ toro2k Weil sonst writenur in den aktuellen Dateinamen geschrieben wird (genau wie bei der Eingabe :write) und :write another_filenamenicht funktioniert (es wird immer noch der ursprüngliche Dateiname verwendet).
Martin Tournoij
1
@whitesiroi Sie können die bufypeEinstellung verwenden, um den Puffertyp abzurufen . Fühlen Sie sich frei, den Beitrag mit einem Fix zu bearbeiten (oder wenn Sie dies nicht tun, werde ich nächste Woche).
Martin Tournoij