Giter VIP home page Giter VIP logo

evil-textobj-tree-sitter's Introduction

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.

evil-textobj-tree-sitter's People

Contributors

aaronjensen avatar acristoffers avatar dvzubarev avatar leungbk avatar matth0204 avatar meain avatar p00f avatar tampix avatar wakira 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  avatar  avatar  avatar

evil-textobj-tree-sitter's Issues

doesn't work with rustic

I'm using (according to this comment)

However, this doesn't work for evil-textobj-tree-sitter. This change works, not sure if this is ideal:

diff --git a/evil-textobj-tree-sitter-core.el b/evil-textobj-tree-sitter-core.el
index 818e99a..0ab321a 100644
--- a/evil-textobj-tree-sitter-core.el
+++ b/evil-textobj-tree-sitter-core.el
@@ -61,7 +61,8 @@
 (defun evil-textobj-tree-sitter--use-builtin-treesitter ()
   "Return non-nil if we should use builtin treesitter."
   (and evil-textobj-tree-sitter--can-use-builtin-treesit
-       (string-suffix-p "-ts-mode" (symbol-name major-mode))))
+       (or (string= "rustic-mode" (symbol-name major-mode))
+           (string-suffix-p "-ts-mode" (symbol-name major-mode)))))
 
 (defun evil-textobj-tree-sitter--get-queries-dir ()
   "Get the queries directory.

Query to get function name from within function body

Hi,

I really like this package in emacs and I use it on a daily basis. I wrote a simple custom query which does just return the identifier at point. This way I can yank function names, variable names etc. without caring about parenthesis at the end of them or underscores in them. (Compared to yanking with yiW or yiw)
FWIW here's what I got:

(map! :map evil-inner-text-objects-map
      "u" (evil-textobj-tree-sitter-get-textobj "identifier"
                '((c-mode . [(identifier) @identifier ]))))

(Using doom emacs, that is where that map! macro is from. But the query itself is the same)

Now often find myself in the situation where I navigate a file looking for a function to use in may program. When I want to copy that function name to call it, it have to move point into the function name and yank it with yiu. I wondered if it is possible to yank the function name (and maybe with evil-outer-text-objects-map the whole declaration from the functions name to the end of the parameters) when point is only within the function body, not at the function name.
I thought maybe to use @function.outer from this repository then get the first identifier from that. But I don't know how. Can you help me out?

Also are there any resources where this query languages is described with some examples? That would be really helpful.

Problems with R

Thanks for putting this package together. I am very excited to use it. Trying it out things seem to work as expected when working in python. Not so much for R.

For example, trying any of the following bindings out in R inevitably ends with a "No [function.outer] text object found."

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

;; 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")))

Any advice?

Implement `inhertis` marker support

This is something that I overlooked in my initial implementation. In case of the neovim project, they provide an option to inherit files from other language textobjects using ; inherits: <lang> marker at the top of the file. We will have to reimplement this logic on our side to be able to use a bunch of the defined textobjects.

Ref: nvim-treesitter/nvim-treesitter#564


Check the file manually, if you find an inherit line and include the code in that file to this. Do this recursively.

No `parameter.outer` text object found

Hi there,

this is an awesome project! Thanks so much for your work on this.

Using the following configuration

  (use-package evil-textobj-tree-sitter
    :ensure t
    :config
    (define-key evil-outer-text-objects-map "a" (evil-textobj-tree-sitter-get-textobj "parameter.outer"))
    (define-key evil-inner-text-objects-map "a" (evil-textobj-tree-sitter-get-textobj "parameter.inner")))

I expect commands like via and vaa to visually select inner and outer parameters, respectively.

The inner parameter works as expected, but the outer parameter provides me the error

No ’parameter.outer’ text object found

This text object is included in the nvim-treesitter-textobjects repository1 so I figured it would be a part of this package too. Am I missing some reason it's not included, or have I bungled my configuration somehow?

Footnotes

  1. https://github.com/nvim-treesitter/nvim-treesitter-textobjects#built-in-textobjects

Usage question: How to define a mapping for inner object

First, thanks for the amazing work that's done here.

I'm using the following to create a text obj keymap:

(define-key evil-outer-text-objects-map ":" (evil-textobj-tree-sitter-get-textobj "pair.outer"
                                              '((imba-mode . [(pair value: (_) @pair.inner) @pair.outer]))))

But I want to change the inner part of the query with ci:. Now only ca: works.

Any clues?

Selecting something that doesn't match at point has surprising results

If I have a Rust file like the following

fn blah() { 1234 }

fn baz() {
  let x = 5678;
}

and put point inside the definition of blah, then the @argument.inner motion will jump all the way to the definition of baz. This is very surprising; imo if there's no text object matching the query that contains point, it should just fail.

Emacs treesit experiments

Hi, I wanted to share my experiments with the Emacs builtin treesit library.
Recently, there were added some functions for creating arbitrary thing at points from the parse tree nodes.
I had an idea to implement text objects based on these things.
The basic idea is to search current thing at point.
Then extend or shrink its bounds according to current modifier (inner, outer, etc.).

There are pros and cons for this approach in comparison with the query based approach.
On the good side, It is more efficient approach, since it does not require to query the whole buffer with bunch of queries.
Its working by local traversing of the tree nodes, that are near the point.
So performance of this approach should not be affected by the size of the buffer.
Also, it allows more fine-grained control of text object ranges.
For example, for parameter outer, its possible to include surrounding spaces.
There are also possibilities to make fancier text objects.

The main downside is the lack of language support.
Since we cannot use community queries, we have to create settings for each language from the scratch.

I ended up crafting a package out of this experiments for my personal use - https://github.com/dvzubarev/evil-ts-obj.
Please feel free to check it out, it would be great to hear some feedback.

Issue with sorting of nested objects in multibyte buffer

Consider this test case:

(ert-deftest evil-textobj-tree-sitter-within-unicode-test4
    ()
  "Check sorting of nested object in multibyte file"
  (let* ((bufname (concat (make-temp-name "evil-textobj-tree-sitter-test--")
                          ".c"))
         (filename (concat "/tmp/" bufname)))
    (find-file filename)
    (with-current-buffer bufname
      (insert "// Комментарий Комментарий Комментарий Комментарий Комментарий
int main() {
    if (1) if (0) { true; }
}")
      (tree-sitter-mode)
      (goto-char 100)
      (should (equal (evil-textobj-tree-sitter--range 1
                                                      (list (intern "conditional.outer"))) (cons 88 104))))
    (set-buffer-modified-p nil)
    (kill-buffer bufname)))

The point is inside the inner if statement and I expect that it should be selected, but the outer if is selected.
When converting pos to bytes in sorting predicate, this test passes, e.g.

(defun evil-textobj-tree-sitter--nodes-within (nodes)
  "NODES which contain the current point inside them ordered inside out."
  (let ((byte-pos (position-bytes (point))))
    (sort (cl-remove-if-not (lambda (x)
                              (and (<= (byte-to-position (car (tsc-node-byte-range x))) (point))
                                   (< (point) (byte-to-position (cdr (tsc-node-byte-range x))))))
                            nodes)
          (lambda (x y)
            (< (+ (abs (- byte-pos
                          (car (tsc-node-byte-range x))))
                  (abs (- byte-pos
                          (cdr (tsc-node-byte-range x))))) (+ (abs (- byte-pos
                          (car (tsc-node-byte-range y))))
                  (abs (- byte-pos
                          (cdr (tsc-node-byte-range y))))))))))

Create text object bindings only for treesitter mode

I have a conflict for the f textobject: In emacs lisp, I want to use the function textobject provided by lispyville, since there is no tree-sitter support for emacs lisp yet. On the other hand, in other programming modes like python, I still want to use the treesitter text objects.

Is there a way I can add these text objects only for tree-sitter mode? Maybe somehow adding them in a buffer local way and use hooks. I guess it's non-trivial because evil-inner-textobj-map/evil-outer-textobj-map are global and not buffer-local. Maybe it would be possible to have a custom evil-treesitter-inner-textobject-map that extends the non-treesitter equivalent, which can be enabled/disabled via a minor mode? I'm not super experience with emacs lisp either, but this is my guess how this could be done.

Actually, this also seems to be an issue on the lispyville side, since they also set their textobjects globally. I found they have even a TODO in their code, but found no corresponding issue, so I just now also created an issue over there.

Remove hard dependency on evil-mode

99% of the code does not depend on evil, it is just the final selection which uses evil. I was thinking that maybe we could expand this to be used without evil as well if there is enough demand. There could be two functionalities that people would primarily use.

  • Get a region (just using as a util func)
  • Bind a keybinding to mark a region of a specific "textobj" to be worked on further by invoking another command

Override `node` with `node.start` if available

We have a few nodes which could have overriding definitions in the same match (example). We have to override the inner one with .start one if this is present.

(decorated_definition
  (function_definition) @function.outer) @function.outer.start

In the above case, we have to use function.outer if function.outer.start is not available, but the latter otherwise and ignore function.outer. We have to remove the first one as otherwise we will have two starts for the same function.

@function.outer.start are optional decorations for the textobject like doctrings or template declarations. They will be added to the textobject range if present.

New Querys

Hi so I am currently working on tree sitter support for doom emacs and i was wondering if you would accept PR's for new querys or if you would prefer them to be upstreamed to neovim?

as far as I am seeing its just a matter of adding the query to the textobjs.scm and it should work ™️ but I could be very wrong.

Thanks for any input you could have

evil-textobj-tree-sitter--treesit-get-nodes: Wrong type argument: treesit-query-p, nil

I'm using typescript with typescript-ts-mode and I defined the text objects suggested in the doc:

(define-key evil-outer-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.outer"))
(define-key evil-inner-text-objects-map "f" (evil-textobj-tree-sitter-get-textobj "function.inner"))

but I get the error evil-textobj-tree-sitter--treesit-get-nodes: Wrong type argument: treesit-query-p, nil every time I try to do something with the object. I'm using emacs 29.1 with the built in tree-sitter implementation.

Thanks!

Add support for additional queries locations

Problem statement

When working on a tree-sitter grammar locally, I need to add the query file to the tree-sitter-langs folder. And I need to make sure I do that again when I upgrade the package or something.

Suggested solution

Just like tree-sitter-load-path which is a list of directories to search for shared libraries that define languages, I suggest adding an evil-textobj-tree-sitter-load-path list to search for queries in.
Something like this would probably do.

(full-path (seq-some (lambda (base-name)
                               (locate-file base-name
                                            tree-sitter-load-path
                                            tree-sitter-load-suffixes))
                             files))

evil-textobj-tree-sitter-get-textobj generate invalid code with multiple bidings

How to reproduce

Take the example in the README :

(macroexpand '(evil-textobj-tree-sitter-get-textobj ("conditional.inner" "loop.inner")))

This will generate code looking like :

		     (if
		      (not
		       (eq range nil))
		      (evil-range
		       (car range)
		       (cdr range))
		      (message
		       (concat "No '"
			       ("conditional.inner" "loop.inner")
			       "' text object found"))))))

Which leads to this error when byte-compiling :

Warning: ‘"conditional.outer"’ is a malformed function

java switch_expression node causing errors.

Hello again!

I have found a bug in the java queries where the switch_expression node type is being called as invalid.
commenting out the query (line 30) in question fixes this but is not ideal for obvious reasons.
I may be able to provide a replacement but not for a bit as I have the first round of {tests, coursework} coming up and I won't have the time for a couple of weeks


backtrace:

Debugger entered--Lisp error: (tsc-query-invalid-node-type "switch_expression" (30 . 1) 655)
  signal(tsc-query-invalid-node-type ("switch_expression" (30 . 1) 655))
  (if (not (memq (car err) '(end-of-line end-of-buffer))) (signal (car err) (cdr err)) (message (error-message-string err)))
  (prog1 nil (evil-repeat-abort) (if (not (memq (car err) '(end-of-line end-of-buffer))) (signal (car err) (cdr err)) (message (error-message-string err))))
  (condition-case err (let ((repeat-type (evil-repeat-type motion t))) (if (functionp repeat-type) (funcall repeat-type 'pre)) (if (condition-case nil (let ((inhibit-quit nil)) (setq range (call-interactively motion)) t) (quit (setq quit-flag t) (eval '(ignore nil)))) nil (evil-repeat-abort) (setq quit-flag t)) (if (functionp repeat-type) (funcall repeat-type 'post))) (error (prog1 nil (evil-repeat-abort) (if (not (memq (car err) '(end-of-line end-of-buffer))) (signal (car err) (cdr err)) (message (error-message-string err))))))
  (let ((current-prefix-arg count) (evil-this-type (or type (evil-type motion 'exclusive)))) (condition-case err (let ((repeat-type (evil-repeat-type motion t))) (if (functionp repeat-type) (funcall repeat-type 'pre)) (if (condition-case nil (let ((inhibit-quit nil)) (setq range (call-interactively motion)) t) (quit (setq quit-flag t) (eval '...))) nil (evil-repeat-abort) (setq quit-flag t)) (if (functionp repeat-type) (funcall repeat-type 'post))) (error (prog1 nil (evil-repeat-abort) (if (not (memq (car err) '...)) (signal (car err) (cdr err)) (message (error-message-string err)))))) (cond ((evil-range-p range)) ((evil-visual-state-p) (setq range (evil-visual-range))) ((region-active-p) (setq range (evil-range (region-beginning) (region-end) evil-this-type))) (t (setq range (evil-expand-range (evil-normalize evil-motion-marker (point) evil-this-type))))) (if (or (null type) (eq (evil-type range) type)) nil (evil-set-type range type) (evil-expand-range range)) (evil-set-range-properties range nil) range)
  (unwind-protect (let ((current-prefix-arg count) (evil-this-type (or type (evil-type motion 'exclusive)))) (condition-case err (let ((repeat-type (evil-repeat-type motion t))) (if (functionp repeat-type) (funcall repeat-type 'pre)) (if (condition-case nil (let (...) (setq range ...) t) (quit (setq quit-flag t) (eval ...))) nil (evil-repeat-abort) (setq quit-flag t)) (if (functionp repeat-type) (funcall repeat-type 'post))) (error (prog1 nil (evil-repeat-abort) (if (not (memq ... ...)) (signal (car err) (cdr err)) (message (error-message-string err)))))) (cond ((evil-range-p range)) ((evil-visual-state-p) (setq range (evil-visual-range))) ((region-active-p) (setq range (evil-range (region-beginning) (region-end) evil-this-type))) (t (setq range (evil-expand-range (evil-normalize evil-motion-marker (point) evil-this-type))))) (if (or (null type) (eq (evil-type range) type)) nil (evil-set-type range type) (evil-expand-range range)) (evil-set-range-properties range nil) range) (if evil-inhibit-operator nil (set-buffer obuffer) (evil-move-mark omark) (goto-char opoint)) (move-marker evil-motion-marker nil))
  (let ((evil-restriction-stack (cons (cons (point-min) (point-max)) evil-restriction-stack))) (evil-narrow (field-beginning) (field-end)) (unwind-protect (let ((current-prefix-arg count) (evil-this-type (or type (evil-type motion 'exclusive)))) (condition-case err (let ((repeat-type (evil-repeat-type motion t))) (if (functionp repeat-type) (funcall repeat-type 'pre)) (if (condition-case nil (let ... ... t) (quit ... ...)) nil (evil-repeat-abort) (setq quit-flag t)) (if (functionp repeat-type) (funcall repeat-type 'post))) (error (prog1 nil (evil-repeat-abort) (if (not ...) (signal ... ...) (message ...))))) (cond ((evil-range-p range)) ((evil-visual-state-p) (setq range (evil-visual-range))) ((region-active-p) (setq range (evil-range (region-beginning) (region-end) evil-this-type))) (t (setq range (evil-expand-range (evil-normalize evil-motion-marker ... evil-this-type))))) (if (or (null type) (eq (evil-type range) type)) nil (evil-set-type range type) (evil-expand-range range)) (evil-set-range-properties range nil) range) (if evil-inhibit-operator nil (set-buffer obuffer) (evil-move-mark omark) (goto-char opoint)) (move-marker evil-motion-marker nil)))
  (save-restriction (let ((evil-restriction-stack (cons (cons (point-min) (point-max)) evil-restriction-stack))) (evil-narrow (field-beginning) (field-end)) (unwind-protect (let ((current-prefix-arg count) (evil-this-type (or type (evil-type motion ...)))) (condition-case err (let ((repeat-type ...)) (if (functionp repeat-type) (funcall repeat-type ...)) (if (condition-case nil ... ...) nil (evil-repeat-abort) (setq quit-flag t)) (if (functionp repeat-type) (funcall repeat-type ...))) (error (prog1 nil (evil-repeat-abort) (if ... ... ...)))) (cond ((evil-range-p range)) ((evil-visual-state-p) (setq range (evil-visual-range))) ((region-active-p) (setq range (evil-range ... ... evil-this-type))) (t (setq range (evil-expand-range ...)))) (if (or (null type) (eq (evil-type range) type)) nil (evil-set-type range type) (evil-expand-range range)) (evil-set-range-properties range nil) range) (if evil-inhibit-operator nil (set-buffer obuffer) (evil-move-mark omark) (goto-char opoint)) (move-marker evil-motion-marker nil))))
  (progn (evil-save-transient-mark-mode) (evil-transient-mark 1) (save-restriction (let ((evil-restriction-stack (cons (cons (point-min) (point-max)) evil-restriction-stack))) (evil-narrow (field-beginning) (field-end)) (unwind-protect (let ((current-prefix-arg count) (evil-this-type (or type ...))) (condition-case err (let (...) (if ... ...) (if ... nil ... ...) (if ... ...)) (error (prog1 nil ... ...))) (cond ((evil-range-p range)) ((evil-visual-state-p) (setq range ...)) ((region-active-p) (setq range ...)) (t (setq range ...))) (if (or (null type) (eq ... type)) nil (evil-set-type range type) (evil-expand-range range)) (evil-set-range-properties range nil) range) (if evil-inhibit-operator nil (set-buffer obuffer) (evil-move-mark omark) (goto-char opoint)) (move-marker evil-motion-marker nil)))))
  (unwind-protect (progn (evil-save-transient-mark-mode) (evil-transient-mark 1) (save-restriction (let ((evil-restriction-stack (cons (cons ... ...) evil-restriction-stack))) (evil-narrow (field-beginning) (field-end)) (unwind-protect (let ((current-prefix-arg count) (evil-this-type ...)) (condition-case err (let ... ... ... ...) (error ...)) (cond (...) (... ...) (... ...) (t ...)) (if (or ... ...) nil (evil-set-type range type) (evil-expand-range range)) (evil-set-range-properties range nil) range) (if evil-inhibit-operator nil (set-buffer obuffer) (evil-move-mark omark) (goto-char opoint)) (move-marker evil-motion-marker nil))))) (evil-restore-transient-mark-mode))
  (let ((inhibit-quit t) evil-transient-vals) (unwind-protect (progn (evil-save-transient-mark-mode) (evil-transient-mark 1) (save-restriction (let ((evil-restriction-stack (cons ... evil-restriction-stack))) (evil-narrow (field-beginning) (field-end)) (unwind-protect (let (... ...) (condition-case err ... ...) (cond ... ... ... ...) (if ... nil ... ...) (evil-set-range-properties range nil) range) (if evil-inhibit-operator nil (set-buffer obuffer) (evil-move-mark omark) (goto-char opoint)) (move-marker evil-motion-marker nil))))) (evil-restore-transient-mark-mode)))
  (let ((opoint (point)) (omark (mark t)) (obuffer (current-buffer)) (evil-motion-marker (move-marker (make-marker) (point))) range) (let ((inhibit-quit t) evil-transient-vals) (unwind-protect (progn (evil-save-transient-mark-mode) (evil-transient-mark 1) (save-restriction (let ((evil-restriction-stack ...)) (evil-narrow (field-beginning) (field-end)) (unwind-protect (let ... ... ... ... ... range) (if evil-inhibit-operator nil ... ... ...) (move-marker evil-motion-marker nil))))) (evil-restore-transient-mark-mode))))
  evil-motion-range(evil-textobj-tree-sitter-function--class\.outer nil nil)
  (setq range (evil-motion-range motion count type))
  (let ((evil-state 'operator) mark-active) (setq range (evil-motion-range motion count type)))
  (progn (let ((evil-state 'operator) mark-active) (setq range (evil-motion-range motion count type))))
  (if motion (progn (let ((evil-state 'operator) mark-active) (setq range (evil-motion-range motion count type)))))
  (progn (if motion nil (evil-change-state 'operator) (let ((keys (nth 2 (evil-extract-count (this-command-keys))))) (setq keys (listify-key-sequence keys)) (let ((--dotimes-limit-- (length keys)) (--dotimes-counter-- 0)) (while (< --dotimes-counter-- --dotimes-limit--) (let ((var --dotimes-counter--)) (define-key evil-operator-shortcut-map (vconcat ...) 'evil-line-or-visual-line)) (setq --dotimes-counter-- (1+ --dotimes-counter--))))) (setq command (evil-read-motion motion) motion (nth 0 command) count (nth 1 command) type (or type (nth 2 command)))) (cond ((eq motion #'undefined) (setq range (if return-type '(nil nil nil) '(nil nil)) motion nil)) ((or (null motion) (evil-get-command-property motion :suppress-operator)) (if (fboundp 'evil-repeat-abort) (progn (evil-repeat-abort))) (setq quit-flag t motion nil)) (evil-repeat-count (setq count evil-repeat-count evil-repeat-count nil)) ((or count current-prefix-arg) (setq count (* (prefix-numeric-value count) (prefix-numeric-value current-prefix-arg))))) (if motion (progn (let ((evil-state 'operator) mark-active) (setq range (evil-motion-range motion count type))))) (setq evil-this-motion motion evil-this-motion-count count type (evil-type range type) evil-this-type type))
  (unwind-protect (progn (if motion nil (evil-change-state 'operator) (let ((keys (nth 2 (evil-extract-count ...)))) (setq keys (listify-key-sequence keys)) (let ((--dotimes-limit-- (length keys)) (--dotimes-counter-- 0)) (while (< --dotimes-counter-- --dotimes-limit--) (let (...) (define-key evil-operator-shortcut-map ... ...)) (setq --dotimes-counter-- (1+ --dotimes-counter--))))) (setq command (evil-read-motion motion) motion (nth 0 command) count (nth 1 command) type (or type (nth 2 command)))) (cond ((eq motion #'undefined) (setq range (if return-type '(nil nil nil) '(nil nil)) motion nil)) ((or (null motion) (evil-get-command-property motion :suppress-operator)) (if (fboundp 'evil-repeat-abort) (progn (evil-repeat-abort))) (setq quit-flag t motion nil)) (evil-repeat-count (setq count evil-repeat-count evil-repeat-count nil)) ((or count current-prefix-arg) (setq count (* (prefix-numeric-value count) (prefix-numeric-value current-prefix-arg))))) (if motion (progn (let ((evil-state 'operator) mark-active) (setq range (evil-motion-range motion count type))))) (setq evil-this-motion motion evil-this-motion-count count type (evil-type range type) evil-this-type type)) (if (buffer-live-p buf) (progn (save-current-buffer (set-buffer buf) (evil-change-state old-state)))))
  (let* ((evil-state evil-state) (evil-previous-state evil-previous-state) (evil-previous-state-alist (copy-tree evil-previous-state-alist)) (evil-next-state evil-next-state) (old-state evil-state) (inhibit-quit t) (buf (current-buffer))) (unwind-protect (progn (if motion nil (evil-change-state 'operator) (let ((keys (nth 2 ...))) (setq keys (listify-key-sequence keys)) (let ((--dotimes-limit-- ...) (--dotimes-counter-- 0)) (while (< --dotimes-counter-- --dotimes-limit--) (let ... ...) (setq --dotimes-counter-- ...)))) (setq command (evil-read-motion motion) motion (nth 0 command) count (nth 1 command) type (or type (nth 2 command)))) (cond ((eq motion #'undefined) (setq range (if return-type '... '...) motion nil)) ((or (null motion) (evil-get-command-property motion :suppress-operator)) (if (fboundp 'evil-repeat-abort) (progn (evil-repeat-abort))) (setq quit-flag t motion nil)) (evil-repeat-count (setq count evil-repeat-count evil-repeat-count nil)) ((or count current-prefix-arg) (setq count (* (prefix-numeric-value count) (prefix-numeric-value current-prefix-arg))))) (if motion (progn (let ((evil-state ...) mark-active) (setq range (evil-motion-range motion count type))))) (setq evil-this-motion motion evil-this-motion-count count type (evil-type range type) evil-this-type type)) (if (buffer-live-p buf) (progn (save-current-buffer (set-buffer buf) (evil-change-state old-state))))))
  (cond ((and evil-ex-p evil-ex-range) (setq range evil-ex-range)) ((and (not evil-ex-p) (evil-visual-state-p)) (setq range (evil-visual-range))) ((and (not evil-ex-p) (region-active-p)) (setq range (evil-range (region-beginning) (region-end) (or evil-this-type 'exclusive)))) (t (let* ((evil-state evil-state) (evil-previous-state evil-previous-state) (evil-previous-state-alist (copy-tree evil-previous-state-alist)) (evil-next-state evil-next-state) (old-state evil-state) (inhibit-quit t) (buf (current-buffer))) (unwind-protect (progn (if motion nil (evil-change-state 'operator) (let (...) (setq keys ...) (let ... ...)) (setq command (evil-read-motion motion) motion (nth 0 command) count (nth 1 command) type (or type ...))) (cond ((eq motion ...) (setq range ... motion nil)) ((or ... ...) (if ... ...) (setq quit-flag t motion nil)) (evil-repeat-count (setq count evil-repeat-count evil-repeat-count nil)) ((or count current-prefix-arg) (setq count ...))) (if motion (progn (let ... ...))) (setq evil-this-motion motion evil-this-motion-count count type (evil-type range type) evil-this-type type)) (if (buffer-live-p buf) (progn (save-current-buffer (set-buffer buf) (evil-change-state old-state))))))))
  (progn (evil-echo-area-save) (cond ((and evil-ex-p evil-ex-range) (setq range evil-ex-range)) ((and (not evil-ex-p) (evil-visual-state-p)) (setq range (evil-visual-range))) ((and (not evil-ex-p) (region-active-p)) (setq range (evil-range (region-beginning) (region-end) (or evil-this-type 'exclusive)))) (t (let* ((evil-state evil-state) (evil-previous-state evil-previous-state) (evil-previous-state-alist (copy-tree evil-previous-state-alist)) (evil-next-state evil-next-state) (old-state evil-state) (inhibit-quit t) (buf (current-buffer))) (unwind-protect (progn (if motion nil (evil-change-state ...) (let ... ... ...) (setq command ... motion ... count ... type ...)) (cond (... ...) (... ... ...) (evil-repeat-count ...) (... ...)) (if motion (progn ...)) (setq evil-this-motion motion evil-this-motion-count count type (evil-type range type) evil-this-type type)) (if (buffer-live-p buf) (progn (save-current-buffer ... ...))))))) (if (evil-range-p range) (progn (if (or (null type) (eq (evil-type range) type)) nil (evil-contract-range range) (evil-set-type range type) (evil-expand-range range)) (evil-set-range-properties range nil) (if return-type nil (evil-set-type range nil)) (setq evil-operator-range-beginning (evil-range-beginning range) evil-operator-range-end (evil-range-end range) evil-operator-range-type (evil-type range)))) range)
  (unwind-protect (progn (evil-echo-area-save) (cond ((and evil-ex-p evil-ex-range) (setq range evil-ex-range)) ((and (not evil-ex-p) (evil-visual-state-p)) (setq range (evil-visual-range))) ((and (not evil-ex-p) (region-active-p)) (setq range (evil-range (region-beginning) (region-end) (or evil-this-type 'exclusive)))) (t (let* ((evil-state evil-state) (evil-previous-state evil-previous-state) (evil-previous-state-alist (copy-tree evil-previous-state-alist)) (evil-next-state evil-next-state) (old-state evil-state) (inhibit-quit t) (buf (current-buffer))) (unwind-protect (progn (if motion nil ... ... ...) (cond ... ... ... ...) (if motion ...) (setq evil-this-motion motion evil-this-motion-count count type ... evil-this-type type)) (if (buffer-live-p buf) (progn ...)))))) (if (evil-range-p range) (progn (if (or (null type) (eq (evil-type range) type)) nil (evil-contract-range range) (evil-set-type range type) (evil-expand-range range)) (evil-set-range-properties range nil) (if return-type nil (evil-set-type range nil)) (setq evil-operator-range-beginning (evil-range-beginning range) evil-operator-range-end (evil-range-end range) evil-operator-range-type (evil-type range)))) range) (evil-echo-area-restore))
  (let ((inhibit-quit t) evil-echo-area-message evil-write-echo-area) (unwind-protect (progn (evil-echo-area-save) (cond ((and evil-ex-p evil-ex-range) (setq range evil-ex-range)) ((and (not evil-ex-p) (evil-visual-state-p)) (setq range (evil-visual-range))) ((and (not evil-ex-p) (region-active-p)) (setq range (evil-range (region-beginning) (region-end) (or evil-this-type ...)))) (t (let* ((evil-state evil-state) (evil-previous-state evil-previous-state) (evil-previous-state-alist ...) (evil-next-state evil-next-state) (old-state evil-state) (inhibit-quit t) (buf ...)) (unwind-protect (progn ... ... ... ...) (if ... ...))))) (if (evil-range-p range) (progn (if (or (null type) (eq ... type)) nil (evil-contract-range range) (evil-set-type range type) (evil-expand-range range)) (evil-set-range-properties range nil) (if return-type nil (evil-set-type range nil)) (setq evil-operator-range-beginning (evil-range-beginning range) evil-operator-range-end (evil-range-end range) evil-operator-range-type (evil-type range)))) range) (evil-echo-area-restore)))
  (let* ((evil-ex-p (and (not (minibufferp)) (evil-ex-p))) (motion (or evil-operator-range-motion (if evil-ex-p (progn 'evil-line)))) (type evil-operator-range-type) (range (evil-range (point) (point))) command count) (setq evil-this-type-modified nil) (let ((inhibit-quit t) evil-echo-area-message evil-write-echo-area) (unwind-protect (progn (evil-echo-area-save) (cond ((and evil-ex-p evil-ex-range) (setq range evil-ex-range)) ((and (not evil-ex-p) (evil-visual-state-p)) (setq range (evil-visual-range))) ((and (not evil-ex-p) (region-active-p)) (setq range (evil-range ... ... ...))) (t (let* (... ... ... ... ... ... ...) (unwind-protect ... ...)))) (if (evil-range-p range) (progn (if (or ... ...) nil (evil-contract-range range) (evil-set-type range type) (evil-expand-range range)) (evil-set-range-properties range nil) (if return-type nil (evil-set-type range nil)) (setq evil-operator-range-beginning (evil-range-beginning range) evil-operator-range-end (evil-range-end range) evil-operator-range-type (evil-type range)))) range) (evil-echo-area-restore))))
  evil-operator-range(t)
  (append (evil-operator-range t) (list evil-this-register (evil-yank-handler)))
  (prog1 (append (evil-operator-range t) (list evil-this-register (evil-yank-handler))) (setq orig (point) evil-inhibit-operator-value evil-inhibit-operator) (if nil (if (evil-visual-state-p) (progn (evil-visual-expand-region))) (if (or (evil-visual-state-p) (region-active-p)) (progn (setq deactivate-mark t)))) (cond ((evil-visual-state-p) (evil-visual-rotate 'upper-left)) ((evil-get-command-property 'evil-yank :move-point) (goto-char (or evil-operator-range-beginning orig))) (t (goto-char orig))))
  (let* ((evil-operator-range-motion (if (evil-has-command-property-p 'evil-yank :motion) (progn (or (evil-get-command-property 'evil-yank :motion) #'undefined)))) (evil-operator-range-type (evil-get-command-property 'evil-yank :type)) (orig (point)) evil-operator-range-beginning evil-operator-range-end evil-inhibit-operator) (setq evil-inhibit-operator-value nil evil-this-operator this-command) (setq evil-operator-start-col (current-column)) (prog1 (append (evil-operator-range t) (list evil-this-register (evil-yank-handler))) (setq orig (point) evil-inhibit-operator-value evil-inhibit-operator) (if nil (if (evil-visual-state-p) (progn (evil-visual-expand-region))) (if (or (evil-visual-state-p) (region-active-p)) (progn (setq deactivate-mark t)))) (cond ((evil-visual-state-p) (evil-visual-rotate 'upper-left)) ((evil-get-command-property 'evil-yank :move-point) (goto-char (or evil-operator-range-beginning orig))) (t (goto-char orig)))))
  #<subr call-interactively>(evil-yank nil nil)
  apply(#<subr call-interactively> (evil-yank nil nil))
  explain-pause--wrap-call-interactively(#<subr call-interactively> evil-yank nil nil)
  apply(explain-pause--wrap-call-interactively #<subr call-interactively> (evil-yank nil nil))
  call-interactively(evil-yank nil nil)
  command-execute(evil-yank)

Add CI to check for grammer rules

Issues like #54 and #30 happen because the upstream language bindings are not the latest. Having a CI to check if we have up to date bindings before we merge in the queries could help avoid things like this.

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.