neovim language server config, for C & alternatives : Nim,Odin,Zig & Scala

This has coloring, completion & function parameters.

cat init.vim
Code:
" Nim,Odin,Zig,Scala 

syntax on            " Schakel syntax highlighting in
filetype plugin on   " Herken bestandstypes voor plugins
set termguicolors    " Zorg voor mooie kleuren in moderne terminals
autocmd BufNewFile,BufRead *.nim set filetype=nim

call plug#begin()
Plug 'alaviss/nim.nvim'
Plug 'neovim/nvim-lspconfig'
Plug 'scalameta/nvim-metals'
Plug 'tetralux/odin.vim'
Plug 'L3MON4D3/LuaSnip'
Plug 'hrsh7th/vim-vsnip'
Plug 'nvim-lua/plenary.nvim'
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/cmp-vsnip'
Plug 'hrsh7th/cmp-buffer'    
Plug 'hrsh7th/cmp-path'      
Plug 'saadparwaiz1/cmp_luasnip'
Plug 'ziglang/zig.vim'
Plug 'nvim-lualine/lualine.nvim'
Plug 'nvim-tree/nvim-web-devicons'
Plug 'ray-x/lsp_signature.nvim'

call plug#end()

" LSP Keybindings
nnoremap <silent> gd <cmd>lua vim.lsp.buf.definition()<CR>
nnoremap <silent> K  <cmd>lua vim.lsp.buf.hover()<CR>
nnoremap <silent> <leader>rn <cmd>lua vim.lsp.buf.rename()<CR>
inoremap <C-k> <cmd>lua vim.lsp.buf.signature_help()<CR>


lua << EOF
-- 1. Metals (Scala) configuratie
local metals_config = require("metals").bare_config()
-- Voeg dit toe in het Metals blok
metals_config.capabilities = require("cmp_nvim_lsp").default_capabilities()
metals_config.init_options.statusBarProvider = "on"

vim.api.nvim_create_autocmd("FileType", {
  pattern = { "scala", "sbt", "java" },
  callback = function()
    require("metals").initialize_or_attach(metals_config)
  end,
})

-- 2. Autocomplete (nvim-cmp) configuratie
local cmp = require('cmp')
cmp.setup({
   window = {
    completion = cmp.config.window.bordered(),
    documentation = cmp.config.window.bordered(),
  },
  snippet = {
    expand = function(args)
      vim.fn["vsnip#anonymous"](args.body) 
    end,
  },
  mapping = cmp.mapping.preset.insert({
    ['<C-Space>'] = cmp.mapping.complete(),
    ['<CR>'] = cmp.mapping.confirm({ select = true }),
    ['<Tab>'] = cmp.mapping(function(fallback)
      if cmp.visible() then cmp.select_next_item() else fallback() end
    end, { 'i', 's' }),
  }),
  sources = cmp.config.sources({
    { name = 'nvim_lsp' },
    { name = 'vsnip' },
  }, {
    { name = 'buffer' },
    { name = 'path' },
  })
})

-- 3. Lualine Toolbar
require('lualine').setup({
  options = { theme = 'gruvbox', globalstatus = true }
})

-- 4. Multi-Language LSP Loop (C, Odin, Zig, D)
local capabilities = require('cmp_nvim_lsp').default_capabilities()
capabilities.textDocument.signatureHelp = {
  dynamicRegistration = false,
  signatureInformation = {
    documentationFormat = { 'markdown', 'plaintext' },
    parameterInformation = { labelOffsetSupport = true },
    activeParameterSupport = true,
  },
}

local get_root = function()
  local markers = {'.git', 'Makefile', 'dub.json', 'ols.json', 'zls.json', 'nim.cfg', 'build.sbt'}
  local root = vim.fs.find(markers, { upward = true })[1]
  return root and vim.fs.dirname(root) or vim.fn.getcwd()
end

local servers = {
  clangd = { cmd = {"clangd", "--background-index"}, filetypes = {"c", "cpp"} },
  ols = { cmd = {"ols"}, filetypes = {"odin"} },
  zls = { 
  cmd = {"zls"}, 
  filetypes = {"zig"},
  settings = {
    zls = {
      -- Zorg dat dit pad exact naar de zig binary wijst
      zig_exe_path = "/home/x/.local/bin/zig", 

      -- Vervang dit pad door de "std_dir" uit 'zig env'
      zig_lib_path = "/home/x/git/zig/lib", 
      enable_snippets = true,
    }
  }
},
  serve_d = { cmd = {"serve-d"}, filetypes = {"d", "di"} },
      nimlangserver = { 
    cmd = {"nimlangserver"}, 
    filetypes = {"nim"},
    capabilities = capabilities, -- Zorg dat snippets/signatures worden doorgegeven
    settings = {
      nim = {
        nimsuggestPath = vim.fn.expand("$HOME/git/Nim/bin/nimsuggest"),
        hints = {
          enables = true,
          typeHints = true,
          parameterHints = true,
        },
        autoCheck = true
      }
    }
  }
}


for server, config in pairs(servers) do
  vim.lsp.config(server, {
    capabilities = capabilities, -- Gebruik de variabele die je boven de tabel hebt gedefinieerd
    cmd = config.cmd,
    filetypes = config.filetypes,
    root_dir = get_root,
    settings = config.settings, -- VOEG DEZE REGEL TOE om de Nim hints te laden
  })
  vim.lsp.enable(server)

-- De FreeBSD Fix: Forceer activatie
  vim.api.nvim_create_autocmd("FileType", {
    pattern = config.filetypes,
    callback = function()
      -- Geef hier ook de settings mee voor de geforceerde start
      vim.lsp.start({ 
        name = server, 
        cmd = config.cmd, 
        root_dir = get_root(),
        settings = config.settings 
      })
    end,
  })
end

-- Auto-format voor specifieke talen
vim.api.nvim_create_autocmd("BufWritePre", {
  pattern = { "*.zig", "*.d", "*.nim" }, -- Voeg *.nim hier toe
  callback = function()
    vim.lsp.buf.format({ async = false })
  end,
})
EOF

lua << EOF
require('lsp_signature').setup({
  bind = true,
  handler_opts = { border = "rounded" },
  floating_window = true,
  hint_enable = true, -- Toont ook hints aan het einde van de regel
})
EOF

Note : For swift & F# one is forced to Linux
 
Update,
cat init.vim
Code:
" Nim,Odin,Zig,Scala,D,Ocaml

" 1. Alle Plugins in één blok
call plug#begin()
" Plug 'neovim/nvim-lspconfig'
" Talen & LSP
Plug 'alaviss/nim.nvim'
Plug 'scalameta/nvim-metals'
Plug 'tetralux/odin.vim'
Plug 'ziglang/zig.vim'
Plug 'ionide/Ionide-vim'
Plug 'Olical/conjure'
Plug 'preservim/tagbar'
Plug 'preservim/nerdtree'

" Completion (nvim-cmp) & Snippets
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/cmp-buffer'
Plug 'hrsh7th/cmp-path'
Plug 'hrsh7th/cmp-cmdline'
Plug 'hrsh7th/cmp-nvim-lua'
Plug 'hrsh7th/cmp-vsnip'
Plug 'hrsh7th/vim-vsnip'
Plug 'L3MON4D3/LuaSnip'
Plug 'saadparwaiz1/cmp_luasnip'

" UI & Look
Plug 'onsails/lspkind.nvim'
Plug 'stevearc/dressing.nvim'
Plug 'nvim-lualine/lualine.nvim'
Plug 'nvim-tree/nvim-web-devicons'
Plug 'ellisonleao/gruvbox.nvim'
Plug 'norcalli/nvim-colorizer.lua'

" Tools
Plug 'nvim-lua/plenary.nvim'
Plug 'ray-x/lsp_signature.nvim'
Plug 'folke/which-key.nvim'
Plug 'akinsho/toggleterm.nvim'
Plug 'kylechui/nvim-surround'
Plug 'guns/vim-sexp'
Plug 'tpope/vim-sexp-mappings-for-regular-people'
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}
call plug#end()

" 2. Vim Settings
set background=dark
colorscheme gruvbox
set autoindent
set clipboard+=unnamedplus
set noexpandtab
set tabstop=4
set shiftwidth=4
set number
set termguicolors
set signcolumn=yes
set shortmess+=A " Voorkom 'ATTENTION' meldingen bij swap files
set shortmess+=I " Geen intro scherm
set shortmess+=c " Geen 'match 1 of 2' meldingen in de completion

" 3. Mappings
let g:conjure#client#scheme#stdio#command = "csi -quiet -:c"
let g:conjure#client#racket#stdio#command = "racket"
nnoremap <silent> gd <cmd>lua vim.lsp.buf.definition()<CR>
nnoremap <silent> K  <cmd>lua vim.lsp.buf.hover()<CR>
nnoremap <silent> <leader>rn <cmd>lua vim.lsp.buf.rename()<CR>
inoremap <C-k> <cmd>lua vim.lsp.buf.signature_help()<CR>
nmap <F8> :TagbarToggle<CR>
nnoremap <C-n> :NERDTreeToggle<CR>
nnoremap <silent><c-t> <Cmd>exe v:count1 . "ToggleTerm"<CR>

" 4. Lua Configuratie (Alles in één blok voor overzicht)
lua << EOF
local cmp = require('cmp')
local lspkind = require('lspkind')

-- Gecombineerde CMP Setup
cmp.setup({
  window = {
    completion =
cat init.vim 
cmp.config.window.bordered(),
    documentation = cmp.config.window.bordered(),
  },
  snippet = {
    expand = function(args) vim.fn["vsnip#anonymous"](args.body) end,
  },
  formatting = {
    format = lspkind.cmp_format({ mode = 'symbol_text', maxwidth = 50 })
  },
  mapping = cmp.mapping.preset.insert({
    ['<C-Space>'] = cmp.mapping.complete(),
    ['<CR>'] = cmp.mapping.confirm({ select = true }),
    ['<Tab>'] = cmp.mapping(function(fallback)
      if cmp.visible() then cmp.select_next_item() else fallback() end
    end, { 'i', 's' }),
  }),
  sources = cmp.config.sources({
    { name = 'nvim_lsp' },
    { name = 'nvim_lua' },
    { name = 'vsnip' },
    { name = 'luasnip' },
  }, {
    { name = 'buffer' },
    { name = 'path' },
  })
})

-- Cmdline setups
cmp.setup.cmdline('/', { mapping = cmp.mapping.preset.cmdline(), sources = {{ name = 'buffer' }} })
cmp.setup.cmdline(':', {
  mapping = cmp.mapping.preset.cmdline(),
  sources = cmp.config.sources({{ name = 'path' }}, {{ name = 'cmdline' }})
})

-- UI Modules
require('lualine').setup({ options = { theme = 'gruvbox', globalstatus = true }})
require('dressing').setup()
require('lsp_signature').setup({ floating_window = true, hint_enable = true })
require('colorizer').setup()
require('toggleterm').setup()
require('which-key').setup()
require('nvim-surround').setup()
require('gruvbox').setup({ transparent_mode = true })

-- Metals Setup
local metals_config = require("metals").bare_config()
metals_config.capabilities = require("cmp_nvim_lsp").default_capabilities()
vim.api.nvim_create_autocmd("FileType", {
  pattern = { "scala", "sbt", "java" },
  callback = function() require("metals").initialize_or_attach(metals_config) end,
})

-- 4. Moderne LSP Setup (Neovim 0.10+ stijl)
-- 4. Herstelde LSP Setup (Gegarandeerde start voor Zig & Nim)
local capabilities = require('cmp_nvim_lsp').default_capabilities()

local servers = {
  ols = {
    cmd = { "/home/x/git/ols/ols" }, -- Of het volledige pad naar je ols binary
    settings = {
      -- OLS verwacht deze specifieke velden om de library te indexeren
      odin_command = "/home/x/git/Odin/odin", -- Zorg dat 'odin' in je PATH staat
      checker_args = "-vet -unused-imports", 
      enable_snippets = true,
      -- Als OLS nog steeds niets vindt, voeg dan de absolute paden toe:
      collections = {
         core = "/home/x/git/Odin/core",
         vendor = "/home/x/git/Odin/vendor",
         }
    }
  },

  zls = {
    cmd = { "/home/x/git/zls/zig-out/bin/zls" },
    filetypes = { "zig" },
    settings = {
      zls = {
        zig_exe_path = "/home/x/.local/bin/zig",
        zig_lib_path = "/home/x/.local/lib/zig", -- Map die 'std' bevat
        enable_snippets = true,
      }
    }
  },
  nimlangserver = {
    cmd = { "/home/x/.nimble/bin/nimlangserver" },
    filetypes = { "nim" },
    settings = { 
      nim = { 
        nimsuggestPath = "/home/x/git/Nim/bin/nimsuggest",
        autoCheck = true,
      } 
    }
  }
}

-- Gebruik een Autocmd om de servers ECHT te starten
vim.api.nvim_create_autocmd("FileType", {
  pattern = { "zig", "nim", "odin" },
  callback = function(args)
    -- 1. Bepaal de juiste servernaam op basis van de filetype
    local server_map = {
      zig = "zls",
      nim = "nimlangserver",
      odin = "ols"
    }
    
    local server_name = server_map[args.match]
    local config = servers[server_name]
    
    if config then
      vim.lsp.start({
        name = server_name,
        cmd = config.cmd,
        capabilities = capabilities,
        settings = config.settings,
        -- 2. Zoek markers (ols.json toegevoegd), anders gebruik huidige map
        root_dir = (function()
                      -- Voeg 'ols.json' toe voor Odin projecten
                      local markers = {'ols.json', 'root', '.git', 'build.zig', 'nim.cfg', 'Makefile'}
                      local found = vim.fs.find(markers, { upward = true })[1]
                      if found then
                         return vim.fs.dirname(found)
                      end
                      return vim.fn.getcwd()
                    end)()
      })
    end
  end,
})
EOF


lua << EOF
-- 1. Setup de installatie-directory
require'nvim-treesitter'.setup {
  install_dir = vim.fn.stdpath('data') .. '/site'
}

-- 2. Installeer de gewenste talen (gebeurt asynchroon)
require'nvim-treesitter'.install {}

-- 3. Activeer Highlighting (Nieuwe methode via FileType)
vim.api.nvim_create_autocmd('FileType', {
  pattern = {},
  callback = function() 
    vim.treesitter.start() 
  end,
})

-- 4. Optioneel: Activeer Indentatie (Nieuwe methode)
vim.api.nvim_create_autocmd('FileType', {
  pattern = {},
  callback = function()
    vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
  end,
})
EOF

" ocamllsp = {},
 
Back
Top