Skip to content
Al3cLee edited this page Oct 14, 2025 · 27 revisions

LanguageClient-neovim

Vim and Neovim are able to use the Julia LanguageServer via LanguageClient-neovim with completion from nvim-completion-manager.

The following is a basic minimal config (vimrc for Vim; init.vim for Neovim) using vim-plug:

call g:plug#begin()
  Plug 'JuliaEditorSupport/julia-vim'
  Plug 'autozimu/LanguageClient-neovim', {'branch': 'next', 'do': 'bash install.sh'}
  Plug 'roxma/nvim-completion-manager'  " optional
call g:plug#end()

" julia
let g:default_julia_version = '1.0'

" language server
let g:LanguageClient_autoStart = 1
let g:LanguageClient_serverCommands = {
\   'julia': ['julia', '--startup-file=no', '--history-file=no', '-e', '
\       using LanguageServer;
\       using Pkg;
\       import StaticLint;
\       import SymbolServer;
\       env_path = dirname(Pkg.Types.Context().env.project_file);
\       
\       server = LanguageServer.LanguageServerInstance(stdin, stdout, env_path, "");
\       server.runlinter = true;
\       run(server);
\   ']
\ }

nnoremap <silent> K :call LanguageClient_textDocument_hover()<CR>
nnoremap <silent> gd :call LanguageClient_textDocument_definition()<CR>
nnoremap <silent> <F2> :call LanguageClient_textDocument_rename()<CR>

Note:

  1. The LanguageServer, SymbolServer and StaticLint packages must be installed in Julia (1.x), i.e.

    julia> using Pkg
    julia> Pkg.add("LanguageServer")
    julia> Pkg.add("SymbolServer")
    julia> Pkg.add("StaticLint")
  2. If Julia (0.6 or greater) is not present in the PATH environment, either add the julia binary folder to PATH or directly reference the julia binary in g:LanguageClient_serverCommands, e.g. for macOS:

    let g:LanguageClient_serverCommands = {
    \   'julia': ['/Applications/Julia-0.6.app/Contents/Resources/julia/bin/julia', ...
  3. See vim-plug for more details on installing/managing packages in Vim/Neovim

SpaceVim

SpaceVim have a layer to use LanguageServer.jl, the setup is automatic once you installed the Julia layer.

Neovim Built In LSP

an overview of state of built-in LSP and friends plug-ins: https://crispgm.com/page/neovim-is-overpowering.html

Using Deoplete

Check out this thread on discourse: https://discourse.julialang.org/t/neovim-languageserver-jl/37286/7 OR this blog post. This provides examples of using neovim's built in language server protocol using deoplete with deoplete-lsp.

Using nvim-cmp and nvim-lspconfig

The neovim/nvim-lspconfig tool is a built-in LSP tool for NeoVim, and it supports Julia. Simply follow its documentation and add one line to init.lua works. Note that installing the Julia LSP from Mason does not work out of the box!

A minimal example here.

Another minimal example here:

-- using packer
-- ...

use({ 
  "hrsh7th/nvim-cmp",
  requires = { { "hrsh7th/cmp-nvim-lsp" } },
  config = function()
    cmp.setup({

      completion = {
        completeopt = "menu,menuone,noselect",
      },

      -- You must set mapping.
      mapping = {
        ["<C-p>"] = cmp.mapping.select_prev_item(),
        ["<C-n>"] = cmp.mapping.select_next_item(),
        ["<C-d>"] = cmp.mapping.scroll_docs(-4),
        ["<C-f>"] = cmp.mapping.scroll_docs(4),
        ["<C-Space>"] = cmp.mapping.complete(),
        ["<C-e>"] = cmp.mapping.close(),
      },

      -- You should specify your *installed* sources.
      sources = {
        { name = "nvim_lsp" },
      },
    })

  end,
})

use({
  "neovim/nvim-lspconfig",
  config = function()
    local function create_capabilities()
      local capabilities = vim.lsp.protocol.make_client_capabilities()
      capabilities.textDocument.completion.completionItem.snippetSupport = true
      capabilities.textDocument.completion.completionItem.preselectSupport = true
      capabilities.textDocument.completion.completionItem.tagSupport = { valueSet = { 1 } }
      capabilities.textDocument.completion.completionItem.deprecatedSupport = true
      capabilities.textDocument.completion.completionItem.insertReplaceSupport = true
      capabilities.textDocument.completion.completionItem.labelDetailsSupport = true
      capabilities.textDocument.completion.completionItem.commitCharactersSupport = true
      capabilities.textDocument.completion.completionItem.resolveSupport = {
        properties = { "documentation", "detail", "additionalTextEdits" },
      }
      capabilities.textDocument.completion.completionItem.documentationFormat = { "markdown" }
      capabilities.textDocument.codeAction = {
        dynamicRegistration = true,
        codeActionLiteralSupport = {
          codeActionKind = {
            valueSet = (function()
              local res = vim.tbl_values(vim.lsp.protocol.CodeActionKind)
              table.sort(res)
              return res
            end)(),
          },
        },
      }
      return capabilities
    end
    
    -- disable virtual text (recommended for julia)
    vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, {
      virtual_text = false,
      underline = false,
      signs = true,
      update_in_insert = false,
    })
    
    local on_attach = function(client, bufnr)
      vim.api.nvim_buf_set_option(bufnr, "omnifunc", "v:lua.vim.lsp.omnifunc")
    end
    
    local lspconfig = require("lspconfig")
    
    local function lsp_setup(name, config)
      lspconfig[name].setup(config)
    end
    
    lsp_setup("julials", {
      on_attach = on_attach,
      capabilities = create_capabilities(),
    })

  end,
})

-- ...

For a full example, see the following files:

Using completion-nvim (deprecated)

You can also see examples of using neovim, nvim-lsp, completion-nvim and diagnostic-nvim here:

https://github.com/kdheepak/dotfiles/blob/47a38e20ef4bef7a189927646eee3c91f911ffd7/vimrc

Here's the relevant pieces:

  1. Install the plugins
Plug 'nvim-lua/completion-nvim'                                    | " better neovim built in lsp completion
  1. Initialize
autocmd BufEnter * lua require'completion'.on_attach()

lua << EOF
    local nvim_lsp = require'nvim_lsp'
    local on_attach_vim = function()
        require'diagnostic'.on_attach()
    end
    nvim_lsp.julials.setup({on_attach=on_attach_vim})
EOF
  1. Configure
let g:diagnostic_auto_popup_while_jump = 0
let g:diagnostic_enable_virtual_text = 0
let g:diagnostic_enable_underline = 0
let g:completion_timer_cycle = 200 "default value is 80
Clone this wiki locally