Làm cách nào tôi có thể ngăn Vim viết tệp mà không bị lỗi?


10

Tôi đang cố gắng cải thiện mã từ câu trả lời này để yêu cầu xác nhận trước khi tạo thư mục bị thiếu, đây là những gì tôi viết:

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

Một điều tôi còn thiếu: khi tôi không nhấn yvào dấu nhắc tôi muốn Vim hủy bỏ việc viết để tôi không gặp lỗi E212: Can't open file for writingvà tôi không cần nhấn một phím khác để làm cho thông báo lỗi biến mất. Có cách nào để đạt được điều này?

Câu trả lời:


9

Thay vì sử dụng BufWritePreautocmd, bạn có thể sử dụng BufWriteCmd autocmd, từ :help BufWriteCmd:

Nên viết tệp và đặt lại 'đã sửa đổi' nếu thành công, trừ khi '+' nằm trong 'cpo' và ghi vào tệp khác cpo- +.

Chúng tôi chỉ có thể gọi :writetừ autocmd. Điều này sẽ chăm sóc thiết lập modified.

Vì vậy, logic sau đó sẽ được sửa đổi để gọi :writekhi thư mục đã tồn tại và gọi :writesau khi tạo thư mục nếu nó chưa tồn tại. Nếu bạn nhấn n, chúng tôi không làm gì cả. Điều này sẽ để lại bộ đệm như hiện tại và sẽ không được đặt lại modified, do đó :qvẫn sẽ E37: No write since last changegây ra lỗi cho bạn .

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
Trong các tệp VimScript, hàng đầu :không bao giờ cần thiết cho các lệnh.
tommcdo

@tommcdo Cảm ơn. Vì một số lý do, bộ não của tôi đôi khi quên điều này> _ <
Martin Tournoij

2
@ toro2k Cảm ơn. Tôi không biết về điều đó. Tôi đã chỉnh sửa câu trả lời của mình, tôi cũng đã thêm silentđể bạn sẽ không nhận được tin nhắn nếu bạn không sử dụng nó autogroup. Tôi cũng đã sửa một vấn đề khác mà tôi nhận thấy: :w another_namekhông hoạt động (không hoạt động).
Martin Tournoij

2
@ toro2k Bởi vì nếu không writesẽ chỉ ghi vào tên tệp hiện tại (giống như khi bạn nhập :write) và :write another_filenamesẽ không hoạt động (nó vẫn sẽ sử dụng tên tệp gốc).
Martin Tournoij

1
@whitesiroi Bạn có thể sử dụng bufypecài đặt để lấy loại bộ đệm. Vui lòng chỉnh sửa bài đăng với một sửa chữa (hoặc nếu bạn không, tôi sẽ vào tuần tới).
Martin Tournoij
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.