Skip to content

Commit 9f8687a

Browse files
committed
Improvements to fontification
1. correctly fontify escape sequences and regex strings; 2. correctly fontify tuple assigments; 3. make function definition name fontification significantly simpler and more robust, fontify more obscure variants correctly.
1 parent d693c6b commit 9f8687a

File tree

4 files changed

+68
-89
lines changed

4 files changed

+68
-89
lines changed

julia-ts-mode.el

Lines changed: 60 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -144,23 +144,38 @@ Otherwise, the indentation is:
144144
(treesit-font-lock-rules
145145
:language 'julia
146146
:feature 'assignment
147-
`((assignment :anchor [(identifier) (operator)] @font-lock-variable-name-face)
147+
`(;; regular variable assignments
148148
(assignment
149149
:anchor
150-
(field_expression
151-
value: (identifier) "." (identifier) @font-lock-variable-name-face))
152-
(assignment (open_tuple (identifier) @font-lock-variable-name-face))
150+
[(identifier) (operator)] @font-lock-variable-name-face)
151+
(assignment
152+
:anchor
153+
(field_expression "." (identifier) @font-lock-variable-name-face))
154+
;; open tuple assignments (comma separated variables without parentheses)
155+
(assignment
156+
:anchor
157+
(open_tuple (identifier) @font-lock-variable-name-face))
153158
(assignment
154159
:anchor
155160
(open_tuple
156-
(field_expression
157-
value: (identifier) "." (identifier) @font-lock-variable-name-face)))
158-
(local_statement (identifier) @font-lock-variable-name-face)
161+
(field_expression "." (identifier) @font-lock-variable-name-face)))
162+
;; closed tuple assignments (comma separated variables with parentheses)
163+
(assignment
164+
:anchor
165+
(tuple_expression (identifier) @font-lock-variable-name-face))
166+
(assignment
167+
:anchor
168+
(tuple_expression
169+
(field_expression "." (identifier) @font-lock-variable-name-face)))
170+
;; let blocks
159171
(let_statement :anchor (identifier) @font-lock-variable-name-face)
160172
((let_statement _ @comma :anchor (identifier) @font-lock-variable-name-face)
161173
(:equal "," @comma))
162174
(let_binding :anchor (identifier) @font-lock-variable-name-face)
175+
;; local and global statements
176+
(local_statement (identifier) @font-lock-variable-name-face)
163177
(global_statement (identifier) @font-lock-variable-name-face)
178+
;; named (keyword) argument names with assigned values
164179
(named_argument (identifier) @julia-ts-keyword-argument-face (operator)))
165180

166181
:language 'julia
@@ -177,81 +192,27 @@ Otherwise, the indentation is:
177192

178193
:language 'julia
179194
:feature 'definition
180-
`((function_definition
181-
(signature (identifier) @font-lock-function-name-face))
182-
(function_definition
183-
(signature
184-
(call_expression [(identifier) (operator)] @font-lock-function-name-face)))
185-
(function_definition
186-
(signature
187-
(typed_expression
188-
(call_expression [(identifier) (operator)] @font-lock-function-name-face))))
189-
(function_definition
190-
(signature
191-
(where_expression
192-
(call_expression [(identifier) (operator)] @font-lock-function-name-face))))
193-
(function_definition
194-
(signature
195-
(where_expression
196-
(typed_expression
197-
(call_expression [(identifier) (operator)] @font-lock-function-name-face)))))
198-
(function_definition
199-
(signature
200-
(call_expression
201-
(field_expression
202-
value: (identifier) "." (identifier) @font-lock-function-name-face))))
195+
`(;; function declaration
203196
(function_definition
204-
(signature
205-
(typed_expression
206-
(call_expression
207-
(field_expression
208-
value: (identifier) "." (identifier) @font-lock-function-name-face)))))
209-
(macro_definition
210-
(signature
211-
(call_expression (identifier) @font-lock-function-name-face)))
212-
(macro_definition
213-
(signature
214-
(call_expression
215-
(field_expression
216-
value: (identifier) "." (identifier) @font-lock-function-name-face))))
217-
(abstract_definition
218-
(type_head (identifier) @font-lock-type-face))
219-
(abstract_definition
220-
(type_head (binary_expression (identifier) @font-lock-type-face)))
221-
(primitive_definition
222-
(type_head (identifier) @font-lock-type-face))
223-
(primitive_definition
224-
(type_head (binary_expression (identifier) @font-lock-type-face)))
225-
(struct_definition
226-
(type_head (identifier) @font-lock-type-face))
227-
(struct_definition
228-
(type_head (binary_expression (identifier) @font-lock-type-face)))
229-
(assignment
230-
:anchor
231-
(call_expression [(identifier) (operator)] @font-lock-function-name-face))
232-
(assignment
233-
:anchor
234-
(call_expression
235-
(parenthesized_expression
236-
[(identifier) (operator)] @font-lock-function-name-face)))
237-
(assignment
238-
:anchor
239-
(call_expression
240-
(field_expression
241-
value: (identifier) "." (identifier) @font-lock-function-name-face)))
242-
(assignment
243-
:anchor
244-
(where_expression
245-
(call_expression (identifier) @font-lock-function-name-face)))
246-
(assignment
247-
:anchor
248-
(where_expression
249-
(call_expression
250-
(field_expression
251-
value: (identifier) "." (identifier) @font-lock-function-name-face))))
197+
(signature (identifier) @font-lock-function-name-face))
198+
;; function definitions (long and short syntax)
199+
(call_expression
200+
[(identifier) (operator)] @font-lock-function-name-face
201+
(:pred julia-ts--fundef-name-p @font-lock-function-name-face))
202+
(call_expression
203+
(parenthesized_expression
204+
[(identifier) (operator)] @font-lock-function-name-face)
205+
(:pred julia-ts--fundef-name-p @font-lock-function-name-face))
206+
(call_expression
207+
(field_expression "." [(identifier) (operator)] @font-lock-function-name-face)
208+
(:pred julia-ts--fundef-name-p @font-lock-function-name-face))
209+
;; binary operator definition as assignment
252210
(assignment
253211
:anchor
254-
(binary_expression _ (operator) @font-lock-function-name-face)))
212+
(binary_expression _ (operator) @font-lock-function-name-face))
213+
;; struct/abstract type/primitive type definitions
214+
(type_head (identifier) @font-lock-type-face)
215+
(type_head (binary_expression (identifier) @font-lock-type-face)))
255216

256217
:language 'julia
257218
:feature 'error
@@ -315,6 +276,12 @@ Otherwise, the indentation is:
315276
:override 'keep
316277
`((quote_expression) @julia-ts-quoted-symbol-face)
317278

279+
:language 'julia
280+
:feature 'string
281+
'(((escape_sequence) @font-lock-escape-face)
282+
((prefixed_string_literal prefix: _ @prefix) @font-lock-regexp-face
283+
(:equal "r" @prefix)))
284+
318285
:language 'julia
319286
:feature 'string
320287
:override 'keep
@@ -432,6 +399,20 @@ Return nil if there is no name or if NODE is not a defun node."
432399
(lambda (child)
433400
(equal (treesit-node-type child) type)))))
434401

402+
(defun julia-ts--fundef-name-p (node)
403+
"Return non-nil if NODE is the name of a function definition.
404+
NODE is recognized as such if it has an ancestor that is either a
405+
`signature' (long syntax) or an `assignment' (short syntax), and
406+
the first child of this ancestor is also an ancestor."
407+
(let ((prev node))
408+
(treesit-parent-until
409+
node
410+
(lambda (ancestor)
411+
(prog1
412+
(and (member (treesit-node-type ancestor) '("signature" "assignment"))
413+
(equal (treesit-node-child ancestor 0) prev))
414+
(setq prev ancestor))))))
415+
435416
;;;###autoload
436417
(add-to-list 'auto-mode-alist '("\\.jl\\'" . julia-ts-mode))
437418

test/Downloads.jl.faceup

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ in which case both the inner and outer code and message may be of interest.
149149
«v:errstr» = err.message
150150
«v:status» = err.response.status
151151
«v:message» = err.response.message
152-
«v:status_re» = Regex(status == «c:0» ? «s:""» : «s:"\\b»«:julia-ts-string-interpolation-face:$»«D:status»«s:\\b"»)
152+
«v:status_re» = Regex(status == «c:0» ? «s:""» : «s:"»«:font-lock-escape-face:\\»«s:b»«:julia-ts-string-interpolation-face:$»«D:status»«:font-lock-escape-face:\\»«s:b"»)
153153

154154
err.code == Curl.CURLE_OK &&
155155
«k:return» isempty(message) ? «s:"Error status »«:julia-ts-string-interpolation-face:$»«D:status»«s:"» :

test/tree-sitter-corpus.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,6 @@ echo "\033[31mred\033[m"
492492
# non-standard string literals
493493
# ==============================
494494

495-
# FIXME: \s shouldn't be an escape_sequence here
496495
trailing_ws = r"\s+$"
497496
version = v"1.0"
498497
K"\\"

test/tree-sitter-corpus.jl.faceup

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ Base.«f:foo»(x) = x
227227
n
228228
«k:end»
229229

230-
f(n::«t:N», m::«t:M») «k:where» {«t:N» <: «t:Number»} «k:where» {«t:M» <: «t:Integer»} = n^m
230+
«f:f»(n::«t:N», m::«t:M») «k:where» {«t:N» <: «t:Number»} «k:where» {«t:M» <: «t:Integer»} = n^m
231231

232232
«t:Foo»{«t:T»}(x::«t:T») «k:where» {«t:T»} = x
233233

@@ -466,10 +466,10 @@ a -> «v:a» = «c:2», «c:3»
466466
«x:# ==============================»
467467

468468
«s:""»
469-
«s:"\"
469+
«s:"»«:font-lock-escape-face:\"»«s:
470470
«s:"foo
471471
bar"»
472-
«s:"this is a \"string\"."»
472+
«s:"this is a »«:font-lock-escape-face:\"»«s:string»«:font-lock-escape-face:\"»«s:."»
473473
«s:"""this is also a "string"."""»
474474
«v:band» = «s:"Interpol"»
475475
«s:"»«:julia-ts-string-interpolation-face:$»«D:band»«s: is a cool band"»
@@ -483,19 +483,18 @@ a -> «v:a» = «c:2», «c:3»
483483
«s:`pwd`»
484484
«s:m`pwd`»
485485
«s:`cd »«:julia-ts-string-interpolation-face:$»«D:dir»«s:`»
486-
«s:`echo \`cmd\`
486+
«s:`echo »«:font-lock-escape-face:\`»«s:cmd»«:font-lock-escape-face:\`»«s:
487487
«s:```
488-
echo "\033[31mred\033[m"
488+
echo "»«:font-lock-escape-face:\033»«s:[31mred»«:font-lock-escape-face:\033»«s:[m"
489489
```»
490490

491491
«x:# ==============================»
492492
«x:# non-standard string literals»
493493
«x:# ==============================»
494494

495-
«x:# FIXME: \s shouldn't be an escape_sequence here»
496-
«v:trailing_ws» = «s:r"\s+$"»
495+
«v:trailing_ws» = «:font-lock-regexp-face:r"\s+$"»
497496
«v:version» = «s:v"1.0"»
498-
«s:K"\\
497+
«s:K"»«:font-lock-escape-face:\\»«s:
499498

500499
«x:# ==============================»
501500
«x:# comments»

0 commit comments

Comments
 (0)