エンター巻き込み事故を防ぐ

ばよえ〜ん(訳:Vim Advent Calendar 2012への15回目の投稿です)
この記事はVim Advent Calendar 2012の140日目の記事になります。
139日目は@manga_osyoさんでVim からでも qmake したいでした。


タイトルの「エンター巻き込み」はYahoo!検索スタッフブログの記事「あなたの知らないタイピングミスの世界」にあった単語です。
具体的に例を挙げると、Vimmerなら誰しも「:w]」としてしまって「]」というファイルを作ってしまったことがあるはずです。
その度にシェルに戻り「rm \]」を実行して消していることでしょう。

" Checking typo.
autocmd BufWriteCmd *[,*] call s:write_check_typo(expand('<afile>'))
function! s:write_check_typo(file)
    let prompt = "possible typo: really want to write to '" . a:file . "'?(y/n):"
    let input = input(prompt)
    if input =~? '^y\(es\)\=$'
        execute 'write'.(v:cmdbang ? '!' : '') a:file
    endif
endfunction

上記のコードを.vimrcにコピペすればそんなFP*1の消費を抑えることができます。
具体的に言うと「file.txt]」などのファイル名で書き込もうとすると
本当にそのファイルに書き込もうとしたのかプロンプトが出ます。
そこで「y」や「yes」と打てばやっと書き込むことができます。


英語キーボードならばautocmdの部分を

autocmd BufWriteCmd *=,*] call s:write_check_typo(expand('<afile>'))

のように変えたりしてください。


しかし話はこれだけで終わりません。
信じ難いことにもしかしたらあなたは本当に「file.txt]」というファイルに書き込みたいのかもしれません。
その度に確認のプロンプトに「y」と入力しなければならないのでしょうか?

" Checking typo.
autocmd BufWriteCmd *[,*] call s:write_check_typo(expand('<afile>'))
function! s:write_check_typo(file)
    let writecmd = 'write'.(v:cmdbang ? '!' : '').' '.a:file
    if exists('b:write_check_typo_nocheck')
        execute writecmd
        return
    endif
    let prompt = "possible typo: really want to write to '" . a:file . "'?(y/n):"
    let input = input(prompt)
    if input ==# 'YES'
        execute writecmd
        let b:write_check_typo_nocheck = 1
    elseif input =~? '^y\(es\)\=$'
        execute writecmd
    endif
endfunction

上記のコードは先程のコードの改良版です。
プロンプトで「YES」と入力すると強い肯定とみなし、以後そのバッファではプロンプトを出さなくなります。

どうでもいいけど

この記事はもともとVim Hacks用にとっておいた記事を少し改変したものです。
文体が違うのはそのせいです。

*1:Finger Point