summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp')
-rw-r--r--lisp/progmodes/c-ts-mode.el48
-rw-r--r--lisp/progmodes/js.el116
2 files changed, 97 insertions, 67 deletions
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 73e488a8058..12e021bc670 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -63,6 +63,8 @@ follows the form of `treesit-simple-indent-rules'."
(function :tag "A function for user customized style" ignore))
:group 'c)
+;;; Syntax table
+
(defvar c-ts-mode--syntax-table
(let ((table (make-syntax-table)))
;; Taken from the cc-langs version
@@ -85,13 +87,27 @@ follows the form of `treesit-simple-indent-rules'."
table)
"Syntax table for `c-ts-mode'.")
-(defvar c++-ts-mode--syntax-table
- (let ((table (make-syntax-table c-ts-mode--syntax-table)))
- ;; Template delimiters.
- (modify-syntax-entry ?< "(" table)
- (modify-syntax-entry ?> ")" table)
- table)
- "Syntax table for `c++-ts-mode'.")
+(defun c-ts-mode--syntax-propertize (beg end)
+ "Apply syntax text property to template delimiters between BEG and END.
+
+< and > are usually punctuation, e.g., in ->. But when used for
+templates, they should be considered pairs.
+
+This function checks for < and > in the changed RANGES and apply
+appropriate text property to alter the syntax of template
+delimiters < and >'s."
+ (goto-char beg)
+ (while (re-search-forward (rx (or "<" ">")) end t)
+ (pcase (treesit-node-type
+ (treesit-node-parent
+ (treesit-node-at (match-beginning 0))))
+ ("template_argument_list"
+ (put-text-property (match-beginning 0)
+ (match-end 0)
+ 'syntax-table
+ (pcase (char-before)
+ (?< '(4 . ?>))
+ (?> '(5 . ?<))))))))
;;; Indent
@@ -574,6 +590,10 @@ ARG is passed to `fill-paragraph'."
(goto-char (match-beginning 1))
(setq start-marker (point-marker))
(replace-match " " nil nil nil 1))
+ ;; Include whitespaces before /*.
+ (goto-char start)
+ (beginning-of-line)
+ (setq start (point))
;; Mask spaces before "*/" if it is attached at the end
;; of a sentence rather than on its own line.
(goto-char end)
@@ -645,11 +665,18 @@ Set up:
(concat (rx (* (syntax whitespace))
(group (or (seq "/" (+ "/")) (* "*"))))
adaptive-fill-regexp))
- ;; Same as `adaptive-fill-regexp'.
+ ;; Note the missing * comparing to `adaptive-fill-regexp'. The
+ ;; reason for its absence is a bit convoluted to explain. Suffice
+ ;; to say that without it, filling a single line paragraph that
+ ;; starts with /* doesn't insert * at the beginning of each
+ ;; following line, and filling a multi-line paragraph whose first
+ ;; two lines start with * does insert * at the beginning of each
+ ;; following line. If you know how does adaptive filling works, you
+ ;; know what I mean.
(setq-local adaptive-fill-first-line-regexp
(rx bos
(seq (* (syntax whitespace))
- (group (or (seq "/" (+ "/")) (* "*")))
+ (group (seq "/" (+ "/")))
(* (syntax whitespace)))
eos))
;; Same as `adaptive-fill-regexp'.
@@ -751,7 +778,6 @@ Set up:
(define-derived-mode c++-ts-mode c-ts-base-mode "C++"
"Major mode for editing C++, powered by tree-sitter."
:group 'c++
- :syntax-table c++-ts-mode--syntax-table
(unless (treesit-ready-p 'cpp)
(error "Tree-sitter for C++ isn't available"))
@@ -761,6 +787,8 @@ Set up:
"raw_string_literal")))
(treesit-parser-create 'cpp)
+ (setq-local syntax-propertize-function
+ #'c-ts-mode--syntax-propertize)
(setq-local treesit-simple-indent-rules
(c-ts-mode--set-indent-style 'cpp))
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index 653038a09e3..79b7e74ec41 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -3479,36 +3479,35 @@ This function is intended for use in `after-change-functions'."
(treesit-font-lock-rules
:language 'javascript
- :override t
:feature 'comment
- `((comment) @font-lock-comment-face)
+ '((comment) @font-lock-comment-face)
:language 'javascript
- :override t
:feature 'constant
- `(((identifier) @font-lock-constant-face
+ '(((identifier) @font-lock-constant-face
(:match "^[A-Z_][A-Z_\\d]*$" @font-lock-constant-face))
[(true) (false) (null)] @font-lock-constant-face)
:language 'javascript
- :override t
:feature 'keyword
`([,@js--treesit-keywords] @font-lock-keyword-face
[(this) (super)] @font-lock-keyword-face)
:language 'javascript
- :override t
:feature 'string
- `((regex pattern: (regex_pattern)) @font-lock-string-face
- (string) @font-lock-string-face
- (template_string) @js--fontify-template-string
- (template_substitution ["${" "}"] @font-lock-builtin-face))
+ '((regex pattern: (regex_pattern)) @font-lock-string-face
+ (string) @font-lock-string-face)
:language 'javascript
+ :feature 'string-interpolation
:override t
- :feature 'declaration
- `((function
+ '((template_string) @js--fontify-template-string
+ (template_substitution ["${" "}"] @font-lock-delimiter-face))
+
+ :language 'javascript
+ :feature 'definition
+ '((function
name: (identifier) @font-lock-function-name-face)
(class_declaration
@@ -3535,24 +3534,10 @@ This function is intended for use in `after-change-functions'."
value: (array (number) (function))))
:language 'javascript
- :override t
- :feature 'identifier
- `((new_expression
- constructor: (identifier) @font-lock-type-face)
-
- (for_in_statement
- left: (identifier) @font-lock-variable-name-face)
-
- (arrow_function
- parameter: (identifier) @font-lock-variable-name-face))
-
- :language 'javascript
- :override t
:feature 'property
- ;; This needs to be before function-name feature, because methods
- ;; can be both property and function-name, and we want them in
- ;; function-name face.
- `((property_identifier) @font-lock-property-face
+ '(((property_identifier) @font-lock-property-face
+ (:pred js--treesit-property-not-function-p
+ @font-lock-property-face))
(pair value: (identifier) @font-lock-variable-name-face)
@@ -3561,36 +3546,27 @@ This function is intended for use in `after-change-functions'."
((shorthand_property_identifier_pattern) @font-lock-property-face))
:language 'javascript
- :override t
- :feature 'expression
- `((assignment_expression
- left: [(identifier) @font-lock-function-name-face
- (member_expression property: (property_identifier)
- @font-lock-function-name-face)]
- right: [(function) (arrow_function)])
-
- (call_expression
+ :feature 'assignment
+ '((assignment_expression
+ left: (_) @js--treesit-fontify-assignment-lhs))
+
+ :language 'javascript
+ :feature 'function
+ '((call_expression
function: [(identifier) @font-lock-function-name-face
(member_expression
property:
(property_identifier) @font-lock-function-name-face)])
-
- (assignment_expression
- left: [(identifier) @font-lock-variable-name-face
- (member_expression
- property: (property_identifier) @font-lock-variable-name-face)]))
-
- :language 'javascript
- :override t
- :feature 'pattern
- `((pair_pattern key: (property_identifier) @font-lock-variable-name-face)
- (array_pattern (identifier) @font-lock-variable-name-face))
+ (method_definition
+ name: (property_identifier) @font-lock-function-name-face)
+ (function_declaration
+ name: (identifier) @font-lock-function-name-face)
+ (function
+ name: (identifier) @font-lock-function-name-face))
:language 'javascript
- :override t
:feature 'jsx
- `(
- (jsx_opening_element
+ '((jsx_opening_element
[(nested_identifier (identifier)) (identifier)]
@font-lock-function-name-face)
@@ -3608,7 +3584,7 @@ This function is intended for use in `after-change-functions'."
:language 'javascript
:feature 'number
- `((number) @font-lock-number-face
+ '((number) @font-lock-number-face
((identifier) @font-lock-number-face
(:match "^\\(:?NaN\\|Infinity\\)$" @font-lock-number-face)))
@@ -3657,6 +3633,31 @@ OVERRIDE is the override flag described in
(setq font-beg (treesit-node-end child)
child (treesit-node-next-sibling child)))))
+(defun js--treesit-property-not-function-p (node)
+ "Check that NODE, a property_identifier, is not used as a function."
+ (not (equal (treesit-node-type
+ (treesit-node-parent ; Maybe call_expression.
+ (treesit-node-parent ; Maybe member_expression.
+ node)))
+ "call_expression")))
+
+(defvar js--treesit-lhs-identifier-query
+ (treesit-query-compile 'javascript '((identifier) @id
+ (property_identifier) @id))
+ "Query that captures identifier and query_identifier.")
+
+(defun js--treesit-fontify-assignment-lhs (node override start end &rest _)
+ "Fontify the lhs NODE of an assignment_expression.
+For OVERRIDE, START, END, see `treesit-font-lock-rules'."
+ (dolist (node (treesit-query-capture
+ node js--treesit-lhs-identifier-query nil nil t))
+ (treesit-fontify-with-override
+ (treesit-node-start node) (treesit-node-end node)
+ (pcase (treesit-node-type node)
+ ("identifier" 'font-lock-variable-name-face)
+ ("property_identifier" 'font-lock-property-face))
+ override start end)))
+
(defun js--treesit-defun-name (node)
"Return the defun name of NODE.
Return nil if there is no name or if NODE is not a defun node."
@@ -3815,11 +3816,12 @@ Currently there are `js-mode' and `js-ts-mode'."
;; Fontification.
(setq-local treesit-font-lock-settings js--treesit-font-lock-settings)
(setq-local treesit-font-lock-feature-list
- '(( comment declaration)
+ '(( comment definition)
( keyword string)
- ( constant escape-sequence expression
- identifier jsx number pattern property)
- ( bracket delimiter operator)))
+ ( assignment constant escape-sequence jsx number
+ pattern)
+ ( bracket delimiter function operator property
+ string-interpolation)))
;; Imenu
(setq-local treesit-simple-imenu-settings
`(("Function" "\\`function_declaration\\'" nil nil)