Write buffer using writefile() instead of :write.

This is to avoid side effects caused by switching to the buffer to be
written and back again.

It also means that the plugin can process any buffer without having to
make it the current buffer.

Using the lower level writefile() function means we have to deal with
line endings.  It might also mean we have to deal with (file) encodings
but I hope not...

See #463, #466.
This commit is contained in:
Andy Stewart
2018-02-13 10:22:36 +00:00
parent 850e947509
commit 4e911819be

View File

@@ -289,31 +289,11 @@ endfunction
function! s:write_buffer(bufnr, file)
let _write = &write
set write
" Write specified buffer (which may not be the current buffer) to buff_file.
" There doesn't seem to be a clean way to write a buffer that isn't the current
" to a file; we have to switch to it, write it, then switch back.
let current_buffer = bufnr('')
execute 'noautocmd buffer' a:bufnr
" Writing the whole buffer resets the '[ and '] marks and also the
" 'modified' flag (if &cpoptions includes '+'). These are unwanted
" side-effects so we save and restore the values ourselves.
let modified = getbufvar(a:bufnr, "&mod")
let op_mark_start = getpos("'[")
let op_mark_end = getpos("']")
execute 'keepalt noautocmd silent write!' a:file
call setbufvar(a:bufnr, "&mod", modified)
call setpos("'[", op_mark_start)
call setpos("']", op_mark_end)
execute 'noautocmd buffer' current_buffer
let &write = _write
let bufcontents = getbufline(a:bufnr, 1, '$')
if getbufvar(a:bufnr, '&fileformat') ==# 'dos'
call map(bufcontents, 'v:val."\r"')
endif
call writefile(bufcontents, a:file)
endfunction