Refresh generated neovim config
This commit is contained in:
@ -42,6 +42,15 @@ of the default settings:
|
||||
changedelete = { text = '~' },
|
||||
untracked = { text = '┆' },
|
||||
},
|
||||
signs_staged = {
|
||||
add = { text = '┃' },
|
||||
change = { text = '┃' },
|
||||
delete = { text = '_' },
|
||||
topdelete = { text = '‾' },
|
||||
changedelete = { text = '~' },
|
||||
untracked = { text = '┆' },
|
||||
},
|
||||
signs_staged_enable = true,
|
||||
signcolumn = true, -- Toggle with `:Gitsigns toggle_signs`
|
||||
numhl = false, -- Toggle with `:Gitsigns toggle_numhl`
|
||||
linehl = false, -- Toggle with `:Gitsigns toggle_linehl`
|
||||
@ -287,9 +296,13 @@ blame({callback?}) *gitsigns.blame()*
|
||||
Run git-blame on the current file and open the results
|
||||
in a scroll-bound vertical split.
|
||||
|
||||
<CR> is mapped to open a menu with the actions:
|
||||
- [Show commit] in a vertical split.
|
||||
- [Reblame at commit]
|
||||
Mappings:
|
||||
<CR> is mapped to open a menu with the other mappings
|
||||
Note: <Alt> must be held to activate the mappings whilst the menu is
|
||||
open.
|
||||
s [Show commit] in a vertical split.
|
||||
S [Show commit] in a new tab.
|
||||
r [Reblame at commit]
|
||||
|
||||
Attributes: ~
|
||||
{async}
|
||||
@ -308,8 +321,6 @@ blame_line({opts}, {callback?}) *gitsigns.blame_line()*
|
||||
Display full commit message with hunk.
|
||||
• {ignore_whitespace}: (boolean)
|
||||
Ignore whitespace when running blame.
|
||||
• {rev}: (string)
|
||||
Revision to blame against.
|
||||
• {extra_opts}: (string[])
|
||||
Extra options passed to `git-blame`.
|
||||
|
||||
@ -561,6 +572,7 @@ signs *gitsigns-config-signs*
|
||||
• `GitSignsAdd` (for normal text signs)
|
||||
• `GitSignsAddNr` (for signs when `config.numhl == true`)
|
||||
• `GitSignsAddLn `(for signs when `config.linehl == true`)
|
||||
• `GitSignsAddCul `(for signs when `config.culhl == true`)
|
||||
|
||||
See |gitsigns-highlight-groups|.
|
||||
|
||||
@ -675,6 +687,16 @@ linehl *gitsigns-config-linehl*
|
||||
the highlight group does not exist, then it is automatically defined
|
||||
and linked to the corresponding highlight group in `signs.*.hl`.
|
||||
|
||||
culhl *gitsigns-config-culhl*
|
||||
Type: `boolean`, Default: `false`
|
||||
|
||||
Enable/disable highlights for the sign column when the cursor is on
|
||||
the same line.
|
||||
|
||||
When enabled the highlights defined in `signs.*.culhl` are used. If
|
||||
the highlight group does not exist, then it is automatically defined
|
||||
and linked to the corresponding highlight group in `signs.*.hl`.
|
||||
|
||||
show_deleted *gitsigns-config-show_deleted*
|
||||
Type: `boolean`, Default: `false`
|
||||
|
||||
@ -1030,6 +1052,36 @@ GitSignsUntrackedLn
|
||||
Used for buffer line (when `config.linehl == true`) of 'untracked' signs.
|
||||
|
||||
Fallbacks: `GitSignsAddLn`
|
||||
*hl-GitSignsAddCul*
|
||||
GitSignsAddCul
|
||||
Used for the text of 'add' signs when the cursor is on the same line as the sign.
|
||||
|
||||
Fallbacks: `GitSignsAdd`
|
||||
*hl-GitSignsChangeCul*
|
||||
GitSignsChangeCul
|
||||
Used for the text of 'change' signs when the cursor is on the same line as the sign.
|
||||
|
||||
Fallbacks: `GitSignsChange`
|
||||
*hl-GitSignsDeleteCul*
|
||||
GitSignsDeleteCul
|
||||
Used for the text of 'delete' signs when the cursor is on the same line as the sign.
|
||||
|
||||
Fallbacks: `GitSignsDelete`
|
||||
*hl-GitSignsChangedeleteCul*
|
||||
GitSignsChangedeleteCul
|
||||
Used for the text of 'changedelete' signs when the cursor is on the same line as the sign.
|
||||
|
||||
Fallbacks: `GitSignsChangeCul`
|
||||
*hl-GitSignsTopdeleteCul*
|
||||
GitSignsTopdeleteCul
|
||||
Used for the text of 'topdelete' signs when the cursor is on the same line as the sign.
|
||||
|
||||
Fallbacks: `GitSignsDeleteCul`
|
||||
*hl-GitSignsUntrackedCul*
|
||||
GitSignsUntrackedCul
|
||||
Used for the text of 'untracked' signs when the cursor is on the same line as the sign.
|
||||
|
||||
Fallbacks: `GitSignsAddCul`
|
||||
*hl-GitSignsAddPreview*
|
||||
GitSignsAddPreview
|
||||
Used for added lines in previews.
|
||||
@ -1202,4 +1254,3 @@ GitSignsChanged After any event in which Gitsigns can potentially change
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
vim:tw=78:ts=8:ft=help:norl:
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ gitsigns-config-attach_to_untracked gitsigns.txt /*gitsigns-config-attach_to_unt
|
||||
gitsigns-config-auto_attach gitsigns.txt /*gitsigns-config-auto_attach*
|
||||
gitsigns-config-base gitsigns.txt /*gitsigns-config-base*
|
||||
gitsigns-config-count_chars gitsigns.txt /*gitsigns-config-count_chars*
|
||||
gitsigns-config-culhl gitsigns.txt /*gitsigns-config-culhl*
|
||||
gitsigns-config-current_line_blame gitsigns.txt /*gitsigns-config-current_line_blame*
|
||||
gitsigns-config-current_line_blame_formatter gitsigns.txt /*gitsigns-config-current_line_blame_formatter*
|
||||
gitsigns-config-current_line_blame_formatter_nc gitsigns.txt /*gitsigns-config-current_line_blame_formatter_nc*
|
||||
@ -82,21 +83,25 @@ gitsigns.toggle_word_diff() gitsigns.txt /*gitsigns.toggle_word_diff()*
|
||||
gitsigns.txt gitsigns.txt /*gitsigns.txt*
|
||||
gitsigns.undo_stage_hunk() gitsigns.txt /*gitsigns.undo_stage_hunk()*
|
||||
hl-GitSignsAdd gitsigns.txt /*hl-GitSignsAdd*
|
||||
hl-GitSignsAddCul gitsigns.txt /*hl-GitSignsAddCul*
|
||||
hl-GitSignsAddInline gitsigns.txt /*hl-GitSignsAddInline*
|
||||
hl-GitSignsAddLn gitsigns.txt /*hl-GitSignsAddLn*
|
||||
hl-GitSignsAddLnInline gitsigns.txt /*hl-GitSignsAddLnInline*
|
||||
hl-GitSignsAddNr gitsigns.txt /*hl-GitSignsAddNr*
|
||||
hl-GitSignsAddPreview gitsigns.txt /*hl-GitSignsAddPreview*
|
||||
hl-GitSignsChange gitsigns.txt /*hl-GitSignsChange*
|
||||
hl-GitSignsChangeCul gitsigns.txt /*hl-GitSignsChangeCul*
|
||||
hl-GitSignsChangeInline gitsigns.txt /*hl-GitSignsChangeInline*
|
||||
hl-GitSignsChangeLn gitsigns.txt /*hl-GitSignsChangeLn*
|
||||
hl-GitSignsChangeLnInline gitsigns.txt /*hl-GitSignsChangeLnInline*
|
||||
hl-GitSignsChangeNr gitsigns.txt /*hl-GitSignsChangeNr*
|
||||
hl-GitSignsChangedelete gitsigns.txt /*hl-GitSignsChangedelete*
|
||||
hl-GitSignsChangedeleteCul gitsigns.txt /*hl-GitSignsChangedeleteCul*
|
||||
hl-GitSignsChangedeleteLn gitsigns.txt /*hl-GitSignsChangedeleteLn*
|
||||
hl-GitSignsChangedeleteNr gitsigns.txt /*hl-GitSignsChangedeleteNr*
|
||||
hl-GitSignsCurrentLineBlame gitsigns.txt /*hl-GitSignsCurrentLineBlame*
|
||||
hl-GitSignsDelete gitsigns.txt /*hl-GitSignsDelete*
|
||||
hl-GitSignsDeleteCul gitsigns.txt /*hl-GitSignsDeleteCul*
|
||||
hl-GitSignsDeleteInline gitsigns.txt /*hl-GitSignsDeleteInline*
|
||||
hl-GitSignsDeleteLnInline gitsigns.txt /*hl-GitSignsDeleteLnInline*
|
||||
hl-GitSignsDeleteNr gitsigns.txt /*hl-GitSignsDeleteNr*
|
||||
@ -104,8 +109,10 @@ hl-GitSignsDeletePreview gitsigns.txt /*hl-GitSignsDeletePreview*
|
||||
hl-GitSignsDeleteVirtLn gitsigns.txt /*hl-GitSignsDeleteVirtLn*
|
||||
hl-GitSignsDeleteVirtLnInLine gitsigns.txt /*hl-GitSignsDeleteVirtLnInLine*
|
||||
hl-GitSignsTopdelete gitsigns.txt /*hl-GitSignsTopdelete*
|
||||
hl-GitSignsTopdeleteCul gitsigns.txt /*hl-GitSignsTopdeleteCul*
|
||||
hl-GitSignsTopdeleteNr gitsigns.txt /*hl-GitSignsTopdeleteNr*
|
||||
hl-GitSignsUntracked gitsigns.txt /*hl-GitSignsUntracked*
|
||||
hl-GitSignsUntrackedCul gitsigns.txt /*hl-GitSignsUntrackedCul*
|
||||
hl-GitSignsUntrackedLn gitsigns.txt /*hl-GitSignsUntrackedLn*
|
||||
hl-GitSignsUntrackedNr gitsigns.txt /*hl-GitSignsUntrackedNr*
|
||||
hl-GitSignsVirtLnum gitsigns.txt /*hl-GitSignsVirtLnum*
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
local async = require('gitsigns.async')
|
||||
local log = require('gitsigns.debug.log')
|
||||
local Config = require('gitsigns.config')
|
||||
|
||||
local gs_config = require('gitsigns.config')
|
||||
local config = gs_config.config
|
||||
local config = Config.config
|
||||
|
||||
local api = vim.api
|
||||
local uv = vim.uv or vim.loop
|
||||
@ -12,8 +12,8 @@ local M = {}
|
||||
local cwd_watcher ---@type uv.uv_fs_event_t?
|
||||
|
||||
--- @async
|
||||
--- @return string gitdir
|
||||
--- @return string head
|
||||
--- @return string? gitdir
|
||||
--- @return string? head
|
||||
local function get_gitdir_and_head()
|
||||
local cwd = assert(uv.cwd())
|
||||
|
||||
@ -29,9 +29,11 @@ local function get_gitdir_and_head()
|
||||
end
|
||||
end
|
||||
|
||||
local info = require('gitsigns.git').get_repo_info(cwd)
|
||||
local info = require('gitsigns.git').Repo.get_info(cwd)
|
||||
|
||||
return info.gitdir, info.abbrev_head
|
||||
if info then
|
||||
return info.gitdir, info.abbrev_head
|
||||
end
|
||||
end
|
||||
|
||||
local update_cwd_head = async.create(function()
|
||||
@ -89,7 +91,7 @@ local update_cwd_head = async.create(function()
|
||||
100,
|
||||
async.create(function()
|
||||
local git = require('gitsigns.git')
|
||||
local new_head = git.get_repo_info(cwd).abbrev_head
|
||||
local new_head = git.Repo.get_info(cwd).abbrev_head
|
||||
async.scheduler()
|
||||
vim.g.gitsigns_head = new_head
|
||||
end)
|
||||
@ -204,7 +206,7 @@ end
|
||||
--- @param cfg table|nil Configuration for Gitsigns.
|
||||
--- See |gitsigns-usage| for more details.
|
||||
function M.setup(cfg)
|
||||
gs_config.build(cfg)
|
||||
Config.build(cfg)
|
||||
|
||||
if vim.fn.executable('git') == 0 then
|
||||
print('gitsigns: git not in path. Aborting setup')
|
||||
|
||||
@ -1,16 +1,14 @@
|
||||
local async = require('gitsigns.async')
|
||||
local config = require('gitsigns.config').config
|
||||
local mk_repeatable = require('gitsigns.repeat').mk_repeatable
|
||||
local git = require('gitsigns.git')
|
||||
local Hunks = require('gitsigns.hunks')
|
||||
local manager = require('gitsigns.manager')
|
||||
local popup = require('gitsigns.popup')
|
||||
local util = require('gitsigns.util')
|
||||
local manager = require('gitsigns.manager')
|
||||
local git = require('gitsigns.git')
|
||||
local run_diff = require('gitsigns.diff')
|
||||
|
||||
local gs_cache = require('gitsigns.cache')
|
||||
local cache = gs_cache.cache
|
||||
|
||||
local Hunks = require('gitsigns.hunks')
|
||||
local config = require('gitsigns.config').config
|
||||
local mk_repeatable = require('gitsigns.repeat').mk_repeatable
|
||||
local cache = require('gitsigns.cache').cache
|
||||
|
||||
local api = vim.api
|
||||
local current_buf = api.nvim_get_current_buf
|
||||
@ -416,7 +414,6 @@ end)
|
||||
--- {async}
|
||||
M.stage_buffer = async.create(function()
|
||||
local bufnr = current_buf()
|
||||
|
||||
local bcache = cache[bufnr]
|
||||
if not bcache then
|
||||
return
|
||||
@ -977,8 +974,6 @@ end
|
||||
--- Display full commit message with hunk.
|
||||
--- • {ignore_whitespace}: (boolean)
|
||||
--- Ignore whitespace when running blame.
|
||||
--- • {rev}: (string)
|
||||
--- Revision to blame against.
|
||||
--- • {extra_opts}: (string[])
|
||||
--- Extra options passed to `git-blame`.
|
||||
M.blame_line = async.create(1, function(opts)
|
||||
@ -1014,16 +1009,14 @@ M.blame_line = async.create(1, function(opts)
|
||||
return
|
||||
end
|
||||
|
||||
assert(result)
|
||||
|
||||
result = util.convert_blame_info(result)
|
||||
result = util.convert_blame_info(assert(result))
|
||||
|
||||
local is_committed = result.sha and tonumber('0x' .. result.sha) ~= 0
|
||||
|
||||
local blame_linespec = create_blame_fmt(is_committed, opts.full)
|
||||
|
||||
if is_committed and opts.full then
|
||||
local body = bcache.git_obj:command(
|
||||
local body = bcache.git_obj.repo:command(
|
||||
{ 'show', '-s', '--format=%B', result.sha },
|
||||
{ text = true }
|
||||
)
|
||||
@ -1055,9 +1048,13 @@ end
|
||||
--- Run git-blame on the current file and open the results
|
||||
--- in a scroll-bound vertical split.
|
||||
---
|
||||
--- <CR> is mapped to open a menu with the actions:
|
||||
--- - [Show commit] in a vertical split.
|
||||
--- - [Reblame at commit]
|
||||
--- Mappings:
|
||||
--- <CR> is mapped to open a menu with the other mappings
|
||||
--- Note: <Alt> must be held to activate the mappings whilst the menu is
|
||||
--- open.
|
||||
--- s [Show commit] in a vertical split.
|
||||
--- S [Show commit] in a new tab.
|
||||
--- r [Reblame at commit]
|
||||
---
|
||||
--- Attributes: ~
|
||||
--- {async}
|
||||
@ -1243,6 +1240,10 @@ M.show = function(revision, callback)
|
||||
diffthis.show(bufnr, revision, callback)
|
||||
end
|
||||
|
||||
C.show = function(args, _)
|
||||
M.show(args[1])
|
||||
end
|
||||
|
||||
CP.show = complete_heads
|
||||
|
||||
--- @param buf_or_filename string|integer
|
||||
@ -1287,17 +1288,24 @@ local function buildqflist(target)
|
||||
end
|
||||
end
|
||||
|
||||
local repo = git.Repo.new(assert(vim.loop.cwd()))
|
||||
if not repos[repo.gitdir] then
|
||||
local repo = git.Repo.get(assert(vim.loop.cwd()))
|
||||
if repo and not repos[repo.gitdir] then
|
||||
repos[repo.gitdir] = repo
|
||||
end
|
||||
|
||||
for _, r in pairs(repos) do
|
||||
for _, f in ipairs(r:files_changed()) do
|
||||
for _, f in ipairs(r:files_changed(config.base)) do
|
||||
local f_abs = r.toplevel .. '/' .. f
|
||||
local stat = vim.loop.fs_stat(f_abs)
|
||||
if stat and stat.type == 'file' then
|
||||
local a = r:get_show_text(':0:' .. f)
|
||||
---@type string
|
||||
local obj
|
||||
if config.base and config.base ~= ':0' then
|
||||
obj = config.base .. ':' .. f
|
||||
else
|
||||
obj = ':0:' .. f
|
||||
end
|
||||
local a = r:get_show_text(obj)
|
||||
async.scheduler()
|
||||
local hunks = run_diff(a, util.file_lines(f_abs))
|
||||
hunks_to_qflist(f_abs, hunks, qflist)
|
||||
|
||||
@ -181,6 +181,7 @@ function M.create(argc_or_func, func)
|
||||
|
||||
return function(...)
|
||||
local callback = argc and select(argc + 1, ...) or nil
|
||||
assert(not callback or type(callback) == 'function')
|
||||
return run(func, callback, unpack({ ... }, 1, argc))
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,20 +1,15 @@
|
||||
local Status = require('gitsigns.status')
|
||||
local async = require('gitsigns.async')
|
||||
local git = require('gitsigns.git')
|
||||
|
||||
local manager = require('gitsigns.manager')
|
||||
|
||||
local Cache = require('gitsigns.cache')
|
||||
local log = require('gitsigns.debug.log')
|
||||
local dprintf = log.dprintf
|
||||
local dprint = log.dprint
|
||||
|
||||
local gs_cache = require('gitsigns.cache')
|
||||
local cache = gs_cache.cache
|
||||
local Status = require('gitsigns.status')
|
||||
|
||||
local config = require('gitsigns.config').config
|
||||
|
||||
local manager = require('gitsigns.manager')
|
||||
local util = require('gitsigns.util')
|
||||
|
||||
local cache = Cache.cache
|
||||
local config = require('gitsigns.config').config
|
||||
local dprint = log.dprint
|
||||
local dprintf = log.dprintf
|
||||
local throttle_by_id = require('gitsigns.debounce').throttle_by_id
|
||||
|
||||
local api = vim.api
|
||||
@ -46,13 +41,25 @@ end
|
||||
--- @return string buffer
|
||||
--- @return string? commit
|
||||
local function parse_gitsigns_uri(name)
|
||||
-- TODO(lewis6991): Support submodules
|
||||
--- @type any, any, string?, string?, string
|
||||
local _, _, root_path, commit, rel_path = name:find([[^gitsigns://(.*)/%.git/(.*):(.*)]])
|
||||
local _proto, head, tail = unpack(vim.split(name, '//'))
|
||||
|
||||
--- @type any, any, string?, string?
|
||||
local _, _, root_path, sub_path = head:find([[(.*)/%.git(.*)]])
|
||||
|
||||
--- @type any, any, string?, string?
|
||||
local _, _, commit, rel_path = tail:find([[(.*):(.*)]])
|
||||
|
||||
commit = util.norm_base(commit)
|
||||
|
||||
if root_path then
|
||||
name = root_path .. '/' .. rel_path
|
||||
if sub_path then
|
||||
sub_path = sub_path:gsub('^/modules/', '')
|
||||
name = string.format('%s/%s/%s', root_path, sub_path, rel_path)
|
||||
else
|
||||
name = string.format('%s/%s', root_path, rel_path)
|
||||
end
|
||||
end
|
||||
|
||||
return name, commit
|
||||
end
|
||||
|
||||
@ -71,7 +78,7 @@ local function get_buf_path(bufnr)
|
||||
dprintf("Fugitive buffer for file '%s' from path '%s'", path, file)
|
||||
if path then
|
||||
local realpath = uv.fs_realpath(path)
|
||||
if realpath then
|
||||
if realpath and vim.fn.isdirectory(realpath) == 0 then
|
||||
return realpath, commit, true
|
||||
end
|
||||
end
|
||||
@ -323,7 +330,7 @@ local attach_throttled = throttle_by_id(function(cbuf, ctx, aucmd)
|
||||
return
|
||||
end
|
||||
|
||||
cache[cbuf] = gs_cache.new({
|
||||
cache[cbuf] = Cache.new({
|
||||
bufnr = cbuf,
|
||||
file = file,
|
||||
git_obj = git_obj,
|
||||
@ -357,6 +364,10 @@ local attach_throttled = throttle_by_id(function(cbuf, ctx, aucmd)
|
||||
|
||||
-- Initial update
|
||||
manager.update(cbuf)
|
||||
|
||||
if config.current_line_blame then
|
||||
require('gitsigns.current_line_blame').update(cbuf)
|
||||
end
|
||||
end)
|
||||
|
||||
--- Detach Gitsigns from all buffers it is attached to.
|
||||
@ -391,7 +402,7 @@ function M.detach(bufnr, _keep_signs)
|
||||
-- Clear status variables
|
||||
Status:clear(bufnr)
|
||||
|
||||
gs_cache.destroy(bufnr)
|
||||
Cache.destroy(bufnr)
|
||||
end
|
||||
|
||||
--- Attach Gitsigns to the buffer.
|
||||
|
||||
@ -22,9 +22,12 @@ local M = {
|
||||
--- @field blame? table<integer,Gitsigns.BlameInfo?>
|
||||
local CacheEntry = M.CacheEntry
|
||||
|
||||
function CacheEntry:get_rev_bufname(rev)
|
||||
function CacheEntry:get_rev_bufname(rev, nofile)
|
||||
rev = rev or self.git_obj.revision or ':0'
|
||||
return string.format('gitsigns://%s/%s:%s', self.git_obj.repo.gitdir, rev, self.git_obj.relpath)
|
||||
if nofile then
|
||||
return string.format('gitsigns://%s//%s', self.git_obj.repo.gitdir, rev)
|
||||
end
|
||||
return string.format('gitsigns://%s//%s:%s', self.git_obj.repo.gitdir, rev, self.git_obj.relpath)
|
||||
end
|
||||
|
||||
--- Invalidate any state dependent on the buffer content.
|
||||
@ -53,6 +56,7 @@ local sleep = async.wrap(2, function(duration, cb)
|
||||
vim.defer_fn(cb, duration)
|
||||
end)
|
||||
|
||||
--- @async
|
||||
--- @private
|
||||
function CacheEntry:wait_for_hunks()
|
||||
local loop_protect = 0
|
||||
@ -65,71 +69,61 @@ end
|
||||
-- If a file contains has up to this amount of lines, then
|
||||
-- always blame the whole file, otherwise only blame one line
|
||||
-- at a time.
|
||||
local BLAME_THRESHOLD_LEN = 1000000
|
||||
local BLAME_THRESHOLD_LEN = 10000
|
||||
|
||||
--- @async
|
||||
--- @private
|
||||
--- @param lnum? integer
|
||||
--- @param opts Gitsigns.BlameOpts
|
||||
--- @return table<integer,Gitsigns.BlameInfo?>?
|
||||
--- @param opts? Gitsigns.BlameOpts
|
||||
--- @return table<integer,Gitsigns.BlameInfo?>
|
||||
--- @return boolean? full
|
||||
function CacheEntry:run_blame(lnum, opts)
|
||||
local bufnr = self.bufnr
|
||||
local blame_cache --- @type table<integer,Gitsigns.BlameInfo?>?
|
||||
local blame --- @type table<integer,Gitsigns.BlameInfo?>?
|
||||
local lnum0 --- @type integer?
|
||||
repeat
|
||||
local buftext = util.buf_lines(bufnr, true)
|
||||
local tick = vim.b[bufnr].changedtick
|
||||
local lnum0 = #buftext > BLAME_THRESHOLD_LEN and lnum or nil
|
||||
lnum0 = #buftext > BLAME_THRESHOLD_LEN and lnum or nil
|
||||
-- TODO(lewis6991): Cancel blame on changedtick
|
||||
blame_cache = self.git_obj:run_blame(buftext, lnum0, opts)
|
||||
blame = self.git_obj:run_blame(buftext, lnum0, self.git_obj.revision, opts)
|
||||
async.scheduler()
|
||||
if not vim.api.nvim_buf_is_valid(bufnr) then
|
||||
return
|
||||
return {}
|
||||
end
|
||||
until vim.b[bufnr].changedtick == tick
|
||||
return blame_cache
|
||||
return blame, lnum0 == nil
|
||||
end
|
||||
|
||||
--- @param file string
|
||||
--- @param lnum integer
|
||||
--- @return Gitsigns.BlameInfo
|
||||
local function get_blame_nc(file, lnum)
|
||||
local Git = require('gitsigns.git')
|
||||
|
||||
return {
|
||||
orig_lnum = 0,
|
||||
final_lnum = lnum,
|
||||
commit = Git.not_committed(file),
|
||||
filename = file,
|
||||
}
|
||||
end
|
||||
|
||||
--- @param lnum integer
|
||||
--- @param opts Gitsigns.BlameOpts
|
||||
--- If lnum is nil then run blame for the entire buffer.
|
||||
--- @async
|
||||
--- @param lnum? integer
|
||||
--- @param opts? Gitsigns.BlameOpts
|
||||
--- @return Gitsigns.BlameInfo?
|
||||
function CacheEntry:get_blame(lnum, opts)
|
||||
if opts.rev then
|
||||
local buftext = util.buf_lines(self.bufnr)
|
||||
return self.git_obj:run_blame(buftext, lnum, opts)[lnum]
|
||||
end
|
||||
local blame = self.blame
|
||||
|
||||
local blame_cache = self.blame
|
||||
|
||||
if not blame_cache or not blame_cache[lnum] then
|
||||
if not blame or (lnum and not blame[lnum]) then
|
||||
self:wait_for_hunks()
|
||||
blame = blame or {}
|
||||
local Hunks = require('gitsigns.hunks')
|
||||
if Hunks.find_hunk(lnum, self.hunks) then
|
||||
if lnum and Hunks.find_hunk(lnum, self.hunks) then
|
||||
--- Bypass running blame (which can be expensive) if we know lnum is in a hunk
|
||||
blame_cache = blame_cache or {}
|
||||
blame_cache[lnum] = get_blame_nc(self.git_obj.relpath, lnum)
|
||||
local Blame = require('gitsigns.git.blame')
|
||||
blame[lnum] = Blame.get_blame_nc(self.git_obj.relpath, lnum)
|
||||
else
|
||||
-- Refresh cache
|
||||
blame_cache = self:run_blame(lnum, opts)
|
||||
-- Refresh/update cache
|
||||
local b, full = self:run_blame(lnum, opts)
|
||||
if lnum and not full then
|
||||
blame[lnum] = b[lnum]
|
||||
else
|
||||
blame = b
|
||||
end
|
||||
end
|
||||
self.blame = blame_cache
|
||||
self.blame = blame
|
||||
end
|
||||
|
||||
if blame_cache then
|
||||
return blame_cache[lnum]
|
||||
end
|
||||
return blame[lnum]
|
||||
end
|
||||
|
||||
function CacheEntry:destroy()
|
||||
@ -137,9 +131,10 @@ function CacheEntry:destroy()
|
||||
if w and not w:is_closing() then
|
||||
w:close()
|
||||
end
|
||||
self.git_obj.repo:unref()
|
||||
end
|
||||
|
||||
---@type table<integer,Gitsigns.CacheEntry>
|
||||
---@type table<integer,Gitsigns.CacheEntry?>
|
||||
M.cache = {}
|
||||
|
||||
--- @param bufnr integer
|
||||
|
||||
@ -1,20 +1,16 @@
|
||||
local async = require('gitsigns.async')
|
||||
|
||||
local log = require('gitsigns.debug.log')
|
||||
local dprintf = log.dprintf
|
||||
local message = require('gitsigns.message')
|
||||
|
||||
local parse_args = require('gitsigns.cli.argparse').parse_args
|
||||
|
||||
local actions = require('gitsigns.actions')
|
||||
local argparse = require('gitsigns.cli.argparse')
|
||||
local async = require('gitsigns.async')
|
||||
local attach = require('gitsigns.attach')
|
||||
local gs_debug = require('gitsigns.debug')
|
||||
local Debug = require('gitsigns.debug')
|
||||
local log = require('gitsigns.debug.log')
|
||||
local message = require('gitsigns.message')
|
||||
|
||||
--- @type table<table<string,function>,boolean>
|
||||
local sources = {
|
||||
[actions] = true,
|
||||
[attach] = false,
|
||||
[gs_debug] = false,
|
||||
[Debug] = false,
|
||||
}
|
||||
|
||||
-- try to parse each argument as a lua boolean, nil or number, if fails then
|
||||
@ -64,7 +60,7 @@ end
|
||||
|
||||
M.run = async.create(1, function(params)
|
||||
local __FUNC__ = 'cli.run'
|
||||
local pos_args_raw, named_args_raw = parse_args(params.args)
|
||||
local pos_args_raw, named_args_raw = argparse.parse_args(params.args)
|
||||
|
||||
local func = pos_args_raw[1]
|
||||
|
||||
@ -79,7 +75,7 @@ M.run = async.create(1, function(params)
|
||||
local named_args = vim.tbl_map(parse_to_lua, named_args_raw)
|
||||
local args = vim.tbl_extend('error', pos_args, named_args)
|
||||
|
||||
dprintf(
|
||||
log.dprintf(
|
||||
"Running action '%s' with arguments %s",
|
||||
func,
|
||||
vim.inspect(args, { newline = ' ', indent = '' })
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
--- @field text string
|
||||
--- @field numhl string
|
||||
--- @field linehl string
|
||||
--- @field culhl string
|
||||
|
||||
--- @alias Gitsigns.SignType
|
||||
--- | 'add'
|
||||
@ -34,7 +35,7 @@
|
||||
--- | 'changedelete'
|
||||
--- | 'untracked'
|
||||
|
||||
--- @alias Gitsigns.CurrentLineBlameFmtFun fun(user: string, info: table<string,any>): {[1]:string,[2]:string}[]
|
||||
--- @alias Gitsigns.CurrentLineBlameFmtFun fun(user: string, info: table<string,any>): [string,string][]
|
||||
|
||||
--- @class (exact) Gitsigns.CurrentLineBlameOpts : Gitsigns.BlameOpts
|
||||
--- @field virt_text? boolean
|
||||
@ -44,7 +45,6 @@
|
||||
|
||||
--- @class (exact) Gitsigns.BlameOpts
|
||||
--- @field ignore_whitespace? boolean
|
||||
--- @field rev? string
|
||||
--- @field extra_opts? string[]
|
||||
|
||||
--- @class (exact) Gitsigns.LineBlameOpts : Gitsigns.BlameOpts
|
||||
@ -61,6 +61,7 @@
|
||||
--- @field signcolumn boolean
|
||||
--- @field numhl boolean
|
||||
--- @field linehl boolean
|
||||
--- @field culhl boolean
|
||||
--- @field show_deleted boolean
|
||||
--- @field sign_priority integer
|
||||
--- @field _on_attach_pre fun(bufnr: integer, callback: fun(_: table))
|
||||
@ -184,10 +185,13 @@ local function validate_signs(x)
|
||||
if x[kind] and x[kind][ty] and vim.endswith(ty, 'hl') then
|
||||
warnings = warnings or {}
|
||||
local w = string.format(
|
||||
"'signs.%s.%s' is now deprecated, please define highlight '%s'",
|
||||
"'signs.%s.%s' is now deprecated, please define highlight '%s' e.g:\n"
|
||||
.. " vim.api.nvim_set_hl(0, '%s', { link = '%s' })",
|
||||
kind,
|
||||
ty,
|
||||
v
|
||||
v,
|
||||
v,
|
||||
x[kind][ty]
|
||||
)
|
||||
warnings[w] = true
|
||||
end
|
||||
@ -210,36 +214,47 @@ M.schema = {
|
||||
type = validate_signs,
|
||||
deep_extend = true,
|
||||
default = {
|
||||
add = { hl = 'GitSignsAdd', text = '┃', numhl = 'GitSignsAddNr', linehl = 'GitSignsAddLn' },
|
||||
add = {
|
||||
hl = 'GitSignsAdd',
|
||||
text = '┃',
|
||||
numhl = 'GitSignsAddNr',
|
||||
linehl = 'GitSignsAddLn',
|
||||
culhl = 'GitSignsAddCul',
|
||||
},
|
||||
change = {
|
||||
hl = 'GitSignsChange',
|
||||
text = '┃',
|
||||
numhl = 'GitSignsChangeNr',
|
||||
linehl = 'GitSignsChangeLn',
|
||||
culhl = 'GitSignsChangeCul',
|
||||
},
|
||||
delete = {
|
||||
hl = 'GitSignsDelete',
|
||||
text = '▁',
|
||||
numhl = 'GitSignsDeleteNr',
|
||||
linehl = 'GitSignsDeleteLn',
|
||||
culhl = 'GitSignsDeleteCul',
|
||||
},
|
||||
topdelete = {
|
||||
hl = 'GitSignsTopdelete',
|
||||
text = '▔',
|
||||
numhl = 'GitSignsTopdeleteNr',
|
||||
linehl = 'GitSignsTopdeleteLn',
|
||||
culhl = 'GitSignsTopdeleteCul',
|
||||
},
|
||||
changedelete = {
|
||||
hl = 'GitSignsChangedelete',
|
||||
text = '~',
|
||||
numhl = 'GitSignsChangedeleteNr',
|
||||
linehl = 'GitSignsChangedeleteLn',
|
||||
culhl = 'GitSignsChangedeleteCul',
|
||||
},
|
||||
untracked = {
|
||||
hl = 'GitSignsUntracked',
|
||||
text = '┆',
|
||||
numhl = 'GitSignsUntrackedNr',
|
||||
linehl = 'GitSignsUntrackedLn',
|
||||
culhl = 'GitSignsUntrackedCul',
|
||||
},
|
||||
},
|
||||
default_help = [[{
|
||||
@ -261,6 +276,7 @@ M.schema = {
|
||||
• `GitSignsAdd` (for normal text signs)
|
||||
• `GitSignsAddNr` (for signs when `config.numhl == true`)
|
||||
• `GitSignsAddLn `(for signs when `config.linehl == true`)
|
||||
• `GitSignsAddCul `(for signs when `config.culhl == true`)
|
||||
|
||||
See |gitsigns-highlight-groups|.
|
||||
]],
|
||||
@ -275,30 +291,35 @@ M.schema = {
|
||||
text = '┃',
|
||||
numhl = 'GitSignsStagedAddNr',
|
||||
linehl = 'GitSignsStagedAddLn',
|
||||
culhl = 'GitSignsStagedAddCul',
|
||||
},
|
||||
change = {
|
||||
hl = 'GitSignsStagedChange',
|
||||
text = '┃',
|
||||
numhl = 'GitSignsStagedChangeNr',
|
||||
linehl = 'GitSignsStagedChangeLn',
|
||||
culhl = 'GitSignsStagedChangeCul',
|
||||
},
|
||||
delete = {
|
||||
hl = 'GitSignsStagedDelete',
|
||||
text = '▁',
|
||||
numhl = 'GitSignsStagedDeleteNr',
|
||||
linehl = 'GitSignsStagedDeleteLn',
|
||||
culhl = 'GitSignsStagedDeleteCul',
|
||||
},
|
||||
topdelete = {
|
||||
hl = 'GitSignsStagedTopdelete',
|
||||
text = '▔',
|
||||
numhl = 'GitSignsStagedTopdeleteNr',
|
||||
linehl = 'GitSignsStagedTopdeleteLn',
|
||||
culhl = 'GitSignsStagedTopdeleteCul',
|
||||
},
|
||||
changedelete = {
|
||||
hl = 'GitSignsStagedChangedelete',
|
||||
text = '~',
|
||||
numhl = 'GitSignsStagedChangedeleteNr',
|
||||
linehl = 'GitSignsStagedChangedeleteLn',
|
||||
culhl = 'GitSignsStagedChangedeleteCul',
|
||||
},
|
||||
},
|
||||
default_help = [[{
|
||||
@ -456,6 +477,19 @@ M.schema = {
|
||||
]],
|
||||
},
|
||||
|
||||
culhl = {
|
||||
type = 'boolean',
|
||||
default = false,
|
||||
description = [[
|
||||
Enable/disable highlights for the sign column when the cursor is on
|
||||
the same line.
|
||||
|
||||
When enabled the highlights defined in `signs.*.culhl` are used. If
|
||||
the highlight group does not exist, then it is automatically defined
|
||||
and linked to the corresponding highlight group in `signs.*.hl`.
|
||||
]],
|
||||
},
|
||||
|
||||
show_deleted = {
|
||||
type = 'boolean',
|
||||
default = false,
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
local async = require('gitsigns.async')
|
||||
local cache = require('gitsigns.cache').cache
|
||||
local config = require('gitsigns.config').config
|
||||
local debounce = require('gitsigns.debounce')
|
||||
local util = require('gitsigns.util')
|
||||
|
||||
local api = vim.api
|
||||
local cache = require('gitsigns.cache').cache
|
||||
local config = require('gitsigns.config').config
|
||||
local schema = require('gitsigns.config').schema
|
||||
local error_once = require('gitsigns.message').error_once
|
||||
|
||||
local debounce = require('gitsigns.debounce')
|
||||
local api = vim.api
|
||||
|
||||
local namespace = api.nvim_create_namespace('gitsigns_blame')
|
||||
|
||||
@ -72,19 +74,31 @@ end
|
||||
|
||||
---@param bufnr integer
|
||||
---@param blame_info Gitsigns.BlameInfoPublic
|
||||
---@return {[1]: string, [2]:string}[]
|
||||
---@return [string, string][]
|
||||
local function get_blame_virt_text(bufnr, blame_info)
|
||||
local git_obj = assert(cache[bufnr]).git_obj
|
||||
local use_nc = blame_info.author == 'Not Committed Yet'
|
||||
|
||||
local clb_formatter = blame_info.author == 'Not Committed Yet'
|
||||
and config.current_line_blame_formatter_nc
|
||||
local clb_formatter = use_nc and config.current_line_blame_formatter_nc
|
||||
or config.current_line_blame_formatter
|
||||
|
||||
if type(clb_formatter) == 'string' then
|
||||
clb_formatter = default_formatter(clb_formatter)
|
||||
if type(clb_formatter) == 'function' then
|
||||
local ok, res = pcall(clb_formatter, git_obj.repo.username, blame_info)
|
||||
if ok then
|
||||
return res
|
||||
end
|
||||
|
||||
local nc_sfx = use_nc and '_nc' or ''
|
||||
error_once(
|
||||
'Failed running config.current_line_blame_formatter%s, using default:\n %s',
|
||||
nc_sfx,
|
||||
res
|
||||
)
|
||||
--- @type string
|
||||
clb_formatter = schema.current_line_blame_formatter.default
|
||||
end
|
||||
|
||||
return clb_formatter(git_obj.repo.username, blame_info)
|
||||
return default_formatter(clb_formatter)(git_obj.repo.username, blame_info)
|
||||
end
|
||||
|
||||
--- @param bufnr integer
|
||||
@ -192,50 +206,53 @@ end
|
||||
local update = async.create(1, debounce.throttle_by_id(update0))
|
||||
|
||||
--- @type fun(bufnr: integer)
|
||||
local update_debounced
|
||||
M.update = nil
|
||||
|
||||
function M.setup()
|
||||
local group = api.nvim_create_augroup('gitsigns_blame', {})
|
||||
|
||||
local opts = config.current_line_blame_opts
|
||||
update_debounced = debounce.debounce_trailing(opts.delay, update)
|
||||
|
||||
for k, _ in pairs(cache) do
|
||||
for k in pairs(cache) do
|
||||
reset(k)
|
||||
end
|
||||
|
||||
if config.current_line_blame then
|
||||
local events = { 'FocusGained', 'BufEnter', 'CursorMoved', 'CursorMovedI' }
|
||||
if vim.fn.exists('#WinResized') == 1 then
|
||||
-- For nvim 0.9+
|
||||
events[#events + 1] = 'WinResized'
|
||||
end
|
||||
local group = api.nvim_create_augroup('gitsigns_blame', {})
|
||||
|
||||
api.nvim_create_autocmd(events, {
|
||||
group = group,
|
||||
callback = function(args)
|
||||
reset(args.buf)
|
||||
update_debounced(args.buf)
|
||||
end,
|
||||
})
|
||||
|
||||
api.nvim_create_autocmd({ 'InsertEnter', 'FocusLost', 'BufLeave' }, {
|
||||
group = group,
|
||||
callback = function(args)
|
||||
reset(args.buf)
|
||||
end,
|
||||
})
|
||||
|
||||
api.nvim_create_autocmd('OptionSet', {
|
||||
group = group,
|
||||
pattern = { 'fileformat', 'bomb', 'eol' },
|
||||
callback = function(args)
|
||||
reset(args.buf)
|
||||
end,
|
||||
})
|
||||
|
||||
update_debounced(api.nvim_get_current_buf())
|
||||
if not config.current_line_blame then
|
||||
return
|
||||
end
|
||||
|
||||
local opts = config.current_line_blame_opts
|
||||
M.update = debounce.debounce_trailing(opts.delay, update)
|
||||
|
||||
-- show current buffer line blame immediately
|
||||
M.update(api.nvim_get_current_buf())
|
||||
|
||||
local events = { 'FocusGained', 'BufEnter', 'CursorMoved', 'CursorMovedI' }
|
||||
if vim.fn.exists('#WinResized') == 1 then
|
||||
-- For nvim 0.9+
|
||||
events[#events + 1] = 'WinResized'
|
||||
end
|
||||
|
||||
api.nvim_create_autocmd(events, {
|
||||
group = group,
|
||||
callback = function(args)
|
||||
reset(args.buf)
|
||||
M.update(args.buf)
|
||||
end,
|
||||
})
|
||||
|
||||
api.nvim_create_autocmd({ 'InsertEnter', 'FocusLost', 'BufLeave' }, {
|
||||
group = group,
|
||||
callback = function(args)
|
||||
reset(args.buf)
|
||||
end,
|
||||
})
|
||||
|
||||
api.nvim_create_autocmd('OptionSet', {
|
||||
group = group,
|
||||
pattern = { 'fileformat', 'bomb', 'eol' },
|
||||
callback = function(args)
|
||||
reset(args.buf)
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
local uv = vim.loop
|
||||
local uv = vim.uv or vim.loop
|
||||
|
||||
local M = {}
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
local Hunks = require('gitsigns.hunks')
|
||||
local util = require('gitsigns.util')
|
||||
|
||||
local scheduler = require('gitsigns.async').scheduler
|
||||
local config = require('gitsigns.config').config
|
||||
local git_diff = require('gitsigns.git').diff
|
||||
|
||||
local gs_hunks = require('gitsigns.hunks')
|
||||
local util = require('gitsigns.util')
|
||||
local scheduler = require('gitsigns.async').scheduler
|
||||
|
||||
local M = {}
|
||||
-- Async function
|
||||
|
||||
@ -61,7 +61,7 @@ function M.run_diff(text_cmp, text_buf)
|
||||
|
||||
for _, line in ipairs(out) do
|
||||
if vim.startswith(line, '@@') then
|
||||
results[#results + 1] = gs_hunks.parse_diff_line(line)
|
||||
results[#results + 1] = Hunks.parse_diff_line(line)
|
||||
elseif #results > 0 then
|
||||
local r = results[#results]
|
||||
if line:sub(1, 1) == '-' then
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
local async = require('gitsigns.async')
|
||||
|
||||
local create_hunk = require('gitsigns.hunks').create_hunk
|
||||
local config = require('gitsigns.config').config
|
||||
local async = require('gitsigns.async')
|
||||
|
||||
local M = {}
|
||||
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
local api = vim.api
|
||||
|
||||
local async = require('gitsigns.async')
|
||||
local cache = require('gitsigns.cache').cache
|
||||
local util = require('gitsigns.util')
|
||||
local manager = require('gitsigns.manager')
|
||||
local message = require('gitsigns.message')
|
||||
local util = require('gitsigns.util')
|
||||
local Status = require('gitsigns.status')
|
||||
|
||||
local dprint = require('gitsigns.debug.log').dprint
|
||||
local cache = require('gitsigns.cache').cache
|
||||
local log = require('gitsigns.debug.log')
|
||||
local throttle_by_id = require('gitsigns.debounce').throttle_by_id
|
||||
|
||||
local api = vim.api
|
||||
|
||||
local M = {}
|
||||
|
||||
--- @async
|
||||
@ -17,7 +17,7 @@ local M = {}
|
||||
--- @param dbufnr integer
|
||||
--- @param base string?
|
||||
local function bufread(bufnr, dbufnr, base)
|
||||
local bcache = cache[bufnr]
|
||||
local bcache = assert(cache[bufnr])
|
||||
base = util.norm_base(base)
|
||||
local text --- @type string[]
|
||||
if base == bcache.git_obj.revision then
|
||||
@ -52,8 +52,9 @@ end
|
||||
--- @param bufnr integer
|
||||
--- @param dbufnr integer
|
||||
--- @param base string?
|
||||
local bufwrite = async.create(3, function(bufnr, dbufnr, base)
|
||||
local bcache = cache[bufnr]
|
||||
--- @param _callback? fun()
|
||||
local bufwrite = async.create(3, function(bufnr, dbufnr, base, _callback)
|
||||
local bcache = assert(cache[bufnr])
|
||||
local buftext = util.buf_lines(dbufnr)
|
||||
base = util.norm_base(base)
|
||||
bcache.git_obj:stage_lines(buftext)
|
||||
@ -151,14 +152,17 @@ end
|
||||
|
||||
--- @param base string?
|
||||
--- @param opts Gitsigns.DiffthisOpts
|
||||
M.diffthis = async.create(2, function(base, opts)
|
||||
--- @param _callback? fun()
|
||||
M.diffthis = async.create(2, function(base, opts, _callback)
|
||||
if vim.wo.diff then
|
||||
log.dprint('diff is disabled')
|
||||
return
|
||||
end
|
||||
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
local bcache = cache[bufnr]
|
||||
if not bcache then
|
||||
log.dprintf('buffer %d is not attached', bufnr)
|
||||
return
|
||||
end
|
||||
|
||||
@ -176,16 +180,24 @@ end)
|
||||
|
||||
--- @param bufnr integer
|
||||
--- @param base string
|
||||
M.show = async.create(2, function(bufnr, base)
|
||||
--- @param _callback? fun()
|
||||
M.show = async.create(2, function(bufnr, base, _callback)
|
||||
__FUNC__ = 'show'
|
||||
local bufname = create_show_buf(bufnr, base)
|
||||
if not bufname then
|
||||
dprint('No bufname for revision ' .. base)
|
||||
log.dprint('No bufname for revision ' .. base)
|
||||
return
|
||||
end
|
||||
|
||||
dprint('bufname ' .. bufname)
|
||||
log.dprint('bufname ' .. bufname)
|
||||
vim.cmd.edit(bufname)
|
||||
|
||||
-- Wait for the buffer to attach in case the user passes a callback that
|
||||
-- requires the buffer to be attached.
|
||||
local sbufnr = api.nvim_get_current_buf()
|
||||
vim.wait(2000, function()
|
||||
return cache[sbufnr] ~= nil
|
||||
end)
|
||||
end)
|
||||
|
||||
--- @param bufnr integer
|
||||
@ -205,16 +217,15 @@ end
|
||||
|
||||
-- This function needs to be throttled as there is a call to vim.ui.input
|
||||
--- @param bufnr integer
|
||||
M.update = throttle_by_id(async.create(1, function(bufnr)
|
||||
--- @param _callback? fun()
|
||||
M.update = throttle_by_id(async.create(1, function(bufnr, _callback)
|
||||
if not vim.wo.diff then
|
||||
return
|
||||
end
|
||||
|
||||
local bcache = cache[bufnr]
|
||||
|
||||
-- Note this will be the bufname for the currently set base
|
||||
-- which are the only ones we want to update
|
||||
local bufname = bcache:get_rev_bufname()
|
||||
local bufname = assert(cache[bufnr]):get_rev_bufname()
|
||||
|
||||
for _, w in ipairs(api.nvim_list_wins()) do
|
||||
if api.nvim_win_is_valid(w) then
|
||||
|
||||
@ -1,25 +1,12 @@
|
||||
local async = require('gitsigns.async')
|
||||
local scheduler = require('gitsigns.async').scheduler
|
||||
|
||||
local log = require('gitsigns.debug.log')
|
||||
local util = require('gitsigns.util')
|
||||
local system = require('gitsigns.system').system
|
||||
|
||||
local gs_config = require('gitsigns.config')
|
||||
local config = gs_config.config
|
||||
|
||||
local uv = vim.uv or vim.loop
|
||||
|
||||
local dprint = log.dprint
|
||||
local dprintf = log.dprintf
|
||||
local error_once = require('gitsigns.message').error_once
|
||||
local Repo = require('gitsigns.git.repo')
|
||||
|
||||
local check_version = require('gitsigns.git.version').check
|
||||
|
||||
local M = {}
|
||||
|
||||
--- @type fun(cmd: string[], opts?: vim.SystemOpts): vim.SystemCompleted
|
||||
local asystem = async.wrap(3, system)
|
||||
M.Repo = Repo
|
||||
|
||||
--- @param file string
|
||||
--- @return boolean
|
||||
@ -48,78 +35,7 @@ local Obj = {}
|
||||
|
||||
M.Obj = Obj
|
||||
|
||||
--- @class Gitsigns.RepoInfo
|
||||
--- @field gitdir string
|
||||
--- @field toplevel string
|
||||
--- @field detached boolean
|
||||
--- @field abbrev_head string
|
||||
|
||||
--- @class Gitsigns.Repo : Gitsigns.RepoInfo
|
||||
--- @field username string
|
||||
local Repo = {}
|
||||
M.Repo = Repo
|
||||
|
||||
--- @class Gitsigns.Git.JobSpec : vim.SystemOpts
|
||||
--- @field command? string
|
||||
--- @field ignore_error? boolean
|
||||
|
||||
--- @async
|
||||
--- @param args string[]
|
||||
--- @param spec? Gitsigns.Git.JobSpec
|
||||
--- @return string[] stdout, string? stderr
|
||||
local function git_command(args, spec)
|
||||
spec = spec or {}
|
||||
|
||||
local cmd = {
|
||||
spec.command or 'git',
|
||||
'--no-pager',
|
||||
'--no-optional-locks',
|
||||
'--literal-pathspecs',
|
||||
'-c',
|
||||
'gc.auto=0', -- Disable auto-packing which emits messages to stderr
|
||||
unpack(args),
|
||||
}
|
||||
|
||||
if spec.text == nil then
|
||||
spec.text = true
|
||||
end
|
||||
|
||||
-- Fix #895. Only needed for Nvim 0.9 and older
|
||||
spec.clear_env = true
|
||||
|
||||
--- @type vim.SystemCompleted
|
||||
local obj = asystem(cmd, spec)
|
||||
local stdout = obj.stdout
|
||||
local stderr = obj.stderr
|
||||
|
||||
if not spec.ignore_error and obj.code > 0 then
|
||||
local cmd_str = table.concat(cmd, ' ')
|
||||
log.eprintf("Received exit code %d when running command\n'%s':\n%s", obj.code, cmd_str, stderr)
|
||||
end
|
||||
|
||||
local stdout_lines = vim.split(stdout or '', '\n')
|
||||
|
||||
if spec.text then
|
||||
-- If stdout ends with a newline, then remove the final empty string after
|
||||
-- the split
|
||||
if stdout_lines[#stdout_lines] == '' then
|
||||
stdout_lines[#stdout_lines] = nil
|
||||
end
|
||||
end
|
||||
|
||||
if log.verbose then
|
||||
log.vprintf('%d lines:', #stdout_lines)
|
||||
for i = 1, math.min(10, #stdout_lines) do
|
||||
log.vprintf('\t%s', stdout_lines[i])
|
||||
end
|
||||
end
|
||||
|
||||
if stderr == '' then
|
||||
stderr = nil
|
||||
end
|
||||
|
||||
return stdout_lines, stderr
|
||||
end
|
||||
local git_command = require('gitsigns.git.cmd')
|
||||
|
||||
--- @async
|
||||
--- @param file_cmp string
|
||||
@ -145,224 +61,9 @@ function M.diff(file_cmp, file_buf, indent_heuristic, diff_algo)
|
||||
})
|
||||
end
|
||||
|
||||
--- @async
|
||||
--- @param gitdir string
|
||||
--- @param head_str string
|
||||
--- @param cwd string
|
||||
--- @param cmd? string
|
||||
--- @return string
|
||||
local function process_abbrev_head(gitdir, head_str, cwd, cmd)
|
||||
if not gitdir then
|
||||
return head_str
|
||||
end
|
||||
if head_str == 'HEAD' then
|
||||
local short_sha = git_command({ 'rev-parse', '--short', 'HEAD' }, {
|
||||
command = cmd,
|
||||
ignore_error = true,
|
||||
cwd = cwd,
|
||||
})[1] or ''
|
||||
if log.debug_mode and short_sha ~= '' then
|
||||
short_sha = 'HEAD'
|
||||
end
|
||||
if
|
||||
util.path_exists(gitdir .. '/rebase-merge')
|
||||
or util.path_exists(gitdir .. '/rebase-apply')
|
||||
then
|
||||
return short_sha .. '(rebasing)'
|
||||
end
|
||||
return short_sha
|
||||
end
|
||||
return head_str
|
||||
end
|
||||
|
||||
local has_cygpath = jit and jit.os == 'Windows' and vim.fn.executable('cygpath') == 1
|
||||
|
||||
local cygpath_convert ---@type fun(path: string): string
|
||||
|
||||
if has_cygpath then
|
||||
cygpath_convert = function(path)
|
||||
--- @type vim.SystemCompleted
|
||||
local obj = asystem({ 'cygpath', '-aw', path })
|
||||
return obj.stdout
|
||||
end
|
||||
end
|
||||
|
||||
--- @param path string
|
||||
--- @return string
|
||||
local function normalize_path(path)
|
||||
if path and has_cygpath and not uv.fs_stat(path) then
|
||||
-- If on windows and path isn't recognizable as a file, try passing it
|
||||
-- through cygpath
|
||||
path = cygpath_convert(path)
|
||||
end
|
||||
return path
|
||||
end
|
||||
|
||||
--- @async
|
||||
--- @param cwd string
|
||||
--- @param cmd? string
|
||||
--- @param gitdir? string
|
||||
--- @param toplevel? string
|
||||
--- @return Gitsigns.RepoInfo
|
||||
function M.get_repo_info(cwd, cmd, gitdir, toplevel)
|
||||
-- Does git rev-parse have --absolute-git-dir, added in 2.13:
|
||||
-- https://public-inbox.org/git/20170203024829.8071-16-szeder.dev@gmail.com/
|
||||
local has_abs_gd = check_version({ 2, 13 })
|
||||
local git_dir_opt = has_abs_gd and '--absolute-git-dir' or '--git-dir'
|
||||
|
||||
-- Wait for internal scheduler to settle before running command (#215)
|
||||
scheduler()
|
||||
|
||||
local args = {}
|
||||
|
||||
if gitdir then
|
||||
vim.list_extend(args, { '--git-dir', gitdir })
|
||||
end
|
||||
|
||||
if toplevel then
|
||||
vim.list_extend(args, { '--work-tree', toplevel })
|
||||
end
|
||||
|
||||
vim.list_extend(args, {
|
||||
'rev-parse',
|
||||
'--show-toplevel',
|
||||
git_dir_opt,
|
||||
'--abbrev-ref',
|
||||
'HEAD',
|
||||
})
|
||||
|
||||
local results = git_command(args, {
|
||||
command = cmd,
|
||||
ignore_error = true,
|
||||
cwd = toplevel or cwd,
|
||||
})
|
||||
|
||||
local toplevel_r = normalize_path(results[1])
|
||||
local gitdir_r = normalize_path(results[2])
|
||||
|
||||
if gitdir_r and not has_abs_gd then
|
||||
gitdir_r = assert(uv.fs_realpath(gitdir_r))
|
||||
end
|
||||
|
||||
return {
|
||||
toplevel = toplevel_r,
|
||||
gitdir = gitdir_r,
|
||||
abbrev_head = process_abbrev_head(gitdir_r, results[3], cwd, cmd),
|
||||
detached = toplevel_r and gitdir_r ~= toplevel_r .. '/.git',
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Git repo object methods
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
--- Run git command the with the objects gitdir and toplevel
|
||||
--- @async
|
||||
--- @param args string[]
|
||||
--- @param spec? Gitsigns.Git.JobSpec
|
||||
--- @return string[] stdout, string? stderr
|
||||
function Repo:command(args, spec)
|
||||
spec = spec or {}
|
||||
spec.cwd = self.toplevel
|
||||
|
||||
local args1 = {
|
||||
'--git-dir',
|
||||
self.gitdir,
|
||||
}
|
||||
|
||||
if self.detached then
|
||||
vim.list_extend(args1, { '--work-tree', self.toplevel })
|
||||
end
|
||||
|
||||
vim.list_extend(args1, args)
|
||||
|
||||
return git_command(args1, spec)
|
||||
end
|
||||
|
||||
--- @return string[]
|
||||
function Repo:files_changed()
|
||||
--- @type string[]
|
||||
local results = self:command({ 'status', '--porcelain', '--ignore-submodules' })
|
||||
|
||||
local ret = {} --- @type string[]
|
||||
for _, line in ipairs(results) do
|
||||
if line:sub(1, 2):match('^.M') then
|
||||
ret[#ret + 1] = line:sub(4, -1)
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
--- @param encoding string
|
||||
--- @return boolean
|
||||
local function iconv_supported(encoding)
|
||||
-- TODO(lewis6991): needs https://github.com/neovim/neovim/pull/21924
|
||||
if vim.startswith(encoding, 'utf-16') then
|
||||
return false
|
||||
elseif vim.startswith(encoding, 'utf-32') then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--- Get version of file in the index, return array lines
|
||||
--- @param object string
|
||||
--- @param encoding? string
|
||||
--- @return string[] stdout, string? stderr
|
||||
function Repo:get_show_text(object, encoding)
|
||||
local stdout, stderr = self:command({ 'show', object }, { text = false, ignore_error = true })
|
||||
|
||||
if encoding and encoding ~= 'utf-8' and iconv_supported(encoding) then
|
||||
for i, l in ipairs(stdout) do
|
||||
--- @diagnostic disable-next-line:param-type-mismatch
|
||||
stdout[i] = vim.iconv(l, encoding, 'utf-8')
|
||||
end
|
||||
end
|
||||
|
||||
return stdout, stderr
|
||||
end
|
||||
|
||||
--- @async
|
||||
function Repo:update_abbrev_head()
|
||||
self.abbrev_head = M.get_repo_info(self.toplevel).abbrev_head
|
||||
end
|
||||
|
||||
--- @async
|
||||
--- @param dir string
|
||||
--- @param gitdir? string
|
||||
--- @param toplevel? string
|
||||
--- @return Gitsigns.Repo
|
||||
function Repo.new(dir, gitdir, toplevel)
|
||||
local self = setmetatable({}, { __index = Repo })
|
||||
|
||||
self.username = git_command({ 'config', 'user.name' }, { ignore_error = true })[1]
|
||||
local info = M.get_repo_info(dir, nil, gitdir, toplevel)
|
||||
for k, v in
|
||||
pairs(info --[[@as table<string,any>]])
|
||||
do
|
||||
---@diagnostic disable-next-line:no-unknown
|
||||
self[k] = v
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Git object methods
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
--- Run git command the with the objects gitdir and toplevel
|
||||
--- @param args string[]
|
||||
--- @param spec? Gitsigns.Git.JobSpec
|
||||
--- @return string[] stdout, string? stderr
|
||||
function Obj:command(args, spec)
|
||||
return self.repo:command(args, spec)
|
||||
end
|
||||
|
||||
--- @param revision? string
|
||||
function Obj:update_revision(revision)
|
||||
revision = util.norm_base(revision)
|
||||
self.revision = revision
|
||||
self.revision = util.norm_base(revision)
|
||||
self:update()
|
||||
end
|
||||
|
||||
@ -434,7 +135,7 @@ function Obj:file_info_index(file, silent)
|
||||
|
||||
cmd[#cmd + 1] = file or self.file
|
||||
|
||||
local results, stderr = self:command(cmd, { ignore_error = true })
|
||||
local results, stderr = self.repo:command(cmd, { ignore_error = true })
|
||||
|
||||
if stderr and not silent then
|
||||
-- ignore_error for the cases when we run:
|
||||
@ -481,7 +182,7 @@ end
|
||||
--- @param silent? boolean
|
||||
--- @return Gitsigns.FileInfo
|
||||
function Obj:file_info_tree(file, silent)
|
||||
local results, stderr = self:command({
|
||||
local results, stderr = self.repo:command({
|
||||
'-c',
|
||||
'core.quotepath=off',
|
||||
'ls-tree',
|
||||
@ -516,14 +217,14 @@ end
|
||||
--- @return string[] stdout, string? stderr
|
||||
function Obj:get_show_text(revision)
|
||||
if revision and not self.relpath then
|
||||
dprint('no relpath')
|
||||
log.dprint('no relpath')
|
||||
return {}
|
||||
end
|
||||
|
||||
local object = revision and (revision .. ':' .. self.relpath) or self.object_name
|
||||
|
||||
if not object then
|
||||
dprint('no revision or object_name')
|
||||
log.dprint('no revision or object_name')
|
||||
return { '' }
|
||||
end
|
||||
|
||||
@ -551,215 +252,17 @@ local function autocmd_changed(file)
|
||||
end
|
||||
|
||||
function Obj:unstage_file()
|
||||
self:command({ 'reset', self.file })
|
||||
self.repo:command({ 'reset', self.file })
|
||||
autocmd_changed(self.file)
|
||||
end
|
||||
|
||||
--- @class Gitsigns.CommitInfo
|
||||
--- @field author string
|
||||
--- @field author_mail string
|
||||
--- @field author_time integer
|
||||
--- @field author_tz string
|
||||
--- @field committer string
|
||||
--- @field committer_mail string
|
||||
--- @field committer_time integer
|
||||
--- @field committer_tz string
|
||||
--- @field summary string
|
||||
--- @field sha string
|
||||
--- @field abbrev_sha string
|
||||
--- @field boundary? true
|
||||
|
||||
--- @class Gitsigns.BlameInfoPublic: Gitsigns.BlameInfo, Gitsigns.CommitInfo
|
||||
--- @field body? string[]
|
||||
--- @field hunk_no? integer
|
||||
--- @field num_hunks? integer
|
||||
--- @field hunk? string[]
|
||||
--- @field hunk_head? string
|
||||
|
||||
--- @class Gitsigns.BlameInfo
|
||||
--- @field orig_lnum integer
|
||||
--- @field final_lnum integer
|
||||
--- @field commit Gitsigns.CommitInfo
|
||||
--- @field filename string
|
||||
--- @field previous_filename? string
|
||||
--- @field previous_sha? string
|
||||
|
||||
local NOT_COMMITTED = {
|
||||
author = 'Not Committed Yet',
|
||||
author_mail = '<not.committed.yet>',
|
||||
committer = 'Not Committed Yet',
|
||||
committer_mail = '<not.committed.yet>',
|
||||
}
|
||||
|
||||
--- @param file string
|
||||
--- @return Gitsigns.CommitInfo
|
||||
function M.not_committed(file)
|
||||
local time = os.time()
|
||||
return {
|
||||
sha = string.rep('0', 40),
|
||||
abbrev_sha = string.rep('0', 8),
|
||||
author = 'Not Committed Yet',
|
||||
author_mail = '<not.committed.yet>',
|
||||
author_tz = '+0000',
|
||||
author_time = time,
|
||||
committer = 'Not Committed Yet',
|
||||
committer_time = time,
|
||||
committer_mail = '<not.committed.yet>',
|
||||
committer_tz = '+0000',
|
||||
summary = 'Version of ' .. file,
|
||||
}
|
||||
end
|
||||
|
||||
---@param x any
|
||||
---@return integer
|
||||
local function asinteger(x)
|
||||
return assert(tonumber(x))
|
||||
end
|
||||
|
||||
--- @param lines string[]
|
||||
--- @param lnum? integer
|
||||
--- @param revision? string
|
||||
--- @param opts? Gitsigns.BlameOpts
|
||||
--- @return table<integer,Gitsigns.BlameInfo?>?
|
||||
function Obj:run_blame(lines, lnum, opts)
|
||||
local ret = {} --- @type table<integer,Gitsigns.BlameInfo>
|
||||
|
||||
if not self.object_name or self.repo.abbrev_head == '' then
|
||||
-- As we support attaching to untracked files we need to return something if
|
||||
-- the file isn't isn't tracked in git.
|
||||
-- If abbrev_head is empty, then assume the repo has no commits
|
||||
local commit = M.not_committed(self.file)
|
||||
for i in ipairs(lines) do
|
||||
ret[i] = {
|
||||
orig_lnum = 0,
|
||||
final_lnum = i,
|
||||
commit = commit,
|
||||
filename = self.file,
|
||||
}
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
local args = { 'blame', '--contents', '-', '--incremental' }
|
||||
|
||||
opts = opts or {}
|
||||
|
||||
if opts.ignore_whitespace then
|
||||
args[#args + 1] = '-w'
|
||||
end
|
||||
|
||||
if lnum then
|
||||
vim.list_extend(args, { '-L', lnum .. ',+1' })
|
||||
end
|
||||
|
||||
if opts.extra_opts then
|
||||
vim.list_extend(args, opts.extra_opts)
|
||||
end
|
||||
|
||||
local ignore_file = self.repo.toplevel .. '/.git-blame-ignore-revs'
|
||||
if uv.fs_stat(ignore_file) then
|
||||
vim.list_extend(args, { '--ignore-revs-file', ignore_file })
|
||||
end
|
||||
|
||||
args[#args + 1] = opts.rev
|
||||
args[#args + 1] = '--'
|
||||
args[#args + 1] = self.file
|
||||
|
||||
local results, stderr = self:command(args, { stdin = lines, ignore_error = true })
|
||||
if stderr then
|
||||
error_once('Error running git-blame: ' .. stderr)
|
||||
return
|
||||
end
|
||||
|
||||
if #results == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local commits = {} --- @type table<string,Gitsigns.CommitInfo>
|
||||
local i = 1
|
||||
|
||||
while i <= #results do
|
||||
--- @param pat? string
|
||||
--- @return string
|
||||
local function get(pat)
|
||||
local l = assert(results[i])
|
||||
i = i + 1
|
||||
if pat then
|
||||
return l:match(pat)
|
||||
end
|
||||
return l
|
||||
end
|
||||
|
||||
local function peek(pat)
|
||||
local l = results[i]
|
||||
if l and pat then
|
||||
return l:match(pat)
|
||||
end
|
||||
return l
|
||||
end
|
||||
|
||||
local sha, orig_lnum_str, final_lnum_str, size_str = get('(%x+) (%d+) (%d+) (%d+)')
|
||||
local orig_lnum = asinteger(orig_lnum_str)
|
||||
local final_lnum = asinteger(final_lnum_str)
|
||||
local size = asinteger(size_str)
|
||||
|
||||
if peek():match('^author ') then
|
||||
--- @type table<string,string|true>
|
||||
local commit = {
|
||||
sha = sha,
|
||||
abbrev_sha = sha:sub(1, 8),
|
||||
}
|
||||
|
||||
-- filename terminates the entry
|
||||
while peek() and not (peek():match('^filename ') or peek():match('^previous ')) do
|
||||
local l = get()
|
||||
local key, value = l:match('^([^%s]+) (.*)')
|
||||
if key then
|
||||
if vim.endswith(key, '_time') then
|
||||
value = tonumber(value)
|
||||
end
|
||||
key = key:gsub('%-', '_') --- @type string
|
||||
commit[key] = value
|
||||
else
|
||||
commit[l] = true
|
||||
if l ~= 'boundary' then
|
||||
dprintf("Unknown tag: '%s'", l)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- New in git 2.41:
|
||||
-- The output given by "git blame" that attributes a line to contents
|
||||
-- taken from the file specified by the "--contents" option shows it
|
||||
-- differently from a line attributed to the working tree file.
|
||||
if
|
||||
commit.author_mail == '<external.file>'
|
||||
or commit.author_mail == 'External file (--contents)'
|
||||
then
|
||||
commit = vim.tbl_extend('force', commit, NOT_COMMITTED)
|
||||
end
|
||||
commits[sha] = commit
|
||||
end
|
||||
|
||||
local previous_sha, previous_filename = peek():match('^previous (%x+) (.*)')
|
||||
if previous_sha then
|
||||
get()
|
||||
end
|
||||
|
||||
local filename = assert(get():match('^filename (.*)'))
|
||||
|
||||
for j = 0, size - 1 do
|
||||
ret[final_lnum + j] = {
|
||||
final_lnum = final_lnum + j,
|
||||
orig_lnum = orig_lnum + j,
|
||||
commit = commits[sha],
|
||||
filename = filename,
|
||||
previous_filename = previous_filename,
|
||||
previous_sha = previous_sha,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
return ret
|
||||
--- @return table<integer,Gitsigns.BlameInfo?>
|
||||
function Obj:run_blame(lines, lnum, revision, opts)
|
||||
return require('gitsigns.git.blame').run_blame(self, lines, lnum, revision, opts)
|
||||
end
|
||||
|
||||
--- @param obj Gitsigns.GitObj
|
||||
@ -770,12 +273,12 @@ local function ensure_file_in_index(obj)
|
||||
|
||||
if not obj.object_name then
|
||||
-- If there is no object_name then it is not yet in the index so add it
|
||||
obj:command({ 'add', '--intent-to-add', obj.file })
|
||||
obj.repo:command({ 'add', '--intent-to-add', obj.file })
|
||||
else
|
||||
-- Update the index with the common ancestor (stage 1) which is what bcache
|
||||
-- stores
|
||||
local info = string.format('%s,%s,%s', obj.mode_bits, obj.object_name, obj.relpath)
|
||||
obj:command({ 'update-index', '--add', '--cacheinfo', info })
|
||||
obj.repo:command({ 'update-index', '--add', '--cacheinfo', info })
|
||||
end
|
||||
|
||||
obj:update()
|
||||
@ -784,17 +287,15 @@ end
|
||||
--- Stage 'lines' as the entire contents of the file
|
||||
--- @param lines string[]
|
||||
function Obj:stage_lines(lines)
|
||||
local stdout = self:command({
|
||||
local new_object = self.repo:command({
|
||||
'hash-object',
|
||||
'-w',
|
||||
'--path',
|
||||
self.relpath,
|
||||
'--stdin',
|
||||
}, { stdin = lines })
|
||||
}, { stdin = lines })[1]
|
||||
|
||||
local new_object = stdout[1]
|
||||
|
||||
self:command({
|
||||
self.repo:command({
|
||||
'update-index',
|
||||
'--cacheinfo',
|
||||
string.format('%s,%s,%s', self.mode_bits, new_object, self.relpath),
|
||||
@ -808,9 +309,7 @@ end
|
||||
function Obj:stage_hunks(hunks, invert)
|
||||
ensure_file_in_index(self)
|
||||
|
||||
local gs_hunks = require('gitsigns.hunks')
|
||||
|
||||
local patch = gs_hunks.create_patch(self.relpath, hunks, self.mode_bits, invert)
|
||||
local patch = require('gitsigns.hunks').create_patch(self.relpath, hunks, self.mode_bits, invert)
|
||||
|
||||
if not self.i_crlf and self.w_crlf then
|
||||
-- Remove cr
|
||||
@ -819,7 +318,7 @@ function Obj:stage_hunks(hunks, invert)
|
||||
end
|
||||
end
|
||||
|
||||
self:command({
|
||||
self.repo:command({
|
||||
'apply',
|
||||
'--whitespace=nowarn',
|
||||
'--cached',
|
||||
@ -834,7 +333,7 @@ end
|
||||
|
||||
--- @return string?
|
||||
function Obj:has_moved()
|
||||
local out = self:command({ 'diff', '--name-status', '-C', '--cached' })
|
||||
local out = self.repo:command({ 'diff', '--name-status', '-C', '--cached' })
|
||||
local orig_relpath = self.orig_relpath or self.relpath
|
||||
for _, l in ipairs(out) do
|
||||
local parts = vim.split(l, '%s+')
|
||||
@ -858,24 +357,25 @@ end
|
||||
--- @return Gitsigns.GitObj?
|
||||
function Obj.new(file, revision, encoding, gitdir, toplevel)
|
||||
if in_git_dir(file) then
|
||||
dprint('In git dir')
|
||||
log.dprint('In git dir')
|
||||
return nil
|
||||
end
|
||||
local self = setmetatable({}, { __index = Obj })
|
||||
|
||||
if not vim.startswith(file, '/') and toplevel then
|
||||
file = toplevel .. util.path_sep .. file
|
||||
end
|
||||
|
||||
local repo = Repo.get(util.dirname(file), gitdir, toplevel)
|
||||
if not repo then
|
||||
log.dprint('Not in git repo')
|
||||
return
|
||||
end
|
||||
|
||||
local self = setmetatable({}, { __index = Obj })
|
||||
self.repo = repo
|
||||
self.file = file
|
||||
self.revision = util.norm_base(revision)
|
||||
self.encoding = encoding
|
||||
self.repo = Repo.new(util.dirname(file), gitdir, toplevel)
|
||||
|
||||
if not self.repo.gitdir then
|
||||
dprint('Not in git repo')
|
||||
return nil
|
||||
end
|
||||
|
||||
-- When passing gitdir and toplevel, suppress stderr when resolving the file
|
||||
local silent = gitdir ~= nil and toplevel ~= nil
|
||||
|
||||
@ -135,6 +135,48 @@ M.hls = {
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
GitSignsAddCul = {
|
||||
'GitSignsAdd',
|
||||
desc = "Used for the text of 'add' signs when the cursor is on the same line as the sign.",
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
GitSignsChangeCul = {
|
||||
'GitSignsChange',
|
||||
desc = "Used for the text of 'change' signs when the cursor is on the same line as the sign.",
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
GitSignsDeleteCul = {
|
||||
'GitSignsDelete',
|
||||
desc = "Used for the text of 'delete' signs when the cursor is on the same line as the sign.",
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
GitSignsChangedeleteCul = {
|
||||
'GitSignsChangeCul',
|
||||
desc = "Used for the text of 'changedelete' signs when the cursor is on the same line as the sign.",
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
GitSignsTopdeleteCul = {
|
||||
'GitSignsDeleteCul',
|
||||
desc = "Used for the text of 'topdelete' signs when the cursor is on the same line as the sign.",
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
GitSignsUntrackedCul = {
|
||||
'GitSignsAddCul',
|
||||
desc = "Used for the text of 'untracked' signs when the cursor is on the same line as the sign.",
|
||||
},
|
||||
},
|
||||
|
||||
-- Don't set GitSignsDeleteLn by default
|
||||
-- {GitSignsDeleteLn = {}},
|
||||
|
||||
@ -153,6 +195,11 @@ M.hls = {
|
||||
{ GitSignsStagedDeleteLn = { 'GitSignsDeleteLn', fg_factor = 0.5, hidden = true } },
|
||||
{ GitSignsStagedChangedeleteLn = { 'GitSignsChangedeleteLn', fg_factor = 0.5, hidden = true } },
|
||||
{ GitSignsStagedTopdeleteLn = { 'GitSignsTopdeleteLn', fg_factor = 0.5, hidden = true } },
|
||||
{ GitSignsStagedAddCul = { 'GitSignsAddCul', fg_factor = 0.5, hidden = true } },
|
||||
{ GitSignsStagedChangeCul = { 'GitSignsChangeCul', fg_factor = 0.5, hidden = true } },
|
||||
{ GitSignsStagedDeleteCul = { 'GitSignsDeleteCul', fg_factor = 0.5, hidden = true } },
|
||||
{ GitSignsStagedChangedeleteCul = { 'GitSignsChangedeleteCul', fg_factor = 0.5, hidden = true } },
|
||||
{ GitSignsStagedTopdeleteCul = { 'GitSignsTopdeleteCul', fg_factor = 0.5, hidden = true } },
|
||||
|
||||
{
|
||||
GitSignsAddPreview = {
|
||||
|
||||
@ -1,22 +1,15 @@
|
||||
local async = require('gitsigns.async')
|
||||
|
||||
local gs_cache = require('gitsigns.cache')
|
||||
local cache = gs_cache.cache
|
||||
|
||||
local log = require('gitsigns.debug.log')
|
||||
local util = require('gitsigns.util')
|
||||
local run_diff = require('gitsigns.diff')
|
||||
local Hunks = require('gitsigns.hunks')
|
||||
local Signs = require('gitsigns.signs')
|
||||
local Status = require('gitsigns.status')
|
||||
|
||||
local debounce_trailing = require('gitsigns.debounce').debounce_trailing
|
||||
local throttle_by_id = require('gitsigns.debounce').throttle_by_id
|
||||
|
||||
local log = require('gitsigns.debug.log')
|
||||
local dprint = log.dprint
|
||||
|
||||
local util = require('gitsigns.util')
|
||||
local run_diff = require('gitsigns.diff')
|
||||
|
||||
local gs_hunks = require('gitsigns.hunks')
|
||||
|
||||
local cache = require('gitsigns.cache').cache
|
||||
local config = require('gitsigns.config').config
|
||||
|
||||
local api = vim.api
|
||||
@ -31,7 +24,7 @@ local M = {}
|
||||
--- @param hunks Gitsigns.Hunk.Hunk[]
|
||||
--- @param top integer
|
||||
--- @param bot integer
|
||||
--- @param clear boolean
|
||||
--- @param clear? boolean
|
||||
--- @param untracked boolean
|
||||
local function apply_win_signs0(bufnr, signs, hunks, top, bot, clear, untracked)
|
||||
if clear then
|
||||
@ -47,14 +40,11 @@ local function apply_win_signs0(bufnr, signs, hunks, top, bot, clear, untracked)
|
||||
-- least one sign. Only do this on the first call after an update when we all
|
||||
-- the signs have been cleared.
|
||||
if clear and i == 1 then
|
||||
signs:add(
|
||||
bufnr,
|
||||
gs_hunks.calc_signs(hunk, next, hunk.added.start, hunk.added.start, untracked)
|
||||
)
|
||||
signs:add(bufnr, Hunks.calc_signs(hunk, next, hunk.added.start, hunk.added.start, untracked))
|
||||
end
|
||||
|
||||
if top <= hunk.vend and bot >= hunk.added.start then
|
||||
signs:add(bufnr, gs_hunks.calc_signs(hunk, next, top, bot, untracked))
|
||||
signs:add(bufnr, Hunks.calc_signs(hunk, next, top, bot, untracked))
|
||||
end
|
||||
if hunk.added.start > bot then
|
||||
break
|
||||
@ -65,13 +55,9 @@ end
|
||||
--- @param bufnr integer
|
||||
--- @param top integer
|
||||
--- @param bot integer
|
||||
--- @param clear boolean
|
||||
--- @param clear? boolean
|
||||
local function apply_win_signs(bufnr, top, bot, clear)
|
||||
local bcache = cache[bufnr]
|
||||
if not bcache then
|
||||
return
|
||||
end
|
||||
|
||||
local bcache = assert(cache[bufnr])
|
||||
local untracked = bcache.git_obj.object_name == nil
|
||||
apply_win_signs0(bufnr, signs_normal, bcache.hunks, top, bot, clear, untracked)
|
||||
if signs_staged then
|
||||
@ -88,15 +74,13 @@ local function on_lines_blame(blame, first, last_orig, last_new)
|
||||
return
|
||||
end
|
||||
|
||||
if last_new ~= last_orig then
|
||||
if last_new < last_orig then
|
||||
util.list_remove(blame, last_new, last_orig)
|
||||
else
|
||||
util.list_insert(blame, last_orig, last_new)
|
||||
end
|
||||
if last_new < last_orig then
|
||||
util.list_remove(blame, last_new + 1, last_orig)
|
||||
elseif last_new > last_orig then
|
||||
util.list_insert(blame, last_orig + 1, last_new)
|
||||
end
|
||||
|
||||
for i = math.min(first + 1, last_new), math.max(first + 1, last_new) do
|
||||
for i = first + 1, last_new do
|
||||
blame[i] = nil
|
||||
end
|
||||
end
|
||||
@ -109,7 +93,7 @@ end
|
||||
function M.on_lines(buf, first, last_orig, last_new)
|
||||
local bcache = cache[buf]
|
||||
if not bcache then
|
||||
dprint('Cache for buffer was nil. Detaching')
|
||||
log.dprint('Cache for buffer was nil. Detaching')
|
||||
return true
|
||||
end
|
||||
|
||||
@ -161,7 +145,7 @@ local function apply_word_diff(bufnr, row)
|
||||
|
||||
local lnum = row + 1
|
||||
|
||||
local hunk = gs_hunks.find_hunk(lnum, bcache.hunks)
|
||||
local hunk = Hunks.find_hunk(lnum, bcache.hunks)
|
||||
if not hunk then
|
||||
-- No hunk at line
|
||||
return
|
||||
@ -320,7 +304,7 @@ function M.show_deleted_in_float(bufnr, nsd, hunk, staged)
|
||||
virt_lines_leftcol = true,
|
||||
})
|
||||
|
||||
local bcache = cache[bufnr]
|
||||
local bcache = assert(cache[bufnr])
|
||||
local pbufnr = api.nvim_create_buf(false, true)
|
||||
local text = staged and bcache.compare_text_head or bcache.compare_text
|
||||
api.nvim_buf_set_lines(pbufnr, 0, -1, false, assert(text))
|
||||
@ -422,7 +406,7 @@ end
|
||||
|
||||
--- @param bufnr integer
|
||||
local function update_show_deleted(bufnr)
|
||||
local bcache = cache[bufnr]
|
||||
local bcache = assert(cache[bufnr])
|
||||
|
||||
clear_deleted(bufnr)
|
||||
if config.show_deleted then
|
||||
@ -440,15 +424,15 @@ end
|
||||
function M.schedule(bufnr, check_compare_text)
|
||||
async.scheduler()
|
||||
if not api.nvim_buf_is_valid(bufnr) then
|
||||
dprint('Buffer not valid, aborting')
|
||||
log.dprint('Buffer not valid, aborting')
|
||||
return false
|
||||
end
|
||||
if not cache[bufnr] then
|
||||
dprint('Has detached, aborting')
|
||||
log.dprint('Has detached, aborting')
|
||||
return false
|
||||
end
|
||||
if check_compare_text and not cache[bufnr].compare_text then
|
||||
dprint('compare_text was invalid, aborting')
|
||||
log.dprint('compare_text was invalid, aborting')
|
||||
return false
|
||||
end
|
||||
return true
|
||||
@ -463,7 +447,7 @@ M.update = throttle_by_id(function(bufnr)
|
||||
if not M.schedule(bufnr) then
|
||||
return
|
||||
end
|
||||
local bcache = cache[bufnr]
|
||||
local bcache = assert(cache[bufnr])
|
||||
local old_hunks, old_hunks_staged = bcache.hunks, bcache.hunks_staged
|
||||
bcache.hunks, bcache.hunks_staged = nil, nil
|
||||
|
||||
@ -500,15 +484,15 @@ M.update = throttle_by_id(function(bufnr)
|
||||
if not M.schedule(bufnr) then
|
||||
return
|
||||
end
|
||||
bcache.hunks_staged = gs_hunks.filter_common(hunks_head, bcache.hunks)
|
||||
bcache.hunks_staged = Hunks.filter_common(hunks_head, bcache.hunks)
|
||||
end
|
||||
|
||||
-- Note the decoration provider may have invalidated bcache.hunks at this
|
||||
-- point
|
||||
if
|
||||
bcache.force_next_update
|
||||
or gs_hunks.compare_heads(bcache.hunks, old_hunks)
|
||||
or gs_hunks.compare_heads(bcache.hunks_staged, old_hunks_staged)
|
||||
or Hunks.compare_heads(bcache.hunks, old_hunks)
|
||||
or Hunks.compare_heads(bcache.hunks_staged, old_hunks_staged)
|
||||
then
|
||||
-- Apply signs to the window. Other signs will be added by the decoration
|
||||
-- provider as they are drawn.
|
||||
@ -517,7 +501,7 @@ M.update = throttle_by_id(function(bufnr)
|
||||
update_show_deleted(bufnr)
|
||||
bcache.force_next_update = false
|
||||
|
||||
local summary = gs_hunks.get_summary(bcache.hunks)
|
||||
local summary = Hunks.get_summary(bcache.hunks)
|
||||
summary.head = git_obj.repo.abbrev_head
|
||||
Status:update(bufnr, summary)
|
||||
end
|
||||
@ -558,7 +542,7 @@ local function on_win(_cb, _winid, bufnr, topline, botline_guess)
|
||||
end
|
||||
local botline = math.min(botline_guess, api.nvim_buf_line_count(bufnr))
|
||||
|
||||
apply_win_signs(bufnr, topline + 1, botline + 1, false)
|
||||
apply_win_signs(bufnr, topline + 1, botline + 1)
|
||||
|
||||
if not (config.word_diff and config.diff_opts.internal) then
|
||||
return false
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
local M = {}
|
||||
|
||||
local api = vim.api
|
||||
|
||||
local M = {}
|
||||
|
||||
--- @param bufnr integer
|
||||
--- @param lines string[]
|
||||
--- @return integer
|
||||
|
||||
@ -65,6 +65,7 @@ function M:add(bufnr, signs)
|
||||
sign_hl_group = hls.hl,
|
||||
number_hl_group = config.numhl and hls.numhl or nil,
|
||||
line_hl_group = config.linehl and hls.linehl or nil,
|
||||
cursorline_hl_group = config.culhl and hls.culhl or nil,
|
||||
})
|
||||
|
||||
if not ok and config.debug_mode then
|
||||
|
||||
@ -327,7 +327,7 @@ end
|
||||
---@param first integer
|
||||
---@param last integer
|
||||
function M.list_remove(t, first, last)
|
||||
local n = #t
|
||||
local n = table.maxn(t)
|
||||
for i = 0, n - first do
|
||||
t[first + i] = t[last + 1 + i]
|
||||
t[last + 1 + i] = nil
|
||||
@ -347,7 +347,7 @@ end
|
||||
---@param last integer
|
||||
---@param v any
|
||||
function M.list_insert(t, first, last, v)
|
||||
local n = #t
|
||||
local n = table.maxn(t)
|
||||
|
||||
-- Shift table forward
|
||||
for i = n - first, 0, -1 do
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
local api = vim.api
|
||||
local uv = vim.loop
|
||||
|
||||
local Status = require('gitsigns.status')
|
||||
local async = require('gitsigns.async')
|
||||
local log = require('gitsigns.debug.log')
|
||||
local util = require('gitsigns.util')
|
||||
local Status = require('gitsigns.status')
|
||||
|
||||
local cache = require('gitsigns.cache').cache
|
||||
local config = require('gitsigns.config').config
|
||||
@ -18,7 +18,7 @@ local dprintf = log.dprintf
|
||||
--- @param bufnr integer
|
||||
--- @param old_relpath string
|
||||
local function handle_moved(bufnr, old_relpath)
|
||||
local bcache = cache[bufnr]
|
||||
local bcache = assert(cache[bufnr])
|
||||
local git_obj = bcache.git_obj
|
||||
|
||||
local new_name = git_obj:has_moved()
|
||||
@ -73,6 +73,7 @@ local function watcher_handler0(bufnr)
|
||||
-- Avoid cache hit for detached buffer
|
||||
-- ref: https://github.com/lewis6991/gitsigns.nvim/issues/956
|
||||
if not manager.schedule(bufnr) then
|
||||
dprint('buffer invalid (1)')
|
||||
return
|
||||
end
|
||||
|
||||
@ -81,6 +82,7 @@ local function watcher_handler0(bufnr)
|
||||
git_obj.repo:update_abbrev_head()
|
||||
|
||||
if not manager.schedule(bufnr) then
|
||||
dprint('buffer invalid (2)')
|
||||
return
|
||||
end
|
||||
|
||||
@ -91,6 +93,7 @@ local function watcher_handler0(bufnr)
|
||||
|
||||
git_obj:update()
|
||||
if not manager.schedule(bufnr) then
|
||||
dprint('buffer invalid (3)')
|
||||
return
|
||||
end
|
||||
|
||||
@ -99,6 +102,7 @@ local function watcher_handler0(bufnr)
|
||||
-- moved. Check if it was moved and switch to it.
|
||||
handle_moved(bufnr, old_relpath)
|
||||
if not manager.schedule(bufnr) then
|
||||
dprint('buffer invalid (4)')
|
||||
return
|
||||
end
|
||||
end
|
||||
@ -108,9 +112,12 @@ local function watcher_handler0(bufnr)
|
||||
require('gitsigns.manager').update(bufnr)
|
||||
end
|
||||
|
||||
--- Debounce and throttle the handler.
|
||||
--- We also throttle in case the debounce delay is not enough and to prevent
|
||||
--- too many handlers from being launched (and interleaved).
|
||||
--- Debounce to:
|
||||
--- - wait for all changes to the gitdir to complete.
|
||||
--- Throttle to:
|
||||
--- - ensure handler is only triggered once per git operation.
|
||||
--- - prevent updates to the same buffer from interleaving as the handler is
|
||||
--- async.
|
||||
local watcher_handler =
|
||||
debounce_trailing(200, async.create(1, throttle_by_id(watcher_handler0, true)), 1)
|
||||
|
||||
@ -123,11 +130,6 @@ end
|
||||
|
||||
local M = {}
|
||||
|
||||
local WATCH_IGNORE = {
|
||||
ORIG_HEAD = true,
|
||||
FETCH_HEAD = true,
|
||||
}
|
||||
|
||||
--- @param bufnr integer
|
||||
--- @param gitdir string
|
||||
--- @return uv.uv_fs_event_t
|
||||
@ -141,17 +143,15 @@ function M.watch_gitdir(bufnr, gitdir)
|
||||
return
|
||||
end
|
||||
|
||||
local info = string.format("Git dir update: '%s' %s", filename, inspect(events))
|
||||
|
||||
-- The luv docs say filename is passed as a string but it has been observed
|
||||
-- to sometimes be nil.
|
||||
-- https://github.com/lewis6991/gitsigns.nvim/issues/848
|
||||
if filename == nil or WATCH_IGNORE[filename] or vim.endswith(filename, '.lock') then
|
||||
dprintf('%s (ignoring)', info)
|
||||
if not filename then
|
||||
log.eprint('No filename')
|
||||
return
|
||||
end
|
||||
|
||||
dprint(info)
|
||||
dprintf("Git dir update: '%s' %s", filename, inspect(events))
|
||||
|
||||
watcher_handler(bufnr)
|
||||
end)
|
||||
|
||||
@ -1 +1 @@
|
||||
/nix/store/3czmrawji85vf8979kll2yx2f1kjkric-lua-5.1.5
|
||||
/nix/store/rn8bzg423wwkayzbsbmhmvcgjmbzrq5z-lua-5.1.5
|
||||
@ -1,50 +1,53 @@
|
||||
rock_manifest = {
|
||||
doc = {
|
||||
["gitsigns.txt"] = "e537e0db7825ce01a1c568a124432989"
|
||||
["gitsigns.txt"] = "ed2c2a9eac117833753afc9dd55adcf4"
|
||||
},
|
||||
["gitsigns.nvim-scm-1.rockspec"] = "a9b165d604ce401cfeea760a9366418d",
|
||||
lua = {
|
||||
gitsigns = {
|
||||
["actions.lua"] = "accecf1db114ace88739c40835cb5a77",
|
||||
["async.lua"] = "15f310cd469f5bfa46bb1e49e5a1d61c",
|
||||
["attach.lua"] = "6f81186d03fbde2ddc631c46fea09315",
|
||||
["blame.lua"] = "e8388c8b29982475bfccec28ea4f72be",
|
||||
["cache.lua"] = "a084b897b3af2f3603a018f4c00c20fa",
|
||||
["actions.lua"] = "ac0661d45e50424f5f59924528b1c031",
|
||||
["async.lua"] = "ab34c767e5b6c917335d19f2acc6fd36",
|
||||
["attach.lua"] = "44664690d66389b4487d934ebcad98e6",
|
||||
["blame.lua"] = "05feea95e221a2409a8d44334c47529f",
|
||||
["cache.lua"] = "523c72aa06168f06b3ecd34fd04cbe9d",
|
||||
cli = {
|
||||
["argparse.lua"] = "fb6c9ffda01b2090f3c252ecaf00f68a"
|
||||
},
|
||||
["cli.lua"] = "f00c3494d6be1b07c352c51132150586",
|
||||
["config.lua"] = "ef58f99d7782297a32e3867634906738",
|
||||
["current_line_blame.lua"] = "b1e920875977e12bb4f9f6be08a92db8",
|
||||
["debounce.lua"] = "e0c1145a3dc341f46b36b43d814c1202",
|
||||
["cli.lua"] = "00273191aa1ca467c5edbd9531f8fd9d",
|
||||
["config.lua"] = "8743742b5a5b0a0713f0352ff4e88db0",
|
||||
["current_line_blame.lua"] = "48e477d836e39ab98e58c2b027dd9db8",
|
||||
["debounce.lua"] = "5a28036b5ac45c1f93f9883b855e564f",
|
||||
debug = {
|
||||
["log.lua"] = "f7e994b68e9cbcf91adfeb5bc379d7b1"
|
||||
},
|
||||
["debug.lua"] = "6a819b17a531b74ee11622145097afae",
|
||||
["diff.lua"] = "0c462ae71c77899e81da151dcfdf77eb",
|
||||
["diff_ext.lua"] = "04005195067132403fc336422e05c7d3",
|
||||
["diff_int.lua"] = "df447e56f11906998e81d5b94499e013",
|
||||
["diffthis.lua"] = "b91c6a177c0a80c5e611b8c09f6eb46e",
|
||||
["diff_ext.lua"] = "31454455cd645f1518d8363446e8d0f6",
|
||||
["diff_int.lua"] = "8e73883f55811dcb68ad481d389aa687",
|
||||
["diffthis.lua"] = "aaac58016e9982bb14e942f9e4e24c52",
|
||||
git = {
|
||||
["blame.lua"] = "e779f4344bcc41cdb92c1a1be5eb2815",
|
||||
["cmd.lua"] = "449c03c67b7ae516babc41d6da0dc66e",
|
||||
["repo.lua"] = "1efe3178f64b77e0fc22cad55d9586a0",
|
||||
["version.lua"] = "068a582ed4565978eb1f6eb089a6fa6c"
|
||||
},
|
||||
["git.lua"] = "8a216cac54214508e798c7f4b920dd36",
|
||||
["highlight.lua"] = "f1966ef758f9a0a86102a699ec7a1eca",
|
||||
["git.lua"] = "0d3e8859ff8cf7ebd3beb739b64a8c49",
|
||||
["highlight.lua"] = "f0bf039b629818fbfae8a6fad161f9a2",
|
||||
["hunks.lua"] = "ee058ee8b056b055cd8404460ca6921f",
|
||||
["manager.lua"] = "527083250ad693ee4faa5e4dde47f275",
|
||||
["manager.lua"] = "f6e7e2430f2f28a4dbcfd2479f2c8480",
|
||||
["message.lua"] = "523ee4df9da4a7fa9b5ab2100eb27ac4",
|
||||
["popup.lua"] = "cbc11678e30094bff8ed54f0357e26f9",
|
||||
["popup.lua"] = "2fcf3052f95d81cb5c0bb04ca4e06aae",
|
||||
["repeat.lua"] = "798544de97c774bc8e10eecfd6479585",
|
||||
["signs.lua"] = "9224bcde01ebd0c320bcd678822fc799",
|
||||
["signs.lua"] = "a22dd6943d762dffcdbb8d2db4d885bb",
|
||||
["status.lua"] = "a229a7213a3fbecfcf2d98aaf587fcab",
|
||||
system = {
|
||||
["compat.lua"] = "05d2b6d08602fba46be9b540288091e7"
|
||||
},
|
||||
["system.lua"] = "d73fac4f6e734cc8ce9f13d6be027503",
|
||||
["test.lua"] = "082f7c7a556bf27352a378d047b8e79b",
|
||||
["util.lua"] = "b24bac967bc60ba1434bf5cd7cf3fc98",
|
||||
["watcher.lua"] = "034303cfa063c77bb6628f1a55d559c4"
|
||||
["util.lua"] = "d30ad092850bd48a1446ce069320f5a7",
|
||||
["watcher.lua"] = "978875698d84bc1f715c55fefa72bcc1"
|
||||
},
|
||||
["gitsigns.lua"] = "784d1b15d5970f0177fd19d163ea9dfb"
|
||||
["gitsigns.lua"] = "bf3f49482d8340f4be41060d7f461fd1"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user