-
Notifications
You must be signed in to change notification settings - Fork 0
feat(neovim): add recommended settings from dmtrKovalenko/dotfiles #393
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,13 +1,113 @@ | ||||||||||||
| local augroup = vim.api.nvim_create_augroup | ||||||||||||
| local autocmd = vim.api.nvim_create_autocmd | ||||||||||||
| local utils = require("utils") | ||||||||||||
|
|
||||||||||||
| -- Highlight on yank | ||||||||||||
| -- ==================================================================================== | ||||||||||||
| -- HIGHLIGHT ON YANK WITH REGISTER ROTATION | ||||||||||||
| -- From: https://github.com/dmtrKovalenko/dotfiles | ||||||||||||
| -- ==================================================================================== | ||||||||||||
| local highlight_yank_group = augroup("HighlightYank", { clear = true }) | ||||||||||||
| autocmd("TextYankPost", { | ||||||||||||
| group = highlight_yank_group, | ||||||||||||
| pattern = "*", | ||||||||||||
| callback = function() | ||||||||||||
| vim.highlight.on_yank() | ||||||||||||
| -- Rotate registers on yank to preserve yank history | ||||||||||||
| if vim.v.event.operator == "y" then | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This yank register rotation fundamentally breaks Vim's numbered register semantics. In standard Vim, registers 1-9 store the last 9 deletions (not yanks), and Vim manages this automatically. By rotating registers on every yank operation:
If keeping this feature, strongly consider:
Prompt for Agent |
||||||||||||
| utils.yank_shift() | ||||||||||||
| end | ||||||||||||
| end, | ||||||||||||
| }) | ||||||||||||
|
|
||||||||||||
| -- ==================================================================================== | ||||||||||||
| -- AUTO-SAVE ON BUFFER LEAVE / FOCUS LOSS | ||||||||||||
| -- From: https://github.com/dmtrKovalenko/dotfiles | ||||||||||||
| -- ==================================================================================== | ||||||||||||
| local autosave_group = augroup("AutoSave", { clear = true }) | ||||||||||||
| autocmd({ "BufLeave", "FocusLost" }, { | ||||||||||||
| group = autosave_group, | ||||||||||||
| pattern = "*", | ||||||||||||
| callback = function() | ||||||||||||
| -- Only save if buffer is modified and has a filename | ||||||||||||
| if vim.bo.modified and vim.fn.expand("%") ~= "" and vim.bo.buftype == "" then | ||||||||||||
| vim.cmd("silent! update") | ||||||||||||
|
||||||||||||
| vim.cmd("silent! update") | |
| local ok, err = pcall(vim.cmd, "update") | |
| if not ok then | |
| vim.notify("Auto-save failed: " .. err, vim.log.levels.WARN) | |
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The silent! suppresses all errors including critical ones like filesystem permission problems, disk full conditions, or network filesystem timeouts. Consider removing silent! and handling errors explicitly, or at minimum add checks for file writability before attempting save. Also consider adding configuration options:
- Global flag:
vim.g.auto_save_enabled - Buffer-local opt-out:
vim.b.disable_auto_save - Per-filetype configuration to avoid interfering with git rebase/merge workflows
Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: shunkakinoki/dotfiles#393
File: home-manager/programs/neovim/lua/autocmds.lua#L33
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.
Feedback:
The `silent!` suppresses all errors including critical ones like filesystem permission problems, disk full conditions, or network filesystem timeouts. Consider removing `silent!` and handling errors explicitly, or at minimum add checks for file writability before attempting save. Also consider adding configuration options:
- Global flag: `vim.g.auto_save_enabled`
- Buffer-local opt-out: `vim.b.disable_auto_save`
- Per-filetype configuration to avoid interfering with git rebase/merge workflows
Copilot
AI
Dec 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BufFilePost is not a standard Neovim autocmd event. This appears to be a typo - the correct event name is likely BufFilePre or BufReadPost. This event will never trigger, meaning the terminal title won't be updated when files are read.
Consider using BufReadPost or BufWinEnter instead, which are standard events that trigger when buffers are loaded or displayed in windows.
| autocmd({ "BufEnter", "BufFilePost" }, { | |
| autocmd({ "BufEnter", "BufReadPost" }, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a lot of repetition in the creation of FileType autocommands for setting iskeyword. This can be refactored into a more concise, data-driven approach to improve maintainability. You can define a table of configurations and loop through it to create the autocommands.
This also allows for merging the rules for css, scss, sass, less, and markdown since they share the same keyword additions.
Additionally, vim.opt_local.iskeyword:append("@-@") is functionally equivalent to vim.opt_local.iskeyword:append("@") but is less clear. The suggested refactoring simplifies this as well.
local keyword_extensions = {
{
patterns = { "typescript", "typescriptreact", "javascript", "javascriptreact" },
keywords = { "@", "-" },
},
{
patterns = { "css", "scss", "sass", "less", "markdown" },
keywords = { "-", "#" },
},
{
patterns = { "html", "xml", "vue", "svelte" },
keywords = { "-", ":" },
},
{
patterns = { "json", "jsonc" },
keywords = { "-", "$" },
},
{
patterns = { "yaml", "toml" },
keywords = { "-", "." },
},
}
for _, config in ipairs(keyword_extensions) do
autocmd("FileType", {
group = keyword_group,
pattern = config.patterns,
callback = function()
for _, keyword in ipairs(config.keywords) do
vim.opt_local.iskeyword:append(keyword)
end
end,
})
end
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -110,6 +110,18 @@ keymap("n", "<leader>py", ':let @" = expand("%:p")<CR>', opts) | |||||||||
| -- @keymap <leader>d: Delete to blackhole register | ||||||||||
| keymap({ "n", "v" }, "<leader>d", '"_d', opts) | ||||||||||
|
|
||||||||||
| -- @keymap dd: Smart delete (uses blackhole register for empty lines) | ||||||||||
| -- From: https://github.com/dmtrKovalenko/dotfiles | ||||||||||
| keymap("n", "dd", function() | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Overriding
The expr mapping adds indirection and could interfere with plugins that rely on standard Prompt for Agent |
||||||||||
| return utils.smart_delete("dd") | ||||||||||
| end, { noremap = true, expr = true }) | ||||||||||
|
|
||||||||||
| -- @keymap <Esc>: Close floating windows | ||||||||||
| keymap("n", "<Esc>", function() | ||||||||||
|
Comment on lines
+119
to
+120
|
||||||||||
| -- @keymap <Esc>: Close floating windows | |
| keymap("n", "<Esc>", function() | |
| -- @keymap <leader><Esc>: Close floating windows | |
| keymap("n", "<leader><Esc>", function() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remapping <Esc> globally changes fundamental Vim behavior. The floating window close could interfere with:
- Plugin UI elements that need manual dismissal (telescope, which-key, lazy.nvim)
- Intentionally persistent floating windows
- Custom workflows that rely on keeping floating windows open
Consider using a different key like <leader><Esc> or <C-l>, or add checks to exclude certain floating windows from being closed.
Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: shunkakinoki/dotfiles#393
File: home-manager/programs/neovim/lua/keymaps.lua#L120
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.
Feedback:
Remapping `<Esc>` globally changes fundamental Vim behavior. The floating window close could interfere with:
- Plugin UI elements that need manual dismissal (telescope, which-key, lazy.nvim)
- Intentionally persistent floating windows
- Custom workflows that rely on keeping floating windows open
Consider using a different key like `<leader><Esc>` or `<C-l>`, or add checks to exclude certain floating windows from being closed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overriding the <Esc> key to close all floating windows is quite aggressive and may lead to unexpected behavior. For instance, many plugins use floating windows where <Esc> is used to return to normal mode within that window. This mapping would close the window entirely, along with any other floating windows that might be open (like diagnostics). Consider using a more specific keymap (e.g., <leader><Esc>) or making the function less aggressive, for example, by only closing the current window if it's a floating window.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,6 +6,30 @@ vim.opt.termsync = true | |||||||||||||||||||||
| vim.opt.hidden = true | ||||||||||||||||||||||
| vim.opt.updatetime = 300 | ||||||||||||||||||||||
| vim.opt.mouse = "a" | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| -- ==================================================================================== | ||||||||||||||||||||||
| -- SSH / OSC52 CLIPBOARD HANDLING | ||||||||||||||||||||||
| -- From: https://github.com/dmtrKovalenko/dotfiles | ||||||||||||||||||||||
| -- Uses OSC 52 protocol for clipboard when running over SSH | ||||||||||||||||||||||
| -- ==================================================================================== | ||||||||||||||||||||||
| local function is_ssh() | ||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Duplicate code: local utils = require("utils")
if utils.is_ssh() then
local ok, osc52 = pcall(require, "vim.ui.clipboard.osc52")
if not ok then
vim.notify("OSC52 clipboard not available", vim.log.levels.WARN)
return
end
-- ... rest of config
endPrompt for Agent |
||||||||||||||||||||||
| return os.getenv("SSH_CLIENT") ~= nil or os.getenv("SSH_TTY") ~= nil | ||||||||||||||||||||||
| end | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if is_ssh() then | ||||||||||||||||||||||
|
Comment on lines
+15
to
+19
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Comment on lines
+15
to
+19
|
||||||||||||||||||||||
| local function is_ssh() | |
| return os.getenv("SSH_CLIENT") ~= nil or os.getenv("SSH_TTY") ~= nil | |
| end | |
| if is_ssh() then | |
| if require("utils").is_ssh() then |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,5 +1,77 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
| local M = {} | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| -- ==================================================================================== | ||||||||||||||||||||||||||||||||||||||||||||||
| -- SMART DELETE FUNCTION | ||||||||||||||||||||||||||||||||||||||||||||||
| -- Avoids polluting registers with whitespace-only lines | ||||||||||||||||||||||||||||||||||||||||||||||
| -- From: https://github.com/dmtrKovalenko/dotfiles | ||||||||||||||||||||||||||||||||||||||||||||||
| -- ==================================================================================== | ||||||||||||||||||||||||||||||||||||||||||||||
| function M.smart_delete(key) | ||||||||||||||||||||||||||||||||||||||||||||||
| local line = vim.api.nvim_get_current_line() | ||||||||||||||||||||||||||||||||||||||||||||||
| -- If the line is empty or contains only whitespace, delete to blackhole register | ||||||||||||||||||||||||||||||||||||||||||||||
| if line:match("^%s*$") then | ||||||||||||||||||||||||||||||||||||||||||||||
| return '"_' .. key | ||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||
| return key | ||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| -- ==================================================================================== | ||||||||||||||||||||||||||||||||||||||||||||||
| -- YANK REGISTER ROTATION | ||||||||||||||||||||||||||||||||||||||||||||||
| -- Rotates registers 1-9 when yanking to preserve yank history | ||||||||||||||||||||||||||||||||||||||||||||||
| -- From: https://github.com/dmtrKovalenko/dotfiles | ||||||||||||||||||||||||||||||||||||||||||||||
| -- ==================================================================================== | ||||||||||||||||||||||||||||||||||||||||||||||
| function M.yank_shift() | ||||||||||||||||||||||||||||||||||||||||||||||
| -- Rotate registers 9 <- 8 <- ... <- 2 <- 1 <- " | ||||||||||||||||||||||||||||||||||||||||||||||
| for i = 9, 2, -1 do | ||||||||||||||||||||||||||||||||||||||||||||||
| local prev_content = vim.fn.getreg(tostring(i - 1)) | ||||||||||||||||||||||||||||||||||||||||||||||
| local prev_type = vim.fn.getregtype(tostring(i - 1)) | ||||||||||||||||||||||||||||||||||||||||||||||
| vim.fn.setreg(tostring(i), prev_content, prev_type) | ||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||
| -- Move unnamed register to register 1 | ||||||||||||||||||||||||||||||||||||||||||||||
| local unnamed_content = vim.fn.getreg('"') | ||||||||||||||||||||||||||||||||||||||||||||||
| local unnamed_type = vim.fn.getregtype('"') | ||||||||||||||||||||||||||||||||||||||||||||||
| vim.fn.setreg("1", unnamed_content, unnamed_type) | ||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| -- ==================================================================================== | ||||||||||||||||||||||||||||||||||||||||||||||
| -- CLOSE FLOATING WINDOWS | ||||||||||||||||||||||||||||||||||||||||||||||
| -- Utility to close all floating windows | ||||||||||||||||||||||||||||||||||||||||||||||
| -- From: https://github.com/dmtrKovalenko/dotfiles | ||||||||||||||||||||||||||||||||||||||||||||||
| -- ==================================================================================== | ||||||||||||||||||||||||||||||||||||||||||||||
| function M.close_floating_wins() | ||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function closes ALL floating windows without discrimination, which could close important plugin UIs (lazy.nvim, mason.nvim, telescope previews, LSP hover docs). Add:
Example: function M.close_floating_wins(opts)
opts = opts or {}
local exclude_fts = opts.exclude_filetypes or {}
for _, win in ipairs(vim.api.nvim_list_wins()) do
if vim.api.nvim_win_is_valid(win) then
local config = vim.api.nvim_win_get_config(win)
if config.relative ~= "" then
local buf = vim.api.nvim_win_get_buf(win)
local ft = vim.bo[buf].filetype
if not vim.tbl_contains(exclude_fts, ft) then
pcall(vim.api.nvim_win_close, win, false)
end
end
end
end
endPrompt for Agent |
||||||||||||||||||||||||||||||||||||||||||||||
| for _, win in ipairs(vim.api.nvim_list_wins()) do | ||||||||||||||||||||||||||||||||||||||||||||||
| if vim.api.nvim_win_is_valid(win) then | ||||||||||||||||||||||||||||||||||||||||||||||
| local config = vim.api.nvim_win_get_config(win) | ||||||||||||||||||||||||||||||||||||||||||||||
| if config.relative ~= "" then | ||||||||||||||||||||||||||||||||||||||||||||||
| vim.api.nvim_win_close(win, false) | ||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+41
to
+48
|
||||||||||||||||||||||||||||||||||||||||||||||
| for _, win in ipairs(vim.api.nvim_list_wins()) do | |
| if vim.api.nvim_win_is_valid(win) then | |
| local config = vim.api.nvim_win_get_config(win) | |
| if config.relative ~= "" then | |
| vim.api.nvim_win_close(win, false) | |
| end | |
| end | |
| end | |
| local floating_wins = {} | |
| for _, win in ipairs(vim.api.nvim_list_wins()) do | |
| if vim.api.nvim_win_is_valid(win) then | |
| local config = vim.api.nvim_win_get_config(win) | |
| if config.relative ~= "" then | |
| table.insert(floating_wins, win) | |
| end | |
| end | |
| end | |
| for _, win in ipairs(floating_wins) do | |
| if vim.api.nvim_win_is_valid(win) then | |
| vim.api.nvim_win_close(win, false) | |
| end | |
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The register rotation runs on every yank operation, including yanks to named registers (e.g.,
"ayy), which may not be the desired behavior. This could pollute the numbered register history with intentional named register operations.Consider checking
vim.v.event.regnameto only rotate when yanking to the unnamed register: