Skip to content

Commit 4b2c9ab

Browse files
committed
feat: improve context for logging
- add more watcher logging
1 parent 45086b3 commit 4b2c9ab

File tree

11 files changed

+208
-106
lines changed

11 files changed

+208
-106
lines changed

lua/gitsigns/actions/blame.lua

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,6 @@ end
332332
--- @async
333333
--- @param opts Gitsigns.BlameOpts?
334334
function M.blame(opts)
335-
local __FUNC__ = 'blame'
336335
local bufnr = api.nvim_get_current_buf()
337336
local win = api.nvim_get_current_win()
338337
local bcache = cache[bufnr]

lua/gitsigns/actions/diffthis.lua

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,6 @@ end
213213
--- @param relpath string?
214214
--- @return boolean did_attach
215215
function M.show(bufnr, base, relpath)
216-
local __FUNC__ = 'show'
217-
218216
bufnr = bufnr or api.nvim_get_current_buf()
219217

220218
if not cache[bufnr] then

lua/gitsigns/attach.lua

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ end
6767
--- @param _ 'reload'
6868
--- @param bufnr integer
6969
local function on_reload(_, bufnr)
70-
local __FUNC__ = 'on_reload'
7170
assert(cache[bufnr]):invalidate()
7271
dprint('Reload')
7372
manager.update_sync_debounced(bufnr)
@@ -360,8 +359,8 @@ M.attach = throttle_async({ hash = 1 }, function(cbuf, ctx, aucmd)
360359

361360
cache[cbuf] = Cache.new(cbuf, file, git_obj)
362361

363-
if config.watch_gitdir.enable then
364-
dprintf('Watching git dir')
362+
if git_obj.repo:has_watcher() then
363+
dprintf('Watching git dir %s', git_obj.repo.gitdir)
365364

366365
--- Throttle to:
367366
--- - ensure handler is only triggered once per git operation.

lua/gitsigns/cli.lua

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ end
5959
--- @async
6060
--- @param params vim.api.keyset.create_user_command.command_args
6161
function M.run(params)
62-
local __FUNC__ = 'cli.run'
6362
local pos_args_raw, named_args_raw = argparse.parse_args(params.args)
6463

6564
local func = pos_args_raw[1]

lua/gitsigns/debug/log.lua

Lines changed: 107 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,31 +59,128 @@ local function getvarvalue(name, lvl)
5959
return getfenv(func)[name]
6060
end
6161

62+
--- @param info debuglib.DebugInfo
63+
--- @return string
64+
local function get_cur_module(info)
65+
local src = info.source or '???'
66+
67+
if vim.startswith(src, '@') then
68+
src = src:sub(2)
69+
end
70+
src = src:gsub('^%./', '')
71+
72+
local rel = src:match('^lua/(.+)$') or src:match('[/\\]lua[/\\](.+)$')
73+
local module = (rel or src):gsub('%.lua$', ''):gsub('/init$', ''):gsub('[\\/]', '.')
74+
return module
75+
end
76+
77+
--- @param tbl table
78+
--- @param func function
79+
--- @return string?
80+
local function find_func_name(tbl, func)
81+
for k, v in pairs(tbl) do
82+
if v == func and type(k) == 'string' then
83+
return k
84+
end
85+
end
86+
end
87+
88+
--- @param func function?
6289
--- @param lvl integer
63-
--- @return {name:string, bufnr: integer}
64-
local function get_context(lvl)
90+
--- @return string?
91+
local function get_cur_func_name_from_self(func, lvl)
92+
if not func then
93+
return
94+
end
95+
96+
local self_tbl = getvarvalue('self', lvl)
97+
if type(self_tbl) ~= 'table' then
98+
return
99+
end
100+
101+
local name = find_func_name(self_tbl, func)
102+
if name then
103+
return name
104+
end
105+
106+
local mt = getmetatable(self_tbl)
107+
local idx = mt and mt.__index
108+
if type(idx) ~= 'table' then
109+
return
110+
end
111+
112+
local name1 = find_func_name(idx, func)
113+
if name1 then
114+
return name1
115+
end
116+
end
117+
118+
--- @param func function?
119+
--- @param module string?
120+
--- @return string?
121+
local function get_cur_func_name_from_loaded(func, module)
122+
if not func then
123+
return
124+
end
125+
local tbl = package.loaded[module]
126+
if type(tbl) == 'table' then
127+
return find_func_name(tbl, func)
128+
end
129+
end
130+
131+
local func_names_cache = {} --- @type table<function, string>
132+
133+
--- @param info debuglib.DebugInfo
134+
--- @param lvl integer
135+
--- @param module string?
136+
--- @return string
137+
local function get_cur_func_name(info, lvl, module)
65138
lvl = lvl + 1
66139

67-
local name = getvarvalue('__FUNC__', lvl)
68-
if not name then
69-
local name0 = debug.getinfo(lvl, 'n').name or ''
70-
name = name0:gsub('(.*)%d+$', '%1')
140+
local func = info.func
141+
142+
if func_names_cache[func] then
143+
return func_names_cache[func]
71144
end
72145

146+
local name = getvarvalue('__FUNC__', lvl) --[[@as string?]]
147+
or info.name
148+
or get_cur_func_name_from_self(func, lvl)
149+
or get_cur_func_name_from_loaded(func, module)
150+
or (info.what == 'main') and 'main'
151+
or ('<anonymous@%d>'):format(info.linedefined or 0)
152+
153+
func_names_cache[func] = name
154+
155+
return name
156+
end
157+
158+
--- @param lvl integer
159+
--- @return {module: string?, name:string, bufnr: integer}
160+
local function get_context(lvl)
161+
lvl = lvl + 1
162+
local info = debug.getinfo(lvl, 'nSf') or {} --- @type any
163+
local module = get_cur_module(info)
164+
local func = get_cur_func_name(info, lvl, module)
165+
166+
module = module:gsub('^gitsigns%.', '')
167+
168+
func = func:gsub('(.*)%d+$', '%1')
169+
73170
local bufnr = getvarvalue('bufnr', lvl)
74171
or getvarvalue('_bufnr', lvl)
75172
or getvarvalue('cbuf', lvl)
76173
or getvarvalue('buf', lvl)
77174

78-
return { name = name, bufnr = bufnr }
175+
return { module = module, name = func, bufnr = bufnr }
79176
end
80177

81178
local function tostring(obj)
82179
return type(obj) == 'string' and obj or vim.inspect(obj)
83180
end
84181

85-
-- If called in a callback then make sure the callback defines a __FUNC__
86-
-- variable which can be used to identify the name of the function.
182+
--- If called in a callback then make sure the callback defines a __FUNC__
183+
--- variable which can be used to identify the name of the function.
87184
--- @param kind string
88185
--- @param lvl integer
89186
--- @param ... any
@@ -96,7 +193,7 @@ local function cprint(kind, lvl, ...)
96193
local msg = table.concat(msgs, ' ')
97194
local ctx = get_context(lvl)
98195
local time = (uv.hrtime() - start_time) / 1e6
99-
local ctx1 = ctx.name
196+
local ctx1 = ctx.module and ctx.module .. '.' .. ctx.name or ctx.name
100197
if ctx.bufnr then
101198
ctx1 = string.format('%s(%s)', ctx1, ctx.bufnr)
102199
end

lua/gitsigns/git/repo.lua

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
local async = require('gitsigns.async')
22
local git_command = require('gitsigns.git.cmd')
3+
local config = require('gitsigns.config').config
34
local log = require('gitsigns.debug.log')
45
local util = require('gitsigns.util')
56
local errors = require('gitsigns.git.errors')
@@ -20,7 +21,7 @@ local uv = vim.uv or vim.loop ---@diagnostic disable-line: deprecated
2021
--- Username configured for the repo.
2122
--- Needed for to determine "You" in current line blame.
2223
--- @field username string
23-
--- @field private _watcher Gitsigns.Repo.Watcher
24+
--- @field private _watcher? Gitsigns.Repo.Watcher
2425
local M = {}
2526

2627
--- @param gitdir string
@@ -74,6 +75,7 @@ end
7475
--- @param callback fun() Callback function to be invoked on update.
7576
--- @return fun() deregister Function to remove the callback from the watcher.
7677
function M:on_update(callback)
78+
assert(self._watcher, 'Watcher not initialized')
7779
return self._watcher:on_update(callback)
7880
end
7981

@@ -162,15 +164,21 @@ function M._new(info)
162164
--- @type Gitsigns.Repo
163165
local self = setmetatable(info, { __index = M })
164166
self.username = self:command({ 'config', 'user.name' }, { ignore_error = true })[1]
165-
self._watcher = Watcher.new(self.gitdir)
166-
self._watcher:on_head_update(function()
167-
self.abbrev_head = abbrev_head(self.gitdir)
168-
log.dprintf('HEAD changed, updating abbrev_head to %s', self.abbrev_head)
169-
end)
167+
if config.watch_gitdir.enable then
168+
self._watcher = Watcher.new(self.gitdir)
169+
self._watcher:on_head_update(function()
170+
self.abbrev_head = abbrev_head(self.gitdir)
171+
log.dprintf('HEAD changed, updating abbrev_head to %s', self.abbrev_head)
172+
end)
173+
end
170174

171175
return self
172176
end
173177

178+
function M:has_watcher()
179+
return self._watcher ~= nil
180+
end
181+
174182
local sem = async.semaphore(1)
175183

176184
--- @async

lua/gitsigns/git/repo/watcher.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ function Watcher.new(gitdir)
4444
handle:close()
4545
end)
4646

47+
log.dprintf('Starting git dir watcher on %s', gitdir)
4748
self.handle:start(gitdir, {}, Watcher.handler1(util.weak_ref(self)))
4849

4950
return self
@@ -66,8 +67,6 @@ end
6667
--- @private
6768
--- @param weak_self {ref:Gitsigns.Repo.Watcher}
6869
function Watcher.handler2(weak_self)
69-
local __FUNC__ = 'watcher (debounced)'
70-
7170
local self = weak_self.ref
7271
if not self then
7372
return -- garbage collected
@@ -93,11 +92,12 @@ function Watcher.handler1(weak_self)
9392
--- @param filename string
9493
--- @param events { change: boolean?, rename: boolean? }
9594
return function(err, filename, events)
96-
local __FUNC__ = 'watcher_cb'
95+
local __FUNC__ = 'watcher.handler1'
9796

9897
local watcher = weak_self.ref
9998
if not watcher then
100-
return -- garbage collected
99+
log.dprint('watcher was garbage collected')
100+
return
101101
end
102102

103103
if err then

lua/gitsigns/signs.lua

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ end
152152
--- @param staged? boolean
153153
--- @return Gitsigns.Signs
154154
function M.new(staged)
155-
local __FUNC__ = 'signs.init'
156155
local self = setmetatable({}, { __index = M })
157156
self.config = staged and config.signs_staged or config.signs
158157
Config.subscribe(staged and 'signs_staged' or 'signs', function()

lua/gitsigns/system.lua

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ local system = vim.fn.has('nvim-0.11.2') == 1 and vim.system or require('gitsign
1010
--- @param on_exit fun(obj: vim.SystemCompleted)
1111
--- @return vim.SystemObj
1212
function M.system(cmd, opts, on_exit)
13-
local __FUNC__ = 'run_job'
1413
log.dprint(unpack(cmd))
1514
return system(cmd, opts, on_exit)
1615
end

test/gitdir_watcher_spec.lua

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,18 @@ describe('gitdir_watcher', function()
4141
command('Gitsigns clear_debug')
4242
edit(test_file)
4343

44-
local revparse_pat = ('run_job: git .* rev-parse --show-toplevel --absolute-git-dir --abbrev-ref HEAD'):gsub(
44+
local revparse_pat = ('system.system: git .* rev-parse --show-toplevel --absolute-git-dir --abbrev-ref HEAD'):gsub(
4545
'%-',
4646
'%%-'
4747
)
4848

4949
match_debug_messages({
50-
'attach(1): Attaching (trigger=BufReadPost)',
50+
'attach.attach(1): Attaching (trigger=BufReadPost)',
5151
np(revparse_pat),
52-
np('run_job: git .* config user.name'),
53-
np('run_job: git .* ls%-files .* ' .. vim.pesc(test_file)),
54-
n('attach(1): Watching git dir'),
55-
np('run_job: git .* show .*'),
52+
np('system.system: git .* config user.name'),
53+
np('system.system: git .* ls%-files .* ' .. vim.pesc(test_file)),
54+
np('attach%.attach%(1%): Watching git dir .*'),
55+
np('system.system: git .* show .*'),
5656
})
5757

5858
eq({ [1] = test_file }, get_bufs())
@@ -63,13 +63,13 @@ describe('gitdir_watcher', function()
6363
git('mv', test_file, test_file2)
6464

6565
match_debug_messages({
66-
p('watcher_cb: Git dir update: .*'),
67-
np('run_job: git .* ls%-files .* ' .. vim.pesc(test_file)),
68-
np('run_job: git .* diff %-%-name%-status .* %-%-cached'),
69-
n('handle_moved(1): File moved to dummy.txt2'),
70-
np('run_job: git .* ls%-files .* ' .. vim.pesc(test_file2)),
71-
np('handle_moved%(1%): Renamed buffer 1 from .*/dummy.txt to .*/dummy.txt2'),
72-
np('run_job: git .* show .*'),
66+
p('git.repo.watcher.watcher.handler: Git dir update: .*'),
67+
np('system.system: git .* ls%-files .* ' .. vim.pesc(test_file)),
68+
np('system.system: git .* diff %-%-name%-status .* %-%-cached'),
69+
n('attach.handle_moved(1): File moved to dummy.txt2'),
70+
np('system.system: git .* ls%-files .* ' .. vim.pesc(test_file2)),
71+
np('attach%.handle_moved%(1%): Renamed buffer 1 from .*/dummy.txt to .*/dummy.txt2'),
72+
np('system.system: git .* show .*'),
7373
})
7474

7575
eq({ [1] = test_file2 }, get_bufs())
@@ -81,13 +81,13 @@ describe('gitdir_watcher', function()
8181
git('mv', test_file2, test_file3)
8282

8383
match_debug_messages({
84-
p('watcher_cb: Git dir update: .*'),
85-
np('run_job: git .* ls%-files .* ' .. vim.pesc(test_file2)),
86-
np('run_job: git .* diff %-%-name%-status .* %-%-cached'),
87-
n('handle_moved(1): File moved to dummy.txt3'),
88-
np('run_job: git .* ls%-files .* ' .. vim.pesc(test_file3)),
89-
np('handle_moved%(1%): Renamed buffer 1 from .*/dummy.txt2 to .*/dummy.txt3'),
90-
np('run_job: git .* show .*'),
84+
p('git.repo.watcher.watcher.handler: Git dir update: .*'),
85+
np('system.system: git .* ls%-files .* ' .. vim.pesc(test_file2)),
86+
np('system.system: git .* diff %-%-name%-status .* %-%-cached'),
87+
n('attach.handle_moved(1): File moved to dummy.txt3'),
88+
np('system.system: git .* ls%-files .* ' .. vim.pesc(test_file3)),
89+
np('attach%.handle_moved%(1%): Renamed buffer 1 from .*/dummy.txt2 to .*/dummy.txt3'),
90+
np('system.system: git .* show .*'),
9191
})
9292

9393
eq({ [1] = test_file3 }, get_bufs())
@@ -97,14 +97,14 @@ describe('gitdir_watcher', function()
9797
git('mv', test_file3, test_file)
9898

9999
match_debug_messages({
100-
p('watcher_cb: Git dir update: .*'),
101-
np('run_job: git .* ls%-files .* ' .. vim.pesc(test_file3)),
102-
np('run_job: git .* diff %-%-name%-status .* %-%-cached'),
103-
np('run_job: git .* ls%-files .* ' .. vim.pesc(test_file)),
104-
n('handle_moved(1): Moved file reset'),
105-
np('run_job: git .* ls%-files .* ' .. vim.pesc(test_file)),
106-
np('handle_moved%(1%): Renamed buffer 1 from .*/dummy.txt3 to .*/dummy.txt'),
107-
np('run_job: git .* show .*'),
100+
p('git.repo.watcher.watcher.handler: Git dir update: .*'),
101+
np('system.system: git .* ls%-files .* ' .. vim.pesc(test_file3)),
102+
np('system.system: git .* diff %-%-name%-status .* %-%-cached'),
103+
np('system.system: git .* ls%-files .* ' .. vim.pesc(test_file)),
104+
n('attach.handle_moved(1): Moved file reset'),
105+
np('system.system: git .* ls%-files .* ' .. vim.pesc(test_file)),
106+
np('attach%.handle_moved%(1%): Renamed buffer 1 from .*/dummy.txt3 to .*/dummy.txt'),
107+
np('system.system: git .* show .*'),
108108
})
109109

110110
eq({ [1] = test_file }, get_bufs())

0 commit comments

Comments
 (0)