JT
  • Home
  • Projects
  • Extras
  • Contact

© 2026 Joshua Tjhie. All rights reserved.

GitHubLinkedInEmail
Back to Extras
  1. Home
  2. Extras
  3. Neovim Setup (Placeholder)
2024-05-01

Neovim Setup (Placeholder)

My current Neovim configuration for TypeScript and Rust work.

A tour of the plugins, keymaps, and workflow choices that make up my daily Neovim setup — including LSP, formatter config, and navigation patterns.

NeovimToolingProductivity
Neovim Setup (Placeholder)

Quick Stats

Role: Developer
Duration: Ongoing
Neovim 0.10Lualazy.nvimTypeScript LSP

Links

Dotfiles Repo

Neovim Setup

This is a living document — the config evolves as my workflow does. The dotfiles repo always has the canonical current state; this write-up explains the why behind the choices.

I switched to Neovim full-time in late 2022. The modal workflow felt awkward for the first two weeks, then clicked hard. I haven't opened VS Code for serious work since.

Goals

Every config decision is weighed against three criteria:

  1. Fast navigation — getting to any file or symbol in under three keystrokes.
  2. Consistent tooling — same lint/format behaviour in TypeScript, Rust, and Lua.
  3. Discoverable keymaps — which-key means I don't need to memorise everything cold.

Plugin manager

Neovim startup screen
lazy.nvim startup — plugins load on demand, startup time stays under 80 ms.

lazy.nvim manages everything. Plugins load lazily by event, command, or filetype — startup stays under 80 ms even with 40+ plugins.


LSP setup

LSP configuration lives in lua/plugins/lsp.lua. I use nvim-lspconfig with none-ls for formatters and linters that don't ship a language server.

TypeScript

typescript-tools.nvim replaces the default tsserver setup — it uses the workspace's own tsserver binary rather than the global one, which means version mismatches disappear.

{
  "pmizio/typescript-tools.nvim",
  ft = { "typescript", "typescriptreact", "javascript", "javascriptreact" },
  opts = {
    settings = {
      tsserver_file_preferences = {
        includeInlayParameterNameHints = "all",
        includeInlayReturnTypeHints = true,
      },
    },
  },
}

Rust

rust-tools.nvim wraps rust-analyzer and adds inlay hints, hover actions, and cargo check integration.

Inline code tip: <leader>ca triggers code actions — renaming, auto-import, and cargo add for missing crates all live here.

Formatters via none-ls

LanguageFormatterLinter
TypeScriptPrettierESLint
Rustrustfmtclippy (via RA)
Luastylua—
Markdownprettiermarkdownlint

Format-on-save is enabled globally via vim.api.nvim_create_autocmd("BufWritePre", ...).

Navigation

The navigation stack:

  • Telescope — fuzzy file finder (<leader>ff), live grep (<leader>fg), LSP references (<leader>fr).
  • Harpoon (v2) — up to four persistent marks per session. <leader>ha to add, <C-1>–<C-4> to jump.
  • nvim-tree — file explorer, hidden by default, toggled with <leader>e.
  • leap.nvim — character-based jump to any visible position, two-keystrokes maximum.

Completion

nvim-cmp with sources in priority order:

  1. luasnip snippets.
  2. LSP completions.
  3. Buffer words (current file).
  4. Path completions.

<Tab> confirms the first entry, <C-Space> forces the menu open, <C-e> dismisses. I deliberately don't use <Enter> for confirmation — it causes too many accidental newlines.

15 minutes of real work — Telescope, Harpoon, LSP actions, and format-on-save in action.
The ambient playlist I code to — lo-fi, no lyricsListen
Your browser does not support the audio element.

Statusline

lualine.nvim with a minimal config: mode indicator, file path (relative), git branch, LSP diagnostics, and clock on the right. No icons — the diagnostic counts in plain text are more glanceable than symbols.

A good editor config is invisible. You stop noticing the tool and start noticing the problem.

Browse the Dotfiles

Have thoughts?

Curious what others see or think

Feel free to reach out or leave feedback

Share Feedback

Prefer email? joshuatjhie@pm.me