It requires some effort to make Neovim work pleasantly with Julia, especially the formatting part. But it's possible with null-ls and precompiling.
Julia is a language designed for scientific computing. Since it's not a general-purpose language, it's lesser-known in the community of programmers, and thus the support is not as rich as Python. The good news is that the community of Julia is mature enough, the editor support in VS Code is great, and it requires just a little effort to have a pleasant editing experience in Neovim.
To install Julia LSP, first, open the mason window and find julia-lsp, and install it. Then you need to configure the LSP as described in NvChad's documentation
-- ~/.config/nvim/lua/custom/plugins/lspconfig.lua
local on_attach = require("plugins.configs.lspconfig").on_attach
local capabilities = require("plugins.configs.lspconfig").capabilities
local lspconfig = require "lspconfig"
local servers = { "html", "cssls", "clangd", "julials" }
-- a bunch of other LSPs... ^^^^^^^^^
for _, lsp in ipairs(servers) do
lspconfig[lsp].setup {
on_attach = on_attach,
capabilities = capabilities,
}
end
Another cool feature of Julia is that you can use Unicode symbols for variable names and some operations. Typing \alpha<Tab> in Julia REPL will give you the symbol α. If used properly, it can make the math-heavy code more readable and elegant. BeautifulAlgorithms.jl has a bunch of examples. And enabling this feature in Neovim is as easy as installing the julia-vim plugin.
NvChad used to come with null-ls.nvim installed, but removed it afterward. It's easy to install null-ls.nvim.
[!NOTE]
null-ls is not maintained. Please use its fork none-ls instead.
Although JuliaFormatter.jl provides formatting for Julia, null-ls doesn't have built-in support for that. Therefore, I must write the integration myself.
In Julia REPL: (] means entering Pkg mode)
]add JuliaFormatter
cd ~/.config/nvim/lua/custom
mkdir plugins/null-ls
mv plugins/null-ls.lua plugins/null-ls/init.lua
vim plugins/null-ls/julia.lua
local h = require("null-ls.helpers")
local methods = require("null-ls.methods")
return {
method = methods.internal.FORMATTING,
name = "JuliaFormatter",
meta = {
url = "https://github.com/domluna/JuliaFormatter.jl",
description = "An opinionated code formatter for Julia.",
},
filetypes = { "julia" },
generator = h.formatter_factory {
command = "juliafmt",
args = {
"-e",
"using JuliaFormatter; println(format_text(String(read(stdin))))",
},
to_stdin = true,
timeout = 30000,
}
}
And add julia-formatter to null-ls sources:
local ok, julia = pcall(require, "custom.plugins.null-ls.julia")
if not ok then
return
end
-- ...
local sources = {
-- ...
julia,
}
null_ls.setup {
sources = sources,
}
Then you just open a Julia file with Neovim, wait for the LSP ready, and hit <leader> f m to format the code.
However, this is not the final solution. JuliaFormatter can be very slow to format files because the JIT compilation is quite slow. The formatting usually takes 10 to 20 seconds. One solution is provided at JuliaFormatter.jl#633 (issue-comment). We just need to precompile the library. Also, JuliaFormatter doesn't pick up project configuration if passed via stdin, so I have to change the juliafmt file whenever I want to change some options, and the changes are applied "globally". That's quite inconvenient, so we'd better use a temp file.
My solution is to put the following content to ~/.local/bin/juliafmt:
#!/bin/bash
OUTPUT_SYSIMAGE=~/.local/lib/juliafmt.so
FORMAT_CMD="using JuliaFormatter; format_file(\"$1\")"
if [ "$1" == "--compile" ]; then
echo "using JuliaFormatter; format_file(\"/tmp/juliafmt.jl\")" > /tmp/juliafmt.jl
julia -e 'using Pkg
Pkg.activate(temp=true)
Pkg.add(["JuliaFormatter", "PackageCompiler"])
using PackageCompiler
create_sysimage(
["JuliaFormatter"],
sysimage_path="'$OUTPUT_SYSIMAGE'",
precompile_execution_file="/tmp/juliafmt.jl"
)'
else
if [ -f "$OUTPUT_SYSIMAGE" ]; then
julia -J $OUTPUT_SYSIMAGE -e "$FORMAT_CMD"
else
julia -e "$FORMAT_CMD"
fi
fi
And run
chmod u+x ~/.local/bin/juliafmt
# If you don't run compile, the script will fall back to old JIT-every-time behavior
juliafmt --compile
If everything works, now you have a juliafmt executable to replace julia -e 'blah blah'. Now we can just change the plugins/null-ls/julia.lua to
local h = require "null-ls.helpers"
local methods = require "null-ls.methods"
return {
method = methods.internal.FORMATTING,
name = "JuliaFormatter",
meta = {
url = "https://github.com/domluna/JuliaFormatter.jl",
description = "An opinionated code formatter for Julia.",
},
filetypes = { "julia" },
generator = h.formatter_factory {
command = "juliafmt",
to_temp_file = true,
from_temp_file = true,
args = {
"$FILENAME",
},
},
}
View Post on Blog
Julia is a language designed for scientific computing. Since it's not a general-purpose language, it's lesser-known in the community of programmers, and thus the support is not as rich as Python. The good news is that the community of Julia is mature enough, the editor support in VS Code is great, and it requires just a little effort to have a pleasant editing experience in Neovim.
Basic setup
I'm using Neovim with NvChad. NvChad comes with simple plugin management based on packer.nvim, LSP installation and configuring stuff with mason.nvim and nvim-lspconfig, Syntax highlighting with nvim-treesitter.
To enable syntax highlighting for Julia, just run
To install Julia LSP, first, open the mason window and find
julia-lsp
, and install it. Then you need to configure the LSP as described in NvChad's documentationAnother cool feature of Julia is that you can use Unicode symbols for variable names and some operations. Typing
\alpha<Tab>
in Julia REPL will give you the symbolα
. If used properly, it can make the math-heavy code more readable and elegant. BeautifulAlgorithms.jl has a bunch of examples. And enabling this feature in Neovim is as easy as installing the julia-vim plugin.And don't forget to run
The remaining problem: formatting
NvChad used to come with null-ls.nvim installed, but removed it afterward. It's easy to install null-ls.nvim.
Although JuliaFormatter.jl provides formatting for Julia, null-ls doesn't have built-in support for that. Therefore, I must write the integration myself.
In Julia REPL: (
]
means enteringPkg
mode)And add
julia-formatter
to null-ls sources:Then you just open a Julia file with Neovim, wait for the LSP ready, and hit
<leader> f m
to format the code.However, this is not the final solution. JuliaFormatter can be very slow to format files because the JIT compilation is quite slow. The formatting usually takes 10 to 20 seconds. One solution is provided at JuliaFormatter.jl#633 (issue-comment). We just need to precompile the library. Also, JuliaFormatter doesn't pick up project configuration if passed via stdin, so I have to change the
juliafmt
file whenever I want to change some options, and the changes are applied "globally". That's quite inconvenient, so we'd better use a temp file.My solution is to put the following content to
~/.local/bin/juliafmt
:And run
If everything works, now you have a
juliafmt
executable to replacejulia -e 'blah blah'
. Now we can just change theplugins/null-ls/julia.lua
to