Skip to content

Commit

Permalink
Merge pull request #20 from julienvincent/jv/deletions
Browse files Browse the repository at this point in the history
Add API's for various deletion operations
  • Loading branch information
julienvincent authored Aug 12, 2023
2 parents a5b1441 + 041039b commit 16747c3
Show file tree
Hide file tree
Showing 4 changed files with 324 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ paredit.api.slurp_forwards()
- **`drag_form_backwards`**
- **`raise_element`**
- **`raise_form`**
- **`delete_form`**
- **`delete_in_form`**
- **`delete_element`**
- **`move_to_next_element`**
- **`move_to_prev_element`**

Expand Down
74 changes: 74 additions & 0 deletions lua/nvim-paredit/api/deletions.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
local traversal = require("nvim-paredit.utils.traversal")
local ts = require("nvim-treesitter.ts_utils")
local langs = require("nvim-paredit.lang")

local M = {}

function M.delete_form()
local lang = langs.get_language_api()
local current_form = traversal.find_nearest_form(ts.get_node_at_cursor(), {
lang = lang,
use_source = false,
})
if not current_form then
return
end

local root = lang.get_node_root(current_form)
local range = { root:range() }

local buf = vim.api.nvim_get_current_buf()
-- stylua: ignore
vim.api.nvim_buf_set_text(
buf,
range[1], range[2],
range[3], range[4],
{}
)
end

function M.delete_in_form()
local lang = langs.get_language_api()
local current_form = traversal.find_nearest_form(ts.get_node_at_cursor(), {
lang = lang,
use_source = false,
})
if not current_form then
return
end

local edges = lang.get_form_edges(current_form)

local buf = vim.api.nvim_get_current_buf()
-- stylua: ignore
vim.api.nvim_buf_set_text(
buf,
edges.left.range[3], edges.left.range[4],
edges.right.range[1], edges.right.range[2],
{}
)

vim.api.nvim_win_set_cursor(0, { edges.left.range[3] + 1, edges.left.range[4] })
end

function M.delete_element()
local lang = langs.get_language_api()
local node = ts.get_node_at_cursor()
if not node then
return
end

local root = lang.get_node_root(node)
local range = { root:range() }

local buf = vim.api.nvim_get_current_buf()
-- stylua: ignore
vim.api.nvim_buf_set_text(
buf,
range[1], range[2],
range[3], range[4],
{}
)
end

return M
5 changes: 5 additions & 0 deletions lua/nvim-paredit/api/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local barfing = require("nvim-paredit.api.barfing")
local dragging = require("nvim-paredit.api.dragging")
local raising = require("nvim-paredit.api.raising")
local motions = require("nvim-paredit.api.motions")
local deletions = require("nvim-paredit.api.deletions")

local M = {
slurp_forwards = slurping.slurp_forwards,
Expand All @@ -20,6 +21,10 @@ local M = {

move_to_next_element = motions.move_to_next_element,
move_to_prev_element = motions.move_to_prev_element,

delete_form = deletions.delete_form,
delete_in_form = deletions.delete_in_form,
delete_element = deletions.delete_element,
}

return M
242 changes: 242 additions & 0 deletions tests/nvim-paredit/deletions_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
local paredit = require("nvim-paredit.api")

local prepare_buffer = require("tests.nvim-paredit.utils").prepare_buffer
local expect_all = require("tests.nvim-paredit.utils").expect_all
local expect = require("tests.nvim-paredit.utils").expect

describe("form deletions", function()
vim.api.nvim_buf_set_option(0, "filetype", "clojure")

it("should delete the form", function()
prepare_buffer({
content = "(a)",
cursor = { 1, 1 },
})
paredit.delete_form()
expect({
content = "",
cursor = { 1, 0 },
})
end)

it("should delete a multi line form", function()
prepare_buffer({
content = { "(a", "b", "c)" },
cursor = { 1, 1 },
})
paredit.delete_form()
expect({
content = "",
cursor = { 1, 0 },
})
end)

it("should delete a nested form", function()
prepare_buffer({
content = "(a (a b c))",
cursor = { 1, 5 },
})
paredit.delete_form()
expect({
content = "(a )",
cursor = { 1, 3 },
})
end)

it("should delete different form types", function()
expect_all(paredit.delete_form, {
{
"list",
before_content = "(a)",
before_cursor = { 1, 1 },
after_content = "",
after_cursor = { 1, 0 },
},
{
"vector",
before_content = "[a]",
before_cursor = { 1, 1 },
after_content = "",
after_cursor = { 1, 0 },
},
{
"quoted list",
before_content = "`(a)",
before_cursor = { 1, 2 },
after_content = "",
after_cursor = { 1, 0 },
},
{
"quoted list",
before_content = "'(a)",
before_cursor = { 1, 2 },
after_content = "",
after_cursor = { 1, 0 },
},
{
"anon fn",
before_content = "#(a)",
before_cursor = { 1, 2 },
after_content = "",
after_cursor = { 1, 0 },
},
{
"set",
before_content = "#{a}",
before_cursor = { 1, 2 },
after_content = "",
after_cursor = { 1, 0 },
},
})
end)
end)

describe("form inner deletions", function()
vim.api.nvim_buf_set_option(0, "filetype", "clojure")

it("should delete everything in the form", function()
prepare_buffer({
content = "(a b)",
cursor = { 1, 2 },
})
paredit.delete_in_form()
expect({
content = "()",
cursor = { 1, 1 },
})
end)

it("should delete everything within a multi line form", function()
prepare_buffer({
content = { "(a", "b", "c)" },
cursor = { 2, 0 },
})
paredit.delete_in_form()
expect({
content = "()",
cursor = { 1, 1 },
})
end)

it("should delete everyting within a nested form", function()
prepare_buffer({
content = "(a (a b c))",
cursor = { 1, 5 },
})
paredit.delete_in_form()
expect({
content = "(a ())",
cursor = { 1, 4 },
})
end)

it("should delete within different form types", function()
expect_all(paredit.delete_in_form, {
{
"list",
before_content = "(a)",
before_cursor = { 1, 1 },
after_content = "()",
after_cursor = { 1, 1 },
},
{
"vector",
before_content = "[a]",
before_cursor = { 1, 1 },
after_content = "[]",
after_cursor = { 1, 1 },
},
{
"quoted list",
before_content = "`(a)",
before_cursor = { 1, 2 },
after_content = "`()",
after_cursor = { 1, 2 },
},
{
"quoted list",
before_content = "'(a)",
before_cursor = { 1, 2 },
after_content = "'()",
after_cursor = { 1, 2 },
},
{
"anon fn",
before_content = "#(a)",
before_cursor = { 1, 2 },
after_content = "#()",
after_cursor = { 1, 2 },
},
{
"set",
before_content = "#{a}",
before_cursor = { 1, 2 },
after_content = "#{}",
after_cursor = { 1, 2 },
},
})
end)
end)

describe("element deletions", function()
vim.api.nvim_buf_set_option(0, "filetype", "clojure")

it("should delete the element under cursor", function()
prepare_buffer({
content = "(ab cd)",
cursor = { 1, 4 },
})
paredit.delete_element()
expect({
content = "(ab )",
cursor = { 1, 4 },
})
end)

it("should delete different element types", function()
expect_all(paredit.delete_element, {
{
"list",
before_content = "(a)",
before_cursor = { 1, 0 },
after_content = "",
after_cursor = { 1, 0 },
},
{
"vector",
before_content = "[a]",
before_cursor = { 1, 0 },
after_content = "",
after_cursor = { 1, 0 },
},
{
"quoted list",
before_content = "`(a)",
before_cursor = { 1, 0 },
after_content = "",
after_cursor = { 1, 0 },
},
{
"quoted list",
before_content = "'(a)",
before_cursor = { 1, 0 },
after_content = "",
after_cursor = { 1, 0 },
},
{
"anon fn",
before_content = "#(a)",
before_cursor = { 1, 0 },
after_content = "",
after_cursor = { 1, 0 },
},
{
"set",
before_content = "#{a}",
before_cursor = { 1, 0 },
after_content = "",
after_cursor = { 1, 0 },
},
})
end)
end)

0 comments on commit 16747c3

Please sign in to comment.