• Stars
    star
    194
  • Rank 200,219 (Top 4 %)
  • Language
    Scheme
  • License
    Apache License 2.0
  • Created over 3 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Tree-sitter powered textobjects for evil mode in Emacs

evil-textobj-tree-sitter

MELPA test

Tree-sitter powered textobjects for Emacs. You can use them with evil-mode or with thing-at-point.

gif

This package will let you create evil textobjects using tree-sitter grammars. You can easily create function,class,comment etc textobjects in multiple languages. It also make additional things available in thing-at-point like function, class, loop, comment etc.

It can work with either elisp-tree-sitter or the builtin treesit library.

Installation

You can install evil-textobj-tree-sitter from melpa. Here is how you would do it using use-package and package.el:

(use-package evil-textobj-tree-sitter :ensure t)

Or you can use straight.el:

(use-package evil-textobj-tree-sitter :straight t)

Or using straight.el and el-get to pull from source:

(use-package evil-textobj-tree-sitter
  :straight (evil-textobj-tree-sitter :type git
                      :host github
                      :repo "meain/evil-textobj-tree-sitter"
                      :files (:defaults "queries" "treesit-queries")))

You will also have to setup tree-sitter.

Usage

thing-at-point additions

The package adds more "things" to thing-at-point. You can find all the things that it adds in the source.

You can use these like any other thing-at-point entries. For example in case of functions, we make the following available:

  • (thing-at-point 'function)
  • (function-at-point)

Mapping textobjects

By default, the library does not provide any keybindings, but it should be relatively easy to add them.

;; bind `function.outer`(entire function block) to `f` for use in things like `vaf`, `yaf`
(define-key evil-outer-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.outer"))
;; bind `function.inner`(function block without name and args) to `f` for use in things like `vif`, `yif`
(define-key evil-inner-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.inner"))

;; You can also bind multiple items and we will match the first one we can find
(define-key evil-outer-text-objects-map "a" (evil-textobj-tree-sitter-get-textobj ("conditional.outer" "loop.outer")))

Custom textobjects

If you are not able to find the text object that you are looking for in the builtin list, you can create custom text objects by passing the a custom query with captures.

For example if you want to create text object to select import statements, you can write something like below. You will have to provide the tree-sitter queries for all the languages that you want it to work for

;; The first arguemnt to `evil-textobj-tree-sitter-get-textobj' will be the capture group to use
;; and the second arg will be an alist mapping major-mode to the corresponding query to use.
(define-key evil-outer-text-objects-map "m" (evil-textobj-tree-sitter-get-textobj "import"
                                              '((python-mode . [(import_statement) @import])
                                                (rust-mode . [(use_declaration) @import]))))

Goto

We have also added support for for a fancier version of goto-char. You can use this to go to the next function, previous class or do any motions like that.

You can use the evil-textobj-tree-sitter-goto-textobj function to invoke goto. You can either use this in other function or just bound to a key. The first argument is the textobj that you want to use, the second one specifies if you want to search forward or backward and the last one is for specifying weather to go to the start or end of the textobj.

Below are some sample binding that you can do. You can use any textobj that is available here.

;; Goto start of next function
(define-key evil-normal-state-map
            (kbd "]f")
            (lambda ()
              (interactive)
              (evil-textobj-tree-sitter-goto-textobj "function.outer")))

;; Goto start of previous function
(define-key evil-normal-state-map
            (kbd "[f")
            (lambda ()
              (interactive)
              (evil-textobj-tree-sitter-goto-textobj "function.outer" t)))

;; Goto end of next function
(define-key evil-normal-state-map
            (kbd "]F")
            (lambda ()
              (interactive)
              (evil-textobj-tree-sitter-goto-textobj "function.outer" nil t)))

;; Goto end of previous function
(define-key evil-normal-state-map
            (kbd "[F")
            (lambda ()
              (interactive)
              (evil-textobj-tree-sitter-goto-textobj "function.outer" t t)))

Finding and contributing to textobjects

evil-textobj-tree-sitter work with both builtin treesit and elisp-tree-sitter. The queries in use are a bit different in both cases with the elisp-tree-sitter version currently being more feature complete. In both cases we pull the queries from external sources. For elisp-tree-sitter, we source them from nvim-treesitter/nvim-treesitter-textobjects and is places into queries directory. And for treesit queries, it is sourced from helix and placed in treesit-queries. You can check these files to see what all is available. If you are interesting in contributing additional textobjects, you can do so by submitting to the respective projects. If there is enough interest, I don't mind starting to manage queries ourselves.

If you are adding a completely new language, there is two other things that you will have to do to make sure everything will work well.

  1. Make sure the lang is available in emacs-tree-sitter/tree-sitter-langs or treesit.
  2. Make sure we have a major-mode mapping in evil-textobj-tree-sitter-major-mode-language-alist

If you would like to test out new textobjects, I would suggest using custom textobjects. If you want to edit the query files, you can edit them in evil-textobj-tree-sitter--queries-dir or by forking the repo, and using the forked version with your edits.

License

The primary codebase is licensed under Apache-2.0. The queries have be taken from nvim-treesitter/nvim-treesitter-textobjects which is also licensed under the same license.

More Repositories

1

dotfiles

If there is a shell, there is a way!
Emacs Lisp
228
star
2

vim-package-info

Vim plugin to quickly view info about the packages you use
JavaScript
71
star
3

vim-printer

Quickly print/log the variable in your favourite language
Vim Script
44
star
4

s3-mounter

Mount s3 buckets into pods in k8s
Dockerfile
39
star
5

scopeline.el

Show info about the block at the end of the block
Emacs Lisp
35
star
6

vim-colorswitch

Cycle between hex, rgb, hsl colors defined in current line
Python
29
star
7

gloc

Run a shell command in all the git repos in a directory.
Go
22
star
8

stag

Tag your local music using spotify api
Python
17
star
9

gourcer

Shell
16
star
10

ytdd

Go
15
star
11

gh-issues-to-rss

Convert github issues and prs into rss feed
Go
13
star
12

hima-theme

A minimal theme with pretty colors
Emacs Lisp
10
star
13

startpage

Custom startpage and newtabpage
JavaScript
9
star
14

logseq-plugin-runjs

Run arbitrary JS in your LogSeq pages
TypeScript
9
star
15

yap

Your Assistant for Prompting LLMs
Emacs Lisp
9
star
16

vim-jsontogo

Vim plugin to convert from json to go struct
Vim Script
8
star
17

temper

A small utility to show presentation in shell
Shell
7
star
18

logseq-plugin-refile

A LogSeq plugin to refile items in your graph
JavaScript
7
star
19

mucri

Quickly fetch a lot of pages/apis using python asyncio
Python
6
star
20

toffee

Universal(in future) test picker
Rust
6
star
21

ppl

The progress bar library that started with the idea of looking pretty
Python
6
star
22

hima-vim

Minimal light colorschme with good GUI element colors
Vim Script
6
star
23

yaq

Your Assistant for Querying (the web using LLMs)
JavaScript
6
star
24

emacsconf-talk-tree-sitter

Slides/Files for EmacsConf 2022 talk "Tree-sitter beyond syntax highlighting"
Rust
5
star
25

v

Quick access to recent files in any Vim clone
Shell
5
star
26

pbbui

A UI for Pure Bash Bible by dylanaraps
JavaScript
5
star
27

quif

Electron app to share files from your laptop via QR codes
JavaScript
5
star
28

marker

Markdown based presentation tool, the good parts.
JavaScript
4
star
29

programmingfonts-screenshots

Shell
3
star
30

vroom

Run VIM macros from cli
Rust
2
star
31

react-quick-select

Quick inline select for react
JavaScript
2
star
32

logseq-plugin-noisy

Enhance your LogSeq experience with sounds
JavaScript
2
star
33

meain.github.io

Personal website. Nothing fancy.
JavaScript
1
star
34

tint

Tree-sitter powered linter
Go
1
star
35

push

Push notes or files to pushbullet
Go
1
star
36

nur-packages

Personal NUR packages
Nix
1
star
37

rust-errors-talk

Rust
1
star
38

venv

Easier workflow for python virtualenvs
Shell
1
star
39

nn

Quick little bot to run shell commands on servers via matrix
Go
1
star
40

cusat-exam-scraper

I was bored one day
Python
1
star
41

tojson

Convert between toml, yaml and json
Rust
1
star
42

minimal-dotfiles

Quickly setup a working environment in servers
Shell
1
star
43

vim-searcher

Search from right within vim
Vim Script
1
star
44

kudo

Manage your todos in Kubernetes using CRD
Shell
1
star
45

depman

Terminal UI for dependency management
Rust
1
star
46

gn

JavaScript
1
star
47

webpageget

Get webpage content in different formats
JavaScript
1
star
48

asin

Just taking care of a small annoyance
HTML
1
star
49

dopy

Simple bash script to download and put files in a specified location
Shell
1
star
50

logseq-plugin-favorite-jump

Use shortcuts to switch between favorite pages
JavaScript
1
star
51

cachehandler

Cache api function callbacks or image links
Python
1
star
52

bridge

Bridging the link between teachers and students
Python
1
star
53

kabarna

In browser model training using tensorflow.js
JavaScript
1
star
54

diagramdraft

Create mermaid diagrams online and export them
JavaScript
1
star
55

glee

Hoogle, but for every language
Go
1
star
56

tree-surgeon

Code manipulation utilities for Emacs using tree-sitter
Emacs Lisp
1
star
57

sleed

Speed up or slow down any video on the internet
JavaScript
1
star