Skip to content

Commit

Permalink
Merge pull request #22 from julienvincent/simplify-keymap-settings
Browse files Browse the repository at this point in the history
Replace `operator` keymap field with smarter funcs
  • Loading branch information
julienvincent authored Aug 12, 2023
2 parents bdd11cb + 51a3c40 commit 3237777
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 47 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,26 +73,28 @@ require("nvim-paredit").setup({
paredit.api.move_to_next_element,
"Jump to next element tail",
-- by default all keybindings are dot repeatable
repeatable = false
repeatable = false,
mode = { "n", "x", "o", "v" },
},
["B"] = {
paredit.api.move_to_prev_element,
"Jump to previous element head",
repeatable = false
repeatable = false,
mode = { "n", "x", "o", "v" },
},

-- These are text object selection keybindings which can used with standard `d, y, c`
-- These are text object selection keybindings which can used with standard `d, y, c`, `v`
["af"] = {
api.select_around_form,
"Around form",
repeatable = false,
mode = { "o" }
mode = { "o", "v" }
},
["if"] = {
api.select_in_form,
"In form",
repeatable = false,
mode = { "o" }
mode = { "o", "v" }
},
}
})
Expand Down
17 changes: 15 additions & 2 deletions lua/nvim-paredit/api/motions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,25 @@ function M._move_to_element(count, reversed)
vim.api.nvim_win_set_cursor(0, cursor_pos)
end

-- When in operator-pending mode (`o` or `no`) then we need to switch to
-- visual mode in order for the operator to apply over a range of text.
local function ensure_visual_if_operator_pending()
local mode = vim.api.nvim_get_mode().mode
if mode == "o" or mode == "no" then
common.ensure_visual_mode()
end
end

function M.move_to_prev_element()
M._move_to_element(vim.v.count1, true)
local count = vim.v.count1
ensure_visual_if_operator_pending()
M._move_to_element(count, true)
end

function M.move_to_next_element()
M._move_to_element(vim.v.count1, false)
local count = vim.v.count1
ensure_visual_if_operator_pending()
M._move_to_element(count, false)
end

return M
8 changes: 4 additions & 4 deletions lua/nvim-paredit/defaults.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,26 @@ M.default_keys = {
api.move_to_next_element,
"Next element tail",
repeatable = false,
operator = true,
mode = { "n", "x", "o", "v" },
},
["B"] = {
api.move_to_prev_element,
"Previous element head",
repeatable = false,
operator = true,
mode = { "n", "x", "o", "v" },
},

["af"] = {
api.select_around_form,
"Around form",
repeatable = false,
mode = { "o", "v" }
mode = { "o", "v" },
},
["if"] = {
api.select_in_form,
"In form",
repeatable = false,
mode = { "o", "v" }
mode = { "o", "v" },
},
}

Expand Down
6 changes: 6 additions & 0 deletions lua/nvim-paredit/utils/common.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,11 @@ function M.intersection(tbl, original)
return result
end

function M.ensure_visual_mode()
if vim.api.nvim_get_mode().mode ~= "v" then
vim.api.nvim_command("normal! v")
end
end

return M

23 changes: 0 additions & 23 deletions lua/nvim-paredit/utils/keybindings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,12 @@ function M.with_repeat(fn)
end
end

-- we wrap motion keys with visual mode for operator mode
-- such that dE/cE becomes dvE/cvE
function M.visualize(fn)
return function()
vim.api.nvim_command("normal! v")
fn()
end
end

function M.setup_keybindings(opts)
for keymap, action in pairs(opts.keys) do
local repeatable = true
local operator = false
if type(action.repeatable) == "boolean" then
repeatable = action.repeatable
end
if type(action.operator) == "boolean" then
operator = action.operator
end

local fn = action[1]
if repeatable then
Expand All @@ -49,16 +36,6 @@ function M.setup_keybindings(opts)
remap = false,
silent = true,
})

if operator then
vim.keymap.set("o", keymap, M.visualize(fn), {
desc = action[2],
buffer = opts.buf or 0,
expr = repeatable,
remap = false,
silent = true,
})
end
end
end

Expand Down
43 changes: 35 additions & 8 deletions tests/nvim-paredit/operator_motion_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ local prepare_buffer = require("tests.nvim-paredit.utils").prepare_buffer
local feedkeys = require("tests.nvim-paredit.utils").feedkeys
local expect = require("tests.nvim-paredit.utils").expect
local keybindings = require("nvim-paredit.utils.keybindings")
local motions = require("nvim-paredit.api.motions")

local next_element = keybindings.visualize(motions.move_to_next_element)
local prev_element = keybindings.visualize(motions.move_to_prev_element)
local defaults = require("nvim-paredit.defaults")

describe("motions with operator pending", function()
before_each(function()
vim.keymap.set("o", "E", next_element, { buffer = true })
vim.keymap.set("o", "B", prev_element, { buffer = true })
keybindings.setup_keybindings({
keys = defaults.default_keys
})
end)

it("should delete next form", function()
Expand Down Expand Up @@ -87,8 +86,36 @@ describe("motions with operator pending", function()
cursor = { 1, 4 },
})
end)
after_each(function()
vim.keymap.del("o", "E")
vim.keymap.del("o", "B")
end)

describe("motions with operator pending and v:count", function()
before_each(function()
keybindings.setup_keybindings({
keys = defaults.default_keys
})
end)

it("should delete the next 2 elements", function()
prepare_buffer({
content = "(aa bb cc)",
cursor = { 1, 4 },
})
feedkeys("d2<S-e>")
expect({
content = "(aa )",
cursor = { 1, 4 },
})
end)

it("should delete the previous 2 elements", function()
prepare_buffer({
content = "(aa bb cc)",
cursor = { 1, 8 },
})
feedkeys("d2<S-b>")
expect({
content = "(aa )",
cursor = { 1, 4 },
})
end)
end)
13 changes: 8 additions & 5 deletions tests/nvim-paredit/text_object_selections_spec.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local paredit = require("nvim-paredit.api")
local keybindings = require("nvim-paredit.utils.keybindings")
local defaults = require("nvim-paredit.defaults")

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

before_each(function()
vim.keymap.set("o", "af", paredit.select_around_form, { buffer = true, remap = false })
vim.keymap.set("o", "if", paredit.select_in_form, { buffer = true, remap = false })
keybindings.setup_keybindings({
keys = defaults.default_keys,
})
end)

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

before_each(function()
vim.keymap.set("v", "af", paredit.select_around_form, { buffer = true, remap = false })
vim.keymap.set("v", "if", paredit.select_in_form, { buffer = true, remap = false })
keybindings.setup_keybindings({
keys = defaults.default_keys,
})
end)

it("should select the form", function()
Expand Down

0 comments on commit 3237777

Please sign in to comment.