oligofren
oligofren

Reputation: 22923

Keep cursor placement after writing buffer to disk using external command

I use a small snippet of vimscript code in my vimrc to be able to automatically encrypt the text to disk when executing :write. Unfortunately, every time I save the file, my cursor is reset to the start of the first line, forcing me to scroll down to where I was. Quite annoying.

Is there a way of restore the cursor placement after I have written the file to disk? The full code can be found below.

# code from http://vim.wikia.com/wiki/Encryption#ccrypt
augroup CPT
  au!
  au BufReadPre *.cpt set bin
  au BufReadPre *.cpt set viminfo=
  au BufReadPre *.cpt set noswapfile
  au BufReadPost *.cpt let $vimpass = inputsecret("Password: ")
  au BufReadPost *.cpt silent '[,']!ccrypt -cb -E vimpass
  au BufReadPost *.cpt set nobin
  au BufWritePre *.cpt set bin
  au BufWritePre *.cpt '[,']!ccrypt -e -E vimpass
  au BufWritePost *.cpt u
  au BufWritePost *.cpt set nobin
augroup END

Upvotes: 1

Views: 189

Answers (2)

oligofren
oligofren

Reputation: 22923

Another version provided by atweiden includes simply storing and restoring the cursor before and after writes.

Code from Github:

  func! s:ccrypt_bufwritepre()
        let b:save_cursor = getpos(".")
        setl bin
        %!ccrypt -e -E crypticnonsense
    endfunc

    func! s:ccrypt_bufwritepost()
        u
        setl nobin
        call setpos('.', b:save_cursor)
    endfunc

Upvotes: 0

Peter Rincker
Peter Rincker

Reputation: 45117

My suggestion would be use Vim's built in encryption. Use :X to set the key. You can at this point use read and write the file the same as you normally would. See :h encryption for more details.

To answer you question on how to save and restore the cursor position:

  • Use winsaveview() to save the view information. e.g. let view = winsaveview()
  • Move the cursor
  • Restore the view state. e.g. call winrestview(view)

As you noted you found someone who bundled up the autocmd's into some functions. You can probably modify this to use the winsaveview()/winrestview() function by saving the view state into a buffer variable. e.g. let b:view = winsaveview() and call winrestview(b:view).

Upvotes: 1

Related Questions