ฉันจะหยุด 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 ขอบคุณ ด้วยเหตุผลบางอย่างทำให้สมองของฉันลืมสิ่งนี้บางครั้ง> _ <
Martin Tournoij

2
@ toro2k ขอบคุณ ฉันไม่รู้เกี่ยวกับสิ่งนั้น ฉันแก้ไขคำตอบของฉันฉันยังเพิ่มดังนั้นคุณจะไม่ได้รับข้อความที่ถ้าคุณไม่ได้ใช้นี้silent autogroupฉันยังแก้ไขปัญหาอื่นที่ฉันพบ: ใช้:w another_nameงานไม่ได้
Martin Tournoij

2
@ toro2k เพราะมิฉะนั้นwriteจะเขียนไปยังชื่อไฟล์ปัจจุบัน (เช่นเมื่อคุณพิมพ์:write) และ:write another_filenameจะไม่ทำงาน (มันจะยังคงใช้ชื่อไฟล์เดิม)
Martin Tournoij

1
@whitesiroi คุณสามารถใช้การbufypeตั้งค่าเพื่อรับประเภทบัฟเฟอร์ รู้สึกอิสระที่จะแก้ไขโพสต์ด้วยการแก้ไข (หรือถ้าคุณไม่ฉันจะสัปดาห์ถัดไป)
Martin Tournoij
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.