Skip to content

Commit 9165c70

Browse files
committed
feat: Support dynamic filetype config evaluation - closes #21
1 parent 0db7ebd commit 9165c70

File tree

5 files changed

+175
-34
lines changed

5 files changed

+175
-34
lines changed

SHOWCASE.md

+23
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,29 @@ The keys in the configuration are used like this:
4343

4444
To see some examples, you can look at the [built-in configurations](lua/debugprint/filetypes.lua).
4545

46+
### Dynamically creating filetype configurations
47+
48+
It is also possible to dynamically create filetype configurations by specifying filetype configurations as callback functions that pass back the contents of the table above, rather than the contents of the table directly. For example:
49+
50+
```lua
51+
local my_fileformat = function(opts)
52+
-- Do some dynamic stuff to calculate my_left, my_right, my_mid_var etc...
53+
54+
return {
55+
left = my_left,
56+
right = my_right,
57+
mid_var = my_mid_var,
58+
right_var = my_right
59+
}
60+
end
61+
62+
require('debugprint').setup({ filetypes = { ["filetype"] = my_fileformat }})
63+
```
64+
65+
The function you specify is invoked each time that a debug line is inserted. In the example above, `opts` is of type `DebugprintFileTypeFunctionParams`. This can be found documented in `lua/debugprint/types.lua`. This type is not stable and the contents are not guaranteed to stay the same between versions, although we'll try not to remove fields from it.
66+
67+
Further documentation on this technique is not provided as this is an advanced approach and is left for the user.
68+
4669
## Use `console.info()` rather than `console.warn()` for JavaScript/TypeScript
4770

4871
`debugprint` uses `console.warn()` by default for these languages ([explanation here](https://github.com/andrewferrier/debugprint.nvim/issues/72#issuecomment-1902469694)). However, some folks don't like this. You can change it to use `console.info()` instead like this:

lua/debugprint/filetype_config.lua

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
local M = {}
2+
3+
local utils = require("debugprint.utils")
4+
5+
---@param fn function(DebugprintFileTypeConfigParams):DebugprintFileTypeConfig
6+
---@return DebugprintFileTypeConfig
7+
local get_function_wrapped_config = function(fn)
8+
local bufnr = vim.fn.bufnr()
9+
10+
local result = fn({
11+
effective_filetypes = utils.get_effective_filetypes(),
12+
bufnr = bufnr,
13+
file_path = vim.api.nvim_buf_get_name(bufnr),
14+
})
15+
16+
return result
17+
end
18+
19+
---@param filetypes DebugprintFileTypeConfigOrDynamic[]
20+
---@return DebugprintFileTypeConfig?
21+
M.get = function(filetypes)
22+
local effective_filetypes = utils.get_effective_filetypes()
23+
local config = {}
24+
local found_config = false
25+
26+
for _, effective_filetype in ipairs(effective_filetypes) do
27+
---@type DebugprintFileTypeConfigOrDynamic
28+
local entry = filetypes[effective_filetype]
29+
30+
if entry ~= nil then
31+
found_config = true
32+
33+
local filetype_contents
34+
35+
if type(entry) == "function" then
36+
filetype_contents = get_function_wrapped_config(entry)
37+
else
38+
filetype_contents = entry
39+
end
40+
---@cast filetype_contents DebugprintFileTypeConfig
41+
42+
-- Combine all valid configs into the same object. This seems to
43+
-- make sense as an approach; the only case where I've found where
44+
-- this applies so far is ["bash", "sh"]. If this causes problems we
45+
-- may need to come up with something more sophisticated.
46+
config = vim.tbl_deep_extend(
47+
"keep",
48+
vim.deepcopy(filetype_contents),
49+
config
50+
)
51+
end
52+
end
53+
54+
if not found_config then
55+
return nil
56+
else
57+
return config
58+
end
59+
end
60+
61+
return M

lua/debugprint/init.lua

+7-33
Original file line numberDiff line numberDiff line change
@@ -112,34 +112,6 @@ local get_debugline_textcontent = function(opts, fileconfig)
112112
return line
113113
end
114114

115-
---@return DebugprintFileTypeConfig?
116-
local get_filetype_config = function()
117-
local effective_filetypes = utils.get_effective_filetypes()
118-
local config = {}
119-
local found_config = false
120-
121-
for _, effective_filetype in ipairs(effective_filetypes) do
122-
if global_opts.filetypes[effective_filetype] ~= nil then
123-
found_config = true
124-
-- Combine all valid configs into the same object. This seems to
125-
-- make sense as an approach; the only case where I've found where
126-
-- this applies so far is ["bash", "sh"]. If this causes problems we
127-
-- may need to come up with something more sophisticated.
128-
config = vim.tbl_deep_extend(
129-
"keep",
130-
vim.deepcopy(global_opts.filetypes[effective_filetype]),
131-
config
132-
)
133-
end
134-
end
135-
136-
if not found_config then
137-
return nil
138-
else
139-
return config
140-
end
141-
end
142-
143115
---@param opts DebugprintFunctionOptionsInternal
144116
---@param fileconfig DebugprintFileTypeConfig
145117
---@return string
@@ -175,10 +147,11 @@ end
175147
local get_debugprint_line = function(opts)
176148
local line_to_insert
177149

178-
local fileconfig = get_filetype_config()
150+
local filetype_config =
151+
require("debugprint.filetype_config").get(global_opts.filetypes)
179152

180-
if fileconfig ~= nil then
181-
line_to_insert = construct_debugprint_line(opts, fileconfig)
153+
if filetype_config ~= nil then
154+
line_to_insert = construct_debugprint_line(opts, filetype_config)
182155
else
183156
line_to_insert = utils_errors.construct_error_line(
184157
"No debugprint configuration for filetype "
@@ -286,7 +259,8 @@ M.debugprint = function(opts)
286259
end
287260

288261
if opts.variable == true then
289-
local filetype_config = get_filetype_config()
262+
local filetype_config =
263+
require("debugprint.filetype_config").get(global_opts.filetypes)
290264

291265
if filetype_config then
292266
opts.variable_name = utils.get_variable_name(
@@ -438,7 +412,7 @@ M._get_global_opts = function()
438412
return global_opts
439413
end
440414

441-
---@param filetypes DebugprintFileTypeConfig[]
415+
---@param filetypes DebugprintFileTypeConfigOrDynamic[]
442416
---@return nil
443417
M.add_custom_filetypes = function(filetypes)
444418
vim.validate({

lua/debugprint/types.lua

+9-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@
1212
---@field display_location? boolean
1313
---@field display_snippet? boolean
1414

15+
---@class DebugprintFileTypeConfigParams
16+
---@field effective_filetypes string[]
17+
---@field file_path string
18+
---@field bufnr integer
19+
20+
---@alias DebugprintFileTypeConfigOrDynamic DebugprintFileTypeConfig |
21+
--- function(DebugprintFileTypeConfigParams):DebugprintFileTypeConfig)
22+
1523
---@class DebugprintGlobalOptions
1624
---@field keymaps? DebugprintKeymapOptions
1725
---@field commands? DebugprintCommandOptions
@@ -21,7 +29,7 @@
2129
---@field move_to_debugline? boolean
2230
---@field notify_for_registers? boolean
2331
---@field highlight_lines? boolean
24-
---@field filetypes? DebugprintFileTypeConfig[]
32+
---@field filetypes? DebugprintFileTypeConfigOrDynamic[]
2533
---@field print_tag? string
2634
---Deprecated
2735
---@field create_keymaps? boolean

tests/debugprint.lua

+75
Original file line numberDiff line numberDiff line change
@@ -3073,3 +3073,78 @@ describe("register support", function()
30733073
})
30743074
end)
30753075
end)
3076+
3077+
describe("dynamic filetype configuration", function()
3078+
before_each(function()
3079+
teardown()
3080+
end)
3081+
3082+
after_each(function()
3083+
teardown()
3084+
end)
3085+
3086+
it("can capture one plain statement", function()
3087+
debugprint.setup({
3088+
filetypes = {
3089+
["lua"] = function(opts)
3090+
assert.equals(type(opts.bufnr), "number")
3091+
assert.equals(type(opts.file_path), "string")
3092+
assert.are.same(opts.effective_filetypes, { "lua" })
3093+
3094+
return {
3095+
left = "blah('",
3096+
right = "')",
3097+
}
3098+
end,
3099+
},
3100+
})
3101+
3102+
local filename = init_file({
3103+
"foo",
3104+
"bar",
3105+
}, "lua", 1, 0)
3106+
3107+
feedkeys("g?p")
3108+
3109+
check_lines({
3110+
"foo",
3111+
"blah('DEBUGPRINT[1]: " .. filename .. ":1 (after foo)')",
3112+
"bar",
3113+
})
3114+
end)
3115+
3116+
it("can capture one variable statement", function()
3117+
debugprint.setup({
3118+
filetypes = {
3119+
["lua"] = function(opts)
3120+
assert.equals(type(opts.bufnr), "number")
3121+
assert.equals(type(opts.file_path), "string")
3122+
assert.are.same(opts.effective_filetypes, { "lua" })
3123+
3124+
return {
3125+
left = "blah('",
3126+
right = "')",
3127+
mid_var = opts.effective_filetypes[1]
3128+
.. "' .. vim.inspect(",
3129+
right_var = "))",
3130+
}
3131+
end,
3132+
},
3133+
})
3134+
3135+
local filename = init_file({
3136+
"foo = 123",
3137+
"bar = 456",
3138+
}, "lua", 1, 0)
3139+
3140+
feedkeys("g?v")
3141+
3142+
check_lines({
3143+
"foo = 123",
3144+
"blah('DEBUGPRINT[1]: "
3145+
.. filename
3146+
.. ":1: foo=lua' .. vim.inspect(foo))",
3147+
"bar = 456",
3148+
})
3149+
end)
3150+
end)

0 commit comments

Comments
 (0)