Skip to content

Commit 22e551a

Browse files
authored
Add Julia formatter (#230)
This formatter uses a script wrapping the [JuliaFormatter.jl library](https://github.com/domluna/JuliaFormatter.jl). This "formatter script in the plugin" approach hasn't been taken before in `vim-codefmt`, so let me know if you'd prefer a different approach or to reorganize things. (The JuliaFormatter.jl library ships with an executable script, but it only works on file paths (not stdin) and can't handle line ranges. I'm also not sure how to get the path of a bin directory in your Julia environment, which doesn't work like executables in a package management system like npm.) If the user hasn't installed the `JuliaFormatter` package, instructions will point to an `install` script in the same directory as the formatter script. I've tested the shell version of this script, but don't have a Windows machine to test the `.cmd` version. The line-range handling is a bit of a hack: the underlying library doesn't expose this functionality, so I used comments to enable/disable the formatter around relevant blocks. I found some edge case behaviors that I've hopefully documented clearly. The script will use the same `.JuliaFormatter.toml` files in the parent directory hierarchy of the source file being edited to determine the formatter options like style, indent, and line width. This is the same behavior that running the executable from JuliaFormatter.
2 parents 03b8f30 + ae8bd7a commit 22e551a

File tree

11 files changed

+662
-0
lines changed

11 files changed

+662
-0
lines changed

autoload/codefmt/juliaformatter.vim

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
" Copyright 2023 Google LLC
2+
"
3+
" Licensed under the Apache License, Version 2.0 (the "License");
4+
" you may not use this file except in compliance with the License.
5+
" You may obtain a copy of the License at
6+
"
7+
" http://www.apache.org/licenses/LICENSE-2.0
8+
"
9+
" Unless required by applicable law or agreed to in writing, software
10+
" distributed under the License is distributed on an "AS IS" BASIS,
11+
" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
" See the License for the specific language governing permissions and
13+
" limitations under the License.
14+
15+
let s:plugin = maktaba#plugin#Get('codefmt')
16+
17+
let s:checkedInstall = 0
18+
19+
""
20+
" @private
21+
" Formatter: JuliaFormatter
22+
function! codefmt#juliaformatter#GetFormatter() abort
23+
let l:installer =
24+
\ maktaba#path#Join([s:plugin.location, 'bin', 'julia', 'install'])
25+
let l:formatter = {
26+
\ 'name': 'JuliaFormatter', 'setup_instructions': 'Run ' . l:installer}
27+
28+
function l:formatter.IsAvailable() abort
29+
let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray('julia_format_executable')
30+
if codefmt#ShouldPerformIsAvailableChecks()
31+
if !executable(l:cmd[0])
32+
return 0
33+
endif
34+
if !s:checkedInstall
35+
let s:checkedInstall = 1
36+
let l:syscall = maktaba#syscall#Create([cmd[0], "--check-install"])
37+
call l:syscall.Call(0)
38+
if v:shell_error != 0
39+
return 0
40+
endif
41+
endif
42+
endif
43+
return 1
44+
endfunction
45+
46+
function l:formatter.AppliesToBuffer() abort
47+
return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'julia')
48+
endfunction
49+
50+
""
51+
" Reformat the current buffer using formatjulia.jl, only targeting {ranges}.
52+
function l:formatter.FormatRanges(ranges) abort
53+
if empty(a:ranges)
54+
return
55+
endif
56+
for [l:startline, l:endline] in a:ranges
57+
call maktaba#ensure#IsNumber(l:startline)
58+
call maktaba#ensure#IsNumber(l:endline)
59+
endfor
60+
let l:exec = s:plugin.Flag('julia_format_executable')
61+
if empty(l:exec)
62+
let l:cmd = [maktaba#path#Join(
63+
\ [s:plugin.location, 'bin', 'julia', 'formatjulia.jl'])]
64+
else
65+
" Split the command on spaces, unless preceeded by a backslash
66+
let l:cmd = split(l:exec, '\\\@<! ')
67+
endif
68+
" JuliaFormatter looks up .JuliaFormatter.toml settings based on file tree
69+
let l:cmd += ['--file-path', @%]
70+
let l:cmd += ['--lines']
71+
let l:cmd += maktaba#function#Map(a:ranges, {x -> x[0] . ':' . x[1]})
72+
call codefmt#formatterhelpers#Format(l:cmd)
73+
endfunction
74+
75+
return l:formatter
76+
endfunction

bin/julia/.JuliaFormatter.toml

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright 2023 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
indent = 2
16+
margin = 80
17+
trailing_comma = false
18+
whitespace_in_kwargs = false

bin/julia/Manifest.toml

+232
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# This file is machine-generated - editing it directly is not advised
2+
3+
julia_version = "1.9.3"
4+
manifest_format = "2.0"
5+
project_hash = "93e024a7bf6c9615a79c4b80b3a014b0f1f744c9"
6+
7+
[[deps.ArgParse]]
8+
deps = ["Logging", "TextWrap"]
9+
git-tree-sha1 = "3102bce13da501c9104df33549f511cd25264d7d"
10+
uuid = "c7e460c6-2fb9-53a9-8c5b-16f535851c63"
11+
version = "1.1.4"
12+
13+
[[deps.ArgTools]]
14+
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"
15+
version = "1.1.1"
16+
17+
[[deps.Artifacts]]
18+
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
19+
20+
[[deps.Base64]]
21+
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
22+
23+
[[deps.CSTParser]]
24+
deps = ["Tokenize"]
25+
git-tree-sha1 = "3ddd48d200eb8ddf9cb3e0189fc059fd49b97c1f"
26+
uuid = "00ebfdb7-1f24-5e51-bd34-a7502290713f"
27+
version = "3.3.6"
28+
29+
[[deps.CommonMark]]
30+
deps = ["Crayons", "JSON", "PrecompileTools", "URIs"]
31+
git-tree-sha1 = "532c4185d3c9037c0237546d817858b23cf9e071"
32+
uuid = "a80b9123-70ca-4bc0-993e-6e3bcb318db6"
33+
version = "0.8.12"
34+
35+
[[deps.Compat]]
36+
deps = ["UUIDs"]
37+
git-tree-sha1 = "8a62af3e248a8c4bad6b32cbbe663ae02275e32c"
38+
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
39+
version = "4.10.0"
40+
41+
[deps.Compat.extensions]
42+
CompatLinearAlgebraExt = "LinearAlgebra"
43+
44+
[deps.Compat.weakdeps]
45+
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
46+
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
47+
48+
[[deps.Crayons]]
49+
git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15"
50+
uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
51+
version = "4.1.1"
52+
53+
[[deps.DataStructures]]
54+
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
55+
git-tree-sha1 = "3dbd312d370723b6bb43ba9d02fc36abade4518d"
56+
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
57+
version = "0.18.15"
58+
59+
[[deps.Dates]]
60+
deps = ["Printf"]
61+
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
62+
63+
[[deps.Downloads]]
64+
deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"]
65+
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
66+
version = "1.6.0"
67+
68+
[[deps.FileWatching]]
69+
uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
70+
71+
[[deps.Glob]]
72+
git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496"
73+
uuid = "c27321d9-0574-5035-807b-f59d2c89b15c"
74+
version = "1.3.1"
75+
76+
[[deps.InteractiveUtils]]
77+
deps = ["Markdown"]
78+
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
79+
80+
[[deps.JSON]]
81+
deps = ["Dates", "Mmap", "Parsers", "Unicode"]
82+
git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a"
83+
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
84+
version = "0.21.4"
85+
86+
[[deps.JuliaFormatter]]
87+
deps = ["CSTParser", "CommonMark", "DataStructures", "Glob", "Pkg", "PrecompileTools", "Tokenize"]
88+
git-tree-sha1 = "3d5b5b539e4606dcca0e6a467b98a64c8da4850b"
89+
uuid = "98e50ef6-434e-11e9-1051-2b60c6c9e899"
90+
version = "1.0.42"
91+
92+
[[deps.LibCURL]]
93+
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
94+
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"
95+
version = "0.6.3"
96+
97+
[[deps.LibCURL_jll]]
98+
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
99+
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"
100+
version = "7.84.0+0"
101+
102+
[[deps.LibGit2]]
103+
deps = ["Base64", "NetworkOptions", "Printf", "SHA"]
104+
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"
105+
106+
[[deps.LibSSH2_jll]]
107+
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
108+
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"
109+
version = "1.10.2+0"
110+
111+
[[deps.Libdl]]
112+
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
113+
114+
[[deps.Logging]]
115+
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
116+
117+
[[deps.Markdown]]
118+
deps = ["Base64"]
119+
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
120+
121+
[[deps.MbedTLS_jll]]
122+
deps = ["Artifacts", "Libdl"]
123+
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
124+
version = "2.28.2+0"
125+
126+
[[deps.Mmap]]
127+
uuid = "a63ad114-7e13-5084-954f-fe012c677804"
128+
129+
[[deps.MozillaCACerts_jll]]
130+
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"
131+
version = "2022.10.11"
132+
133+
[[deps.NetworkOptions]]
134+
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
135+
version = "1.2.0"
136+
137+
[[deps.OrderedCollections]]
138+
git-tree-sha1 = "2e73fe17cac3c62ad1aebe70d44c963c3cfdc3e3"
139+
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
140+
version = "1.6.2"
141+
142+
[[deps.Parsers]]
143+
deps = ["Dates", "PrecompileTools", "UUIDs"]
144+
git-tree-sha1 = "716e24b21538abc91f6205fd1d8363f39b442851"
145+
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
146+
version = "2.7.2"
147+
148+
[[deps.Pkg]]
149+
deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"]
150+
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
151+
version = "1.9.2"
152+
153+
[[deps.PrecompileTools]]
154+
deps = ["Preferences"]
155+
git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f"
156+
uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
157+
version = "1.2.0"
158+
159+
[[deps.Preferences]]
160+
deps = ["TOML"]
161+
git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e"
162+
uuid = "21216c6a-2e73-6563-6e65-726566657250"
163+
version = "1.4.1"
164+
165+
[[deps.Printf]]
166+
deps = ["Unicode"]
167+
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
168+
169+
[[deps.REPL]]
170+
deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"]
171+
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
172+
173+
[[deps.Random]]
174+
deps = ["SHA", "Serialization"]
175+
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
176+
177+
[[deps.SHA]]
178+
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
179+
version = "0.7.0"
180+
181+
[[deps.Serialization]]
182+
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
183+
184+
[[deps.Sockets]]
185+
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
186+
187+
[[deps.TOML]]
188+
deps = ["Dates"]
189+
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
190+
version = "1.0.3"
191+
192+
[[deps.Tar]]
193+
deps = ["ArgTools", "SHA"]
194+
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"
195+
version = "1.10.0"
196+
197+
[[deps.TextWrap]]
198+
git-tree-sha1 = "9250ef9b01b66667380cf3275b3f7488d0e25faf"
199+
uuid = "b718987f-49a8-5099-9789-dcd902bef87d"
200+
version = "1.0.1"
201+
202+
[[deps.Tokenize]]
203+
git-tree-sha1 = "0454d9a9bad2400c7ccad19ca832a2ef5a8bc3a1"
204+
uuid = "0796e94c-ce3b-5d07-9a54-7f471281c624"
205+
version = "0.5.26"
206+
207+
[[deps.URIs]]
208+
git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b"
209+
uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"
210+
version = "1.5.1"
211+
212+
[[deps.UUIDs]]
213+
deps = ["Random", "SHA"]
214+
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
215+
216+
[[deps.Unicode]]
217+
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
218+
219+
[[deps.Zlib_jll]]
220+
deps = ["Libdl"]
221+
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
222+
version = "1.2.13+0"
223+
224+
[[deps.nghttp2_jll]]
225+
deps = ["Artifacts", "Libdl"]
226+
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"
227+
version = "1.48.0+0"
228+
229+
[[deps.p7zip_jll]]
230+
deps = ["Artifacts", "Libdl"]
231+
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
232+
version = "17.4.0+0"

bin/julia/Project.toml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name = "julia"
2+
uuid = "f7e72769-0d4f-4e1c-bb39-275b23f83607"
3+
authors = ["Trevor Stone <[email protected]>"]
4+
version = "0.1.0"
5+
6+
[deps]
7+
ArgParse = "c7e460c6-2fb9-53a9-8c5b-16f535851c63"
8+
JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899"

0 commit comments

Comments
 (0)