Skip to content

Latest commit

 

History

335 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nvim

Personal Neovim configuration built on Neovim 0.12, designed around minimalism, reliability, and reducing external dependencies (as much as I could, but some plugins are so cool):

  • Plugin manager framework: vim.pack.
  • No LSP client plugin, I just use native vim.lsp.enable().
  • I'm starting to hate autocompletion, so I switched to using just the (incredible) <C-x><C-o>, and related.

Philosophy

I tried to stick as much as possible to the guiding principle that if Neovim can do it natively, I won't install a plugin for it.

  • vim.pack replaces lazy.nvim. Plugins are declared, cloned, and loaded with the built-in package manager. I lose lazy loading, though, however, most plugins loads only on certain filetypes or user commands anyway.
  • vim.lsp.enable() + lsp/ directory replaces nvim-lspconfig. Each language server is a standalone Lua file returning a vim.lsp.Config table. I still use mason for the installation, because, well, it is really good.
  • I tried setting up Treesitter using the native API (also because nvim-treesitter has been recently archived), but I just couldn't bother, and I'm still using nvim-treesitter to manage parsers and query, maybe in the future...
  • Manual completion via omnifunc (<C-x><C-o> and related).
  • vim.g.pretty, a single flag at the top of init.lua that controls whether the config uses nerd font icons or plain-text fallbacks. Every plugin reads from config/ui.lua, which resolves the flag once at load time.
  • vim.g.ai, another flag to control the AI-related plugins. I use nvim to write my grocery list, I'm ok with *insert big tech company here* not knowing what kind of risotto I will cook today (shout out to Risotto Pumpkin and Gorgonzola).
  • Theme-agnostic colors: the highlight palette is derived from whatever colorscheme is active (default: gruvbox - come on, that is just the best colorscheme available). A ColorScheme autocmd reapplies custom groups automatically, so switching themes doesn't break anything.

Structure

~/.config/nvim/
├── init.lua                    -- vim.loader, flags, require order
├── lua/
│   ├── config/
│   │   ├── init.lua            -- requires sub-modules
│   │   ├── globals.lua         -- generic global functions (e.g. recursive table print)
│   │   ├── settings.lua        -- core vim options
│   │   ├── mappings.lua        -- general keymaps
│   │   ├── ui.lua              -- icon tables (pretty / plain), single source of truth
│   │   ├── utils.lua           -- map(), bufdelete(), helpers
│   │   ├── pin.lua             -- custom file pinning and picker (harpoon replacement)
│   │   ├── autocmds.lua        -- some general useful autocmd
│   │   ├── usercommands.lua    -- user commands
│   │   └── statusline.lua      -- custom statusline and winbar
│   ├── plugins/
│   │   ├── init.lua            -- requires all plugin sub-files
│   │   ├── builtins.lua        -- enable those amazing builtin plugins
│   │   ├── git.lua             -- fugitive + gitsigns
│   │   ├── colors.lua          -- colorscheme + derived palette + custom highlights
│   │   ├── fuzzy.lua           -- fzf-lua + custom git blame pickers
│   │   ├── lsp.lua             -- mason + conform + nvim-lint + LspAttach
│   │   ├── treesitter.lua      -- nvim-treesitter and treesitter-context
│   │   ├── aerial.lua          -- code outline
│   │   ├── latex.lua           -- vimtex + ltex-extra
│   │   ├── snippets.lua        -- luasnip
│   │   ├── surround.lua        -- nvim-surround
│   │   ├── indent.lua          -- indent-blankline
│   │   └── codecompanion.lua   -- AI in neovim
│   └── wiki/
│       ├── init.lua            -- commands, mappings, journal automation
│       ├── plugins.lua         -- wiki and writing plugin declarations/options
│       ├── config.lua          -- tag vocabulary, mappings, UI constants
│       ├── render.lua          -- render-markdown handler for native wiki tags
│       ├── links.lua           -- alternate-buffer and journal links
│       ├── tags.lua            -- tag parsing and insertion
│       ├── projects.lua        -- Taskwarrior project picker
│       ├── search.lua          -- line-oriented WikiTagFind picker
│       └── dates.lua           -- human-readable date parsing
├── tests/
│   └── wiki_spec.lua           -- headless wiki workflow tests
└── lsp/                        -- vim.lsp.Config files (one per server)
    ├── clangd.lua
    ├── pyright.lua
    ├── lua_ls.lua
    ├── fortls.lua
    ├── rust_analyzer.lua
    └── ...                     -- 15 servers total

Features

Custom components (no plugins)

  • pin: harpoon-like file switcher. Opens a floating buffer listing a list of stored files; reorder lines with dd/p, delete entries, press <CR> to jump. The pin-list persists across sessions via Session.vim, because it is stored as a global variable and globals has been added to sessionoptions. I decided to not use harpoon (still an amazing plugin), because I wasn't using many of its features, and I reckoned a very small utility function based on a global variable would do the trick.

  • Statusline and winbar: hand-written statusline and winbar with mode indicator, cwd, diagnostics, LSP status, git diff counts, file-relative paths, and inactive window dimming. All symbols are obtained from ui.lua.

  • Derived color palette: colors.lua extracts colors from the active colorscheme's highlight groups at runtime and builds a consistent set of custom highlights on top. Switching colorschemes re-derives everything automatically.

Built-in Neovim 0.12 plugins

These are shipped with Neovim and activated via packadd:

  • nvim.undotree: interactive undo tree (:Undotree)
  • nvim.difftool: directory/file diff (:DiffTool)
  • cfilter: quickfix list filtering Not many people use this plugin, actually, not many people use the quickfix list at all, that's an amazing tool, check it out!

External plugins

Git

Plugin Description
vim-fugitive Git commands from inside Neovim
gitsigns.nvim Git signs in the sign column, hunk staging, inline blame

Fuzzy finding

Plugin Description
fzf-lua Fuzzy finder over files, buffers, grep, LSP symbols

Code intelligence

Plugin Description
mason.nvim LSP/formatter/linter installer
conform.nvim Formatter runner (clang-format, black, stylua, prettier, ...)
nvim-lint Linter runner (shellcheck, cpplint, pylint, luacheck, ...)
aerial.nvim Code outline / symbol sidebar

Treesitter

Plugin Description
nvim-treesitter Automatic management of parsers and queries
nvim-treesitter-context Sticky context lines at the top of the window

Writing and wiki

Plugin Description
wiki.vim Personal research wiki with journal support
render-markdown.nvim In-buffer markdown rendering with conceal, checkboxes, callouts
calendar.vim Calendar view, integrated with wiki journal
image.nvim Inline image rendering (kitty terminal only)
vim-table-mode Markdown table formatting
vim-easy-align Text alignment
link.vim Link handling

Wiki automation workflow

The wiki remains a directory of ordinary Markdown files. Links express relationships, headings provide document structure, and native wiki.vim colon tags provide semantic classification:

- Asked Jørgen to test the MI300 implementation :request: :@jorgen: :amd: :gpu: :p/madgraph.performance:
  • Generic tags such as :bug: and :gpu: come from the vocabulary in lua/wiki/config.lua.
  • Project tags use :p/<project>: and are discovered dynamically with task _unique project.
  • Person mentions use the free-form :@<name>: namespace.

Native wiki tags are rendered by render-markdown.nvim without changing their Markdown source. Only the syntax markers—the surrounding :, plus p/ for projects or @ for mentions—are concealed. The icon is virtual text, while the tag name remains ordinary, directly editable buffer text with an applied highlight. Generic tags use a quiet shared style, while projects and mentions have distinct icons and colors; configured tags can override either their icon or highlight. For example, :bug: uses a bug badge, :nvidia: uses NVIDIA green, and the C++ and Python glyphs match nvim-web-devicons. Historical tags that are no longer in the insertion vocabulary still receive the generic style.

In lua/wiki/config.lua, generic_tags accepts either a name such as "meeting" or a table such as { name = "bug", icon = " ", highlight = "DiagnosticError", padding = 1 }. highlight may be an existing Neovim highlight-group name or an nvim_set_hl() specification table; omitted fields inherit render.default_tag.

Markdown remains rendered on the cursor line by default. Press <leader>tc to toggle whether the cursor line is revealed without changing the rendered state of the rest of the buffer; <leader>tC (or :RenderMarkdown toggle) toggles the renderer globally. Tag-shaped text inside fenced and inline code remains literal. With NOPRETTY=1, all tag icons disappear while their highlights and shortened project/mention labels remain.

Wiki keybindings
Mode Keymap Action
Normal <leader>ml Insert a Markdown link to the alternate buffer and its nearest heading. Prefix with a count, for example 1<leader>ml, to enter custom link text. Journal targets use journal:YYYY-MM-DD.
Normal <leader>mt Pick and insert one or more generic tags. Use <Tab> for multiple selection and <Enter> to insert.
Normal <leader>mp Pick a Taskwarrior project and insert it as :p/<project>:.
Normal <leader>mm Prompt for a person and insert a free-form :@<name>: mention.
Insert <C-g>t Pick and insert one or more generic tags without leaving the writing workflow.
Insert <C-g>m Prompt for and insert a person mention.
Insert <C-g>p Pick and insert a Taskwarrior project tag.
Normal <leader>ft Open the line-oriented tag browser across the entire wiki.
Normal <leader>fm Open the same tag browser with the initial query @, showing mentions.
Normal <leader>fp Open the same tag browser with the initial query p/, showing project tags.
Normal <leader>fw Browse Markdown files in the wiki with fzf-lua.
Normal <leader>gw Live-grep the wiki.
Normal <leader>cm / <leader>cy Open the monthly / yearly calendar.
Normal <leader>tc Toggle whether Markdown markup is revealed on the cursor line.
Normal <leader>tC Toggle the full Markdown renderer.
Normal [w / ]w Open the previous / next wiki journal entry.

Inside WikiTagFind, <Enter> opens the file at the exact matching line, <C-j> toggles journal results in unrestricted searches, and <F4> toggles the Markdown preview. The picker preserves reverse-chronological journal ordering.

Wiki commands
Command Description
:WikiTagFind [query] Browse all tagged lines, using any non-option arguments as the editable initial fzf query.
:WikiTagFind --since="2 weeks ago" --until=yesterday Browse journal tags in an inclusive date range. Supplying either date option makes the search journal-only.
:WikiMentions Equivalent to :WikiTagFind @.
:WikiProjectTags Equivalent to :WikiTagFind p/.
:WikiTagInsert Insert generic tags from the configured vocabulary.
:WikiProjectTag Insert a project tag selected from Taskwarrior.
:WikiMention [name] Insert a mention, prompting for the name when omitted.
:WikiLinkAlternate Insert a link to the alternate buffer.

The alternate-buffer link workflow is: open the target note, move to the relevant section, return with <C-^>, then press <leader>ml. Heading-like lines inside fenced code blocks are ignored, and duplicate headings receive stable numbered anchors.

LaTeX

Plugin Description
vimtex LaTeX editing, compilation, and preview
ltex_extra.nvim ltex-ls dictionary and rule management (for now I'm using my fork because of some incompatibilities)

Editing

Plugin Description
nvim-surround Add/change/delete surrounding pairs
indent-blankline.nvim Indent guides
LuaSnip Snippet engine

UI

Plugin Description
nvim-web-devicons File type icons (only loaded when vim.g.pretty = true)

AI

Plugin Description
codecompanion.nvim Use different LLM chatbots and agents within neovim (only loaded when vim.g.ai = true)

Quality-of-Life (QoL)

Plugin Description
vim-obsession Smart session management

Language servers

Configured via native lsp/ directory files. Each returns a vim.lsp.Config table.

Server Languages
clangd C, C++, CUDA
ty Python
lua_ls Lua
fortls Fortran
bashls Bash, Sh
awk_ls AWK
cmake CMake
cssls CSS
dockerls Dockerfile
html HTML
jsonls JSON
ltex-plus LaTeX, Markdown (grammar/spell checking)
texlab LaTeX (compilation, references)
vimls Vimscript
yamlls YAML

Requirements

  • Neovim 0.12+ (for vim.pack, vim.lsp.enable(), built-in opt plugins)
  • luarocks with Lua 5.1 (for treesitter parser installation)
  • fzf and delta on $PATH (for fuzzy finding and git diff previews)
  • Taskwarrior on $PATH (for dynamic wiki project-tag discovery)
  • kitty terminal (optional, for inline image rendering)
  • A nerd font (optional, only if vim.g.pretty == true in init.lua - default)
  • A subscription to an AI tool (in my case Copilot and ClaudeCode, optional only if vim.g.ai == true in init.lua - default)

Installation

git clone https://github.com/<user>/nvim.git ~/.config/nvim
nvim

On first launch, vim.pack clones all plugins automatically. Then install treesitter parsers:

:TSInstallAll

And install LSP servers, formatters, and linters:

:Mason

Run modes

You can run with

NOPRETTY=1 nvim

To disable icons and general nerd UI features.

If you run with

NOAI=1 nvim

You disable AI-related plugins (grocery list is safe).

Defined keymaps

To generate the following table, launch the command :DumpKeymaps. It will catch all mappings generated through the use of the custom map function defined in config.utils module.

Mode Keymap Description Source
c <C-a> Move cursor to the beginning of the line config/mappings
c <C-b> Move cursor one character to the left config/mappings
c <C-d> Delete the character under the cursor config/mappings
c <C-e> Move cursor to the end of the line config/mappings
c <C-f> Move cursor one character to the right config/mappings
c <M-b> Move cursor one word to the left config/mappings
c <M-d> Delete the word after the cursor config/mappings
c <M-f> Move cursor one word to the right config/mappings
n ' Jump to mark (easy to press on my keyboard, and more efficient) config/mappings
n <C-d> Scroll half-page down and center viewport config/mappings
n <C-h> Edit 1st element of arglist config/mappings
n <C-j> Edit 2nd element of arglist config/mappings
n <C-k> Edit 3rd element of arglist config/mappings
n <C-l> Edit 4th element of arglist config/mappings
n <C-u> Scroll half-page up and center viewport config/mappings
n <Esc> Disable search-highlighting config/mappings
n <leader>D Delete without polluting the register config/mappings
n <leader>N Find previous (original) config/mappings
n <leader>aa [A]dd the current file to the [A]rg list and remove possible duplicates config/mappings
n <leader>bd Unload the current [B]uffer and [D]elete it from the list config/mappings
n <leader>cd [C]hange current [D]irectory to the base directory of the active buffer config/mappings
n <leader>d Delete without polluting the register config/mappings
n <leader>ln Go to the [L]oclist [N]ext config/mappings
n <leader>lp Go to the [L]oclist [P]revious config/mappings
n <leader>n Find next (original) config/mappings
n <leader>oa [O]pen [A]rglist picker config/mappings
n <leader>qn Go to the [Q]uickfix list [N]ext config/mappings
n <leader>qp Go to the [Q]uickfix list [P]revious config/mappings
n <leader>sr [S]earch and [R]eplace the word under the cursor config/mappings
n <leader>tcd [C]hange current [D]irectory to the base directory of the active buffer, locally to the [T]ab page config/mappings
n <leader>th [T]oggle search-[H]ighlighting config/mappings
n <leader>tl [T]oggle [L]ocation list config/mappings
n <leader>tn [T]oggle relative line [N]umbers config/mappings
n <leader>tq [T]oggle [Q]uickfix list config/mappings
n <leader>tu [T]oggle [U]ndotree config/mappings
n <leader>tw [T]oggle word-[W]rap config/mappings
n N Find previous and center viewport config/mappings
n [<C-L> Display the last error in the previous file in the location list config/mappings
n [<C-Q> Display the first error in the next file in the quickfix list config/mappings
n [A Go to first [A]rg config/mappings
n [B Go to first [B]uffer config/mappings
n [L Go to first [L]ocation list element and center viewport config/mappings
n [Q Go to first [Q]uickfix list element and center viewport config/mappings
n [a Go to previous [A]rg config/mappings
n [b Go to previous [B]uffer config/mappings
n [d Go to previous [D]iagnostic, center viewport config/mappings
n [l Go to previous [L]ocation list element and center viewport config/mappings
n [q Go to previous [Q]uickfix list element and center viewport config/mappings
n ]<C-L> Display the first error in the next file in the location list config/mappings
n ]<C-Q> Display the first error in the next file in the quickfix list config/mappings
n ]A Go to last [A]rg config/mappings
n ]B Go to last [B]uffer config/mappings
n ]L Go to last [L]ocation list element and center viewport config/mappings
n ]Q Go to last [Q]uickfix list element and center viewport config/mappings
n ]a Go to next [A]rg config/mappings
n ]b Go to next [B]uffer config/mappings
n ]d Go to next [D]iagnostic, center viewport config/mappings
n ]l Go to next [L]ocation list element and center viewport config/mappings
n ]q Go to next [Q]uickfix list element and center viewport config/mappings
n g[ [G]et the merge resolution from the buffer on the left [h] (target parent) config/mappings
n g] [G]et the merge resolution from the buffer on the right [l] (merge parent) config/mappings
n n Find next and center viewport config/mappings
v <leader>D Delete without polluting the register config/mappings
v <leader>d Delete without polluting the register config/mappings
v <leader>fi [FI]nd the visual selection in the current file config/mappings
v <leader>p Replace selected text with the content of the default register but don't pollute the register itself config/mappings
v <leader>sr [S]earch and [R]eplace the visual selection config/mappings
v J Move line down, respect indentation config/mappings
v K Move line up, respect indentation config/mappings
n <leader>tt [T]oggle [T]ags sidebar, powered by Aerial plugins/aerial
n,v <leader>ca [C]odeCompation CLI for [A]gent interaction plugins/codecompanion
n,v <leader>cc [C]ode[C]ompanion Actions plugins/codecompanion
n,v <leader>co [C]odeCompation Chat [O]pen plugins/codecompanion
v ga Add visually selected chat to the current chat buffer plugins/codecompanion
n <leader>/ FZF search in current buffer [/] plugins/fuzzy
n <leader>fO FZF over files [unrestricted] -- [F]ind [O]pen plugins/fuzzy
n <leader>fb FZF over loaded buffers -- [F]ind [B]uffers plugins/fuzzy
n <leader>ff Resume latest FZF search -- [F]ind [F]ind plugins/fuzzy
n <leader>fo FZF over files -- [F]ind [O]pen plugins/fuzzy
n <leader>fq FZF over quickfix stack -- [F]ind [Q]uickfix plugins/fuzzy
n <leader>fw FZF over wiki files -- [F]ind [W]iki plugins/fuzzy
n <leader>gO Live grep over files [unrestricted] -- [G]rep [O]pen plugins/fuzzy
n <leader>gT Live grep of the WORD under the cursor -- [G]rep [T]his plugins/fuzzy
n <leader>go Live grep over files -- [G]rep [O]pen plugins/fuzzy
n <leader>gt Live grep of the word under the cursor -- [G]rep [T]his plugins/fuzzy
n <leader>gw Live grep over files -- [G]rep [W]iki plugins/fuzzy
n <leader>sf FZF over LSP [S]ymbols in the current [F]ile plugins/fuzzy
n <leader>sw FZF over LSP [S]ymbols in the current [W]orkspace plugins/fuzzy
n <leader>gD Populate command line with [G]it [D]iff plugins/git
n <leader>gF Populate the command line with git pull --rebase -u origin plugins/git
n <leader>gP Populate command line with [G]it [P]ush -u origin plugins/git
n <leader>gb [G]it [B]lame plugins/git
n <leader>gd [G]it [D]iff in split window plugins/git
n <leader>gf Run git pull --rebase (a [G]it [F]etch followed by a rebase in the current branch) plugins/git
n <leader>gl [G]it [L]og, prefix with any count to display only commits that changed the current file plugins/git
n <leader>gp Run a [G]it [P]ush plugins/git
n <leader>gs Run [G]it [S]tatus (open vim-fugitive prompt) plugins/git
n <leader>hp Current [H]unk and [P]review it plugins/git
n <leader>hr Current [H]unk and [R]eset it plugins/git
n <leader>hs Current [H]unk and [S]tage it plugins/git
n <leader>hu Current [H]unk and [U]nstage it plugins/git
n <leader>tB [T]oggle git [B]lame (full blame with count) plugins/git
n <leader>tD [T]oggle git [D]iff plugins/git
n [c Go to the previous [C]hange (git hunk) or [C]onflict marker (in diff mode) plugins/git
n ]c Go to the next [C]hange (git hunk) or [C]onflict marker (in diff mode) plugins/git
o ih Select [I]nside the current [H]unk plugins/git
v <leader>gb [G]it [B]lame -- range history (pickaxe) plugins/git
v <leader>hr Current [H]unk and [R]eset it plugins/git
v <leader>hs Current [H]unk and [S]tage it plugins/git
x ih Select [I]nside the current [H]unk plugins/git
i <C-s> Signature help (insert mode) plugins/lsp
n <leader>cf [C]ode [F]ormatting plugins/lsp
n <leader>ll Open the [L]ist of diagnostics in the [L]ocation list plugins/lsp
n <leader>lq Open the [L]ist of diagnostics in the [Q]uickfix list plugins/lsp
n <leader>om [O]pen [M]ason dashboard plugins/lsp
n <leader>sd Go to [S]ymbol [D]eclaration plugins/lsp
n <leader>sh [S]ignature [H]elp plugins/lsp
n <leader>ti [T]oggle [I]nlay hints plugins/lsp
n <leader>tv [T]oggle [V]irtual text in diagnostic plugins/lsp
n [d Go to previous [D]iagnostic, center viewport plugins/lsp
n ]d Go to next [D]iagnostic, center viewport plugins/lsp
i <S-Tab> When inside a snippet, jump back plugins/snippets
i <Tab> Expand snippet or jump forward, fallback to Tab plugins/snippets
i,n <C-n> When inside a choice node, select next choice plugins/snippets
i,n <C-p> When inside a choice node, select previous choice plugins/snippets
n <leader>U Reload/[U]pdate the snippets at runtime plugins/snippets
s <S-Tab> When inside a snippet, jump back plugins/snippets
s <Tab> When inside a snippet, jump forward plugins/snippets
n,x,o [M Move to @function.outer plugins/treesitter
n,x,o [[ Move to @class.outer plugins/treesitter
n,x,o [m Move to @function.outer plugins/treesitter
n,x,o [o Move to @loop.inner,@loop.outer plugins/treesitter
n,x,o ]M Move to @function.outer plugins/treesitter
n,x,o ]] Move to @class.outer plugins/treesitter
n,x,o ]m Move to @function.outer plugins/treesitter
n,x,o ]o Move to @loop.inner,@loop.outer plugins/treesitter
x,o aa Select @parameter.outer plugins/treesitter
x,o ac Select @class.outer plugins/treesitter
x,o ad Select @comment.outer plugins/treesitter
x,o af Select @function.outer plugins/treesitter
x,o as Select @statement.outer plugins/treesitter
x,o ia Select @parameter.inner plugins/treesitter
x,o ic Select @class.inner plugins/treesitter
x,o if Select @function.inner plugins/treesitter
n <leader>cm [C]alendar for the current [M]onth wiki/plugins
n <leader>cy [C]alendar for the current [Y]ear wiki/plugins
n <leader>tc [T]oggle cursor-line markdown [C]oncealment wiki/plugins
n <leader>tC [T]oggle full markdown [C]oncealment wiki/plugins
i <C-g>m Insert person mention wiki/init
i <C-g>p Insert Taskwarrior project tag wiki/init
i <C-g>t Insert wiki tag(s) wiki/init
n <leader>fm Find wiki mentions wiki/init
n <leader>fp Find wiki project tags wiki/init
n <leader>ft Find tagged wiki lines wiki/init
n <leader>ml Insert Markdown link to alternate buffer wiki/init
n <leader>mm Insert person mention wiki/init
n <leader>mp Insert Taskwarrior project tag wiki/init
n <leader>mt Insert wiki tag(s) wiki/init

About

My neovim config

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Contributors

Languages