This commit is contained in:
MasterGordon 2026-03-12 16:12:37 +01:00
parent 547f5dbf18
commit c333c1ffb7
11 changed files with 340 additions and 102 deletions

135
CLAUDE.md Normal file
View File

@ -0,0 +1,135 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Overview
This is a personal Neovim configuration built on lazy.nvim with a focus on LSP, testing, and modern plugin management. The configuration emphasizes a clean, modular structure with separate plugin files.
## Architecture
### Core Structure
- **init.lua**: Entry point that sets up vim options, loads lazy.nvim, and initializes core modules
- **lua/keybinds.lua**: Global keybindings (ALT navigation, terminal toggle, C# namespace helper)
- **lua/diagnostic.lua**: Diagnostic display configuration with custom signs and virtual text
- **lua/snippets.lua**: LuaSnip snippets (currently contains C# namespace/class generation)
- **lua/plugins/**: Modular plugin configurations, each file returns a lazy.nvim plugin spec
### Plugin Architecture Pattern
Each plugin file follows lazy.nvim's structure:
```lua
return {
'author/plugin-name',
dependencies = { ... },
opts = { ... },
config = function() ... end,
}
```
## Key Plugins & Configuration
### LSP (lua/plugins/lsp.lua)
- Uses mason.nvim with custom registry including Crashdummyy's registry
- Configured servers: lua_ls, vtsls, jsonls (with schemastore), bashls, zls, cssls, prismals, intelephense, html, yamlls, eslint, tailwindcss, gopls, rust_analyzer, roslyn
- Auto-installs tools: stylua, prettierd, php-cs-fixer, cspell
- Blink.cmp integration for completion capabilities
- Keybindings set on LspAttach:
- `<leader>a`: Code actions
- `gd`, `gr`, `gi`: Definition/references/implementation via Telescope
- `<f2>`: Rename
- `<leader>d`: Show diagnostics float
- `<leader>D`: Jump to next diagnostic
### Formatting (lua/plugins/conform.lua)
- Format-on-save enabled (3s timeout)
- Formatters: stylua (Lua), prettierd/prettier (JS/TS/CSS/JSON/Markdown), php-cs-fixer (PHP), gofmt (Go), csharpierd (C#)
- Manual format: `<leader>f`
### Testing (lua/plugins/neotest.lua)
- Adapters: neotest-jest, neotest-bun
- Jest config auto-detection from project root
- Keybindings:
- `<leader>tt`: Run nearest test
- `<leader>tf`: Run all tests in current file
- `<leader>td`: Display test output
### Fuzzy Finding (lua/plugins/telescope.lua)
- Keybindings (all start with `<leader>f`):
- `ff`: Find files
- `fg`: Live grep
- `fb`: Buffers
- `fd`: Diagnostics
- `fw`: Grep string under cursor
- `fh/fk/fs/fr/f.`: Help/keymaps/builtin/resume/oldfiles
- `ft`: Todo comments
### C# Development
- Roslyn LSP configured
- Custom namespace insertion: `<leader>n` (reads .csproj, constructs namespace from path)
- C# class snippet: `csc` (auto-generates namespace and class from filename)
- csharpierd formatter integration
## Development Workflow
### Testing JavaScript/TypeScript
```bash
# Run nearest test (with cursor on test)
<leader>tt
# Run all tests in file
<leader>tf
# View test output
<leader>td
```
### Formatting
- Auto-formats on save (configured in conform.lua)
- Manual format: `<leader>f`
### LSP Operations
- Jump to definition: `gd` (opens in Telescope)
- Find references: `gr` (opens in Telescope)
- Rename symbol: `<F2>`
- Code actions: `<leader>a`
- Show diagnostics: `<leader>d`
- Next diagnostic: `<leader>D`
- Workspace symbols: `<leader>fs`
## Special Configurations
### Clipboard
Uses xclip for clipboard integration on Linux (configured in init.lua with vim.schedule)
### Theme
TokyoNight theme with transparency disabled on WSL, terminal colors disabled
### Tab Behavior
2-space indentation, tabs converted to spaces globally
### Window Navigation
- ALT + Arrow keys to navigate between splits
- `<C-p>` mapped to `<C-i>` for jump forward
### Terminal
- `<leader><CR>`: Open terminal in insert mode
- `<Esc>`: Exit terminal mode to normal mode
## Plugin Management
### Installing/Updating Plugins
Lazy.nvim auto-bootstraps on first run. To manage plugins:
- Add new plugin specs to lua/plugins/ or directly in init.lua's require('lazy').setup()
- Lazy will auto-install on next startup
### Mason Tool Management
LSP servers and formatters are auto-installed via mason-tool-installer based on the ensure_installed list in lua/plugins/lsp.lua
## Important Notes
- Leader key is Space
- Nerd Font required (vim.g.have_nerd_font = true)
- Swap and backup files disabled
- Relative line numbers enabled
- 10-line scrolloff for cursor positioning
- The configuration uses Neovim 0.10+ APIs with compatibility shim for 0.11 (see client_supports_method in lsp.lua)

88
README.md Normal file
View File

@ -0,0 +1,88 @@
# Neovim Configuration
Personal Neovim configuration built with [lazy.nvim](https://github.com/folke/lazy.nvim) for modern plugin management.
## Requirements
- Neovim >= 0.10
- [Nerd Font](https://www.nerdfonts.com/) (for icons)
- [xclip](https://github.com/astrand/xclip) (for clipboard support on Linux)
- [ripgrep](https://github.com/BurntSushi/ripgrep) (for Telescope live grep)
- [make](https://www.gnu.org/software/make/) (for building Telescope fzf-native)
## Installation
1. Backup your existing Neovim configuration if you have one
2. Clone this repository to your Neovim config directory:
```bash
git clone <your-repo-url> ~/.config/nvim
```
3. Start Neovim - lazy.nvim will automatically bootstrap and install all plugins:
```bash
nvim
```
## Features
- **LSP Support**: Pre-configured language servers for TypeScript, Lua, Go, Rust, C#, PHP, and more
- **Auto-formatting**: Format-on-save with conform.nvim
- **Testing**: Integrated test runner with neotest (Jest and Bun support)
- **Fuzzy Finding**: Telescope for files, grep, LSP symbols, and more
- **Syntax Highlighting**: Tree-sitter based highlighting
- **Git Integration**: Gitsigns for inline git blame and hunks
- **Completions**: Blink.cmp for fast autocompletion
- **File Explorer**: Neo-tree for file navigation
- **Status Line**: Custom Heirline configuration
## Key Bindings
Leader key: `Space`
### File Navigation
- `<leader>ff` - Find files
- `<leader>fg` - Live grep
- `<leader>fb` - Browse buffers
### LSP
- `gd` - Go to definition
- `gr` - Find references
- `<F2>` - Rename symbol
- `<leader>a` - Code actions
- `<leader>d` - Show diagnostics
### Testing
- `<leader>tt` - Run nearest test
- `<leader>tf` - Run tests in current file
- `<leader>td` - Display test output
### Formatting
- `<leader>f` - Format buffer (also auto-formats on save)
### Other
- `<leader><CR>` - Open terminal
- `<leader>n` - Insert C# namespace (C# files only)
## Structure
```
.
├── init.lua # Entry point
├── lua/
│ ├── keybinds.lua # Global keybindings
│ ├── diagnostic.lua # Diagnostic configuration
│ ├── snippets.lua # Custom snippets
│ └── plugins/ # Plugin configurations
│ ├── lsp.lua
│ ├── telescope.lua
│ ├── conform.lua
│ ├── neotest.lua
│ └── ...
└── CLAUDE.md # AI assistant context
```
## Customization
- Edit plugin configurations in `lua/plugins/`
- Add new plugins to the `require('lazy').setup()` call in `init.lua`
- Modify keybindings in `lua/keybinds.lua` or plugin-specific files
- LSP servers and formatters are managed in `lua/plugins/lsp.lua` and `lua/plugins/conform.lua`

View File

@ -42,6 +42,7 @@ vim.cmd([[filetype plugin indent on]])
vim.o.tabstop = 2
vim.o.shiftwidth = 2
vim.o.expandtab = true
vim.o.winborder = 'rounded'
vim.filetype.add({
extension = {
@ -109,7 +110,6 @@ require('lazy').setup({
require('plugins/pairs'),
require('plugins/ccc'),
require('plugins/heirline'),
require('plugins/lspsaga'),
{ 'folke/ts-comments.nvim', opts = {}, event = 'VeryLazy' },
{
'folke/todo-comments.nvim',
@ -136,14 +136,14 @@ require('lazy').setup({
opts = {},
},
'jghauser/mkdir.nvim',
{
'supermaven-inc/supermaven-nvim',
config = function()
if not (vim.fn.has_key(vim.fn.environ(), 'LOAD_SUPERMAVEN') == 0) then
require('supermaven-nvim').setup({})
end
end,
},
-- {
-- 'supermaven-inc/supermaven-nvim',
-- config = function()
-- if not (vim.fn.has_key(vim.fn.environ(), 'LOAD_SUPERMAVEN') == 0) then
-- require('supermaven-nvim').setup({})
-- end
-- end,
-- },
{
'folke/todo-comments.nvim',
dependencies = 'nvim-lua/plenary.nvim',

View File

@ -43,6 +43,7 @@ map ctrl+shift+p set_background_opacity 1
map super+t set_background_opacity default
map ctrl+shift+enter new_window_with_cwd
map ctrl+shift+n new_window_with_cwd
map ctrl+shift+u kitten unicode_input
map ctrl+shift+wheel_up change_font_size all +0.5
map ctrl+shift+wheel_down change_font_size all -0.5

View File

@ -1,45 +1,43 @@
{
"FixCursorHold.nvim": { "branch": "master", "commit": "1900f89dc17c603eec29960f57c00bd9ae696495" },
"LuaSnip": { "branch": "master", "commit": "21e9fecfc07fb2cd707b6c7c3fa148550a34d053" },
"blink.cmp": { "branch": "main", "commit": "327fff91fe6af358e990be7be1ec8b78037d2138" },
"LuaSnip": { "branch": "master", "commit": "dae4f5aaa3574bd0c2b9dd20fb9542a02c10471c" },
"blink.cmp": { "branch": "main", "commit": "4b18c32adef2898f95cdef6192cbd5796c1a332d" },
"ccc.nvim": { "branch": "main", "commit": "9d1a256e006decc574789dfc7d628ca11644d4c2" },
"conform.nvim": { "branch": "master", "commit": "fbcb4fa7f34bfea9be702ffff481a8e336ebf6ed" },
"cspell.nvim": { "branch": "main", "commit": "07d75238648ef99c0c5c05f4cfd83093d0a01dd4" },
"fidget.nvim": { "branch": "main", "commit": "3f5475949679953af6d78654db29b944fa826e6a" },
"friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" },
"gitsigns.nvim": { "branch": "main", "commit": "1ee5c1fd068c81f9dd06483e639c2aa4587dc197" },
"grug-far.nvim": { "branch": "main", "commit": "2e991081c0e653e151fc9e659514d7c2fc31d22a" },
"conform.nvim": { "branch": "master", "commit": "e969e302bced7ffb9a0a0323629f31feb0ca35a6" },
"cspell.nvim": { "branch": "main", "commit": "5feecef8d109f5460c576596aba44a6253127aa4" },
"fidget.nvim": { "branch": "main", "commit": "7fa433a83118a70fe24c1ce88d5f0bd3453c0970" },
"friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" },
"gitsigns.nvim": { "branch": "main", "commit": "9f3c6dd7868bcc116e9c1c1929ce063b978fa519" },
"grug-far.nvim": { "branch": "main", "commit": "9370422e5cdd55321c0b8c4880082c5fd4e52e99" },
"heirline.nvim": { "branch": "master", "commit": "fae936abb5e0345b85c3a03ecf38525b0828b992" },
"lazy.nvim": { "branch": "main", "commit": "1ea3c4085785f460fb0e46d2fe1ee895f5f9e7c1" },
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
"leetcode.nvim": { "branch": "master", "commit": "fdd3f91800b3983e27bc9fcfb99cfa7293d7f11a" },
"lspsaga.nvim": { "branch": "main", "commit": "8efe00d6aed9db6449969f889170f1a7e43101a1" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "6bdb14f230de0904229ec367b410fb817e59b072" },
"mason-tool-installer.nvim": { "branch": "main", "commit": "517ef5994ef9d6b738322664d5fdd948f0fdeb46" },
"mason.nvim": { "branch": "main", "commit": "ad7146aa61dcaeb54fa900144d768f040090bff0" },
"mini.pairs": { "branch": "main", "commit": "b9aada8c0e59f2b938e98fbf4eae0799eba96ad9" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "a324581a3c83fdacdb9804b79de1cbe00ce18550" },
"mason-tool-installer.nvim": { "branch": "main", "commit": "443f1ef8b5e6bf47045cb2217b6f748a223cf7dc" },
"mason.nvim": { "branch": "main", "commit": "44d1e90e1f66e077268191e3ee9d2ac97cc18e65" },
"mini.pairs": { "branch": "main", "commit": "b7fde3719340946feb75017ef9d75edebdeb0566" },
"mkdir.nvim": { "branch": "main", "commit": "c55d1dee4f099528a1853b28bb28caa802eba217" },
"neo-tree.nvim": { "branch": "main", "commit": "20244beec28b9d79ffb75fe1b1606f4dd8d476fc" },
"neotest": { "branch": "master", "commit": "7166dc36af2760a76479e021e0521e23f62165f1" },
"neotest-bun": { "branch": "main", "commit": "453759015c4c87792a720fa3cc7b643cebe9d4cf" },
"neotest-jest": { "branch": "main", "commit": "2f657403aabab7d68eaa2cb9181dc4bb7fdd8a08" },
"none-ls.nvim": { "branch": "main", "commit": "a96172f673f720cd4f3572e1fcd08400ed3eb25d" },
"neo-tree.nvim": { "branch": "main", "commit": "9d6826582a3e8c84787bd7355df22a2812a1ad59" },
"neotest": { "branch": "master", "commit": "deadfb1af5ce458742671ad3a013acb9a6b41178" },
"neotest-bun": { "branch": "main", "commit": "af0f8684cd00a96f1e0359f1aeff2b9bf7a0ec88" },
"neotest-jest": { "branch": "main", "commit": "3f0cc2cff1ee05394081805c622dc2551b54d8c4" },
"none-ls.nvim": { "branch": "main", "commit": "f61f46ded0ca9edce7a09b674f8e162d10921426" },
"nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" },
"nvim-lspconfig": { "branch": "master", "commit": "ac98db2f9f06a56498ec890a96928774eae412c3" },
"nvim-lspconfig": { "branch": "master", "commit": "ead0f5f342d8d323441e7d4b88f0fc436a81ad5f" },
"nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" },
"nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" },
"nvim-ts-autotag": { "branch": "main", "commit": "c4ca798ab95b316a768d51eaaaee48f64a4a46bc" },
"nvim-web-devicons": { "branch": "master", "commit": "b8221e42cf7287c4dcde81f232f58d7b947c210d" },
"nvim-ts-autotag": { "branch": "main", "commit": "8e1c0a389f20bf7f5b0dd0e00306c1247bda2595" },
"nvim-web-devicons": { "branch": "master", "commit": "737cf6c657898d0c697311d79d361288a1343d50" },
"nvim-window-picker": { "branch": "main", "commit": "6382540b2ae5de6c793d4aa2e3fe6dbb518505ec" },
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
"roslyn.nvim": { "branch": "main", "commit": "7d8819239c5e2c4a0d8150da1c00fa583f761704" },
"schemastore.nvim": { "branch": "main", "commit": "667eaa5da8f66f1dd97c905a12dd1eb544a2d259" },
"snacks.nvim": { "branch": "main", "commit": "454ba02d69347c0735044f159b95d2495fc79a73" },
"supermaven-nvim": { "branch": "main", "commit": "07d20fce48a5629686aefb0a7cd4b25e33947d50" },
"telescope-fzf-native.nvim": { "branch": "main", "commit": "1f08ed60cafc8f6168b72b80be2b2ea149813e55" },
"roslyn.nvim": { "branch": "main", "commit": "7deb9bb5b6afcb3c03c70741c6d364ffd8b59bda" },
"schemastore.nvim": { "branch": "main", "commit": "2c2f2d3fb568bbff1a5e1344e87a979b7edf50a8" },
"snacks.nvim": { "branch": "main", "commit": "9912042fc8bca2209105526ac7534e9a0c2071b2" },
"telescope-fzf-native.nvim": { "branch": "main", "commit": "6fea601bd2b694c6f2ae08a6c6fab14930c60e2c" },
"telescope-ui-select.nvim": { "branch": "master", "commit": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2" },
"telescope.nvim": { "branch": "master", "commit": "b4da76be54691e854d3e0e02c36b0245f945c2c7" },
"template-string.nvim": { "branch": "main", "commit": "da5f326b65fb74fd068aa1d8b55461b64c8fb23b" },
"todo-comments.nvim": { "branch": "main", "commit": "19d461ddd543e938eb22505fb03fa878800270b6" },
"tokyonight.nvim": { "branch": "main", "commit": "d14614cbfc63b6037bfccd48bb982d2ad2003352" },
"ts-comments.nvim": { "branch": "main", "commit": "217ab9cc137fceb6659b53790bd25e608219abe1" }
"telescope.nvim": { "branch": "master", "commit": "5255aa27c422de944791318024167ad5d40aad20" },
"template-string.nvim": { "branch": "main", "commit": "d3a26d3c449a97c44891a31736a101b60b64cf2b" },
"todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" },
"tokyonight.nvim": { "branch": "main", "commit": "5da1b76e64daf4c5d410f06bcb6b9cb640da7dfd" },
"ts-comments.nvim": { "branch": "main", "commit": "123a9fb12e7229342f807ec9e6de478b1102b041" }
}

View File

@ -8,23 +8,4 @@ vim.api.nvim_set_keymap('', '<A-Down>', '<C-w><Down>', { silent = true })
vim.api.nvim_set_keymap('', '<A-Right>', '<C-w><Right>', { silent = true })
vim.api.nvim_set_keymap('', '<C-p>', '<C-i>', { silent = true, noremap = true })
local print_namespace = function()
local cmd = 'bash -c "xq *.csproj -q RootNamespace"'
-- insert namespace NAMESPACE.PATH.TO.FILE; at the start of the file
local output = vim.fn.system(cmd):gsub('\n', '')
local relative_path = vim.fn.expand('%:h')
local short_path = relative_path:gsub('/', '.')
local namespace = output .. '.' .. short_path
if relative_path == '.' then
namespace = output
end
vim.cmd([[normal! gg]])
vim.cmd([[normal! }]])
vim.cmd([[normal! o]])
vim.api.nvim_put({ 'namespace ' .. namespace .. ';' }, 'c', true, true)
vim.cmd([[normal! o]])
end
vim.keymap.set('n', '<leader>n', print_namespace, { silent = true })
vim.api.nvim_set_keymap('n', '<leader><cr>', '<cmd>terminal<cr>i', { silent = true })

View File

@ -20,9 +20,10 @@ return {
},
completion = {
documentation = { auto_show = true },
documentation = { auto_show = true, window = { border = 'none' } },
menu = {
max_height = 24,
border = 'none',
},
},

View File

@ -129,11 +129,11 @@ return {
yamlls = {},
eslint = {},
tailwindcss = {},
-- vtsls = {
-- settings = {
-- vtsls = { autoUseWorkspaceTsdk = true },
-- },
-- },
vtsls = {
settings = {
vtsls = { autoUseWorkspaceTsdk = true },
},
},
jsonls = {
settings = {
json = {
@ -144,8 +144,12 @@ return {
},
gopls = {},
rust_analyzer = {},
-- C#
roslyn = {},
tsgo = {},
-- F#
fsautocomplete = {},
-- tsgo = {},
clangd = {},
}
local ensure_installed = vim.tbl_keys(servers or {})
vim.list_extend(ensure_installed, {

View File

@ -1,31 +0,0 @@
return {
'nvimdev/lspsaga.nvim',
config = function()
require('lspsaga').setup({
symbol_in_winbar = {
enable = false,
},
lightbulb = {
enable = false,
},
beacon = {
enable = false,
},
rename = {
keys = {
quit = '<C-c>',
},
},
code_action = {
keys = {
quit = '<C-c>',
},
},
})
vim.keymap.set('n', 'K', '<cmd>Lspsaga hover_doc<CR>')
end,
dependencies = {
'nvim-treesitter/nvim-treesitter', -- optional
'nvim-tree/nvim-web-devicons', -- optional
},
}

View File

@ -52,6 +52,11 @@ return {
color = '#FFFFFF',
name = 'Jar',
},
['fsproj'] = {
icon = '󰪮',
color = '#66b2b2',
name = 'FsProj',
},
})
end,
}

View File

@ -52,13 +52,69 @@ local function get_classname()
return vim.fn.expand('%:t:r')
end
-- C# class snippet
-- C# snippets
ls.add_snippets('cs', {
s('csc', {
-- C# class snippet
s('class', {
t('namespace '),
f(function() return get_namespace() end),
f(function()
return get_namespace()
end),
t({ ';', '', 'public class ' }),
f(function() return get_classname() end),
f(function()
return get_classname()
end),
t({ '', '{', '\t' }),
i(0),
t({ '', '}' }),
}),
-- C# property snippet
s('prop', {
t('public '),
i(1, 'string'),
t(' '),
i(2, 'Name'),
t(' { get; set; }'),
i(0),
}),
-- C# constructor snippet
s('ctor', {
t('public '),
f(function()
return get_classname()
end),
t('('),
i(1),
t({ ')', '{', '\t' }),
i(0),
t({ '', '}' }),
}),
-- C# enum snippet
s('enum', {
t('namespace '),
f(function()
return get_namespace()
end),
t({ ';', '', 'public enum ' }),
f(function()
return get_classname()
end),
t({ '', '{', '\t' }),
i(1, 'Value1'),
t({ ',', '\t' }),
i(0),
t({ '', '}' }),
}),
-- C# interface snippet
s('interface', {
t('namespace '),
f(function()
return get_namespace()
end),
t({ ';', '', 'public interface I' }),
f(function()
return get_classname()
end),
t({ '', '{', '\t' }),
i(0),
t({ '', '}' }),