mirror of
https://github.com/CKolkey/ts-node-action
synced 2024-09-16 13:44:05 +02:00
style: apply markdown formatting
This commit is contained in:
parent
0cfc5b4121
commit
b089a308b0
4 changed files with 200 additions and 92 deletions
9
.markdownlint.yaml
Normal file
9
.markdownlint.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
default: true
|
||||
|
||||
# MD033/no-inline-html
|
||||
MD033:
|
||||
allowed_elements:
|
||||
- summary
|
||||
- details
|
||||
- a
|
|
@ -4,3 +4,19 @@ repos:
|
|||
rev: v0.18.1
|
||||
hooks:
|
||||
- id: stylua-github
|
||||
|
||||
- repo: https://github.com/executablebooks/mdformat
|
||||
rev: 0.7.16
|
||||
hooks:
|
||||
- id: mdformat
|
||||
additional_dependencies:
|
||||
- mdformat-gfm
|
||||
- mdformat-frontmatter
|
||||
- mdformat-footnote
|
||||
- mdformat-tables
|
||||
- mdformat-toc
|
||||
|
||||
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||
rev: v0.35.0
|
||||
hooks:
|
||||
- id: markdownlint-fix
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
rust 1.71.0
|
||||
python 3.10.12
|
||||
|
|
266
README.md
266
README.md
|
@ -1,18 +1,24 @@
|
|||
# TS Node Action
|
||||
|
||||
A framework for running functions on Tree-sitter nodes, and updating the buffer with the result.
|
||||
A framework for running functions on Tree-sitter nodes, and updating the buffer
|
||||
with the result.
|
||||
|
||||
- [Installation](https://github.com/CKolkey/ts-node-action/blob/master/README.md#installation)
|
||||
- [Usage](https://github.com/CKolkey/ts-node-action/blob/master/README.md#usage)
|
||||
- [Configuration](https://github.com/CKolkey/ts-node-action/blob/master/README.md#configuration)
|
||||
- [Multiple Actions for a Node Type](https://github.com/CKolkey/ts-node-action/blob/master/README.md#multiple-actions-for-a-node-type)
|
||||
- [Writing Your Own Actions](https://github.com/CKolkey/ts-node-action#writing-your-own-node-actions)
|
||||
- [API](https://github.com/CKolkey/ts-node-action#writing-your-own-node-actions)
|
||||
- [Helpers](https://github.com/CKolkey/ts-node-action#helpers)
|
||||
- [Null-LS](https://github.com/CKolkey/ts-node-action#null-ls-integration)
|
||||
- [Builtin Actions](https://github.com/CKolkey/ts-node-action#builtin-actions)
|
||||
- [Testing](https://github.com/CKolkey/ts-node-action#testing)
|
||||
- [Contributing](https://github.com/CKolkey/ts-node-action#contributing)
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=3 --minlevel=2 -->
|
||||
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [Configuration](#configuration)
|
||||
- [Multiple Actions for a Node Type](#multiple-actions-for-a-node-type)
|
||||
- [Writing your own Node Actions](#writing-your-own-node-actions)
|
||||
- [Options](#options)
|
||||
- [API](#api)
|
||||
- [null-ls Integration](#null-ls-integration)
|
||||
- [Helpers](#helpers)
|
||||
- [Builtin Actions](#builtin-actions)
|
||||
- [Testing](#testing)
|
||||
- [Contributing](#contributing)
|
||||
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
![cycle case](https://user-images.githubusercontent.com/7228095/210154055-8851210e-e8e1-4ba3-a474-0be373df8d1b.gif)
|
||||
|
||||
|
@ -29,6 +35,7 @@ A framework for running functions on Tree-sitter nodes, and updating the buffer
|
|||
## Installation
|
||||
|
||||
`Lazy.nvim`:
|
||||
|
||||
```lua
|
||||
{
|
||||
'ckolkey/ts-node-action',
|
||||
|
@ -38,6 +45,7 @@ A framework for running functions on Tree-sitter nodes, and updating the buffer
|
|||
```
|
||||
|
||||
`packer`:
|
||||
|
||||
```lua
|
||||
use({
|
||||
'ckolkey/ts-node-action',
|
||||
|
@ -48,21 +56,31 @@ use({
|
|||
})
|
||||
```
|
||||
|
||||
**Note**: It's not required to call `require("ts-node-action").setup()` to initialize the plugin,
|
||||
but a table can be passed into the setup function to specify new actions for nodes or additional langs.
|
||||
> \[!NOTE\]
|
||||
> It's not required to call `require("ts-node-action").setup()` to
|
||||
> initialize the plugin, but a table can be passed into the setup function to
|
||||
> specify new actions for nodes or additional langs.
|
||||
|
||||
## Usage
|
||||
|
||||
Bind `require("ts-node-action").node_action` to something. This is left up to the user.
|
||||
Bind `require("ts-node-action").node_action` to something. This is left up to
|
||||
the user.
|
||||
|
||||
For example, this would bind the function to `K`:
|
||||
|
||||
```lua
|
||||
vim.keymap.set({ "n" }, "K", require("ts-node-action").node_action, { desc = "Trigger Node Action" })
|
||||
vim.keymap.set(
|
||||
{ "n" },
|
||||
"K",
|
||||
require("ts-node-action").node_action,
|
||||
{ desc = "Trigger Node Action" },
|
||||
)
|
||||
```
|
||||
|
||||
If `tpope/vim-repeat` is installed, calling `node_action()` is dot-repeatable.
|
||||
|
||||
If `setup()` is called, user commands `:NodeAction` and `:NodeActionDebug` are defined.
|
||||
If `setup()` is called, user commands `:NodeAction` and `:NodeActionDebug` are
|
||||
defined.
|
||||
|
||||
See `available_actions()` below for how to set this up with LSP Code Actions.
|
||||
|
||||
|
@ -87,11 +105,13 @@ The `setup()` function accepts a table that conforms to the following schema:
|
|||
- `lang` should be the treesitter parser lang, or `'*'` for the global table
|
||||
- `node_type` should be the value of `vim.treesitter.get_node_at_cursor()`
|
||||
|
||||
A definition on the `lang` table will take precedence over the `*` (global) table.
|
||||
A definition on the `lang` table will take precedence over the `*` (global)
|
||||
table.
|
||||
|
||||
### Multiple Actions for a Node Type
|
||||
|
||||
To define multiple actions for a node type, structure your `node_type` value as a table of tables, like so:
|
||||
To define multiple actions for a node type, structure your `node_type` value as
|
||||
a table of tables, like so:
|
||||
|
||||
```lua
|
||||
["node_type"] = {
|
||||
|
@ -100,11 +120,12 @@ To define multiple actions for a node type, structure your `node_type` value as
|
|||
}
|
||||
```
|
||||
|
||||
`vim.ui.select` will use the value of `name` to when prompting you on which action to perform.
|
||||
`vim.ui.select` will use the value of `name` to when prompting you on which
|
||||
action to perform.
|
||||
|
||||
If you want to bypass `vim.ui.select` and instead just want all actions to be applied
|
||||
without prompting, you can pass `ask = false` as an argument in the `node_type` value.
|
||||
Using the same example as above, it would look like this:
|
||||
If you want to bypass `vim.ui.select` and instead just want all actions to be
|
||||
applied without prompting, you can pass `ask = false` as an argument in the
|
||||
`node_type` value. Using the same example as above, it would look like this:
|
||||
|
||||
```lua
|
||||
["node_type"] = {
|
||||
|
@ -116,17 +137,19 @@ Using the same example as above, it would look like this:
|
|||
|
||||
## Writing your own Node Actions
|
||||
|
||||
All node actions should be a function that takes one argument: the tree-sitter node under the cursor.
|
||||
All node actions should be a function that takes one argument: the tree-sitter
|
||||
node under the cursor.
|
||||
|
||||
You can read more about their API via `:help tsnode`
|
||||
|
||||
This function can return one or two values:
|
||||
|
||||
- The first being the text to replace the node with. The replacement text can be either a `"string"` or
|
||||
`{ "table", "of", "strings" }`. With a table of strings, each string will be on it's own line.
|
||||
- The first being the text to replace the node with. The replacement text can be
|
||||
either a `"string"` or `{ "table", "of", "strings" }`. With a table of
|
||||
strings, each string will be on it's own line.
|
||||
|
||||
- The second (optional) returned value is a table of options. Supported keys are: `cursor`, `callback`, `format`, and
|
||||
`target`.
|
||||
- The second (optional) returned value is a table of options. Supported keys
|
||||
are: `cursor`, `callback`, `format`, and `target`.
|
||||
|
||||
Here's how that can look.
|
||||
|
||||
|
@ -139,21 +162,31 @@ Here's how that can look.
|
|||
}
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
#### `cursor`
|
||||
If the `cursor` key is present with an empty table value, the cursor will be moved to the start of the line where the
|
||||
current node is (`row = 0` `col = 0` relative to node `start_row` and `start_col`).
|
||||
|
||||
If the `cursor` key is present with an empty table value, the cursor will be
|
||||
moved to the start of the line where the current node is (`row = 0` `col = 0`
|
||||
relative to node `start_row` and `start_col`).
|
||||
|
||||
#### `callback`
|
||||
If `callback` is present, it will simply get called without arguments after the buffer has been updated, and after the
|
||||
cursor has been positioned.
|
||||
|
||||
If `callback` is present, it will simply get called without arguments after the
|
||||
buffer has been updated, and after the cursor has been positioned.
|
||||
|
||||
#### `format`
|
||||
Boolean value. If `true`, will run `=` operator on new buffer text. Requires `indentexpr` to be set.
|
||||
|
||||
Boolean value. If `true`, will run `=` operator on new buffer text. Requires
|
||||
`indentexpr` to be set.
|
||||
|
||||
#### `target`
|
||||
TSNode. If present, this node will be used as the target for replacement instead of the node under your cursor.
|
||||
|
||||
TSNode. If present, this node will be used as the target for replacement instead
|
||||
of the node under your cursor.
|
||||
|
||||
Here's a simplified example of how a node-action function gets called:
|
||||
|
||||
```lua
|
||||
local action = node_actions[lang][node:type()]
|
||||
local replacement, opts = action(node)
|
||||
|
@ -162,23 +195,28 @@ replace_node(node, replacement, opts or {})
|
|||
|
||||
## API
|
||||
|
||||
`require("ts-node-action").node_action()`
|
||||
Main function for plugin. Should be assigned by user, and when called will attempt to run the assigned function for the
|
||||
node your cursor is currently on.
|
||||
<hr>
|
||||
`require("ts-node-action").node_action()` Main function for plugin. Should be
|
||||
assigned by user, and when called will attempt to run the assigned function for
|
||||
the node your cursor is currently on.
|
||||
|
||||
`require("ts-node-action").debug()`
|
||||
Prints some helpful information about the current node, as well as the loaded node actions for all langs
|
||||
<hr>
|
||||
______________________________________________________________________
|
||||
|
||||
`require("ts-node-action").available_actions()`
|
||||
Exposes the function assigned to the node your cursor is currently on, as well as its name
|
||||
<hr>
|
||||
`require("ts-node-action").debug()` Prints some helpful information about the
|
||||
current node, as well as the loaded node actions for all langs
|
||||
|
||||
______________________________________________________________________
|
||||
|
||||
`require("ts-node-action").available_actions()` Exposes the function assigned to
|
||||
the node your cursor is currently on, as well as its name
|
||||
|
||||
______________________________________________________________________
|
||||
|
||||
## null-ls Integration
|
||||
|
||||
Users can set up integration with [null-ls](https://github.com/jose-elias-alvarez/null-ls.nvim) and use it to display
|
||||
available node actions by registering the builtin `ts_node_action` code action source
|
||||
Users can set up integration with
|
||||
[null-ls](https://github.com/jose-elias-alvarez/null-ls.nvim) and use it to
|
||||
display available node actions by registering the builtin `ts_node_action` code
|
||||
action source
|
||||
|
||||
```lua
|
||||
local null_ls = require("null-ls")
|
||||
|
@ -190,35 +228,53 @@ null_ls.setup({
|
|||
})
|
||||
```
|
||||
|
||||
This will present the available node action(s) for the node under your cursor alongside your `lsp`/`null-ls` code actions.
|
||||
<hr>
|
||||
This will present the available node action(s) for the node under your cursor
|
||||
alongside your `lsp`/`null-ls` code actions.
|
||||
|
||||
______________________________________________________________________
|
||||
|
||||
## Helpers
|
||||
|
||||
`require("ts-node-action.helpers").node_text(node)`
|
||||
```lua
|
||||
require("ts-node-action.helpers").node_text(node)
|
||||
```
|
||||
|
||||
```lua
|
||||
@node: tsnode
|
||||
@return: string
|
||||
```
|
||||
Returns the text of the specified node.
|
||||
<hr>
|
||||
|
||||
`require("ts-node-action.helpers").node_is_multiline(node)`
|
||||
Returns the text of the specified node.
|
||||
|
||||
______________________________________________________________________
|
||||
|
||||
```lua
|
||||
require("ts-node-action.helpers").node_is_multiline(node)
|
||||
```
|
||||
|
||||
```lua
|
||||
@node: tsnode
|
||||
@return: boolean
|
||||
```
|
||||
Returns true if node spans multiple lines, and false if it's a single line.
|
||||
<hr>
|
||||
|
||||
`require("ts-node-action.helpers").padded_node_text(node, padding)`
|
||||
Returns true if node spans multiple lines, and false if it's a single line.
|
||||
|
||||
______________________________________________________________________
|
||||
|
||||
```lua
|
||||
require("ts-node-action.helpers").padded_node_text(node, padding)
|
||||
```
|
||||
|
||||
```lua
|
||||
@node: tsnode
|
||||
@padding: table
|
||||
@return: string
|
||||
```
|
||||
For formatting unnamed tsnodes. For example, if you pass in an unnamed node representing the text `,`, you could pass in
|
||||
a `padding` table (below) to add a trailing whitespace to `,` nodes.
|
||||
|
||||
For formatting unnamed tsnodes. For example, if you pass in an unnamed node
|
||||
representing the text `,`, you could pass in a `padding` table (below) to add a
|
||||
trailing whitespace to `,` nodes.
|
||||
|
||||
```lua
|
||||
{ [","] = "%s " }
|
||||
```
|
||||
|
@ -228,68 +284,94 @@ Nodes not specified in table are returned unchanged.
|
|||
## Builtin Actions
|
||||
|
||||
<details>
|
||||
<summary>Cycle Case</summary>
|
||||
|
||||
`require("ts-node-action.actions").cycle_case(formats)`
|
||||
<!-- markdownlint-disable-next-line no-inline-html -->
|
||||
<summary><h3>Cycle Case</h3></summary>
|
||||
|
||||
```lua
|
||||
require("ts-node-action.actions").cycle_case(formats)
|
||||
```
|
||||
|
||||
```lua
|
||||
@param formats table|nil
|
||||
```
|
||||
|
||||
`formats` param can be a table of strings specifying the different formats to cycle through. By default it's `{
|
||||
"snake_case", "pascal_case", "screaming_snake_case", "camel_case" }`.
|
||||
`formats` param can be a table of strings specifying the different formats to
|
||||
cycle through. By default it's
|
||||
|
||||
```lua
|
||||
{ "snake_case", "pascal_case", "screaming_snake_case", "camel_case" }
|
||||
```
|
||||
|
||||
A table can also be used in place of a string to implement a custom formatter.
|
||||
Every format is a table that implements the following interface:
|
||||
|
||||
A table can also be used in place of a string to implement a custom formatter. Every format is a table that implements the following interface:
|
||||
- pattern (string)
|
||||
- apply (function)
|
||||
- standardize (function)
|
||||
|
||||
### pattern
|
||||
#### `pattern` <!-- markdownlint-disable-line header-increment -->
|
||||
|
||||
A Lua pattern (string) that matches the format
|
||||
|
||||
### apply
|
||||
A function that takes a _table_ of standardized strings as it's argument, and returns a _string_ in the format
|
||||
#### `apply`
|
||||
|
||||
### standardize
|
||||
A function that takes a _string_ in this format, and returns a table of strings, all lower case, no special chars.
|
||||
ie:
|
||||
```
|
||||
A function that takes a _table_ of standardized strings as it's argument, and
|
||||
returns a _string_ in the format
|
||||
|
||||
#### `standardize`
|
||||
|
||||
A function that takes a _string_ in this format, and returns a table of strings,
|
||||
all lower case, no special chars. ie:
|
||||
|
||||
```lua
|
||||
standardize("ts_node_action") -> { "ts", "node", "action" }
|
||||
standardize("tsNodeAction") -> { "ts", "node", "action" }
|
||||
standardize("TsNodeAction") -> { "ts", "node", "action" }
|
||||
standardize("TS_NODE_ACTION") -> { "ts", "node", "action" }
|
||||
```
|
||||
|
||||
NOTE: The order of formats can be important, as some identifiers are the same for multiple formats.
|
||||
Take the string 'action' for example. This is a match for both snake_case _and_ camel_case. It's
|
||||
therefore important to place a format between those two so we can correcly change the string.
|
||||
<hr />
|
||||
> \[!NOTE\]
|
||||
> The order of formats can be important, as some identifiers are the same
|
||||
> for multiple formats. Take the string 'action' for example. This is a match for
|
||||
> both snake*case \_and* camel_case. It's therefore important to place a format
|
||||
> between those two so we can correcly change the string.
|
||||
|
||||
______________________________________________________________________
|
||||
|
||||
</details>
|
||||
|
||||
Builtin actions are all higher-order functions so they can easily have options overridden on a per-lang basis. Check out the implementations under `lua/filetypes/` to see how!
|
||||
Builtin actions are all higher-order functions so they can easily have options
|
||||
overridden on a per-lang basis. Check out the implementations under
|
||||
`lua/filetypes/` to see how!
|
||||
|
||||
| | (*) | Ruby | js/ts/tsx/jsx | Lua | Python | PHP | Rust | JSON | HTML | YAML | R |
|
||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||
| `toggle_boolean()` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | ✅ | ✅ |
|
||||
| `cycle_case()` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | | ✅ | ✅ |
|
||||
| `cycle_quotes()` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | | | ✅ |
|
||||
| `toggle_multiline()` | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | ✅ |
|
||||
| `toggle_operator()` | | ✅ | ✅ | ✅ | ✅ | ✅ | | | | | ✅ |
|
||||
| `toggle_int_readability()` | | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ | | | |
|
||||
| `toggle_block()` | | ✅ | | | | | | | | | |
|
||||
| if/else <-> ternery | | ✅ | | | ✅ | | | | | | |
|
||||
| if block/postfix | | ✅ | | | | | | | | | |
|
||||
| `toggle_hash_style()` | | ✅ | | | | | | | | | |
|
||||
| `conceal_string()` | | | ✅ | | | | | | ✅ | | |
|
||||
<!-- markdownlint-disable line-length -->
|
||||
|
||||
| | (\*) | Ruby | js/ts/tsx/jsx | Lua | Python | PHP | Rust | JSON | HTML | YAML | R |
|
||||
| -------------------------- | ---- | ---- | ------------- | --- | ------ | --- | ---- | ---- | ---- | ---- | --- |
|
||||
| `toggle_boolean()` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | ✅ | ✅ |
|
||||
| `cycle_case()` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | | ✅ |
|
||||
| `cycle_quotes()` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | | | ✅ |
|
||||
| `toggle_multiline()` | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | ✅ |
|
||||
| `toggle_operator()` | | ✅ | ✅ | ✅ | ✅ | ✅ | | | | | ✅ |
|
||||
| `toggle_int_readability()` | | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ | | | |
|
||||
| `toggle_block()` | | ✅ | | | | | | | | | |
|
||||
| if/else \<-> ternery | | ✅ | | | ✅ | | | | | | |
|
||||
| if block/postfix | | ✅ | | | | | | | | | |
|
||||
| `toggle_hash_style()` | | ✅ | | | | | | | | | |
|
||||
| `conceal_string()` | | | ✅ | | | | | | ✅ | | |
|
||||
|
||||
<!-- markdownlint-enable line-length -->
|
||||
|
||||
## Testing
|
||||
To run the test suite, clone the repo and run `./run_spec`. It should pull all dependencies into `spec/support/` on
|
||||
first run, then execute the tests.
|
||||
|
||||
To run the test suite, clone the repo and run `./run_spec`. It should pull all
|
||||
dependencies into `spec/support/` on first run, then execute the tests.
|
||||
|
||||
This is still a little WIP.
|
||||
|
||||
## Contributing
|
||||
|
||||
If you come up with something that would be a good fit, pull requests for node actions are welcome!
|
||||
If you come up with something that would be a good fit, pull requests for node
|
||||
actions are welcome!
|
||||
|
||||
Visit: https://www.github.com/ckolkey/ts-node-action
|
||||
Visit: <https://www.github.com/ckolkey/ts-node-action>
|
||||
|
|
Loading…
Reference in a new issue