neovim

Personal neovim configuration files
git clone git://gtms.dev:neovim
Log | Files | Refs

git_blame.lua (3236B)


      1 local create_win = function()
      2   -- We save handle to window from which we open the navigation
      3   -- start_win = vim.api.nvim_get_current_win()
      4   local startingBuf = vim.api.nvim_command_output('echo expand(\'%:p\')  ')
      5 
      6   vim.api.nvim_command('topleft vnew') -- We open a new vertical window at the far left
      7   local win = vim.api.nvim_get_current_win() -- We save our navigation window handle...
      8   local buf = vim.api.nvim_get_current_buf() -- ...and it's buffer handle.
      9 
     10   -- We should name our buffer. All buffers in vim must have unique names.
     11   -- The easiest solution will be adding buffer handle to it
     12   -- because it is already unique and it's just a number.
     13   vim.api.nvim_buf_set_name(buf, 'GBlame #' .. buf)
     14 
     15   -- Now we set some options for our buffer.
     16   -- nofile prevent mark buffer as modified so we never get warnings about not saved changes.
     17   -- Also some plugins treat nofile buffers different.
     18   -- For example coc.nvim don't triggers aoutcompletation for these.
     19   vim.api.nvim_buf_set_option(buf, 'buftype', 'nofile')
     20   -- We do not need swapfile for this buffer.
     21   vim.api.nvim_buf_set_option(buf, 'swapfile', false)
     22   -- And we would rather prefer that this buffer will be destroyed when hide.
     23   vim.api.nvim_buf_set_option(buf, 'bufhidden', 'wipe')
     24   -- It's not necessary but it is good practice to set custom filetype.
     25   -- This allows users to create their own autocommand or colorschemes on filetype.
     26   -- and prevent collisions with other plugins.
     27   vim.api.nvim_buf_set_option(buf, 'filetype', 'git-blame')
     28 
     29   -- For better UX we will turn off line wrap and turn on current line highlight.
     30   vim.api.nvim_win_set_option(win, 'wrap', false)
     31   vim.api.nvim_win_set_option(win, 'cursorline', true)
     32   vim.api.nvim_win_set_width(win, 40)
     33   -- set_mappings() -- At end we will set mappings for our navigation.
     34 
     35   -- the grep is an ugly but super performant way to remove everything up until the first occurance of " ("
     36   -- which strips off the commit hash and filename from the git blame log
     37 
     38   vim.api.nvim_command('read!git blame --date human ' .. startingBuf .. ' | grep -o " (.* [0-9]\\+)" | cut -c 3- ')
     39   -- vim.api.nvim_command('read!git blame --date human ' .. startingBuf  .. ' |  sed -n "s/ (/&\n/;s/.*\n//p"' )
     40   vim.cmd('normal gg')
     41   vim.cmd('normal dd') -- there is an empty line at the top of the file - remove it
     42 end
     43 
     44 local get_current_window = function() return vim.api.nvim_get_current_win() end
     45 
     46 local function get_current_cursor_location(window) return vim.api.nvim_win_get_cursor(window) end
     47 
     48 local function set_cursor_position(window, position) return vim.api.nvim_win_set_cursor(window, position) end
     49 
     50 local blame = function()
     51   local starting_window = get_current_window()
     52 
     53   vim.api.nvim_win_set_option(starting_window, 'scrollbind', true)
     54 
     55   local starting_cursor_location = get_current_cursor_location(starting_window)
     56 
     57   vim.cmd('normal gg')
     58 
     59   create_win()
     60 
     61   local blame_window = get_current_window()
     62 
     63   set_cursor_position(blame_window, starting_cursor_location)
     64 
     65   vim.api.nvim_win_set_option(starting_window, 'scrollbind', true)
     66 
     67   vim.cmd('normal gg')
     68 
     69   set_cursor_position(starting_window, starting_cursor_location)
     70 end
     71 
     72 vim.api.nvim_create_user_command('GitBlame', blame, {})