Add syntax-propertize-function to ruby-ts-mode
* lisp/progmodes/ruby-ts-mode.el (ruby-ts--s-p-query): New variable. (ruby-ts--syntax-propertize): New function. (ruby-ts--parser-after-change): New function. (ruby-ts-mode): Use both of them.
This commit is contained in:
parent
f25c15ceb7
commit
d99b5151f8
1 changed files with 84 additions and 1 deletions
|
@ -95,6 +95,11 @@
|
||||||
(declare-function treesit-node-end "treesit.c")
|
(declare-function treesit-node-end "treesit.c")
|
||||||
(declare-function treesit-node-start "treesit.c")
|
(declare-function treesit-node-start "treesit.c")
|
||||||
(declare-function treesit-node-string "treesit.c")
|
(declare-function treesit-node-string "treesit.c")
|
||||||
|
(declare-function treesit-query-compile "treesit.c")
|
||||||
|
(declare-function treesit-query-capture "treesit.c")
|
||||||
|
(declare-function treesit-parser-add-notifier "treesit.c")
|
||||||
|
(declare-function treesit-parser-buffer "treesit.c")
|
||||||
|
(declare-function treesit-parser-list "treesit.c")
|
||||||
|
|
||||||
(defgroup ruby-ts nil
|
(defgroup ruby-ts nil
|
||||||
"Major mode for editing Ruby code."
|
"Major mode for editing Ruby code."
|
||||||
|
@ -1002,6 +1007,70 @@ leading double colon is not added."
|
||||||
(concat result sep method-name)
|
(concat result sep method-name)
|
||||||
result)))
|
result)))
|
||||||
|
|
||||||
|
(defvar ruby-ts--s-p-query
|
||||||
|
(when (treesit-available-p)
|
||||||
|
(treesit-query-compile 'ruby
|
||||||
|
'(((heredoc_body) @heredoc)
|
||||||
|
;; $' $" $`.
|
||||||
|
((global_variable) @global_var
|
||||||
|
(:match "\\`\\$[#\"'`:?]" @global_var))
|
||||||
|
;; ?' ?" ?` are character literals.
|
||||||
|
((character) @char
|
||||||
|
(:match "\\`?[#\"'`:?]" @char))
|
||||||
|
;; Symbols like :+, :<=> or :foo=.
|
||||||
|
((simple_symbol) @symbol
|
||||||
|
(:match "[[:punct:]]" @symbol))
|
||||||
|
;; Method calls with name ending with ? or !.
|
||||||
|
((call method: (identifier) @ident)
|
||||||
|
(:match "[?!]\\'" @ident))
|
||||||
|
;; Backtick method redefinition.
|
||||||
|
((operator "`" @backtick))
|
||||||
|
;; TODO: Stop at interpolations.
|
||||||
|
((regex "/" @regex-slash))
|
||||||
|
;; =begin...=end
|
||||||
|
((comment) @comm
|
||||||
|
(:match "\\`=" @comm))
|
||||||
|
;; Percent literals: %w[], %q{}, ...
|
||||||
|
((string) @percent
|
||||||
|
(:match "\\`%" @percent))))))
|
||||||
|
|
||||||
|
(defun ruby-ts--syntax-propertize (beg end)
|
||||||
|
(let ((captures (treesit-query-capture 'ruby ruby-ts--s-p-query beg end)))
|
||||||
|
(pcase-dolist (`(,name . ,node) captures)
|
||||||
|
(pcase name
|
||||||
|
('regex_slash
|
||||||
|
(put-text-property (treesit-node-start node) (treesit-node-end node)
|
||||||
|
'syntax-table (string-to-syntax "\"/")))
|
||||||
|
('ident
|
||||||
|
(put-text-property (1- (treesit-node-end node)) (treesit-node-end node)
|
||||||
|
'syntax-table (string-to-syntax "_")))
|
||||||
|
('symbol
|
||||||
|
(put-text-property (1+ (treesit-node-start node)) (treesit-node-end node)
|
||||||
|
'syntax-table (string-to-syntax "_")))
|
||||||
|
('heredoc
|
||||||
|
(put-text-property (treesit-node-start node) (1+ (treesit-node-start node))
|
||||||
|
'syntax-table (string-to-syntax "\""))
|
||||||
|
(put-text-property (1- (treesit-node-end node)) (treesit-node-end node)
|
||||||
|
'syntax-table (string-to-syntax "\"")))
|
||||||
|
('percent
|
||||||
|
(put-text-property (1+ (treesit-node-start node)) (+ 2 (treesit-node-start node))
|
||||||
|
'syntax-table (string-to-syntax "|"))
|
||||||
|
(put-text-property (1- (treesit-node-end node)) (treesit-node-end node)
|
||||||
|
'syntax-table (string-to-syntax "|")))
|
||||||
|
((or 'global_var 'char)
|
||||||
|
(put-text-property (treesit-node-start node) (1+ (treesit-node-start node))
|
||||||
|
'syntax-table (string-to-syntax "'"))
|
||||||
|
(put-text-property (1+ (treesit-node-start node)) (treesit-node-end node)
|
||||||
|
'syntax-table (string-to-syntax "_")))
|
||||||
|
('backtick
|
||||||
|
(put-text-property (treesit-node-start node) (treesit-node-end node)
|
||||||
|
'syntax-table (string-to-syntax "_")))
|
||||||
|
('comm
|
||||||
|
(dolist (pos (list (treesit-node-start node)
|
||||||
|
(1- (treesit-node-end node))))
|
||||||
|
(put-text-property pos (1+ pos) 'syntax-table
|
||||||
|
(string-to-syntax "!"))))))))
|
||||||
|
|
||||||
(defvar-keymap ruby-ts-mode-map
|
(defvar-keymap ruby-ts-mode-map
|
||||||
:doc "Keymap used in Ruby mode"
|
:doc "Keymap used in Ruby mode"
|
||||||
:parent prog-mode-map
|
:parent prog-mode-map
|
||||||
|
@ -1049,7 +1118,21 @@ leading double colon is not added."
|
||||||
interpolation literal symbol assignment)
|
interpolation literal symbol assignment)
|
||||||
( bracket error function operator punctuation)))
|
( bracket error function operator punctuation)))
|
||||||
|
|
||||||
(treesit-major-mode-setup))
|
(treesit-major-mode-setup)
|
||||||
|
|
||||||
|
(treesit-parser-add-notifier (car (treesit-parser-list))
|
||||||
|
#'ruby-ts--parser-after-change)
|
||||||
|
|
||||||
|
(setq-local syntax-propertize-function #'ruby-ts--syntax-propertize))
|
||||||
|
|
||||||
|
(defun ruby-ts--parser-after-change (ranges parser)
|
||||||
|
;; Make sure we re-syntax-propertize the full node that is being
|
||||||
|
;; edited. This is most pertinent to multi-line complex nodes such
|
||||||
|
;; as heredocs.
|
||||||
|
(when ranges
|
||||||
|
(with-current-buffer (treesit-parser-buffer parser)
|
||||||
|
(syntax-ppss-flush-cache (cl-loop for r in ranges
|
||||||
|
minimize (car r))))))
|
||||||
|
|
||||||
(if (treesit-ready-p 'ruby)
|
(if (treesit-ready-p 'ruby)
|
||||||
;; Copied from ruby-mode.el.
|
;; Copied from ruby-mode.el.
|
||||||
|
|
Loading…
Add table
Reference in a new issue