Skip to content

Commit df75a4b

Browse files
committed
Using syntax to highlight name and comment instead of regex alone
1 parent 90ad838 commit df75a4b

File tree

1 file changed

+43
-22
lines changed

1 file changed

+43
-22
lines changed

json-mode.el

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ Return the new `auto-mode-alist' entry"
6969
".bowerrc"
7070
"composer.lock"
7171
)
72-
"List of filename as string to pass for the JSON entry of
73-
`auto-mode-alist'.
72+
"List of filename as string to pass for the JSON entry of `auto-mode-alist'.
7473
7574
Note however that custom `json-mode' entries in `auto-mode-alist'
7675
won’t be affected."
@@ -108,39 +107,61 @@ This function calls `json-mode--update-auto-mode' to change the
108107
(defconst json-mode-number-re (rx (group (one-or-more digit)
109108
(optional ?\. (one-or-more digit)))))
110109
(defconst json-mode-keyword-re (rx (group (or "true" "false" "null"))))
111-
(defconst json-mode-line-comments-re
112-
(rx (and bol (0+ space) (group (and "//" (*? nonl) eol)))))
113-
(defconst json-mode-block-comments-re
114-
(rx (group (and "/*" (*? anything) "*/"))))
115110

116111
(defconst json-font-lock-keywords-1
117112
(list
118-
(list json-mode-quoted-key-re 1 font-lock-keyword-face)
119-
(list json-mode-quoted-string-re 1 font-lock-string-face)
120-
(list json-mode-keyword-re 1 font-lock-constant-face)
121-
(list json-mode-number-re 1 font-lock-constant-face)
122-
)
123-
"Level one font lock for `json-mode'.")
124-
125-
(defconst jsonc-font-lock-keywords-1
126-
(list
127-
(list json-mode-line-comments-re 1 font-lock-comment-face)
128-
(list json-mode-block-comments-re 1 font-lock-comment-face)
129-
(list json-mode-quoted-key-re 1 font-lock-keyword-face)
130-
(list json-mode-quoted-string-re 1 font-lock-string-face)
131113
(list json-mode-keyword-re 1 font-lock-constant-face)
132114
(list json-mode-number-re 1 font-lock-constant-face))
133-
"Level one font lock for `jsonc-mode'.")
115+
"Level one font lock.")
116+
117+
(defvar json-mode-syntax-table
118+
(let ((st (make-syntax-table)))
119+
;; Objects
120+
(modify-syntax-entry ?\{ "(}" st)
121+
(modify-syntax-entry ?\} "){" st)
122+
;; Arrays
123+
(modify-syntax-entry ?\[ "(]" st)
124+
(modify-syntax-entry ?\] ")[" st)
125+
;; Strings
126+
(modify-syntax-entry ?\" "\"" st)
127+
st))
128+
129+
(defvar jsonc-mode-syntax-table
130+
(let ((st (copy-syntax-table json-mode-syntax-table)))
131+
;; Comments
132+
(modify-syntax-entry ?/ "! 124" st)
133+
(modify-syntax-entry ?\n ">" st)
134+
(modify-syntax-entry ?* "! 23b" st)
135+
st))
136+
137+
(defun json-mode--syntactic-face (state)
138+
"Return syntactic face function for the position represented by STATE.
139+
STATE is a `parse-partial-sexp' state, and the returned function is the
140+
json font lock syntactic face function."
141+
(cond
142+
((nth 3 state)
143+
;; This might be a string or a name
144+
(let ((startpos (nth 8 state)))
145+
(save-excursion
146+
(goto-char startpos)
147+
(if (looking-at-p json-mode-quoted-key-re)
148+
font-lock-keyword-face
149+
font-lock-string-face))))
150+
((nth 4 state) font-lock-comment-face)))
134151

135152
;;;###autoload
136153
(define-derived-mode json-mode javascript-mode "JSON"
137154
"Major mode for editing JSON files"
138-
(set (make-local-variable 'font-lock-defaults) '(json-font-lock-keywords-1 t)))
155+
:syntax-table json-mode-syntax-table
156+
(set (make-local-variable 'font-lock-defaults)
157+
'(json-font-lock-keywords-1
158+
nil nil nil nil
159+
(font-lock-syntactic-face-function . json-mode--syntactic-face))))
139160

140161
;;;###autoload
141162
(define-derived-mode jsonc-mode json-mode "JSONC"
142163
"Major mode for editing JSON files with comments"
143-
(set (make-local-variable 'font-lock-defaults) '(jsonc-font-lock-keywords-1 t)))
164+
:syntax-table jsonc-mode-syntax-table)
144165

145166
;; Well formatted JSON files almost always begin with “{” or “[”.
146167
;;;###autoload

0 commit comments

Comments
 (0)