vimtricks.wiki Concise Vim tricks, one at a time.

How do I read from and write to files directly in Vimscript without shelling out to external commands?

Answer

readfile() and writefile()

Explanation

readfile({path}) reads a file and returns its contents as a list of lines, and writefile({list}, {path}) writes a list of lines back to disk. Together they let you load, transform, and persist data entirely within Vimscript — no external commands needed.

How it works

" Read a file into a list of lines
let lines = readfile(expand('~/.vim/wordlist.txt'))

" Modify the list
call filter(lines, 'v:val !~ "^#"')   " strip comment lines

" Write the modified list back
call writefile(lines, expand('~/.vim/wordlist.clean.txt'))

Key signatures:

  • readfile(path) — returns a List of strings, one per line
  • readfile(path, 'b') — binary mode (no line-ending conversion)
  • writefile(list, path) — overwrites the file
  • writefile(list, path, 'a') — appends to the file

Example

Save the current session's open file paths for later reference:

let bufs = filter(range(1, bufnr('$')), 'buflisted(v:val)')
let paths = map(bufs, 'bufname(v:val)')
call writefile(paths, '/tmp/vim_session_files.txt')

" Later, restore from another session:
for f in readfile('/tmp/vim_session_files.txt')
  execute 'edit ' . fnameescape(f)
endfor

Tips

  • Always check existence first: if filereadable(path) before calling readfile()
  • writefile() creates the file if it doesn't exist, but not intermediate directories — use mkdir(fnamemodify(path, ':h'), 'p') if needed
  • In Neovim Lua: vim.fn.readfile(path) and vim.fn.writefile(list, path) are identical
  • For JSON data, combine with json_decode(join(readfile(path))) and writefile([json_encode(data)], path) (Vim 8+/Neovim)

Next

How do I make the K key look up documentation in a language-specific tool instead of man pages?