Your comment made me think about why it fails for me as I’m setting the server path in the local config. I found the problem which is happening because I insist on printing out bayes formula when I start julia. The PR for fixing julials
config in nvim-lspconfig is here: Fixed a small gotcha where the server_path is set to nonsense if you print stuff in your startup.jl by DoktorMike · Pull Request #1017 · neovim/nvim-lspconfig · GitHub
What about GitHub - hrsh7th/nvim-compe: Auto completion Lua plugin for nvim ?
Does this do autocomplete for Julia?
I’m trying to figure out if I should go with lspconfig or coc; do you have any comments on the pros and cons?
My current setup is using nvim-compe + built in lsp for neovim. I like this set up for other languages. For Julia, I have disabled lsp because it hangs for me on some projects and I haven’t had time to debug it. On small files and small projects though, things seem to work well with this set up. It was quite a bit of configuration (nvim-compe + lspsaga + lspconfig + other plugins) though.
I’m guessing coc is more straightforward, but I haven’t used it extensively and not tried it in a long time. So I’m not sure what the advantages or the differences are exactly. If others have thoughts, feel free to chime in.
Hi all,
Looking for a little help. :LspInstall julials
results in “Could not find language server for julials”
I have included the following snippet
require'lspconfig'.julials.setup{}
in my init.lua
Somehow lspinstall isn’t aware of the lspconfig julials server config. Anyone come across this before?
From the listed servers in nvim-lspinstall/lua/lspinstall/servers at main · kabouzeid/nvim-lspinstall · GitHub nvim-lspinstall
doesn’t look to have one for julials
.
(The recommended install method in https://github.com/neovim/nvim-lspconfig/blob/master/lua/lspconfig/julials.lua#L44 works well though.)
Okay, great! I had already stumbled onto this file, but wasn’t sure how to implement.
The line you referenced will install LanguageServer.jl & SymbolServer.jl but that alone will not allow me to do something like :LspInstall julials
.
I even tried taking the entire config from nvim-lspconfig/julials.lua
and integrating with my config but there is still no language server attaching to the buffer and no change when trying to LspInstall
.
How does Neovim know that there is a julials
option that should then kick off the command to start the LanguageServer.jl?
Could be worth doing a :checkhealth
if you’ve not already to see whether there’s anything obvious that’s causing it. Do any other language servers work in your setup?
I struggled with the default settings for a while before just customising it enough to work for me with (the relevant parts):
local util = require "lspconfig/util"
local cmd = {
"julia",
"--startup-file=no",
"--history-file=no",
"/home/mike/.config/nvim/lua/mike/lsp.jl"
}
require"lspconfig".julials.setup {
cmd = cmd,
on_new_config = function(new_config, _)
local server_path = vim.fn.system "julia --startup-file=no -q -e 'print(dirname(dirname(Base.find_package(\"LanguageServer\"))))'"
local new_cmd = vim.deepcopy(cmd)
table.insert(new_cmd, 2, "--project=" .. server_path)
new_config.cmd = new_cmd
end,
filetypes = {"julia"},
root_dir = function(fname)
return util.find_git_ancestor(fname) or vim.fn.getcwd()
end
}
and lsp.jl
(since I didn’t like passing it all as an argument):
using LanguageServer
using LanguageServer.SymbolServer
let env = Base.load_path(),
dir = pwd(),
depot_path = get(ENV, "JULIA_DEPOT_PATH", ""),
project_path = dirname(something(Base.current_project(pwd()), Base.load_path_expand(LOAD_PATH[2])))
@info env dir project_path depot_path
server = LanguageServer.LanguageServerInstance(stdin, stdout, project_path, depot_path)
server.runlinter = true
run(server)
end
(Hopefully that might help you out a bit.)
Helped me out A TON!
Thank you! I had many of the parts, but couldn’t find the glue!
One more question - Not really sure if this is a LanguageServer.jl or a Neovim-LspConfig issue, but could any of this be shared upstream in order to get things working “out of the box” for others?
PS - You were right to ask about :checkhealth
because that was my first thought, but didn’t find anything seriously broken.
Glad it’s working now.
Yes, things should be made to just work with the defaults. I hadn’t spent the time to workout whether it was just my config that was causing issues so haven’t reported anything upstream yet.
Thanks for sharing that configuration @mike. I used that to try out LanguageServer for the first time just now. I made some modifications to your setup that I believe are strict improvements (borderline bugfixes?).
init.vim
:
lua << EOF
local cmd = {
"julia",
"--startup-file=no",
"--history-file=no",
"/home/fredrik/.config/nvim/lsp-julia/run.jl"
}
require'lspconfig'.julials.setup{
cmd = cmd,
-- Why do I need this? Shouldn't it be enough to override cmd on the line above?
on_new_config = function(new_config, _)
new_config.cmd = cmd
end,
filetypes = {"julia"},
}
EOF
And in /home/fredrik/.config/nvim/lsp-julia/
I have
$ tree ~/.config/nvim/lsp-julia/
/home/fredrik/.config/nvim/lsp-julia/
├── Manifest.toml
├── Project.toml
└── run.jl
where ~/.config/nvim/lsp-julia/Project.toml
contains the LS deps
[deps]
LanguageServer = "2b0e0bc5-e4fd-59b4-8912-456d1b03d8d7"
SymbolServer = "cf896787-08d5-524d-9de7-132aaa0cb996"
and ~/.config/nvim/lsp-julia/run.jl
is
# Load LanguageServer from the project next to this file
## Save old load path
old_load_path = copy(LOAD_PATH)
push!(empty!(LOAD_PATH), @__DIR__)
## Load packages
using LanguageServer, SymbolServer
## Restore old load path
append!(empty!(LOAD_PATH), old_load_path)
# Figure out the active project
## This works if you are *not* using a Pkg.activate based workflow
## e.g. if you set up LOAD_PATH manually or set JULIA_PROJECT=@. in
## .bashrc or equivalent
project_path = Base.active_project()
## This works if you are using a Pkg.activated based workflow
# project_path = something(Base.current_project(pwd()), Base.active_project())
# Depot path for the server to index
depot_path = get(ENV, "JULIA_DEPOT_PATH", "")
# Start the server
@info "Running julia language server" project_path depot_path
server = LanguageServer.LanguageServerInstance(stdin, stdout, project_path, depot_path)
server.runlinter = true
run(server)
The major improvements compared to your version is that (i) LanguageServer
is running in a proper environment defined by the Project.toml
and Manifest.toml
in ~/.config/nvim/lsp-julia/Project.toml
and (ii) it is independent of the environment (e.g. JULIA_LOAD_PATH
).
Nice, thanks @fredrikekre. That does look like it should improve things.
Most things seems to work for me, but I get
import JSON ■ Missing reference: JSON
for all package importsl. I verified from the logs that the server is running in the correct project where JSON
is installed. Am I missing something?
Yeah, it’s not getting the right imports for me either with those changes. Not 100% sure what needs adjusted though.
Are you saying it works with your configuration from Neovim + LanguageServer.jl - #47 by mike ?
Yup, my current config picks them all up fine.
Okay, strange. I get the same errors with your setup.
Here’s the diff in my dotfiles that’s working for me:
I think the project_path
in the set up by @mike is not matching the one in the built in lsp. The diff I’ve shared above uses the same set up (from @fredrikekre’s repo) and changes the project_path
to match the one in the built in LSP.
There’s also some changes I made to make the diff portable (i.e. using vim.fn.expand
to expand the home directory) and an example of how to get detailed LSP log messages (vim.lsp.set_log_level('trace')
).
I’m sharing here in case others are interested in trying it out. Once we figure out exactly what is going on we can update the nvim-lspconfig to do the right thing.
Here’s a link to the repo I’m using for this test:
It’s very simple with just a couple of dependencies:
6 │ [deps]
7 │ JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
8 │ JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
───────┴──────────────────────────────────────────────────────────────────────────
Thanks @kdheepak, that config works nicely.
I found the problems:
- I was using Julia 1.6.2 which SymbolServer didn’t like (julia-vscode/SymbolServer.jl#224).
- I was passing the path to the
Project.toml
file, which SymbolServer didn’t like since it unconditionally appendedProject.toml
to the path and thus looked for things in.../Project.toml/Project.toml
(julia-vscode/SymbolServer.jl#227).
Here is my new configuration: fredrikekre/.dotfiles. Relevant extract:
init.vim
:
lua << EOF
local cmd = {
"julia",
"--startup-file=no",
"--history-file=no",
vim.fn.expand("~/.config/nvim/lsp-julia/run.jl")
}
require'lspconfig'.julials.setup{
cmd = cmd,
-- Why do I need this? Shouldn't it be enough to override cmd on the line above?
on_new_config = function(new_config, _)
new_config.cmd = cmd
end,
filetypes = {"julia"},
}
-- vim.lsp.set_log_level("debug")
EOF
~/.config/nvim/lsp-julia/run.jl
:
# Load LanguageServer from the project next to this file
## Save old load path
old_load_path = copy(LOAD_PATH)
push!(empty!(LOAD_PATH), @__DIR__)
## Load packages
using LanguageServer, SymbolServer
## Restore old load path
append!(empty!(LOAD_PATH), old_load_path)
# Figure out the active project
## This configuration is a good default
project_path = let
dirname(something(
## 1. Finds an explicitly set project (JULIA_PROJECT)
Base.load_path_expand((
p = get(ENV, "JULIA_PROJECT", nothing);
p === nothing ? nothing : isempty(p) ? nothing : p
)),
## 2. Look for a Project.toml file in the current working directory,
## or parent directories, with $HOME as an upper boundary
Base.current_project(),
## 3. First entry in the load path
get(Base.load_path(), 1, nothing),
## 4. Fallback to default global environment,
## this is more or less unreachable
Base.load_path_expand("@v#.#"),
))
end
# Depot path for the server to index (empty uses default).
depot_path = get(ENV, "JULIA_DEPOT_PATH", "")
# Start the server
@info "Running julia language server" VERSION project_path depot_path
server = LanguageServer.LanguageServerInstance(stdin, stdout, project_path, depot_path)
server.runlinter = true
run(server)
This is working perfectly for me!