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, {})