3

I've installed and aliased some a newer version of vim and aliased vim to call that version.

I also aliased sudo so that it can just call the system default vi when I need to edit a file as sudo but this has two issues. Mainly there's no syntax highlighting in the system version of vi and sometimes I just vim a file and want to make some small tests while the file is live but I have to quit vim and go to vi and that's just a slow workflow.

I found this link that explains a cool sudo hack so that I can stay in my currently syntax highlighted vim and save file as sudo with a special command.

cnoremap w!! w !sudo /usr/bin/tee > /dev/null %

that works really well, but I have one issue that's coming up.

running the command I always get this output.

:w !sudo /usr/bin/tee > /dev/null %

W12: Warning: File "../lid.sh" has changed and the buffer was changed in Vim as well
See ":help W12" for more info.
[O]K, (L)oad File: 

looking at :help W12 says this:

  Warning: File "{filename}" has changed and the buffer was changed in Vim as well

Like the above, and the buffer for the file was changed in this Vim as well.
You will have to decide if you want to keep the version in this Vim or the one
on disk.  This message is not given when 'buftype' is not empty.

autoread help says:

'autoread' 'ar' 'noautoread' 'noar' 'autoread' 'ar' boolean (default on) global or local to buffer |global-local| When a file has been detected to have been changed outside of Vim and it has not been changed inside of Vim, automatically read it again. When the file has been deleted this is not done. |timestamp| If this option has a local value, use this command to switch back to using the global value: > :set autoread<

and I do have :set autoread in my .vimrc but that doesn't seem to work. I always get asked every time, is it okay to reload the file.

how can I just choose to reload the file without having to manually accept it each time. Typing :w!! is a long enough command where I won't be doing that unless I have to.

  • 1
    Forget all this and run vim as your own user. To edit files as root, use sudoedit. – Gilles Dec 14 '15 at 23:05
  • If you want sudo to use your user aliases set an alias for sudo as sudo with a space after it in your bashrc file. – mchid Dec 22 '15 at 3:10
  • 1
    I already do that, the problem is that I do not have vim installed as root only vi. I sorted it out though. – user1610950 Dec 23 '15 at 4:27
3
+50

I solved this issue by adding this to my vimrc file.

cnoremap w!! call SudoSaveFile()

function! SudoSaveFile() abort
  execute (has('gui_running') ? '' : 'silent') 'write !env SUDO_EDITOR=tee sudo -e % >/dev/null'
  let &modified = v:shell_error
endfunction
0

The accepted answer (with bounty) is wrong. It will not solve the problem at all, because the warning W12 will happen after the function returns.

The problem is, as stated by the doc quoted in the question (my bold):

autoread' 'ar' 'noautoread' 'noar' 'autoread' 'ar'
boolean (default on) global or local to buffer |global-local|

When a file has been detected to have been changed outside of Vim and it has not been changed inside of Vim, automatically read it again.

That means, autoread option only addresses W11 warnings.

To solve the problem I've tried for long hours to come up with a solution, temporarily changing buftype, among other stuff, but it turned out to be quite simple:

cnoremap w!! execute 'silent! write !sudo tee % >/dev/null' <bar> edit!

That means, force reload the file after saving. This will ensure that the warning won't happen, since the file now is identical to the buffer.

  • This solution also works no matter of your autoread option. I like mine noautoread, so I know if I want to discard changes or not.

You could put an extra "<CR>" at the end,

cnoremap w!! execute 'silent! write !sudo tee % >/dev/null' <bar> edit!<CR>

or if you want a function, something like:

cnoremap w!! call SudoWriteBangBang()<CR>
function! SudoWriteBangBang()
    execute 'silent! write !sudo tee % >/dev/null' <bar> edit!<CR>
endfunction

but I prefer not having the command completed at once. Without <CR> you have a chance to take a look at the command one more time before making up your mind. Also, it mimics better the behaviour of :w and :w!, as they expect a manual <CR> as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.