Go to file
Hung 969834a1ed fun: add fennel impl 2023-06-03 23:43:02 -07:00
fennel fun: add fennel impl 2023-06-03 23:43:02 -07:00
lua test: add qa through repl and hopefully self-documented development via repl 2023-06-03 23:38:45 -07:00
.gitignore docs 2023-06-01 08:20:36 -07:00
.neoconf.json feat(buf_select) 2023-05-29 21:39:15 -07:00
LICENSE docs 2023-06-01 08:20:36 -07:00
README.md test: add qa through repl and hopefully self-documented development via repl 2023-06-03 23:38:45 -07:00
repl.md test: add qa through repl and hopefully self-documented development via repl 2023-06-03 23:38:45 -07:00
selene.toml feat(buf_select) 2023-05-29 21:39:15 -07:00
stylua.toml feat(buf_select) 2023-05-29 21:39:15 -07:00
vim.toml feat(buf_select) 2023-05-29 21:39:15 -07:00

README.md

Treesitter QL

A Neovim plugin allowing users to perform workspace-wise operations (highlighting, list processing, mutation) on existing Treesitter query in Scheme.

Please see repl.md for examples

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:

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()):do_nvim()

Installation

Use your favorite package manager to install the plugin. For example, with vim-plug:

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 (and is the default configuration):

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.