From 2899bf062db7e6bf199025ecef9d903760a0ef7d Mon Sep 17 00:00:00 2001 From: JimMoen Date: Thu, 20 Feb 2025 17:45:27 +0800 Subject: [PATCH 01/14] refactor: predicate function in-type-context-p --- erlang-ts.el | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/erlang-ts.el b/erlang-ts.el index 1563c3f..6f1f382 100644 --- a/erlang-ts.el +++ b/erlang-ts.el @@ -155,7 +155,7 @@ FUNC with ARGS will be called if `erlang-ts-mode' is not active." :override t `( ;; Might be slow but don't know a better way to do it (call expr: (_) @font-lock-type-face - (:pred erlang-ts-paren-is-type @font-lock-type-face)) + (:pred erlang-ts-in-type-context-p @font-lock-type-face)) (type_name name: (atom) @font-lock-type-face) (export_type_attribute types: (fa fun: (atom) @font-lock-type-face)) (record_decl name: (atom) @font-lock-type-face @@ -185,7 +185,9 @@ FUNC with ARGS will be called if `erlang-ts-mode' is not active." (remote_module module: (atom) @module (:equal "erlang" @module)) fun: (atom) @fun (:match ,erlang-ext-bif-regexp @fun)) - @font-lock-builtin-face)) + @font-lock-builtin-face) + (call expr: (atom) @font-lock-builtin-face + (:match ,erlang-guards-regexp @font-lock-builtin-face))) :language 'erlang :feature 'preprocessor @@ -240,15 +242,15 @@ FUNC with ARGS will be called if `erlang-ts-mode' is not active." Use `treesit-font-lock-level' or `treesit-font-lock-feature-list' to change settings") -(defun erlang-ts-paren-is-type (node) - "Check if any parent of NODE is a type." - (let ((type (treesit-node-type node))) - (cond ((member type '("type_alias" "ann_type" "type_sig" - "opaque" "field_type")) - t) - ((not type) nil) - (t - (erlang-ts-paren-is-type (treesit-node-parent node)))))) +(defun erlang-ts-in-type-context-p (node) + "Check if NODE is within a type definition context." + (when node + (let ((parent (treesit-node-parent node))) + (cond + ((null parent) nil) + ((member (treesit-node-type parent) + '("type_alias" "ann_type" "type_sig" "opaque" "field_type")) t) + (t (erlang-ts-in-type-context-p parent)))))) (defun erlang-ts-setup () "Setup treesit for erlang." From d04255427f9590c21c1b7bf731b2fa9efd0912f8 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Thu, 20 Feb 2025 17:49:05 +0800 Subject: [PATCH 02/14] feat: module name as constant face --- erlang-ts.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erlang-ts.el b/erlang-ts.el index 6f1f382..5a56f4f 100644 --- a/erlang-ts.el +++ b/erlang-ts.el @@ -201,7 +201,8 @@ FUNC with ARGS will be called if `erlang-ts-mode' is not active." :language 'erlang :feature 'constant - `(((atom) @font-lock-constant-face (:match "^'.*" @font-lock-constant-face)) + `((module_attribute name: (atom) @font-lock-constant-face) + ((atom) @font-lock-constant-face (:match "^'.*" @font-lock-constant-face)) ((char) @font-lock-constant-face (:match "^$.*" @font-lock-constant-face))) :language 'erlang From a267314b7a1f4b0ff3335d2b0bccb88a45ac8637 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Thu, 20 Feb 2025 17:50:33 +0800 Subject: [PATCH 03/14] feat: function-call and remote call face --- erlang-ts.el | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/erlang-ts.el b/erlang-ts.el index 5a56f4f..ed14887 100644 --- a/erlang-ts.el +++ b/erlang-ts.el @@ -222,7 +222,12 @@ FUNC with ARGS will be called if `erlang-ts-mode' is not active." :language 'erlang :feature 'function-call - `((call expr: (_) @font-lock-function-call-face)) + `( + (call expr: (atom) @font-lock-function-call-face) + (call expr: (remote module: (remote_module module: (atom) @font-lock-constant-face) + fun: (atom) @font-lock-function-call-face)) + (call expr: (remote fun: (atom) @font-lock-function-call-face)) + (remote module: (remote_module module: (atom) @font-lock-constant-face))) :language 'erlang :feature 'bracket @@ -272,12 +277,12 @@ Use `treesit-font-lock-level' or `treesit-font-lock-feature-list' (builtin ;; Level 3 variable guards + function-call constant) (operator ;; Level 4 delimiter bracket number - function-call index-atom))) ;; Should we set this or let the user decide? From 2017190de3d69a706961c4c40aa8d382750a1231 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Sun, 23 Feb 2025 16:47:59 +0800 Subject: [PATCH 04/14] fix: record decl without fields --- erlang-ts.el | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erlang-ts.el b/erlang-ts.el index ed14887..72cebb8 100644 --- a/erlang-ts.el +++ b/erlang-ts.el @@ -160,6 +160,9 @@ FUNC with ARGS will be called if `erlang-ts-mode' is not active." (export_type_attribute types: (fa fun: (atom) @font-lock-type-face)) (record_decl name: (atom) @font-lock-type-face (record_field name: (atom) @font-lock-property-name-face)) + ;; for records without fields e.g + ;; `-record(name, {}).` + (record_decl name: (atom) @font-lock-type-face) (record_name name: (atom) @font-lock-type-face)) :language 'erlang From c78c01612131626a1880ddef88d001a49cd18a6e Mon Sep 17 00:00:00 2001 From: JimMoen Date: Sun, 23 Feb 2025 16:48:30 +0800 Subject: [PATCH 05/14] fix: callback function name --- erlang-ts.el | 1 + 1 file changed, 1 insertion(+) diff --git a/erlang-ts.el b/erlang-ts.el index 72cebb8..0cb9b1a 100644 --- a/erlang-ts.el +++ b/erlang-ts.el @@ -168,6 +168,7 @@ FUNC with ARGS will be called if `erlang-ts-mode' is not active." :language 'erlang :feature 'definition `((function_clause name: (atom) @font-lock-function-name-face) + (callback fun: (atom) @font-lock-function-name-face) (spec fun: (atom) @font-lock-function-name-face) (fa fun: (atom) @font-lock-function-name-face) (binary_op_expr lhs: (atom) @font-lock-function-name-face "/" From 947160b7ba4bc200ef7faca1ed7a641d833d4204 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Sun, 23 Feb 2025 16:56:07 +0800 Subject: [PATCH 06/14] fix: pp constant face --- erlang-ts.el | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/erlang-ts.el b/erlang-ts.el index 0cb9b1a..19c0dda 100644 --- a/erlang-ts.el +++ b/erlang-ts.el @@ -206,6 +206,13 @@ FUNC with ARGS will be called if `erlang-ts-mode' is not active." :language 'erlang :feature 'constant `((module_attribute name: (atom) @font-lock-constant-face) + (behaviour_attribute name: (_) @font-lock-constant-face) + + (pp_define lhs: (macro_lhs name: (_) @font-lock-constant-face)) + (pp_undef name: (_) @font-lock-constant-face) + (pp_ifdef name: (_) @font-lock-constant-face) + (pp_ifndef name: (_) @font-lock-constant-face) + ((atom) @font-lock-constant-face (:match "^'.*" @font-lock-constant-face)) ((char) @font-lock-constant-face (:match "^$.*" @font-lock-constant-face))) From 61a0504419e745cc6dff8fa8f290210d12af377b Mon Sep 17 00:00:00 2001 From: JimMoen Date: Sat, 22 Feb 2025 19:27:00 +0800 Subject: [PATCH 07/14] fix: preprocessor faces - To make `-` before attrs highlighted --- erlang-ts.el | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/erlang-ts.el b/erlang-ts.el index 19c0dda..6293885 100644 --- a/erlang-ts.el +++ b/erlang-ts.el @@ -197,11 +197,35 @@ FUNC with ARGS will be called if `erlang-ts-mode' is not active." :feature 'preprocessor :override t `((wild_attribute name: (_) @font-lock-preprocessor-face) - (pp_define lhs: (macro_lhs name: (_) @font-lock-preprocessor-face)) + (module_attribute (["-" "module"]) @font-lock-preprocessor-face) + (behaviour_attribute (["-" "behaviour" "behavior"]) @font-lock-preprocessor-face) + (deprecated_attribute (["-" "deprecated"]) @font-lock-preprocessor-face) + (export_attribute (["-" "export"]) @font-lock-preprocessor-face) + (import_attribute (["-" "import"]) @font-lock-preprocessor-face) + (export_type_attribute (["-" "export_type"]) @font-lock-preprocessor-face) + (compile_options_attribute (["-" "compile"]) @font-lock-preprocessor-face) + (file_attribute (["-" "file"]) @font-lock-preprocessor-face) + (feature_attribute (["-" "feature"]) @font-lock-preprocessor-face) + (optional_callbacks_attribute (["-" "optional_callbacks"]) @font-lock-preprocessor-face) + + (pp_define (["-" "define"]) @font-lock-preprocessor-face) + (pp_include (["-" "include"]) @font-lock-preprocessor-face) + (pp_include_lib (["-" "include_lib"]) @font-lock-preprocessor-face) + (pp_undef (["-" "undef"]) @font-lock-preprocessor-face) + (pp_ifdef (["-" "ifdef"]) @font-lock-preprocessor-face) + (pp_ifndef (["-" "ifndef"]) @font-lock-preprocessor-face) + (pp_else (["-" "else"]) @font-lock-preprocessor-face) + (pp_endif (["-" "endif"]) @font-lock-preprocessor-face) + (pp_if (["-" "if"]) @font-lock-preprocessor-face) + (pp_elif (["-" "elif"]) @font-lock-preprocessor-face) + + (record_decl (["-" "record"]) @font-lock-preprocessor-face) (macro_call_expr name: (_) @font-lock-preprocessor-face) - (["module" "export" "import" "compile" "define" "record" - "spec" "type" "export_type" "opaque" "behaviour" "include" "include_lib"] - @font-lock-preprocessor-face)) + (callback (["-" "callback"]) @font-lock-preprocessor-face) + + (type_alias (["-" "type"]) @font-lock-preprocessor-face) + (opaque (["-" "opaque"]) @font-lock-preprocessor-face) + (spec (["-" "spec"]) @font-lock-preprocessor-face)) :language 'erlang :feature 'constant From 11382dc3e6b6d12f876fb3bf35720d29192c45fc Mon Sep 17 00:00:00 2001 From: JimMoen Date: Sun, 23 Feb 2025 18:55:47 +0800 Subject: [PATCH 08/14] feat: predefined macro as constant --- erlang-ts.el | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/erlang-ts.el b/erlang-ts.el index 6293885..3bb1a20 100644 --- a/erlang-ts.el +++ b/erlang-ts.el @@ -229,6 +229,7 @@ FUNC with ARGS will be called if `erlang-ts-mode' is not active." :language 'erlang :feature 'constant + :override t `((module_attribute name: (atom) @font-lock-constant-face) (behaviour_attribute name: (_) @font-lock-constant-face) @@ -237,6 +238,9 @@ FUNC with ARGS will be called if `erlang-ts-mode' is not active." (pp_ifdef name: (_) @font-lock-constant-face) (pp_ifndef name: (_) @font-lock-constant-face) + (macro_call_expr name: (var) @font-lock-constant-face + (:pred erlang-ts-predefined-macro-p @font-lock-constant-face)) + ((atom) @font-lock-constant-face (:match "^'.*" @font-lock-constant-face)) ((char) @font-lock-constant-face (:match "^$.*" @font-lock-constant-face))) @@ -293,6 +297,18 @@ Use `treesit-font-lock-level' or `treesit-font-lock-feature-list' '("type_alias" "ann_type" "type_sig" "opaque" "field_type")) t) (t (erlang-ts-in-type-context-p parent)))))) +(defun erlang-ts-predefined-macro-p (node) + "Check if macro_call_expr var NODE is a builtin macro." + (when node + (if (member (treesit-node-text node) + '("OTP_RELEASE" "MACHINE" + "MODULE" "MODULE_STRING" + "FILE" "LINE" + "FUNCTION_NAME" "FUNCTION_ARITY" + "FEATURE_AVAILABLE" "FEATURE_ENABLED")) + t + nil))) + (defun erlang-ts-setup () "Setup treesit for erlang." From 60ee3416722a9ddc469a29675eaa0dedf0a48430 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Sun, 23 Feb 2025 21:22:46 +0800 Subject: [PATCH 09/14] fix: quoted atom and ASCII form char --- erlang-ts.el | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/erlang-ts.el b/erlang-ts.el index 3bb1a20..ad557c4 100644 --- a/erlang-ts.el +++ b/erlang-ts.el @@ -241,8 +241,10 @@ FUNC with ARGS will be called if `erlang-ts-mode' is not active." (macro_call_expr name: (var) @font-lock-constant-face (:pred erlang-ts-predefined-macro-p @font-lock-constant-face)) - ((atom) @font-lock-constant-face (:match "^'.*" @font-lock-constant-face)) - ((char) @font-lock-constant-face (:match "^$.*" @font-lock-constant-face))) + ((atom) @font-lock-constant-face (:match ,erlang-atom-quoted-regexp @font-lock-constant-face)) + ((char) @font-lock-constant-face + (:match "\\(\\$\\([^\\]\\|\\\\\\([^0-7^\n]\\|[0-7]+\\|\\^[a-zA-Z]\\)\\)\\)" + @font-lock-constant-face))) :language 'erlang :feature 'index-atom From a37f7d23f6d55fd950541d4ae9dd9b51d9be4932 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Mon, 24 Feb 2025 03:02:44 +0800 Subject: [PATCH 10/14] fix: set syntax-propertize function - `$` in atom and string - Tripled-quoted string in doc or Var --- erlang-ts.el | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/erlang-ts.el b/erlang-ts.el index ad557c4..60c378e 100644 --- a/erlang-ts.el +++ b/erlang-ts.el @@ -311,6 +311,28 @@ Use `treesit-font-lock-level' or `treesit-font-lock-feature-list' t nil))) +(defvar erlang-ts--syntax-propertize-query + (when (treesit-available-p) + (treesit-query-compile + 'erlang + '(((atom) @node-atom) + ((string) @node-string))))) + +(defun erlang-ts--process-node (node) + "Apply syntax-descriptor as `w' for atom or normal string NODE." + (let* ((string-start (1+ (treesit-node-start node))) + (string-end (1- (treesit-node-end node)))) + (put-text-property string-start string-end 'syntax-table (string-to-syntax "w")))) + +(defun erlang-ts--syntax-propertize (start end) + "Apply syntax properties for Erlang specific patterns from START to END." + (let ((captures + (treesit-query-capture 'erlang erlang-ts--syntax-propertize-query start end))) + (pcase-dolist (`(,name . ,node) captures) + (pcase name + ('node-atom (erlang-ts--process-node node)) + ('node-string (erlang-ts--process-node node)))))) + (defun erlang-ts-setup () "Setup treesit for erlang." @@ -367,7 +389,8 @@ Use `treesit-font-lock-level' or `treesit-font-lock-feature-list' (advice-add #'erlang-font-lock-level-3 :around #'erlang-ts--font-lock-level-3) (advice-add #'erlang-font-lock-level-4 :around #'erlang-ts--font-lock-level-4) - (treesit-major-mode-setup)) + (treesit-major-mode-setup) + (setq-local syntax-propertize-function #'erlang-ts--syntax-propertize)) (defun erlang-ts-unload-function () From 76dc399d73b48c6897de34adc6d2fb963d3674e7 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Mon, 24 Feb 2025 10:51:25 +0800 Subject: [PATCH 11/14] fix: treesit-node-text process func --- erlang-ts.el | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/erlang-ts.el b/erlang-ts.el index 60c378e..3bb96fc 100644 --- a/erlang-ts.el +++ b/erlang-ts.el @@ -316,13 +316,49 @@ Use `treesit-font-lock-level' or `treesit-font-lock-feature-list' (treesit-query-compile 'erlang '(((atom) @node-atom) + ((string) @node-string-triple-quoted (:match "^\"\"\"" @node-string-triple-quoted)) ((string) @node-string))))) (defun erlang-ts--process-node (node) - "Apply syntax-descriptor as `w' for atom or normal string NODE." - (let* ((string-start (1+ (treesit-node-start node))) - (string-end (1- (treesit-node-end node)))) - (put-text-property string-start string-end 'syntax-table (string-to-syntax "w")))) + "Process a single or double quoted string or atom node. +NODE is the treesit node to process." + (let* ((node-text (treesit-node-text node)) + (node-start (treesit-node-start node)) + (node-end (treesit-node-end node)) + (first-char (aref node-text 0)) + (last-char (aref node-text (1- (length node-text))))) + (when (and (or (eq first-char ?\") (eq first-char ?\')) + (eq first-char last-char)) + (let ((escaped-last-quote (and (eq last-char ?\") + (> (length node-text) 1) + (eq (aref node-text (- (length node-text) 2)) ?\\)))) + (put-text-property node-start (1+ node-start) 'syntax-table (string-to-syntax "|")) + (put-text-property (1- node-end) node-end 'syntax-table (string-to-syntax "|")) + (unless escaped-last-quote + (put-text-property (1- node-end) node-end 'syntax-table (string-to-syntax "|"))) + (let ((content-start (1+ node-start)) + (content-end (1- node-end))) + (when (> content-end content-start) + (let ((custom-table (copy-syntax-table (syntax-table)))) + (modify-syntax-entry ?$ "w" custom-table) + (put-text-property content-start content-end 'syntax-table custom-table)))))))) + +(defun erlang-ts--process-node-triple-quoted (node) + "Process a triple quoted string node. +NODE is the treesit node to process." + (let* ((node-text (treesit-node-text node)) + (node-start (treesit-node-start node)) + (node-end (treesit-node-end node)) + (text-length (length node-text))) + (put-text-property node-start (+ node-start 3) 'syntax-table (string-to-syntax "|")) + (when (>= text-length 3) + (put-text-property (- node-end 3) node-end 'syntax-table (string-to-syntax "|"))) + (let ((content-start (+ node-start 3)) + (content-end (- node-end 3))) + (when (> content-end content-start) + (let ((custom-table (copy-syntax-table (syntax-table)))) + (modify-syntax-entry ?$ "w" custom-table) + (put-text-property content-start content-end 'syntax-table custom-table)))))) (defun erlang-ts--syntax-propertize (start end) "Apply syntax properties for Erlang specific patterns from START to END." @@ -331,7 +367,8 @@ Use `treesit-font-lock-level' or `treesit-font-lock-feature-list' (pcase-dolist (`(,name . ,node) captures) (pcase name ('node-atom (erlang-ts--process-node node)) - ('node-string (erlang-ts--process-node node)))))) + ('node-string (erlang-ts--process-node node)) + ('node-string-triple-quoted (erlang-ts--process-node-triple-quoted node)))))) (defun erlang-ts-setup () "Setup treesit for erlang." From 9a273d9ae42cc4559c5592325170bd677c6f48bf Mon Sep 17 00:00:00 2001 From: JimMoen Date: Mon, 24 Feb 2025 17:13:49 +0800 Subject: [PATCH 12/14] fix: external_fun highlight face --- erlang-ts.el | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/erlang-ts.el b/erlang-ts.el index 3bb96fc..f84d731 100644 --- a/erlang-ts.el +++ b/erlang-ts.el @@ -173,7 +173,11 @@ FUNC with ARGS will be called if `erlang-ts-mode' is not active." (fa fun: (atom) @font-lock-function-name-face) (binary_op_expr lhs: (atom) @font-lock-function-name-face "/" rhs: (integer)) - (internal_fun fun: (atom) @font-lock-function-name-face)) + (internal_fun fun: (atom) @font-lock-function-name-face) + (external_fun module: (module name: (atom) @font-lock-constant-face) + fun: (atom) @font-lock-function-name-face) + (external_fun module: (module name: (atom) @font-lock-constant-face)) + (external_fun fun: (atom) @font-lock-function-name-face)) :language 'erlang :feature 'guards From e6c3a854235c9764c787277fa19088509c176ae1 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Tue, 25 Feb 2025 15:54:25 +0800 Subject: [PATCH 13/14] fix: improve record faces --- erlang-ts.el | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/erlang-ts.el b/erlang-ts.el index f84d731..51abef5 100644 --- a/erlang-ts.el +++ b/erlang-ts.el @@ -158,12 +158,10 @@ FUNC with ARGS will be called if `erlang-ts-mode' is not active." (:pred erlang-ts-in-type-context-p @font-lock-type-face)) (type_name name: (atom) @font-lock-type-face) (export_type_attribute types: (fa fun: (atom) @font-lock-type-face)) - (record_decl name: (atom) @font-lock-type-face - (record_field name: (atom) @font-lock-property-name-face)) - ;; for records without fields e.g - ;; `-record(name, {}).` (record_decl name: (atom) @font-lock-type-face) - (record_name name: (atom) @font-lock-type-face)) + (record_name name: (atom) @font-lock-type-face) + (record_field name: (atom) @font-lock-constant-face) + (record_field_name name: (atom) @font-lock-constant-face)) :language 'erlang :feature 'definition From a9523914f3c7633a3e63d380f0ecbafd5fc18b21 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Wed, 19 Mar 2025 16:41:39 +0800 Subject: [PATCH 14/14] fix: make erlang-ts-mode-syntax-table and mark `?$` as word - for char like `$'`, `$"`, `$\"`, modify text property as word --- erlang-ts.el | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/erlang-ts.el b/erlang-ts.el index 51abef5..17123f6 100644 --- a/erlang-ts.el +++ b/erlang-ts.el @@ -244,9 +244,7 @@ FUNC with ARGS will be called if `erlang-ts-mode' is not active." (:pred erlang-ts-predefined-macro-p @font-lock-constant-face)) ((atom) @font-lock-constant-face (:match ,erlang-atom-quoted-regexp @font-lock-constant-face)) - ((char) @font-lock-constant-face - (:match "\\(\\$\\([^\\]\\|\\\\\\([^0-7^\n]\\|[0-7]+\\|\\^[a-zA-Z]\\)\\)\\)" - @font-lock-constant-face))) + ((char) @font-lock-constant-face)) :language 'erlang :feature 'index-atom @@ -317,7 +315,8 @@ Use `treesit-font-lock-level' or `treesit-font-lock-feature-list' (when (treesit-available-p) (treesit-query-compile 'erlang - '(((atom) @node-atom) + '(((char) @node-char) + ((atom) @node-atom) ((string) @node-string-triple-quoted (:match "^\"\"\"" @node-string-triple-quoted)) ((string) @node-string))))) @@ -341,9 +340,18 @@ NODE is the treesit node to process." (let ((content-start (1+ node-start)) (content-end (1- node-end))) (when (> content-end content-start) - (let ((custom-table (copy-syntax-table (syntax-table)))) - (modify-syntax-entry ?$ "w" custom-table) - (put-text-property content-start content-end 'syntax-table custom-table)))))))) + (put-text-property content-start content-end 'syntax-table (syntax-table)))))))) + +(defun erlang-ts--process-node-char (node) + "Process char NODE like `$\'' or `$\"'." + (let* ((node-start (treesit-node-start node)) + (node-end (treesit-node-end node))) + (message "modify char node") + (when (> node-end node-start) + (let ((custom-table (copy-syntax-table (syntax-table)))) + (modify-syntax-entry ?' "w" custom-table) + (modify-syntax-entry ?\" "w" custom-table) + (put-text-property node-start node-end 'syntax-table custom-table))))) (defun erlang-ts--process-node-triple-quoted (node) "Process a triple quoted string node. @@ -358,9 +366,7 @@ NODE is the treesit node to process." (let ((content-start (+ node-start 3)) (content-end (- node-end 3))) (when (> content-end content-start) - (let ((custom-table (copy-syntax-table (syntax-table)))) - (modify-syntax-entry ?$ "w" custom-table) - (put-text-property content-start content-end 'syntax-table custom-table)))))) + (put-text-property content-start content-end 'syntax-table (syntax-table)))))) (defun erlang-ts--syntax-propertize (start end) "Apply syntax properties for Erlang specific patterns from START to END." @@ -368,10 +374,22 @@ NODE is the treesit node to process." (treesit-query-capture 'erlang erlang-ts--syntax-propertize-query start end))) (pcase-dolist (`(,name . ,node) captures) (pcase name + ('node-char (erlang-ts--process-node-char node)) ('node-atom (erlang-ts--process-node node)) ('node-string (erlang-ts--process-node node)) ('node-string-triple-quoted (erlang-ts--process-node-triple-quoted node)))))) +(defvar erlang-ts-mode-syntax-table nil + "Syntax table in use in Erlang-ts-mode buffers.") + +(defun erlang-ts-syntax-table-init () + "Initialize the syntax table for `erlang-ts-mode'." + (unless erlang-ts-mode-syntax-table + (let ((table (copy-syntax-table erlang-mode-syntax-table))) + (modify-syntax-entry ?$ "w" table) + (setq erlang-ts-mode-syntax-table table))) + (set-syntax-table erlang-ts-mode-syntax-table)) + (defun erlang-ts-setup () "Setup treesit for erlang." @@ -449,7 +467,8 @@ NODE is the treesit node to process." ;;;###autoload (define-derived-mode erlang-ts-mode erlang-mode "erl-ts" "Major mode for editing erlang with tree-sitter." - :syntax-table erlang-mode-syntax-table + :syntax-table nil + (erlang-ts-syntax-table-init) (when (treesit-ready-p 'erlang) (treesit-parser-create 'erlang) (erlang-ts-setup)))