LVIM IDE

March 21, 2026 · View on GitHub

LVIM IDE

A modular Neovim configuration written in Lua, built around a first-party plugin ecosystem — lvim-tech/* — that provides LSP management, settings persistence, project/workspace handling, colorschemes, and more. Fully customizable without touching core files.

Current version — 9.0.0 (2026-03-21)


Table of Contents


Requirements

ToolPurpose
neovim >= 0.11.4Runtime
pynvimPython provider
neovim-remoteRemote control
nodeJS/TS language servers
ripgrepSearch backend
fzfFuzzy finder binary
gitVersion control
curlHTTP downloads
wgetHTTP downloads
tarArchive extraction
gzipCompression
Nerd FontsIcons
sedText processing

Install

git clone https://github.com/lvim-tech/lvim.git ~/.config/nvim

Plugin dependencies are managed by lazy.nvim and installed automatically on first launch. LSP servers, linters, formatters, and debuggers are installed on demand via Mason when you open a file of the corresponding type.


Architecture

~/.config/nvim/
├── lua/
│   ├── configs/
│   │   ├── base/           ← base editor settings, keymaps, options, UI
│   │   └── user/           ← user overrides for base configs
│   ├── core/
│   │   ├── init.lua        ← bootstrap: OS detection, globals, lazy load
│   │   ├── lazy.lua        ← lazy.nvim integration
│   │   ├── funcs/          ← shared utility functions
│   │   └── types.lua       ← LuaLS type annotations for the entire config
│   └── modules/
│       ├── base/
│       │   ├── init.lua    ← all plugin registrations
│       │   └── configs/    ← per-plugin configuration
│       │       ├── dependencies/
│       │       ├── editor/
│       │       │   └── control_center/   ← lvim-control-center groups
│       │       ├── languages/
│       │       │   └── lsp/
│       │       │       ├── servers/      ← per-language LSP configs (34 files)
│       │       │       ├── dap_utils.lua ← DAP process picker & local config loader
│       │       │       ├── diagnostics.lua
│       │       │       └── file_types.lua
│       │       └── ui/
│       │           └── heirline/         ← statusline, winbar, statuscolumn components
│       └── user/
│           ├── init.lua    ← user plugin additions/overrides
│           └── configs/    ← user plugin configs

The base/user separation means all customization lives in modules/user/ and configs/user/ — core files are never modified.


LSP Support

LSP is managed entirely by lvim-lsp (see below). Language server configs live in lua/modules/base/configs/languages/lsp/servers/ — one file per language.

Supported languages (34):

LanguageServerNotes
Angularangularls
Astroastro
C / C++clangd + cpptools DAPcpplint via EFM
CMakecmake
CSS / SCSS / Lessvscode-css-language-server
Dserve-d
Dart / Flutterdartlsflutter-tools integration
Emmetemmet-language-server
Gogopls + delve DAPgolangci-lint via EFM
Helmhelm_ls
HTMLvscode-html-language-serverprettierd via EFM
JSONvscode-json-language-server
JS / TStypescript-language-server + DAPprettierd via EFM
Kotlinkotlin-language-server
LaTeXtexlabvimtex integration
Lualua-language-server + osv DAPstylua via EFM
Markdownmarksmancbfmt via EFM
Nginxnginx-language-server
OCamlocamllsp
PerlPerlNavigator
PHPintelephense + php-debug-adapter DAP
Pythonpyright + debugpy DAPblack via EFM
Rr-languageserver
Rustrust-analyzer + codelldb DAP
Scalametals + DAPnvim-metals integration
Shellbash-language-servershfmt via EFM, vint via EFM
SQLsqls
Stylelintstylelint-lsp
Tailwindtailwindcss-language-server
TOMLtaplo
Vimvim-language-server
Vuevolar
XMLlemminx
YAMLyaml-language-serveryamllint + yamlfmt via EFM
Zigzls

Debug (DAP)

DAP is managed by nvim-dap + nvim-dap-view. Debug adapters are installed via Mason automatically alongside LSP servers.

Languages with DAP support (8):

LanguageAdapter
C / C++cpptools (OpenDebugAD7)
Godelve (dlv dap, local port 38697)
JS / TSvscode-js-debug
Luaone-small-step-for-vimkind (osv)
PHPphp-debug-adapter
Pythondebugpy
Rustcodelldb
ScalaMetals built-in DAP

Project-local DAP config: dap_utils.lua loads a project-local nvim-dap.lua file from the project root when present, allowing per-project adapter/configuration overrides without touching the global config.

DAP keymaps:

KeyAction
<A-1>Toggle breakpoint
<A-2>Start / Continue (Lua: osv)
<A-3>Step into
<A-4>Step over
<A-5>Step out
<A-6>Up (stack frame)
<A-7>Down (stack frame)
<A-8>Close session + UI
<A-9>Restart
<A-0>Toggle REPL

lvim-tech Plugin Ecosystem

All lvim-tech/* plugins share a common design: they use lvim-utils for UI components and lvim-colorscheme for color palette, so every floating window, notification, and picker inherits the active theme automatically.


lvim-lsp

lvim-tech/lvim-lsp — LSP lifecycle manager

Manages LSP servers, EFM tools, DAP adapters, and Mason installations without requiring third-party config bridges like mason-lspconfig.

Features:

  • State management — all LSP feature flags live in lvim-lsp.state and are the single source of truth
  • Global settings persistence — feature flags are written to stdpath("data")/lvim-lsp-settings.json and survive across sessions independently of any UI plugin
  • Per-project override.lvim-lsp/config.lua in any project root is loaded after global defaults, allowing project-specific server settings, disabled servers, or feature overrides
  • On-demand Mason installer — when opening a file type for the first time, a popup lists missing tools; Space toggles, Enter installs, q/Esc skips (suppressed for 5 min)
  • Declined tools tracking — skipped tools are stored in stdpath("data")/lvim-lsp-declined.json; review with :LvimLsp declined

Feature flags (all persistable globally and per-project):

FlagDefaultDescription
auto_formattrueFormat on save (BufWritePre)
inlay_hintstrueInline type/parameter hints
document_highlightfalseHighlight symbol under cursor on CursorHold
code_lenstrueDisplay code lens annotations
progress.enabledtrueLSP progress notifications

Virtual diagnostics modes: text-and-lines / text / lines / none

Commands:

CommandDescription
:LvimLsp infoFloating info panel: clients, capabilities, diagnostics, Mason versions, EFM tools
:LvimLsp restartRestart all LSP clients on the current buffer
:LvimLsp toggle_serversPicker to enable/disable servers for the current workspace
:LvimLsp toggle_servers_buffer <bufnr>Picker scoped to a specific buffer
:LvimLsp declinedReview and re-enable declined Mason tools
:LvimLsp reattachRe-read project config and reattach clients

Global settings UI (inside :LvimControlCenter → Global tab):

  • "Apply for session" — writes to lvim-lsp.state (memory only, lost on exit)
  • "Apply permanently" — writes to lvim-lsp-settings.json (survives restarts)

Load order priority:

  1. lvim-lsp defaults
  2. User config (languages/init.lua)
  3. globals.load() — wins over defaults
  4. Project .lvim-lsp/config.lua — wins over globals for that project
  5. apply_buffer_features() per LspAttach

lvim-control-center

lvim-tech/lvim-control-center — Runtime settings panel with SQLite persistence

:LvimControlCenter

A tabbed floating panel for changing frequently used settings at runtime — no restart required for most options. All settings are persisted to an SQLite database and applied automatically on startup.

General tab:

SettingTypeDescription
Relative line numbersboolvim.opt.relativenumber — skips neo-tree, Fyler
Cursor lineboolvim.opt.cursorline — skips neo-tree
Cursor columnboolvim.opt.cursorcolumn — skips neo-tree, markdown, Fyler, time-machine-list
Wrap linesboolvim.opt.wrap — skips markdown
Color columnstringColumn position(s), comma-separated (default: "80")
Timeout lengthintKey sequence timeout in ms (default: 500)
Keys helperboolEnable/disable which-key (requires restart)
Keys helper delayselectwhich-key popup delay in ms: 0–1000

LSP tab (reads from and writes to lvim-lsp.state + global persistence):

SettingTypeDescription
Auto formatboolFormat on save
Inlay hintboolInline hints
Virtual diagnosticselecttext-and-lines / text / lines / none
LSP progressboolShow/hide LSP progress notifications
Code lensboolEnable/disable code lens
Info LSPaction:LvimLsp info
Restart LSPaction:LvimLsp restart
Toggle LSP servers for workspaceaction:LvimLsp toggle_servers
Toggle LSP servers for bufferaction:LvimLsp toggle_servers_buffer

Jump to specific setting:

require("lvim-control-center.ui").open("lsp", "codelens") -- by name
require("lvim-control-center.ui").open("lsp", 2) -- by row index

lvim-colorscheme

`lvim-tech/lvim-colorscheme$ — \text{Multi}-\text{family}, \text{multi}-\text{variant} \text{colorscheme}

4 \text{theme} \text{families} \times 4 \text{variants} = 16 \text{themes}:

\text{Family}\text{Soft}\text{Dark}\text{Darker}\text{Light}
\text{Lvim}$lvim-soft`lvim-darklvim-darkerlvim-light
Kanagawalvim-kanagawa-softlvim-kanagawa-darklvim-kanagawa-darkerlvim-kanagawa-light
Gruvboxlvim-gruvbox-softlvim-gruvbox-darklvim-gruvbox-darkerlvim-gruvbox-light
Everforestlvim-everforest-softlvim-everforest-darklvim-everforest-darkerlvim-everforest-light

The active theme is persisted to .configs/lvim/.theme and applied on startup. Change it via :LvimControlCenter → Appearance tab or directly:

:colorscheme lvim-darker

lvim-utils

lvim-tech/lvim-utils — Shared utility library for the lvim-tech ecosystem

Independent modules, each usable standalone:

ModuleDescription
lvim-utils.colorsShared color palette, auto-synced from lvim-colorscheme; blend(), lighten(), darken()
lvim-utils.uiFloating window components used by all lvim-tech plugins
lvim-utils.cursorHides cursor in registered filetypes (uses blend=100 highlight)
lvim-utils.notifyNotification system with theming
lvim-utils.quitQuit dialog — replaces the old :Quit custom command
lvim-utils.gxUniversal "open under cursor" — URLs, files, Git repos, plugin specs
lvim-utils.highlightHighlight group registration with auto-reload on colorscheme change

The :Quit user command and the gx key binding are both registered through lvim-utils in modules/base/configs/dependencies/init.lua:

vim.api.nvim_create_user_command("Quit", function()
    require("lvim-utils.quit").open()
end, {})

require("lvim-utils.gx").map_default()

lvim-space

lvim-tech/lvim-space v1.3.0 — Project, workspace, tab, and file manager

A full project management system backed by SQLite.

Features:

  • Projects — multiple independent projects, each with their own workspaces
  • Workspaces — named contexts within a project (e.g. frontend, backend)
  • Tabs — multiple tab layouts per workspace, each remembering window/buffer layout and cursor positions
  • Files — per-tab file tracking with fuzzy search
  • Session management — automatic or manual save/restore
  • Reordering — move projects, workspaces, tabs up/down
  • Public APIrequire("lvim-space.pub") for statusline and plugin integration
  • NerdFont icons for all entity types

lvim-linguistics

lvim-tech/lvim-linguistics v1.2.00 — Spelling and keyboard language control

Manages spell checking and keyboard layout switching in insert mode — useful for writing documents in a foreign language without leaving Neovim.

Supported display servers and tools:

SessionTool
X11xkb-switch
Wayland — Hyprlandhyprctl
Wayland — niriniri
Wayland — swayswaymsg
Wayland — mangommsg
Wayland — GNOMEgdbus

The tool is auto-detected from XDG_SESSION_TYPE / XDG_CURRENT_DESKTOP / WAYLAND_DISPLAY at startup. Can be overridden manually via kbrd_cmd.

Per-project config: .lvim_linguistics.json in the project root overrides global spell/language settings for that project.


lvim-shell

lvim-tech/lvim-shell — Shell applications in Neovim buffers

Runs any shell application (lazygit, btop, etc.) in a floating window or split. Configurable borders, blend, dimensions, and backdrop.

Default mappings inside the shell buffer:

KeyAction
<C-x>Open in horizontal split
<C-v>Open in vertical split
<C-t>Open in new tab
<C-e>Open in current window
<C-Space>Close

lvim-move

lvim-tech/lvim-move — Move lines and selections in any direction

Features:

  • Move lines up/down in normal and linewise visual mode
  • Move character selections up/down/left/right in charwise visual mode
  • Move lines left/right (indent/dedent) in normal and linewise visual mode
  • Fold-aware — opens folds instead of moving when cursor is inside one
  • Auto-indent after vertical moves (configurable)
  • Custom highlight color while moving
  • Column position preserved across vertical moves

lvim-qf-loc

lvim-tech/lvim-qf-loc — Enhanced quickfix and location list

Features:

  • Navigation (prev/next) via floating popup
  • Switch between quickfix and location lists
  • Delete entries from quickfix/location lists
  • Save and load lists to/from JSON files
  • Diagnostics in quickfix
  • Floating tabbed UI powered by lvim-utils

User Customization

All user customization goes in lua/configs/user/ and lua/modules/user/. Core files are never modified.

Editor Config

-- lua/configs/user/init.lua

-- Disable a base config function
configs["base_vim"] = false

-- Rewrite a base config function
configs["base_vim"] = {
    -- your code
}

-- Add a new config function
configs["user_vim"] = {
    -- your code
}

Plugins

-- lua/modules/user/init.lua

-- Disable a base plugin
modules["author/plugin-name"] = false

-- Override a base plugin's settings
modules["author/plugin-name"] = {
    -- your lazy.nvim spec
}

-- Add a new plugin
modules["author/new-plugin"] = {
    config = function()
        require("new-plugin").setup({})
    end,
}

LSP — Language Server Config

Language server configs live in lua/modules/base/configs/languages/lsp/servers/. To override or add a server, place a file with the same name in lua/modules/user/configs/languages/lsp/servers/.

File types are registered in lua/modules/base/configs/languages/lsp/file_types.lua. Override by returning a table from lua/modules/user/configs/languages/lsp/file_types.lua.

LSP — Global Feature Flags

Change at runtime via :LvimControlCenter → LSP tab, or programmatically:

-- Apply for session only (memory)
require("lvim-lsp.state").config.features.auto_format = false

-- Apply permanently (survives restarts)
require("lvim-lsp.core.globals").save({ auto_format = false })

LSP — Per-Project Override

Create .lvim-lsp/config.lua in any project root:

-- .lvim-lsp/config.lua
return {
    auto_format = false,
    inlay_hints = true,
    code_lens = { enabled = false },
}

Run :LvimLsp reattach to apply immediately without restarting.


Changelog

v9.0.0 — Breaking Changes (2026-03-21)

New features:

  • lvim-lsp/core/globals.lua — new JSON-based persistence for LSP feature flags written to stdpath("data")/lvim-lsp-settings.json; survives sessions without SQLite. Persisted flags: auto_format, inlay_hints, document_highlight, code_lens, progress, virtual_text, virtual_lines, underline, severity_sort, update_in_insert
  • Load order: lvim-lsp defaults → user config → globals.load() → project .lvim-lsp/config.lua
  • LSP Progress toggle — "LSP Progress" bool added to both lvim-control-center LSP tab and lvim-lsp Global tab UI with "Apply for session" / "Apply permanently"

lvim-control-center LSP tab rewrite:

  • All LSP settings now read from and write to lvim-lsp.state + globals.save() directly — no duplication between CC and lvim-lsp
  • lspprogress changed from select (fidget/notify/none) to bool — fidget.nvim removed
  • virtualdiagnostic now correctly calls vim.diagnostic.config() at runtime
  • Fixed action button commands: LvimLspInfo:LvimLsp info, LvimLspRestart:LvimLsp restart, etc.
  • Fixed colorcolumn in General tab (was displaying Lua table address instead of value)

Bug fixes:

  • ocaml.lua — critical copy-paste bug: cmd was "r-languageserver" instead of "ocamllsp"; removed duplicate .git root marker
  • css.luadocumentSymbolProvider capability check was all-lowercase — nvim-navic never attached to CSS buffers
  • go.lua — replaced deprecated vim.loop.spawn with vim.uv.spawn
  • heirline/git.lua — replaced deprecated vim.loop with vim.uv
  • dap_utils.lua — removed dead code: two IIFE assignments immediately overwritten by :luafile
  • modules/user/init.lua — treewalker spec used setup instead of config (lazy.nvim field); plugin was never configured
  • core/init.lua — removed unreachable io.popen fallback in getOS() (Neovim always uses LuaJIT); removed implicit global Osname
  • Spelling: "unsuported" → "unsupported" in core/init.lua and core/types.lua

Refactoring:

  • lsp/dap.lua renamed to lsp/dap_utils.lua — resolved different-requires LuaLS diagnostic caused by name conflict with the nvim-dap plugin module
  • All DAP key handler closures use consistent local dap = require("dap") pattern
  • core/types.luaLvimGit and LvimGitHead type definitions updated to match actual runtime structure; added LvimGitTag class

Removed:

  • lua/core/ext/gxplus.lua — replaced by lvim-utils.gx.map_default()
  • lua/core/ext/quite.lua — replaced by lvim-utils.quit.open() via :Quit user command
  • fidget.nvim — plugin registration and config block removed entirely
  • lua/languages/ — entire old LSP directory structure removed; all language configs now in lua/modules/base/configs/languages/lsp/servers/