Skip to content

Commit

Permalink
Highlight regular expressions with tree-sitter-regex grammar
Browse files Browse the repository at this point in the history
This grammar is bundled in nixos by default and seems good enough for
java regular expressions. It is also maintained under the tree-sitter
github org so is "official".

In order to property identify the #" and closing " characters we have to
parse them with the clojure grammar (in case the regex grammar is not
available) and again with the regex grammar as part of the actual
pattern. This could be avoided if either the clojure grammar captured a
node for the inner contents of the regex literal, or the
treesit-range-settings supported some kind of offest argument like the
neovim tree-sitter mechanisms do.

Should address issue #11
  • Loading branch information
dannyfreeman committed Aug 24, 2023
1 parent d698528 commit 855cddd
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
49 changes: 47 additions & 2 deletions clojure-ts-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -283,12 +283,48 @@ Only intended for use at development time.")
:feature 'string
:language 'clojure
'((str_lit) @font-lock-string-face
(regex_lit) @font-lock-string-face)
(regex_lit) @font-lock-regex-face)

:feature 'regex
:language 'clojure
:override t
'((regex_lit marker: _ @font-lock-property-face))
'((regex_lit marker: "#" @font-lock-regex-face))

;; https://github.com/tree-sitter/tree-sitter-regex/blob/master/grammar.js
:feature 'regex
:language 'regex
:override t
'(;; This captures the #"" characters that surround a regex in clojure.
;; If we could define offsets in treesit-range-settings
;; this would not be necessary
((pattern (term
:anchor (pattern_character) @font-lock-regex-face
:anchor (pattern_character) @font-lock-string-face
(pattern_character) @font-lock-string-face :anchor))
(:equal @font-lock-regex-face "#")
(:equal @font-lock-string-face "\""))
;; Capturing Groups
((anonymous_capturing_group (["(" ")"]) @font-lock-regexp-grouping-construct))
((non_capturing_group (["(?:" ")"]) @font-lock-regexp-grouping-construct))
((lookahead_assertion (["(?" "=" "!" ")"]) @font-lock-regexp-grouping-construct))
((named_capturing_group (["(?<" ">" ")"]) @font-lock-regexp-grouping-construct))
((group_name) @font-lock-variable-name-face)
;; Character classes
((character_class (["[" "]"]) @font-lock-bracket-face))
((character_class "^" @font-lock-negation-char-face))
((class_range "-" @font-lock-punctuation-face))
;; Quantifiers
([(zero_or_more) (one_or_more) (optional)]) @font-lock-keyword-face
((count_quantifier (["{" "}"]) @font-lock-bracket-face))
((count_quantifier "," @font-lock-punctuation-face))
((count_quantifier (decimal_digits) @font-lock-number-face))
;;; Escaping
([(start_assertion) (any_character) (end_assertion)]) @font-lock-keyword-face
([(decimal_escape)
(identity_escape)
(character_class_escape)]) @font-lock-regexp-grouping-backslash
((pattern_character) @font-lock-regexp-face)
([(control_escape) (boundary_assertion)] @font-lock-builtin-face))

:feature 'number
:language 'clojure
Expand Down Expand Up @@ -597,6 +633,12 @@ See `clojure-ts--standard-definition-node-name' for the implementation used.")
(interactive)
(message "clojure-ts-mode (version %s)" clojure-ts-mode-version))

(defvar clojure-ts--treesit-range-settings
(treesit-range-rules
:embed 'regex
:host 'clojure
'((regex_lit) @capture)))

;;;###autoload
(define-derived-mode clojure-ts-mode prog-mode "Clojure[TS]"
"Major mode for editing Clojure code.
Expand All @@ -607,6 +649,9 @@ See `clojure-ts--standard-definition-node-name' for the implementation used.")
(treesit-install-language-grammar 'clojure))
(setq-local comment-start ";")
(when (treesit-ready-p 'clojure)
(when (treesit-ready-p 'regex 'message)
(treesit-parser-create 'regex)
(setq-local treesit-range-settings clojure-ts--treesit-range-settings))
(treesit-parser-create 'clojure)
(setq-local treesit-font-lock-settings (clojure-ts--font-lock-settings)
treesit-defun-prefer-top-level t
Expand Down
2 changes: 1 addition & 1 deletion test/test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ Etiam commodo nulla id risus convallis pharetra. Integer dapibus, eros vitae veh
(println "Hello, World!"))

(binding [*out* nil]
#"regex string"
#"^(?<lookup>abc)[0-9]\b$"
(def #^Typehint x 1)
(def #^:metadata x 1)
(def ^Typehint x 2)
Expand Down

0 comments on commit 855cddd

Please sign in to comment.