Giter VIP home page Giter VIP logo

architext.nvim's Introduction

This project has moved to sourcehut

architext.nvim

A structural editing plugin for neovim, powered by treesitter.

Installation

Use the only package manager :

use {
  "vigoux/architext.nvim"
  requires = {
    -- Not required, only used to refine the language resolution
    "nvim-treesitter/nvim-treesitter"
  }
}

Usage

Using the REPL

  1. Open a buffer, and be sure to have the correct parsers installed for the buffers filetype.
  2. :ArchitextREPL
  3. Type your query, with captures for the things we want to replace / refer to
  4. Type the replacements for them (empty to not replace), and refer to a capture using @{capture name}
  5. Hit <CR> your edits happen !

Using :Architext

First, open a buffer, be sure to have a parser for it installed.

Then, you can use the :Architext (or :A in short) command. This is a substitue like command, with this signature :

:{range}Architext/{query}(/{capture name}:{replacement})*

Which instanciates into this, to replace every occurence of the identifier foo by bar :

:Architext/((identifier) @i (#eq? @i "foo"))/i:bar/

You can refer to captured nodes like this, lets say you want to wrap an identifier into a function:

:A/((identifier) @wrapit (#eq? @wrapit "foo"))/wrapit:func(@wrapit)/

Additional notes :

  • The delimiter can be anything, and is specified by the first character after the command
  • You can insert a literal @ like so @@

Query templates

You can recall query templates by starting the query argument with a $. Query templates are called like so :

$TEMPLATE:arg1:arg2:...

The : can be replaced by any non uppercase character (though, : is recommended).

If you want to omit an argument :

$TEMPLATE::arg2:...

While this might seem useful, and robust, it is actually not, and no check is done on the number of arguments you pass to a query, and wether they are expected.

Writing templates

Writing templates is easy, and follows an over-simplified snippet-like syntax, for example the builtin IDENT template looks like this :

((identifier) @id (#eq? @id "$1"))

Arguments of the template are called with ${number}, 1-based (why not ?).

Using the API

The main function une architext is architext.edit.edit, which contains all the machinery for handling replacements on (non-template) queries.

The signature is as follows:

edit(buf, parser, query, changes, start_row, end_row)

The arguments are thus:

  1. The buffer number where the edits take place
  2. The parser to use for that given buffer
  3. The query used as reference for matching the tree (think the first part of the :Architext command)
  4. The actual changes to perform, in the form of a map between capture names and their replacements (think, the rest of the :Architext command): note the there must not be the leading @ in the capture names.
  5. The start row (inclusive)
  6. The end row (inclusive)

As an example, here is the API to swap the first two arguments of function calls in lua:

local curbuf = vim.api.nvim_get_current_buf()
local parser = vim.treesitter.get_parser(curbuf)

local query = vim.treesitter.query.parse("lua", [[
  (arguments 
    . (_) @first
    . (_) @second)
]])

require'architext.edit'.edit(curbuf, parser, query, { first =
"@second", second = "@first" }, 0, 10)

Credits

Thanks @tjdevries for the name.

architext.nvim's People

Contributors

famiu avatar molleweide avatar sh3rm4n avatar vigoux avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

architext.nvim's Issues

How to use the REPL

I'm trying to understand how to use the REPL. I started it and tried to enter either (identifier) @i or ((identifier) @i (#eq? @i "foo")), then it says Capture i> and I enter something but nothing really happens. After that whatever I enter it just stays at the Query> prompt.

Then I tried to close it with exit or quit but didn't work so I closed with <esc>:q. But then if I open the REPL again I get:

E5108: Error executing lua ...te/pack/packer/opt/architext.nvim/lua/architext/repl.lua:91: Vim:E95: Buffer with this name already exists

Sorry for my ignorance but would be happy to hear how to use it properly :)

Where can I add my own templates?

Where do I actually add templates? Can I do it in a config file? On the vim prompt? Or do I have to add them to query.lua?

Sorry if this is a stupid question and there is an easy way to add stuff to the templates variable in query.lua from a config file or something. I don't know much about the nvim plugin architecture or lua or whatever is needed for this.

architext UI options

Hi again Vigoux,

Idea:

When you call ArchitextREPL you coul optionally edit the query in a buffer split or a nui.nvim popup so that one can more freely move around and edit the query and also save the query to a templates dir. (edit: I just saw that you have also made a template plugin which I am going to checkout)

I will look into this because it could be quite fun.

Cheers,

Feature request: call `cmd.run` with `table` arg and apply changes to `file/path` instead of open `buffer`.

Hi Vigoux,

This plugin is such a cool tool and I am studying the source now when I am learning about treesitter.

feat req

I would like to be able to apply edits with architext to a filepath instead of open buffer. My thinking is to modify the cmd.run func and make it so that you can pass a table with all necessary params, (including path = ...) so that

Do you have any recommendations on how to write the edits to a file that has not been loaded into a buffer? I see that many of you who are more proficient with treesitter and lsp use the lsp_range in order to make edits but I am not sure how to use this when writing to a file not yet loaded into buffer. Browsing through the docs myself I am not yet sure which is the more correct way of doing this?

If you could give me some guidance on how to write edits to a file, then I would like to try to make a pull request for this feature.

edit start

I have been thinking about the vim.lsp.utils.apply_text_edits function and realise that it updates all captures across the whole project and so maybe it is a requirement that one first reads the file into a buffer.

Maybe, something like vim.lsp.buf.references could be used to find references for the filepath and then you would manually update all paths that include the references?

edit end

Please tell me if you understand my idea :)

my use case

I am using doom-nvim and am working on some fun UI for the next unreleased version. If it was possible to use Architext on a filepath, then it would be quite easy to make some cool UI for doom that allows you to toggle and update config settings with eg. telescope really fast.

An example would be toggle module(s) action where I'd pipe all config modules into telescope, and then if you select module x then I would tell Architext find module name x in the module_enabled file and then comment it out and reload the config. So that one could eg. batch turn on/off all config modules in one single command with Architext.

question about the code

How does the command understand that everything after :A is the argument for the command? I read about under the map.txt docs but I don't understand what it is that specifies this?

Cheers.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.