Come posso impedire a Vim di scrivere un file senza generare un errore?


10

Sto cercando di migliorare il codice da questa risposta per chiedere conferma prima di creare la directory mancante, questo è quello che scrivo:

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

Una cosa che mi manca: quando non premo yal prompt vorrei che Vim interrompesse la scrittura, quindi non ricevo l'errore E212: Can't open file for writinge non ho bisogno di premere un altro tasto per far scomparire il messaggio di errore. C'è un modo per raggiungere questo obiettivo?

Risposte:


9

Invece di usare BufWritePreautocmd, puoi usare BufWriteCmd autocmd da :help BufWriteCmd:

Dovrebbe eseguire la scrittura del file e reimpostare 'modificato' in caso di successo, a meno che '+' non sia in 'cpo' e scrivere in un altro file cpo- +.

Possiamo semplicemente chiamare :writeda autocmd. Questo si occuperà dell'impostazione modified.

Quindi la logica verrebbe quindi modificata per chiamare :writequando la directory esiste già e chiamare :writedopo aver creato la directory se non esiste ancora. Se premi n, non facciamo nulla. Questo lascerà il buffer così com'è e non verrà reimpostato modified, quindi :qti darà comunque un E37: No write since last changeerrore.

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

2
Nei file VimScript, il :comando iniziale non è mai necessario per i comandi.
Tommaso,

@tommcdo Grazie. Per qualche ragione il mio cervello a volte lo dimentica> _ <
Martin Tournoij l'

2
@ toro2k Grazie. Non lo sapevo. Ho modificato la mia risposta, ho anche aggiunto in silentmodo da non ricevere un messaggio se non lo stai utilizzando autogroup. Ho anche risolto un altro problema che avevo notato: :w another_namenon funzionava (non funziona).
Martin Tournoij,

2
@ toro2k Perché altrimenti writescriverà solo nel nome del file corrente (proprio come quando si digita :write) e :write another_filenamenon funzionerà (utilizzerà comunque il nome del file originale).
Martin Tournoij,

1
@whitesiroi È possibile utilizzare l' bufypeimpostazione per ottenere il tipo di buffer. Sentiti libero di modificare il post con una correzione (o, in caso contrario, lo farò la prossima settimana).
Martin Tournoij,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.