Skip to content

Commit 3237777

Browse files
Merge pull request #22 from julienvincent/simplify-keymap-settings
Replace `operator` keymap field with smarter funcs
2 parents bdd11cb + 51a3c40 commit 3237777

File tree

7 files changed

+75
-47
lines changed

7 files changed

+75
-47
lines changed

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,26 +73,28 @@ require("nvim-paredit").setup({
7373
paredit.api.move_to_next_element,
7474
"Jump to next element tail",
7575
-- by default all keybindings are dot repeatable
76-
repeatable = false
76+
repeatable = false,
77+
mode = { "n", "x", "o", "v" },
7778
},
7879
["B"] = {
7980
paredit.api.move_to_prev_element,
8081
"Jump to previous element head",
81-
repeatable = false
82+
repeatable = false,
83+
mode = { "n", "x", "o", "v" },
8284
},
8385

84-
-- These are text object selection keybindings which can used with standard `d, y, c`
86+
-- These are text object selection keybindings which can used with standard `d, y, c`, `v`
8587
["af"] = {
8688
api.select_around_form,
8789
"Around form",
8890
repeatable = false,
89-
mode = { "o" }
91+
mode = { "o", "v" }
9092
},
9193
["if"] = {
9294
api.select_in_form,
9395
"In form",
9496
repeatable = false,
95-
mode = { "o" }
97+
mode = { "o", "v" }
9698
},
9799
}
98100
})

lua/nvim-paredit/api/motions.lua

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,25 @@ function M._move_to_element(count, reversed)
124124
vim.api.nvim_win_set_cursor(0, cursor_pos)
125125
end
126126

127+
-- When in operator-pending mode (`o` or `no`) then we need to switch to
128+
-- visual mode in order for the operator to apply over a range of text.
129+
local function ensure_visual_if_operator_pending()
130+
local mode = vim.api.nvim_get_mode().mode
131+
if mode == "o" or mode == "no" then
132+
common.ensure_visual_mode()
133+
end
134+
end
135+
127136
function M.move_to_prev_element()
128-
M._move_to_element(vim.v.count1, true)
137+
local count = vim.v.count1
138+
ensure_visual_if_operator_pending()
139+
M._move_to_element(count, true)
129140
end
130141

131142
function M.move_to_next_element()
132-
M._move_to_element(vim.v.count1, false)
143+
local count = vim.v.count1
144+
ensure_visual_if_operator_pending()
145+
M._move_to_element(count, false)
133146
end
134147

135148
return M

lua/nvim-paredit/defaults.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,26 @@ M.default_keys = {
2222
api.move_to_next_element,
2323
"Next element tail",
2424
repeatable = false,
25-
operator = true,
25+
mode = { "n", "x", "o", "v" },
2626
},
2727
["B"] = {
2828
api.move_to_prev_element,
2929
"Previous element head",
3030
repeatable = false,
31-
operator = true,
31+
mode = { "n", "x", "o", "v" },
3232
},
3333

3434
["af"] = {
3535
api.select_around_form,
3636
"Around form",
3737
repeatable = false,
38-
mode = { "o", "v" }
38+
mode = { "o", "v" },
3939
},
4040
["if"] = {
4141
api.select_in_form,
4242
"In form",
4343
repeatable = false,
44-
mode = { "o", "v" }
44+
mode = { "o", "v" },
4545
},
4646
}
4747

lua/nvim-paredit/utils/common.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,11 @@ function M.intersection(tbl, original)
5959
return result
6060
end
6161

62+
function M.ensure_visual_mode()
63+
if vim.api.nvim_get_mode().mode ~= "v" then
64+
vim.api.nvim_command("normal! v")
65+
end
66+
end
67+
6268
return M
6369

lua/nvim-paredit/utils/keybindings.lua

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,12 @@ function M.with_repeat(fn)
1717
end
1818
end
1919

20-
-- we wrap motion keys with visual mode for operator mode
21-
-- such that dE/cE becomes dvE/cvE
22-
function M.visualize(fn)
23-
return function()
24-
vim.api.nvim_command("normal! v")
25-
fn()
26-
end
27-
end
28-
2920
function M.setup_keybindings(opts)
3021
for keymap, action in pairs(opts.keys) do
3122
local repeatable = true
32-
local operator = false
3323
if type(action.repeatable) == "boolean" then
3424
repeatable = action.repeatable
3525
end
36-
if type(action.operator) == "boolean" then
37-
operator = action.operator
38-
end
3926

4027
local fn = action[1]
4128
if repeatable then
@@ -49,16 +36,6 @@ function M.setup_keybindings(opts)
4936
remap = false,
5037
silent = true,
5138
})
52-
53-
if operator then
54-
vim.keymap.set("o", keymap, M.visualize(fn), {
55-
desc = action[2],
56-
buffer = opts.buf or 0,
57-
expr = repeatable,
58-
remap = false,
59-
silent = true,
60-
})
61-
end
6239
end
6340
end
6441

tests/nvim-paredit/operator_motion_spec.lua

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ local prepare_buffer = require("tests.nvim-paredit.utils").prepare_buffer
22
local feedkeys = require("tests.nvim-paredit.utils").feedkeys
33
local expect = require("tests.nvim-paredit.utils").expect
44
local keybindings = require("nvim-paredit.utils.keybindings")
5-
local motions = require("nvim-paredit.api.motions")
65

7-
local next_element = keybindings.visualize(motions.move_to_next_element)
8-
local prev_element = keybindings.visualize(motions.move_to_prev_element)
6+
local defaults = require("nvim-paredit.defaults")
97

108
describe("motions with operator pending", function()
119
before_each(function()
12-
vim.keymap.set("o", "E", next_element, { buffer = true })
13-
vim.keymap.set("o", "B", prev_element, { buffer = true })
10+
keybindings.setup_keybindings({
11+
keys = defaults.default_keys
12+
})
1413
end)
1514

1615
it("should delete next form", function()
@@ -87,8 +86,36 @@ describe("motions with operator pending", function()
8786
cursor = { 1, 4 },
8887
})
8988
end)
90-
after_each(function()
91-
vim.keymap.del("o", "E")
92-
vim.keymap.del("o", "B")
89+
end)
90+
91+
describe("motions with operator pending and v:count", function()
92+
before_each(function()
93+
keybindings.setup_keybindings({
94+
keys = defaults.default_keys
95+
})
96+
end)
97+
98+
it("should delete the next 2 elements", function()
99+
prepare_buffer({
100+
content = "(aa bb cc)",
101+
cursor = { 1, 4 },
102+
})
103+
feedkeys("d2<S-e>")
104+
expect({
105+
content = "(aa )",
106+
cursor = { 1, 4 },
107+
})
108+
end)
109+
110+
it("should delete the previous 2 elements", function()
111+
prepare_buffer({
112+
content = "(aa bb cc)",
113+
cursor = { 1, 8 },
114+
})
115+
feedkeys("d2<S-b>")
116+
expect({
117+
content = "(aa )",
118+
cursor = { 1, 4 },
119+
})
93120
end)
94121
end)

tests/nvim-paredit/text_object_selections_spec.lua

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
local paredit = require("nvim-paredit.api")
1+
local keybindings = require("nvim-paredit.utils.keybindings")
2+
local defaults = require("nvim-paredit.defaults")
23

34
local prepare_buffer = require("tests.nvim-paredit.utils").prepare_buffer
45
local feedkeys = require("tests.nvim-paredit.utils").feedkeys
@@ -9,8 +10,9 @@ describe("form deletions", function()
910
vim.api.nvim_buf_set_option(0, "filetype", "clojure")
1011

1112
before_each(function()
12-
vim.keymap.set("o", "af", paredit.select_around_form, { buffer = true, remap = false })
13-
vim.keymap.set("o", "if", paredit.select_in_form, { buffer = true, remap = false })
13+
keybindings.setup_keybindings({
14+
keys = defaults.default_keys,
15+
})
1416
end)
1517

1618
it("should delete the form", function()
@@ -78,8 +80,9 @@ describe("form selections", function()
7880
vim.api.nvim_buf_set_option(0, "filetype", "clojure")
7981

8082
before_each(function()
81-
vim.keymap.set("v", "af", paredit.select_around_form, { buffer = true, remap = false })
82-
vim.keymap.set("v", "if", paredit.select_in_form, { buffer = true, remap = false })
83+
keybindings.setup_keybindings({
84+
keys = defaults.default_keys,
85+
})
8386
end)
8487

8588
it("should select the form", function()

0 commit comments

Comments
 (0)