Comment puis-je empêcher Vim d'écrire un fichier sans générer d'erreur?

10

J'essaie d'améliorer le code de cette réponse pour demander une confirmation avant de créer le répertoire manquant, voici ce que j'écris:

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

Une chose me manque: lorsque je n'appuie pas yà l'invite, j'aimerais que Vim abandonne l'écriture pour ne pas avoir l'erreur E212: Can't open file for writinget je n'ai pas besoin d' appuyer sur une autre touche pour faire disparaître le message d'erreur. Il existe un moyen d'y parvenir?

toro2k
la source

Réponses:

9

Au lieu d'utiliser l' BufWritePreautocmd, vous pouvez utiliser l' BufWriteCmd autocmd à partir de :help BufWriteCmd:

Devrait faire l'écriture du fichier et réinitialiser «modifié» en cas de succès, sauf si «+» est dans «cpo» et écrire dans un autre fichier cpo- +.

Nous pouvons simplement appeler à :writepartir de l'autocmd. Cela se chargera du réglage modified.

Ainsi, la logique serait alors modifiée pour appeler :writelorsque le répertoire existe déjà, et appeler :writeaprès avoir créé le répertoire s'il n'existe pas encore. Si vous appuyez n, nous ne faisons rien. Cela laissera le tampon tel quel et ne sera pas réinitialisé modified, donc :qvous donnera toujours une E37: No write since last changeerreur.

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
la source
2
Dans les fichiers VimScript, l'interligne :n'est jamais nécessaire pour les commandes.
tommcdo
@tommcdo Merci. Pour une raison quelconque, mon cerveau oublie cela parfois> _ <
Martin Tournoij
2
@ toro2k Merci. Je n'en savais rien. J'ai modifié ma réponse, j'ai également ajouté silentafin que vous n'obteniez pas de message si vous ne l'utilisez pas autogroup. J'ai également corrigé un autre problème que j'ai remarqué: :w another_namene fonctionnait pas (ça ne fonctionne pas).
Martin Tournoij
2
@ toro2k Parce qu'autrement, writeil suffit d'écrire dans le nom de fichier actuel (comme lorsque vous tapez :write) et :write another_filenamene fonctionnera pas (il utilisera toujours le nom de fichier d'origine).
Martin Tournoij
1
@whitesiroi Vous pouvez utiliser le bufypeparamètre pour obtenir le type de tampon. N'hésitez pas à modifier le message avec un correctif (ou si vous ne le faites pas, je le ferai la semaine prochaine).
Martin Tournoij