Neovim Tip, GitLens

Posted on 2020-01-28

Intro

GitLens is a VSCode plugin that, among other things, allows you to see the time, commit author, and commit message of the current line. With a little help from to the neovim api and our shell, it we can recreate this functionality in a few lines of lua code.

The Code

-- in utils.lua
local M = {}
local api = vim.api
function M.blameVirtText()
  local ft = vim.fn.expand('%:h:t') -- get the current file extension
  if ft == '' then -- if we are in a scratch buffer or unknown filetype
    return
  end
  if ft == 'bin' then -- if we are in nvim's terminal window
    return
  end
  api.nvim_buf_clear_namespace(0, 2, 0, -1) -- clear out virtual text from namespace 2 (the namespace we will set later)
  local currFile = vim.fn.expand('%')
  local line = api.nvim_win_get_cursor(0)
  local blame = vim.fn.system(string.format('git blame -c -L %d,%d %s', line[1], line[1], currFile))
  local hash = vim.split(blame, '%s')[1]
  local cmd = string.format("git show %s ", hash).."--format='%an | %ar | %s'"
  if hash == '00000000' then
    text = 'Not Committed Yet'
  else
    text = vim.fn.system(cmd)
    text = vim.split(text, '\n')[1]
    if text:gmatch("fatal") then -- if the call to git show fails
      text = 'Not Committed Yet'
    end
  end
  api.nvim_buf_set_virtual_text(0, 2, line[1] - 1, {{ text,'GitLens' }}, {}) -- set virtual text for namespace 2 with the content from git and assign it to the higlight group 'GitLens'
end

function M.clearBlameVirtText() -- important for clearing out the text when our cursor moves
  api.nvim_buf_clear_namespace(0, 2, 0, -1)
end

return M
" in init.vim
lua vim.api.nvim_command [[autocmd CursorHold   * lua require'utils'.blameVirtText()]]
lua vim.api.nvim_command [[autocmd CursorMoved  * lua require'utils'.clearBlameVirtText()]]
lua vim.api.nvim_command [[autocmd CursorMovedI * lua require'utils'.clearBlameVirtText()]]

hi! link GitLens Comment

See Also

Mentioned around the web

commented on Feb 15, 2020 see original

This is really cool, thanks for sharing

commented on Feb 11, 2020 see original

Is there an installable form for this?

commented on Feb 14, 2020 see original

Source at /r/neovim

commented on Feb 11, 2020 see original

Nice!

This one's vimscript and somewhat longer but has been working well for me: https://github.com/APZelos/blamer.nvim

commented on Sep 10, 2020 see original

Another one: svermeulen/vimpeccable

commented on Aug 8, 2020 see original

https://oli.me.uk/neovim-configuration-and-plugins-in-fennel-lisp/

Throwing my own hat into the ring :D

Fennel is a Lisp which I compile to Lua for all of my configuration and plugins.

commented on Aug 8, 2020 see original
Just a bunch of articles about using lua in neovim config and neovim plugins: - https://gabrielpoca.com/2019-11-02-a-little-bit-of-lua-in-your-vim/ - https://www.2n.pl/blog/how-to-write-neovim-plugins-in-lua - https://teukka.tech/vimtip-gitlens.html - Upd: https://oli.me.uk/neovim-configuration-and-plugins-in-fennel-lisp/ https://gabrielpoca.com/2019-11-02-a-little-bit-of-lua-in-your-vim/ https://oli.me.uk/neovim-configuration-and-plugins-in-fennel-lisp/ https://teukka.tech/vimtip-gitlens.html https://www.2n.pl/blog/how-to-write-neovim-plugins-in-lua

Mentioned on https://reddit.com/r/neovim/comments/i61cic/neovim_lua_articles/