1

I have a function in my bashrc that checks if a file is writable with [ -w "$1" ]. If it is, I open it with vim normally. If it's not, I open with sudo via sudo env HOME="$HOME" vim -u ~/.vimrc "$1" to make sure vim sources my .vimrc and colorscheme correctly. I want to print a warning message on the message line (whatever that line is called) when I do this, so I know I've had to use sudo. I wrote a vimrc function to display the message how I want:

"sudo warning label:
function! Sudowarn ()
  hi TempColor ctermfg=255 ctermbg=88
  echohl TempColor
  echo "Automatically sudo'd to have write access!"
  echohl None
endfunction

My problem is that I don't know how to call this function when the file loads only when I've sudo'd. I know vim knows about the $USER variable ("root" when sudo'd, "jeremysprofile" when not), and I know autocmd has a User option but I don't know how to use these to solve my problem.

If someone can at least tell me what I should be doing to solve my problem instead of asking internet questions, it would be greatly appreciated.

  • 1
    IIRC sudo sets the SUDO_USER environment variable, as well as some others. Try env | grep SUDO. You can access all environment variables from Vim with $VARNAME. I'm sure I answered this question (or something very similar) before in more detail, but I can't find it right now :-( – Martin Tournoij Jul 10 '18 at 17:40
  • @MartinTournoij, $USER works as I want, i.e., :echom $USER gives "root" when I've used sudo and my username otherwise. I just don't know how to use that in an autocmd =( – jeremysprofile Jul 10 '18 at 17:47
  • 1
    You can just use if, right? autocmd BufRead * if $USER == "root" | call Sudowarn() | endif (Arguably better to put that if in the Sudowarn() function though) Or am I misunderstanding what you mean? – Martin Tournoij Jul 10 '18 at 17:53
  • ...oh. No, that's pretty much it. Is there any way to have that message appear and not block the file appearing? With that (or BufReadPost) the file contents don't appear until after I've hit enter; the messages seems to block that. – jeremysprofile Jul 10 '18 at 18:14
  • @MartinTournoij, figured it out; had to change cmdheight settings. if you want to post an answer, I'll accept it, otherwise I'll post an answer tomorrow. – jeremysprofile Jul 10 '18 at 18:28
3

I would use the VimEnter autocommand and move the conditional inside the function, i.e.

augroup vimrc
  autocmd!
  autocmd VimEnter * call SudoWarn()
augroup END

function! SudoWarn()
  if $USER !=# 'root' | return | endif
  ...
endfunction

This also moves the autocommand inside an autocommand group; "vimrc" is just an example name, it could be anything. The autocmd! will remove all previous autocommands in this group, which is sensible if you should load the vimrc file multiple times.

Note, with this approach, I don't think you need to change the cmdheight option, since the echo is issued at a later time.

  • What is the benefit of having the if statement in the function vs the autocmd? I know how autocmd groups and ! overwriting work, but so far I haven't found them necessary. – jeremysprofile Jul 11 '18 at 18:39
2

As @Martin pointed out, the autocmd was a simple if statement. I didn't realize autocmd could do do if or read variables the way echom could. I also added cmdheight so that the message would not block displaying the file

"sudo warning label:
function! Sudowarn ()
  "cmdheight prevents vim from forcing 'push ENTER to continue'
  set cmdheight=2
  hi SudoColor ctermfg=255 ctermbg=88
  echohl SudoColor
  echo "Automatically sudo'd to have write access!"
  echohl None
  set cmdheight=1
endfunction
autocmd BufNewFile,BufRead * if $USER == "root" | call Sudowarn() | endif

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.