Refresh generated neovim config
This commit is contained in:
@ -215,10 +215,10 @@ local function get_hunks(bufnr, bcache, greedy, staged)
|
||||
end
|
||||
|
||||
if staged then
|
||||
return bcache.hunks_staged
|
||||
return vim.deepcopy(bcache.hunks_staged)
|
||||
end
|
||||
|
||||
return bcache.hunks
|
||||
return vim.deepcopy(bcache.hunks)
|
||||
end
|
||||
|
||||
--- @param bufnr integer
|
||||
@ -478,6 +478,7 @@ end)
|
||||
--- @field greedy boolean
|
||||
--- @field preview boolean
|
||||
--- @field count integer
|
||||
--- @field target 'unstaged'|'staged'|'all'
|
||||
|
||||
--- @param x string
|
||||
--- @param word string
|
||||
@ -513,6 +514,10 @@ local function process_nav_opts(opts)
|
||||
opts.count = vim.v.count1
|
||||
end
|
||||
|
||||
if opts.target == nil then
|
||||
opts.target = 'unstaged'
|
||||
end
|
||||
|
||||
return opts
|
||||
end
|
||||
|
||||
@ -532,6 +537,30 @@ local function has_preview_inline(bufnr)
|
||||
return #api.nvim_buf_get_extmarks(bufnr, ns_inline, 0, -1, { limit = 1 }) > 0
|
||||
end
|
||||
|
||||
--- @param bufnr integer
|
||||
--- @param target 'unstaged'|'staged'|'all'
|
||||
--- @param greedy boolean
|
||||
--- @return Gitsigns.Hunk.Hunk[]
|
||||
local function get_nav_hunks(bufnr, target, greedy)
|
||||
local bcache = assert(cache[bufnr])
|
||||
local hunks_main = get_hunks(bufnr, bcache, greedy, false) or {}
|
||||
|
||||
local hunks --- @type Gitsigns.Hunk.Hunk[]
|
||||
if target == 'unstaged' then
|
||||
hunks = hunks_main
|
||||
else
|
||||
local hunks_head = get_hunks(bufnr, bcache, greedy, true) or {}
|
||||
hunks_head = Hunks.filter_common(hunks_head, hunks_main) or {}
|
||||
if target == 'all' then
|
||||
hunks = hunks_main
|
||||
vim.list_extend(hunks, hunks_head)
|
||||
elseif target == 'staged' then
|
||||
hunks = hunks_head
|
||||
end
|
||||
end
|
||||
return hunks
|
||||
end
|
||||
|
||||
--- @async
|
||||
--- @param direction 'first'|'last'|'next'|'prev'
|
||||
--- @param opts? Gitsigns.NavOpts
|
||||
@ -543,9 +572,7 @@ local function nav_hunk(direction, opts)
|
||||
return
|
||||
end
|
||||
|
||||
local hunks = get_hunks(bufnr, bcache, opts.greedy, false) or {}
|
||||
local hunks_head = get_hunks(bufnr, bcache, opts.greedy, true) or {}
|
||||
vim.list_extend(hunks, Hunks.filter_common(hunks_head, hunks) or {})
|
||||
local hunks = get_nav_hunks(bufnr, opts.target, opts.greedy)
|
||||
|
||||
if not hunks or vim.tbl_isempty(hunks) then
|
||||
if opts.navigation_message then
|
||||
@ -629,6 +656,8 @@ end
|
||||
--- • {greedy}: (boolean)
|
||||
--- Only navigate between non-contiguous hunks. Only useful if
|
||||
--- 'diff_opts' contains `linematch`. Defaults to `true`.
|
||||
--- • {target}: (`'unstaged'|'staged'|'all'`)
|
||||
--- Which kinds of hunks to target. Defaults to `'unstaged'`.
|
||||
--- • {count}: (integer)
|
||||
--- Number of times to advance. Defaults to |v:count1|.
|
||||
M.nav_hunk = async.create(2, function(direction, opts)
|
||||
@ -1023,6 +1052,19 @@ C.blame_line = function(args, _)
|
||||
M.blame_line(args)
|
||||
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]
|
||||
---
|
||||
--- Attributes: ~
|
||||
--- {async}
|
||||
M.blame = async.create(0, function()
|
||||
return require('gitsigns.blame').blame()
|
||||
end)
|
||||
|
||||
--- @param bcache Gitsigns.CacheEntry
|
||||
--- @param base string?
|
||||
local function update_buf_base(bcache, base)
|
||||
@ -1191,14 +1233,14 @@ CP.diffthis = complete_heads
|
||||
---
|
||||
--- Attributes: ~
|
||||
--- {async}
|
||||
M.show = function(revision)
|
||||
M.show = function(revision, callback)
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
if not cache[bufnr] then
|
||||
print('Error: Buffer is not attached.')
|
||||
return
|
||||
end
|
||||
local diffthis = require('gitsigns.diffthis')
|
||||
diffthis.show(bufnr, revision)
|
||||
diffthis.show(bufnr, revision, callback)
|
||||
end
|
||||
|
||||
CP.show = complete_heads
|
||||
|
||||
@ -138,15 +138,16 @@ end
|
||||
|
||||
--- @param _bufnr integer
|
||||
--- @param file string
|
||||
--- @param revision string?
|
||||
--- @param encoding string
|
||||
--- @return Gitsigns.GitObj?
|
||||
local function try_worktrees(_bufnr, file, encoding)
|
||||
local function try_worktrees(_bufnr, file, revision, encoding)
|
||||
if not config.worktrees then
|
||||
return
|
||||
end
|
||||
|
||||
for _, wt in ipairs(config.worktrees) do
|
||||
local git_obj = git.Obj.new(file, encoding, wt.gitdir, wt.toplevel)
|
||||
local git_obj = git.Obj.new(file, revision, encoding, wt.gitdir, wt.toplevel)
|
||||
if git_obj and git_obj.object_name then
|
||||
dprintf('Using worktree %s', vim.inspect(wt))
|
||||
return git_obj
|
||||
@ -211,13 +212,12 @@ local function get_buf_context(bufnr)
|
||||
file = file,
|
||||
gitdir = gitdir,
|
||||
toplevel = toplevel,
|
||||
-- Commit buffers have there base set back one revision with '^'
|
||||
-- Stage buffers always compare against the common ancestor (':1')
|
||||
-- :0: index
|
||||
-- :1: common ancestor
|
||||
-- :2: target commit (HEAD)
|
||||
-- :3: commit which is being merged
|
||||
base = commit and (commit:match('^:[1-3]') and ':1' or commit .. '^') or nil,
|
||||
base = commit and (commit:match('^:[1-3]') and ':1' or commit) or nil,
|
||||
}
|
||||
end
|
||||
|
||||
@ -273,7 +273,7 @@ local attach_throttled = throttle_by_id(function(cbuf, ctx, aucmd)
|
||||
local git_obj = git.Obj.new(file, revision, encoding, ctx.gitdir, ctx.toplevel)
|
||||
|
||||
if not git_obj and not passed_ctx then
|
||||
git_obj = try_worktrees(cbuf, file, encoding)
|
||||
git_obj = try_worktrees(cbuf, file, revision, encoding)
|
||||
async.scheduler()
|
||||
if not api.nvim_buf_is_valid(cbuf) then
|
||||
return
|
||||
|
||||
@ -67,15 +67,15 @@ end
|
||||
-- at a time.
|
||||
local BLAME_THRESHOLD_LEN = 1000000
|
||||
|
||||
--- @private
|
||||
--- @param lnum integer
|
||||
--- @async
|
||||
--- @param lnum? integer
|
||||
--- @param opts Gitsigns.BlameOpts
|
||||
--- @return table<integer,Gitsigns.BlameInfo?>?
|
||||
function CacheEntry:run_blame(lnum, opts)
|
||||
local bufnr = self.bufnr
|
||||
local blame_cache --- @type table<integer,Gitsigns.BlameInfo?>?
|
||||
repeat
|
||||
local buftext = util.buf_lines(bufnr)
|
||||
local buftext = util.buf_lines(bufnr, true)
|
||||
local tick = vim.b[bufnr].changedtick
|
||||
local lnum0 = #buftext > BLAME_THRESHOLD_LEN and lnum or nil
|
||||
-- TODO(lewis6991): Cancel blame on changedtick
|
||||
@ -97,7 +97,7 @@ local function get_blame_nc(file, lnum)
|
||||
return {
|
||||
orig_lnum = 0,
|
||||
final_lnum = lnum,
|
||||
commit = Git.not_commited(file),
|
||||
commit = Git.not_committed(file),
|
||||
filename = file,
|
||||
}
|
||||
end
|
||||
|
||||
@ -1,21 +1,10 @@
|
||||
--- @class (exact) Gitsigns.SchemaElem.Deprecated
|
||||
---
|
||||
--- Used for renaming fields.
|
||||
--- @field new_field? string
|
||||
---
|
||||
--- Documentation for deprecation. Will be added to the help file and used in
|
||||
--- the notification if `hard = true`.
|
||||
--- @field message? string
|
||||
---
|
||||
--- Emit a message via vim.notify
|
||||
--- @field hard? boolean
|
||||
|
||||
--- @class (exact) Gitsigns.SchemaElem
|
||||
--- @field type string|string[]
|
||||
--- @field type string|string[]|fun(x:any): boolean
|
||||
--- @field type_help? string
|
||||
--- @field refresh? fun(cb: fun()) Function to refresh the config value
|
||||
--- @field deep_extend? boolean
|
||||
--- @field default any
|
||||
--- @field deprecated? boolean|Gitsigns.SchemaElem.Deprecated
|
||||
--- @field deprecated? boolean
|
||||
--- @field default_help? string
|
||||
--- @field description string
|
||||
|
||||
@ -45,10 +34,7 @@
|
||||
--- | 'changedelete'
|
||||
--- | 'untracked'
|
||||
|
||||
--- @class (exact) Gitsigns.CurrentLineBlameFmtOpts
|
||||
--- @field relative_time boolean
|
||||
|
||||
--- @alias Gitsigns.CurrentLineBlameFmtFun fun(user: string, info: table<string,any>, opts: Gitsigns.CurrentLineBlameFmtOpts): {[1]:string,[2]:string}[]
|
||||
--- @alias Gitsigns.CurrentLineBlameFmtFun fun(user: string, info: table<string,any>): {[1]:string,[2]:string}[]
|
||||
|
||||
--- @class (exact) Gitsigns.CurrentLineBlameOpts : Gitsigns.BlameOpts
|
||||
--- @field virt_text? boolean
|
||||
@ -69,8 +55,8 @@
|
||||
--- @field diff_opts Gitsigns.DiffOpts
|
||||
--- @field base? string
|
||||
--- @field signs table<Gitsigns.SignType,Gitsigns.SignConfig>
|
||||
--- @field _signs_staged table<Gitsigns.SignType,Gitsigns.SignConfig>
|
||||
--- @field _signs_staged_enable boolean
|
||||
--- @field signs_staged table<Gitsigns.SignType,Gitsigns.SignConfig>
|
||||
--- @field signs_staged_enable boolean
|
||||
--- @field count_chars table<string|integer,string>
|
||||
--- @field signcolumn boolean
|
||||
--- @field numhl boolean
|
||||
@ -84,14 +70,12 @@
|
||||
--- @field update_debounce integer
|
||||
--- @field status_formatter fun(_: table<string,any>): string
|
||||
--- @field current_line_blame boolean
|
||||
--- @field current_line_blame_formatter_opts { relative_time: boolean }
|
||||
--- @field current_line_blame_formatter string|Gitsigns.CurrentLineBlameFmtFun
|
||||
--- @field current_line_blame_formatter_nc string|Gitsigns.CurrentLineBlameFmtFun
|
||||
--- @field current_line_blame_opts Gitsigns.CurrentLineBlameOpts
|
||||
--- @field preview_config table<string,any>
|
||||
--- @field auto_attach boolean
|
||||
--- @field attach_to_untracked boolean
|
||||
--- @field yadm { enable: boolean }
|
||||
--- @field worktrees {toplevel: string, gitdir: string}[]
|
||||
--- @field word_diff boolean
|
||||
--- @field trouble boolean
|
||||
@ -108,9 +92,7 @@ local M = {
|
||||
DiffOpts = {},
|
||||
SignConfig = {},
|
||||
watch_gitdir = {},
|
||||
current_line_blame_formatter_opts = {},
|
||||
current_line_blame_opts = {},
|
||||
yadm = {},
|
||||
Worktree = {},
|
||||
},
|
||||
}
|
||||
@ -182,10 +164,50 @@ M.config = setmetatable({}, {
|
||||
end,
|
||||
})
|
||||
|
||||
local function warn(s, ...)
|
||||
vim.notify_once(s:format(...), vim.log.levels.WARN, { title = 'gitsigns' })
|
||||
end
|
||||
|
||||
--- @param x Gitsigns.SignConfig
|
||||
--- @return boolean
|
||||
local function validate_signs(x)
|
||||
if type(x) ~= 'table' then
|
||||
return false
|
||||
end
|
||||
|
||||
local warnings --- @type table<string,true>?
|
||||
|
||||
--- @diagnostic disable-next-line:no-unknown
|
||||
for kind, s in pairs(M.schema.signs.default) do
|
||||
--- @diagnostic disable-next-line:no-unknown
|
||||
for ty, v in pairs(s) do
|
||||
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'",
|
||||
kind,
|
||||
ty,
|
||||
v
|
||||
)
|
||||
warnings[w] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if warnings then
|
||||
for w in vim.spairs(warnings) do
|
||||
warn(w)
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--- @type table<string,Gitsigns.SchemaElem>
|
||||
M.schema = {
|
||||
signs = {
|
||||
type = 'table',
|
||||
type_help = 'table',
|
||||
type = validate_signs,
|
||||
deep_extend = true,
|
||||
default = {
|
||||
add = { hl = 'GitSignsAdd', text = '┃', numhl = 'GitSignsAddNr', linehl = 'GitSignsAddLn' },
|
||||
@ -244,7 +266,7 @@ M.schema = {
|
||||
]],
|
||||
},
|
||||
|
||||
_signs_staged = {
|
||||
signs_staged = {
|
||||
type = 'table',
|
||||
deep_extend = true,
|
||||
default = {
|
||||
@ -293,9 +315,9 @@ M.schema = {
|
||||
]],
|
||||
},
|
||||
|
||||
_signs_staged_enable = {
|
||||
signs_staged_enable = {
|
||||
type = 'boolean',
|
||||
default = false,
|
||||
default = true,
|
||||
description = [[
|
||||
Show signs for staged hunks.
|
||||
|
||||
@ -649,24 +671,9 @@ M.schema = {
|
||||
]],
|
||||
},
|
||||
|
||||
current_line_blame_formatter_opts = {
|
||||
type = 'table',
|
||||
deep_extend = true,
|
||||
deprecated = true,
|
||||
default = {
|
||||
relative_time = false,
|
||||
},
|
||||
description = [[
|
||||
Options for the current line blame annotation formatter.
|
||||
|
||||
Fields: ~
|
||||
• relative_time: boolean
|
||||
]],
|
||||
},
|
||||
|
||||
current_line_blame_formatter = {
|
||||
type = { 'string', 'function' },
|
||||
default = ' <author>, <author_time> - <summary> ',
|
||||
default = ' <author>, <author_time:%R> - <summary> ',
|
||||
description = [[
|
||||
String or function used to format the virtual text of
|
||||
|gitsigns-config-current_line_blame|.
|
||||
@ -735,9 +742,6 @@ M.schema = {
|
||||
Note that the keys map onto the output of:
|
||||
`git blame --line-porcelain`
|
||||
|
||||
{opts} Passed directly from
|
||||
|gitsigns-config-current_line_blame_formatter_opts|.
|
||||
|
||||
Return: ~
|
||||
The result of this function is passed directly to the `opts.virt_text`
|
||||
field of |nvim_buf_set_extmark| and thus must be a list of
|
||||
@ -769,17 +773,6 @@ M.schema = {
|
||||
]],
|
||||
},
|
||||
|
||||
yadm = {
|
||||
type = 'table',
|
||||
deprecated = {
|
||||
message = 'Please use |gitsigns-config-on_attach_pre| instead',
|
||||
},
|
||||
default = { enable = false },
|
||||
description = [[
|
||||
yadm configuration.
|
||||
]],
|
||||
},
|
||||
|
||||
_git_version = {
|
||||
type = 'string',
|
||||
default = 'auto',
|
||||
@ -861,22 +854,18 @@ M.schema = {
|
||||
},
|
||||
}
|
||||
|
||||
local function warn(s, ...)
|
||||
vim.notify(s:format(...), vim.log.levels.WARN, { title = 'gitsigns' })
|
||||
end
|
||||
|
||||
--- @param config Gitsigns.Config
|
||||
local function validate_config(config)
|
||||
--- @diagnostic disable-next-line:no-unknown
|
||||
for k, v in pairs(config) do
|
||||
for k, v in
|
||||
pairs(config --[[@as table<string,any>]])
|
||||
do
|
||||
local kschema = M.schema[k]
|
||||
if kschema == nil then
|
||||
warn("gitsigns: Ignoring invalid configuration field '%s'", k)
|
||||
elseif kschema.type then
|
||||
if type(kschema.type) == 'string' then
|
||||
vim.validate({
|
||||
[k] = { v, kschema.type },
|
||||
})
|
||||
else
|
||||
local ty = kschema.type
|
||||
if type(ty) == 'string' or type(ty) == 'function' then
|
||||
vim.validate({ [k] = { v, ty } })
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -888,28 +877,15 @@ local function handle_deprecated(cfg)
|
||||
local dep = v.deprecated
|
||||
if dep and cfg[k] ~= nil then
|
||||
if type(dep) == 'table' then
|
||||
if dep.new_field then
|
||||
local opts_key, field = dep.new_field:match('(.*)%.(.*)')
|
||||
if opts_key and field then
|
||||
-- Field moved to an options table
|
||||
local opts = (cfg[opts_key] or {}) --[[@as table<any,any>]]
|
||||
opts[field] = cfg[k]
|
||||
cfg[opts_key] = opts
|
||||
else
|
||||
-- Field renamed
|
||||
cfg[dep.new_field] = cfg[k]
|
||||
end
|
||||
end
|
||||
|
||||
if dep.hard then
|
||||
if dep.message then
|
||||
warn(dep.message)
|
||||
elseif dep.new_field then
|
||||
warn('%s is now deprecated, please use %s', k, dep.new_field)
|
||||
else
|
||||
warn('%s is now deprecated; ignoring', k)
|
||||
end
|
||||
end
|
||||
else
|
||||
warn('%s is now deprecated; ignoring', k)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -28,7 +28,7 @@ local function expand_blame_format(fmt, name, info)
|
||||
if info.author == name then
|
||||
info.author = 'You'
|
||||
end
|
||||
return util.expand_format(fmt, info, config.current_line_blame_formatter_opts.relative_time)
|
||||
return util.expand_format(fmt, info)
|
||||
end
|
||||
|
||||
--- @param virt_text {[1]: string, [2]: string}[]
|
||||
@ -41,7 +41,6 @@ local function flatten_virt_text(virt_text)
|
||||
return table.concat(res)
|
||||
end
|
||||
|
||||
--- @param winid integer
|
||||
--- @return integer
|
||||
local function win_width()
|
||||
local winid = api.nvim_get_current_win()
|
||||
@ -61,7 +60,7 @@ end
|
||||
--- @param fmt string
|
||||
--- @return Gitsigns.CurrentLineBlameFmtFun
|
||||
local function default_formatter(fmt)
|
||||
return function(username, blame_info, _opts)
|
||||
return function(username, blame_info)
|
||||
return {
|
||||
{
|
||||
expand_blame_format(fmt, username, blame_info),
|
||||
@ -85,7 +84,7 @@ local function get_blame_virt_text(bufnr, blame_info)
|
||||
clb_formatter = default_formatter(clb_formatter)
|
||||
end
|
||||
|
||||
return clb_formatter(git_obj.repo.username, blame_info, config.current_line_blame_formatter_opts)
|
||||
return clb_formatter(git_obj.repo.username, blame_info)
|
||||
end
|
||||
|
||||
--- @param bufnr integer
|
||||
|
||||
@ -43,20 +43,7 @@ function M.dump_cache()
|
||||
vim.api.nvim_echo({ { text } }, false, {})
|
||||
end
|
||||
|
||||
--- @param noecho boolean
|
||||
--- @return string[]?
|
||||
function M.debug_messages(noecho)
|
||||
if noecho then
|
||||
return log.messages
|
||||
else
|
||||
for _, m in ipairs(log.messages) do
|
||||
vim.api.nvim_echo({ { m } }, false, {})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.clear_debug()
|
||||
log.messages = {}
|
||||
end
|
||||
M.debug_messages = log.show
|
||||
M.clear_debug = log.clear
|
||||
|
||||
return M
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
local start_time = vim.loop.hrtime()
|
||||
|
||||
local M = {
|
||||
debug_mode = false,
|
||||
verbose = false,
|
||||
messages = {}, --- @type string[]
|
||||
messages = {} --- @type [number, string, string, string][]
|
||||
}
|
||||
|
||||
--- @param name string
|
||||
@ -44,7 +46,6 @@ local function getvarvalue(name, lvl)
|
||||
end
|
||||
|
||||
-- not found; get global
|
||||
--- @diagnostic disable-next-line:deprecated
|
||||
return getfenv(func)[name]
|
||||
end
|
||||
|
||||
@ -52,71 +53,72 @@ end
|
||||
--- @return {name:string, bufnr: integer}
|
||||
local function get_context(lvl)
|
||||
lvl = lvl + 1
|
||||
local ret = {} --- @type {name:string, bufnr: integer}
|
||||
ret.name = getvarvalue('__FUNC__', lvl)
|
||||
if not ret.name then
|
||||
|
||||
local name = getvarvalue('__FUNC__', lvl)
|
||||
if not name then
|
||||
local name0 = debug.getinfo(lvl, 'n').name or ''
|
||||
ret.name = name0:gsub('(.*)%d+$', '%1')
|
||||
name = name0:gsub('(.*)%d+$', '%1')
|
||||
end
|
||||
ret.bufnr = getvarvalue('bufnr', lvl)
|
||||
|
||||
local bufnr = getvarvalue('bufnr', lvl)
|
||||
or getvarvalue('_bufnr', lvl)
|
||||
or getvarvalue('cbuf', lvl)
|
||||
or getvarvalue('buf', lvl)
|
||||
|
||||
return ret
|
||||
return {name=name, bufnr=bufnr}
|
||||
end
|
||||
|
||||
-- If called in a callback then make sure the callback defines a __FUNC__
|
||||
-- variable which can be used to identify the name of the function.
|
||||
--- @param kind string
|
||||
--- @param obj any
|
||||
--- @param lvl integer
|
||||
local function cprint(obj, lvl)
|
||||
local function cprint(kind, obj, lvl)
|
||||
lvl = lvl + 1
|
||||
--- @type string
|
||||
local msg = type(obj) == 'string' and obj or vim.inspect(obj)
|
||||
local ctx = get_context(lvl)
|
||||
local msg2 --- @type string
|
||||
local time = (vim.loop.hrtime() - start_time) / 1e6
|
||||
local ctx1 = ctx.name
|
||||
if ctx.bufnr then
|
||||
msg2 = string.format('%s(%s): %s', ctx.name, ctx.bufnr, msg)
|
||||
else
|
||||
msg2 = string.format('%s: %s', ctx.name, msg)
|
||||
ctx1 = string.format('%s(%s)', ctx1, ctx.bufnr)
|
||||
end
|
||||
table.insert(M.messages, msg2)
|
||||
table.insert(M.messages, {time, kind, ctx1, msg})
|
||||
end
|
||||
|
||||
function M.dprint(obj)
|
||||
if not M.debug_mode then
|
||||
return
|
||||
end
|
||||
cprint(obj, 2)
|
||||
cprint('debug', obj, 2)
|
||||
end
|
||||
|
||||
function M.dprintf(obj, ...)
|
||||
if not M.debug_mode then
|
||||
return
|
||||
end
|
||||
cprint(obj:format(...), 2)
|
||||
cprint('debug', obj:format(...), 2)
|
||||
end
|
||||
|
||||
function M.vprint(obj)
|
||||
if not (M.debug_mode and M.verbose) then
|
||||
return
|
||||
end
|
||||
cprint(obj, 2)
|
||||
cprint('info', obj, 2)
|
||||
end
|
||||
|
||||
function M.vprintf(obj, ...)
|
||||
if not (M.debug_mode and M.verbose) then
|
||||
return
|
||||
end
|
||||
cprint(obj:format(...), 2)
|
||||
cprint('info', obj:format(...), 2)
|
||||
end
|
||||
|
||||
local function eprint(msg, level)
|
||||
local info = debug.getinfo(level + 2, 'Sl')
|
||||
if info then
|
||||
msg = string.format('(ERROR) %s(%d): %s', info.short_src, info.currentline, msg)
|
||||
end
|
||||
M.messages[#M.messages + 1] = debug.traceback(msg)
|
||||
local ctx = info and string.format('%s<%d>', info.short_src, info.currentline) or '???'
|
||||
local time = (vim.loop.hrtime() - start_time) / 1e6
|
||||
table.insert(M.messages, { time, 'error', ctx, debug.traceback(msg) })
|
||||
if M.debug_mode then
|
||||
error(msg, 3)
|
||||
end
|
||||
@ -141,4 +143,49 @@ function M.assert(cond, msg)
|
||||
return not cond
|
||||
end
|
||||
|
||||
local sev_to_hl = {
|
||||
debug = 'Title',
|
||||
info = 'MoreMsg',
|
||||
warn = 'WarningMsg',
|
||||
error = 'ErrorMsg',
|
||||
}
|
||||
|
||||
function M.clear()
|
||||
M.messages = {}
|
||||
end
|
||||
|
||||
--- @param m [number, string, string, string]
|
||||
--- @return [string,string][]
|
||||
local function build_msg(m)
|
||||
local time, kind, ctx, msg = m[1], m[2], m[3], m[4]
|
||||
local hl = sev_to_hl[kind]
|
||||
return {
|
||||
{ string.format('%.2f ', time), 'Comment' },
|
||||
{ kind:upper():sub(1,1), hl },
|
||||
{ string.format(' %s:', ctx), 'Tag'},
|
||||
{ ' ' },
|
||||
{ msg }
|
||||
}
|
||||
end
|
||||
|
||||
function M.show()
|
||||
for _, m in ipairs(M.messages) do
|
||||
vim.api.nvim_echo(build_msg(m), false, {})
|
||||
end
|
||||
end
|
||||
|
||||
--- @return string[]?
|
||||
function M.get()
|
||||
local r = {} --- @type string[]
|
||||
for _, m in ipairs(M.messages) do
|
||||
local e = build_msg(m)
|
||||
local e1 = {} --- @type string[]
|
||||
for _, x in ipairs(e) do
|
||||
e1[#e1+1] = x[1]
|
||||
end
|
||||
r[#r+1] = table.concat(e1)
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
@ -7,6 +7,7 @@ local manager = require('gitsigns.manager')
|
||||
local message = require('gitsigns.message')
|
||||
local Status = require('gitsigns.status')
|
||||
|
||||
local dprint = require('gitsigns.debug.log').dprint
|
||||
local throttle_by_id = require('gitsigns.debounce').throttle_by_id
|
||||
|
||||
local M = {}
|
||||
@ -176,11 +177,14 @@ end)
|
||||
--- @param bufnr integer
|
||||
--- @param base string
|
||||
M.show = async.create(2, function(bufnr, base)
|
||||
__FUNC__ = 'show'
|
||||
local bufname = create_show_buf(bufnr, base)
|
||||
if not bufname then
|
||||
dprint('No bufname for revision ' .. base)
|
||||
return
|
||||
end
|
||||
|
||||
dprint('bufname ' .. bufname)
|
||||
vim.cmd.edit(bufname)
|
||||
end)
|
||||
|
||||
|
||||
@ -327,35 +327,6 @@ function Repo:update_abbrev_head()
|
||||
self.abbrev_head = M.get_repo_info(self.toplevel).abbrev_head
|
||||
end
|
||||
|
||||
--- @private
|
||||
--- @param dir string
|
||||
--- @param gitdir? string
|
||||
--- @param toplevel? string
|
||||
function Repo:try_yadm(dir, gitdir, toplevel)
|
||||
if not config.yadm.enable or self.gitdir then
|
||||
return
|
||||
end
|
||||
|
||||
local home = os.getenv('HOME')
|
||||
|
||||
if not home or not vim.startswith(dir, home) then
|
||||
return
|
||||
end
|
||||
|
||||
if #git_command({ 'ls-files', dir }, { command = 'yadm' }) == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
M.get_repo_info(dir, 'yadm', gitdir, toplevel)
|
||||
local yadm_info = M.get_repo_info(dir, 'yadm', gitdir, toplevel)
|
||||
for k, v in
|
||||
pairs(yadm_info --[[@as table<string,any>]])
|
||||
do
|
||||
---@diagnostic disable-next-line:no-unknown
|
||||
self[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
--- @async
|
||||
--- @param dir string
|
||||
--- @param gitdir? string
|
||||
@ -373,8 +344,6 @@ function Repo.new(dir, gitdir, toplevel)
|
||||
self[k] = v
|
||||
end
|
||||
|
||||
self:try_yadm(dir, gitdir, toplevel)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@ -424,11 +393,15 @@ end
|
||||
--- @field object_name? string
|
||||
--- @field has_conflicts? true
|
||||
|
||||
function Obj:from_tree()
|
||||
return self.revision and not vim.startswith(self.revision, ':')
|
||||
end
|
||||
|
||||
--- @param file? string
|
||||
--- @param silent? boolean
|
||||
--- @return Gitsigns.FileInfo
|
||||
function Obj:file_info(file, silent)
|
||||
if self.revision and not vim.startswith(self.revision, ':') then
|
||||
if self:from_tree() then
|
||||
return self:file_info_tree(file, silent)
|
||||
else
|
||||
return self:file_info_index(file, silent)
|
||||
@ -436,12 +409,16 @@ function Obj:file_info(file, silent)
|
||||
end
|
||||
|
||||
--- @private
|
||||
--- Get information about files in the index and the working tree
|
||||
--- @param file? string
|
||||
--- @param silent? boolean
|
||||
--- @return Gitsigns.FileInfo
|
||||
function Obj:file_info_index(file, silent)
|
||||
local has_eol = check_version({ 2, 9 })
|
||||
|
||||
-- --others + --exclude-standard means ignored files won't return info, but
|
||||
-- untracked files will. Unlike file_info_tree which won't return untracked
|
||||
-- files.
|
||||
local cmd = {
|
||||
'-c',
|
||||
'core.quotepath=off',
|
||||
@ -499,6 +476,7 @@ function Obj:file_info_index(file, silent)
|
||||
end
|
||||
|
||||
--- @private
|
||||
--- Get information about files in a certain revision
|
||||
--- @param file? string
|
||||
--- @param silent? boolean
|
||||
--- @return Gitsigns.FileInfo
|
||||
@ -615,7 +593,7 @@ local NOT_COMMITTED = {
|
||||
|
||||
--- @param file string
|
||||
--- @return Gitsigns.CommitInfo
|
||||
function M.not_commited(file)
|
||||
function M.not_committed(file)
|
||||
local time = os.time()
|
||||
return {
|
||||
sha = string.rep('0', 40),
|
||||
@ -649,7 +627,7 @@ function Obj:run_blame(lines, lnum, opts)
|
||||
-- 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_commited(self.file)
|
||||
local commit = M.not_committed(self.file)
|
||||
for i in ipairs(lines) do
|
||||
ret[i] = {
|
||||
orig_lnum = 0,
|
||||
|
||||
@ -283,7 +283,8 @@ local function cmul(x, factor)
|
||||
end
|
||||
|
||||
local function dprintf(fmt, ...)
|
||||
require('gitsigns.debug.log').dprintf(fmt, ...)
|
||||
dprintf = require('gitsigns.debug.log').dprintf
|
||||
dprintf(fmt, ...)
|
||||
end
|
||||
|
||||
--- @param hl string
|
||||
|
||||
@ -432,7 +432,6 @@ function M.filter_common(a, b)
|
||||
end
|
||||
|
||||
a, b = a or {}, b or {}
|
||||
local max_iter = math.max(#a, #b)
|
||||
|
||||
local a_i = 1
|
||||
local b_i = 1
|
||||
@ -440,7 +439,9 @@ function M.filter_common(a, b)
|
||||
--- @type Gitsigns.Hunk.Hunk[]
|
||||
local ret = {}
|
||||
|
||||
for _ = 1, max_iter do
|
||||
-- Need an offset of 1 in order to process when we hit the end of either
|
||||
-- a or b
|
||||
for _ = 1, math.max(#a, #b) + 1 do
|
||||
local a_h, b_h = a[a_i], b[b_i]
|
||||
|
||||
if not a_h then
|
||||
|
||||
@ -488,9 +488,10 @@ M.update = throttle_by_id(function(bufnr)
|
||||
return
|
||||
end
|
||||
|
||||
if config._signs_staged_enable and not file_mode and not git_obj.revision then
|
||||
if config.signs_staged_enable and not file_mode then
|
||||
if not bcache.compare_text_head or config._refresh_staged_on_update then
|
||||
bcache.compare_text_head = git_obj:get_show_text('HEAD')
|
||||
local staged_rev = git_obj:from_tree() and git_obj.revision .. '^' or 'HEAD'
|
||||
bcache.compare_text_head = git_obj:get_show_text(staged_rev)
|
||||
if not M.schedule(bufnr, true) then
|
||||
return
|
||||
end
|
||||
@ -581,8 +582,8 @@ function M.setup()
|
||||
})
|
||||
|
||||
signs_normal = Signs.new(config.signs)
|
||||
if config._signs_staged_enable then
|
||||
signs_staged = Signs.new(config._signs_staged, 'staged')
|
||||
if config.signs_staged_enable then
|
||||
signs_staged = Signs.new(config.signs_staged, 'staged')
|
||||
end
|
||||
|
||||
M.update_debounced = debounce_trailing(config.update_debounce, async.create(1, M.update))
|
||||
|
||||
@ -126,7 +126,7 @@ function M.new(cfg, name)
|
||||
|
||||
local self = setmetatable({}, { __index = M })
|
||||
self.config = cfg
|
||||
self.hls = name == 'staged' and config._signs_staged or config.signs
|
||||
self.hls = name == 'staged' and config.signs_staged or config.signs
|
||||
self.group = 'gitsigns_signs_' .. (name or '')
|
||||
self.ns = api.nvim_create_namespace(self.group)
|
||||
return self
|
||||
|
||||
@ -71,8 +71,9 @@ local function add_bom(x, encoding)
|
||||
end
|
||||
|
||||
--- @param bufnr integer
|
||||
--- @param noendofline? boolean
|
||||
--- @return string[]
|
||||
function M.buf_lines(bufnr)
|
||||
function M.buf_lines(bufnr, noendofline)
|
||||
-- nvim_buf_get_lines strips carriage returns if fileformat==dos
|
||||
local buftext = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
|
||||
|
||||
@ -84,7 +85,7 @@ function M.buf_lines(bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
if vim.bo[bufnr].endofline then
|
||||
if not noendofline and vim.bo[bufnr].endofline then
|
||||
-- Add CR to the last line
|
||||
if dos then
|
||||
buftext[#buftext] = buftext[#buftext] .. '\r'
|
||||
@ -116,6 +117,15 @@ function M.buf_rename(bufnr, name)
|
||||
delete_alt(bufnr)
|
||||
end
|
||||
|
||||
--- @param events string[]
|
||||
--- @param f fun()
|
||||
function M.noautocmd(events, f)
|
||||
local ei = vim.o.eventignore
|
||||
vim.o.eventignore = table.concat(events, ',')
|
||||
f()
|
||||
vim.o.eventignore = ei
|
||||
end
|
||||
|
||||
--- @param bufnr integer
|
||||
--- @param start_row integer
|
||||
--- @param end_row integer
|
||||
@ -254,9 +264,8 @@ end
|
||||
|
||||
---@param fmt string
|
||||
---@param info table<string,any>
|
||||
---@param reltime? boolean Use relative time as the default date format
|
||||
---@return string
|
||||
function M.expand_format(fmt, info, reltime)
|
||||
function M.expand_format(fmt, info)
|
||||
local ret = {} --- @type string[]
|
||||
|
||||
for _ = 1, 20 do -- loop protection
|
||||
@ -277,7 +286,7 @@ function M.expand_format(fmt, info, reltime)
|
||||
end
|
||||
if vim.endswith(key, '_time') then
|
||||
if time_fmt == '' then
|
||||
time_fmt = reltime and '%R' or '%Y-%m-%d'
|
||||
time_fmt = '%Y-%m-%d'
|
||||
end
|
||||
v = expand_date(time_fmt, v)
|
||||
end
|
||||
|
||||
@ -8,6 +8,7 @@ local util = require('gitsigns.util')
|
||||
|
||||
local cache = require('gitsigns.cache').cache
|
||||
local config = require('gitsigns.config').config
|
||||
local throttle_by_id = require('gitsigns.debounce').throttle_by_id
|
||||
local debounce_trailing = require('gitsigns.debounce').debounce_trailing
|
||||
local manager = require('gitsigns.manager')
|
||||
|
||||
@ -52,15 +53,21 @@ local function handle_moved(bufnr, old_relpath)
|
||||
local old_name = api.nvim_buf_get_name(bufnr)
|
||||
|
||||
if not bufexists then
|
||||
util.buf_rename(bufnr, bcache.file)
|
||||
-- Do not trigger BufFilePre/Post
|
||||
-- TODO(lewis6991): figure out how to avoid reattaching without
|
||||
-- disabling all autocommands.
|
||||
util.noautocmd({ 'BufFilePre', 'BufFilePost' }, function()
|
||||
util.buf_rename(bufnr, bcache.file)
|
||||
end)
|
||||
end
|
||||
|
||||
local msg = bufexists and 'Cannot rename' or 'Renamed'
|
||||
dprintf('%s buffer %d from %s to %s', msg, bufnr, old_name, bcache.file)
|
||||
end
|
||||
|
||||
--- @async
|
||||
--- @param bufnr integer
|
||||
local watcher_handler = async.create(1, function(bufnr)
|
||||
local function watcher_handler0(bufnr)
|
||||
local __FUNC__ = 'watcher_handler'
|
||||
|
||||
-- Avoid cache hit for detached buffer
|
||||
@ -99,9 +106,13 @@ local watcher_handler = async.create(1, function(bufnr)
|
||||
cache[bufnr]:invalidate(true)
|
||||
|
||||
require('gitsigns.manager').update(bufnr)
|
||||
end)
|
||||
end
|
||||
|
||||
local watcher_handler_debounced = debounce_trailing(200, watcher_handler, 1)
|
||||
--- 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).
|
||||
local watcher_handler =
|
||||
debounce_trailing(200, async.create(1, throttle_by_id(watcher_handler0, true)), 1)
|
||||
|
||||
--- vim.inspect but on one line
|
||||
--- @param x any
|
||||
@ -142,7 +153,7 @@ function M.watch_gitdir(bufnr, gitdir)
|
||||
|
||||
dprint(info)
|
||||
|
||||
watcher_handler_debounced(bufnr)
|
||||
watcher_handler(bufnr)
|
||||
end)
|
||||
return w
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user