Jak mogę zatrzymać Vima przed zapisaniem pliku bez zgłaszania błędu?

10

Próbuję ulepszyć kod z tej odpowiedzi, aby poprosić o potwierdzenie przed utworzeniem brakującego katalogu, oto co piszę:

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

Brakuje mi jednej rzeczy: kiedy nie naciskam yna monit, chciałbym, aby Vim przerwał zapis, więc nie dostaję błędu E212: Can't open file for writingi nie muszę naciskać innego klawisza, aby komunikat o błędzie zniknął. Jest sposób na osiągnięcie tego?

toro2k
źródło

Odpowiedzi:

9

Zamiast korzystać z BufWritePreautocmd, możesz użyć BufWriteCmd autocmd z :help BufWriteCmd:

Powinieneś zrobić zapis pliku i zresetować „zmodyfikowany”, jeśli się powiedzie, chyba że „+” jest w „cpo” i zapis do innego pliku cpo- +.

Możemy po prostu zadzwonić :writez autocmd. To zajmie się ustawieniem modified.

Zatem logika zostałaby zmodyfikowana tak, aby wywoływała, :writegdy katalog już istnieje, i wywoływała :writepo utworzeniu katalogu, jeśli jeszcze nie istnieje. Jeśli naciśniesz n, nic nie zrobimy. Spowoduje to pozostawienie bufora w niezmienionej postaci i nie zostanie zresetowane modified, więc :qnadal pojawi się E37: No write since last changebłąd.

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
źródło
2
W plikach VimScript wiodące :polecenie nigdy nie jest konieczne.
tommcdo
@tommcdo Thanks. Z jakiegoś powodu mój mózg czasami zapomina o tym> _ <
Martin Tournoij
2
@ toro2k Dzięki. Nie wiedziałem o tym. Zredagowałem swoją odpowiedź, dodałem również silent, abyś nie dostał wiadomości, jeśli jej nie używasz autogroup. Naprawiłem również inny problem, który zauważyłem: :w another_namenie działał (nie działa).
Martin Tournoij
2
@ toro2k Ponieważ w przeciwnym razie writepo prostu zapisze bieżącą nazwę pliku (tak jak podczas pisania :write) i :write another_filenamenie będzie działać (nadal będzie używać oryginalnej nazwy pliku).
Martin Tournoij
1
@whitesiroi Możesz użyć tego bufypeustawienia, aby uzyskać typ bufora. Edytuj post z poprawką (lub jeśli nie, zrobię to w przyszłym tygodniu).
Martin Tournoij,