function! AtomicSave()
if (getftype(expand('<afile>')) == "file")|
if (writefile(getline(1, '$'), expand('<afile>').'.tmp') == 0)|
let l:filename = shellescape(expand('<afile>'))|
let l:tempfile = l:filename . '.tmp'|
" it's hard to grab the perms to make this portable. see http://mywiki.wooledge.org/BashFAQ/087
call system('! test -e ' . l:filename . ' || chmod --reference=' . l:filename . ' ' . l:tempfile)|
if v:shell_error|
echo "error setting permissions on temporary file: chmod returned " . v:shell_error|
return|
endif|
" NOTE: vim's "rename" erroneously calls "unlink" on its target!
" THIS DOES NOT WORK: if (rename(expand('<afile>').'.tmp', expand('<afile>')) == 0) | set nomodified | echo "error" | endif
call system('mv ' . l:tempfile . ' ' . l:filename)|
if v:shell_error|
echo "error renaming file: mv returned " . v:shell_error|
else|
echomsg l:filename . ' written (atomically)'|
set nomodified|
endif|
else|
echo "error writing file"|
endif|
else|
if (writefile(getline(1, '$'), expand('<afile>')) == 0)|
echomsg expand('<afile>') . ' written normally (file is a ' . getftype(expand('<afile>')) . ')'|
set nomodified|
else|
echo "error writing file"|
endif|
endif|
endfunction
augroup atomicwrite
autocmd BufWriteCmd * call AtomicSave()
augroup END