From 2306f0d35457c3b3715a86eb848e19c7c2fdd4b3 Mon Sep 17 00:00:00 2001 From: Julien Vincent Date: Sun, 10 Sep 2023 16:15:44 +0100 Subject: [PATCH] Add README section on auto-indentation --- README.md | 80 +++++++++++++++++++++++++++++++++++ lua/nvim-paredit/defaults.lua | 2 +- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dc1bf8a..c1c8493 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,27 @@ require("nvim-paredit").setup({ -- defaults to all supported file types including custom lang -- extensions (see next section) filetypes = { "clojure" }, + + -- This controls where the cursor is placed when performing slurp/barf operations + -- + -- - "remain" - It will never change the cursor position, keeping it in the same place + -- - "follow" - It will always place the cursor on the form edge that was moved + -- - "auto" - A combination of remain and follow, it will try keep the cursor in the original position + -- unless doing so would result in the cursor no longer being within the original form. In + -- this case it will place the cursor on the moved edge cursor_behaviour = "auto", -- remain, follow, auto + + indent = { + -- This controls how nvim-paredit handles indentation when performing operations which + -- should change the indentation of the form (such as when slurping or barfing). + -- + -- When set to true then it will attempt to fix the indentation of nodes operated on. + enabled = false, + -- A function that will be called after a slurp/barf if you want to provide a custom indentation + -- implementation. + indentor = require("nvim-paredit.indentation.native").indentor, + }, + -- list of default keybindings keys = { [">)"] = { paredit.api.slurp_forwards, "Slurp forwards" }, @@ -112,6 +132,65 @@ require("nvim-paredit").setup({ }) ``` +## Auto Indentation + +Nvim-paredit comes with built-in support for fixing form indentation when performing slurp and barf operations. By default this behaviour is disabled and can be enabled by setting `indent.enabled = true` in the [configuration](#configuration) + +The main goal of this implementation is to provide a visual aid to the user, allowing them to confirm they are operating on the correct node and to know when to stop when performing recursive slurp/barf operations. This implementation is fast and does not result in any UI lag or jitter. + +The goal is _not_ to be 100% correct. The implementation follows a simple set of rules which account for most scenarios but not all. If a more correct implementation is needed then the native implementation can be replaced by setting the configuration property `intent.indentor`. For example an implementation using `vim.lsp.buf.format` could be built if the user doesn't mind sacrificing performance for correctness. + +### Recipes + +
+ vim.lsp.buf.format + + Below is a reference implementation for using `vim.lsp.buf.format` to replace the native implementation. This implementation won't be nearly as performant but it will be more correct. + + ```lua + local function lsp_indent(event, opts) + local traversal = require("nvim-paredit.utils.traversal") + local utils = require("nvim-paredit.indentation.utils") + local langs = require("nvim-paredit.lang") + + local lang = langs.get_language_api() + + local parent = event.parent + + local child + if event.type == "slurp-forwards" then + child = parent:named_child(parent:named_child_count() - 1) + elseif event.type == "slurp-backwards" then + child = parent:named_child(1) + elseif event.type == "barf-forwards" then + child = traversal.get_next_sibling_ignoring_comments(event.parent, { lang = lang }) + elseif event.type == "barf-backwards" then + child = event.parent + else + return + end + + local child_range = { child:range() } + local lines = utils.find_affected_lines(child, utils.get_node_line_range(child_range)) + + vim.lsp.buf.format({ + bufnr = opts.buf or 0, + range = { + ["start"] = { lines[1] + 1, 0 }, + ["end"] = { lines[#lines] + 1, 0 }, + }, + }) + end + + require("nvim-paredit").setup({ + indent = { + enabled = true, + indentor = lsp_indent + } + }) + ``` +
+ ## Language Support As this is built using Treesitter it requires that you have the relevant Treesitter grammar installed for your language of choice. Additionally `nvim-paredit` will need explicit support for the treesitter grammar as the node names and metadata of nodes vary between languages. @@ -270,6 +349,7 @@ The main reasons you might want to consider `nvim-paredit` instead are: - Easier configuration and an exposed lua API - Control over how the cursor is moved during slurp/barf. (For example if you don't want the cursor to always be moved) - Recursive slurp/barf operations. If your cursor is in a nested form you can still slurp from the forms parent(s) +- Automatic form/element indentations on slurp/barf - Subjectively better out-of-the-box keybindings ### [vim-sexp-mappings-for-regular-people](https://github.com/tpope/vim-sexp-mappings-for-regular-people) diff --git a/lua/nvim-paredit/defaults.lua b/lua/nvim-paredit/defaults.lua index 9796505..1a5e4ae 100644 --- a/lua/nvim-paredit/defaults.lua +++ b/lua/nvim-paredit/defaults.lua @@ -62,7 +62,7 @@ M.defaults = { use_default_keys = true, cursor_behaviour = "auto", -- remain, follow, auto indent = { - enabled = true, + enabled = false, indentor = require("nvim-paredit.indentation.native").indentor, }, keys = {},