docs
parent
c3bfb4c48f
commit
d7691ecaef
|
@ -0,0 +1,2 @@
|
|||
.worktree
|
||||
.luarc.json
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2023 Pegasust
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
143
README.md
143
README.md
|
@ -1 +1,144 @@
|
|||
# Treesitter QL
|
||||
|
||||
A Neovim plugin allowing users to perform workspace-wise operations (highlighting,
|
||||
list processing, mutation) on existing Treesitter query in Scheme.
|
||||
|
||||
## Features
|
||||
|
||||
### Buffer selection (`require('tsql').buf_match`)
|
||||
|
||||
* Filter logic via `buf_match.{path,filetype,ext,any}`.
|
||||
|
||||
#### Combinators
|
||||
|
||||
* With Tacit programming `BufMatch.or_(buf_match.path("world"), BufMatch.not_(buf_match.ext("txt")))`
|
||||
* With method pipelines `buf_match.path("world").or(buf_match.ext("txt").not_())`
|
||||
* Hybrid works too `buf_match.path("world").or(BufMatch.not(buf_match.ext("txt")))`
|
||||
|
||||
### Node query (`require('tsql').token_select`)
|
||||
|
||||
Currently support string-passthru of Treesitter query in Scheme
|
||||
|
||||
`token_select.from_scm("function")`
|
||||
|
||||
### Sink (`require('tsql').sink_by`)
|
||||
|
||||
* Any `{sink: fun(self, QNode[]) -> void}` works!
|
||||
* Processes all workspace nodes.
|
||||
* Highlight specific patterns in your text with `sink_by.highlight()`.
|
||||
Clear all highlights by `require('tsql').clear_highlights()`
|
||||
* Format and print your nodes with `M.sink_by.print()`. This allows you to easily inspect your nodes.
|
||||
* Copy nodes to your clipboard with `M.sink_by.nvim_yank_buf()`.
|
||||
|
||||
#### Format (`require('tsql').format`)
|
||||
|
||||
- Type: `Format = fun(QNode[]): string`
|
||||
- `display: Format`: Representation in a concise/DSL format. This is inspired by Rust's `Display` trait
|
||||
- `dump: Format`: Pretty-print string format for Lua table. Think of this like RON for Rust,
|
||||
some language-native object representation.
|
||||
- `debug: Format`: Aliased from `dump` so that it's consistent with Rust's `Debug` trait
|
||||
|
||||
#### Pre-sink list processing
|
||||
|
||||
WIP
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Here's a basic example of how to use tsql.nvim:
|
||||
|
||||
```lua
|
||||
local ts = require('tsql')
|
||||
-- ts.t(<buf_match>, <ts_query>, <sink>)
|
||||
-- Matches all strings in our neovim workspace.
|
||||
ts.t(ts.buf_match.any(), ts.ts_query.from_scm("string"), ts.sink_by.print())
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
Use your favorite package manager to install the plugin. For example, with [vim-plug](https://github.com/junegunn/vim-plug):
|
||||
|
||||
```vim
|
||||
Plug 'pegasust/tsql.nvim'
|
||||
```
|
||||
|
||||
Don't forget to run `:PlugInstall` to actually install the plugin.
|
||||
|
||||
## Configuration
|
||||
|
||||
To configure tsql.nvim, you can provide a configuration table to the `M.setup` function. Here's an example:
|
||||
|
||||
```lua
|
||||
local tsql = require('tsql')
|
||||
|
||||
tsql.setup({
|
||||
nvim_hl_group = "Search" -- defines the highlight group used for highlighting
|
||||
})
|
||||
```
|
||||
|
||||
By default, `nvim_hl_group` is set to "Search".
|
||||
|
||||
## Commands
|
||||
|
||||
The following commands are available:
|
||||
|
||||
* `:Noh` - Clear all highlights added by this plugin.
|
||||
* `:lua local ts = require('tsql'); ts.t(<buf_match>, <ts_query>, <sink>)`: Perform tsql in Lua bindings
|
||||
* Example: `:lua local ts = require('tsql'); ts.t(ts.buf_match.any(), ts.ts_query.from_scm("string"), ts.sink_by.print())`
|
||||
* Prints all strings in all buffers reachable from `nvim`
|
||||
* Note that `ts.sink_by.print()` will use `ts.format.default`, which is `ts.format.display` without additional configurations
|
||||
|
||||
### TDSL (Work in progress)
|
||||
|
||||
* `:Tdsl */scm:string/p` - DSL without interacting with Lua API. This example
|
||||
prints all strings on all buffers in default (display) format
|
||||
|
||||
#### Advanced example (`feat:TDSL` + `feat:list_process`)
|
||||
|
||||
Highlight all strings within the current buffer that has more than one occurences
|
||||
|
||||
```
|
||||
:Tdsl bufnr:0/scm:string/group_by(t:qnode:text) | values | filter(count | ge(2)) | flatten | h
|
||||
```
|
||||
|
||||
If you're a FP nerd, power to you! Here's the breakdown of the pre-sink processing:
|
||||
- `group_by`: Group items in a list based on a key returned by a function.
|
||||
|
||||
Function Signature: `group_by(func: (item: T) -> K, list: T[]) -> Map<K, T[]>`
|
||||
|
||||
- `flatten`: Flatten a list of lists into a single list. `flatten([[a], [b, c], []]) -> [a, b, c]`
|
||||
|
||||
Function Signature: `flatten(list: T[][]) -> T[]`
|
||||
|
||||
- `values`: Creates an iterator that goes through all values of a map (created by `group_by` in this case)
|
||||
|
||||
Function Signature: `values(map: Map<K, V>) -> V[]`
|
||||
|
||||
- `filter_map`: Return a new list containing only the items where the given function maps to non-null
|
||||
|
||||
Function Signature: `filter_map(fn: (item: T) -> Option<T>) -> (T[] -> T[])`
|
||||
|
||||
- `some_if`: Lifts a predicate (`T -> bool`) into an "option predicate": `T -> Option<T>`
|
||||
|
||||
Function Signature: `some_if(fn: (item: T) -> bool) -> (T -> Option<T>)`
|
||||
|
||||
- `count`: Counts the number of elements in an interable
|
||||
|
||||
Function Signature: `count(list: T[]) -> number`
|
||||
|
||||
- `ge`: A higher-order function to compare if a number is greater or equal to a set number. `ge(2)(3) == 3 >= 2`
|
||||
|
||||
Function Signature: `ge(lower: number) -> (number -> bool)`
|
||||
|
||||
## Documentation
|
||||
|
||||
For detailed information on each function and class, refer to the source code.
|
||||
It contains extensive inline documentation that should be enough to understand each part of the plugin.
|
||||
|
||||
## Contribution
|
||||
|
||||
If you want to contribute to the development of tsql.nvim, feel free to open a pull request.
|
||||
|
||||
## License
|
||||
|
||||
Tsql.nvim is distributed under the MIT license. See the LICENSE file in the repository for details.
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
{
|
||||
"workspace.library": [
|
||||
"/nix/store/7mwww77s7jads5ymvn9vv11vkywfh1sp-vim-pack-dir",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/plenary.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/nlua.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/nvim-treesitter",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/nvim-treesitter-textobjects",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/telescope.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/telescope-fzf-native.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/telescope-file-browser.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/nvim-lspconfig",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/cmp-nvim-lsp",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/cmp-path",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/cmp-buffer",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/cmp-cmdline",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/nvim-cmp",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/lspkind-nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/nvim-yati",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/yang.vim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/nvim-autopairs",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/nvim-ts-autotag",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/guess-indent.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/Comment.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/gitsigns.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/vim-fugitive",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/mason.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/mason-lspconfig.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/harpoon",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/neogit",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/trouble.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/vim-dispatch",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/vim-jack-in",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/vim-dispatch-neovim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/conjure",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/nvim-jqx",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/nvim-surround",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/rust-tools.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/inlay-hints.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/gruvbox",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/lualine.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/indent-blankline.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/nvim-web-devicons",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/hlargs.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/todo-comments.nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/nvim-treesitter-context",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/playground",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/cmp_luasnip",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/LuaSnip",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/zk-nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/vim-caser",
|
||||
"/Users/hungtran/.config/nvim",
|
||||
"/Users/hungtran/.local/share/nvim/site",
|
||||
"/nix/store/2xr2f568qzslyfmb7zw3sdp8kdv0w7qi-neovim-unwrapped-236c207/share/nvim/runtime",
|
||||
"/nix/store/2xr2f568qzslyfmb7zw3sdp8kdv0w7qi-neovim-unwrapped-236c207/lib/nvim",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/nlua.nvim/after",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/cmp-nvim-lsp/after",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/cmp-path/after",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/cmp-buffer/after",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/cmp-cmdline/after",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/playground/after",
|
||||
"/Users/hungtran/.local/share/nvim/plugged/cmp_luasnip/after",
|
||||
"${3rd}/luassert/library"
|
||||
]
|
||||
}
|
23
lua/tsql.lua
23
lua/tsql.lua
|
@ -17,11 +17,21 @@ M.sink_by = {}
|
|||
---@alias Format fun(nodes: QNode[]): string
|
||||
M.format = {}
|
||||
|
||||
M.format.default = M.format.display
|
||||
|
||||
---@class Sink
|
||||
---@field sink fun(self, nodes: QNode[])
|
||||
M.Sink = {}
|
||||
M.Sink.__index = M.Sink
|
||||
|
||||
---@return Sink
|
||||
---@param func fun(self, nodes:QNode[])
|
||||
function M.sink_by.pure_fn(func)
|
||||
return setmetatable({
|
||||
sink = func
|
||||
}, M.Sink)
|
||||
end
|
||||
|
||||
---@return Sink
|
||||
function M.sink_by.highlight()
|
||||
return setmetatable({
|
||||
|
@ -72,9 +82,14 @@ function M.format.dump(nodes)
|
|||
return vim.inspect(nodes, { newline = '\n', indent = ' ' })
|
||||
end
|
||||
|
||||
---@param format Format
|
||||
M.format.debug = M.format.dump
|
||||
|
||||
---@param format Format | nil
|
||||
---@return Sink
|
||||
function M.sink_by.print(format)
|
||||
if format == nil then
|
||||
format = M.format.default
|
||||
end
|
||||
return setmetatable({
|
||||
---@type fun(nodes: QNode[])
|
||||
sink = function(nodes)
|
||||
|
@ -86,6 +101,9 @@ end
|
|||
---@param format Format
|
||||
---@return Sink
|
||||
function M.sink_by.nvim_yank_buf(format)
|
||||
if format == nil then
|
||||
format = M.format.default
|
||||
end
|
||||
return setmetatable({
|
||||
---@type fun(nodes: QNode[])
|
||||
sink = function(nodes)
|
||||
|
@ -209,6 +227,9 @@ function M.setup(config)
|
|||
M.config.nvim_ns = vim.api.nvim_create_namespace("tsql")
|
||||
|
||||
vim.api.nvim_create_user_command("Noh", M.clear_highlights)
|
||||
vim.api.nvim_create_user_command("Tdsl", function(cmd)
|
||||
M.s(cmd.args):do_nvim(M.store)
|
||||
end)
|
||||
|
||||
M.store = M.Store:new()
|
||||
end
|
||||
|
|
|
@ -104,6 +104,10 @@ function M.buf_match.filetype(...)
|
|||
end)
|
||||
end
|
||||
|
||||
function M.buf_match.any()
|
||||
return M.BufMatch.new(function(_) return true end)
|
||||
end
|
||||
|
||||
---@vararg string OR for path
|
||||
---@return BufMatch
|
||||
function M.buf_match.path(...)
|
||||
|
|
|
@ -39,12 +39,12 @@ function M.TSQuery:find_nodes(files)
|
|||
local tree = parser:parse()[1]
|
||||
local root = tree:root()
|
||||
---@type Query
|
||||
local query = vim.treesitter.parse_query(file.lang, self.query)
|
||||
local query = vim.treesitter.query.parse_query(file.lang, self.query)
|
||||
for _, match, _ in query:iter_matches(root, file.bufnr, 0, -1) do
|
||||
for id, node in pairs(match) do
|
||||
local start_row, start_col, end_row, end_col = node:range(false)
|
||||
local start = { row_0 = start_row, col_0 = start_col }
|
||||
-- NOTE: Will need to validate that this is correct to be exclusive
|
||||
-- CORRECTNESS:
|
||||
-- :lua local parser = vim.treesitter.get_parser(0, 'lua'); local tree = parser:parse()[1]; local query = vim.treesitter.parse_query('lua', '(identifier) @name'); for id, node in query:iter_captures(tree:root(), 0) do local name = query.captures[id]; if name == 'name' and vim.treesitter.get_node_text(node, 0) == 'TSQuery' then local sr, sc, er, ec = node:range(); print(string.format("TSQuery Start: (%d, %d), End: (%d, %d)", sr, sc, er, ec)); end; end
|
||||
local end_ex_col = { row_0 = end_row, col_0 = end_col }
|
||||
local qnode = { buf = file, start = start, end_ex_col = end_ex_col }
|
||||
|
|
Loading…
Reference in New Issue