Since you use Neovim and you are fine with a simple message telling you to pull your dotfiles repository here is a very basic solution which you could work on.
The solution has its drawbacks (which I'll explain later) but it has the advantages of not relying on a plugin or any other tool than the git
cli and of begin asynchronous, which I believe is important: Since you will call git remote update
and that can take some time to execute you probably don't want to block neovim's UI will it runs.
So you can add that to your vimrc
/init.vim
:
" Asynchronously check if the dotfil repository has changes to pull
function CheckVimrcRemoteUpdate()
" Put the dotfiles repo in a variable
let dotfiles_repo_path = "$HOME/.dotfiles"
" The shell command we will use to check for updates
let cmd = 'cd ' . dotfiles_repo_path . ' && git remote update && git status -uno'
" The function we will call when the git command as finished to be read
function HandleData(chanid, data, name)
" a:data holds all the lines of stdout
" if the output contains the string 'is behind' then we show a message
let is_behind = v:false
for line in a:data
if line =~ 'is behind'
let is_behind = v:true
endif
endfor
if (is_behind)
echom 'Dotfiles should be updated'
endif
endfunction
" Start an asynchronous job to execute the git command and execute HandleData on stdout
call jobstart(cmd, {'stdout_buffered': v:true, 'on_stdout': function('HandleData')})
endfunction
" Run the CheckVimrcRemoteUpdate function after Vim start up
augroup CheckDotfiles
autocmd!
autocmd VimEnter * call CheckVimrcRemoteUpdate()
augroup END
The idea is to create a CheckVimrcRemoteUpdate()
function which will do 3 things:
- Build the command to be run by the script to check the status of your dotfile repository
- Create a function which will handle the output of this command and display a message if you need to update your repo
- Start a job which will run the command and attach the function to its result.
A few things to note:
- The command ran is
cd $your_repo_path && git remote update && git status -uno
: This means that if you have a change in your repository which isn't about your vimrc
file you will still get the message. You can probably play with git
to have a better command checking only the status of this file (but you also probably want to check if the .vim
directory has been updated too).
- The check relies on
git
showing a line like Your branch is behind 'origin/master' by 47 commits
this is not a very strict check and could probably be improved. As Ben suggested in the comments a first step to improve that is to force the local when running the command to avoid having the string localized if your system is not in English.
- To show the notification I used
echom
, maybe you'll want a different UI.
'stdout_buffered': v:true
in the jobstart
function is important to trigger HandleData
only once you received all of the lines from stdout.
- There is no error handling, so if you specify a directory which is not a git repo in
dotfiles_repo_path
things will most likely break. Same if you don't have network connectivity.
- I put the call to
CheckVimrcRemoteUpdate()
in the VimEnter
autocommand event, maybe there is a better one.
Relevant help topics:
FWIW a synchronous version of the solution would be this simple function:
" Synchronously check if the dotfiles repository has changes to pull
function CheckVimrcRemoteUpdate()
" Put the dotfiles repo in a variable
" let dotfiles_repo_path = "$HOME/.dotfiles"
let dotfiles_repo_path = "$HOME/projects/nodews"
" The shell command we will use to check for updates
let data = systemlist('cd ' . dotfiles_repo_path . ' && git remote update && git status -uno')
let is_behind = v:false
for line in data
if line =~ 'is behind'
echom 'Dotfiles should be updated'
endif
endfor
endfunction
~/.vimrc
. Something like that. I'm fine with it not taking effect until a restart of vim (if there's not easy way to apply it immediately), as long as it tells me it updated, and that I should restart vim.:h system()
call in your vimrc which will do agit pull
in the repo holding your vimrc. If you don't want to do apull
automatically you can still do agit remote update
to get the remote updated refs and then check ifgit status -uno
shows a change. If there is a change then you display a message to pull.