Skip to content

Commit 2b86631

Browse files
feat: various logging improvements
## Details Related issue: #165 It is currently difficult to figure out why a user is experiencing problems with this plugin just not working. To improve this we need to make some pretty large changes to how the logger works, since it currently it only runs at a per render level. Meaning most information is lost, i.e. we overwrite the file and we don't log anything until we're attempting to render a file, which will not help figure out something not working in general. To imrove this: - log information when attempting to attach to a buffer along with reasons for any skipped buffers - doing the previous items requires updating when items are flushed to disk since there is no longer a convenient start and end, so instead: - When 1000 items have been added without being written - When neovim is closed - If the `log` command is triggered by the user - logger is now additive, meaning we keep appending logs to the same file - logic to prevent file from getting too large, currently hard coded to 5 MB, after which the file is cleared - adds `log` subcommand to quickly open log file in a new tab, similar to `MasonLog` and `LspLog` - input to log is now a `vararg` of messages rather than a single item Unrelated changes: - renames `logger` module to `log` - Moves `RenderMarkdown` command creation logic out of plugin directory and into its own module - Small change to `in_section` logic for nodes
1 parent 044f2d6 commit 2b86631

File tree

22 files changed

+265
-210
lines changed

22 files changed

+265
-210
lines changed

.github/ISSUE_TEMPLATE/bug_report.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,15 @@ body:
4848
- type: textarea
4949
attributes:
5050
label: Plugin error log
51-
description: Error log stored in vim.fn.stdpath(state)/render-markdown.log, typically ~/.local/state/nvim/render-markdown.log, if file is missing put N/A.
51+
description: Error log (:RenderMarkdown log) if empty put N/A.
5252
validations:
5353
required: true
5454
- type: checkboxes
5555
attributes:
5656
label: Confirmations
5757
options:
58+
- label: I have updated this plugin to the latest version using my plugin manager
59+
required: true
5860
- label: I have provided text for all screenshots & understand that my issue will be closed if I have not
5961
required: true
6062
- type: textarea

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ use({
101101
- Can also be accessed directly through `require('render-markdown').disable()`
102102
- `:RenderMarkdown toggle` - Switch between enabling & disabling this plugin
103103
- Can also be accessed directly through `require('render-markdown').toggle()`
104+
- `:RenderMarkdown log` - Opens the log file for this plugin
105+
- Can also be accessed directly through `require('render-markdown').log()`
104106
- `:RenderMarkdown expand` - Increase anti-conceal margin above and below by 1
105107
- Can also be accessed directly through `require('render-markdown').expand()`
106108
- `:RenderMarkdown contract` - Decrease anti-conceal margin above and below by 1

doc/render-markdown.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*render-markdown.txt* For 0.10.0 Last change: 2024 September 13
1+
*render-markdown.txt* For 0.10.0 Last change: 2024 September 14
22

33
==============================================================================
44
Table of Contents *render-markdown-table-of-contents*
@@ -132,6 +132,8 @@ PACKER.NVIM *render-markdown-install-packer.nvim*
132132
- Can also be accessed directly through `require('render-markdown').disable()`
133133
- `:RenderMarkdown toggle` - Switch between enabling & disabling this plugin
134134
- Can also be accessed directly through `require('render-markdown').toggle()`
135+
- `:RenderMarkdown log` - Opens the log file for this plugin
136+
- Can also be accessed directly through `require('render-markdown').log()`
135137
- `:RenderMarkdown expand` - Increase anti-conceal margin above and below by 1
136138
- Can also be accessed directly through `require('render-markdown').expand()`
137139
- `:RenderMarkdown contract` - Decrease anti-conceal margin above and below by 1

lua/render-markdown/api.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
local log = require('render-markdown.core.log')
12
local manager = require('render-markdown.manager')
23
local state = require('render-markdown.state')
34

@@ -16,6 +17,11 @@ function M.toggle()
1617
manager.set_all(not state.enabled)
1718
end
1819

20+
function M.log()
21+
log.flush()
22+
vim.cmd.tabnew(log.file)
23+
end
24+
1925
function M.expand()
2026
state.modify_anti_conceal(1)
2127
M.enable()

lua/render-markdown/colors.lua

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ local cache = {}
55
local M = {}
66

77
---@private
8-
---@type string
98
M.prefix = 'RenderMarkdown'
109

1110
-- stylua: ignore

lua/render-markdown/command.lua

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
local api = require('render-markdown.api')
2+
3+
---@class render.md.Command
4+
local M = {}
5+
6+
---@private
7+
M.name = 'RenderMarkdown'
8+
9+
---@private
10+
M.plugin = 'render-markdown.nvim'
11+
12+
---Should only be called from plugin directory
13+
function M.setup()
14+
vim.api.nvim_create_user_command(M.name, M.command, {
15+
nargs = '*',
16+
desc = M.plugin .. ' commands',
17+
complete = function(_, cmdline)
18+
if cmdline:find(M.name .. '%s+%S+%s+.*') then
19+
return {}
20+
elseif cmdline:find(M.name .. '%s+') then
21+
return vim.tbl_keys(api)
22+
else
23+
return {}
24+
end
25+
end,
26+
})
27+
end
28+
29+
---@private
30+
---@param opts { fargs: string[] }
31+
function M.command(opts)
32+
local args, error_message = opts.fargs, nil
33+
if #args == 0 or #args == 1 then
34+
local command = #args == 0 and api.enable or api[args[1]]
35+
if command ~= nil then
36+
command()
37+
else
38+
error_message = string.format('unexpected command: %s', args[1])
39+
end
40+
else
41+
error_message = string.format('unexpected # arguments: %d', #args)
42+
end
43+
if error_message ~= nil then
44+
vim.notify(string.format('%s: %s', M.plugin, error_message), vim.log.levels.ERROR)
45+
end
46+
end
47+
48+
return M

lua/render-markdown/core/context.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
local NodeInfo = require('render-markdown.core.node_info')
2-
local logger = require('render-markdown.core.logger')
2+
local log = require('render-markdown.core.log')
33
local str = require('render-markdown.core.str')
44
local util = require('render-markdown.core.util')
55

@@ -133,7 +133,7 @@ function Context:query(root, query, callback)
133133
for id, node in query:iter_captures(root, self.buf, self.top, self.bottom) do
134134
local capture = query.captures[id]
135135
local info = NodeInfo.new(self.buf, node)
136-
logger.debug_node_info(capture, info)
136+
log.debug_node_info(capture, info)
137137
callback(capture, info)
138138
end
139139
end

lua/render-markdown/core/list.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
local logger = require('render-markdown.core.logger')
1+
local log = require('render-markdown.core.log')
22
local util = require('render-markdown.core.util')
33

44
---@class render.md.Marks
@@ -32,14 +32,14 @@ function Marks:add(conceal, start_row, start_col, opts)
3232
opts = opts,
3333
}
3434
if opts.virt_text_pos == 'inline' and not util.has_10 then
35-
logger.error('inline marks require neovim >= 0.10.0', mark)
35+
log.error('inline marks require neovim >= 0.10.0', mark)
3636
return false
3737
end
3838
if opts.virt_text_repeat_linebreak ~= nil and not util.has_10 then
39-
logger.error('repeat linebreak marks require neovim >= 0.10.0', mark)
39+
log.error('repeat linebreak marks require neovim >= 0.10.0', mark)
4040
return false
4141
end
42-
logger.debug('mark', mark)
42+
log.debug('mark', mark)
4343
table.insert(self.marks, mark)
4444
return true
4545
end

lua/render-markdown/core/log.lua

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
local util = require('render-markdown.core.util')
2+
3+
---@class render.md.log.Entry
4+
---@field date string
5+
---@field level string
6+
---@field name string
7+
---@field message string
8+
9+
---@class render.md.Log
10+
---@field private level render.md.config.LogLevel
11+
---@field private entries render.md.log.Entry[]
12+
---@field file string
13+
local M = {}
14+
15+
---@param level render.md.config.LogLevel
16+
function M.setup(level)
17+
M.level = level
18+
M.entries = {}
19+
-- Typically resolves to ~/.local/state/nvim/render-markdown.log
20+
M.file = vim.fn.stdpath('state') .. '/render-markdown.log'
21+
-- Clear the file contents if it is too big
22+
if util.file_size_mb(M.file) > 5 then
23+
assert(io.open(M.file, 'w')):close()
24+
end
25+
end
26+
27+
---@param capture string
28+
---@param info render.md.NodeInfo
29+
function M.debug_node_info(capture, info)
30+
M.debug('node info', {
31+
capture = capture,
32+
text = info.text,
33+
rows = { info.start_row, info.end_row },
34+
cols = { info.start_col, info.end_col },
35+
})
36+
end
37+
38+
---Encountered if user provides custom capture
39+
---@param group string
40+
---@param capture string
41+
function M.unhandled_capture(group, capture)
42+
M.error('unhandled capture', string.format('%s -> %s', group, capture))
43+
end
44+
45+
---Encountered if new type is seen for a particular group
46+
---@param language string
47+
---@param group string
48+
---@param value string
49+
function M.unhandled_type(language, group, value)
50+
M.error('unhandled type', string.format('%s -> %s -> %s', language, group, value))
51+
end
52+
53+
---@param name string
54+
---@param ... any
55+
function M.debug(name, ...)
56+
if vim.tbl_contains({ 'debug' }, M.level) then
57+
M.add('debug', name, ...)
58+
end
59+
end
60+
61+
---@param name string
62+
---@param ... any
63+
function M.error(name, ...)
64+
if vim.tbl_contains({ 'debug', 'error' }, M.level) then
65+
M.add('error', name, ...)
66+
end
67+
end
68+
69+
---@private
70+
---@param level render.md.config.LogLevel
71+
---@param name string
72+
---@param ... any
73+
function M.add(level, name, ...)
74+
local messages = {}
75+
local args = vim.F.pack_len(...)
76+
for i = 1, args.n do
77+
local message = type(args[i]) == 'string' and args[i] or vim.inspect(args[i])
78+
table.insert(messages, message)
79+
end
80+
---@type render.md.log.Entry
81+
local entry = {
82+
date = vim.fn.strftime('%Y-%m-%d %H:%M:%S'),
83+
level = string.upper(level),
84+
name = name,
85+
message = table.concat(messages, ' | '),
86+
}
87+
table.insert(M.entries, entry)
88+
-- Periodically flush logs to disk
89+
if #M.entries > 1000 then
90+
M.flush()
91+
end
92+
end
93+
94+
function M.flush()
95+
if #M.entries == 0 then
96+
return
97+
end
98+
local file = assert(io.open(M.file, 'a'))
99+
for _, entry in ipairs(M.entries) do
100+
local line = string.format('%s %s [%s] - %s', entry.date, entry.level, entry.name, entry.message)
101+
file:write(line .. '\n')
102+
end
103+
file:close()
104+
M.entries = {}
105+
end
106+
107+
return M

lua/render-markdown/core/logger.lua

Lines changed: 0 additions & 113 deletions
This file was deleted.

0 commit comments

Comments
 (0)