From 879e2b4970aed169d28c31e5d9b1873e2e1086d0 Mon Sep 17 00:00:00 2001 From: Artem Medeu Date: Sun, 15 Oct 2023 13:17:38 +0600 Subject: [PATCH 1/4] fixes #43 unwrap/splice sexp --- README.md | 12 +++++- lua/nvim-paredit/api/unwrap.lua | 47 +++++++++++++++++++++ lua/nvim-paredit/init.lua | 1 + tests/nvim-paredit/form_unwrap_spec.lua | 56 +++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 lua/nvim-paredit/api/unwrap.lua create mode 100644 tests/nvim-paredit/form_unwrap_spec.lua diff --git a/README.md b/README.md index 27c263b..0c9ad59 100644 --- a/README.md +++ b/README.md @@ -327,13 +327,13 @@ Cursor api `paredit.cursor` - `placement` - enumeration `left_edge`,`inner_start`,`inner_end`,`right_edge` - `mode` - currently only `insert` is supported, defaults to `normal` -## API usage recipes +## Additional API usage recipes ### `vim-sexp` wrap form (head/tail) replication Require api module: ```lua -local paredit = require("nvim-paredit.api") +local paredit = require("nvim-paredit") ``` Add following keybindings to config: ```lua @@ -383,6 +383,14 @@ Add following keybindings to config: ``` Same approach can be used for other `vim-sexp` keybindings (e.g. `e[`) with cursor placement or without. +### `vim-sexp` splice sexp + +```lua + ["@"] = { + paredit.unwrap.unwrap_form_under_cursor, + "Splice sexp", + }, +``` ## Prior Art ### [vim-sexp](https://github.com/guns/vim-sexp) diff --git a/lua/nvim-paredit/api/unwrap.lua b/lua/nvim-paredit/api/unwrap.lua new file mode 100644 index 0000000..ab7dbc5 --- /dev/null +++ b/lua/nvim-paredit/api/unwrap.lua @@ -0,0 +1,47 @@ +local traversal = require("nvim-paredit.utils.traversal") +local langs = require("nvim-paredit.lang") +local ts = require("nvim-treesitter.ts_utils") + +local M = {} + +function M.unwrap_form(buf, form) + local lang = langs.get_language_api() + local edges = lang.get_form_edges(form) + local left = edges.left + local right = edges.right + vim.api.nvim_buf_set_text( + buf, + right.range[1], + right.range[2], + right.range[3], + right.range[4], + { "" } + ) + vim.api.nvim_buf_set_text( + buf, + left.range[1], + left.range[2], + left.range[3], + left.range[4], + { "" } + ) +end + +function M.unwrap_form_under_cursor() + local buf = vim.api.nvim_get_current_buf() + local lang = langs.get_language_api() + local node = ts.get_node_at_cursor() + local current_element = lang.get_node_root(node) + local form = traversal.find_nearest_form( + current_element, + { lang = lang, use_source = false } + ) + if not form then + return false + end + + M.unwrap_form(buf, form) + return true +end + +return M diff --git a/lua/nvim-paredit/init.lua b/lua/nvim-paredit/init.lua index 64b0895..66437b6 100644 --- a/lua/nvim-paredit/init.lua +++ b/lua/nvim-paredit/init.lua @@ -33,6 +33,7 @@ end local M = { api = require("nvim-paredit.api"), wrap = require("nvim-paredit.api.wrap"), + unwrap = require("nvim-paredit.api.unwrap"), cursor = require("nvim-paredit.api.cursor"), extension = { add_language_extension = add_language_extension, diff --git a/tests/nvim-paredit/form_unwrap_spec.lua b/tests/nvim-paredit/form_unwrap_spec.lua new file mode 100644 index 0000000..768c745 --- /dev/null +++ b/tests/nvim-paredit/form_unwrap_spec.lua @@ -0,0 +1,56 @@ +local paredit = require("nvim-paredit") +local prepare_buffer = require("tests.nvim-paredit.utils").prepare_buffer +local expect = require("tests.nvim-paredit.utils").expect + +describe("form uwrap (e.g. splice)", function() + vim.api.nvim_buf_set_option(0, "filetype", "clojure") + local unwrap = paredit.unwrap + + it("should uwrap list under cursor", function() + prepare_buffer({ + content = { "(+ 2 :foo/bar)" }, + cursor = { 1, 0 }, + }) + + unwrap.unwrap_form_under_cursor() + expect({ + content = { "+ 2 :foo/bar" }, + }) + end) + + it("should uwrap list under cursor", function() + prepare_buffer({ + content = { "(+ 2 :foo/bar)" }, + cursor = { 1, 13 }, + }) + + unwrap.unwrap_form_under_cursor() + expect({ + content = { "+ 2 :foo/bar" }, + }) + end) + + it("should uwrap set under cursor", function() + prepare_buffer({ + content = { "#{1 2 3}" }, + cursor = { 1, 4 }, + }) + + unwrap.unwrap_form_under_cursor() + expect({ + content = { "1 2 3" }, + }) + end) + + it("should uwrap fn under cursor", function() + prepare_buffer({ + content = { "#(+ % 2 3)" }, + cursor = { 1, 4 }, + }) + + unwrap.unwrap_form_under_cursor() + expect({ + content = { "+ % 2 3" }, + }) + end) +end) From 2f0628e4379d357f0a5a51981c56ab40047d0b0b Mon Sep 17 00:00:00 2001 From: Artem Medeu Date: Mon, 16 Oct 2023 18:49:29 +0600 Subject: [PATCH 2/4] fix: add splice key to defaults --- lua/nvim-paredit/defaults.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lua/nvim-paredit/defaults.lua b/lua/nvim-paredit/defaults.lua index 972bb7c..03eb727 100644 --- a/lua/nvim-paredit/defaults.lua +++ b/lua/nvim-paredit/defaults.lua @@ -1,8 +1,11 @@ local api = require("nvim-paredit.api") +local unwrap = require("nvim-paredit.api.unwrap") local M = {} M.default_keys = { + ["@"] = { unwrap.unwrap_form_under_cursor, "Splice sexp", }, + [">)"] = { api.slurp_forwards, "Slurp forwards" }, [">("] = { api.barf_backwards, "Barf backwards" }, From f0575390af0128c3fb3928312579449eeea82973 Mon Sep 17 00:00:00 2001 From: Artem Medeu Date: Mon, 16 Oct 2023 18:55:31 +0600 Subject: [PATCH 3/4] chore: update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0c9ad59..13dc6b0 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ paredit.setup({ -- list of default keybindings keys = { + ["@"] = { paredit.unwrap.unwrap_form_under_cursor, "Splice sexp" }, [">)"] = { paredit.api.slurp_forwards, "Slurp forwards" }, [">("] = { paredit.api.barf_backwards, "Barf backwards" }, From 262a0ef74ff40705654b95e88a07270100b306e4 Mon Sep 17 00:00:00 2001 From: Artem Medeu Date: Mon, 16 Oct 2023 18:58:30 +0600 Subject: [PATCH 4/4] chore: update readme --- README.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/README.md b/README.md index 13dc6b0..217d5fc 100644 --- a/README.md +++ b/README.md @@ -384,14 +384,6 @@ Add following keybindings to config: ``` Same approach can be used for other `vim-sexp` keybindings (e.g. `e[`) with cursor placement or without. -### `vim-sexp` splice sexp - -```lua - ["@"] = { - paredit.unwrap.unwrap_form_under_cursor, - "Splice sexp", - }, -``` ## Prior Art ### [vim-sexp](https://github.com/guns/vim-sexp)