diff --git a/README.md b/README.md
index e04282a..c8b79ec 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,8 @@
-The goal of `nvim-paredit` is to provide a comparable s-expression editing experience in Neovim to that provided by Emacs. This is what is provided:
+The goal of `nvim-paredit` is to provide a comparable s-expression editing experience in Neovim to that provided by
+Emacs. This is what is provided:
- Treesitter based lisp structural editing, cursor motions and text object selections
- Dot-repeatable keybindings
@@ -24,9 +25,11 @@ The goal of `nvim-paredit` is to provide a comparable s-expression editing exper
## Project Status
-This is currently **beta software**. It works well in the workflows of the current maintainers but has not been thoroughly tested with many users.
+This is currently **beta software**. It works well in the workflows of the current maintainers but has not been
+thoroughly tested with many users.
-It currently only has first-class support for the `clojure` language and has a focus on supporting the fundamental paredit operations and motions.
+It currently only has first-class support for the `clojure` language and has a focus on supporting the fundamental
+paredit operations and motions.
## Installation
@@ -136,25 +139,25 @@ paredit.setup({
paredit.api.select_around_form,
"Around form",
repeatable = false,
- mode = { "o", "v" }
+ mode = { "o", "v" },
},
["if"] = {
paredit.api.select_in_form,
"In form",
repeatable = false,
- mode = { "o", "v" }
+ mode = { "o", "v" },
},
["aF"] = {
paredit.api.select_around_top_level_form,
"Around top level form",
repeatable = false,
- mode = { "o", "v" }
+ mode = { "o", "v" },
},
["iF"] = {
paredit.api.select_in_top_level_form,
"In top level form",
repeatable = false,
- mode = { "o", "v" }
+ mode = { "o", "v" },
},
["ae"] = {
paredit.api.select_element,
@@ -168,74 +171,99 @@ paredit.setup({
repeatable = false,
mode = { "o", "v" },
},
- }
+ },
})
```
## 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)
+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 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.
+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 },
- },
- })
+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
- require("nvim-paredit").setup({
- indent = {
- enabled = true,
- indentor = lsp_indent
- }
+ 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
+
+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.
+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.
-Right now `nvim-paredit` only has built in support for `clojure` but exposes an extension API for adding support for other lisp dialects. This API is considered **very alpha** and may change without warning to properly account for other languages when attempts are made to add support.
+Right now `nvim-paredit` only has built in support for `clojure` but exposes an extension API for adding support for
+other lisp dialects. This API is considered **very alpha** and may change without warning to properly account for other
+languages when attempts are made to add support.
Extensions can either be added as config when calling `setup`:
@@ -247,22 +275,18 @@ require("nvim-paredit").setup({
-- The node at cursor in the below example is `()` or 'list_lit':
-- '(|)
-- But the node root is `'()` or 'quoting_lit'
- get_node_root = function(node)
- end,
+ get_node_root = function(node) end,
-- This is the inverse of `get_node_root` for forms and should find the inner node for which
-- the forms elements are direct children.
--
-- For example given the node `'()` or 'quoting_lit', this function should return `()` or 'list_lit'.
- unwrap_form = function(node)
- end,
+ unwrap_form = function(node) end,
-- Accepts a Treesitter node and should return true or false depending on whether the given node
-- can be considered a 'form'
- node_is_form = function(node)
- end,
+ node_is_form = function(node) end,
-- Accepts a Treesitter node and should return true or false depending on whether the given node
-- can be considered a 'comment'
- node_is_comment = function(node)
- end,
+ node_is_comment = function(node) end,
-- Accepts a Treesitter node representing a form and should return the 'edges' of the node. This
-- includes the node text and the range covered by the node
get_form_edges = function(node)
@@ -271,12 +295,13 @@ require("nvim-paredit").setup({
right = { text = "}", range = { 0, 5, 0, 6 } },
}
end,
- }
- }
+ },
+ },
})
```
-Or by calling the `add_language_extension` API directly before the setup. This would be the recommended approach for extension plugin authors.
+Or by calling the `add_language_extension` API directly before the setup. This would be the recommended approach for
+extension plugin authors.
```lua
require("nvim-paredit").extension.add_language_extension("commonlisp", { ... }).
@@ -284,12 +309,13 @@ require("nvim-paredit").extension.add_language_extension("commonlisp", { ... }).
### Existing Language Extensions
-+ [fennel](https://github.com/julienvincent/nvim-paredit-fennel)
-+ [scheme](https://github.com/ekaitz-zarraga/nvim-paredit-scheme)
+- [fennel](https://github.com/julienvincent/nvim-paredit-fennel)
+- [scheme](https://github.com/ekaitz-zarraga/nvim-paredit-scheme)
---
-As no attempt has been made to add support for other grammars I have no idea if the language extension API's are actually sufficient for adding additional languages. They will evolve as attempts are made.
+As no attempt has been made to add support for other grammars I have no idea if the language extension API's are
+actually sufficient for adding additional languages. They will evolve as attempts are made.
## API
@@ -334,10 +360,13 @@ Cursor api `paredit.cursor`
### `vim-sexp` wrap form (head/tail) replication
Require api module:
+
```lua
local paredit = require("nvim-paredit")
```
+
Add following keybindings to config:
+
```lua
["w"] = {
function()
@@ -383,13 +412,16 @@ Add following keybindings to config:
"Wrap form insert tail",
}
```
+
Same approach can be used for other `vim-sexp` keybindings (e.g. `e[`) with cursor placement or without.
## Prior Art
### [vim-sexp](https://github.com/guns/vim-sexp)
-Currently the de-facto s-expression editing plugin with the most extensive set of available editing operations. If you are looking for a more complete plugin with a wider range of supported languages then you might want to look into using this instead.
+Currently the de-facto s-expression editing plugin with the most extensive set of available editing operations. If you
+are looking for a more complete plugin with a wider range of supported languages then you might want to look into using
+this instead.
The main reasons you might want to consider `nvim-paredit` instead are:
@@ -401,4 +433,5 @@ The main reasons you might want to consider `nvim-paredit` instead are:
### [vim-sexp-mappings-for-regular-people](https://github.com/tpope/vim-sexp-mappings-for-regular-people)
-A companion to `vim-sexp` which configures `vim-sexp` with better mappings. The default mappings for `nvim-paredit` were derived from here.
+A companion to `vim-sexp` which configures `vim-sexp` with better mappings. The default mappings for `nvim-paredit` were
+derived from here.