Як я можу відмовити Vim писати файл, не видаючи помилку?


10

Я намагаюся вдосконалити код з цієї відповіді, щоб попросити підтвердження перед тим, як створити відсутні каталог, ось що я пишу:

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

Одне, що мені не вистачає: коли я не натискаю yна запит, я хотів би, щоб Vim перервав написання, щоб я не отримав помилку, E212: Can't open file for writingі мені не потрібно натиснути іншу клавішу, щоб повідомлення про помилку зникло. Є спосіб досягти цього?

Відповіді:


9

Замість використання BufWritePreautocmd ви можете використовувати BufWriteCmd autocmd з :help BufWriteCmd:

Слід виконати запис файлу та скинути «модифікований», якщо це вдало, якщо «+» не вказано у «cpo» та записі до іншого файлу cpo- +.

Ми можемо просто зателефонувати :writeз autocmd. Це подбає про налаштування modified.

Тож логіка буде змінена на виклик, :writeколи каталог вже існує, і виклик :writeпісля створення каталогу, якщо він ще не існує. Якщо ти натиснеш n, ми нічого не робимо. Це дозволить залишити буфер таким, який є, і не буде встановлено повторно modified, тому :qвсе одно ви отримаєте E37: No write since last changeпомилку.

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
У файлах VimScript провідні :ніколи не потрібні для команд.
tommcdo

@tommcdo Дякую Чомусь мій мозок іноді це забуває> _ <
Мартін Турной

2
@ toro2k Дякую Я про це не знав. Я відредагував свою відповідь, також додав, silentщоб ви не отримали повідомлення, якщо не використовуєте це autogroup. Я також виправив ще одну проблему, яку я помітив: :w another_nameне працював (не працює).
Мартін Турноїй

2
@ toro2k Тому що в іншому випадку writeбуде просто записувати до поточного імені файлу (як і під час введення :write), і :write another_filenameвін не працюватиме (він все одно використовуватиме оригінальне ім'я файлу).
Мартін Турноїй

1
@whitesiroi Ви можете використовувати цей bufypeпараметр, щоб отримати тип буфера. Не соромтесь редагувати публікацію з виправленням (або якщо ви цього не зробите, я наступного тижня).
Мартін Турной
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.