Nvim revamp - #376
Conversation
- Implemented various autocmds for improved user experience, including: - Highlighting on yank - Resizing splits on window resize - Automatic file change checks - Git commit message enhancements - Ensuring parent directories exist for new files - Help window positioning - Git and Fugitive buffer configurations - Integrated completion setup using nvim-cmp and copilot, with custom mappings for snippets and sources. - Established key mappings for efficient navigation, buffer management, and Git operations. - Configured LSP with multiple language servers and diagnostic settings, including custom signs for diagnostics. - Added plugin management with a focus on UI enhancements, coding tools, and Treesitter support. - Set up user interface elements including lualine, nvim-tree, and notification handling. - Enhanced Treesitter configuration with various language support and text object mappings. - Implemented terminal management with toggleterm for better terminal integration. - Created utility functions for buffer cycling and quickfix management.
… and add new plugins
…ce diagnostics, and improve settings
…ock configuration
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughSummary by CodeRabbitRelease Notes
✏️ Tip: You can customize this high-level summary in your review settings. WalkthroughAdds a Lua formatter (Stylua) to treefmt config, centralizes CI detection in Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
You do not have enough credits to review this pull request. Please purchase more credits to continue. |
Summary of ChangesHello @shunkakinoki, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a comprehensive revamp of the Neovim configuration, moving from a monolithic Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
Mesa DescriptionTL;DRMajor Neovim revamp: split config into Lua modules, switch to nvim-cmp, add terminal/AI/UI/search tooling; add Stylua to treefmt/flake and update Nix/macOS packages; add Biome/TypeScript deps. What changed?
Description generated by Mesa. Update settings |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for name, config in pairs(servers) do | ||
| config.on_attach = on_attach | ||
| config.capabilities = capabilities | ||
| vim.lsp.config(name, config) | ||
| end | ||
| vim.lsp.enable(vim.tbl_keys(servers)) |
There was a problem hiding this comment.
LSP setup uses nonexistent vim.lsp API
The new LSP bootstrap calls vim.lsp.config(name, config) and vim.lsp.enable(...), but the stock pkgs.neovim build used in home-manager/programs/neovim/default.nix does not expose those functions; the supported entrypoints remain require('lspconfig').<server>.setup(...) or vim.lsp.start. On current releases this code raises attempt to call field 'config' (a nil value) when lsp.lua is required, so no servers are registered and Neovim init halts before the rest of the modules run.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Code Review
This pull request is a major and impressive refactoring of the Neovim configuration. It moves from a large, monolithic init.lua to a well-structured, modular setup with separate files for settings, plugins, keymaps, LSP, and more. This greatly improves maintainability and readability. The addition of new plugins like toggleterm, trouble, and flash, along with the switch to nvim-cmp, modernizes the editing experience. The Nix configuration changes are also clean and improve organization. My review includes a few suggestions to further improve modularity and address some minor regressions or code smells introduced during the refactoring. Overall, this is an excellent update.
| local config_lua_path = vim.fn.stdpath("config") .. "/lua/?.lua" | ||
| append_package_path(config_lua_path) | ||
| append_package_path(vim.fn.stdpath("config") .. "/lua/?/init.lua") |
There was a problem hiding this comment.
The logic to determine the script's directory and add the lua subdirectory to package.path (lines 20-27) is robust and should be sufficient on its own. The preceding lines that add paths relative to vim.fn.stdpath("config") are likely redundant, as init_dir and vim.fn.stdpath("config") should point to the same location in a typical setup. Removing this redundant setup would make the configuration cleaner.
| [vim.diagnostic.severity.ERROR] = "", | ||
| [vim.diagnostic.severity.WARN] = "", |
There was a problem hiding this comment.
The diagnostic signs for ERROR and WARN levels are configured as empty strings. This disables visual indicators in the sign column for errors and warnings, which is a regression from the previous configuration and reduces the at-a-glance visibility of code issues. I recommend re-enabling them to improve the debugging experience. You could restore the previous icons or use alternatives.
[vim.diagnostic.severity.ERROR] = "",
[vim.diagnostic.severity.WARN] = "",
| vim.api.nvim_create_autocmd({ "BufWritePost" }, { | ||
| callback = function() | ||
| lint.try_lint() | ||
| end, | ||
| }) |
| -- Suppress deprecation warnings (temporary until plugins update) | ||
| vim.deprecate = function() end |
There was a problem hiding this comment.
Suppressing all deprecation warnings by overriding vim.deprecate can hide important information about outdated APIs used by plugins. While the comment indicates this is temporary, this is a form of technical debt that should be tracked more formally, for instance with a TODO comment, to ensure it gets addressed.
-- TODO: Remove this once plugins are updated to not use deprecated APIs
vim.deprecate = function() end
| -- Manage Neovim-hosted terminals with floating/split layouts. | ||
| -- From: https://github.com/akinsho/toggleterm.nvim | ||
| local toggleterm = require("toggleterm") | ||
| -- Expose the toggleterm terminal constructor for custom instances. | ||
| -- From: https://github.com/akinsho/toggleterm.nvim | ||
| local Terminal = require("toggleterm.terminal").Terminal | ||
|
|
||
| toggleterm.setup({ | ||
| direction = "horizontal", | ||
| size = function(term) | ||
| if term.direction == "horizontal" then | ||
| return math.floor(vim.o.lines * 0.3) | ||
| end | ||
| return 20 | ||
| end, | ||
| start_in_insert = true, | ||
| shade_terminals = true, | ||
| persist_size = true, | ||
| }) | ||
|
|
||
| local function create_term(count) | ||
| return Terminal:new({ | ||
| direction = "horizontal", | ||
| count = count, | ||
| hidden = true, | ||
| on_open = function() | ||
| vim.cmd("startinsert!") | ||
| end, | ||
| }) | ||
| end | ||
|
|
||
| local term_sequence = { 1, 2 } | ||
| local terms = { | ||
| [1] = create_term(1), | ||
| [2] = create_term(2), | ||
| } | ||
| local current_index = 1 | ||
|
|
||
| local function index_of(count) | ||
| for idx, value in ipairs(term_sequence) do | ||
| if value == count then | ||
| return idx | ||
| end | ||
| end | ||
| return 1 | ||
| end | ||
|
|
||
| local function toggle_term(count) | ||
| for other_count, term in pairs(terms) do | ||
| if other_count ~= count and term:is_open() then | ||
| term:close() | ||
| end | ||
| end | ||
|
|
||
| local term = terms[count] | ||
| term:toggle() | ||
| if term:is_open() then | ||
| current_index = index_of(count) | ||
| end | ||
| end | ||
|
|
||
| function TogglePrimaryTerm() | ||
| toggle_term(1) | ||
| end | ||
|
|
||
| function ToggleSecondaryTerm() | ||
| toggle_term(2) | ||
| end | ||
|
|
||
| local function cycle(step) | ||
| local len = #term_sequence | ||
| current_index = ((current_index - 1 + step) % len) + 1 | ||
| local next_count = term_sequence[current_index] | ||
| local term = terms[next_count] | ||
| if not term:is_open() then | ||
| toggle_term(next_count) | ||
| else | ||
| for _, t in pairs(terms) do | ||
| if t ~= term and t:is_open() then | ||
| t:close() | ||
| end | ||
| end | ||
| term:close() | ||
| term:open() | ||
| end | ||
| end | ||
|
|
||
| function CycleNextTerm() | ||
| cycle(1) | ||
| end | ||
|
|
||
| function CyclePreviousTerm() | ||
| cycle(-1) | ||
| end |
There was a problem hiding this comment.
This module defines several functions like TogglePrimaryTerm and CycleNextTerm in the global scope, which are then called from keymaps.lua. This pollutes the global namespace and can lead to name collisions. A better practice is to return these functions in a table from the module and explicitly require and use them in keymaps.lua, similar to how utils.lua is structured and used.
For example, in terminal.lua:
local M = {}
-- ... existing local functions ...
function M.TogglePrimaryTerm()
toggle_term(1)
end
-- ... other functions on M ...
return MAnd in keymaps.lua:
local terminal = require("terminal")
-- ...
keymap({ "n", "t" }, "<leader>j", function()
teminal.TogglePrimaryTerm()
end, opts)There was a problem hiding this comment.
Pull request overview
This PR represents a major refactoring of the Neovim configuration, transitioning from a monolithic 1330-line init.lua to a modular architecture with separate configuration files. The refactoring improves maintainability and organization while switching from blink.cmp to nvim-cmp for completion, and adding several new plugins for enhanced functionality.
Key Changes
- Modularized Neovim configuration: Split the massive init.lua into 12 focused modules (settings, plugins, autocmds, keymaps, lsp, telescope, treesitter, completion, ai, terminal, ui, utils)
- Completion engine migration: Replaced blink.cmp with nvim-cmp ecosystem (including nvim-cmp, cmp-nvim-lsp, cmp-buffer, cmp-path, cmp-cmdline, LuaSnip, cmp_luasnip, copilot-cmp)
- New plugins added: toggleterm.nvim for terminal management, trouble.nvim for diagnostics, which-key.nvim for keybinding hints, fidget.nvim for LSP progress, oil.nvim for file navigation, flash.nvim for motion jumping, grug-far.nvim for search/replace, telescope extensions (fzf-native, ui-select), nvim-lint, nvim-vtsls, and vim-illuminate
Reviewed changes
Copilot reviewed 22 out of 23 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| home-manager/programs/neovim/init.lua | Drastically simplified to 43 lines; now only sets leader key, configures module paths, and requires all modular components |
| home-manager/programs/neovim/lua/settings.lua | Extracted all vim options and settings from init.lua into dedicated module |
| home-manager/programs/neovim/lua/plugins.lua | Centralized plugin declarations using vim.pack.add with setup calls for various plugins |
| home-manager/programs/neovim/lua/keymaps.lua | Consolidated all keymaps including buffer operations, terminal toggles, navigation, git operations, and diagnostics |
| home-manager/programs/neovim/lua/lsp.lua | LSP configuration with on_attach keymaps and server setup using new vim.lsp.config/enable API |
| home-manager/programs/neovim/lua/completion.lua | nvim-cmp setup with LSP, Copilot, LuaSnip, buffer, and path sources; replaces blink.cmp configuration |
| home-manager/programs/neovim/lua/telescope.lua | Telescope configuration with ivy theme, fzf extension, and various picker keymaps |
| home-manager/programs/neovim/lua/treesitter.lua | Treesitter setup with syntax highlighting, indentation, autopairs, and textobject navigation |
| home-manager/programs/neovim/lua/terminal.lua | toggleterm.nvim configuration with functions for managing multiple terminal instances |
| home-manager/programs/neovim/lua/ui.lua | UI plugin setup including lualine, nvim-tree, which-key, fidget, oil, trouble, auto-dark-mode, dressing, and notify |
| home-manager/programs/neovim/lua/autocmds.lua | All autocommands for highlight on yank, window resize, git workflows, file type settings, etc. |
| home-manager/programs/neovim/lua/utils.lua | Utility functions for buffer cycling and quickfix list management |
| home-manager/programs/neovim/lua/ai.lua | Simple sidekick.nvim setup for AI workspace integration |
| home-manager/programs/neovim/nvim-pack-lock.json | Added 19 new plugins for completion, linting, navigation, and UI enhancements |
| treefmt.toml | Added stylua formatter for Lua files |
| flake.nix | Added stylua formatter configuration in treefmt setup |
| package.json | Added @biomejs/biome, @typescript/native-preview, and typescript dependencies; reordered entries |
| bun.lock | Updated lockfile with new dependency entries and trust relationships |
| nix-darwin/config/homebrew.nix | Changed 'tailscale' to 'tailscale-app' (correct cask name); added 'visual-studio-code@insiders' |
| nix-darwin/config/dock.nix | Added Tailscale.app and Visual Studio Code Insiders.app to dock |
| home-manager/packages/default.nix | Moved isCI environment detection to lib/env.nix; added speedtest-cli package |
| lib/env.nix | New shared module for environment detection (CI/Docker) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| -- @keymap i: Open in horizontal split (nvim-tree) | ||
| vim.keymap.set("n", "i", api.node.open.horizontal, opts("Open: Horizontal Split")) |
There was a problem hiding this comment.
Duplicate keymap functionality: Both 's' (line 96-97) and 'i' (line 100-101) are mapped to the same action api.node.open.horizontal (Open: Horizontal Split). This appears to be redundant. Consider removing one of these mappings or assigning 'i' to a different action if that was intended.
| -- @keymap i: Open in horizontal split (nvim-tree) | |
| vim.keymap.set("n", "i", api.node.open.horizontal, opts("Open: Horizontal Split")) |
| local flash = require("flash") | ||
|
|
||
| -- @keymap <Space>: Set as leader key | ||
| --Remap space as leader key |
There was a problem hiding this comment.
Missing space after comment delimiter. Should be -- Remap space as leader key (with a space after --).
| --Remap space as leader key | |
| -- Remap space as leader key |
| @@ -0,0 +1,71 @@ | |||
| -- Keymaps for LSP actions in on_attach | |||
| local on_attach = function(client, bufnr) | |||
There was a problem hiding this comment.
The client parameter in the on_attach function is defined but never used. Consider prefixing it with an underscore (_client) to indicate it's intentionally unused, or remove it if it's not needed for the function signature.
| local on_attach = function(client, bufnr) | |
| local on_attach = function(_client, bufnr) |
| vim.opt.termsync = true | ||
| vim.opt.hidden = true | ||
| vim.opt.updatetime = 300 | ||
| vim.opt.mouse = "a" |
There was a problem hiding this comment.
The mouse setting has been changed from disabled ("") to enabled ("a"). In the old init.lua, mouse was set to vim.opt.mouse = "" (disabled), but now it's set to "a" (enabled in all modes). This is a significant behavior change that may not be intentional.
If this change was intentional, it should be noted in the PR description. Otherwise, consider reverting to vim.opt.mouse = "".
| vim.opt.mouse = "a" | |
| vim.opt.mouse = "" |
| "@biomejs/biome": "^2.3.8", | ||
| "@getgrit/cli": "^0.1.0-alpha.1743007075", | ||
| "@github/copilot": "^0.0.365", | ||
| "@google/jules": "^0.1.40", | ||
| "@getgrit/cli": "^0.1.0-alpha.1743007075", | ||
| "@nanocollective/nanocoder": "^1.16.3", | ||
| "@typescript/native-preview": "^7.0.0-dev.20251127.1", | ||
| "cline": "^1.0.5", | ||
| "open-composer": "^0.8.23" | ||
| "open-composer": "^0.8.23", | ||
| "typescript": "^5.9.3" |
There was a problem hiding this comment.
[nitpick] Dependencies are not in alphabetical order. @biomejs/biome and @getgrit/cli have been moved to the top, but ideally all dependencies should be sorted alphabetically for better maintainability. Consider sorting them:
"@biomejs/biome": "^2.3.8",
"@getgrit/cli": "^0.1.0-alpha.1743007075",
"@github/copilot": "^0.0.365",
"@google/jules": "^0.1.40",
"@nanocollective/nanocoder": "^1.16.3",
"@typescript/native-preview": "^7.0.0-dev.20251127.1",
"cline": "^1.0.5",
"open-composer": "^0.8.23",
"typescript": "^5.9.3"| function TogglePrimaryTerm() | ||
| toggle_term(1) | ||
| end | ||
|
|
||
| function ToggleSecondaryTerm() | ||
| toggle_term(2) | ||
| end | ||
|
|
||
| local function cycle(step) | ||
| local len = #term_sequence | ||
| current_index = ((current_index - 1 + step) % len) + 1 | ||
| local next_count = term_sequence[current_index] | ||
| local term = terms[next_count] | ||
| if not term:is_open() then | ||
| toggle_term(next_count) | ||
| else | ||
| for _, t in pairs(terms) do | ||
| if t ~= term and t:is_open() then | ||
| t:close() | ||
| end | ||
| end | ||
| term:close() | ||
| term:open() | ||
| end | ||
| end | ||
|
|
||
| function CycleNextTerm() | ||
| cycle(1) | ||
| end | ||
|
|
||
| function CyclePreviousTerm() | ||
| cycle(-1) | ||
| end |
There was a problem hiding this comment.
Global functions should be declared as local. These functions (TogglePrimaryTerm, ToggleSecondaryTerm, CycleNextTerm, CyclePreviousTerm) are used in keymaps.lua but are declared as global functions without the local keyword. This pollutes the global namespace and is not best practice in Lua.
Consider declaring them as local and returning them in a module table:
local M = {}
M.TogglePrimaryTerm = function() toggle_term(1) end
M.ToggleSecondaryTerm = function() toggle_term(2) end
M.CycleNextTerm = function() cycle(1) end
M.CyclePreviousTerm = function() cycle(-1) end
return MThen in keymaps.lua, require the module: local terminal = require("terminal") and use terminal.TogglePrimaryTerm() instead.
| vim.notify = notify | ||
|
|
||
| local section_b = { "branch", "diff", { "diagnostics", sources = { "nvim_workspace_diagnostic" } } } | ||
| local section_c = { "%=", { "filename", file_status = true, path = 1 } } |
There was a problem hiding this comment.
The file_status option has been changed from false to true compared to the original init.lua configuration. This will now show modified/readonly status indicators in the filename component of lualine. If this change was unintentional, consider reverting to file_status = false.
| local section_c = { "%=", { "filename", file_status = true, path = 1 } } | |
| local section_c = { "%=", { "filename", file_status = false, path = 1 } } |
| require("ai") | ||
| require("terminal") | ||
| require("ui") | ||
| require("utils") |
There was a problem hiding this comment.
The utils module is required here but doesn't export anything (returns M module table). However, in keymaps.lua (line 3), it's required and used to call utils.cycle_buffer(). This works because the utils module does return M, but the require here in init.lua serves no purpose since nothing from utils is used in init.lua itself. Consider removing this line as utils is already properly loaded when keymaps.lua requires it.
| require("utils") |
| "@biomejs/biome", | ||
| "@getgrit/cli", | ||
| "@github/copilot", | ||
| "@google/jules", | ||
| "@getgrit/cli", | ||
| "@nanocollective/nanocoder", | ||
| "@typescript/native-preview", | ||
| "cline", | ||
| "open-composer" | ||
| "open-composer", | ||
| "typescript" |
There was a problem hiding this comment.
[nitpick] The trustedDependencies array is not sorted alphabetically (similar to the dependencies). This array has been reordered but not fully sorted. Consider maintaining alphabetical order:
"trustedDependencies": [
"@biomejs/biome",
"@getgrit/cli",
"@github/copilot",
"@google/jules",
"@nanocollective/nanocoder",
"@typescript/native-preview",
"cline",
"open-composer",
"typescript"
]There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (19)
nix-darwin/config/homebrew.nix (1)
89-89: Consider sortingtailscale-appalphabetically.The cask
tailscale-appis placed at the end of the list but should be positioned between"slack"and"visual-studio-code"for alphabetical consistency. Based on coding guidelines, configuration lists should be sorted alphabetically when possible."slack" + "tailscale-app" "visual-studio-code" "visual-studio-code@insiders" "vscodium" "warp" "wezterm" "windsurf" "zed" "zoom" - "tailscale-app" ];home-manager/programs/neovim/lua/autocmds.lua (4)
107-120: Window closes before async operation completes.The
vim.cmd("silent! close")executes immediately after startingvim.system, not after it completes. This can be confusing since the user sees the window close but success/error notifications may appear much later in a different context.Consider moving the close inside the callback or awaiting completion:
vim.keymap.set("n", "gp", function() - async_git({ "push", "--quiet" }, "Pushed!", "Push failed!") - vim.cmd("silent! close") + vim.cmd("silent! close") + async_git({ "push", "--quiet" }, "Pushed!", "Push failed!") end, buf_opts)Or keep the window open until completion by moving close into the callback.
153-160: Empty placeholder callback.The Terminal augroup has no functionality. Either add the intended terminal settings or remove the placeholder to avoid dead code.
32-44: Consolidate duplicate gitcommit autocmds.These two autocmds for the same filetype can be merged into a single callback:
-autocmd("FileType", { - group = gitcommit_group, - pattern = "gitcommit", - command = "startinsert", -}) -autocmd("FileType", { - group = gitcommit_group, - pattern = "gitcommit", - callback = function() - vim.opt_local.spell = true - vim.opt_local.textwidth = 72 - end, -}) +autocmd("FileType", { + group = gitcommit_group, + pattern = "gitcommit", + callback = function() + vim.cmd("startinsert") + vim.opt_local.spell = true + vim.opt_local.textwidth = 72 + end, +})
46-58: Minor: Simplify the reload command.The
:e %command has redundant syntax.- vim.cmd([[ :e % ]]) + vim.cmd("edit %")home-manager/programs/neovim/lua/telescope.lua (1)
57-67: Consider adding--excludepatterns to fd command.The
--hiddenflag will include dotfiles, which is often desired. However, you may want to exclude common directories like.git,node_modules, etc., to avoid noise:builtin.find_files(ivy({ find_command = { "fd", "--type", "f", "--strip-cwd-prefix", "--hidden", + "--exclude", + ".git", }, }))This is optional as fd respects
.gitignoreby default.home-manager/programs/neovim/lua/completion.lua (1)
22-35: Tab navigation doesn't integrate with LuaSnip jump points.The current Tab/S-Tab mappings only handle cmp visibility. Consider adding LuaSnip jump support for snippet placeholders:
["<Tab>"] = cmp.mapping(function(fallback) + local luasnip = require("luasnip") if cmp.visible() then cmp.select_next_item() + elseif luasnip.expand_or_jumpable() then + luasnip.expand_or_jump() else fallback() end end, { "i", "s" }), ["<S-Tab>"] = cmp.mapping(function(fallback) + local luasnip = require("luasnip") if cmp.visible() then cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) else fallback() end end, { "i", "s" }),home-manager/programs/neovim/init.lua (1)
20-27: Consider usingvim.uvinstead ofvim.loop.
vim.loopis deprecated in Neovim 0.10+ in favor ofvim.uv. While it still works, updating ensures forward compatibility.-local init_path = vim.loop.fs_realpath(init_source) or init_source +local init_path = vim.uv.fs_realpath(init_source) or init_sourcehome-manager/programs/neovim/lua/settings.lua (1)
50-51: Suppressing all deprecation warnings may hide important issues.Completely overwriting
vim.deprecateto a no-op will silence all deprecation warnings, including those that indicate breaking changes in future Neovim versions. Consider a more targeted approach or at least add a TODO to revisit this.-- Suppress deprecation warnings (temporary until plugins update) -vim.deprecate = function() end +-- TODO: Remove once plugins are updated for Neovim 0.11+ +vim.deprecate = function() endAlternatively, consider logging deprecations to a file instead of completely suppressing them.
home-manager/programs/neovim/lua/lsp.lua (2)
10-10: Consider using<leader>cainstead of barecafor code action.The
camapping without a leader prefix may conflict with other mappings (likecfor change followed bya) and is inconsistent with other leader-prefixed mappings like<leader>rnand<leader>D.- vim.keymap.set("n", "ca", vim.lsp.buf.code_action, opts) + vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, opts)
63-69: Clarify intent: Empty strings for ERROR, WARN, and INFO signs.The diagnostic signs for ERROR, WARN, and INFO are set to empty strings while HINT has an icon. If this is intentional (relying on virtual text only for these severities), consider adding a brief comment explaining the design choice.
signs = { text = { + -- Using virtual text for these severities; signs intentionally hidden [vim.diagnostic.severity.ERROR] = "", [vim.diagnostic.severity.WARN] = "", [vim.diagnostic.severity.INFO] = "", [vim.diagnostic.severity.HINT] = "", }, },home-manager/programs/neovim/lua/terminal.lua (3)
62-68: Consider using module exports instead of global functions.Defining functions as globals (
TogglePrimaryTerm,ToggleSecondaryTerm, etc.) pollutes the global namespace. Consider returning a module table instead.-function TogglePrimaryTerm() - toggle_term(1) -end - -function ToggleSecondaryTerm() - toggle_term(2) -end +local M = {} + +function M.toggle_primary() + toggle_term(1) +end + +function M.toggle_secondary() + toggle_term(2) +endThen at the end of the file:
return MUpdate keymaps to use
require("terminal").toggle_primary().Also applies to: 88-94
70-86: Redundant close/open when terminal is already open.When cycling to a terminal that's already open (line 75), the code closes all other terminals, then closes and reopens the target terminal (lines 83-84). This causes unnecessary flicker. If the target is already open and focused, you may want to skip the close/open cycle.
local function cycle(step) local len = #term_sequence current_index = ((current_index - 1 + step) % len) + 1 local next_count = term_sequence[current_index] local term = terms[next_count] if not term:is_open() then toggle_term(next_count) else + -- Terminal is already open; close others and refocus for _, t in pairs(terms) do if t ~= term and t:is_open() then t:close() end end - term:close() - term:open() + -- Only reopen if we need to ensure insert mode + vim.cmd("startinsert!") end end
10-15: Unreachable branch in size function.The
toggleterm.setupconfiguresdirection = "horizontal", andcreate_termalso usesdirection = "horizontal". Theelsebranch returning20will never execute.size = function(term) - if term.direction == "horizontal" then - return math.floor(vim.o.lines * 0.3) - end - return 20 + return math.floor(vim.o.lines * 0.3) end,Or keep the branch if you plan to support vertical terminals in the future.
home-manager/programs/neovim/lua/ui.lua (2)
52-54: Consider usinglualine.refresh()instead of fulllualine.setup().Calling
lualine.setup()on every theme change reinitializes the entire plugin. If only the theme needs updating,lualine.refresh()may be more efficient.-- Refresh lualine to update theme if package.loaded["lualine"] then - lualine.setup(lualine_config) + require("lualine").refresh() endNote: Verify that
refresh()properly picks up the new background value for the dynamic theme function.Also applies to: 60-62
142-145: Minor: Inconsistent keymap comment for 'I'.The comment says "Toggle dotfiles" but the action is
toggle_hidden_filter. The comment for 'H' says "Toggle dotfiles" but maps totoggle_gitignore_filter. Consider updating for clarity.- -- @keymap H: Toggle dotfiles (nvim-tree) + -- @keymap H: Toggle git-ignored files (nvim-tree) vim.keymap.set("n", "H", api.tree.toggle_gitignore_filter, opts("Toggle Git Ignore")) - -- @keymap I: Toggle dotfiles (nvim-tree) + -- @keymap I: Toggle hidden/dotfiles (nvim-tree) vim.keymap.set("n", "I", api.tree.toggle_hidden_filter, opts("Toggle Dotfiles"))home-manager/programs/neovim/lua/plugins.lua (1)
110-113: Consider increasing the format timeout for larger files.The 500ms timeout might be insufficient for formatting large files, especially with formatters like black or biome that can be slower on complex codebases. Consider increasing to at least 1000-2000ms or making this configurable.
Apply this diff to increase the timeout:
format_on_save = { - timeout_ms = 500, + timeout_ms = 2000, lsp_fallback = true, },home-manager/programs/neovim/lua/keymaps.lua (2)
46-46: Potentially destructive operation - wipes all buffers without confirmation.The
%bwipeout!command force-wipes all buffers. Consider adding a confirmation prompt or using a less destructive alternative for this keymap.Consider adding a confirmation:
-- @keymap <leader>bad: Wipe all buffers -keymap("n", "<leader>bad", ":%bwipeout!<cr>:intro<cr>", opts) +keymap("n", "<leader>bad", function() + if vim.fn.confirm("Wipe all buffers?", "&Yes\n&No", 2) == 1 then + vim.cmd("%bwipeout!") + vim.cmd("intro") + end +end, opts)
58-74: Terminal functions are called as globals without explicit import, creating an implicit dependency that works by accident.The review comment is correct. Terminal.lua defines
TogglePrimaryTerm(),ToggleSecondaryTerm(),CycleNextTerm(), andCyclePreviousTerm()as global functions (lines 62, 66, 88, 92), but keymaps.lua never requires the terminal module. While the code currently works because these functions are called inside keymap callbacks (executed at runtime, after terminal.lua has been loaded in init.lua), this pattern is fragile and could break if:
- The loading order in init.lua is changed
- Code is refactored to call these functions at module load time
- The module structure changes
The suggested refactoring to use
require("terminal")and call functions as module methods is a valid improvement that would eliminate the implicit dependency and make the code more robust.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (21)
flake.nix(1 hunks)home-manager/packages/default.nix(2 hunks)home-manager/programs/neovim/init.lua(1 hunks)home-manager/programs/neovim/lua/ai.lua(1 hunks)home-manager/programs/neovim/lua/autocmds.lua(1 hunks)home-manager/programs/neovim/lua/completion.lua(1 hunks)home-manager/programs/neovim/lua/keymaps.lua(1 hunks)home-manager/programs/neovim/lua/lsp.lua(1 hunks)home-manager/programs/neovim/lua/plugins.lua(1 hunks)home-manager/programs/neovim/lua/settings.lua(1 hunks)home-manager/programs/neovim/lua/telescope.lua(1 hunks)home-manager/programs/neovim/lua/terminal.lua(1 hunks)home-manager/programs/neovim/lua/treesitter.lua(1 hunks)home-manager/programs/neovim/lua/ui.lua(1 hunks)home-manager/programs/neovim/lua/utils.lua(1 hunks)home-manager/programs/neovim/nvim-pack-lock.json(10 hunks)lib/env.nix(1 hunks)nix-darwin/config/dock.nix(1 hunks)nix-darwin/config/homebrew.nix(1 hunks)package.json(1 hunks)treefmt.toml(1 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.nix
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.nix: Use nixfmt for formatting all Nix files
Document complex configurations with comments in Nix files
**/*.nix: Use 2 spaces for indentation in Nix files
Keep line length under 100 characters in Nix files
Sort attribute sets alphabetically in Nix files
Use consistent spacing around operators in Nix files
Format lists and sets consistently in Nix filesUse treefmt.toml for formatting Nix files
**/*.nix: UsemkOptionfor configurable options in Nix modules
Implement proper typing for all options in Nix modules
Follow the Nix expression language style guide
Files:
nix-darwin/config/homebrew.nixflake.nixlib/env.nixnix-darwin/config/dock.nixhome-manager/packages/default.nix
nix-darwin/**/*.nix
📄 CodeRabbit inference engine (CLAUDE.md)
Use Homebrew only for macOS-specific applications
Files:
nix-darwin/config/homebrew.nixnix-darwin/config/dock.nix
**/*.{json,yaml,yml,toml}
📄 CodeRabbit inference engine (.cursor/rules/formatting.mdc)
**/*.{json,yaml,yml,toml}: Use consistent indentation (2 spaces) in configuration files
Sort keys alphabetically when possible in configuration files
Use clear, descriptive names in configuration files
Files:
treefmt.tomlhome-manager/programs/neovim/nvim-pack-lock.jsonpackage.json
**/*.{yaml,yml,toml}
📄 CodeRabbit inference engine (.cursor/rules/formatting.mdc)
Add comments for complex configurations
Files:
treefmt.toml
flake.nix
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
Maintain flake.nix as the main Nix configuration with proper structure
Always pin package versions in
flake.lock
Files:
flake.nix
**/default.nix
📄 CodeRabbit inference engine (CLAUDE.md)
Use
default.nixfiles for module exports
Files:
home-manager/packages/default.nix
home-manager/**/*.nix
📄 CodeRabbit inference engine (.cursor/rules/home-manager.mdc)
home-manager/**/*.nix: Use typed options whenever possible in Nix configurations
Document all configuration options in Nix modules and programs
Follow home-manager's module structure and keep configurations modular
Use proper indentation and formatting in Nix configuration files
Files:
home-manager/packages/default.nix
**/*.{js,ts,jsx,tsx,json}
📄 CodeRabbit inference engine (CLAUDE.md)
Use Biome with 2-space indentation, 80-character line width, double quotes, and trailing commas (ES5) for JSON/JavaScript/TypeScript files
Files:
home-manager/programs/neovim/nvim-pack-lock.jsonpackage.json
**/*.{js,jsx,ts,tsx,json}
📄 CodeRabbit inference engine (.cursor/rules/formatting.mdc)
**/*.{js,jsx,ts,tsx,json}: Format JavaScript/TypeScript/JSON files using Biome with 2-space indentation and 80 character line width
Enable Biome linter with recommended rules for JavaScript/TypeScript/JSON files
Files:
home-manager/programs/neovim/nvim-pack-lock.jsonpackage.json
**/*.{js,jsx,ts,tsx,json,jsonc,md}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
Use Biome for code formatting as configured in biome.json
Files:
home-manager/programs/neovim/nvim-pack-lock.jsonpackage.json
🧠 Learnings (15)
📚 Learning: 2025-11-25T09:34:23.224Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:34:23.224Z
Learning: Applies to nix-darwin/**/*.nix : Use Homebrew only for macOS-specific applications
Applied to files:
nix-darwin/config/homebrew.nixnix-darwin/config/dock.nixhome-manager/packages/default.nix
📚 Learning: 2025-11-25T09:34:40.062Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-11-25T09:34:40.062Z
Learning: Document all major changes in Nix configurations
Applied to files:
nix-darwin/config/homebrew.nixnix-darwin/config/dock.nixhome-manager/packages/default.nix
📚 Learning: 2025-11-25T09:34:40.062Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-11-25T09:34:40.062Z
Learning: Applies to **/*.nix : Use treefmt.toml for formatting Nix files
Applied to files:
treefmt.tomlflake.nix
📚 Learning: 2025-11-25T09:34:23.224Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:34:23.224Z
Learning: Applies to **/*.{sh,bash} : Use shfmt with 2-space indentation for shell scripts
Applied to files:
treefmt.toml
📚 Learning: 2025-11-25T09:34:23.224Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:34:23.224Z
Learning: Run `make format` before committing code
Applied to files:
treefmt.toml
📚 Learning: 2025-11-25T09:34:23.224Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:34:23.224Z
Learning: Applies to **/*.nix : Use nixfmt for formatting all Nix files
Applied to files:
treefmt.tomlflake.nix
📚 Learning: 2025-11-25T09:34:40.062Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-11-25T09:34:40.062Z
Learning: Applies to flake.nix : Maintain flake.nix as the main Nix configuration with proper structure
Applied to files:
flake.nixhome-manager/packages/default.nix
📚 Learning: 2025-11-25T09:34:55.014Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: .cursor/rules/home-manager.mdc:0-0
Timestamp: 2025-11-25T09:34:55.014Z
Learning: Applies to home-manager/programs/**/default.nix : Program configurations must include all necessary dependencies in their configuration
Applied to files:
home-manager/packages/default.nix
📚 Learning: 2025-11-25T09:34:23.224Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:34:23.224Z
Learning: Prefer Nix packages over external package managers
Applied to files:
home-manager/packages/default.nix
📚 Learning: 2025-11-25T09:34:55.014Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: .cursor/rules/home-manager.mdc:0-0
Timestamp: 2025-11-25T09:34:55.014Z
Learning: Applies to home-manager/programs/**/*.nix : Follow program-specific best practices in program configuration files
Applied to files:
home-manager/packages/default.nix
📚 Learning: 2025-11-25T09:34:23.224Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:34:23.224Z
Learning: Applies to **/default.nix : Use `default.nix` files for module exports
Applied to files:
home-manager/packages/default.nix
📚 Learning: 2025-11-25T09:34:40.062Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-11-25T09:34:40.062Z
Learning: Applies to **/*.{js,jsx,ts,tsx,json,jsonc,md} : Use Biome for code formatting as configured in biome.json
Applied to files:
package.json
📚 Learning: 2025-11-25T09:34:23.224Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:34:23.224Z
Learning: Applies to **/*.{js,ts,jsx,tsx,json} : Use Biome with 2-space indentation, 80-character line width, double quotes, and trailing commas (ES5) for JSON/JavaScript/TypeScript files
Applied to files:
package.json
📚 Learning: 2025-11-25T09:34:32.423Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: .cursor/rules/formatting.mdc:0-0
Timestamp: 2025-11-25T09:34:32.423Z
Learning: Applies to **/*.{js,jsx,ts,tsx,json} : Enable Biome linter with recommended rules for JavaScript/TypeScript/JSON files
Applied to files:
package.json
📚 Learning: 2025-11-25T09:34:32.423Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: .cursor/rules/formatting.mdc:0-0
Timestamp: 2025-11-25T09:34:32.423Z
Learning: Applies to **/*.{js,jsx,ts,tsx,json} : Format JavaScript/TypeScript/JSON files using Biome with 2-space indentation and 80 character line width
Applied to files:
package.json
🧬 Code graph analysis (1)
home-manager/programs/neovim/lua/keymaps.lua (1)
home-manager/programs/neovim/lua/terminal.lua (4)
TogglePrimaryTerm(62-64)ToggleSecondaryTerm(66-68)CycleNextTerm(88-90)CyclePreviousTerm(92-94)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
- GitHub Check: cubic · AI code reviewer
- GitHub Check: Agent
- GitHub Check: Cursor Bugbot
- GitHub Check: lua-neovim
- GitHub Check: lua-hammerspoon
- GitHub Check: nix-nixos
- GitHub Check: nix-linux
- GitHub Check: nix-darwin
- GitHub Check: docker-build-push (linux/amd64, amd64, ubuntu-latest)
- GitHub Check: docker-build-push (linux/arm64, arm64, ubuntu-24.04-arm)
- GitHub Check: e2e-run (MacOS, macos-latest)
- GitHub Check: e2e-run (NixOS, ubuntu-latest)
- GitHub Check: e2e-run (Ubuntu, ubuntu-latest)
🔇 Additional comments (27)
package.json (2)
14-22: Dependencies include pre-release and alpha versions.The new dependencies include pre-release versions:
@getgrit/cliat^0.1.0-alpha.1743007075(alpha)@typescript/native-previewat^7.0.0-dev.20251127.1(dev preview)These are acceptable for a dotfiles repository but may introduce breaking changes. Ensure you're prepared to handle potential API instability.
24-34: trustedDependencies correctly updated.All newly added dependencies are appropriately included in
trustedDependencies, ensuring they can execute lifecycle scripts.nix-darwin/config/dock.nix (1)
31-34: LGTM!The new dock entries for Tailscale and VS Code Insiders are correctly positioned alongside related applications, and they align with the corresponding Homebrew cask additions in
homebrew.nix.home-manager/programs/neovim/lua/utils.lua (3)
3-90: Buffer cycling implementation is well-structured.The
cycle_bufferfunction handles edge cases properly with valid buffer checks, deduplication, and wrapping logic. Minor note: line 30 (buffer_set[current_buf] = true) is technically redundant sincebuffer_setisn't used after this point, but it's harmless and maintains consistency.
92-98: Verify intended behavior for single-item quickfix lists.The condition
size > 1means the quickfix window opens only when there are 2+ items. A single-item list will close the quickfix window. If you intend to show the quickfix for any non-empty list, consider:function M.copen() - if vim.fn.getqflist({ size = 0 }).size > 1 then + if vim.fn.getqflist({ size = 0 }).size > 0 then vim.cmd("copen") else vim.cmd("cclose") end endIf hiding single-item lists is intentional (e.g., for cleaner UX when there's only one result), the current logic is fine.
100-104: LGTM!The
cclearfunction correctly usessetqflistwith the"r"action to replace and clear the quickfix list.home-manager/programs/neovim/lua/ai.lua (1)
1-3: Perfect! I've completed the verification. Let me summarize my findings:Verification Results:
- ✅ sidekick.nvim IS declared as a dependency in
plugins.lua(line 79, under AI category)- ✅ ai.lua IS properly required in
init.lua(line 40)- ✅ Loading order is correct: plugins are loaded (line 33) before ai module (line 40)
- ✅ The empty config
{}is valid and appropriateThe original review's concern about verifying the plugin installation is unnecessary—the plugin is already properly configured. Additionally, the original review contains non-standard tags that should be removed.
LGTM!
The sidekick.nvim setup is correctly configured. The plugin is properly declared as a dependency in
plugins.lua(line 79), andai.luais loaded ininit.luaafter plugins are initialized. The empty options table uses sensible defaults.home-manager/programs/neovim/nvim-pack-lock.json (1)
1-257: Lock file additions look good.The new plugin entries are well-structured with consistent
revandsrcfields. Keys are alphabetically sorted as expected. The plugins align with the modular Neovim configuration changes in this PR.treefmt.toml (1)
20-23: Stylua formatter addition looks good.The Lua formatter entry follows the established pattern. Consider adding explicit options for consistency with the Neovim config's indentation style (tabs vs spaces):
[formatter.lua] command = "stylua" +options = ["--indent-type", "Tabs"] includes = ["*.lua"]This is optional since stylua can also read from a
.stylua.tomlif present. Based on learnings, treefmt.toml is the expected location for formatting configuration.lib/env.nix (1)
1-3: Environment detection module is functional.The
builtins.getEnvusage is appropriate for CI detection. Note that this makes the expression impure—evaluations will differ based on environment variables at eval time. This is expected and necessary for conditional package inclusion.Consider documenting the expected environment variables:
{ + # CI detection: true when running in CI or Docker environments + # Set CI=1 or IN_DOCKER=true to enable isCI = builtins.getEnv "CI" != "" || builtins.getEnv "IN_DOCKER" == "true"; }home-manager/programs/neovim/lua/telescope.lua (1)
42-44: Extension loading order is correct.The gh extension requires
telescope-github.nvimwhich is present in the lock file. Good practice loading extensions after setup.home-manager/packages/default.nix (2)
1-3: Clean import pattern for environment detection.The use of
inheritto destructureisCIfrom the imported module is idiomatic Nix. This centralizes CI detection logic inlib/env.nixfor reuse across the codebase.
92-98: Good separation of CI-excluded packages.Heavy GUI applications like
chromium,github-desktop,signal-desktop, andvlcare appropriately excluded from CI builds to reduce build times and avoid unnecessary downloads. This is a sensible optimization.flake.nix (1)
170-172: Lua formatter configuration is correct—no conflicts or duplication.The review comment incorrectly flagged a potential conflict. Here's why there is none:
- treefmt.toml defines the base lua formatter configuration (command: "stylua", includes: "*.lua")
- flake.nix treefmtSettings overrides the command to use the Nix-wrapped executable (
lib.getExe pkgs.stylua)- treefmt.programs.stylua.enable enables stylua in the devenv integration layer
This is the correct architecture: the base config lives in treefmt.toml, the Nix package override happens in flake.nix, and the devenv enablement is separate. All formatters (nix, biome, json, shell, lua) follow this identical pattern. No duplication or conflict exists.
home-manager/programs/neovim/init.lua (2)
10-14: LGTM! Clean helper for extending package.path.The duplicate check with
string.find(..., 1, true)using plain matching is correct and prevents redundant path entries.
32-43: Module loading order looks intentional and correct.Settings before plugins ensures vim options are configured before plugins initialize. The dependency chain (settings → plugins → autocmds → keymaps → lsp → etc.) is logical.
home-manager/programs/neovim/lua/settings.lua (1)
26-31: LGTM! Directory creation with proper error handling.Using
"p"flag formkdircorrectly creates parent directories as needed and doesn't error if the directory already exists.home-manager/programs/neovim/lua/ui.lua (3)
14-41: LGTM! Dynamic theme configuration for lualine.The theme function and lualine configuration are well-structured with proper section organization.
95-101: Multiple keys mapped to the same action (horizontal split).Both
s(line 97) andi(line 101) are mapped toapi.node.open.horizontal. If intentional, this is fine for muscle-memory compatibility; otherwise, consider removing the duplicate.
149-163: LGTM! Clean plugin initialization.The remaining plugin setups with empty configs are appropriate for using plugin defaults. Good use of comments documenting the purpose and source of each plugin.
home-manager/programs/neovim/lua/plugins.lua (2)
94-94: AI summary inconsistency detected.The AI-generated summary mentions formatters like "prettier" and "ruff", but the actual code uses "biome" for JavaScript/TypeScript and "black" for Python. The code takes precedence.
30-30:makeis already included as a managed dependency viagnumakein home-manager packages and installed byinstall.sh.The telescope-fzf-native plugin does require
maketo build from source. However, this dependency is already handled by the repository's build system:
install.sh(lines 28–36) explicitly checks for and installsmakeif not presenthome-manager/packages/default.nixincludesgnumakeas a managed package- The plugin build executes in an environment where this dependency is available
No action needed—the build dependency is properly managed.
home-manager/programs/neovim/lua/treesitter.lua (2)
1-27: LGTM!The plugin configurations are clean and well-documented with source URLs. Using default configurations is appropriate for these plugins, as they work well out of the box.
110-162: LGTM!The textobjects configuration is comprehensive and follows Vim conventions. The keymaps for swapping, moving, and selecting code structures are well-organized and shouldn't conflict with standard Vim keybindings.
home-manager/programs/neovim/lua/keymaps.lua (3)
1-11: LGTM!The keymap setup is clean and well-structured. The Space leader key is a good choice, and the opts table with noremap and silent defaults will prevent mapping recursion and suppress command-line messages.
77-152: LGTM!These keymap sections are well-organized and follow Neovim best practices:
- Navigation keymaps with centering improve UX
- Flash integration is clean
- Git operations properly leverage vim-fugitive and gitsigns
- Visual mode operations enhance workflow
- Insert mode undo breakpoints after punctuation are a nice productivity touch
155-224: LGTM!The diagnostics and code operations sections are comprehensive:
- Trouble integration provides multiple entry points for different diagnostic views
- Code navigation keymaps (Oil, GrugFar, other.nvim, Neogen) are well-organized
- Treesj setup and usage are clean
- Which-key group definitions will provide helpful hints to users
| cmp.setup.filetype("gitcommit", { | ||
| sources = cmp.config.sources({ | ||
| { name = "git" }, -- You can specify the `git` source if you have it configured | ||
| }, { | ||
| { name = "buffer" }, | ||
| }), | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for lock file and cmp-git references
echo "=== Searching for lock files ==="
find . -name "*lock*" -type f | head -20
echo ""
echo "=== Searching for cmp-git in the repo ==="
rg -i "cmp-git|petertriho" --type=json --type=nix --type=yaml -nRepository: shunkakinoki/dotfiles
Length of output: 215
🏁 Script executed:
#!/bin/bash
# Check the nvim-pack-lock.json file
echo "=== Checking nvim-pack-lock.json file size ==="
wc -l ./home-manager/programs/neovim/nvim-pack-lock.json
echo ""
echo "=== Searching for 'git' in the lock file ==="
rg -i "git" ./home-manager/programs/neovim/nvim-pack-lock.json -n
echo ""
echo "=== Listing all plugins in lock file ==="
rg '"repo"' ./home-manager/programs/neovim/nvim-pack-lock.json -n | head -30Repository: shunkakinoki/dotfiles
Length of output: 4245
🏁 Script executed:
#!/bin/bash
# Read the completion.lua file to verify the configuration
echo "=== Reading completion.lua ==="
cat -n ./home-manager/programs/neovim/lua/completion.luaRepository: shunkakinoki/dotfiles
Length of output: 2956
🏁 Script executed:
#!/bin/bash
# Search web for cmp-git plugin and nvim-cmp missing source handling
echo "=== Checking cmp-git plugin ==="
rg -i "petertriho/cmp-git" . 2>/dev/null || echo "No references found"
echo ""
echo "=== Checking if there's any documentation about missing sources ==="
fd "README*" ./home-manager/programs/neovim --type f | head -5Repository: shunkakinoki/dotfiles
Length of output: 185
Based on my verification, the review comment is accurate and identifies a real issue. Here's what I confirmed:
Verification Results:
- ✅
cmp-gitplugin is NOT innvim-pack-lock.json(checked 256-line file, found no petertriho/cmp-git) - ✅
completion.lualine 49 references{ name = "git" }source unconditionally - ✅ The comment on line 49 acknowledges the source is optional ("if you have it configured"), but this doesn't prevent the configuration from being loaded
- ✅ No error handling exists for missing sources; nvim-cmp will fail when trying to initialize a non-existent source provider
The issue is legitimate: the configuration attempts to use a completion source (cmp-git) that is not installed. While there's a fallback to the buffer source, the git source entry itself will cause errors during initialization.
Missing cmp-git plugin.
The { name = "git" } source on line 49 requires the cmp-git plugin, which is not installed in your setup (verified in nvim-pack-lock.json). This will cause completion source initialization to fail for gitcommit buffers.
Either install cmp-git or remove this source from the configuration:
cmp.setup.filetype("gitcommit", {
sources = cmp.config.sources({
- { name = "git" }, -- You can specify the `git` source if you have it configured
- }, {
{ name = "buffer" },
}),
})📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| cmp.setup.filetype("gitcommit", { | |
| sources = cmp.config.sources({ | |
| { name = "git" }, -- You can specify the `git` source if you have it configured | |
| }, { | |
| { name = "buffer" }, | |
| }), | |
| }) | |
| cmp.setup.filetype("gitcommit", { | |
| sources = cmp.config.sources({ | |
| { name = "buffer" }, | |
| }), | |
| }) |
🤖 Prompt for AI Agents
In home-manager/programs/neovim/lua/completion.lua around lines 47 to 53, the
cmp configuration unconditionally includes the { name = "git" } source which
requires the cmp-git plugin (not present in nvim-pack-lock.json) and will cause
nvim-cmp to fail; fix by either adding cmp-git to your plugin list
(nvim-pack-lock.json / plugin manager) or remove the { name = "git" } entry from
the cmp.setup.filetype("gitcommit", ...) block, or guard its inclusion with a
runtime check (e.g., pcall(require, "cmp_git") or a boolean flag) so the git
source is only registered when the plugin is installed.
| for name, config in pairs(servers) do | ||
| config.on_attach = on_attach | ||
| config.capabilities = capabilities | ||
| vim.lsp.config(name, config) | ||
| end | ||
| vim.lsp.enable(vim.tbl_keys(servers)) |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Neovim vim.lsp.config vim.lsp.enable API version 0.11 introduction
💡 Result:
Short summary — what changed in v0.11
-
Neovim 0.11 introduced a built-in LSP configuration API: vim.lsp.config and vim.lsp.enable. Use vim.lsp.config(...) to define or modify server configs and vim.lsp.enable(...) to auto-start/stop those configs for matching buffers. [1]
-
Purpose: unify/centralize LSP config into core (less boilerplate), allow plugins (and your local lsp/*.lua) to provide configs that are merged with user overrides, and replace the old programmatic setup API used by require('lspconfig').setup(...). [1][2]
-
Migration notes: nvim-lspconfig now provides server configs under an lsp/ directory consumed by vim.lsp.config; the old require('lspconfig') "framework"/setup API is deprecated and users are encouraged to migrate to vim.lsp.config + vim.lsp.enable (and use LspAttach for on_attach behavior). See the project migration issue/README for details and examples. [2][3]
Quick example
- Define defaults or a server:
vim.lsp.config('clangd', { cmd = {'clangd'}, filetypes = {'c','cpp'} }) - Enable it (auto-starts on matching filetypes/root):
vim.lsp.enable('clangd')
(You can pass a list to vim.lsp.enable and pass false to disable.) [1]
Sources
[1] Neovim LSP docs (:help lsp) — vim.lsp.config / vim.lsp.enable (Since: 0.11.0).
[2] nvim-lspconfig README / migration notes (migration to vim.lsp.config).
[3] nvim-lspconfig GitHub discussion/issue about migrating to vim.lsp.config.
🏁 Script executed:
#!/bin/bash
# Find Neovim version requirements in the repository
echo "=== Searching for Neovim version requirements ==="
find . -type f \( -name "*.md" -o -name "*.nix" -o -name "*.lua" -o -name "*.toml" -o -name "*.json" \) | head -20 | xargs grep -l "neovim" 2>/dev/null | head -10
echo ""
echo "=== Checking file location and size ==="
wc -l home-manager/programs/neovim/lua/lsp.lua 2>/dev/null || echo "File not found, searching..."
find . -name "lsp.lua" -type f 2>/dev/nullRepository: shunkakinoki/dotfiles
Length of output: 242
🏁 Script executed:
#!/bin/bash
# Read the full lsp.lua file
echo "=== Full lsp.lua file ==="
cat -n home-manager/programs/neovim/lua/lsp.lua
echo ""
echo "=== Searching for Neovim version specifications ==="
# Search for version constraints in common config files
find . -type f \( -name "*.nix" -o -name "flake.lock" -o -name "init.lua" -o -name "*.json" \) | xargs grep -i "neovim\|nvim" 2>/dev/null | grep -i "version\|0\.[0-9]\|unstable" | head -20Repository: shunkakinoki/dotfiles
Length of output: 2559
🏁 Script executed:
#!/bin/bash
echo "=== Searching for Neovim in nix files ==="
find . -name "*.nix" -type f | head -20 | xargs grep -A3 -B3 "neovim\|nvim" 2>/dev/null | head -50
echo ""
echo "=== Looking for flake.nix or default.nix ==="
find . -name "flake.nix" -o -name "default.nix" 2>/dev/null | head -5
echo ""
echo "=== Searching in README files ==="
find . -name "README*" -type f | xargs grep -i "neovim\|nvim" 2>/dev/null | head -10Repository: shunkakinoki/dotfiles
Length of output: 564
Based on my verification, I can now provide the rewritten review comment:
Add Neovim 0.11+ version requirement or implement version guard for LSP configuration APIs.
The vim.lsp.config and vim.lsp.enable functions were introduced in Neovim 0.11.0. Your code uses these APIs without a version guard, but the project's devenv.nix uses pkgs.neovim without pinning a specific version. Either add an explicit Neovim 0.11+ version constraint to your nix configuration or add a runtime version check (e.g., vim.fn.has('nvim-0.11')) to gracefully handle earlier versions.
for name, config in pairs(servers) do
config.on_attach = on_attach
config.capabilities = capabilities
vim.lsp.config(name, config)
end
vim.lsp.enable(vim.tbl_keys(servers))
🤖 Prompt for AI Agents
In home-manager/programs/neovim/lua/lsp.lua around lines 40 to 45, the code
calls vim.lsp.config and vim.lsp.enable which only exist in Neovim 0.11+, so add
a version guard or require a 0.11+ pin: either (A) add a runtime check using
vim.fn.has('nvim-0.11') and only run the vim.lsp.* block when true (otherwise
fall back to the older lspconfig setup for each server or skip), or (B) enforce
Neovim >= 0.11 in the Nix config by pinning pkgs.neovim to a 0.11+ release;
implement one of these fixes and ensure the fallback path configures servers via
require('lspconfig')[name].setup with on_attach and capabilities when the
runtime check fails.
| require("conform").setup({ | ||
| formatters_by_ft = { | ||
| lua = { "stylua" }, | ||
| python = { "black" }, | ||
| javascript = { "biome" }, | ||
| typescript = { "biome" }, | ||
| javascriptreact = { "biome" }, | ||
| typescriptreact = { "biome" }, | ||
| json = { "biome" }, | ||
| yaml = { "biome" }, | ||
| markdown = { "biome" }, | ||
| html = { "biome" }, | ||
| css = { "biome" }, | ||
| go = { "gofmt", "goimports" }, | ||
| nix = { "nixfmt" }, | ||
| }, | ||
| format_on_save = { | ||
| timeout_ms = 500, | ||
| lsp_fallback = true, | ||
| }, | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# First, check the repository structure to understand the context
echo "=== Repository Structure ==="
git ls-files | head -20
echo ""
echo "=== Checking for nix configuration ==="
find . -name "*.nix" -type f | head -20Repository: shunkakinoki/dotfiles
Length of output: 1201
🏁 Script executed:
#!/bin/bash
# Find neovim configuration in home-manager
echo "=== Finding neovim configuration ==="
find home-manager/programs -name "*neovim*" -o -name "*nvim*" | head -20
echo ""
echo "=== Checking the specific plugins.lua file ==="
find . -path "*neovim/lua/plugins.lua" -o -path "*nvim/lua/plugins.lua"
echo ""
echo "=== Checking devenv.nix ==="
wc -l devenv.nixRepository: shunkakinoki/dotfiles
Length of output: 317
🏁 Script executed:
#!/bin/bash
# Read the plugins.lua file
echo "=== Reading plugins.lua ==="
cat -n home-manager/programs/neovim/lua/plugins.lua
echo ""
echo "=== Reading devenv.nix ==="
cat -n devenv.nix
echo ""
echo "=== Finding home-manager neovim configuration ==="
find home-manager/programs/neovim -name "*.nix"Repository: shunkakinoki/dotfiles
Length of output: 6211
🏁 Script executed:
#!/bin/bash
# Read the neovim home-manager configuration
echo "=== Reading home-manager/programs/neovim/default.nix ==="
cat -n home-manager/programs/neovim/default.nixRepository: shunkakinoki/dotfiles
Length of output: 1009
🏁 Script executed:
#!/bin/bash
# Search for formatter declarations across home-manager
echo "=== Searching for stylua in home-manager ==="
rg -n "stylua" home-manager/ 2>/dev/null || echo "Not found"
echo ""
echo "=== Searching for black in home-manager ==="
rg -n "black" home-manager/ 2>/dev/null || echo "Not found"
echo ""
echo "=== Searching for biome in home-manager ==="
rg -n "biome" home-manager/ 2>/dev/null || echo "Not found"
echo ""
echo "=== Searching for goimports in home-manager ==="
rg -n "goimports" home-manager/ 2>/dev/null || echo "Not found"
echo ""
echo "=== Searching for nixfmt in home-manager ==="
rg -n "nixfmt" home-manager/ 2>/dev/null || echo "Not found"Repository: shunkakinoki/dotfiles
Length of output: 1363
🏁 Script executed:
#!/bin/bash
# Check home-manager/default.nix
echo "=== Reading home-manager/default.nix ==="
wc -l home-manager/default.nix
head -100 home-manager/default.nix
echo ""
echo "=== Reading home-manager/packages/default.nix ==="
wc -l home-manager/packages/default.nixRepository: shunkakinoki/dotfiles
Length of output: 1089
🏁 Script executed:
#!/bin/bash
# Read the full packages/default.nix
echo "=== Reading home-manager/packages/default.nix ==="
cat -n home-manager/packages/default.nixRepository: shunkakinoki/dotfiles
Length of output: 1951
🏁 Script executed:
#!/bin/bash
# Search for extraPackages in neovim config
echo "=== Searching for extraPackages in neovim ==="
rg -n "extraPackages" home-manager/programs/neovim/ 2>/dev/null || echo "Not found"
echo ""
# Check for flake.nix
echo "=== Checking for flake.nix ==="
find . -name "flake.nix" -type f
echo ""
# Check for any documentation about formatters or setup
echo "=== Checking README and FAQ ==="
ls -la *.mdRepository: shunkakinoki/dotfiles
Length of output: 497
🏁 Script executed:
#!/bin/bash
# Check flake.nix for formatter declarations
echo "=== Reading flake.nix ==="
wc -l flake.nix
head -150 flake.nix
echo ""
# Check README and documentation
echo "=== Reading README.md ==="
cat README.md
echo ""
echo "=== Reading FAQ.md ==="
cat FAQ.mdRepository: shunkakinoki/dotfiles
Length of output: 5929
🏁 Script executed:
#!/bin/bash
# Read the rest of flake.nix
echo "=== Reading rest of flake.nix (lines 150-198) ==="
tail -50 flake.nix
echo ""
# Check for treefmt.nix
echo "=== Checking for treefmt.nix ==="
find . -name "treefmt.nix" -type f
echo ""
# Search for formatter configurations in flake.nix
echo "=== Searching for treefmt configuration in flake.nix ==="
rg -n "treefmt" flake.nixRepository: shunkakinoki/dotfiles
Length of output: 2665
🏁 Script executed:
#!/bin/bash
# Read treefmt.toml
echo "=== Reading treefmt.toml ==="
cat -n treefmt.toml
echo ""
# Search for black, gofmt, goimports in entire repo
echo "=== Searching for go package declarations ==="
rg -n "pkgs\.go\b|pkgs\.python" flake.nix home-manager/
echo ""
# List all formatters mentioned in treefmt and compare with conform
echo "=== Summary of available vs configured formatters ==="
echo "Formatters in conform.nvim config:"
echo " - stylua (lua)"
echo " - black (python)"
echo " - biome (javascript, typescript, json, yaml, markdown, html, css)"
echo " - gofmt, goimports (go)"
echo " - nixfmt (nix)"
echo ""
echo "Formatters available in treefmt:"
rg "command = lib.getExe pkgs\." flake.nix | sed 's/.*pkgs\.\([^ ;]*\).*/ - \1/'Repository: shunkakinoki/dotfiles
Length of output: 151
🏁 Script executed:
#!/bin/bash
# Read treefmt.toml
echo "=== Reading treefmt.toml ==="
cat treefmt.tomlRepository: shunkakinoki/dotfiles
Length of output: 558
Some configured formatters are missing from the nix environment, which will cause format_on_save to fail for affected file types.
The conform.nvim setup references six formatters, but only three are provisioned in the nix environment:
Available (via treefmt): stylua, biome, nixfmt
Missing: black (Python), gofmt, goimports (Go)
When format_on_save is triggered on Python or Go files, conform will fail to find these tools and fall back to LSP, potentially degrading the formatting experience. Consider either:
- Adding missing formatters to
home-manager/packages/default.nix:black,go(includes gofmt and goimports), or - Removing them from the conform configuration if they're not needed
🤖 Prompt for AI Agents
In home-manager/programs/neovim/lua/plugins.lua around lines 94 to 114, the
conform.nvim config references formatters (black, gofmt, goimports) that are not
provided by the nix environment which will cause format_on_save to fail for
Python and Go; either add those binaries to the nix profile (e.g., add black and
go to home-manager/packages/default.nix) or remove those formatters from
formatters_by_ft so conform only lists tools actually available (ensure changes
are mirrored in the nix expression and rebuild the environment).
| local lint = require("lint") | ||
| lint.linters_by_ft = { | ||
| python = { "pylint" }, | ||
| javascript = { "eslint" }, | ||
| typescript = { "eslint" }, | ||
| } | ||
|
|
||
| vim.api.nvim_create_autocmd({ "BufWritePost" }, { | ||
| callback = function() | ||
| lint.try_lint() | ||
| end, | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# First, let's understand the repository structure and find related files
echo "=== Repository structure ==="
find . -type f -name "*.lua" -o -name "*.nix" | head -20
echo ""
echo "=== Searching for nvim-lint or lint references ==="
rg -i "nvim-lint|lint" --type lua --type nix -A 2 -B 2 | head -50Repository: shunkakinoki/dotfiles
Length of output: 2107
🏁 Script executed:
#!/bin/bash
# Check the actual file in question
echo "=== Content of plugins.lua around lines 119-130 ==="
if [ -f "home-manager/programs/neovim/lua/plugins.lua" ]; then
sed -n '100,140p' "home-manager/programs/neovim/lua/plugins.lua"
else
echo "File not found, searching for plugins.lua..."
fd "plugins.lua" -e lua
fiRepository: shunkakinoki/dotfiles
Length of output: 747
🌐 Web query:
nvim-lint try_lint missing linters error handling
💡 Result:
Summary — what's happening
- require("lint").try_lint() uses the linters listed in lint.linters_by_ft for the current filetype (or any explicit linter names you pass). If a configured linter's executable or output differs (writes to stderr, returns non‑zero exit code, or prints plain error text when no config/exec is found), nvim-lint will still run the linter and then try to parse its output — which can produce "Could not parse linter output..." or similar messages. [1][2]
How to diagnose & fix
-
Confirm which linters are being run
- Check your lint.linters_by_ft and call try_lint with explicit names to isolate: require('lint').try_lint('eslint_d') or require('lint').try_lint({'eslint_d','other'}). (try_lint() with no args runs linters_by_ft for the buffer.) [1]
-
Ensure the linter executable is found
- Either install the linter in the project, make sure the global exe is on PATH accessible to Neovim, or set your linter's cmd to a full path in require('lint').linters..cmd. Many "missing" errors come from the executable not being found. [1][2]
-
Handle linters that print errors to stderr or exit non‑zero
- Configure the linter entry:
- stream = 'stderr' (or 'both') if the tool writes to stderr.
- ignore_exitcode = true if the linter uses non‑zero exit codes for normal cases.
- add a custom parser (linters..parser) to ignore or transform human error messages (e.g., "No ESLint found" or "No ESLint configuration found") so they don’t cause a parse failure. [1][2]
- Configure the linter entry:
-
Example (Lua)
- Minimal ideas (adapt to your linter):
- set full cmd path: require('lint').linters.eslint_d.cmd = '/usr/local/bin/eslint_d'
- tell plugin to read stderr: require('lint').linters.eslint_d.stream = 'stderr'
- ignore exit code: require('lint').linters.eslint_d.ignore_exitcode = true
- add parser to filter messages (implement parser to return empty table when output contains "No ESLint configuration"). See custom linter docs in README. [1]
- Minimal ideas (adapt to your linter):
Known issues & context
- There are existing issues where eslint_d or other linters produce plain error text (or a missing config) and the built‑in parser fails to parse it; people have reported that ignore_errors/ignore_exitcode alone may not be sufficient and a custom parser or ensuring the correct executable/config is required. See issue discussion for eslint_d examples. [2]
References
- nvim-lint README / linters and custom linter fields (cmd, stream, ignore_exitcode, parser, linters_by_ft, try_lint usage). [1]
- GitHub issue examples showing parse failures when linter prints human error messages (eslint_d / "No ESLint configuration found"). [2]
If you want, paste your linters_by_ft plus the specific linter config and the exact error output you see and I’ll give the exact config or a parser function to swallow that message.
🏁 Script executed:
#!/bin/bash
# Check for any error handling or pcall around lint operations
echo "=== Searching for error handling in lint configuration ==="
rg -i "pcall|try|catch|error" -A 3 -B 3 "lint" --type lua
echo ""
echo "=== Full lint configuration block ==="
sed -n '119,150p' "home-manager/programs/neovim/lua/plugins.lua"Repository: shunkakinoki/dotfiles
Length of output: 459
🏁 Script executed:
#!/bin/bash
# Check for any installation or setup documentation
echo "=== Searching for dependency documentation ==="
fd -e nix -e md | xargs grep -l "pylint\|eslint" | head -10
echo ""
echo "=== Check home-manager neovim configuration ==="
find home-manager/programs/neovim -type f | head -20Repository: shunkakinoki/dotfiles
Length of output: 877
🏁 Script executed:
#!/bin/bash
# Check the neovim nix configuration for linter dependencies
echo "=== Checking default.nix for linter dependencies ==="
cat home-manager/programs/neovim/default.nix | head -100
echo ""
echo "=== Searching for pylint/eslint in nix files ==="
rg "pylint|eslint" --type nix home-manager/programs/neovim/Repository: shunkakinoki/dotfiles
Length of output: 151
Based on my verification, I have enough evidence to rewrite the review comment. The web search confirmed that nvim-lint's try_lint() method requires the configured linter executables to be available in PATH and will produce errors if they are missing. The code contains no error handling around the callback.
Ensure configured linters (pylint, eslint) are available in the environment or wrap the lint call in error handling.
The linting setup calls lint.try_lint() on every BufWritePost without error handling. If pylint or eslint are not installed or not in PATH, this will produce errors on every file save. Either ensure these linters are available as dependencies in your environment, or wrap the callback with pcall() to suppress errors gracefully:
vim.api.nvim_create_autocmd({ "BufWritePost" }, {
callback = function()
pcall(function() lint.try_lint() end)
end,
})| vim.opt.termguicolors = true | ||
| vim.opt.shortmess:append("c") | ||
| vim.opt.timeoutlen = 300 | ||
| vim.opt.winborder = "none" |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Neovim winborder option availability version
💡 Result:
The global 'winborder' option was added for Neovim 0.11 (via PR neovim/neovim#31074). See the options docs and related issue referencing the 0.11 change. [1][2]
Sources:
- Neovim options documentation ('winborder'). [1]
- Issue/notes referencing the new winborder addition in the 0.11 milestone (feat(float): add winborder option neovim/neovim#31074 referenced). [2]
🏁 Script executed:
#!/bin/bash
# Search for Neovim version specifications in the repository
find . -type f \( -name "*.md" -o -name "*.nix" -o -name "*.lua" -o -name "*.json" -o -name "*.toml" \) | head -20Repository: shunkakinoki/dotfiles
Length of output: 531
🏁 Script executed:
#!/bin/bash
# Look for version requirements in README or main config files
rg -i "neovim.*version|minimum.*neovim|nvim.*require" -C 2 | head -50Repository: shunkakinoki/dotfiles
Length of output: 47
🏁 Script executed:
#!/bin/bash
# Check for any version specifications in the neovim settings file and nearby files
fd -e nix -e lua -e md . home-manager/programs/neovim/ 2>/dev/null | head -20Repository: shunkakinoki/dotfiles
Length of output: 678
🏁 Script executed:
#!/bin/bash
# Check the neovim default.nix for version specifications
cat -n home-manager/programs/neovim/default.nix | head -100Repository: shunkakinoki/dotfiles
Length of output: 952
🏁 Script executed:
#!/bin/bash
# Check README and documentation for Neovim version requirements
rg -i "neovim.*version|minimum.*version|0\.[0-9]+" README* 2>/dev/null | head -20Repository: shunkakinoki/dotfiles
Length of output: 47
🏁 Script executed:
#!/bin/bash
# Check settings.lua for any version-related comments
cat -n home-manager/programs/neovim/lua/settings.lua | grep -i "version\|winborder" -B 2 -A 2Repository: shunkakinoki/dotfiles
Length of output: 278
Document minimum Neovim version requirement or add version check for winborder option.
vim.opt.winborder was added in Neovim 0.11. The configuration uses pkgs.neovim without a pinned version, which typically resolves to the latest stable release. However, if you support users with older Neovim versions, this setting will cause an error. Either document the minimum Neovim 0.11+ requirement in your README or add a version guard:
if vim.fn.has("nvim-0.11") == 1 then
vim.opt.winborder = "none"
end🤖 Prompt for AI Agents
In home-manager/programs/neovim/lua/settings.lua around line 49, the config sets
vim.opt.winborder which only exists in Neovim 0.11+, so add a version guard or
document the minimum version; fix by wrapping the assignment in a check using
vim.fn.has("nvim-0.11") == 1 before setting vim.opt.winborder, or alternatively
update README to explicitly require Neovim 0.11+ so users with older versions
won't hit an error.
| scope_incremental = "<noop>", | ||
| }, | ||
| }, | ||
| auto_install = true, |
There was a problem hiding this comment.
Consider the implications of auto_install = true in CI/restricted environments.
The auto_install setting will automatically install missing Treesitter parsers when opening files. This might cause issues in CI environments, read-only filesystems, or air-gapped systems. Based on learnings, you may want to conditionally disable this in CI.
Consider checking if the isCI variable from lib/env.nix is available and conditionally setting this:
-- Conditionally set auto_install based on environment
auto_install = not vim.env.IS_CI,Or explicitly set it to false if you prefer manual parser management in your Nix-based setup.
🤖 Prompt for AI Agents
In home-manager/programs/neovim/lua/treesitter.lua around line 109, auto_install
is set to true which will attempt to download/install parsers at runtime and can
fail in CI, read-only or air-gapped environments; change this to be conditional
on the environment (disable in CI) or explicitly false. Modify the assignment to
consult an environment flag (e.g., vim.env.IS_CI or a value exported from
lib/env.nix) and set auto_install = not vim.env.IS_CI (or auto_install = false)
so parsers are not installed automatically in restricted environments.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
home-manager/programs/neovim/init.lua (2)
16-27: Consider removing redundant package.path setup.A previous reviewer noted that lines 16-18 are likely redundant with lines 20-27, since both should point to the same configuration directory in typical setups. The dynamic resolution (lines 20-27) is more robust as it resolves symlinks, making the earlier setup unnecessary.
Apply this diff to remove the redundancy:
-local config_lua_path = vim.fn.stdpath("config") .. "/lua/?.lua" -append_package_path(config_lua_path) -append_package_path(vim.fn.stdpath("config") .. "/lua/?/init.lua") - local init_source = debug.getinfo(1, "S").source
43-43: Consider removing redundant utils require.A previous reviewer noted that
utilsis not used ininit.luaitself and is already properly required inkeymaps.luawhere it's actually needed (forutils.cycle_buffer()). Unless theutilsmodule has initialization side effects that should run at startup, this line can be removed.Apply this diff if the utils module has no critical initialization side effects:
require("terminal") require("ui") -require("utils") require("workspace")
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (4)
home-manager/programs/neovim/init.lua(1 hunks)home-manager/programs/neovim/lua/workspace.lua(1 hunks)nix-darwin/config/dock.nix(1 hunks)nix-darwin/config/homebrew.nix(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- nix-darwin/config/dock.nix
🧰 Additional context used
📓 Path-based instructions (2)
**/*.nix
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.nix: Use nixfmt for formatting all Nix files
Document complex configurations with comments in Nix files
**/*.nix: Use 2 spaces for indentation in Nix files
Keep line length under 100 characters in Nix files
Sort attribute sets alphabetically in Nix files
Use consistent spacing around operators in Nix files
Format lists and sets consistently in Nix filesUse treefmt.toml for formatting Nix files
**/*.nix: UsemkOptionfor configurable options in Nix modules
Implement proper typing for all options in Nix modules
Follow the Nix expression language style guide
Files:
nix-darwin/config/homebrew.nix
nix-darwin/**/*.nix
📄 CodeRabbit inference engine (CLAUDE.md)
Use Homebrew only for macOS-specific applications
Files:
nix-darwin/config/homebrew.nix
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-11-25T09:34:40.062Z
Learning: Applies to **/*.nix : Use treefmt.toml for formatting Nix files
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-11-25T09:34:40.062Z
Learning: Keep configurations modular across home-manager, hosts, and nix-darwin directories
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:34:23.224Z
Learning: Applies to **/*.nix : Use nixfmt for formatting all Nix files
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: .cursor/rules/home-manager.mdc:0-0
Timestamp: 2025-11-25T09:34:55.014Z
Learning: Applies to home-manager/**/*.nix : Follow home-manager's module structure and keep configurations modular
📚 Learning: 2025-11-25T09:34:23.224Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:34:23.224Z
Learning: Applies to nix-darwin/**/*.nix : Use Homebrew only for macOS-specific applications
Applied to files:
nix-darwin/config/homebrew.nix
📚 Learning: 2025-11-25T09:34:40.062Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-11-25T09:34:40.062Z
Learning: Document all major changes in Nix configurations
Applied to files:
nix-darwin/config/homebrew.nix
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: docker-build-push (linux/amd64, amd64, ubuntu-latest)
- GitHub Check: docker-build-push (linux/arm64, arm64, ubuntu-24.04-arm)
- GitHub Check: lua-neovim
- GitHub Check: lua-hammerspoon
- GitHub Check: e2e-run (NixOS, ubuntu-latest)
- GitHub Check: e2e-run (MacOS, macos-latest)
- GitHub Check: e2e-run (Ubuntu, ubuntu-latest)
- GitHub Check: nix-nixos
- GitHub Check: nix-linux
- GitHub Check: nix-darwin
- GitHub Check: Mesa Description
🔇 Additional comments (5)
home-manager/programs/neovim/lua/workspace.lua (1)
15-19: LGTM!The
WorkspaceRootcommand implementation is correct, and the immediatesetup()call is appropriate for a Neovim configuration module.Also applies to: 21-23
home-manager/programs/neovim/init.lua (3)
4-5: LGTM!Leader key configuration is standard and correct.
20-27: LGTM!The dynamic init path resolution properly handles symlinks via
fs_realpathand ensures the module search path includes the actual location of the init file.
32-44: LGTM on the modular architecture!The refactoring from a monolithic configuration to discrete, purpose-driven modules (settings, plugins, autocmds, keymaps, lsp, etc.) significantly improves maintainability and organization. The loading order appears well-considered.
nix-darwin/config/homebrew.nix (1)
81-90: New Homebrew casks are valid macOS apps and keep style consistentThe additions of
trae,visual-studio-code@insiders, and the switch totailscale-appall point at valid Homebrew casks for macOS GUI/tools, so they fit the nix-darwin rule of using Homebrew only for macOS-specific applications and should behave as expected. (formulae.brew.sh) Formatting (2-space indentation, list layout, line length) also remains compatible with nixfmt/treefmt. Based on learnings, this looks good as-is; if you maintain multiple Macs, you might still want to run a quickbrew info --caskfor these tokens locally once to confirm availability in your tap set.
| ---Set workspace-specific helpers and defaults. | ||
| ---@return nil | ||
| local M = {} |
There was a problem hiding this comment.
Correct the return type annotation.
The docstring indicates @return nil, but the module actually returns a table M at line 23.
Apply this diff to fix the annotation:
---Set workspace-specific helpers and defaults.
----@return nil
+---@return table
local M = {}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ---Set workspace-specific helpers and defaults. | |
| ---@return nil | |
| local M = {} | |
| ---Set workspace-specific helpers and defaults. | |
| ---@return table | |
| local M = {} |
🤖 Prompt for AI Agents
In home-manager/programs/neovim/lua/workspace.lua around lines 1 to 3, the
docstring incorrectly states "@return nil" even though the module returns the
table M at the end; update the return annotation to reflect the actual return
value (e.g., "@return table" or "@return table M — module table") so the
documentation matches the code.
| vim.api.nvim_create_autocmd("FileType", { | ||
| pattern = "*", | ||
| callback = function() | ||
| vim.opt_local.shiftwidth = 2 | ||
| vim.opt_local.tabstop = 2 | ||
| end, | ||
| }) |
There was a problem hiding this comment.
Consider language-specific indentation preferences.
The FileType autocmd with pattern = "*" enforces 2-space indentation globally, overriding language-specific conventions. This may cause issues with:
- Python (typically 4 spaces)
- Go (tabs by convention)
- Makefiles (tabs required)
- Other languages with established style guides
Consider either excluding specific file types or documenting this as an intentional workspace-wide override.
If you want to keep the global 2-space default but respect certain file types, apply this diff:
-- Ensure projects default to 2-space indents.
vim.api.nvim_create_autocmd("FileType", {
- pattern = "*",
+ pattern = { "*" },
callback = function()
- vim.opt_local.shiftwidth = 2
- vim.opt_local.tabstop = 2
+ -- Skip file types that have strong conventions
+ local ft = vim.bo.filetype
+ if ft == "go" or ft == "make" or ft == "python" then
+ return
+ end
+ vim.opt_local.shiftwidth = 2
+ vim.opt_local.tabstop = 2
end,
})🤖 Prompt for AI Agents
In home-manager/programs/neovim/lua/workspace.lua around lines 7 to 13, the
FileType autocmd with pattern="*" forcibly sets shiftwidth and tabstop to 2 for
all filetypes which overrides language-specific indentation (e.g., Python, Go,
Makefiles); change the autocmd to either (a) apply the 2-space defaults only to
a whitelist of filetypes that should use 2 spaces, or (b) keep the global
2-space default but add explicit guards that skip or set different values for
specific filetypes (at minimum: set python to shiftwidth=4, set go and make to
use tabs, and skip any other language with established conventions), and update
or add a comment documenting this behavior so future maintainers understand the
intentional exceptions.
There was a problem hiding this comment.
6 issues found across 22 files
Prompt for AI agents (all 6 issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="home-manager/programs/neovim/lua/treesitter.lua">
<violation number="1" location="home-manager/programs/neovim/lua/treesitter.lua:112">
`lookahead` must be configured inside the `select` module; placing it at the top level means the option is ignored and lookahead remains disabled.</violation>
</file>
<file name="home-manager/programs/neovim/lua/utils.lua">
<violation number="1" location="home-manager/programs/neovim/lua/utils.lua:93">
`M.copen()` never opens the quickfix window when the list has exactly one entry, preventing users from inspecting single quickfix results.</violation>
</file>
<file name="home-manager/programs/neovim/lua/autocmds.lua">
<violation number="1" location="home-manager/programs/neovim/lua/autocmds.lua:66">
Use the buffer-local filetype when detecting help buffers so the Help autocmd actually runs.</violation>
</file>
<file name="home-manager/programs/neovim/lua/lsp.lua">
<violation number="1" location="home-manager/programs/neovim/lua/lsp.lua:10">
Mapping code actions to plain "ca" in normal mode overrides the built-in change-around operator (e.g., `caw`, `ca(`), preventing users from performing those edits when an LSP is attached.</violation>
</file>
<file name="home-manager/programs/neovim/lua/plugins.lua">
<violation number="1" location="home-manager/programs/neovim/lua/plugins.lua:120">
`javascriptreact` and `typescriptreact` buffers never run eslint because those filetypes are missing from `lint.linters_by_ft`, so the save-time linting added below silently skips React files even though they use the same toolchain.</violation>
<violation number="2" location="home-manager/programs/neovim/lua/plugins.lua:126">
Create a dedicated augroup for this BufWritePost autocmd so that reloading the config doesn’t register duplicate lint callbacks.</violation>
</file>
Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR
| auto_install = true, | ||
| textobjects = { | ||
| enable = true, | ||
| lookahead = true, |
There was a problem hiding this comment.
lookahead must be configured inside the select module; placing it at the top level means the option is ignored and lookahead remains disabled.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/programs/neovim/lua/treesitter.lua, line 112:
<comment>`lookahead` must be configured inside the `select` module; placing it at the top level means the option is ignored and lookahead remains disabled.</comment>
<file context>
@@ -0,0 +1,163 @@
+ auto_install = true,
+ textobjects = {
+ enable = true,
+ lookahead = true,
+ swap = {
+ enable = true,
</file context>
| end | ||
|
|
||
| function M.copen() | ||
| if vim.fn.getqflist({ size = 0 }).size > 1 then |
There was a problem hiding this comment.
M.copen() never opens the quickfix window when the list has exactly one entry, preventing users from inspecting single quickfix results.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/programs/neovim/lua/utils.lua, line 93:
<comment>`M.copen()` never opens the quickfix window when the list has exactly one entry, preventing users from inspecting single quickfix results.</comment>
<file context>
@@ -0,0 +1,104 @@
+end
+
+function M.copen()
+ if vim.fn.getqflist({ size = 0 }).size > 1 then
+ vim.cmd("copen")
+ else
</file context>
| if vim.fn.getqflist({ size = 0 }).size > 1 then | |
| if vim.fn.getqflist({ size = 0 }).size > 0 then |
| group = help_group, | ||
| pattern = { "*.txt" }, | ||
| callback = function() | ||
| if vim.o.filetype == "help" then |
There was a problem hiding this comment.
Use the buffer-local filetype when detecting help buffers so the Help autocmd actually runs.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/programs/neovim/lua/autocmds.lua, line 66:
<comment>Use the buffer-local filetype when detecting help buffers so the Help autocmd actually runs.</comment>
<file context>
@@ -0,0 +1,160 @@
+ group = help_group,
+ pattern = { "*.txt" },
+ callback = function()
+ if vim.o.filetype == "help" then
+ vim.cmd.wincmd("L")
+ end
</file context>
| if vim.o.filetype == "help" then | |
| if vim.bo.filetype == "help" then |
| vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts) | ||
| vim.keymap.set("n", "gr", vim.lsp.buf.references, opts) | ||
| vim.keymap.set("n", "<leader>D", vim.lsp.buf.type_definition, opts) | ||
| vim.keymap.set("n", "ca", vim.lsp.buf.code_action, opts) |
There was a problem hiding this comment.
Mapping code actions to plain "ca" in normal mode overrides the built-in change-around operator (e.g., caw, ca(), preventing users from performing those edits when an LSP is attached.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/programs/neovim/lua/lsp.lua, line 10:
<comment>Mapping code actions to plain "ca" in normal mode overrides the built-in change-around operator (e.g., `caw`, `ca(`), preventing users from performing those edits when an LSP is attached.</comment>
<file context>
@@ -0,0 +1,71 @@
+ vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts)
+ vim.keymap.set("n", "gr", vim.lsp.buf.references, opts)
+ vim.keymap.set("n", "<leader>D", vim.lsp.buf.type_definition, opts)
+ vim.keymap.set("n", "ca", vim.lsp.buf.code_action, opts)
+ vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts)
+ vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help, opts)
</file context>
| vim.keymap.set("n", "ca", vim.lsp.buf.code_action, opts) | |
| vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, opts) |
| typescript = { "eslint" }, | ||
| } | ||
|
|
||
| vim.api.nvim_create_autocmd({ "BufWritePost" }, { |
There was a problem hiding this comment.
Create a dedicated augroup for this BufWritePost autocmd so that reloading the config doesn’t register duplicate lint callbacks.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/programs/neovim/lua/plugins.lua, line 126:
<comment>Create a dedicated augroup for this BufWritePost autocmd so that reloading the config doesn’t register duplicate lint callbacks.</comment>
<file context>
@@ -0,0 +1,130 @@
+ typescript = { "eslint" },
+}
+
+vim.api.nvim_create_autocmd({ "BufWritePost" }, {
+ callback = function()
+ lint.try_lint()
</file context>
| require("colorizer").setup() | ||
|
|
||
| local lint = require("lint") | ||
| lint.linters_by_ft = { |
There was a problem hiding this comment.
javascriptreact and typescriptreact buffers never run eslint because those filetypes are missing from lint.linters_by_ft, so the save-time linting added below silently skips React files even though they use the same toolchain.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/programs/neovim/lua/plugins.lua, line 120:
<comment>`javascriptreact` and `typescriptreact` buffers never run eslint because those filetypes are missing from `lint.linters_by_ft`, so the save-time linting added below silently skips React files even though they use the same toolchain.</comment>
<file context>
@@ -0,0 +1,130 @@
+require("colorizer").setup()
+
+local lint = require("lint")
+lint.linters_by_ft = {
+ python = { "pylint" },
+ javascript = { "eslint" },
</file context>
Note
Major Neovim revamp: split config into Lua modules, switch to nvim-cmp, add terminal/AI/UI/search tooling; add Stylua to treefmt/flake and update Nix/macOS packages; add Biome/TypeScript deps.
init.luawith modules (lua/settings,plugins,autocmds,keymaps,lsp,telescope,treesitter,completion,ai,terminal,ui,utils).nvim-cmpwithcopilot-cmpandLuaSnip(replacing prior setup); add cmdline and gitcommit sources.gopls,vtsls,lua_ls, etc., withcmp_nvim_lspcapabilities and unified diagnostics; addvim-illuminate.which-key,trouble,lualine,notify,auto-dark-mode,oil,flash; enhancenvim-treebindings; enablecolorizer.telescopewithfzfandui-selectextensions and keymaps.tsx,typescript,nix) and enableautopairs,autotag,surround,context,todo-comments,treesj.toggletermwith primary/secondary toggles and cycling.sidekick.nvimvialua/ai.lua.conform.nvim(Biome/Stylua/Go/Nix),nvim-lint, andgrug-far.treefmt.tomland wire inflake.nix(pkgs.stylua).isCItolib/env.nix; addspeedtest-clito packages.visual-studio-code@insiders, switch totailscale-app) and Dock apps (include Tailscale and VS Code Insiders).@biomejs/biome,typescript, and@typescript/native-previewinpackage.json.Written by Cursor Bugbot for commit f35831e. Configure here.
Summary by cubic
Revamps Neovim into a modular Lua setup with improved editing, navigation, and terminal workflows. Also updates formatting and dev tooling across Nix and package configs.
New Features
Refactors & Dependencies
Written for commit 69ceac0. Summary will update automatically on new commits.