Skip to content

Commit 3ad3f73

Browse files
committed
feat: support registers - closes #148
1 parent 7a95d5f commit 3ad3f73

File tree

7 files changed

+450
-161
lines changed

7 files changed

+450
-161
lines changed

README.md

+77-70
Large diffs are not rendered by default.

SHOWCASE.md

+20
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,23 @@ add({
172172
depends = { 'echasnovski/mini.nvim' }, -- Needed for :ToggleCommentDebugPrints (not needed for NeoVim 0.10+)
173173
})
174174
```
175+
176+
## Register Usage
177+
178+
Each of the standard keymappings (except the ones for insert mode) can be [prefixed with a register](https://neovim.io/doc/user/change.html#registers) in the same way as the standard 'y' (yank), 'd' (delete) keys, etc. When doing this, the content that would normally be inserted into the buffer is instead set into the register (lowercase register names) or appended to the register (uppercase register name). This means you can 'capture' several debugprint lines into a register, than insert them elsewhere in the buffer. This is particularly useful for 'variable' debugprint lines.
179+
180+
For example, given this buffer:
181+
182+
```lua
183+
foo = 123
184+
bar = 456
185+
```
186+
187+
You can put your cursor on `foo`, and type `"ag?v`. Then put your cursor on `bar`, and type `"Ag?v`. Then you can move to the end of the buffer and type `"ap`. The end result will look like this:
188+
189+
```lua
190+
foo = 123
191+
bar = 456
192+
print('DEBUGPRINT[1]: filename.lua:1: foo=' .. vim.inspect(foo))
193+
print('DEBUGPRINT[2]: filename.lua:2: bar=' .. vim.inspect(bar))
194+
```

lua/debugprint/init.lua

+75-36
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ local utils = require("debugprint.utils")
44
local utils_buffer = require("debugprint.utils.buffer")
55
local utils_errors = require("debugprint.utils.errors")
66
local utils_operator = require("debugprint.utils.operator")
7+
local utils_register = require("debugprint.utils.register")
78

89
local global_opts
910

@@ -190,37 +191,61 @@ local get_debugprint_line = function(opts)
190191
return line_to_insert
191192
end
192193

194+
---@param opts DebugprintFunctionOptionsInternal
195+
---@param keys string
196+
local add_to_register = function(opts, keys)
197+
utils_register.set_register(keys)
198+
199+
local content
200+
201+
if opts.variable_name then
202+
content = "variable debug line (" .. opts.variable_name .. ")"
203+
else
204+
content = "plain debug line"
205+
end
206+
207+
if utils_register.register_append() then
208+
vim.notify("Appended " .. content .. " to register " .. opts.register)
209+
else
210+
vim.notify("Written " .. content .. " to register " .. opts.register)
211+
end
212+
end
213+
193214
---@param opts DebugprintFunctionOptionsInternal
194215
---@return nil
195216
local insert_debugprint_line = function(opts)
196-
local line_to_insert = get_debugprint_line(opts)
197-
198217
-- Inserting the leading space from the current line effectively acts as a
199218
-- 'default' indent for languages like Python, where the NeoVim or Treesitter
200219
-- indenter doesn't know how to indent them.
201220
local leading_space = vim.api.nvim_get_current_line():match("^(%s+)") or ""
202221

203-
local current_line_nr = vim.api.nvim_win_get_cursor(0)[1]
204-
local line_to_insert_linenr
222+
local line_to_insert = leading_space .. get_debugprint_line(opts)
205223

206-
if opts.above then
207-
line_to_insert_linenr = current_line_nr - 1
224+
if opts.register then
225+
add_to_register(opts, line_to_insert)
208226
else
209-
line_to_insert_linenr = current_line_nr
210-
end
227+
local current_line_nr = vim.api.nvim_win_get_cursor(0)[1]
228+
local line_to_insert_linenr
211229

212-
vim.api.nvim_buf_set_lines(
213-
0,
214-
line_to_insert_linenr,
215-
line_to_insert_linenr,
216-
true,
217-
{ leading_space .. line_to_insert }
218-
)
230+
if opts.above then
231+
line_to_insert_linenr = current_line_nr - 1
232+
else
233+
line_to_insert_linenr = current_line_nr
234+
end
219235

220-
utils_buffer.indent_line(
221-
line_to_insert_linenr,
222-
global_opts.move_to_debugline
223-
)
236+
vim.api.nvim_buf_set_lines(
237+
0,
238+
line_to_insert_linenr,
239+
line_to_insert_linenr,
240+
true,
241+
{ line_to_insert }
242+
)
243+
244+
utils_buffer.indent_line(
245+
line_to_insert_linenr,
246+
global_opts.move_to_debugline
247+
)
248+
end
224249
end
225250

226251
local cache_request = {}
@@ -239,50 +264,64 @@ M.debugprint_operatorfunc_motion = function()
239264
M.debugprint_operatorfunc_regular()
240265
end
241266

267+
---@param keys string
268+
---@param insert boolean
269+
local debugprint_insertkeys = function(keys, insert)
270+
if keys ~= nil and keys ~= "" then
271+
if insert then
272+
vim.api.nvim_put({ keys }, "c", true, true)
273+
else
274+
vim.api.nvim_feedkeys(keys, "xt", true)
275+
end
276+
end
277+
end
278+
242279
---@param opts? DebugprintFunctionOptions
243-
---@return string?
280+
---@return nil
244281
M.debugprint = function(opts)
245-
local func_opts =
246-
require("debugprint.options").get_and_validate_function_opts(opts)
282+
opts = require("debugprint.options").get_and_validate_function_opts(opts)
283+
---@cast opts DebugprintFunctionOptionsInternal
284+
285+
opts.register = require("debugprint.utils.register").register_named()
247286

248-
---@cast func_opts DebugprintFunctionOptionsInternal
287+
assert(not (opts.insert and opts.register))
249288

250289
if not utils_buffer.is_modifiable() then
251290
return
252291
end
253292

254-
if func_opts.variable == true then
293+
if opts.variable == true then
255294
local filetype_config = get_filetype_config()
256295

257296
if filetype_config then
258-
func_opts.variable_name = utils.get_variable_name(
259-
global_opts.ignore_treesitter
260-
or func_opts.ignore_treesitter
261-
or false,
297+
opts.variable_name = utils.get_variable_name(
298+
global_opts.ignore_treesitter or opts.ignore_treesitter or false,
262299
filetype_config
263300
)
264301

265-
if not func_opts.variable_name then
302+
if not opts.variable_name then
266303
return
267304
end
268305
end
269306
end
270307

271-
if func_opts.insert == true then
272-
cache_request = {}
273-
return get_debugprint_line(func_opts)
274-
elseif func_opts.motion == true then
275-
cache_request = func_opts
308+
if opts.motion == true then
309+
cache_request = opts
276310
utils_operator.set_operatorfunc(
277311
"v:lua.require'debugprint'.debugprint_operatorfunc_motion"
278312
)
279313
return "g@"
314+
end
315+
316+
if opts.insert == true then
317+
cache_request = {}
318+
debugprint_insertkeys(get_debugprint_line(opts), opts.insert)
280319
else
281-
cache_request = func_opts
320+
cache_request = opts
282321
utils_operator.set_operatorfunc(
283322
"v:lua.require'debugprint'.debugprint_operatorfunc_regular"
284323
)
285-
return "g@l"
324+
debugprint_insertkeys("g@l", opts.insert)
286325
end
287326
end
288327

lua/debugprint/setup.lua

+27-55
Original file line numberDiff line numberDiff line change
@@ -22,79 +22,57 @@ local create_command = function(name, command, opts)
2222
end
2323
end
2424

25-
---@param keys string?
26-
---@param insert_mode boolean
27-
---@return nil
28-
local feedkeys = function(keys, insert_mode)
29-
if keys ~= nil and keys ~= "" then
30-
if insert_mode then
31-
vim.api.nvim_put({ keys }, "c", true, true)
32-
else
33-
vim.api.nvim_feedkeys(keys, "xt", true)
34-
end
35-
end
36-
end
37-
3825
---@param global_opts DebugprintGlobalOptions
3926
---@return nil
4027
M.map_keys_and_commands = function(global_opts)
4128
map_key("n", global_opts.keymaps.normal.plain_below, {
4229
callback = function()
43-
feedkeys(debugprint.debugprint({}), false)
30+
debugprint.debugprint({})
4431
end,
4532
desc = "Plain debug below current line",
4633
})
4734

4835
map_key("n", global_opts.keymaps.normal.plain_above, {
4936
callback = function()
50-
feedkeys(debugprint.debugprint({ above = true }), false)
37+
debugprint.debugprint({ above = true })
5138
end,
5239
desc = "Plain debug above current line",
5340
})
5441

5542
map_key("n", global_opts.keymaps.normal.variable_below, {
5643
callback = function()
57-
feedkeys(debugprint.debugprint({ variable = true }), false)
44+
debugprint.debugprint({ variable = true })
5845
end,
5946
desc = "Variable debug below current line",
6047
})
6148

6249
map_key("n", global_opts.keymaps.normal.variable_above, {
6350
callback = function()
64-
feedkeys(
65-
debugprint.debugprint({
66-
above = true,
67-
variable = true,
68-
}),
69-
false
70-
)
51+
debugprint.debugprint({
52+
above = true,
53+
variable = true,
54+
})
7155
end,
7256
desc = "Variable debug above current line",
7357
})
7458

7559
map_key("n", global_opts.keymaps.normal.variable_below_alwaysprompt, {
7660
callback = function()
77-
feedkeys(
78-
debugprint.debugprint({
79-
variable = true,
80-
ignore_treesitter = true,
81-
}),
82-
false
83-
)
61+
debugprint.debugprint({
62+
variable = true,
63+
ignore_treesitter = true,
64+
})
8465
end,
8566
desc = "Variable debug below current line (always prompt)",
8667
})
8768

8869
map_key("n", global_opts.keymaps.normal.variable_above_alwaysprompt, {
8970
callback = function()
90-
feedkeys(
91-
debugprint.debugprint({
92-
above = true,
93-
variable = true,
94-
ignore_treesitter = true,
95-
}),
96-
false
97-
)
71+
debugprint.debugprint({
72+
above = true,
73+
variable = true,
74+
ignore_treesitter = true,
75+
})
9876
end,
9977
desc = "Variable debug above current line (always prompt)",
10078
})
@@ -120,41 +98,35 @@ M.map_keys_and_commands = function(global_opts)
12098

12199
map_key("i", global_opts.keymaps.insert.plain, {
122100
callback = function()
123-
feedkeys(debugprint.debugprint({ insert = true }), true)
101+
debugprint.debugprint({ insert = true })
124102
end,
125103
desc = "Plain debug in-place",
126104
})
127105

128106
map_key("i", global_opts.keymaps.insert.variable, {
129107
callback = function()
130-
feedkeys(
131-
debugprint.debugprint({
132-
insert = true,
133-
variable = true,
134-
ignore_treesitter = true,
135-
}),
136-
true
137-
)
108+
debugprint.debugprint({
109+
insert = true,
110+
variable = true,
111+
ignore_treesitter = true,
112+
})
138113
end,
139114
desc = "Variable debug in-place (always prompt)",
140115
})
141116

142117
map_key("x", global_opts.keymaps.visual.variable_below, {
143118
callback = function()
144-
feedkeys(debugprint.debugprint({ variable = true }), false)
119+
debugprint.debugprint({ variable = true })
145120
end,
146121
desc = "Variable debug below current line",
147122
})
148123

149124
map_key("x", global_opts.keymaps.visual.variable_above, {
150125
callback = function()
151-
feedkeys(
152-
debugprint.debugprint({
153-
above = true,
154-
variable = true,
155-
}),
156-
false
157-
)
126+
debugprint.debugprint({
127+
above = true,
128+
variable = true,
129+
})
158130
end,
159131
desc = "Variable debug above current line",
160132
})

lua/debugprint/types.lua

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565

6666
---@class DebugprintFunctionOptionsInternal: DebugprintFunctionOptions
6767
---@field variable_name? string
68+
---@field register? string
6869

6970
---@class DebugprintCommandOpts
7071
---@field line1 integer

lua/debugprint/utils/register.lua

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
local M = {}
2+
3+
---@return string|nil
4+
M.register_named = function()
5+
if
6+
vim.v.register
7+
and string.find(
8+
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
9+
vim.v.register
10+
)
11+
then
12+
return vim.v.register
13+
else
14+
return nil
15+
end
16+
end
17+
18+
---@return string|nil
19+
M.register_append = function()
20+
if
21+
vim.v.register
22+
and string.find("ABCDEFGHIJKLMNOPQRSTUVWXYZ", vim.v.register)
23+
then
24+
return vim.v.register
25+
else
26+
return nil
27+
end
28+
end
29+
30+
---@param value string
31+
M.set_register = function(value)
32+
assert(M.register_named ~= nil)
33+
vim.fn.setreg(vim.v.register, value, "l")
34+
end
35+
36+
return M

0 commit comments

Comments
 (0)