mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-06 06:20:55 -08:00
Embed elixir in heex as well as elixir->heex->elixir (bug#76788).
* lisp/progmodes/elixir-ts-mode.el (elixir-ts--range-rules): Rename to a shorter name from 'elixir-ts--treesit-range-rules'. (elixir-ts--font-lock-feature-list, elixir-ts--thing-settings) (elixir-ts--range-rules): New variables with default values extracted from 'elixir-ts-mode'. (elixir-ts-mode): Use 'elixir-ts--font-lock-feature-list', 'elixir-ts--thing-settings', 'elixir-ts--range-rules' and 'heex-ts--range-rules'. Use 'treesit-merge-font-lock-feature-list' to merge 'heex-ts--font-lock-feature-list'. * lisp/progmodes/heex-ts-mode.el (heex-ts--font-lock-feature-list, heex-ts--range-rules): New variables. (heex-ts-mode): Use 'heex-ts--font-lock-feature-list', 'heex-ts--range-rules'. Merge 'elixir-ts--font-lock-settings', 'elixir-ts--font-lock-feature-list', 'elixir-ts--thing-settings' for embedding elixir in heex. Enable the 'sexp' navigation by default with 'treesit-cycle-sexp-type'. * lisp/progmodes/c-ts-mode.el (c-ts-mode): Append 'treesit-range-rules' to possibly already existing list in 'treesit-range-settings'. * lisp/treesit.el (treesit-language-at-point-default): Optimize to use 'when-let*'.
This commit is contained in:
parent
3d3be6dd0e
commit
d56e37c83c
4 changed files with 116 additions and 65 deletions
|
|
@ -1516,13 +1516,14 @@ in your init files."
|
||||||
treesit-font-lock-settings
|
treesit-font-lock-settings
|
||||||
c-ts-mode-doxygen-comment-font-lock-settings))
|
c-ts-mode-doxygen-comment-font-lock-settings))
|
||||||
(setq-local treesit-range-settings
|
(setq-local treesit-range-settings
|
||||||
(treesit-range-rules
|
(append treesit-range-settings
|
||||||
:embed 'doxygen
|
(treesit-range-rules
|
||||||
:host 'c
|
:embed 'doxygen
|
||||||
:local t
|
:host 'c
|
||||||
`(((comment) @cap
|
:local t
|
||||||
(:match
|
`(((comment) @cap
|
||||||
,c-ts-mode--doxygen-comment-regex @cap)))))))))
|
(:match
|
||||||
|
,c-ts-mode--doxygen-comment-regex @cap))))))))))
|
||||||
|
|
||||||
(derived-mode-add-parents 'c-ts-mode '(c-mode))
|
(derived-mode-add-parents 'c-ts-mode '(c-mode))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -567,18 +567,59 @@
|
||||||
|
|
||||||
"Tree-sitter font-lock settings.")
|
"Tree-sitter font-lock settings.")
|
||||||
|
|
||||||
(defvar elixir-ts--treesit-range-rules
|
(defvar elixir-ts--font-lock-feature-list
|
||||||
(when (treesit-available-p)
|
'(( elixir-comment elixir-doc elixir-definition)
|
||||||
(treesit-range-rules
|
( elixir-string elixir-keyword elixir-data-type)
|
||||||
:embed 'heex
|
( elixir-sigil elixir-builtin elixir-string-escape)
|
||||||
:host 'elixir
|
( elixir-function-call elixir-variable elixir-operator elixir-number ))
|
||||||
'((sigil (sigil_name) @_name
|
"Tree-sitter font-lock feature list.")
|
||||||
(:match "^[HF]$" @_name)
|
|
||||||
(quoted_content) @heex)))))
|
|
||||||
|
|
||||||
|
(defvar elixir-ts--thing-settings
|
||||||
|
`((sexp (not (or (and named
|
||||||
|
,(rx bos (or "source" "comment") eos))
|
||||||
|
(and anonymous
|
||||||
|
,(rx (or "{" "}" "[" "]" "(" ")"
|
||||||
|
"do" "end"))))))
|
||||||
|
(list
|
||||||
|
(or (and "\\`arguments\\'" ,#'elixir-ts--with-parens-0-p)
|
||||||
|
(and "\\`unary_operator\\'" ,#'elixir-ts--with-parens-1-p)
|
||||||
|
,(rx bos (or "block"
|
||||||
|
"quoted_atom"
|
||||||
|
"string"
|
||||||
|
"interpolation"
|
||||||
|
"sigil"
|
||||||
|
"quoted_keyword"
|
||||||
|
"list"
|
||||||
|
"tuple"
|
||||||
|
"bitstring"
|
||||||
|
"map"
|
||||||
|
"do_block"
|
||||||
|
"anonymous_function")
|
||||||
|
eos)))
|
||||||
|
(sexp-default
|
||||||
|
;; For `C-M-f' in "&|(a)"
|
||||||
|
("(" . ,(lambda (node)
|
||||||
|
(equal (treesit-node-type (treesit-node-parent node))
|
||||||
|
"unary_operator"))))
|
||||||
|
(sentence
|
||||||
|
,(rx bos (or "call") eos))
|
||||||
|
(text
|
||||||
|
,(rx bos (or "string" "sigil" "comment") eos)))
|
||||||
|
"`treesit-thing-settings' for Elixir.")
|
||||||
|
|
||||||
|
(defvar elixir-ts--range-rules
|
||||||
|
(treesit-range-rules
|
||||||
|
:embed 'heex
|
||||||
|
:host 'elixir
|
||||||
|
'((sigil (sigil_name) @_name
|
||||||
|
(:match "^[HF]$" @_name)
|
||||||
|
(quoted_content) @heex))))
|
||||||
|
|
||||||
|
(defvar heex-ts--range-rules)
|
||||||
(defvar heex-ts--thing-settings)
|
(defvar heex-ts--thing-settings)
|
||||||
(defvar heex-ts--indent-rules)
|
(defvar heex-ts--indent-rules)
|
||||||
(defvar heex-ts--font-lock-settings)
|
(defvar heex-ts--font-lock-settings)
|
||||||
|
(defvar heex-ts--font-lock-feature-list)
|
||||||
|
|
||||||
(defun elixir-ts--treesit-anchor-grand-parent-bol (_n parent &rest _)
|
(defun elixir-ts--treesit-anchor-grand-parent-bol (_n parent &rest _)
|
||||||
"Return the beginning of non-space characters for the parent node of PARENT."
|
"Return the beginning of non-space characters for the parent node of PARENT."
|
||||||
|
|
@ -693,11 +734,7 @@ Return nil if NODE is not a defun node or doesn't have a name."
|
||||||
;; Font-lock.
|
;; Font-lock.
|
||||||
(setq-local treesit-font-lock-settings elixir-ts--font-lock-settings)
|
(setq-local treesit-font-lock-settings elixir-ts--font-lock-settings)
|
||||||
(setq-local treesit-font-lock-feature-list
|
(setq-local treesit-font-lock-feature-list
|
||||||
'(( elixir-comment elixir-doc elixir-definition)
|
elixir-ts--font-lock-feature-list)
|
||||||
( elixir-string elixir-keyword elixir-data-type)
|
|
||||||
( elixir-sigil elixir-builtin elixir-string-escape)
|
|
||||||
( elixir-function-call elixir-variable elixir-operator elixir-number )))
|
|
||||||
|
|
||||||
|
|
||||||
;; Imenu.
|
;; Imenu.
|
||||||
(setq-local treesit-simple-imenu-settings
|
(setq-local treesit-simple-imenu-settings
|
||||||
|
|
@ -708,37 +745,7 @@ Return nil if NODE is not a defun node or doesn't have a name."
|
||||||
|
|
||||||
;; Navigation.
|
;; Navigation.
|
||||||
(setq-local treesit-thing-settings
|
(setq-local treesit-thing-settings
|
||||||
`((elixir
|
`((elixir ,@elixir-ts--thing-settings)
|
||||||
(sexp (not (or (and named
|
|
||||||
,(rx bos (or "source" "comment") eos))
|
|
||||||
(and anonymous
|
|
||||||
,(rx (or "{" "}" "[" "]" "(" ")"
|
|
||||||
"do" "end"))))))
|
|
||||||
(list
|
|
||||||
(or (and "\\`arguments\\'" ,#'elixir-ts--with-parens-0-p)
|
|
||||||
(and "\\`unary_operator\\'" ,#'elixir-ts--with-parens-1-p)
|
|
||||||
,(rx bos (or "block"
|
|
||||||
"quoted_atom"
|
|
||||||
"string"
|
|
||||||
"interpolation"
|
|
||||||
"sigil"
|
|
||||||
"quoted_keyword"
|
|
||||||
"list"
|
|
||||||
"tuple"
|
|
||||||
"bitstring"
|
|
||||||
"map"
|
|
||||||
"do_block"
|
|
||||||
"anonymous_function")
|
|
||||||
eos)))
|
|
||||||
(sexp-default
|
|
||||||
;; For `C-M-f' in "&|(a)"
|
|
||||||
("(" . ,(lambda (node)
|
|
||||||
(equal (treesit-node-type (treesit-node-parent node))
|
|
||||||
"unary_operator"))))
|
|
||||||
(sentence
|
|
||||||
,(rx bos (or "call") eos))
|
|
||||||
(text
|
|
||||||
,(rx bos (or "string" "sigil" "comment") eos)))
|
|
||||||
(heex ,@heex-ts--thing-settings)))
|
(heex ,@heex-ts--thing-settings)))
|
||||||
(setq-local treesit-defun-type-regexp
|
(setq-local treesit-defun-type-regexp
|
||||||
'("call" . elixir-ts--defun-p))
|
'("call" . elixir-ts--defun-p))
|
||||||
|
|
@ -747,7 +754,12 @@ Return nil if NODE is not a defun node or doesn't have a name."
|
||||||
|
|
||||||
;; Embedded Heex.
|
;; Embedded Heex.
|
||||||
(when (treesit-ensure-installed 'heex)
|
(when (treesit-ensure-installed 'heex)
|
||||||
(setq-local treesit-range-settings elixir-ts--treesit-range-rules)
|
(setq-local treesit-range-settings
|
||||||
|
(append elixir-ts--range-rules
|
||||||
|
;; Leave only local parsers from heex
|
||||||
|
;; for elixir->heex->elixir embedding.
|
||||||
|
(seq-filter (lambda (r) (nth 2 r))
|
||||||
|
heex-ts--range-rules)))
|
||||||
|
|
||||||
(setq-local treesit-font-lock-settings
|
(setq-local treesit-font-lock-settings
|
||||||
(append treesit-font-lock-settings
|
(append treesit-font-lock-settings
|
||||||
|
|
@ -758,12 +770,9 @@ Return nil if NODE is not a defun node or doesn't have a name."
|
||||||
heex-ts--indent-rules))
|
heex-ts--indent-rules))
|
||||||
|
|
||||||
(setq-local treesit-font-lock-feature-list
|
(setq-local treesit-font-lock-feature-list
|
||||||
'(( elixir-comment elixir-doc elixir-definition
|
(treesit-merge-font-lock-feature-list
|
||||||
heex-comment heex-keyword heex-doctype )
|
treesit-font-lock-feature-list
|
||||||
( elixir-string elixir-keyword elixir-data-type
|
heex-ts--font-lock-feature-list)))
|
||||||
heex-component heex-tag heex-attribute heex-string )
|
|
||||||
( elixir-sigil elixir-builtin elixir-string-escape)
|
|
||||||
( elixir-function-call elixir-variable elixir-operator elixir-number ))))
|
|
||||||
|
|
||||||
(treesit-major-mode-setup)
|
(treesit-major-mode-setup)
|
||||||
(setq-local syntax-propertize-function #'elixir-ts--syntax-propertize)
|
(setq-local syntax-propertize-function #'elixir-ts--syntax-propertize)
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,12 @@
|
||||||
])))
|
])))
|
||||||
"Tree-sitter font-lock settings.")
|
"Tree-sitter font-lock settings.")
|
||||||
|
|
||||||
|
(defvar heex-ts--font-lock-feature-list
|
||||||
|
'(( heex-comment heex-keyword heex-doctype )
|
||||||
|
( heex-component heex-tag heex-attribute heex-string )
|
||||||
|
() ())
|
||||||
|
"Tree-sitter font-lock feature list.")
|
||||||
|
|
||||||
(defun heex-ts--defun-name (node)
|
(defun heex-ts--defun-name (node)
|
||||||
"Return the name of the defun NODE.
|
"Return the name of the defun NODE.
|
||||||
Return nil if NODE is not a defun node or doesn't have a name."
|
Return nil if NODE is not a defun node or doesn't have a name."
|
||||||
|
|
@ -166,6 +172,24 @@ Return nil if NODE is not a defun node or doesn't have a name."
|
||||||
,(rx bos (or "comment" "text") eos)))
|
,(rx bos (or "comment" "text") eos)))
|
||||||
"`treesit-thing-settings' for HEEx.")
|
"`treesit-thing-settings' for HEEx.")
|
||||||
|
|
||||||
|
(defvar heex-ts--range-rules
|
||||||
|
(treesit-range-rules
|
||||||
|
:embed 'elixir
|
||||||
|
:host 'heex
|
||||||
|
'((directive [(partial_expression_value)
|
||||||
|
(ending_expression_value)]
|
||||||
|
@cap))
|
||||||
|
|
||||||
|
:embed 'elixir
|
||||||
|
:host 'heex
|
||||||
|
:local t
|
||||||
|
'((directive (expression_value) @cap)
|
||||||
|
(expression (expression_value) @cap))))
|
||||||
|
|
||||||
|
(defvar elixir-ts--font-lock-settings)
|
||||||
|
(defvar elixir-ts--font-lock-feature-list)
|
||||||
|
(defvar elixir-ts--thing-settings)
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(define-derived-mode heex-ts-mode html-mode "HEEx"
|
(define-derived-mode heex-ts-mode html-mode "HEEx"
|
||||||
"Major mode for editing HEEx, powered by tree-sitter."
|
"Major mode for editing HEEx, powered by tree-sitter."
|
||||||
|
|
@ -204,11 +228,29 @@ Return nil if NODE is not a defun node or doesn't have a name."
|
||||||
(setq-local treesit-simple-indent-rules heex-ts--indent-rules)
|
(setq-local treesit-simple-indent-rules heex-ts--indent-rules)
|
||||||
|
|
||||||
(setq-local treesit-font-lock-feature-list
|
(setq-local treesit-font-lock-feature-list
|
||||||
'(( heex-comment heex-keyword heex-doctype )
|
heex-ts--font-lock-feature-list)
|
||||||
( heex-component heex-tag heex-attribute heex-string )
|
|
||||||
() ()))
|
|
||||||
|
|
||||||
(treesit-major-mode-setup)))
|
(when (treesit-ready-p 'elixir)
|
||||||
|
(require 'elixir-ts-mode)
|
||||||
|
(treesit-parser-create 'elixir)
|
||||||
|
|
||||||
|
(setq-local treesit-range-settings heex-ts--range-rules)
|
||||||
|
|
||||||
|
(setq-local treesit-font-lock-settings
|
||||||
|
(append treesit-font-lock-settings
|
||||||
|
elixir-ts--font-lock-settings))
|
||||||
|
(setq-local treesit-font-lock-feature-list
|
||||||
|
(treesit-merge-font-lock-feature-list
|
||||||
|
treesit-font-lock-feature-list
|
||||||
|
elixir-ts--font-lock-feature-list))
|
||||||
|
|
||||||
|
(setq-local treesit-thing-settings
|
||||||
|
(append treesit-thing-settings
|
||||||
|
`((elixir ,@elixir-ts--thing-settings)))))
|
||||||
|
|
||||||
|
(treesit-major-mode-setup)
|
||||||
|
;; Enable the 'sexp' navigation by default
|
||||||
|
(treesit-cycle-sexp-type)))
|
||||||
|
|
||||||
(derived-mode-add-parents 'heex-ts-mode '(heex-mode))
|
(derived-mode-add-parents 'heex-ts-mode '(heex-mode))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -195,9 +195,8 @@ Returns the language at POSITION, or nil if there's no parser in the
|
||||||
buffer. When there are multiple parsers that cover POSITION, use the
|
buffer. When there are multiple parsers that cover POSITION, use the
|
||||||
parser with the deepest embed level as it's the \"most relevant\" parser
|
parser with the deepest embed level as it's the \"most relevant\" parser
|
||||||
at POSITION."
|
at POSITION."
|
||||||
(let ((parser (car (treesit-parsers-at position))))
|
(when-let* ((parser (car (treesit-parsers-at position))))
|
||||||
(when parser
|
(treesit-parser-language parser)))
|
||||||
(treesit-parser-language parser))))
|
|
||||||
|
|
||||||
;;; Node API supplement
|
;;; Node API supplement
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue