From bd1a28f7a69601e8a7b4522e50e62f9949ce9409 Mon Sep 17 00:00:00 2001 From: Kyle Grierson Date: Tue, 15 Aug 2023 06:42:11 +0100 Subject: [PATCH] wrap and insertion --- fnl/formedit/find.fnl | 36 ++++++++++++++++++++++++ fnl/formedit/insertion.fnl | 23 ++++++++++++++++ fnl/formedit/select.fnl | 45 ++++-------------------------- fnl/formedit/wrap.fnl | 17 ++++++++++++ fnl/spec/delete_around_spec.fnl | 4 +-- fnl/spec/helper.fnl | 6 ++-- fnl/spec/insertion_spec.fnl | 38 +++++++++++++++++++++++++ fnl/spec/wrap_form_spec.fnl | 21 ++++++++++++++ lua/formedit/find.lua | 31 +++++++++++++++++++++ lua/formedit/insertion.lua | 35 +++++++++++++++++++++++ lua/formedit/select.lua | 43 ++++++----------------------- lua/formedit/wrap.lua | 25 +++++++++++++++++ lua/spec/delete_around_spec.lua | 4 +-- lua/spec/helper.lua | 7 ++++- lua/spec/insertion_spec.lua | 49 +++++++++++++++++++++++++++++++++ lua/spec/wrap_form_spec.lua | 28 +++++++++++++++++++ 16 files changed, 331 insertions(+), 81 deletions(-) create mode 100644 fnl/formedit/find.fnl create mode 100644 fnl/formedit/insertion.fnl create mode 100644 fnl/formedit/wrap.fnl create mode 100644 fnl/spec/insertion_spec.fnl create mode 100644 fnl/spec/wrap_form_spec.fnl create mode 100644 lua/formedit/find.lua create mode 100644 lua/formedit/insertion.lua create mode 100644 lua/formedit/wrap.lua create mode 100644 lua/spec/insertion_spec.lua create mode 100644 lua/spec/wrap_form_spec.lua diff --git a/fnl/formedit/find.fnl b/fnl/formedit/find.fnl new file mode 100644 index 0000000..eadd9e9 --- /dev/null +++ b/fnl/formedit/find.fnl @@ -0,0 +1,36 @@ +(local ts (require :nvim-treesitter.ts_utils)) + +(local forms {:list_lit true + :vec_lit true + :map_lit true + :set_lit true + :anon_fn_lit true}) + +;; Tree search +(fn find-current-form [node] + (if (. forms (node:type)) + node + (let [parent (node:parent)] + (when parent (find-current-form parent))))) + +(fn find-root-form [node] + (if (node:parent) + (find-root-form (node:parent)) + node)) + +;; Find node +(fn form [] + (let [node (ts.get_node_at_cursor)] + (find-current-form node))) + +(fn root [] + (let [node (ts.get_node_at_cursor)] + (find-root-form node))) + +; (fn get-inner-form [] +; (let [form (get-current-form) +; [open-row open-col] [(: (. (form:field :open) 1) :end_)] +; [end-row end-col] [(: (. (form:field :close) 1) :start)]] +; [open-row open-col end-row end-col])) + +{: form : root} diff --git a/fnl/formedit/insertion.fnl b/fnl/formedit/insertion.fnl new file mode 100644 index 0000000..aafeb4e --- /dev/null +++ b/fnl/formedit/insertion.fnl @@ -0,0 +1,23 @@ +(local find (require :formedit.find)) + +(fn range [form] + (let [[start-row start-col end-row end-col] [(form:range)]] + [(+ start-row 1) start-col (+ end-row 1) end-col])) + +(fn head [] + (let [form (find.form) + [start-row start-col _ _] (range form)] + (vim.api.nvim_win_set_cursor 0 [start-row start-col]) + (vim.api.nvim_command "normal! a ") + (vim.api.nvim_win_set_cursor 0 [start-row start-col]) + (vim.api.nvim_feedkeys :i :n true))) + +(fn tail [] + (let [form (find.form) + [_ _ end-row end-col] (range form)] + (vim.api.nvim_win_set_cursor 0 [end-row (- end-col 1)]) + (vim.api.nvim_command "normal! i ") + (vim.api.nvim_win_set_cursor 0 [end-row end-col]) + (vim.api.nvim_feedkeys :i :n true))) + +{: head : tail} diff --git a/fnl/formedit/select.fnl b/fnl/formedit/select.fnl index 86bff60..d57d274 100644 --- a/fnl/formedit/select.fnl +++ b/fnl/formedit/select.fnl @@ -1,45 +1,12 @@ (local ts (require :nvim-treesitter.ts_utils)) +(local find (require :formedit.find)) -(local forms {:list_lit true - :vec_lit true - :map_lit true - :set_lit true - :anon_fn_lit true}) - -;; Tree search -(fn find-current-form [node] - (if (. forms (node:type)) - node - (let [parent (node:parent)] - (when parent (find-current-form parent))))) - -(fn find-root-form [node] - (if (node:parent) - (find-root-form (node:parent)) - node)) - -;; Find node -(fn get-current-form [] - (let [node (ts.get_node_at_cursor)] - (find-current-form node))) - -(fn get-current-root-form [] - (let [node (ts.get_node_at_cursor)] - (find-root-form node))) - -; (fn get-inner-form [] -; (let [form (get-current-form) -; [open-row open-col] [(: (. (form:field :open) 1) :end_)] -; [end-row end-col] [(: (. (form:field :close) 1) :start)]] -; [open-row open-col end-row end-col])) - -;; Select node -(fn select-form [] - (let [form (get-current-form)] +(fn form [] + (let [form (find.form)] (ts.update_selection 0 form))) -(fn select-root-form [] - (let [form (get-current-root-form)] +(fn root [] + (let [form (find.root)] (ts.update_selection 0 form))) -{: get-current-form : select-form : select-root-form} +{: form : root} diff --git a/fnl/formedit/wrap.fnl b/fnl/formedit/wrap.fnl new file mode 100644 index 0000000..b83e2e3 --- /dev/null +++ b/fnl/formedit/wrap.fnl @@ -0,0 +1,17 @@ +(local find (require :formedit.find)) + +(fn range [form] + (let [[start-row start-col end-row end-col] [(form:range)]] + [(+ start-row 1) start-col (+ end-row 1) end-col])) + +(fn form-head [] + (let [form (find.form) + [start-row start-col end-row end-col] (range form)] + (vim.api.nvim_win_set_cursor 0 [end-row end-col]) + (vim.api.nvim_command "normal! i)") + (vim.api.nvim_win_set_cursor 0 [start-row start-col]) + (vim.api.nvim_command "normal! i( ") + (vim.api.nvim_win_set_cursor 0 [start-row start-col]) + (vim.api.nvim_feedkeys :i :n true))) + +{: form-head} diff --git a/fnl/spec/delete_around_spec.fnl b/fnl/spec/delete_around_spec.fnl index b92f5aa..915319a 100644 --- a/fnl/spec/delete_around_spec.fnl +++ b/fnl/spec/delete_around_spec.fnl @@ -5,7 +5,7 @@ (describe "delete around" (fn [] (before_each (fn [] - (vim.keymap.set :o :af select.select-form))) + (vim.keymap.set :o :af select.form))) (it :list (fn [] (h.setup {:content "(1)" :cursor [1 1]}) @@ -45,7 +45,7 @@ (describe "delete around root" (fn [] (before_each (fn [] - (vim.keymap.set :o :aF select.select-root-form))) + (vim.keymap.set :o :aF select.root))) (it "cursor at head of form deletes root" (fn [] (h.setup {:content "(+ 1 (+ 2 3))" :cursor [1 0]}) diff --git a/fnl/spec/helper.fnl b/fnl/spec/helper.fnl index 6422d52..288f27f 100644 --- a/fnl/spec/helper.fnl +++ b/fnl/spec/helper.fnl @@ -13,11 +13,13 @@ (fn escape-keys [keys] (vim.api.nvim_replace_termcodes keys true false true)) (fn feedkeys [keys] (vim.api.nvim_feedkeys (escape-keys keys) :xmt true)) -(fn expect [{: cursor : content}] +(fn expect [{: cursor : content : mode}] (when content (assert.are.same content (core.first (vim.api.nvim_buf_get_lines 0 0 10 false)))) (when cursor - (assert.are.same cursor (vim.api.nvim_win_get_cursor 0)))) + (assert.are.same cursor (vim.api.nvim_win_get_cursor 0))) + (when mode + (assert.are.equal mode (. (vim.api.nvim_get_mode) :mode)))) {: setup : expect : feedkeys} diff --git a/fnl/spec/insertion_spec.fnl b/fnl/spec/insertion_spec.fnl new file mode 100644 index 0000000..c41a397 --- /dev/null +++ b/fnl/spec/insertion_spec.fnl @@ -0,0 +1,38 @@ +(local {: describe : it : before_each} (require :plenary.busted)) +(local h (require :spec.helper)) +(local insertion (require :formedit.insertion)) + +(local head-keymap :h) +(local tail-keymap :t) + +(describe "head insertion" + (fn [] + (before_each (fn [] + (set vim.g.maplocalleader ",") + (vim.keymap.set :n head-keymap insertion.head))) + (it :form + (fn [] + (h.setup {:content "(1)" :cursor [1 0]}) + (h.feedkeys head-keymap) + (h.expect {:content "( 1)" :cursor [1 0]}))) + (it :sub + (fn [] + (h.setup {:content "(1 (2))" :cursor [1 4]}) + (h.feedkeys head-keymap) + (h.expect {:content "(1 ( 2))" :cursor [1 2]}))))) + +(describe "tail insertion" + (fn [] + (before_each (fn [] + (set vim.g.maplocalleader ",") + (vim.keymap.set :n tail-keymap insertion.tail))) + (it :form + (fn [] + (h.setup {:content "(1)" :cursor [1 0]}) + (h.feedkeys tail-keymap) + (h.expect {:content "(1 )" :cursor [1 2]}))) + (it :sub + (fn [] + (h.setup {:content "(1 (2))" :cursor [1 4]}) + (h.feedkeys tail-keymap) + (h.expect {:content "(1 (2 ))" :cursor [1 5]}))))) diff --git a/fnl/spec/wrap_form_spec.fnl b/fnl/spec/wrap_form_spec.fnl new file mode 100644 index 0000000..8157da0 --- /dev/null +++ b/fnl/spec/wrap_form_spec.fnl @@ -0,0 +1,21 @@ +(local {: describe : it : before_each} (require :plenary.busted)) +(local h (require :spec.helper)) +(local wrap (require :formedit.wrap)) + +(local keymap :i) + +(describe :wrap + (fn [] + (before_each (fn [] + (set vim.g.maplocalleader keymap) + (vim.keymap.set :n keymap wrap.form-head))) + (it "form head" + (fn [] + (h.setup {:content "(1)" :cursor [1 0]}) + (h.feedkeys keymap) + (h.expect {:content "( (1))" :cursor [1 0]}))) + (it "sub form" + (fn [] + (h.setup {:content "(1 (2))" :cursor [1 4]}) + (h.feedkeys keymap) + (h.expect {:content "(1 ( (2)))" :cursor [1 2]}))))) diff --git a/lua/formedit/find.lua b/lua/formedit/find.lua new file mode 100644 index 0000000..8a67094 --- /dev/null +++ b/lua/formedit/find.lua @@ -0,0 +1,31 @@ +-- [nfnl] Compiled from fnl/formedit/find.fnl by https://github.com/Olical/nfnl, do not edit. +local ts = require("nvim-treesitter.ts_utils") +local forms = {list_lit = true, vec_lit = true, map_lit = true, set_lit = true, anon_fn_lit = true} +local function find_current_form(node) + if forms[node:type()] then + return node + else + local parent = node:parent() + if parent then + return find_current_form(parent) + else + return nil + end + end +end +local function find_root_form(node) + if node:parent() then + return find_root_form(node:parent()) + else + return node + end +end +local function form() + local node = ts.get_node_at_cursor() + return find_current_form(node) +end +local function root() + local node = ts.get_node_at_cursor() + return find_root_form(node) +end +return {form = form, root = root} diff --git a/lua/formedit/insertion.lua b/lua/formedit/insertion.lua new file mode 100644 index 0000000..e06d90b --- /dev/null +++ b/lua/formedit/insertion.lua @@ -0,0 +1,35 @@ +-- [nfnl] Compiled from fnl/formedit/insertion.fnl by https://github.com/Olical/nfnl, do not edit. +local find = require("formedit.find") +local function range(form) + local _let_1_ = {form:range()} + local start_row = _let_1_[1] + local start_col = _let_1_[2] + local end_row = _let_1_[3] + local end_col = _let_1_[4] + return {(start_row + 1), start_col, (end_row + 1), end_col} +end +local function head() + local form = find.form() + local _let_2_ = range(form) + local start_row = _let_2_[1] + local start_col = _let_2_[2] + local _ = _let_2_[3] + local _0 = _let_2_[4] + vim.api.nvim_win_set_cursor(0, {start_row, start_col}) + vim.api.nvim_command("normal! a ") + vim.api.nvim_win_set_cursor(0, {start_row, start_col}) + return vim.api.nvim_feedkeys("i", "n", true) +end +local function tail() + local form = find.form() + local _let_3_ = range(form) + local _ = _let_3_[1] + local _0 = _let_3_[2] + local end_row = _let_3_[3] + local end_col = _let_3_[4] + vim.api.nvim_win_set_cursor(0, {end_row, (end_col - 1)}) + vim.api.nvim_command("normal! i ") + vim.api.nvim_win_set_cursor(0, {end_row, end_col}) + return vim.api.nvim_feedkeys("i", "n", true) +end +return {head = head, tail = tail} diff --git a/lua/formedit/select.lua b/lua/formedit/select.lua index 5924df3..f469f00 100644 --- a/lua/formedit/select.lua +++ b/lua/formedit/select.lua @@ -1,39 +1,12 @@ -- [nfnl] Compiled from fnl/formedit/select.fnl by https://github.com/Olical/nfnl, do not edit. local ts = require("nvim-treesitter.ts_utils") -local forms = {list_lit = true, vec_lit = true, map_lit = true, set_lit = true, anon_fn_lit = true} -local function find_current_form(node) - if forms[node:type()] then - return node - else - local parent = node:parent() - if parent then - return find_current_form(parent) - else - return nil - end - end +local find = require("formedit.find") +local function form() + local form0 = find.form() + return ts.update_selection(0, form0) end -local function find_root_form(node) - if node:parent() then - return find_root_form(node:parent()) - else - return node - end +local function root() + local form0 = find.root() + return ts.update_selection(0, form0) end -local function get_current_form() - local node = ts.get_node_at_cursor() - return find_current_form(node) -end -local function get_current_root_form() - local node = ts.get_node_at_cursor() - return find_root_form(node) -end -local function select_form() - local form = get_current_form() - return ts.update_selection(0, form) -end -local function select_root_form() - local form = get_current_root_form() - return ts.update_selection(0, form) -end -return {["get-current-form"] = get_current_form, ["select-form"] = select_form, ["select-root-form"] = select_root_form} +return {form = form, root = root} diff --git a/lua/formedit/wrap.lua b/lua/formedit/wrap.lua new file mode 100644 index 0000000..eada701 --- /dev/null +++ b/lua/formedit/wrap.lua @@ -0,0 +1,25 @@ +-- [nfnl] Compiled from fnl/formedit/wrap.fnl by https://github.com/Olical/nfnl, do not edit. +local find = require("formedit.find") +local function range(form) + local _let_1_ = {form:range()} + local start_row = _let_1_[1] + local start_col = _let_1_[2] + local end_row = _let_1_[3] + local end_col = _let_1_[4] + return {(start_row + 1), start_col, (end_row + 1), end_col} +end +local function form_head() + local form = find.form() + local _let_2_ = range(form) + local start_row = _let_2_[1] + local start_col = _let_2_[2] + local end_row = _let_2_[3] + local end_col = _let_2_[4] + vim.api.nvim_win_set_cursor(0, {end_row, end_col}) + vim.api.nvim_command("normal! i)") + vim.api.nvim_win_set_cursor(0, {start_row, start_col}) + vim.api.nvim_command("normal! i( ") + vim.api.nvim_win_set_cursor(0, {start_row, start_col}) + return vim.api.nvim_feedkeys("i", "n", true) +end +return {["form-head"] = form_head} diff --git a/lua/spec/delete_around_spec.lua b/lua/spec/delete_around_spec.lua index 613e0c0..49f7871 100644 --- a/lua/spec/delete_around_spec.lua +++ b/lua/spec/delete_around_spec.lua @@ -7,7 +7,7 @@ local h = require("spec.helper") local select = require("formedit.select") local function _2_() local function _3_() - return vim.keymap.set("o", "af", select["select-form"]) + return vim.keymap.set("o", "af", select.form) end before_each(_3_) local function _4_() @@ -56,7 +56,7 @@ end describe("delete around", _2_) local function _11_() local function _12_() - return vim.keymap.set("o", "aF", select["select-root-form"]) + return vim.keymap.set("o", "aF", select.root) end before_each(_12_) local function _13_() diff --git a/lua/spec/helper.lua b/lua/spec/helper.lua index f16600f..e198a69 100644 --- a/lua/spec/helper.lua +++ b/lua/spec/helper.lua @@ -26,12 +26,17 @@ local function expect(_4_) local _arg_5_ = _4_ local cursor = _arg_5_["cursor"] local content = _arg_5_["content"] + local mode = _arg_5_["mode"] if content then assert.are.same(content, core.first(vim.api.nvim_buf_get_lines(0, 0, 10, false))) else end if cursor then - return assert.are.same(cursor, vim.api.nvim_win_get_cursor(0)) + assert.are.same(cursor, vim.api.nvim_win_get_cursor(0)) + else + end + if mode then + return assert.are.equal(mode, vim.api.nvim_get_mode().mode) else return nil end diff --git a/lua/spec/insertion_spec.lua b/lua/spec/insertion_spec.lua new file mode 100644 index 0000000..e76f813 --- /dev/null +++ b/lua/spec/insertion_spec.lua @@ -0,0 +1,49 @@ +-- [nfnl] Compiled from fnl/spec/insertion_spec.fnl by https://github.com/Olical/nfnl, do not edit. +local _local_1_ = require("plenary.busted") +local describe = _local_1_["describe"] +local it = _local_1_["it"] +local before_each = _local_1_["before_each"] +local h = require("spec.helper") +local insertion = require("formedit.insertion") +local head_keymap = "h" +local tail_keymap = "t" +local function _2_() + local function _3_() + vim.g.maplocalleader = "," + return vim.keymap.set("n", head_keymap, insertion.head) + end + before_each(_3_) + local function _4_() + h.setup({content = "(1)", cursor = {1, 0}}) + h.feedkeys(head_keymap) + return h.expect({content = "( 1)", cursor = {1, 0}}) + end + it("form", _4_) + local function _5_() + h.setup({content = "(1 (2))", cursor = {1, 4}}) + h.feedkeys(head_keymap) + return h.expect({content = "(1 ( 2))", cursor = {1, 2}}) + end + return it("sub", _5_) +end +describe("head insertion", _2_) +local function _6_() + local function _7_() + vim.g.maplocalleader = "," + return vim.keymap.set("n", tail_keymap, insertion.tail) + end + before_each(_7_) + local function _8_() + h.setup({content = "(1)", cursor = {1, 0}}) + h.feedkeys(tail_keymap) + return h.expect({content = "(1 )", cursor = {1, 2}}) + end + it("form", _8_) + local function _9_() + h.setup({content = "(1 (2))", cursor = {1, 4}}) + h.feedkeys(tail_keymap) + return h.expect({content = "(1 (2 ))", cursor = {1, 5}}) + end + return it("sub", _9_) +end +return describe("tail insertion", _6_) diff --git a/lua/spec/wrap_form_spec.lua b/lua/spec/wrap_form_spec.lua new file mode 100644 index 0000000..1770c39 --- /dev/null +++ b/lua/spec/wrap_form_spec.lua @@ -0,0 +1,28 @@ +-- [nfnl] Compiled from fnl/spec/wrap_form_spec.fnl by https://github.com/Olical/nfnl, do not edit. +local _local_1_ = require("plenary.busted") +local describe = _local_1_["describe"] +local it = _local_1_["it"] +local before_each = _local_1_["before_each"] +local h = require("spec.helper") +local wrap = require("formedit.wrap") +local keymap = "i" +local function _2_() + local function _3_() + vim.g.maplocalleader = keymap + return vim.keymap.set("n", keymap, wrap["form-head"]) + end + before_each(_3_) + local function _4_() + h.setup({content = "(1)", cursor = {1, 0}}) + h.feedkeys(keymap) + return h.expect({content = "( (1))", cursor = {1, 0}}) + end + it("form head", _4_) + local function _5_() + h.setup({content = "(1 (2))", cursor = {1, 4}}) + h.feedkeys(keymap) + return h.expect({content = "(1 ( (2)))", cursor = {1, 2}}) + end + return it("sub form", _5_) +end +return describe("wrap", _2_)