Skip to content

Commit a62c1d6

Browse files
committed
Upgrade grammar to version 0.23.1, add more faceup tests
Change-Id: I97687a2c37ada49808747d91575783e5c8549765
1 parent f1b0610 commit a62c1d6

File tree

6 files changed

+1683
-62
lines changed

6 files changed

+1683
-62
lines changed

julia-ts-mode.el

Lines changed: 72 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@
4040
(require 'julia-mode)
4141
(require 'julia-ts-misc)
4242

43-
;; Fix grammar version to 0.23.0, which is known to be compatible with the
43+
;; Fix grammar version to 0.23.1, which is known to be compatible with the
4444
;; treesitter queries defined in the present version of the mode definition.
4545
(add-to-list 'treesit-language-source-alist
46-
'(julia "https://github.com/tree-sitter/tree-sitter-julia" "v0.23.0"))
46+
'(julia "https://github.com/tree-sitter/tree-sitter-julia" "v0.23.1"))
4747

4848
(declare-function treesit-parser-create "treesit.c")
4949

@@ -132,8 +132,8 @@ Otherwise, the indentation is:
132132

133133
(defvar julia-ts--keywords
134134
'("baremodule" "begin" "catch" "const" "do" "else" "elseif" "end" "export"
135-
"finally" "for" "function" "global" "if" "in" "let" "local" "macro" "module"
136-
"quote" "return" "try" "where" "while")
135+
"finally" "for" "function" "global" "if" "import" "let" "local" "macro"
136+
"module" "outer" "public" "quote" "return" "try" "using" "where" "while")
137137
"Keywords for `julia-ts-mode'.")
138138

139139
(defvar julia-ts--treesit-font-lock-settings
@@ -152,7 +152,9 @@ Otherwise, the indentation is:
152152
(field_expression
153153
value: (identifier) "." (identifier) @font-lock-variable-name-face)))
154154
(local_statement (identifier) @font-lock-variable-name-face)
155-
(let_binding (identifier) @font-lock-variable-name-face)
155+
(let_statement :anchor (identifier) @font-lock-variable-name-face)
156+
(let_statement "," :anchor (identifier) @font-lock-variable-name-face)
157+
(let_binding :anchor (identifier) @font-lock-variable-name-face)
156158
(global_statement (identifier) @font-lock-variable-name-face))
157159

158160
:language 'julia
@@ -174,12 +176,31 @@ Otherwise, the indentation is:
174176
(signature (identifier) @font-lock-function-name-face))
175177
(function_definition
176178
(signature
177-
(call_expression (identifier) @font-lock-function-name-face)))
179+
(call_expression [(identifier) (operator)] @font-lock-function-name-face)))
180+
(function_definition
181+
(signature
182+
(typed_expression
183+
(call_expression [(identifier) (operator)] @font-lock-function-name-face))))
184+
(function_definition
185+
(signature
186+
(where_expression
187+
(call_expression [(identifier) (operator)] @font-lock-function-name-face))))
188+
(function_definition
189+
(signature
190+
(where_expression
191+
(typed_expression
192+
(call_expression [(identifier) (operator)] @font-lock-function-name-face)))))
178193
(function_definition
179194
(signature
180195
(call_expression
181196
(field_expression
182197
value: (identifier) "." (identifier) @font-lock-function-name-face))))
198+
(function_definition
199+
(signature
200+
(typed_expression
201+
(call_expression
202+
(field_expression
203+
value: (identifier) "." (identifier) @font-lock-function-name-face)))))
183204
(macro_definition
184205
(signature
185206
(call_expression (identifier) @font-lock-function-name-face)))
@@ -188,11 +209,21 @@ Otherwise, the indentation is:
188209
(call_expression
189210
(field_expression
190211
value: (identifier) "." (identifier) @font-lock-function-name-face))))
191-
(abstract_definition name: (identifier) @font-lock-type-face)
192-
(struct_definition name: (identifier) @font-lock-type-face)
212+
(abstract_definition
213+
(type_head (identifier) @font-lock-type-face))
214+
(abstract_definition
215+
(type_head (binary_expression (identifier) @font-lock-type-face)))
216+
(primitive_definition
217+
(type_head (identifier) @font-lock-type-face))
218+
(primitive_definition
219+
(type_head (binary_expression (identifier) @font-lock-type-face)))
220+
(struct_definition
221+
(type_head (identifier) @font-lock-type-face))
222+
(struct_definition
223+
(type_head (binary_expression (identifier) @font-lock-type-face)))
193224
(assignment
194225
:anchor
195-
(call_expression (identifier) @font-lock-function-name-face))
226+
(call_expression [(identifier) (operator)] @font-lock-function-name-face))
196227
(assignment
197228
:anchor
198229
(call_expression
@@ -217,15 +248,12 @@ Otherwise, the indentation is:
217248
:language 'julia
218249
:feature 'keyword
219250
`((abstract_definition ["abstract" "type"] @font-lock-keyword-face)
251+
(primitive_definition ["primitive" "type"] @font-lock-keyword-face)
252+
(struct_definition ["mutable" "struct"] @font-lock-keyword-face)
220253
(break_statement) @font-lock-keyword-face
221254
(continue_statement) @font-lock-keyword-face
222-
(for_binding "in" @font-lock-keyword-face)
223-
(import_statement ["import" "using"] @font-lock-keyword-face)
224-
((vector_expression
225-
(range_expression
226-
(identifier) @font-lock-keyword-face
227-
(:match "^\\(:?begin\\|end\\)$" @font-lock-keyword-face))))
228-
(struct_definition ["mutable" "struct"] @font-lock-keyword-face)
255+
((operator) @font-lock-keyword-face
256+
(:equal "in" @font-lock-keyword-face))
229257
([,@julia-ts--keywords]) @font-lock-keyword-face)
230258

231259
:language 'julia
@@ -242,9 +270,10 @@ Otherwise, the indentation is:
242270
:language 'julia
243271
:feature 'operator
244272
`((adjoint_expression "'" @font-lock-type-face)
245-
(let_binding "=" @font-lock-type-face)
246-
(for_binding ["=" ""] @font-lock-type-face)
247-
(function_expression "->" @font-lock-type-face)
273+
(let_binding (operator) @font-lock-type-face)
274+
((for_binding (operator) @font-lock-type-face)
275+
(:match "^\\[=∈\\]$" @font-lock-type-face))
276+
(arrow_function_expression "->" @font-lock-type-face)
248277
(operator) @font-lock-type-face
249278
(splat_expression "..." @font-lock-type-face)
250279
(ternary_expression ["?" ":"] @font-lock-type-face)
@@ -287,15 +316,30 @@ Otherwise, the indentation is:
287316
:language 'julia
288317
:feature 'type
289318
:override t
290-
`((type_clause (operator) (_) @font-lock-type-face)
291-
(typed_expression (_) "::" (_) @font-lock-type-face)
292-
(unary_typed_expression (_) @font-lock-type-face)
293-
(where_clause "where"
294-
(curly_expression "{"
295-
(binary_expression (identifier)
296-
(operator)
297-
(_)
298-
@font-lock-type-face)))))
319+
`((typed_expression (_) "::" (identifier) @font-lock-type-face)
320+
(typed_expression (_) "::" (field_expression "." (identifier) @font-lock-type-face))
321+
(unary_typed_expression "::" (_) @font-lock-type-face)
322+
(parametrized_type_expression (identifier) @font-lock-type-face)
323+
(parametrized_type_expression
324+
(curly_expression "{" (identifier) @font-lock-type-face))
325+
(parametrized_type_expression
326+
(curly_expression "{" (unary_expression (identifier) @font-lock-type-face)))
327+
(parametrized_type_expression
328+
(curly_expression "{" (binary_expression (identifier) @font-lock-type-face)))
329+
(where_expression "where" (identifier) @font-lock-type-face)
330+
(where_expression
331+
"where"
332+
(curly_expression "{" (identifier) @font-lock-type-face))
333+
(where_expression
334+
"where"
335+
(curly_expression "{" (binary_expression (identifier) @font-lock-type-face))))
336+
337+
:language 'julia
338+
:feature 'keyword
339+
:override t
340+
'((((identifier) @font-lock-keyword-face)
341+
(:equal "new" @font-lock-keyword-face))))
342+
299343
"Tree-sitter font-lock settings for `julia-ts-mode'.")
300344

301345
(defvar julia-ts--treesit-indent-rules

test/ArgTools.jl.faceup

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ This restriction may be relaxed in the future, which would not break any working
4545
The `ArgRead` types is a union of the types that the `arg_read` function knows
4646
how to convert into readable IO handles. See [`arg_read`](@ref) for details.
4747
"""»
48-
«k:const» «v:ArgRead» = Union{AbstractString, AbstractCmd, IO}
48+
«k:const» «v:ArgRead» = «t:Union»{«t:AbstractString», «t:AbstractCmd», «t:IO»}
4949

5050
«s:"""
5151
ArgWrite = Union{AbstractString, AbstractCmd, IO}
@@ -54,7 +54,7 @@ The `ArgWrite` types is a union of the types that the `arg_write` function knows
5454
how to convert into writeable IO handles, except for `Nothing` which `arg_write`
5555
handles by generating a temporary file. See [`arg_write`](@ref) for details.
5656
"""»
57-
«k:const» «v:ArgWrite» = Union{AbstractString, AbstractCmd, IO}
57+
«k:const» «v:ArgWrite» = «t:Union»{«t:AbstractString», «t:AbstractCmd», «t:IO»}
5858

5959
«s:"""
6060
arg_read(f::Function, arg::ArgRead) -> f(arg_io)
@@ -166,7 +166,7 @@ In all cases the path to the directory is returned. If an error occurs during
166166
`f(arg)`, the directory is returned to its original state: if it already existed
167167
but was empty, it will be emptied; if it did not exist it will be deleted.
168168
"""»
169-
«k:function» «f:arg_mkdir»(f::«t:Function», arg::«t:Union{AbstractString, Nothing)
169+
«k:function» «f:arg_mkdir»(f::«t:Function», arg::«t:Union»{«t:AbstractString», «t:Nothing»})
170170
«v:existed» = «c:false»
171171
«k:if» arg === «b:nothing»
172172
«v:arg» = mktempdir()

test/Downloads.jl.faceup

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ resources are not cleaned up until `Downloader` is garbage collected.
3838
"""»
3939
«k:mutable» «k:struct» «t:Downloader»
4040
multi::«t:Multi»
41-
ca_roots::«t:Union{String, Nothing
42-
easy_hook::«t:Union{Function, Nothing
41+
ca_roots::«t:Union»{«t:String», «t:Nothing»}
42+
easy_hook::«t:Union»{«t:Function», «t:Nothing»}
4343

44-
«f:Downloader»(multi::«t:Multi») = new(multi, get_ca_roots(), EASY_HOOK[])
44+
«f:Downloader»(multi::«t:Multi») = «k:new»(multi, get_ca_roots(), EASY_HOOK[])
4545
«k:end»
4646
«f:Downloader»(; grace::«t:Real»=«c:30») = Downloader(Multi(grace_ms(grace)))
4747

@@ -63,7 +63,7 @@ resources are not cleaned up until `Downloader` is garbage collected.
6363
«k:end»
6464

6565
«k:const» «v:DOWNLOAD_LOCK» = ReentrantLock()
66-
«k:const» «v:DOWNLOADER» = Ref{Union{Downloader, Nothing}}(«b:nothing»)
66+
«k:const» «v:DOWNLOADER» = «t:Ref»{«t:Union»{«t:Downloader», «t:Nothing»}}(«b:nothing»)
6767

6868
«s:"""
6969
`EASY_HOOK` is a modifable global hook to used as the default `easy_hook` on
@@ -73,7 +73,7 @@ new `Downloader` objects. This supplies a mechanism to set options for the
7373
It is expected to be function taking two arguments: an `Easy` struct and an
7474
`info` NamedTuple with names `url`, `method` and `headers`.
7575
"""»
76-
«k:const» «v:EASY_HOOK» = Ref{Union{Function, Nothing}}(«b:nothing»)
76+
«k:const» «v:EASY_HOOK» = «t:Ref»{«t:Union»{«t:Function», «t:Nothing»}}(«b:nothing»)
7777

7878
«s:"""
7979
struct Response
@@ -100,11 +100,11 @@ not support headers, the headers vector will be empty. HTTP/2 does not include a
100100
status message, only a status code, so the message will be empty.
101101
"""»
102102
«k:struct» «t:Response»
103-
proto :: «t:Union{String, Nothing
103+
proto :: «t:Union»{«t:String», «t:Nothing»}
104104
url :: «t:String» «x:# redirected URL»
105105
status :: «t:Int»
106106
message :: «t:String»
107-
headers :: «t:Vector{Pair{String,String}}»
107+
headers :: «t:Vector»{«t:Pair»{«t:String»,«t:String»}}
108108
«k:end»
109109

110110
Curl.«f:status_ok»(response::«t:Response») = status_ok(response.proto, response.status)
@@ -246,14 +246,14 @@ Downloads.download("https://httpbingo.julialang.org/delay/30"; downloader)
246246
"""»
247247
«k:function» «f:download»(
248248
url :: «t:AbstractString»,
249-
output :: «t:Union{ArgWrite, Nothing = «b:nothing»;
250-
method :: «t:Union{AbstractString, Nothing = «b:nothing»,
251-
headers :: «t:Union{AbstractVector, AbstractDict = Pair{String,String}[],
249+
output :: «t:Union»{«t:ArgWrite», «t:Nothing»} = «b:nothing»;
250+
method :: «t:Union»{«t:AbstractString», «t:Nothing»} = «b:nothing»,
251+
headers :: «t:Union»{«t:AbstractVector», «t:AbstractDict»} = «t:Pair»{«t:String»,«t:String»}[],
252252
timeout :: «t:Real» = «b:Inf»,
253-
progress :: «t:Union{Function, Nothing = «b:nothing»,
253+
progress :: «t:Union»{«t:Function», «t:Nothing»} = «b:nothing»,
254254
verbose :: «t:Bool» = «c:false»,
255-
debug :: «t:Union{Function, Nothing = «b:nothing»,
256-
downloader :: «t:Union{Downloader, Nothing = «b:nothing»,
255+
debug :: «t:Union»{«t:Function», «t:Nothing»} = «b:nothing»,
256+
downloader :: «t:Union»{«t:Downloader», «t:Nothing»} = «b:nothing»,
257257
) :: «t:ArgWrite»
258258
arg_write(output) «k:do» output
259259
«v:response» = request(
@@ -327,18 +327,18 @@ running request, for example if the user wants to cancel a download.
327327
"""»
328328
«k:function» «f:request»(
329329
url :: «t:AbstractString»;
330-
input :: «t:Union{ArgRead, Nothing = «b:nothing»,
331-
output :: «t:Union{ArgWrite, Nothing = «b:nothing»,
332-
method :: «t:Union{AbstractString, Nothing = «b:nothing»,
333-
headers :: «t:Union{AbstractVector, AbstractDict = Pair{String,String}[],
330+
input :: «t:Union»{«t:ArgRead», «t:Nothing»} = «b:nothing»,
331+
output :: «t:Union»{«t:ArgWrite», «t:Nothing»} = «b:nothing»,
332+
method :: «t:Union»{«t:AbstractString», «t:Nothing»} = «b:nothing»,
333+
headers :: «t:Union»{«t:AbstractVector», «t:AbstractDict»} = «t:Pair»{«t:String»,«t:String»}[],
334334
timeout :: «t:Real» = «b:Inf»,
335-
progress :: «t:Union{Function, Nothing = «b:nothing»,
335+
progress :: «t:Union»{«t:Function», «t:Nothing»} = «b:nothing»,
336336
verbose :: «t:Bool» = «c:false»,
337-
debug :: «t:Union{Function, Nothing = «b:nothing»,
337+
debug :: «t:Union»{«t:Function», «t:Nothing»} = «b:nothing»,
338338
throw :: «t:Bool» = «c:true»,
339-
downloader :: «t:Union{Downloader, Nothing = «b:nothing»,
340-
interrupt :: «t:Union{Nothing, Base.Event}» = «b:nothing»,
341-
) :: «t:Union{Response, RequestError
339+
downloader :: «t:Union»{«t:Downloader», «t:Nothing»} = «b:nothing»,
340+
interrupt :: «t:Union»{«t:Nothing», Base.Event} = «b:nothing»,
341+
) :: «t:Union»{«t:Response», «t:RequestError»}
342342
«k:if» downloader === «b:nothing»
343343
lock(DOWNLOAD_LOCK) «k:do»
344344
«v:downloader» = DOWNLOADER[]
@@ -396,7 +396,7 @@ running request, for example if the user wants to cancel a download.
396396

397397
«x:# do the request»
398398
add_handle(downloader.multi, easy)
399-
«v:interrupted» = Threads.Atomic{Bool}(«c:false»)
399+
«v:interrupted» = Threads.Atomic{«t:Bool»}(«c:false»)
400400
«k:if» interrupt !== «b:nothing»
401401
«v:interrupt_task» = «:julia-ts-macro-face:@async» «k:begin»
402402
«x:# wait for the interrupt event»
@@ -459,8 +459,8 @@ running request, for example if the user wants to cancel a download.
459459
«x:## helper functions ##»
460460

461461
«k:function» «f:p_func»(progress::«t:Function», input::«t:ArgRead», output::«t:ArgWrite»)
462-
hasmethod(progress, NTuple{«c:4»,Int}) && «k:return» progress
463-
hasmethod(progress, NTuple{«c:2»,Int}) ||
462+
hasmethod(progress, «t:NTuple»{«c:4»,«t:Int»}) && «k:return» progress
463+
hasmethod(progress, «t:NTuple»{«c:2»,«t:Int»}) ||
464464
throw(ArgumentError(«s:"invalid progress callback"»))
465465

466466
input === devnull && output !== devnull &&
@@ -474,11 +474,11 @@ running request, for example if the user wants to cancel a download.
474474
«f:p_func»(progress::«t:Nothing», input::«t:ArgRead», output::«t:ArgWrite») = «b:nothing»
475475

476476
«f:arg_read_size»(path::«t:AbstractString») = filesize(path)
477-
«f:arg_read_size»(io::«t:Base.GenericIOBuffer») = bytesavailable(io)
477+
«f:arg_read_size»(io::Base.«t:GenericIOBuffer») = bytesavailable(io)
478478
«f:arg_read_size»(::«t:Base.DevNull») = «c:0»
479479
«f:arg_read_size»(::«t:Any») = «b:nothing»
480480

481-
«k:function» «f:content_length»(headers::«t:Union{AbstractVector, AbstractDict)
481+
«k:function» «f:content_length»(headers::«t:Union»{«t:AbstractVector», «t:AbstractDict»})
482482
«k:for» (key, value) «k:in» headers
483483
«k:if» lowercase(key) == «s:"content-length"» && isa(value, AbstractString)
484484
«k:return» tryparse(Int, value)
@@ -497,7 +497,7 @@ running request, for example if the user wants to cancel a download.
497497
Set the default `Downloader`. If no argument is provided, resets the default downloader so that a fresh one is created the next time the default downloader is needed.
498498
"""»
499499
«k:function» «f:default_downloader!»(
500-
downloader :: «t:Union{Downloader, Nothing = «b:nothing»
500+
downloader :: «t:Union»{«t:Downloader», «t:Nothing»} = «b:nothing»
501501
)
502502
lock(DOWNLOAD_LOCK) «k:do»
503503
DOWNLOADER[] = downloader
@@ -510,8 +510,8 @@ Set the default `Downloader`. If no argument is provided, resets the default dow
510510
«v:d» = Downloader()
511511
«v:f» = mktemp()[«c:1»]
512512
download(«s:"file://"» * f; «:julia-ts-quoted-symbol-face:downloader»=d)
513-
precompile(Tuple{typeof(Downloads.download), String, String})
514-
precompile(Tuple{typeof(Downloads.Curl.status_2xx_ok), Int64})
513+
precompile(«t:Tuple»{typeof(Downloads.download), «t:String», «t:String»})
514+
precompile(«t:Tuple»{typeof(Downloads.Curl.status_2xx_ok), «t:Int64»})
515515
«k:end»
516516

517517
«k:end» «x:# module»

test/test.el

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
;;; test.el --- ert tests for font-locking with julia-ts-mode
2+
;;; Commentary:
3+
;; Load this package then run M-x ert RET t RET
4+
5+
;;; Code:
16
(require 'faceup)
27

38
(defvar julia-font-lock-test-dir (faceup-this-file-directory))
@@ -10,5 +15,9 @@
1015
(faceup-defexplainer julia-font-lock-test)
1116

1217
(ert-deftest julia-font-lock-file-test ()
13-
(should (julia-font-lock-test "ArgTools.jl")
18+
(should (julia-font-lock-test "ArgTools.jl"))
1419
(should (julia-font-lock-test "Downloads.jl"))
20+
(should (julia-font-lock-test "tree-sitter-corpus.jl")))
21+
22+
(provide 'test)
23+
;;; test.el ends here

0 commit comments

Comments
 (0)