Compare commits

...

9 Commits

Author SHA1 Message Date
David Ibia d24b3ba574 chore(nvim): update plugins
Lazy update across 28 plugins, including snacks.nvim, gitsigns, conform, mason, nvim-lspconfig, nvim-dap and image.nvim. Startup is clean, lua_ls and ts_ls attach, and the treesitter health check passes after rebuilding the parsers.
2026-10-10 22:28:54 +01:00
David Ibia a0adcf2224 docs(readme): rewrite the README for the modernized config
Phase 1 deleted the old README, which listed Telescope, nvim-cmp and other removed plugins. The new one covers install, layout, the current plugin stack, theme sync and the main keymaps.
2026-10-10 22:23:41 +01:00
David Ibia 2d427aac96 fix(nvim): drop the last nvim-cmp dependency from lsp-config
Capabilities already come from blink.cmp, so cmp-nvim-lsp only kept a dead plugin installed. Also ignore oh-my-claudecode's .omc session state.
2026-10-10 22:18:35 +01:00
David Ibia e98864d488 fix(nvim): purge lingering telescope back-references
Four plugin specs still listed telescope (or telescope-dap) as a
dependency, causing :Lazy sync to silently re-install telescope
after Phase 3. Drop the explicit telescope dep from venv-selector
(v2 has its own picker UI) and from dap (telescope-dap was unused).
Delete cheatsheet.nvim and gitignore.nvim entirely — both are
pure-telescope frontends with no fallback, and removing telescope
broke them.
2026-05-02 21:35:59 +01:00
David Ibia 81662b99b5 feat(nvim): phase 3 — replace nvim-cmp with blink.cmp and telescope with snacks.picker
Swap the completion engine to blink.cmp v1.x, dropping nvim-cmp,
its eight cmp-* sources, lspkind, and LuaSnip. Swap the picker
to snacks.picker, removing telescope.nvim and six telescope
extensions. LSP capabilities now sourced from blink.cmp; LSP
navigation keymaps and the colorscheme/keymaps/todo pickers move
to Snacks.picker. friendly-snippets is preserved as blink's
snippet source.
2026-05-02 21:25:57 +01:00
David Ibia 58db15c1c0 feat(nvim): phase 2 — replace nvim-notify and dressing with snacks
Enable snacks.input and snacks.notifier modules; remove the
now-redundant nvim-notify and archived dressing.nvim specs.
Notifier preserves the prior icons and 3000 ms timeout.
2026-05-02 13:38:02 +01:00
David Ibia 38606b86c6 feat(nvim): phase 1 — triage and abandoned-plugin cleanup
Fix keymap collision on <leader>j/<leader>k (now resize-only;
location-list moved to ]l/[l). Migrate diagnostic signs from
deprecated vim.fn.sign_define to vim.diagnostic.config. Drop
orphan after/nvim-tree.lua and the bogus require("../current-theme").
Add foundation snacks.nvim spec. Remove playground, vim-maximizer,
poet-v, git-blame, render-markdown, and all five AI plugin specs.
Enable gitsigns current_line_blame.
2026-05-02 13:36:16 +01:00
David Ibia b4bb915a3f docs(plan): add nvim modernization implementation plan
Three-phase, single-branch plan derived from the modernization
spec. Each phase is one commit with restart-and-validate gates.
Phase 1 fixes critical bugs and removes abandoned plugins;
phase 2 swaps notify/dressing for snacks UI; phase 3 swaps
nvim-cmp for blink.cmp and telescope for snacks.picker.
2026-05-02 06:04:43 +01:00
David Ibia 5d9852f4ee docs(spec): add nvim modernization design
Plan a three-phase modernization: triage critical bugs and remove
abandoned plugins, swap notify+dressing for snacks UI, and replace
nvim-cmp with blink.cmp + telescope with snacks.picker.
2026-05-02 06:04:31 +01:00
48 changed files with 2497 additions and 1015 deletions
+3
View File
@@ -49,3 +49,6 @@ luac.out
.DS_Store
/Screenshots/*
.env
# oh-my-claudecode session state
.omc/
+63 -20
View File
@@ -1,38 +1,81 @@
# Absolute VIM Configuration
# Absolute VIM
## Introduction
A Lua Neovim configuration managed by [lazy.nvim](https://github.com/folke/lazy.nvim). It lives at `.config/nvim` in [absolute-dotfiles](https://github.com/boxpositron/absolute-dotfiles) as a submodule, and works on its own too.
VIM Configurations for the modern developer. This configuration is designed to be efficient for my personal workflow. It is designed to be minimalistic and easy to use.
## Install
## Installation
Requirements: Neovim 0.12 or newer, git, a Nerd Font, `ripgrep` and `fd` for the picker, a C compiler for treesitter parsers, and optionally `lazygit` and ImageMagick (for image previews).
```bash
git clone https://github.com/boxpositron/absolute-vim ~/.config/nvim --depth 1 && nvim
git clone https://github.com/boxpositron/absolute-vim ~/.config/nvim
nvim # lazy.nvim bootstraps itself and installs the pinned plugins from lazy-lock.json
```
## Dependencies
Plugin versions are pinned in `lazy-lock.json`. Update them with `:Lazy update`, then commit the lockfile.
### Binaries
## Layout
> Improved Git Experience
```
init.lua -> require("absolute")
lua/current-theme.lua default colorscheme
lua/absolute/
core/ options, leader, colorscheme sync and the theme registry
lazy.lua lazy.nvim bootstrap; imports every spec in plugins/
plugins/ one plugin spec per file
after/ the matching configuration, required from each spec's config
remap.lua editor keymaps
lsp/, helpers/, utils/ extra LSP setup, project helpers, environment detection
docs/superpowers/ design spec and plan for the 2026 modernization
```
- [lazygit](https://github.com/jesseduffield/lazygit)
To add a plugin, create `plugins/<name>.lua` returning its spec, and put its setup in `after/<name>.lua`.
> Beautiful Code Screenshots
## What's inside
- [silicon](https://github.com/Aloxaf/silicon)
| Area | Plugins |
|---|---|
| Picker, explorer, notifications, input | snacks.nvim (also `bigfile` and `quickfile`) |
| Completion | blink.cmp with friendly-snippets; LSP, path, snippet and buffer sources, plus cmdline completion |
| LSP and formatting | nvim-lspconfig, mason (ts_ls, lua_ls, rust_analyzer, clangd, tailwindcss, svelte, astro, biome and more), conform |
| Syntax | nvim-treesitter, treesitter-context, treesj, tree-sitter-ghostty |
| Git | gitsigns with current-line blame, mini.diff, lazygit in toggleterm |
| Diagnostics and lists | trouble, todo-comments, nvim-bqf |
| Debugging | nvim-dap and dap-ui |
| Languages and tools | flutter-tools, venv-selector, apple-pkl, tailwind-sorter, markview, image.nvim, nvim-silicon |
| UI | lualine, incline, indent-blankline, smear-cursor, highlight-colors, flash, mini |
| Themes | tokyonight (default), catppuccin, rose-pine, nightfly |
> Fuzzy Finder
The 2026 modernization replaced Telescope with the snacks picker, nvim-cmp with blink.cmp, and nvim-notify and dressing with snacks, and removed abandoned and AI plugins. The spec and plan are in `docs/superpowers/`.
- [fzf](https://github.com/junegunn/fzf)
## Themes
### Fonts
`<leader>cs` opens a colorscheme picker. Changing the colorscheme also switches Ghostty and WezTerm to the matching theme, using the mappings in `core/theme-registry.lua`. The startup colorscheme is set in `lua/current-theme.lua`.
- [Noto Emoji](https://fonts.google.com/noto/specimen/Noto+Emoji)
- [JetBrains Mono](https://fonts.google.com/specimen/JetBrains+Mono)
## Keymaps
The leader is Space. Highlights:
Work in progress...
| Keys | Action |
|---|---|
| `<C-p>` | Find files |
| `<leader>gf` / `<leader>pr` | Git files / recent files |
| `<leader>ps` / `<leader>sb` | Live grep / grep the word under the cursor |
| `<leader>pf` / `<leader>cf` | File explorer at the cwd / at the current file's directory |
| `<leader>pt` / `<leader>tt` | TODO comments in the picker / in Trouble |
| `gd` `gi` `gt` / `<leader>cr` | Definitions, implementations, type definitions / references |
| `K` / `<leader>gh` | Hover docs / signature help |
| `<leader>rn` / `<leader>ca` / `<leader>f` | Rename / code actions / format |
| `<leader>rs` | Restart LSP |
| `<leader>td` `<leader>ts` `<leader>tq` | Trouble: diagnostics, symbols, quickfix |
| `<leader>gs` | lazygit |
| `<leader>db` | Toggle a breakpoint |
| `<leader>m` | Split or join the node under the cursor (treesj) |
| `<leader>u` | Undo tree |
| `<leader>sr` | Replace the word under the cursor |
| `<leader>y` / `<leader>p` | Yank to the system clipboard / paste without overwriting the register |
| `<leader>gr` | Run a shell command in the git root |
| `<leader>vs` | Select a Python virtualenv |
| `<leader>sc` | Screenshot the selection with Silicon |
| `<leader>?` | Search all keymaps |
blink.cmp uses its default keymap preset: `<C-space>` opens the menu, `<C-y>` accepts, `<C-n>` and `<C-p>` move through items.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,369 @@
# Neovim Config Modernization — Design Spec
**Date:** 2026-05-02
**Target Neovim version:** 0.12.x
**Branch strategy:** Single branch, three sequential commits with restart-and-validate between each.
## Goals
1. Fix four silent breakages currently in the running config.
2. Remove abandoned, archived, or superseded plugins.
3. Swap two plugin engines that have been overtaken by snacks.nvim and blink.cmp in the 2026 ecosystem.
4. End up with a smaller, less-redundant `lua/absolute/` tree that is consistent with Neovim 0.12 idioms.
## Non-goals
- Migrating `nvim-treesitter` from frozen `master` to the 0.12-only `main` rewrite. Deferred to a separate, future spec.
- Restructuring the `absolute/` module layout. The current `core / plugins / after / utils / helpers` split is preserved.
- Adding new AI plugins. All AI integrations (`opencode`, `codecompanion`, `copilot`, `gen`, `llm`) are removed in this spec.
- Changing colorscheme behavior or the `theme-registry` system, which is recent and intentional.
## Scope summary
| Phase | Theme | Risk | Files touched |
|---|---|---|---|
| 1 | Triage and deletions | Low | ~20 files (mostly deletes) |
| 2 | UI swap (notify + dressing → snacks) | Low | 4 files |
| 3 | Engine swaps (nvim-cmp → blink, telescope → snacks.picker) | Medium | ~15 files |
Each phase is one commit on the same branch. Restart Neovim and validate after each commit before starting the next.
---
## Phase 1 — Triage and deletions
### Critical fixes
**C1 — `lua/absolute/remap.lua`: keymap collision on `<leader>j` / `<leader>k`.**
Lines 70–73 bind `<leader>k`/`<leader>j` to `lnext`/`lprev`. Lines 120–124 rebind the same keys to window resize, silently overriding them. The window-resize 4-way pad (`<leader>h/j/k/l`) is the intentional binding.
**Action:** Delete lines 70–73. If location-list nav is wanted, rebind to the idiomatic `]l` / `[l` pair (next / previous location-list entry). Decision in this spec: rebind to `]l` / `[l`.
**C2 — `lua/absolute/after/lsp-config.lua`: deprecated diagnostic-sign API.**
Lines 73–83 use `vim.fn.sign_define` to set diagnostic gutter icons. This API is deprecated in 0.10 and is removed in 0.12.
**Action:** Replace with the modern `vim.diagnostic.config` table:
```lua
vim.diagnostic.config({
signs = {
text = {
[vim.diagnostic.severity.ERROR] = " ",
[vim.diagnostic.severity.WARN] = " ",
[vim.diagnostic.severity.HINT] = "󰠠 ",
[vim.diagnostic.severity.INFO] = " ",
},
},
})
```
**C3 — Orphan after-file `lua/absolute/after/nvim-tree.lua`.**
There is no matching plugin spec in `lua/absolute/plugins/`. The file is dead but will crash on `require` if anything ever loads it.
**Action:** Delete the file.
**C4 — Non-idiomatic require in `lua/absolute/lazy.lua:36`.**
`require("../current-theme")` uses a literal-slash module name. The file is at `lua/current-theme.lua`, which is on the runtime path; the canonical form is `require("current-theme")`.
**Action:** Change to `require("current-theme")`.
### Plugin removals
The following plugin specs and their after-files are deleted. lazy.nvim removes them from `lazy-lock.json` automatically on the next `:Lazy sync`.
| Plugin | Files deleted | Reason |
|---|---|---|
| `playground` | `plugins/nvim-treesitter-playground.lua` | Repo archived 2024; replaced by built-in `:Inspect` / `:InspectTree` / `:EditQuery` |
| `vim-maximizer` | `plugins/vim-maximizer.lua` | Last commit 2013; native `<C-w>_` and `<C-w>\|` cover the use case |
| `poet-v` | `plugins/poet-v.lua`, `after/poet-v.lua` | Abandoned; `venv-selector.nvim` covers Python envs |
| `git-blame.nvim` | `plugins/git-blame.lua` | Replaced by gitsigns `current_line_blame` |
| `render-markdown.nvim` | `plugins/render-markdown.lua` | Picked `markview.nvim` as single markdown renderer |
| `codecompanion.nvim` | `plugins/codecompanion.lua`, `after/codecompanion.lua` | AI cleanup |
| `copilot.vim` | `plugins/copilot.lua` | AI cleanup |
| `gen.nvim` | `plugins/gen.lua`, `after/gen.lua` | AI cleanup |
| `llm.nvim` | `plugins/llm.lua`, `after/llm.lua` | AI cleanup |
| `opencode.nvim` | `plugins/opencode.lua`, `after/opencode.lua` | AI cleanup |
`dressing.nvim` and `nvim-notify` removal is deferred to Phase 2 because both are *swapped*, not deleted.
### New file: `lua/absolute/plugins/snacks.lua`
Removing `opencode.nvim` removes the dependency that pulled `snacks.nvim` into the tree. snacks is required for Phase 2 (input, notifier) and Phase 3 (picker), so a top-level spec is added now.
```lua
return {
"folke/snacks.nvim",
priority = 1000,
lazy = false,
---@type snacks.Config
opts = {
bigfile = { enabled = true },
quickfile = { enabled = true },
-- input, notifier added in Phase 2
-- picker added in Phase 3
},
}
```
### Config tweak: gitsigns line-blame
`lua/absolute/after/gitsigns.lua` is updated to enable virtual-text blame on the current line, replacing the functionality lost when `git-blame.nvim` is removed:
```lua
current_line_blame = true,
current_line_blame_opts = {
virt_text_pos = "eol",
delay = 500,
ignore_whitespace = false,
},
```
### Untracked work
- `lua/absolute/core/theme-registry.lua` is committed as-is (already complete).
- `lua/absolute/plugins/flash.lua` is committed as-is, retaining `enabled = false`.
- `lua/absolute/after/opencode.lua` is deleted in this phase along with the rest of opencode.
### Disabled-spec policy
Seven plugin specs currently have `enabled = false` and look intentional:
`apple-pkl`, `flash`, `flutter-tools`, `mini`, `nvim-surround`, `smear-cursor`, `tailwind-sorter`.
These are left untouched — the user toggles them on for specific projects. They are not part of this modernization.
### Phase 1 net change
- 16 plugin spec or after-files deleted
- 1 file added (`plugins/snacks.lua`)
- 4 files edited (`remap.lua`, `after/lsp-config.lua`, `after/gitsigns.lua`, `lazy.lua`)
- ~10 plugins removed from lockfile
### Phase 1 validation
After committing Phase 1, restart Neovim and verify:
1. No errors on startup (`:messages` empty of `E:` lines).
2. Diagnostic signs render (open a Lua file with an error).
3. `:Lazy clean` removes the orphaned plugins from disk.
4. `<leader>j` and `<leader>k` resize the current window.
5. `]l` / `[l` jump in location list.
6. Gitsigns shows current-line blame after a 500 ms idle.
7. `:Inspect`, `:InspectTree`, `:EditQuery` all work (proves treesitter playground replacement).
---
## Phase 2 — UI swap (notify + dressing → snacks)
Both replaced plugins are tiny. Migration is mostly deletes plus a snacks config bump.
### Deletions
| File | Notes |
|---|---|
| `lua/absolute/plugins/notify.lua` | Lazy spec |
| `lua/absolute/after/notify.lua` | Configures `vim.notify = notify` |
| `lua/absolute/plugins/dressing.lua` | Trivial `VeryLazy` spec, no after-file |
`nvim-notify` and `dressing.nvim` drop from the lockfile.
### Update `lua/absolute/plugins/snacks.lua`
Add `input` and `notifier` modules. Notifier config preserves the icons and timeout from the existing nvim-notify setup:
```lua
opts = {
bigfile = { enabled = true },
quickfile = { enabled = true },
input = { enabled = true },
notifier = {
enabled = true,
timeout = 3000,
style = "compact",
top_down = true,
icons = {
debug = "",
error = "",
info = "",
trace = "✎",
warn = "",
},
},
}
```
snacks installs `vim.notify = Snacks.notifier.notify` and overrides `vim.ui.input` automatically when the modules are enabled. No manual hookup is needed.
### Settings dropped (no equivalent needed)
`background_colour`, `fps`, `render`, `stages`, `minimum_width`, `time_formats` from the old nvim-notify config — all subsumed by snacks defaults or replaced by the `style = "compact"` choice.
### Phase 2 net change
- 3 files deleted
- 1 file edited (`plugins/snacks.lua`)
- 0 keymaps changed
- 2 plugins removed from lockfile
### Phase 2 validation
1. Restart Neovim. No errors on startup.
2. Trigger a notification (e.g. `:lua vim.notify("test", vim.log.levels.INFO)`) — toast appears in the top-right.
3. Trigger a `vim.ui.input` (e.g. `<leader>rn` to LSP-rename, or `<leader>gr` to enter a git-root command) — centered floating prompt appears.
4. Trigger a `vim.ui.select` (e.g. `<leader>ca` for code actions) — the snacks select UI appears.
---
## Phase 3 — Engine swaps (blink.cmp + snacks.picker)
The largest phase. Two engine swaps in one commit because they share the snacks ecosystem and both touch the LSP attach path.
### 3a — `nvim-cmp` → `blink.cmp`
**Plugins removed from lockfile** when `nvim-cmp` is deleted (they were nvim-cmp dependencies):
`nvim-cmp`, `cmp-nvim-lsp`, `cmp-buffer`, `cmp-path`, `cmp-cmdline`, `cmp_luasnip`, `LuaSnip`, `lspkind.nvim`. `friendly-snippets` is kept and consumed directly by blink.
Files deleted: `lua/absolute/plugins/nvim-cmp.lua`, `lua/absolute/after/nvim-cmp.lua`.
**New file `lua/absolute/plugins/blink-cmp.lua`:**
```lua
return {
"saghen/blink.cmp",
version = "1.*", -- pin to v1 stable
event = "InsertEnter",
dependencies = { "rafamadriz/friendly-snippets" },
config = function()
require("absolute.after.blink-cmp")
end,
}
```
**New file `lua/absolute/after/blink-cmp.lua`:**
```lua
require("blink.cmp").setup({
keymap = { preset = "default" }, -- C-y accept, C-n/p navigate, C-Space trigger
appearance = { nerd_font_variant = "mono" },
sources = {
default = { "lsp", "path", "snippets", "buffer" },
},
cmdline = {
keymap = { preset = "cmdline" },
completion = { menu = { auto_show = true } },
},
signature = { enabled = true },
})
```
**Edit `lua/absolute/after/lsp-config.lua`:**
Replace the cmp-nvim-lsp capabilities provider:
```lua
-- old:
local cmp_nvim_lsp = require("cmp_nvim_lsp")
local capabilities = cmp_nvim_lsp.default_capabilities()
-- new:
local capabilities = require("blink.cmp").get_lsp_capabilities()
```
### 3b — `telescope.nvim` → `snacks.picker`
**Plugins removed from lockfile** when `telescope.nvim` is deleted:
`telescope.nvim`, `telescope-file-browser.nvim`, `telescope-live-grep-args.nvim`, `telescope-media-files.nvim`, `telescope-themes`, `telescope-dap.nvim`, `popup.nvim`.
`junegunn/fzf` **stays** — it is also a dependency of `nvim-bqf` (`lua/absolute/plugins/nvim-bqf.lua:6`), which is unrelated to this swap. The `lua/absolute/plugins/fzf.lua` spec is kept as-is.
Files deleted:
- `lua/absolute/plugins/telescope.lua`
- `lua/absolute/after/telescope.lua`
- `lua/absolute/utils/telescope_image_preview.lua` (replaced by snacks built-in image preview via image.nvim)
**Update `lua/absolute/plugins/snacks.lua`** — add the picker module:
```lua
opts = {
bigfile = { enabled = true },
quickfile = { enabled = true },
input = { enabled = true },
notifier = { enabled = true, ... }, -- from Phase 2
picker = {
enabled = true,
ui_select = true, -- override vim.ui.select with picker
},
}
```
**New file `lua/absolute/after/snacks.lua`** — replaces the old `after/telescope.lua` and houses the picker keymaps:
```lua
local map = vim.keymap.set
local opts = { noremap = true, silent = true }
map("n", "<C-p>", function() Snacks.picker.files() end, vim.tbl_extend("force", opts, { desc = "Find files" }))
map("n", "<leader>gf", function() Snacks.picker.git_files() end, vim.tbl_extend("force", opts, { desc = "Find git files" }))
map("n", "<leader>pr", function() Snacks.picker.recent() end, vim.tbl_extend("force", opts, { desc = "Recent files" }))
map("n", "<leader>ps", function() Snacks.picker.grep() end, vim.tbl_extend("force", opts, { desc = "Live grep" }))
map("n", "<leader>sb", function() Snacks.picker.grep_word() end, vim.tbl_extend("force", opts, { desc = "Grep word under cursor" }))
map("n", "<leader>pf", function() Snacks.picker.explorer() end, vim.tbl_extend("force", opts, { desc = "File explorer" }))
map("n", "<leader>cf", function() Snacks.picker.explorer({ cwd = vim.fn.expand("%:p:h") }) end, vim.tbl_extend("force", opts, { desc = "File explorer at file dir" }))
```
**Edits to existing files**, swapping `<cmd>Telescope ...<CR>` for `Snacks.picker.*` calls:
| File | Old binding | New binding |
|---|---|---|
| `remap.lua:7` | `<cmd>Telescope keymaps<CR>` | `function() Snacks.picker.keymaps() end` |
| `core/colorscheme.lua:150` | `<cmd>Telescope colorscheme<CR>` | `function() Snacks.picker.colorschemes() end` |
| `core/colorscheme.lua:153` | `<cmd>Telescope themes<CR>` | **delete** the `<leader>th` binding entirely (merged into `<leader>cs`) |
| `after/lsp-config.lua:20` | `<cmd>Telescope lsp_definitions<CR>` | `function() Snacks.picker.lsp_definitions() end` |
| `after/lsp-config.lua:26` | `<cmd>Telescope lsp_implementations<CR>` | `function() Snacks.picker.lsp_implementations() end` |
| `after/lsp-config.lua:38` | `<cmd>Telescope lsp_type_definitions<CR>` | `function() Snacks.picker.lsp_type_definitions() end` |
| `after/lsp-config.lua:47` | `<cmd>Telescope lsp_references<CR>` | `function() Snacks.picker.lsp_references() end` |
| `after/todo-comments.lua:18-20` | `vim.cmd([[TodoTelescope]])` | `Snacks.picker.todo_comments()` |
### Things lost in Phase 3
1. **DAP picker** (`telescope-dap`) — DAP itself works; the picker UI for breakpoints/variables is gone. `nvim-dap-ui` already covers most of this.
2. **`live-grep-args` argument syntax** — snacks accepts `--type lua` style args via a slightly different prompt prefix; muscle-memory shifts.
3. **Custom `telescope_image_preview.lua`** — dropped. snacks displays images natively via `image.nvim` integration in its file picker.
4. **`telescope-themes` registry helpers** — `<leader>th` is dropped. `<leader>cs` (colorschemes picker) replaces both. The `theme-registry.lua` system continues to work because it hooks `ColorScheme` autocmds, which fire regardless of how the colorscheme is selected.
### Phase 3 net change
- ~14 plugins removed from lockfile (8 from `nvim-cmp` chain, 7 from `telescope` chain — `friendly-snippets` stays)
- 5 files deleted (`plugins/nvim-cmp.lua`, `after/nvim-cmp.lua`, `plugins/telescope.lua`, `after/telescope.lua`, `utils/telescope_image_preview.lua`)
- 3 files added (`plugins/blink-cmp.lua`, `after/blink-cmp.lua`, `after/snacks.lua`)
- 5 files edited (`plugins/snacks.lua`, `after/lsp-config.lua`, `core/colorscheme.lua`, `remap.lua`, `after/todo-comments.lua`)
### Phase 3 validation
1. Restart Neovim. No errors on startup.
2. Open an insert-mode completion (`<C-Space>` in a code file) — blink menu appears with LSP, snippets, path, buffer sources.
3. Trigger snippet expansion (e.g. `for<Tab>` in Lua) — friendly-snippets fire via blink's snippet engine.
4. `<C-p>` opens snacks file picker and previews work.
5. `<leader>ps` opens live grep; `<leader>sb` greps the word under cursor.
6. LSP `gd` / `gi` / `gt` / `<leader>cr` open snacks LSP pickers.
7. `<leader>cs` opens colorscheme picker; selecting a theme triggers the wezterm/ghostty sync.
8. `<leader>?` opens keymaps picker.
9. `:checkhealth blink.cmp` is clean.
---
## Risk and rollback
Each phase is one commit. To roll a phase back, `git revert <sha>` and `:Lazy sync` to restore the prior plugin set. Because each phase ends in a working state, partial rollback (e.g. revert Phase 3 but keep Phases 1 and 2) is safe.
The highest-risk single change is the LSP-capabilities provider swap in `after/lsp-config.lua` (Phase 3a). If LSP completion misbehaves after Phase 3, isolate by temporarily reverting just that one line to the cmp-nvim-lsp provider and bisecting the blink.cmp config.
## Open items deferred
- Treesitter `master` → `main` rewrite (Neovim 0.12-only). Worth its own spec when ready.
- Replacing `nvim-tmux-navigation` configuration file naming (the spec file is `vim-tmux-navigator.lua` but the plugin is `alexghergh/nvim-tmux-navigation`). Cosmetic; not part of this work.
- Auditing the seven intentionally-disabled plugin specs. Out of scope.
## Acceptance criteria
After all three phases land:
1. `:checkhealth` reports no deprecated API usage related to this work.
2. `lazy-lock.json` no longer contains: `nvim-cmp`, `cmp-*`, `lspkind.nvim`, `LuaSnip`, `telescope.nvim`, `telescope-*`, `popup.nvim`, `nvim-notify`, `dressing.nvim`, `playground`, `vim-maximizer`, `poet-v`, `git-blame.nvim`, `render-markdown.nvim`, `codecompanion.nvim`, `copilot.vim`, `gen.nvim`, `llm.nvim`, `opencode.nvim`.
3. `lazy-lock.json` newly contains: `blink.cmp`, `snacks.nvim`.
4. Every keymap in the migration tables resolves to a working snacks.picker or blink.cmp action.
5. Diagnostic gutter signs render through `vim.diagnostic.config`.
6. `<leader>j` and `<leader>k` resize the current window with no collision.
7. Startup time as reported by `:Lazy profile` is no worse than before.
+38 -65
View File
@@ -1,78 +1,51 @@
{
"Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" },
"LuaSnip": { "branch": "master", "commit": "831a130291eb6dae0dabd2748d0a99401a2eebc4" },
"catppuccin": { "branch": "main", "commit": "fa42eb5e26819ef58884257d5ae95dd0552b9a66" },
"cheatsheet.nvim": { "branch": "master", "commit": "9716f9aaa94dd1fd6ce59b5aae0e5f25e2a463ef" },
"cmp-buffer": { "branch": "main", "commit": "b74fab3656eea9de20a9b8116afa3cfc4ec09657" },
"cmp-cmdline": { "branch": "main", "commit": "d126061b624e0af6c3a556428712dd4d4194ec6d" },
"cmp-path": { "branch": "main", "commit": "e52e640b7befd8113b3350f46e8cfcfe98fcf730" },
"cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" },
"codecompanion.nvim": { "branch": "main", "commit": "99448f47c3e23a06009ac176ba4c785e162d9c10" },
"conform.nvim": { "branch": "master", "commit": "973f3cb73887d510321653044791d7937c7ec0fa" },
"copilot.vim": { "branch": "release", "commit": "12995dffe10282b29b8335650bf3e7457f4870e7" },
"dressing.nvim": { "branch": "master", "commit": "2d7c2db2507fa3c4956142ee607431ddb2828639" },
"blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" },
"catppuccin": { "branch": "main", "commit": "edefef779ab08ce1a4a404713e3012b0d202bd35" },
"conform.nvim": { "branch": "master", "commit": "016802de402556da54c36bd7359b441266b01cdd" },
"flash.nvim": { "branch": "main", "commit": "3c942666f115e2811e959eabbdd361a025db8b63" },
"flutter-tools.nvim": { "branch": "main", "commit": "70430c32d176f4a15c6e2c80586cd2791e3a664e" },
"friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" },
"fzf": { "branch": "master", "commit": "ead302981cc9d9219e58c1517921e9f2d68a6b6e" },
"gen.nvim": { "branch": "main", "commit": "e09a8dbffa139ad60d5b47998fcc8669ead1ebf4" },
"git-blame.nvim": { "branch": "master", "commit": "8503b199edf9a666fe7b1a989cf14e3c26b2eb03" },
"gitignore.nvim": { "branch": "master", "commit": "0344f643768c4d64af4add8c1bdddf6f7d4c9010" },
"gitsigns.nvim": { "branch": "main", "commit": "0cb5a7753d3c4b8e9cfdc9d88d9110cb8d4b1544" },
"image.nvim": { "branch": "master", "commit": "4c51d6202628b3b51e368152c053c3fb5c5f76f2" },
"incline.nvim": { "branch": "main", "commit": "0fd2d5a27504dba7fdc507a53275f22c081fe640" },
"indent-blankline.nvim": { "branch": "master", "commit": "005b56001b2cb30bfa61b7986bc50657816ba4ba" },
"lazy.nvim": { "branch": "main", "commit": "6c3bda4aca61a13a9c63f1c1d1b16b9d3be90d7a" },
"llm.nvim": { "branch": "main", "commit": "9832a149bdcf0709433ca9c2c3a1c87460e98d13" },
"lspkind.nvim": { "branch": "master", "commit": "d79a1c3299ad0ef94e255d045bed9fa26025dab6" },
"lualine.nvim": { "branch": "master", "commit": "a94fc68960665e54408fe37dcf573193c4ce82c9" },
"markview.nvim": { "branch": "main", "commit": "ec33f2aa333ca1d76f51847922578434d7aeadf7" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "bb3a17efc797c34c054463174e5522442576ebd8" },
"mason-registry": { "branch": "main", "commit": "467ac84d138997773be67e2e5bd4020cb96a3697" },
"mason.nvim": { "branch": "main", "commit": "8024d64e1330b86044fed4c8494ef3dcd483a67c" },
"mcphub.nvim": { "branch": "main", "commit": "0d53a53f327b61c45691d6a60a16c20baf4590ea" },
"mini.diff": { "branch": "main", "commit": "63a7ce537ced356b8180892d9586826b0afb519c" },
"friendly-snippets": { "branch": "main", "commit": "b4d01b0fdf3c9a549961c2f9ffe8dc09be166219" },
"fzf": { "branch": "master", "commit": "25adb674537bb2140f82602651a31fbd7677cd50" },
"gitsigns.nvim": { "branch": "main", "commit": "851a051e2bd2caba97e23314c68d69f1b1cf5d19" },
"image.nvim": { "branch": "master", "commit": "365e2ace0f619164ae6fd2f6f1d2807775dd6849" },
"incline.nvim": { "branch": "main", "commit": "debd628e9395f7a9da57bdc31ce75ca6b40a880b" },
"indent-blankline.nvim": { "branch": "master", "commit": "f1e186e44d3b7f9ae918008e2c28ce37c6023d2d" },
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
"lualine.nvim": { "branch": "master", "commit": "221ce6b2d999187044529f49da6554a92f740a96" },
"markview.nvim": { "branch": "main", "commit": "49d2cf7ced872db74083a144ded1f94fe224d09a" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "e17625cdc8c2650787467398e02c5d63a2cde966" },
"mason-registry": { "branch": "main", "commit": "ee10e9db59f13054eea925042cae6d1df461ec25" },
"mason.nvim": { "branch": "main", "commit": "2a6940af80375532e5e9e7c1f2fc6319a1b7a69d" },
"mini.diff": { "branch": "main", "commit": "626b8a5b93874c4d05ca25aedec56cfff0b378fb" },
"mini.nvim": { "branch": "main", "commit": "0420076298c4457f200c2de468f65d080597a347" },
"nightfly": { "branch": "master", "commit": "8c55003e89f321a48a8cd4bb426dd3e7c58f0646" },
"nvim-bqf": { "branch": "main", "commit": "dd17c73912487dccb372deff85d4262d2b89bc2b" },
"nvim-cmp": { "branch": "main", "commit": "b5311ab3ed9c846b585c0c15b7559be131ec4be9" },
"nvim-dap": { "branch": "master", "commit": "5dd4d50f2e6a2eaf9e57fad023d294ef371bda35" },
"nvim-dap-python": { "branch": "master", "commit": "261ce649d05bc455a29f9636dc03f8cdaa7e0e2c" },
"nvim-dap-ui": { "branch": "master", "commit": "cf91d5e2d07c72903d052f5207511bf7ecdb7122" },
"nightfly": { "branch": "master", "commit": "2c31d07ce05efa92bcb7f893f9c74a846226c898" },
"nvim-bqf": { "branch": "main", "commit": "c282a62bec6c0621a1ef5132aa3f4c9fc4dcc2c7" },
"nvim-dap": { "branch": "master", "commit": "cfa2d58f4537aca6ca83e2de1a0d9f1491121264" },
"nvim-dap-ui": { "branch": "master", "commit": "cc9dd33aade7f20bae414d0cba163bc60d4d4b43" },
"nvim-dap-virtual-text": { "branch": "master", "commit": "fbdb48c2ed45f4a8293d0d483f7730d24467ccb6" },
"nvim-highlight-colors": { "branch": "main", "commit": "b42a5ccec7457b44e89f7ed3b3afb1b375bb2093" },
"nvim-lsp-file-operations": { "branch": "master", "commit": "9744b738183a5adca0f916527922078a965515ed" },
"nvim-lspconfig": { "branch": "master", "commit": "f47cd681d7cb6048876a2e908b6d8ba1e530d152" },
"nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" },
"nvim-notify": { "branch": "master", "commit": "a22f5d7ac511c2df2fd3290a9f04c48d5a822e2e" },
"nvim-highlight-colors": { "branch": "main", "commit": "e4c7af0211866162d999ce0bdd6a029302e19139" },
"nvim-lsp-file-operations": { "branch": "master", "commit": "72ea1d0fb1e5be0b4434ad794c8e0bb46d4df64c" },
"nvim-lspconfig": { "branch": "master", "commit": "c59fc922f718fa055f69f5f3bc888f23211571eb" },
"nvim-nio": { "branch": "master", "commit": "edcc181a875301dd21840189aa2f2f9ad69fc172" },
"nvim-silicon": { "branch": "main", "commit": "7f66bda8f60c97a5bf4b37e5b8acb0e829ae3c32" },
"nvim-surround": { "branch": "main", "commit": "ae298105122c87bbe0a36b1ad20b06d417c0433e" },
"nvim-tmux-navigation": { "branch": "main", "commit": "4898c98702954439233fdaf764c39636681e2861" },
"nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" },
"nvim-treesitter-context": { "branch": "master", "commit": "59f318a65d42a5c4037796886a8874fd57f774fc" },
"nvim-web-devicons": { "branch": "master", "commit": "0422a19d9aa3aad2c7e5cca167e5407b13407a9d" },
"nvim_lsp": { "branch": "main", "commit": "a8912b88ce488f411177fc8aed358b04dc246d7b" },
"nvim-treesitter": { "branch": "master", "commit": "cf12346a3414fa1b06af75c79faebe7f76df080a" },
"nvim-treesitter-context": { "branch": "master", "commit": "8decd73460d26ef0a0befb745d022dd1fc2c38b8" },
"nvim-web-devicons": { "branch": "master", "commit": "58447c1fca354bbf184425e4a8d01deecbd6f3c4" },
"pkl-neovim": { "branch": "main", "commit": "da9d189b4fad7e67e6b2a5456a3cbc4c9d32a17f" },
"playground": { "branch": "master", "commit": "ba48c6a62a280eefb7c85725b0915e021a1a0749" },
"plenary.nvim": { "branch": "master", "commit": "857c5ac632080dba10aae49dba902ce3abf91b35" },
"poet-v": { "branch": "master", "commit": "85a5dd44d89602cc3dccd2489924e9c7caab0044" },
"popup.nvim": { "branch": "master", "commit": "b7404d35d5d3548a82149238289fa71f7f6de4ac" },
"render-markdown.nvim": { "branch": "main", "commit": "7620d4e96eb5cf8d12e76c6fcaf1267628564ba9" },
"rose-pine": { "branch": "main", "commit": "72befaffeac38db7bdd49e0549eaa2c4806dd878" },
"plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" },
"rose-pine": { "branch": "main", "commit": "ff483051a47e27d84bdef47703538df1ed9f4a47" },
"smear-cursor.nvim": { "branch": "main", "commit": "4a0f7ac265b4ed1ce4d0af2afc13072763bfa691" },
"snacks.nvim": { "branch": "main", "commit": "882c996cf28183f4d63640de0b4c02ec886d01f2" },
"tailwind-sorter.nvim": { "branch": "main", "commit": "717e5c9761ed8334dadbb9357df7d826aae97b92" },
"telescope-dap.nvim": { "branch": "master", "commit": "783366bd6c1e7fa0a5c59c07db37f49c805a28df" },
"telescope-file-browser.nvim": { "branch": "master", "commit": "7bf55ed0ff5be182ad3301cff266581fc1c56cce" },
"telescope-live-grep-args.nvim": { "branch": "master", "commit": "8ad632f793fd437865f99af5684f78300dac93fb" },
"telescope-media-files.nvim": { "branch": "master", "commit": "0826c7a730bc4d36068f7c85cf4c5b3fd9fb570a" },
"telescope-themes": { "branch": "main", "commit": "65721365bd7a04a6c9679e76b6387b60320fd5f3" },
"telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" },
"todo-comments.nvim": { "branch": "main", "commit": "304a8d204ee787d2544d8bc23cd38d2f929e7cc5" },
"todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" },
"toggleterm.nvim": { "branch": "main", "commit": "50ea089fc548917cc3cc16b46a8211833b9e3c7c" },
"tokyonight": { "branch": "main", "commit": "057ef5d260c1931f1dffd0f052c685dcd14100a3" },
"tree-sitter-ghostty": { "branch": "main", "commit": "1d5238fc0da5fd5a59130b95c3e1c4948a3f96c1" },
"treesj": { "branch": "main", "commit": "3b4a2bc42738a63de17e7485d4cc5e49970ddbcc" },
"trouble.nvim": { "branch": "main", "commit": "85bedb7eb7fa331a2ccbecb9202d8abba64d37b3" },
"undotree": { "branch": "master", "commit": "28f2f54a34baff90ea6f4a735ef1813ad875c743" },
"venv-selector.nvim": { "branch": "regexp", "commit": "c677caa1030808a9f90092e522de7cc20c1390dd" },
"vim-maximizer": { "branch": "master", "commit": "2e54952fe91e140a2e69f35f22131219fcd9c5f1" }
"tokyonight": { "branch": "main", "commit": "cdc07ac78467a233fd62c493de29a17e0cf2b2b6" },
"tree-sitter-ghostty": { "branch": "main", "commit": "a2075c3761a41449bb4faf69794c902dfef6d70e" },
"treesj": { "branch": "main", "commit": "9f349ba62c524f065d6f43254d731ddf8319b9bf" },
"trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" },
"undotree": { "branch": "master", "commit": "6fa6b57cda8459e1e4b2ca34df702f55242f4e4d" },
"venv-selector.nvim": { "branch": "main", "commit": "cc4bb3975de8835291f9bb45889e96c6b2795fc4" }
}
+14
View File
@@ -0,0 +1,14 @@
require("blink.cmp").setup({
keymap = { preset = "default" },
appearance = {
nerd_font_variant = "mono",
},
sources = {
default = { "lsp", "path", "snippets", "buffer" },
},
cmdline = {
keymap = { preset = "cmdline" },
completion = { menu = { auto_show = true } },
},
signature = { enabled = true },
})
-9
View File
@@ -1,9 +0,0 @@
local cheatsheet = require("cheatsheet")
cheatsheet.setup({})
local opts = { noremap = true, silent = true }
opts.desc = "Show Cheatsheet"
vim.keymap.set("n", "<leader>\\", "<cmd>Cheatsheet<CR>", opts) -- toggle file explorer
-40
View File
@@ -1,40 +0,0 @@
local codecompanion = require("codecompanion")
codecompanion.setup({
strategies = {
chat = {
adapter = "openai",
},
},
extensions = {
mcphub = {
callback = "mcphub.extensions.codecompanion",
opts = {
make_vars = true,
make_slash_commands = true,
show_result_in_chat = true,
},
},
},
})
local opts = {
noremap = true,
silent = true,
}
vim.keymap.set("n", "<leader>ac", function()
vim.cmd("CodeCompanionChat")
end, opts)
vim.keymap.set({ "n", "v" }, "<leader>ai", function()
local input = vim.fn.input("[Code Companion Inline]: ")
local trimmed_input = vim.fn.trim(input)
if trimmed_input == "" then
vim.notify("No input provided for inline code companion", vim.log.levels.WARN)
return
end
vim.cmd("CodeCompanion" .. " " .. vim.fn.shellescape(trimmed_input))
end, opts)
-36
View File
@@ -1,36 +0,0 @@
local gen = require("gen")
gen.setup({
-- Custom Parameters (with defaults)
model = "deepseek-r1:7b", -- The default model to use.
quit_map = "q", -- set keymap to close the response window
retry_map = "<c-r>", -- set keymap to re-send the current prompt
accept_map = "<c-cr>", -- set keymap to replace the previous selection with the last result
host = "localhost", -- The host running the Ollama service.
port = "11434", -- The port on which the Ollama service is listening.
display_mode = "split", -- The display mode. Can be "float" or "split" or "horizontal-split".
show_prompt = false, -- Shows the prompt submitted to Ollama. Can be true (3 lines) or "full".
show_model = false, -- Displays which model you are using at the beginning of your chat session.
no_auto_close = false, -- Never closes the window automatically.
file = false, -- Write the payload to a temporary file to keep the command short.
hidden = false, -- Hide the generation window (if true, will implicitly set `prompt.replace = true`), requires Neovim >= 0.10
init = function(options)
pcall(io.popen, "ollama serve > /dev/null 2>&1 &")
end,
-- Function to initialize Ollama
command = function(options)
local body = { model = options.model, stream = true }
return "curl --silent --no-buffer -X POST http://"
.. options.host
.. ":"
.. options.port
.. "/api/chat -d $body"
end,
-- The command for the Ollama service. You can use placeholders $prompt, $model and $body (shellescaped).
-- This can also be a command string.
-- The executed command must return a JSON object with { response, context }
-- (context property is optional).
-- list_models = '<omitted lua function>', -- Retrieves a list of model names
result_filetype = "markdown", -- Configure filetype of the result buffer
debug = false, -- Prints errors and the command which is run.
})
-18
View File
@@ -1,18 +0,0 @@
local gitignore = require("gitignore")
local GetProjectRoot = require("absolute.utils.get-git-root")
-- Keymaps
local opts = { noremap = true, silent = true }
opts.desc = "GitIgnore: Generate .gitignore"
vim.keymap.set("n", "<leader>gi", function()
local path = GetProjectRoot()
gitignore.generate(path)
end, opts)
-- Global Settings
vim.g.gitignore_nvim_overwrite = true
+8 -1
View File
@@ -1,3 +1,10 @@
local gitsigns = require("gitsigns")
gitsigns.setup()
gitsigns.setup({
current_line_blame = true,
current_line_blame_opts = {
virt_text_pos = "eol",
delay = 500,
ignore_whitespace = false,
},
})
-105
View File
@@ -1,105 +0,0 @@
local llm = require("llm")
local llmCompletion = require("llm.completion")
llm.setup({
api_token = nil, -- cf Install paragraph
model = "codellama:13b", -- the model ID, behavior depends on backend
backend = "ollama", -- backend ID, "huggingface" | "ollama" | "openai" | "tgi"
url = "http://localhost:11434", -- the http url of the backend
-- tokens_to_clear = { "<|endoftext|>" }, -- tokens to remove from the model's output
tokens_to_clear = { "<EOT>" },
-- parameters that are added to the request body, values are arbitrary, you can set any field:value pair here it will be passed as is to the backend
request_body = {
parameters = {
-- max_new_tokens = 60,
temperature = 0.2,
top_p = 0.95,
},
},
-- set this if the model supports fill in the middle
-- fim = {
-- enabled = false,
-- prefix = "<fim_prefix>",
-- middle = "<fim_middle>",
-- suffix = "<fim_suffix>",
-- },
fim = {
enabled = true,
prefix = "<PRE> ",
middle = " <MID>",
suffix = " <SUF>",
},
debounce_ms = 150,
accept_keymap = nil,
dismiss_keymap = nil,
tls_skip_verify_insecure = false,
-- llm-ls configuration, cf llm-ls section
lsp = {
bin_path = vim.api.nvim_call_function("stdpath", { "data" }) .. "/mason/bin/llm-ls",
cmd_env = { LLM_LOG_LEVEL = "DEBUG" },
},
-- tokenizer = nil, -- cf Tokenizer paragraph
tokenizer = {
repository = "codellama/CodeLlama-13b-hf",
},
context_window = 4096,
enable_suggestions_on_startup = false,
enable_suggestions_on_files = { "*.py", "*.js", "*.ts", "*.astro", "*.vue", "*.lua" },
disable_url_path_completion = false, -- cf Backend
})
vim.keymap.set("i", "<Tab>", function()
if llmCompletion.shown_suggestion ~= nil then
llmCompletion.complete()
else
local keys = vim.api.nvim_replace_termcodes("<Tab>", true, false, true)
vim.api.nvim_feedkeys(keys, "n", false)
end
end, { noremap = true, silent = true })
vim.keymap.set("n", "<Tab>", function()
if llmCompletion.shown_suggestion ~= nil then
llmCompletion.complete()
else
local keys = vim.api.nvim_replace_termcodes("<Tab>", true, false, true)
vim.api.nvim_feedkeys(keys, "n", false)
end
end, { noremap = true, silent = true })
-- Debounce helper
local debounce = function(func, timeout)
if type(func) ~= "function" then
error("Expected a function")
end
if type(timeout) ~= "number" or timeout <= 0 then
error("Expected a positive number for timeout")
end
local timer = vim.uv.new_timer()
return function(...)
local args = { ... }
timer:stop() -- Reset the timer
timer:start(
timeout,
0,
vim.schedule_wrap(function()
func(unpack(args))
end)
)
end
end
-- Define the function to be executed
local function on_text_change()
llmCompletion.lsp_suggest()
end
-- Debounce the function
local debounced_on_text_change = debounce(on_text_change, 3000)
-- Set up the autocommand
vim.api.nvim_create_autocmd({ "InsertCharPre" }, {
pattern = "*",
callback = debounced_on_text_change,
desc = "Run method after typing stops with debounce",
})
+64 -85
View File
@@ -1,7 +1,5 @@
-- Setup language servers.
local conform = require("conform")
local lspconfig = require("lspconfig")
local cmp_nvim_lsp = require("cmp_nvim_lsp")
local opts = { noremap = true, silent = true }
@@ -18,13 +16,13 @@ local on_attach = function(client, bufnr)
vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts)
opts.desc = "Go to definitions"
vim.keymap.set("n", "gd", "<cmd>Telescope lsp_definitions<CR>", opts)
vim.keymap.set("n", "gd", function() Snacks.picker.lsp_definitions() end, opts)
opts.desc = "Show documentation for what is under cursor"
vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)
opts.desc = "Show LSP Implementation"
vim.keymap.set("n", "gi", "<cmd>Telescope lsp_implementations<CR>", opts)
vim.keymap.set("n", "gi", function() Snacks.picker.lsp_implementations() end, opts)
opts.desc = "Get Help"
vim.keymap.set("n", "<leader>gh", vim.lsp.buf.signature_help, opts)
@@ -36,7 +34,7 @@ local on_attach = function(client, bufnr)
-- end, opts)
opts.desc = "Show LSP type definitions"
vim.keymap.set("n", "gt", "<cmd>Telescope lsp_type_definitions<CR>", opts)
vim.keymap.set("n", "gt", function() Snacks.picker.lsp_type_definitions() end, opts)
opts.desc = "Smart rename"
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts)
@@ -45,7 +43,7 @@ local on_attach = function(client, bufnr)
vim.keymap.set({ "n", "v" }, "<leader>ca", vim.lsp.buf.code_action, opts)
opts.desc = "Show LSP references"
vim.keymap.set("n", "<leader>cr", "<cmd>Telescope lsp_references<CR>", opts)
vim.keymap.set("n", "<leader>cr", function() Snacks.picker.lsp_references() end, opts)
opts.desc = "Format File"
vim.keymap.set({ "n", "v" }, "<leader>f", function()
@@ -68,29 +66,27 @@ local on_attach = function(client, bufnr)
end
end
local capabilities = cmp_nvim_lsp.default_capabilities()
local capabilities = require("blink.cmp").get_lsp_capabilities()
-- Change the Diagnostic symbols in the sign column (gutter)
local signs = {
Error = "",
Warn = "",
Hint = "󰠠 ",
Info = " ",
}
-- Configure diagnostic signs (Neovim 0.10+ API; required in 0.12)
vim.diagnostic.config({
signs = {
text = {
[vim.diagnostic.severity.ERROR] = " ",
[vim.diagnostic.severity.WARN] = " ",
[vim.diagnostic.severity.HINT] = "󰠠 ",
[vim.diagnostic.severity.INFO] = "",
},
},
})
for type, icon in pairs(signs) do
local hl = "DiagnosticSign" .. type
vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = "" })
end
-- configure html server
lspconfig["html"].setup({
-- Configure LSP servers using vim.lsp.config
vim.lsp.config("html", {
capabilities = capabilities,
on_attach = on_attach,
})
-- configure typescript server with plugin
lspconfig["ts_ls"].setup({
vim.lsp.config("ts_ls", {
capabilities = capabilities,
on_attach = on_attach,
init_options = {
@@ -105,21 +101,18 @@ lspconfig["ts_ls"].setup({
filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact", "vue" },
})
-- configure css server
lspconfig["cssls"].setup({
vim.lsp.config("cssls", {
capabilities = capabilities,
on_attach = on_attach,
})
-- configure tailwindcss server
lspconfig["tailwindcss"].setup({
vim.lsp.config("tailwindcss", {
capabilities = capabilities,
on_attach = on_attach,
filetypes = { "html", "svelte", "vue", "astro" },
})
-- configure svelte server
lspconfig["svelte"].setup({
vim.lsp.config("svelte", {
capabilities = capabilities,
on_attach = function(client, bufnr)
on_attach(client, bufnr)
@@ -135,8 +128,7 @@ lspconfig["svelte"].setup({
end,
})
-- configure emmet language server
lspconfig["emmet_ls"].setup({
vim.lsp.config("emmet_ls", {
capabilities = capabilities,
on_attach = on_attach,
filetypes = {
@@ -153,14 +145,12 @@ lspconfig["emmet_ls"].setup({
},
})
-- configure ruff server
lspconfig["ruff"].setup({
vim.lsp.config("ruff", {
capabilities = capabilities,
on_attach = on_attach,
})
-- configure pyright server
lspconfig["pyright"].setup({
vim.lsp.config("pyright", {
capabilities = capabilities,
on_attach = on_attach,
filetypes = { "python" },
@@ -175,20 +165,17 @@ lspconfig["pyright"].setup({
},
})
-- configure docker server
lspconfig["dockerls"].setup({
vim.lsp.config("dockerls", {
capabilities = capabilities,
on_attach = on_attach,
})
-- configure json server
lspconfig["jsonls"].setup({
vim.lsp.config("jsonls", {
capabilities = capabilities,
on_attach = on_attach,
})
-- configure vue server
lspconfig["volar"].setup({
vim.lsp.config("vue_ls", {
capabilities = capabilities,
on_attach = on_attach,
filetypes = { "vue" },
@@ -221,9 +208,7 @@ lspconfig["volar"].setup({
},
})
-- configure rust server
lspconfig.rust_analyzer.setup({
-- Server-specific settings. See `:help lspconfig-setup`
vim.lsp.config("rust_analyzer", {
on_attach = on_attach,
capabilities = capabilities,
settings = {
@@ -231,18 +216,15 @@ lspconfig.rust_analyzer.setup({
},
})
-- configure lua server (with special settings)
lspconfig["lua_ls"].setup({
vim.lsp.config("lua_ls", {
capabilities = capabilities,
on_attach = on_attach,
settings = { -- custom settings for lua
settings = {
Lua = {
-- make the language server recognize "vim" global
diagnostics = {
globals = { "vim" },
},
workspace = {
-- make language server aware of runtime files
library = {
[vim.fn.expand("$VIMRUNTIME/lua")] = true,
[vim.fn.stdpath("config") .. "/lua"] = true,
@@ -252,73 +234,45 @@ lspconfig["lua_ls"].setup({
},
})
-- configure css server
lspconfig["cssls"].setup({
vim.lsp.config("docker_compose_language_service", {
capabilities = capabilities,
on_attach = on_attach,
})
--configure docker file server
lspconfig["dockerls"].setup({
vim.lsp.config("eslint", {
capabilities = capabilities,
on_attach = on_attach,
})
-- configure docker compose server
lspconfig["docker_compose_language_service"].setup({
vim.lsp.config("astro", {
capabilities = capabilities,
on_attach = on_attach,
})
-- configure eslint server
lspconfig["eslint"].setup({
vim.lsp.config("kotlin_language_server", {
capabilities = capabilities,
on_attach = on_attach,
})
-- configure astro server
lspconfig["astro"].setup({
capabilities = capabilities,
on_attach = on_attach,
-- init_options = {
-- typescript = {
-- tsdk = ResolveTypescriptServer(),
-- },
-- },
})
-- configure kotlin server
lspconfig["kotlin_language_server"].setup({
capabilities = capabilities,
on_attach = on_attach,
})
-- configure clang server
lspconfig["clangd"].setup({
vim.lsp.config("clangd", {
cmd = { "clangd", "--compile-commands-dir=./", "--background-index=false" },
capabilities = capabilities,
on_attach = on_attach,
filetypes = { "c", "cpp", "objc", "objcpp" },
})
-- configure bufls server
lspconfig["buf_ls"].setup({
vim.lsp.config("buf_ls", {
capabilities = capabilities,
on_attach = on_attach,
filetypes = { "proto" },
})
-- configure arduino language server
lspconfig["arduino_language_server"].setup({
vim.lsp.config("arduino_language_server", {
capabilities = capabilities,
on_attach = on_attach,
})
-- configure biome server
lspconfig["biome"].setup({
vim.lsp.config("biome", {
capabilities = capabilities,
on_attach = on_attach,
filetypes = {
@@ -334,3 +288,28 @@ lspconfig["biome"].setup({
"vue",
},
})
-- Enable all configured LSP servers
vim.lsp.enable({
"html",
"ts_ls",
"cssls",
"tailwindcss",
"svelte",
"emmet_ls",
"ruff",
"pyright",
"dockerls",
"jsonls",
"vue_ls",
"rust_analyzer",
"lua_ls",
"docker_compose_language_service",
"eslint",
"astro",
"kotlin_language_server",
"clangd",
"buf_ls",
"arduino_language_server",
"biome",
})
-25
View File
@@ -1,25 +0,0 @@
local notify = require("notify")
notify.setup({
background_colour = "#000000",
fps = 15,
icons = {
DEBUG = "",
ERROR = "",
INFO = "",
TRACE = "✎",
WARN = "",
},
level = 2,
minimum_width = 50,
render = "default",
stages = "static",
time_formats = {
notification = "%T",
notification_history = "%FT%T",
},
timeout = 3000,
top_down = true,
})
vim.notify = notify
-72
View File
@@ -1,72 +0,0 @@
local cmp = require("cmp")
local types = require("cmp.types")
local luasnip = require("luasnip")
local lspkind = require("lspkind")
-- loads vscode style snippets from installed plugins (e.g. friendly-snippets)
require("luasnip.loaders.from_vscode").lazy_load()
cmp.setup({
completion = {
completeopt = "menu,menuone,preview,noinsert,noselect",
autocomplete = { types.cmp.TriggerEvent.TextChanged },
},
window = {
documentation = {
border = { "┌", "─", "┐", "│", "┘", "─", "└", "│" },
winhighlight = "Normal:CmpPmenu,FloatBorder:CmpPmenuBorder,CursorLine:PmenuSel,Search:None",
},
completion = {
side_padding = 1,
border = { "┌", "─", "┐", "│", "┘", "─", "└", "│" },
winhighlight = "Normal:CmpPmenu,FloatBorder:CmpPmenuBorder,CursorLine:PmenuSel,Search:None",
scrollbar = false,
},
},
snippet = { -- configure how nvim-cmp interacts with snippet engine
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
mapping = cmp.mapping.preset.insert({
["<C-.>"] = cmp.mapping.complete(), -- show completion suggestions
["C-<BS>"] = cmp.mapping.abort(), -- close completion menu
["<CR>"] = cmp.mapping.confirm({ select = true }), -- accept current selection
}),
-- sources for autocompletion
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "codecompanion" }, -- code companion for AI-assisted coding
{ name = "luasnip" }, -- snippets
{ name = "buffer" }, -- text within current buffer
{ name = "path" }, -- file system paths,
{ name = "nvim_lsp_signature_help" },
}),
-- configure lspkind for vs-code like pictograms in completion menu
formatting = {
format = lspkind.cmp_format({
maxwidth = 50,
ellipsis_char = "...",
}),
},
})
-- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore).
cmp.setup.cmdline({ "/", "?" }, {
mapping = cmp.mapping.preset.cmdline(),
sources = {
{ name = "buffer" },
},
})
-- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore).
cmp.setup.cmdline(":", {
mapping = cmp.mapping.preset.cmdline(),
sources = cmp.config.sources({
{ name = "path" },
}, {
{ name = "cmdline" },
}),
matching = { disallow_symbol_nonprefix_matching = false },
})
-49
View File
@@ -1,49 +0,0 @@
local nvimtree = require("absolute.disabled.nvim-tree")
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
vim.cmd([[ highlight NvimTreeIndentMarker guifg=#3FC5FF ]])
vim.cmd([[ highlight NvimTreeFolderArrowClosed guifg=#3FC5FF ]])
vim.cmd([[ highlight NvimTreeFolderArrowOpen guifg=#3FC5FF ]])
nvimtree.setup({
view = {
width = 45,
relativenumber = true,
},
update_focused_file = {
enable = true,
},
renderer = {
indent_markers = {
enable = true,
},
icons = {
glyphs = {
folder = {
arrow_closed = "", -- arrow when folder is closed
arrow_open = "", -- arrow when folder is open
},
},
},
},
-- disable window_picker for
-- explorer to work well with
-- window splits
actions = {
open_file = {
window_picker = {
enable = false,
},
},
},
filters = {
custom = { ".DS_Store" },
},
git = {
ignore = false,
},
})
-20
View File
@@ -1,20 +0,0 @@
vim.g.poetv_executables = { "poetry" }
vim.g.poetv_auto_activate = 0
vim.g.poetv_set_environment = 1
vim.g.poetv_statusline_symbol = "🐍"
-- Setup Autocommands
vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter" }, {
pattern = { "*/.venv/*", "*.py" },
callback = function()
-- check if poetv is activated
if vim.g.poetv_name ~= nil then
return
else
vim.cmd([[ PoetvActivate ]])
vim.cmd([[ LspRestart ]])
end
end,
})
+33
View File
@@ -0,0 +1,33 @@
local map = vim.keymap.set
local function with_desc(desc)
return { noremap = true, silent = true, desc = desc }
end
map("n", "<C-p>", function()
Snacks.picker.files()
end, with_desc("Find files"))
map("n", "<leader>gf", function()
Snacks.picker.git_files()
end, with_desc("Find git files"))
map("n", "<leader>pr", function()
Snacks.picker.recent()
end, with_desc("Recent files"))
map("n", "<leader>ps", function()
Snacks.picker.grep()
end, with_desc("Live grep"))
map("n", "<leader>sb", function()
Snacks.picker.grep_word()
end, with_desc("Grep word under cursor"))
map("n", "<leader>pf", function()
Snacks.picker.explorer()
end, with_desc("File explorer (cwd)"))
map("n", "<leader>cf", function()
Snacks.picker.explorer({ cwd = vim.fn.expand("%:p:h") })
end, with_desc("File explorer (current file dir)"))
-182
View File
@@ -1,182 +0,0 @@
local telescope = require("telescope")
local builtin = require("telescope.builtin")
local actions = require("telescope.actions")
local trouble = require("trouble.sources.telescope")
local file_browser_actions = require("telescope._extensions.file_browser.actions")
local live_grep_shortcuts = require("telescope-live-grep-args.shortcuts")
local live_grep_actions = require("telescope-live-grep-args.actions")
local image_preview = require("absolute.utils.telescope_image_preview")
-- local function chafa_previewer_mime_hook(filepath, bufnr, opts)
-- local is_image = function(current_filepath)
-- local image_extensions = { "png", "jpg", "jpeg", "gif" } -- Supported image formats
-- local split_path = vim.split(current_filepath:lower(), ".", { plain = true })
-- local extension = split_path[#split_path]
-- return vim.tbl_contains(image_extensions, extension)
-- end
-- if is_image(filepath) then
-- local term = vim.api.nvim_open_term(bufnr, {})
-- local function send_output(_, data, _)
-- for _, d in ipairs(data) do
-- vim.api.nvim_chan_send(term, d .. "\r\n")
-- end
-- end
-- vim.fn.jobstart("chafa --passthrough tmux --exact-size off --format=symbols " .. filepath, {
-- on_stdout = send_output,
-- stdout_buffered = true,
-- })
-- else
-- require("telescope.previewers.utils").set_preview_message(bufnr, opts.winid, "Binary cannot be previewed")
-- end
-- end
telescope.setup({
defaults = {
file_previewer = image_preview.file_previewer,
buffer_previewer_maker = image_preview.buffer_previewer_maker,
vimgrep_arguments = {
"rg",
"--color=never",
"--no-heading",
"--with-filename",
"--line-number",
"--column",
"--smart-case",
"--follow",
"--hidden",
"--glob=!.git/",
},
mappings = {
i = {
["<C-t>"] = trouble.open,
["<C-q>"] = actions.send_to_qflist,
},
n = {
["<C-t>"] = trouble.open,
["<C-q>"] = actions.send_to_qflist,
},
},
},
extensions = {
media_files = {
filetypes = { "png", "webp", "jpg", "jpeg", "svg" },
find_cmd = "rg",
},
live_grep_args = {
auto_quoting = false,
mappings = {
i = {
["C-space"] = live_grep_actions.to_fuzzy_refine,
},
},
},
file_browser = {
hijack_netrw = true,
hide_parent_dir = true,
depth = 1,
respect_gitignore = vim.fn.executable("fd") == 1,
hidden = { file_browser = true, folder_browser = false },
auto_depth = false,
browse_files = require("telescope._extensions.file_browser.finders").browse_files,
display_stat = {
date = true,
size = true,
mode = false,
},
use_fd = true,
git_status = true,
mappings = {
["i"] = {
["<A-c>"] = file_browser_actions.create,
["<S-CR>"] = file_browser_actions.create_from_prompt,
["<A-r>"] = file_browser_actions.rename,
["<A-m>"] = file_browser_actions.move,
["<A-y>"] = file_browser_actions.copy,
["<A-d>"] = file_browser_actions.remove,
["<C-o>"] = file_browser_actions.open,
["<C-g>"] = file_browser_actions.goto_parent_dir,
["<C-e>"] = file_browser_actions.goto_home_dir,
["<C-w>"] = file_browser_actions.goto_cwd,
["<C-t>"] = file_browser_actions.change_cwd,
["<C-f>"] = file_browser_actions.toggle_browser,
["<C-h>"] = file_browser_actions.toggle_hidden,
["<C-s>"] = file_browser_actions.toggle_all,
["<bs>"] = file_browser_actions.backspace,
},
["n"] = {
["c"] = file_browser_actions.create,
["r"] = file_browser_actions.rename,
["m"] = file_browser_actions.move,
["y"] = file_browser_actions.copy,
["d"] = file_browser_actions.remove,
["o"] = file_browser_actions.open,
["g"] = file_browser_actions.goto_parent_dir,
["e"] = file_browser_actions.goto_home_dir,
["w"] = file_browser_actions.goto_cwd,
["t"] = file_browser_actions.change_cwd,
["f"] = file_browser_actions.toggle_browser,
["h"] = file_browser_actions.toggle_hidden,
["s"] = file_browser_actions.toggle_all,
},
},
},
},
})
telescope.load_extension("live_grep_args")
telescope.load_extension("file_browser")
telescope.load_extension("media_files")
telescope.load_extension("themes")
telescope.load_extension("dap")
local find_files = function()
builtin.find_files({
find_command = { "rg", "--files", "--hidden", "--glob", "!.git" },
})
end
local default_grep_files = function()
local input = vim.fn.input("[Global Search]: ")
local trimmed_input = vim.fn.trim(input)
-- Check the length of the input
local live_grep_args = telescope.extensions.live_grep_args
-- If the input is empty open the search prompt
if trimmed_input == "" then
live_grep_args.live_grep_args()
return
end
builtin.grep_string({ search = trimmed_input })
end
-- Function to get the visually selected text
-- Pipe the visual selection into Telescope find_files
local opts = { noremap = true, silent = true }
opts.desc = "Open file browser (cwd)"
vim.keymap.set("n", "<leader>pf", "<cmd>Telescope file_browser<CR>", opts)
opts.desc = "Open file browser (current file)"
vim.keymap.set("n", "<leader>cf", "<cmd>Telescope file_browser path=%:p:h select_buffer=true<CR>", opts)
opts.desc = "Fuzzy find files (cwd)"
vim.keymap.set("n", "<C-p>", find_files, opts)
opts.desc = "Fuzzy find recent files"
vim.keymap.set("n", "<leader>pr", builtin.oldfiles, opts)
opts.desc = "Fuzzy find files in git in cwd"
vim.keymap.set("n", "<leader>gf", builtin.git_files, opts)
opts.desc = "Fuzzy find files in cwd"
vim.keymap.set("n", "<leader>ps", default_grep_files, opts)
opts.desc = "Fuzzy find word under cursor in cwd"
vim.keymap.set("n", "<leader>sb", live_grep_shortcuts.grep_word_under_cursor, opts)
+2 -2
View File
@@ -14,9 +14,9 @@ vim.keymap.set("n", "]t", function()
todo_comments.jump_next()
end, opts)
opts.desc = "Open Comments in Telescope"
opts.desc = "Open todo comments in picker"
vim.keymap.set("n", "<leader>pt", function()
vim.cmd([[TodoTelescope]])
Snacks.picker.todo_comments()
end, opts)
opts.desc = "Open Comments in Trouble"
+21 -22
View File
@@ -1,3 +1,5 @@
local ThemeRegistry = require("absolute.core.theme-registry")
local function SetupWindowPreferences()
-- Utility function to get the blend value or set a default
local function get_blend_value(group_name, default_blend)
@@ -20,24 +22,15 @@ local function SetupWindowPreferences()
end
local function SyncWezTerm()
local colorschemes = {
["tokyonight-day"] = "Tokyo Night Day",
["tokyonight-night"] = "Tokyo Night Night",
["tokyonight-storm"] = "Tokyo Night Storm",
["tokynight-moon"] = "Tokyo Night Moon",
["catppuccin-frappe"] = "Catppuccin Frappe",
["catppuccin-latte"] = "Catppuccin Latte",
["catppuccin-macchiato"] = "Catppuccin Macchiato",
["catppuccin-mocha"] = "Catppuccin Mocha",
}
vim.api.nvim_create_autocmd("ColorScheme", {
group = vim.api.nvim_create_augroup("wezterm_colorscheme", { clear = true }),
callback = function(args)
SetupWindowPreferences()
local colorscheme = colorschemes[args.match]
if not colorscheme then
-- Get terminal theme from registry
local wezterm_theme = ThemeRegistry.get_theme(args.match, "wezterm")
if not wezterm_theme then
-- Theme not in registry, skip silently
return
end
@@ -54,9 +47,9 @@ local function SyncWezTerm()
assert(file)
file:write(colorscheme)
file:write(wezterm_theme)
file:close()
-- vim.notify("Setting WezTerm color scheme to " .. colorscheme, vim.log.levels.INFO)
-- vim.notify("Setting WezTerm color scheme to " .. wezterm_theme, vim.log.levels.INFO)
end,
})
end
@@ -75,6 +68,13 @@ local function SyncGhostyTerm()
local notifyOpts = { title = "Set Ghostty Theme" }
-- Get terminal theme from registry
local ghostty_colorscheme = ThemeRegistry.get_theme(args.match, "ghostty")
if not ghostty_colorscheme then
-- Theme not in registry, skip silently
return
end
-- if the file does not exists, exit early
local filename = vim.fn.expand("$XDG_CONFIG_HOME/ghostty/colorscheme")
@@ -86,14 +86,14 @@ local function SyncGhostyTerm()
-- lets check if ghostty supports the theme
-- ghostty +list-themes | xargs -I {} echo {} | grep <theme>
local cmd = "ghostty +list-themes | sed 's/ (resources)//g' | grep '^" .. args.match .. "$'"
local cmd = "ghostty +list-themes | sed 's/ (resources)//g' | grep '^" .. ghostty_colorscheme .. "$'"
local status = vim.fn.system(cmd)
local trimmed_output = vim.fn.substitute(status, "^s+|s+$", "", "g")
-- check if status is empty
if trimmed_output == "" then
vim.notify(args.match .. " is not supported by Ghostty", vim.log.levels.ERROR, notifyOpts)
vim.notify(ghostty_colorscheme .. " is not supported by Ghostty", vim.log.levels.ERROR, notifyOpts)
return
end
@@ -103,7 +103,7 @@ local function SyncGhostyTerm()
assert(file)
local theme_string = 'theme = "' .. args.match .. '"'
local theme_string = 'theme = "' .. ghostty_colorscheme .. '"'
file:write(theme_string)
file:close()
@@ -147,7 +147,6 @@ SetupAutocommands()
local opts = { noremap = true, silent = true }
opts.desc = "Fuzzy find colorschemes"
vim.api.nvim_set_keymap("n", "<leader>cs", "<cmd>Telescope colorscheme<CR>", opts)
opts.desc = "Fuzzy find themes"
vim.api.nvim_set_keymap("n", "<leader>th", "<cmd>Telescope themes<CR>", opts)
vim.keymap.set("n", "<leader>cs", function()
Snacks.picker.colorschemes()
end, opts)
+29
View File
@@ -6,6 +6,13 @@ local current_home = os.getenv("HOME")
vim.g.python3_host_prog = current_home .. "/.pyenv/versions/py3nvim/bin/python"
vim.opt.title = true
vim.opt.titlestring = "%{fnamemodify(getcwd(), ':t')}"
-- auto reload
vim.o.autoread = true
-- disable nvim intro
vim.opt.shortmess:append("sI")
@@ -74,4 +81,26 @@ vim.api.nvim_create_autocmd("InsertLeave", {
end,
})
vim.api.nvim_create_user_command("GitRootRun", function(opts)
local cmd = opts.args
local git_root = vim.fn.systemlist("git rev-parse --show-toplevel")[1]
if git_root and git_root ~= "" then
vim.cmd("!cd " .. git_root .. " && " .. cmd)
else
print("Not in a Git repository.")
end
end, { nargs = "+" })
local opts = { noremap = true, silent = true }
opts.desc = "Run command in Git root"
vim.keymap.set("n", "<leader>gr", function()
local command = vim.fn.input("$: ")
if command ~= "" then
vim.cmd("GitRootRun " .. command)
else
print("No command entered.")
end
end, opts)
-- Add similar autocommands for other modes as needed
+491
View File
@@ -0,0 +1,491 @@
-- Theme Registry
-- Central mapping between Neovim colorschemes and terminal themes (WezTerm, Ghostty)
-- Maintains a curated list of popular themes with verified mappings
local M = {}
-- Core theme mappings (manually curated and tested)
-- Each entry maps a Neovim colorscheme to its terminal equivalents
M.themes = {
-- ============================================================================
-- Tokyo Night Family (5 variants)
-- ============================================================================
["tokyonight"] = {
nvim = "tokyonight",
wezterm = "Tokyo Night",
ghostty = "TokyoNight",
family = "tokyonight",
variant = "night",
description = "A clean, dark Tokyo Night theme",
},
["tokyonight-night"] = {
nvim = "tokyonight-night",
wezterm = "Tokyo Night",
ghostty = "TokyoNight Night",
family = "tokyonight",
variant = "night",
description = "Tokyo Night (night variant)",
},
["tokyonight-storm"] = {
nvim = "tokyonight-storm",
wezterm = "Tokyo Night Storm",
ghostty = "TokyoNight Storm",
family = "tokyonight",
variant = "storm",
description = "Tokyo Night (storm variant)",
},
["tokyonight-day"] = {
nvim = "tokyonight-day",
wezterm = "Tokyo Night Day",
ghostty = "TokyoNight Day",
family = "tokyonight",
variant = "day",
description = "Tokyo Night (light day variant)",
},
["tokyonight-moon"] = {
nvim = "tokyonight-moon",
wezterm = "Tokyo Night Moon",
ghostty = "TokyoNight Moon",
family = "tokyonight",
variant = "moon",
description = "Tokyo Night (moon variant)",
},
-- ============================================================================
-- Catppuccin Family (4 variants)
-- ============================================================================
["catppuccin"] = {
nvim = "catppuccin",
wezterm = "Catppuccin Mocha",
ghostty = "Catppuccin Mocha",
family = "catppuccin",
variant = "mocha",
description = "Catppuccin (default mocha variant)",
},
["catppuccin-mocha"] = {
nvim = "catppuccin-mocha",
wezterm = "Catppuccin Mocha",
ghostty = "Catppuccin Mocha",
family = "catppuccin",
variant = "mocha",
description = "Catppuccin Mocha (warm, dark)",
},
["catppuccin-macchiato"] = {
nvim = "catppuccin-macchiato",
wezterm = "Catppuccin Macchiato",
ghostty = "Catppuccin Macchiato",
family = "catppuccin",
variant = "macchiato",
description = "Catppuccin Macchiato (mid-tone dark)",
},
["catppuccin-frappe"] = {
nvim = "catppuccin-frappe",
wezterm = "Catppuccin Frappe",
ghostty = "Catppuccin Frappe",
family = "catppuccin",
variant = "frappe",
description = "Catppuccin Frappe (cool, dark)",
},
["catppuccin-latte"] = {
nvim = "catppuccin-latte",
wezterm = "Catppuccin Latte",
ghostty = "Catppuccin Latte",
family = "catppuccin",
variant = "latte",
description = "Catppuccin Latte (light variant)",
},
-- ============================================================================
-- Rose Pine Family (4 variants)
-- ============================================================================
["rose-pine"] = {
nvim = "rose-pine",
wezterm = "rose-pine",
ghostty = "Rose Pine",
family = "rose-pine",
variant = "main",
description = "Rose Pine (main dark variant)",
},
["rose-pine-main"] = {
nvim = "rose-pine-main",
wezterm = "rose-pine",
ghostty = "Rose Pine",
family = "rose-pine",
variant = "main",
description = "Rose Pine (main dark variant)",
},
["rose-pine-moon"] = {
nvim = "rose-pine-moon",
wezterm = "rose-pine-moon",
ghostty = "Rose Pine Moon",
family = "rose-pine",
variant = "moon",
description = "Rose Pine Moon (darker variant)",
},
["rose-pine-dawn"] = {
nvim = "rose-pine-dawn",
wezterm = "rose-pine-dawn",
ghostty = "Rose Pine Dawn",
family = "rose-pine",
variant = "dawn",
description = "Rose Pine Dawn (light variant)",
},
-- ============================================================================
-- Nightfox Family (7 variants)
-- ============================================================================
["nightfox"] = {
nvim = "nightfox",
wezterm = "nightfox",
ghostty = "Nightfox",
family = "nightfox",
variant = "night",
description = "Nightfox (main dark variant)",
},
["carbonfox"] = {
nvim = "carbonfox",
wezterm = "carbonfox",
ghostty = "Carbonfox",
family = "nightfox",
variant = "carbon",
description = "Carbonfox (carbon variant)",
},
["dawnfox"] = {
nvim = "dawnfox",
wezterm = "dawnfox",
ghostty = "Dawnfox",
family = "nightfox",
variant = "dawn",
description = "Dawnfox (dawn variant)",
},
["dayfox"] = {
nvim = "dayfox",
wezterm = "dayfox",
ghostty = "Dayfox",
family = "nightfox",
variant = "day",
description = "Dayfox (light day variant)",
},
["duskfox"] = {
nvim = "duskfox",
wezterm = "duskfox",
ghostty = "Duskfox",
family = "nightfox",
variant = "dusk",
description = "Duskfox (dusk variant)",
},
["nordfox"] = {
nvim = "nordfox",
wezterm = "nordfox",
ghostty = "Nordfox",
family = "nightfox",
variant = "nord",
description = "Nordfox (nord-inspired variant)",
},
["terafox"] = {
nvim = "terafox",
wezterm = "terafox",
ghostty = "Terafox",
family = "nightfox",
variant = "tera",
description = "Terafox (tera variant)",
},
-- ============================================================================
-- Gruvbox Family (4 variants)
-- ============================================================================
["gruvbox"] = {
nvim = "gruvbox",
wezterm = "GruvboxDark",
ghostty = "Gruvbox Dark",
family = "gruvbox",
variant = "dark",
description = "Gruvbox (dark variant)",
},
["gruvbox-material"] = {
nvim = "gruvbox-material",
wezterm = "Gruvbox Material (Gogh)",
ghostty = "Gruvbox Material",
family = "gruvbox",
variant = "material",
description = "Gruvbox Material",
},
-- ============================================================================
-- Nord
-- ============================================================================
["nord"] = {
nvim = "nord",
wezterm = "Nord (base16)",
ghostty = "Nord",
family = "nord",
variant = "main",
description = "Nord (arctic, north-bluish color palette)",
},
-- ============================================================================
-- Dracula
-- ============================================================================
["dracula"] = {
nvim = "dracula",
wezterm = "Dracula (Official)",
ghostty = "Dracula",
family = "dracula",
variant = "main",
description = "Dracula (dark theme)",
},
-- ============================================================================
-- One Dark / One Light
-- ============================================================================
["onedark"] = {
nvim = "onedark",
wezterm = "OneDark (base16)",
ghostty = "Atom One Dark",
family = "onedark",
variant = "dark",
description = "One Dark (Atom-inspired dark theme)",
},
["onelight"] = {
nvim = "onelight",
wezterm = "One Light (base16)",
ghostty = "Atom One Light",
family = "onelight",
variant = "light",
description = "One Light (Atom-inspired light theme)",
},
-- ============================================================================
-- Material
-- ============================================================================
["material"] = {
nvim = "material",
wezterm = "MaterialDark",
ghostty = "Material",
family = "material",
variant = "dark",
description = "Material (dark variant)",
},
["material-darker"] = {
nvim = "material-darker",
wezterm = "MaterialDarker",
ghostty = "Material Darker",
family = "material",
variant = "darker",
description = "Material (darker variant)",
},
-- ============================================================================
-- Solarized
-- ============================================================================
["solarized-dark"] = {
nvim = "solarized-dark",
wezterm = "Builtin Solarized Dark",
ghostty = "Builtin Solarized Dark",
family = "solarized",
variant = "dark",
description = "Solarized Dark",
},
["solarized-light"] = {
nvim = "solarized-light",
wezterm = "Builtin Solarized Light",
ghostty = "Builtin Solarized Light",
family = "solarized",
variant = "light",
description = "Solarized Light",
},
-- ============================================================================
-- Monokai
-- ============================================================================
["monokai"] = {
nvim = "monokai",
wezterm = "Monokai Remastered",
ghostty = "Monokai Classic",
family = "monokai",
variant = "main",
description = "Monokai (classic variant)",
},
["monokai-pro"] = {
nvim = "monokai-pro",
wezterm = "Monokai Pro (Gogh)",
ghostty = "Monokai Pro",
family = "monokai",
variant = "pro",
description = "Monokai Pro",
},
-- ============================================================================
-- GitHub
-- ============================================================================
["github-dark"] = {
nvim = "github-dark",
wezterm = "GitHub Dark",
ghostty = "GitHub Dark",
family = "github",
variant = "dark",
description = "GitHub Dark",
},
-- ============================================================================
-- Ayu
-- ============================================================================
["ayu-dark"] = {
nvim = "ayu-dark",
wezterm = "Ayu Dark (Gogh)",
ghostty = "Ayu",
family = "ayu",
variant = "dark",
description = "Ayu (dark variant)",
},
["ayu-mirage"] = {
nvim = "ayu-mirage",
wezterm = "Ayu Mirage",
ghostty = "Ayu Mirage",
family = "ayu",
variant = "mirage",
description = "Ayu Mirage (mid-tone variant)",
},
["ayu-light"] = {
nvim = "ayu-light",
wezterm = "Ayu Light (Gogh)",
ghostty = "Ayu Light",
family = "ayu",
variant = "light",
description = "Ayu (light variant)",
},
}
-- ============================================================================
-- Helper Functions
-- ============================================================================
--- Get the terminal theme name for a given Neovim colorscheme
--- @param nvim_name string The Neovim colorscheme name
--- @param terminal_type string The terminal type ("wezterm" or "ghostty")
--- @return string|nil The terminal theme name, or nil if not found
function M.get_theme(nvim_name, terminal_type)
local theme = M.themes[nvim_name]
if not theme then
return nil
end
if terminal_type == "wezterm" then
return theme.wezterm
elseif terminal_type == "ghostty" then
return theme.ghostty
end
return nil
end
--- Check if a Neovim colorscheme is supported for a given terminal
--- @param nvim_name string The Neovim colorscheme name
--- @param terminal_type string The terminal type ("wezterm" or "ghostty")
--- @return boolean True if the mapping exists
function M.is_supported(nvim_name, terminal_type)
return M.get_theme(nvim_name, terminal_type) ~= nil
end
--- Get all Neovim themes in the registry
--- @return table List of Neovim colorscheme names
function M.get_all_nvim_themes()
local themes = {}
for nvim_name, _ in pairs(M.themes) do
table.insert(themes, nvim_name)
end
table.sort(themes)
return themes
end
--- Get theme family and variant information
--- @param nvim_name string The Neovim colorscheme name
--- @return table|nil Theme metadata (family, variant, description)
function M.get_theme_info(nvim_name)
local theme = M.themes[nvim_name]
if not theme then
return nil
end
return {
family = theme.family,
variant = theme.variant,
description = theme.description,
wezterm = theme.wezterm,
ghostty = theme.ghostty,
}
end
--- Get all themes in a family
--- @param family_name string The theme family name (e.g., "tokyonight", "catppuccin")
--- @return table List of theme entries in the family
function M.get_family_themes(family_name)
local family_themes = {}
for nvim_name, theme in pairs(M.themes) do
if theme.family == family_name then
table.insert(family_themes, {
nvim = nvim_name,
variant = theme.variant,
description = theme.description,
})
end
end
-- Sort by variant name
table.sort(family_themes, function(a, b)
return a.variant < b.variant
end)
return family_themes
end
--- Get a list of all theme families
--- @return table List of unique family names
function M.get_all_families()
local families = {}
local seen = {}
for _, theme in pairs(M.themes) do
if not seen[theme.family] then
seen[theme.family] = true
table.insert(families, theme.family)
end
end
table.sort(families)
return families
end
--- Get statistics about the theme registry
--- @return table Statistics (total_themes, families_count, terminal_coverage)
function M.get_stats()
local total = 0
local wezterm_count = 0
local ghostty_count = 0
local families = {}
for _, theme in pairs(M.themes) do
total = total + 1
if theme.wezterm then
wezterm_count = wezterm_count + 1
end
if theme.ghostty then
ghostty_count = ghostty_count + 1
end
families[theme.family] = true
end
local families_count = 0
for _ in pairs(families) do
families_count = families_count + 1
end
return {
total_themes = total,
families_count = families_count,
wezterm_coverage = wezterm_count,
ghostty_coverage = ghostty_count,
}
end
return M
+4 -1
View File
@@ -27,7 +27,10 @@ require("lazy")
change_detection = {
notify = false,
},
ui = {
border = "rounded",
},
})
require("absolute.core.colorscheme")
require("../current-theme");
require("current-theme")
+9
View File
@@ -0,0 +1,9 @@
return {
"saghen/blink.cmp",
version = "1.*",
event = "InsertEnter",
dependencies = { "rafamadriz/friendly-snippets" },
config = function()
require("absolute.after.blink-cmp")
end,
}
-11
View File
@@ -1,11 +0,0 @@
return {
"sudormrfbin/cheatsheet.nvim",
dependencies = {
{ "nvim-telescope/telescope.nvim" },
{ "nvim-lua/plenary.nvim" },
},
config = function()
require("absolute.after.cheatsheet")
end,
}
-11
View File
@@ -1,11 +0,0 @@
return {
"olimorris/codecompanion.nvim",
dependencies = {
"ravitemer/mcphub.nvim",
"nvim-lua/plenary.nvim",
"nvim-treesitter/nvim-treesitter",
},
config = function()
require("absolute.after.codecompanion")
end,
}
-3
View File
@@ -1,3 +0,0 @@
return {
"github/copilot.vim",
}
-1
View File
@@ -4,7 +4,6 @@ return {
"theHamsta/nvim-dap-virtual-text",
"rcarriga/nvim-dap-ui",
"nvim-neotest/nvim-nio",
"nvim-telescope/telescope-dap.nvim",
},
config = function()
require("absolute.after.dap")
-4
View File
@@ -1,4 +0,0 @@
return {
"stevearc/dressing.nvim",
event = "VeryLazy"
}
+15
View File
@@ -0,0 +1,15 @@
return {
enabled = false,
"folke/flash.nvim",
event = "VeryLazy",
---@type Flash.Config
opts = {},
-- stylua: ignore
keys = {
{ "s", mode = { "n", "x", "o" }, function() require("flash").jump() end, desc = "Flash" },
{ "S", mode = { "n", "x", "o" }, function() require("flash").treesitter() end, desc = "Flash Treesitter" },
{ "r", mode = "o", function() require("flash").remote() end, desc = "Remote Flash" },
{ "R", mode = { "o", "x" }, function() require("flash").treesitter_search() end, desc = "Treesitter Search" },
{ "<c-s>", mode = { "c" }, function() require("flash").toggle() end, desc = "Toggle Flash Search" },
},
}
-7
View File
@@ -1,7 +0,0 @@
return {
"David-Kunz/gen.nvim",
enabled = false,
config = function()
require("absolute.after.gen")
end,
}
-4
View File
@@ -1,4 +0,0 @@
return {
"f-person/git-blame.nvim",
event = "VeryLazy",
}
-9
View File
@@ -1,9 +0,0 @@
return {
"wintermute-cell/gitignore.nvim",
dependencies = {
"nvim-telescope/telescope.nvim",
},
config = function()
require("absolute.after.gitignore")
end
}
-7
View File
@@ -1,7 +0,0 @@
return {
"huggingface/llm.nvim",
enabled = false,
config = function()
require("absolute.after.llm")
end,
}
-4
View File
@@ -2,10 +2,6 @@ return {
"neovim/nvim-lspconfig",
event = { "BufReadPre", "BufNewFile" },
dependencies = {
{
"hrsh7th/cmp-nvim-lsp",
name = "nvim_lsp",
},
{
"antosha417/nvim-lsp-file-operations",
config = true,
-8
View File
@@ -1,8 +0,0 @@
return {
"rcarriga/nvim-notify",
lazy = false,
priority = 1000,
config = function()
require("absolute.after.notify")
end,
}
-18
View File
@@ -1,18 +0,0 @@
return {
'hrsh7th/nvim-cmp',
event = "InsertEnter",
dependencies = {
'neovim/nvim-lspconfig',
'hrsh7th/cmp-nvim-lsp',
'hrsh7th/cmp-buffer', --source for text in buffer
'hrsh7th/cmp-path', --source for file system paths
'hrsh7th/cmp-cmdline',
"saadparwaiz1/cmp_luasnip", --source for autocompletion
"onsails/lspkind.nvim",
"L3MON4D3/LuaSnip", --Snippet Engine
"rafamadriz/friendly-snippets", --Useful snippets
},
config = function()
require("absolute.after.nvim-cmp")
end
}
@@ -1,3 +0,0 @@
return {
"nvim-treesitter/playground",
}
-7
View File
@@ -1,7 +0,0 @@
return {
enabled = false,
"petobens/poet-v",
config = function()
require("absolute.after.poet-v")
end,
}
-4
View File
@@ -1,4 +0,0 @@
return {
"MeanderingProgrammer/render-markdown.nvim",
ft = { "markdown", "codecompanion" }
}
+32
View File
@@ -0,0 +1,32 @@
return {
"folke/snacks.nvim",
priority = 1000,
lazy = false,
---@type snacks.Config
opts = {
bigfile = { enabled = true },
quickfile = { enabled = true },
input = { enabled = true },
notifier = {
enabled = true,
timeout = 3000,
style = "compact",
top_down = true,
icons = {
debug = "",
error = "",
info = "",
trace = "✎",
warn = "",
},
},
picker = {
enabled = true,
ui_select = true,
},
},
config = function(_, opts)
require("snacks").setup(opts)
require("absolute.after.snacks")
end,
}
-21
View File
@@ -1,21 +0,0 @@
return {
"nvim-telescope/telescope.nvim",
branch = "0.1.x",
dependencies = {
"nvim-lua/popup.nvim",
"nvim-lua/plenary.nvim",
"nvim-telescope/telescope-dap.nvim",
"andrew-george/telescope-themes",
"nvim-telescope/telescope-media-files.nvim",
"nvim-telescope/telescope-file-browser.nvim",
{
"nvim-telescope/telescope-live-grep-args.nvim",
-- This will not install any breaking changes.
-- For major updates, this must be adjusted manually.
version = "^1.0.0",
},
},
config = function()
require("absolute.after.telescope")
end,
}
+1 -3
View File
@@ -1,11 +1,9 @@
return {
"linux-cultist/venv-selector.nvim",
lazy = false,
branch = "regexp", -- This is the regexp branch, use this for the new version
branch = "main", -- This is the regexp branch, use this for the new version
dependencies = {
"neovim/nvim-lspconfig",
"nvim-telescope/telescope.nvim",
"mfussenegger/nvim-dap-python",
},
config = function()
require("absolute.after.venv-selector")
-3
View File
@@ -1,3 +0,0 @@
return {
"szw/vim-maximizer"
}
+9 -7
View File
@@ -3,8 +3,10 @@ local opts = {
silent = true,
}
opts.desc = "Show Keymap"
vim.keymap.set("n", "<leader>?", "<cmd>Telescope keymaps<CR>", opts) -- toggle file explorer
opts.desc = "Show keymaps"
vim.keymap.set("n", "<leader>?", function()
Snacks.picker.keymaps()
end, opts)
opts.desc = "Select All"
vim.keymap.set("n", "<C-a>", "gg0vG$", opts) -- select all
@@ -66,18 +68,18 @@ vim.keymap.set("n", "<C-k>", "<cmd>cnext<CR>zz", opts)
opts.desc = "Jump down and center screen"
vim.keymap.set("n", "<C-j>", "<cmd>cprev<CR>zz", opts)
opts.desc = "Jump to next location and center screen"
vim.keymap.set("n", "<leader>k", "<cmd>lnext<CR>zz", opts)
opts.desc = "Next location-list entry"
vim.keymap.set("n", "]l", "<cmd>lnext<CR>zz", opts)
opts.desc = "Jump to previous location and center screen"
vim.keymap.set("n", "<leader>j", "<cmd>lprev<CR>zz", opts)
opts.desc = "Previous location-list entry"
vim.keymap.set("n", "[l", "<cmd>lprev<CR>zz", opts)
-- Search Regex Keymap
opts.desc = "Regex Replace"
vim.keymap.set("n", "<leader>sr", [[:%s/\<<C-r><C-w>\>/<C-r><C-w>/gI<Left><Left><Left>]], opts)
opts.desc = "Replace selected text"
vim.keymap.set("v", "<leader>ss", [[:s/\<<C-r><C-w>\>/<C-r><C-w>/gI<Left><Left><Left>]], opts)
vim.keymap.set("v", "<leader>sr", [[:s/\<<C-r><C-w>\>/<C-r><C-w>/gI<Left><Left><Left>]], opts)
-- -- Source File Keymap
-- opts.desc = "Source File"
@@ -1,127 +0,0 @@
-- Sourced from github
-- https://github.com/3rd/image.nvim/issues/183#issuecomment-2572606511
M = {}
local supported_images = { "svg", "png", "jpg", "jpeg", "gif", "webp", "avif" }
local from_entry = require("telescope.from_entry")
local Path = require("plenary.path")
local conf = require("telescope.config").values
local Previewers = require("telescope.previewers")
local previewers = require("telescope.previewers")
local image_api = require("image")
local is_image_preview = false
local image = nil
local last_file_path = ""
local is_supported_image = function(filepath)
local split_path = vim.split(filepath:lower(), ".", { plain = true })
local extension = split_path[#split_path]
return vim.tbl_contains(supported_images, extension)
end
local delete_image = function()
if not image then
return
end
image:clear()
is_image_preview = false
end
local create_image = function(filepath, winid, bufnr)
image = image_api.hijack_buffer(filepath, winid, bufnr)
if not image then
return
end
vim.schedule(function()
image:render()
end)
is_image_preview = true
end
local function defaulter(f, default_opts)
default_opts = default_opts or {}
return {
new = function(opts)
if conf.preview == false and not opts.preview then
return false
end
opts.preview = type(opts.preview) ~= "table" and {} or opts.preview
if type(conf.preview) == "table" then
for k, v in pairs(conf.preview) do
opts.preview[k] = vim.F.if_nil(opts.preview[k], v)
end
end
return f(opts)
end,
__call = function()
local ok, err = pcall(f(default_opts))
if not ok then
error(debug.traceback(err))
end
end,
}
end
-- NOTE: Add teardown to cat previewer to clear image when close Telescope
local file_previewer = defaulter(function(opts)
opts = opts or {}
local cwd = opts.cwd or vim.fn.getcwd()
return Previewers.new_buffer_previewer({
title = "File Preview",
dyn_title = function(_, entry)
return Path:new(from_entry.path(entry, true)):normalize(cwd)
end,
get_buffer_by_name = function(_, entry)
return from_entry.path(entry, true)
end,
define_preview = function(self, entry, _)
local p = from_entry.path(entry, true)
if p == nil or p == "" then
return
end
conf.buffer_previewer_maker(p, self.state.bufnr, {
bufname = self.state.bufname,
winid = self.state.winid,
preview = opts.preview,
})
end,
teardown = function(_)
if is_image_preview then
delete_image()
end
end,
})
end, {})
local buffer_previewer_maker = function(filepath, bufnr, opts)
-- NOTE: Clear image when preview other file
if is_image_preview and last_file_path ~= filepath then
delete_image()
end
last_file_path = filepath
if is_supported_image(filepath) then
filepath = string.gsub(filepath, " ", "%%20"):gsub("\\", "")
create_image(filepath, opts.winid, bufnr)
else
previewers.buffer_previewer_maker(filepath, bufnr, opts)
end
end
M.buffer_previewer_maker = buffer_previewer_maker
M.file_previewer = file_previewer.new
return M
+1 -1
View File
@@ -1 +1 @@
vim.cmd("colorscheme catppuccin-macchiato")
vim.cmd("colorscheme tokyonight-night")