0

I have the following code for updating my statusline:

set laststatus=2
set statusline=

def Get_gitbranch(): string
    var current_branch = trim(system("git -C " .. expand("%:h") .. " branch
                \ --show-current"))
    # strdix(A,B) >=0 check if B is in A.
    if stridx(current_branch, "not a git repository") >= 0
        current_branch = "(no repo)"
    endif
    return current_branch
enddef

augroup Gitget
    autocmd!
    autocmd BufAdd,BufEnter,BufWinEnter * b:gitbranch = Get_gitbranch()
augroup END

set statusline+=%#WildMenu#\ \ %{b:gitbranch}\ %*

Although the way I am fetching the current git branch may be questionable, the following mechanism works fairly well.

However, sometimes I get the error E212: Undefined variable b:git_branch that I am failing to root-cause. I think the error is due to the events used in the autocommand, i.e. in some circumstances the statusline is attempted to be updated before the buffer-local variables are defined.

Does anyone know how to solve it? Do you more info or this is enough?

I tried the following ugly hack to get rid off the problem:

set statusline+=%#WildMenu#\ \ %{get(b:, 'gitbranch', '')}\ %*

resulting in E540.

4
  • Not ugly and not a hack. Just clean defensive coding. You can remove the spaces from your expression to avoid the E540: %{get(b:,'gitbranch','')}.
    – romainl
    Commented Jul 10 at 14:39
  • Are you sure the Get_gitbranch() is never failing? Do you get the problem if you do: autocmd BufAdd,BufEnter,BufWinEnter * b:gitbranch = 'main'? (of course not a solution but just a test to verify that the problem is not in Get_gitbranch()) Commented Jul 10 at 14:51
  • 1
    @VivianDeSmedt I tried but the issue is still there :(
    – Barzi2001
    Commented Jul 10 at 15:23
  • 1
    Thanks. It exclude that hypothesis. It seems that @Matt has the correct analysis :-) Commented Jul 10 at 15:29

3 Answers 3

1

BufAdd is an early event that is normally triggered before loading buffer contents and, hence, long before it may get activated. This is, of course, also mentioned in help. An obvious consequence is that you can not access it by b: from inside of an autocommand. Instead, use setbufvar() with <abuf> or such.

Two other events are ok, but they may get triggered after initial status line update, and so the error appears.

BTW. BufEnter may get triggered quite a few times. You should optimise the code of an autocommand or skip updating status line during this event at all.

6
  • You mean something like this: autocmd BufEnter,BufWinEnter * setbufvar(expand('<abuf>'), 'gitbranch', Get_gitbranch()) ? `
    – Barzi2001
    Commented Jul 10 at 15:32
  • @Barzi2001 str2nr(<abuf>)
    – Matt
    Commented Jul 10 at 15:37
  • @Barzi2001 Although, this is in vim9script... So maybe expand is the way to go. You need to check it yourself.
    – Matt
    Commented Jul 10 at 15:48
  • At the end I solved it with autocmd BufEnter,BufWinEnter * Set_b_gitbranch() where in Set_b_gitbranch() I used setbufvar(bufnr('%'), 'gitbranch', branch_name) and in the statusline I left set statusline+=%#WildMenu#\ \ %{get(b:,'gitbranch','')}\ %*. So far it is working well.
    – Barzi2001
    Commented Jul 10 at 16:36
  • 1
    @Barzi2001 The shortest way is to read HEAD (with mtime caching) directly from disk bypassing slow git completely. This is what vim-fugitive does. Even better is do not have branch indication at all. It's not the most frequently changed thing, so I can check it manually whenever I want. In fact, personally, I only have Git and Diff commands to run git manually.
    – Matt
    Commented Jul 11 at 4:45
1

I use fugitive, so I also use its statusline integration:

set statusline+=%([%{exists('*FugitiveHead')?FugitiveHead():''}]%)
0

I would have implemented a cache mechanism.

" Sorry I haven't migrated => I'm still writing portable (n)vim code
function my#statusline#gitbranch() abort
  if ! exists('b:gitbranch')
    let b:gitbranch = Get_gitbranch()
  endif
  return b:gitbranch
endfunction

...
set statusline+=%#WildMenu#\ \ %{my#statusline#gitbranch}\ %*

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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