Skip to content

Commit 5f628f5

Browse files
author
Andrew Ferrier
committed
feat: Support motion mode - closes #23
1 parent 3603a47 commit 5f628f5

File tree

3 files changed

+176
-23
lines changed

3 files changed

+176
-23
lines changed

README.md

+23-19
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ It provides various improvements:
3131
* It provides keymappings for visual mode, so you can select a variable
3232
visually and print it out.
3333

34+
* It provides keymappings for operator-pending mode, so you can select a
35+
variable using a motion.
36+
3437
* It indents the lines it inserts more accurately.
3538

3639
* The output when printing a 'plain' debug line, or a variable, is more
@@ -95,21 +98,22 @@ any breaking issues.
9598

9699
## Keymappings
97100

98-
By default, the plugin will create some normal-mode keymappings, which are the
99-
standard way to use it. There are also some function invocations which are not
100-
mapped to any keymappings by default, but could be. This is all shown in the
101-
following table.
102-
103-
| Mode | Keymap | Purpose | Equivalent Lua Function |
104-
| ------ | --------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
105-
| Normal | `g?p` | Insert a 'plain' debug line appropriate to the filetype just below the current line | `require('debugprint').debugprint()` |
106-
| Normal | `g?P` | The same, but above the current line | `require('debugprint').debugprint({above = true})` |
107-
| Normal | `g?v` | Insert a variable debugging line below the current line. If the cursor is on a variable name, use that, otherwise prompt for one. | `require('debugprint').debugprint({variable = true})` |
108-
| Normal | `g?V` | The same, but above the current line | `require('debugprint').debugprint({above = true, variable = true})` |
109-
| Normal | None by default | Always prompt for a variable name, and insert a debugging line just below the current line which outputs it | `require('debugprint').debugprint({ignore_treesitter = true, variable = true})` |
110-
| Normal | None by default | Always prompt for a variable name, and insert a debugging line just above the current line which outputs it | `require('debugprint').debugprint({ignore_treesitter = true, above = true, variable = true})` |
111-
| Visual | `g?v` | Find the visually select variable name, and insert a debugging line just below the current line which outputs it | `require('debugprint').debugprint({variable = true})` |
112-
| Visual | `g?V` | Find the visually select variable name, and insert a debugging line just above the current line which outputs it | `require('debugprint').debugprint({above = true, variable = true})` |
101+
By default, the plugin will create some keymappings, which are the standard way
102+
to use it. There are also some function invocations which are not mapped to any
103+
keymappings by default, but could be. This is all shown in the following table.
104+
105+
| Mode | Keymap | Purpose | Equivalent Lua Function |
106+
| ------ | --------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
107+
| Normal | `g?p` | Insert a 'plain' debug line appropriate to the filetype just below the current line | `require('debugprint').debugprint()` |
108+
| Normal | `g?P` | The same, but above the current line | `require('debugprint').debugprint({above = true})` |
109+
| Normal | `g?v` | Insert a variable debugging line below the current line. If the cursor is on a variable name, use that, otherwise prompt for one. | `require('debugprint').debugprint({variable = true})` |
110+
| Normal | `g?V` | The same, but above the current line | `require('debugprint').debugprint({above = true, variable = true})` |
111+
| Normal | None by default | Always prompt for a variable name, and insert a debugging line just below the current line which outputs it | `require('debugprint').debugprint({ignore_treesitter = true, variable = true})` |
112+
| Normal | None by default | Always prompt for a variable name, and insert a debugging line just above the current line which outputs it | `require('debugprint').debugprint({ignore_treesitter = true, above = true, variable = true})` |
113+
| Visual | `g?v` | Find the visually select variable name, and insert a debugging line just below the current line which outputs it | `require('debugprint').debugprint({variable = true})` |
114+
| Visual | `g?v` | Find the visually select variable name, and insert a debugging line just below the current line which outputs it | `require('debugprint').debugprint({variable = true})` |
115+
| Operator-pending | `g?o` | Locate a variable using a motion, and insert a debugging line just above the current line which outputs it | `require('debugprint').debugprint({above = true, variable = true})` |
116+
| Operator-pending | `g?O` | Locate a variable using a motion, and insert a debugging line just above the current line which outputs it | `require('debugprint').debugprint({above = true, variable = true})` |
113117

114118
These keybindings are chosen specifically because by default in NeoVim they are
115119
used to convert sections to ROT-13, which most folks don't use. You can disable
@@ -211,10 +215,10 @@ configuration.
211215

212216
The keys in the configuration are used like this:
213217

214-
| Type of debug line | Default keys | How debug line is constructed
215-
| - | - | - |
216-
| Plain debug line | `g?p`/`g?P` | `my_fileformat.left .. "auto-gen DEBUG string" .. my_fileformat.right` |
217-
| Variable debug line | `g?v`/`g?V` | `my_fileformat.left .. "auto-gen DEBUG string, variable=" .. my_file_format.mid_var .. variable .. my_fileformat.right_var` |
218+
| Type of debug line | Default keys | How debug line is constructed
219+
| - | - | - |
220+
| Plain debug line | `g?p`/`g?P` | `my_fileformat.left .. "auto-gen DEBUG string" .. my_fileformat.right` |
221+
| Variable debug line | `g?v`/`g?V`/`g?o`/`g?O` | `my_fileformat.left .. "auto-gen DEBUG string, variable=" .. my_file_format.mid_var .. variable .. my_fileformat.right_var` |
218222

219223
If it helps to understand these, you can look at the built-in configurations in
220224
[filetypes.lua](lua/debugprint/filetypes.lua).

lua/debugprint/init.lua

+45-4
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,25 @@ local get_visual_selection = function()
127127
return vim.api.nvim_buf_get_text(0, line1, col1, line2, col2, {})[1]
128128
end
129129

130+
local get_operator_selection = function()
131+
local first_pos, last_pos = vim.fn.getpos("'["), vim.fn.getpos("']")
132+
133+
local line1 = first_pos[2] - 1
134+
local line2 = last_pos[2] - 1
135+
local col1 = first_pos[3] - 1
136+
local col2 = last_pos[3]
137+
138+
if line1 ~= line2 then
139+
vim.notify(
140+
"debugprint not supported when multiple lines in motion.",
141+
vim.log.levels.ERROR
142+
)
143+
return false
144+
end
145+
146+
return vim.api.nvim_buf_get_text(0, line1, col1, line2, col2, {})[1]
147+
end
148+
130149
local debugprint_addline = function(funcopts)
131150
local current_line = vim.api.nvim_win_get_cursor(0)[1]
132151
local filetype =
@@ -209,7 +228,6 @@ M.debugprint_cache = function(o)
209228
end
210229

211230
debugprint_addline(cache_request)
212-
213231
set_callback("v:lua.require'debugprint'.debugprint_cache")
214232
end
215233

@@ -233,9 +251,22 @@ M.debugprint = function(o)
233251
ignore_treesitter = { funcopts.ignore_treesitter, "boolean" },
234252
})
235253

236-
funcopts.prerepeat = true
237-
cache_request = nil
238-
return M.debugprint_cache(funcopts)
254+
if funcopts.motion == true then
255+
cache_request = funcopts
256+
vim.go.operatorfunc =
257+
"v:lua.require'debugprint'.debugprint_motion_callback"
258+
return "g@"
259+
else
260+
cache_request = nil
261+
funcopts.prerepeat = true
262+
return M.debugprint_cache(funcopts)
263+
end
264+
end
265+
266+
M.debugprint_motion_callback = function()
267+
cache_request.variable_name = get_operator_selection()
268+
debugprint_addline(cache_request)
269+
set_callback("v:lua.require'debugprint'.debugprint_cache")
239270
end
240271

241272
M.setup = function(o)
@@ -276,6 +307,16 @@ M.setup = function(o)
276307
end, {
277308
expr = true,
278309
})
310+
vim.keymap.set("n", "g?o", function()
311+
return M.debugprint({ motion = true })
312+
end, {
313+
expr = true,
314+
})
315+
vim.keymap.set("n", "g?O", function()
316+
return M.debugprint({ motion = true, above = true })
317+
end, {
318+
expr = true,
319+
})
279320

280321
vim.keymap.set("n", "dqp", function()
281322
notify_deprecated()

tests/debugprint.lua

+108
Original file line numberDiff line numberDiff line change
@@ -840,3 +840,111 @@ describe("visual selection", function()
840840
)
841841
end)
842842
end)
843+
844+
describe("motion mode", function()
845+
it("standard", function()
846+
debugprint.setup({ ignore_treesitter = true })
847+
848+
set_lines({
849+
"function x() {",
850+
"local xyz = 3",
851+
"end",
852+
})
853+
854+
local filename = write_file("lua")
855+
vim.api.nvim_win_set_cursor(0, { 2, 6 })
856+
feedkeys("g?o2l")
857+
858+
check_lines({
859+
"function x() {",
860+
"local xyz = 3",
861+
"print('DEBUG[1]: " .. filename .. ":2: xy=' .. vim.inspect(xy))",
862+
"end",
863+
})
864+
end)
865+
866+
it("repeat", function()
867+
debugprint.setup({ ignore_treesitter = true })
868+
869+
set_lines({
870+
"function x() {",
871+
"local xyz = 3",
872+
"end",
873+
})
874+
875+
local filename = write_file("lua")
876+
vim.api.nvim_win_set_cursor(0, { 2, 6 })
877+
feedkeys("g?o2l.")
878+
879+
check_lines({
880+
"function x() {",
881+
"local xyz = 3",
882+
"print('DEBUG[2]: " .. filename .. ":2: xy=' .. vim.inspect(xy))",
883+
"print('DEBUG[1]: " .. filename .. ":2: xy=' .. vim.inspect(xy))",
884+
"end",
885+
})
886+
end)
887+
888+
it("above", function()
889+
debugprint.setup({ ignore_treesitter = true })
890+
891+
set_lines({
892+
"function x() {",
893+
"local xyz = 3",
894+
"end",
895+
})
896+
897+
local filename = write_file("lua")
898+
vim.api.nvim_win_set_cursor(0, { 2, 6 })
899+
feedkeys("g?Oiw")
900+
901+
check_lines({
902+
"function x() {",
903+
" print('DEBUG[1]: " .. filename .. ":2: xyz=' .. vim.inspect(xyz))",
904+
"local xyz = 3",
905+
"end",
906+
})
907+
end)
908+
909+
it("repeat", function()
910+
debugprint.setup({ ignore_treesitter = true })
911+
912+
set_lines({
913+
"function x() {",
914+
"local xyz = 3",
915+
"end",
916+
})
917+
918+
local filename = write_file("lua")
919+
vim.api.nvim_win_set_cursor(0, { 2, 6 })
920+
feedkeys("g?oiw")
921+
feedkeys("j.")
922+
923+
check_lines({
924+
"function x() {",
925+
"local xyz = 3",
926+
"print('DEBUG[1]: " .. filename .. ":2: xyz=' .. vim.inspect(xyz))",
927+
"print('DEBUG[2]: " .. filename .. ":3: xyz=' .. vim.inspect(xyz))",
928+
"end",
929+
})
930+
end)
931+
932+
it("ignore multiline", function()
933+
debugprint.setup({ ignore_treesitter = true })
934+
935+
set_lines({
936+
"function x() {",
937+
"local xyz = 3",
938+
"end",
939+
})
940+
941+
write_file("lua")
942+
vim.api.nvim_win_set_cursor(0, { 1, 1 })
943+
feedkeys("g?oj")
944+
945+
assert.are.same(
946+
"debugprint not supported when multiple lines in motion.",
947+
notify_message
948+
)
949+
end)
950+
end)

0 commit comments

Comments
 (0)