From d5efcb95d923e79c0578a95cfef8e4a9a76725f9 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 08:31:47 -0600 Subject: [PATCH 01/92] feat(sync.sh): add 'github.vscode-github-actions' to proprietary extensions list - Included 'github.vscode-github-actions' in the proprietary extensions to enhance the sync script's functionality and prevent sync errors. --- home-manager/services/code-syncer/sync.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/home-manager/services/code-syncer/sync.sh b/home-manager/services/code-syncer/sync.sh index aacef3d87..2545b0bcf 100755 --- a/home-manager/services/code-syncer/sync.sh +++ b/home-manager/services/code-syncer/sync.sh @@ -22,6 +22,7 @@ PROPRIETARY_EXTENSIONS=( "github.codespaces" "github.copilot" "github.copilot-chat" + "github.vscode-github-actions" "ms-python.debugpy" "ms-python.python" "ms-python.vscode-pylance" From 40b07d3fec3882c06965c99c4105a743941ddebb Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 08:37:58 -0600 Subject: [PATCH 02/92] revamp: migrate neovim config to new lua-based setup with plugins --- config/nvim/init.lua | 1204 ++++++++++++++++++ config/nvim/nvim-pack-lock.json | 45 + home-manager/programs/neovim/config/init.lua | 1 - home-manager/programs/neovim/default.nix | 5 +- 4 files changed, 1250 insertions(+), 5 deletions(-) create mode 100644 config/nvim/init.lua create mode 100644 config/nvim/nvim-pack-lock.json delete mode 100644 home-manager/programs/neovim/config/init.lua diff --git a/config/nvim/init.lua b/config/nvim/init.lua new file mode 100644 index 000000000..095f59015 --- /dev/null +++ b/config/nvim/init.lua @@ -0,0 +1,1204 @@ +vim.opt.compatible = false +vim.opt.termsync = true +vim.opt.hidden = true +vim.opt.updatetime = 250 +vim.opt.mouse = "" +vim.opt.inccommand = "nosplit" +vim.opt.splitbelow = true +vim.opt.splitright = true +vim.opt.wrap = false +vim.opt.textwidth = 0 +vim.opt.expandtab = true +vim.opt.smartindent = true +vim.opt.shiftwidth = 2 +vim.opt.softtabstop = 2 +vim.opt.tabstop = 2 +vim.opt.signcolumn = "yes" +vim.opt.scrolloff = 10 +vim.opt.sidescrolloff = 10 +vim.opt.number = true +vim.opt.relativenumber = true +vim.opt.smoothscroll = true +vim.opt.swapfile = false +vim.opt.backup = false +vim.opt.undofile = true +vim.opt.undodir = vim.fn.stdpath("data") .. "undodir" +vim.opt.hlsearch = false +vim.opt.ignorecase = true +vim.opt.incsearch = true +vim.opt.ruler = true +vim.opt.wildmenu = true +vim.opt.autoread = true +vim.opt.completeopt = { "menu", "menuone", "noselect" } +vim.opt.colorcolumn = "80" +vim.opt.backspace = { "indent", "eol", "start" } +vim.opt.spelllang = { "en_us" } +vim.opt.spellfile = vim.uv.os_homedir() .. "/.spell.add" +vim.opt.laststatus = 2 +vim.opt.cursorline = true +vim.opt.grepprg = "rg --vimgrep --smart-case --follow" +vim.opt.background = "dark" +vim.opt.termguicolors = true +vim.opt.shortmess:append("c") +vim.opt.timeoutlen = 300 +vim.opt.winborder = "none" + +vim.hl.priorities.semantic_tokens = 10 +vim.g.fugitive_legacy_commands = 0 + +vim.cmd([[ +inoreabbrev Goreleaser GoReleaser +inoreabbrev gorelesaer goreleaser +inoreabbrev carlos0 caarlos0 +inoreabbrev descriptoin description +inoreabbrev fucn func +inoreabbrev sicne since +inoreabbrev emtpy empty +inoreabbrev udpate update +inoreabbrev dont don't +inoreabbrev wont won't +inoreabbrev cant can't +inoreabbrev lenght length +inoreabbrev Lenght Length + +" ptbr +inoreabbrev neh né +inoreabbrev soh só +inoreabbrev nao não +inoreabbrev sao são +]]) + +vim.pack.add({ + -- UI + { src = "https://github.com/nvim-tree/nvim-web-devicons" }, + { src = "https://github.com/ellisonleao/gruvbox.nvim" }, + { src = "https://github.com/nvim-lualine/lualine.nvim" }, + { src = "https://github.com/stevearc/dressing.nvim" }, + { src = "https://github.com/rcarriga/nvim-notify" }, + { src = "https://github.com/christoomey/vim-tmux-navigator" }, + { src = "https://github.com/asiryk/auto-hlsearch.nvim" }, + { src = "https://github.com/famiu/bufdelete.nvim" }, + { src = "https://github.com/norcalli/nvim-colorizer.lua" }, + { src = "https://github.com/lewis6991/gitsigns.nvim" }, + { src = "https://github.com/akinsho/git-conflict.nvim" }, + -- telescope + { src = "https://github.com/nvim-lua/plenary.nvim" }, + { src = "https://github.com/nvim-telescope/telescope-github.nvim" }, + { src = "https://github.com/nvim-telescope/telescope.nvim" }, + + -- CODING + { src = "https://github.com/rgroli/other.nvim" }, + { src = "https://github.com/danymat/neogen" }, + { src = "https://github.com/neovim/nvim-lspconfig" }, + { src = "https://github.com/stevearc/conform.nvim" }, + { src = "https://github.com/zbirenbaum/copilot.lua" }, + { src = "https://github.com/rafamadriz/friendly-snippets" }, + { src = "https://github.com/giuxtaposition/blink-cmp-copilot" }, + { + src = "https://github.com/saghen/blink.cmp", + version = vim.version.range("1.*"), + }, + + -- tpope gang + { src = "https://github.com/tpope/vim-fugitive" }, + { src = "https://github.com/tpope/vim-rhubarb" }, + { src = "https://github.com/tpope/vim-abolish" }, + { src = "https://github.com/tpope/vim-repeat" }, + { src = "https://github.com/tpope/vim-eunuch" }, + { src = "https://github.com/tpope/vim-sleuth" }, + { src = "https://github.com/tpope/vim-speeddating" }, + + -- treesitter and friends + { src = "https://github.com/nvim-treesitter/nvim-treesitter" }, + { src = "https://github.com/lukas-reineke/indent-blankline.nvim" }, + { src = "https://github.com/wansmer/treesj" }, + { src = "https://github.com/windwp/nvim-autopairs" }, + { src = "https://github.com/windwp/nvim-ts-autotag" }, + { src = "https://github.com/kylechui/nvim-surround" }, + { src = "https://github.com/folke/todo-comments.nvim" }, + { src = "https://github.com/nvim-treesitter/nvim-treesitter-context" }, + { src = "https://github.com/nvim-treesitter/nvim-treesitter-textobjects" }, + { src = "https://github.com/RRethy/nvim-treesitter-endwise" }, +}) + +local opts = { noremap = true, silent = true } +local keymap = vim.keymap.set + +--Remap space as leader key +keymap("", "", "", opts) +vim.g.mapleader = " " +vim.g.maplocalleader = " " + +-- quicklists +keymap("n", "co", ":copen", opts) +keymap("n", "cc", ":cclose", opts) + +-- write, buffer killing +keymap("n", "q", ":Bdelete", opts) +keymap("n", "bad", ":%bwipeout!:intro", opts) +keymap("n", "w", ":write", opts) + +-- zz +keymap("n", "n", "nzzzv", opts) +keymap("n", "N", "Nzzzv", opts) +keymap("n", "", "zz", opts) +keymap("n", "", "zz", opts) +keymap("n", "", "zz", opts) +keymap("n", "", "zz", opts) + +-- system clipboard integration +keymap({ "n", "v" }, "y", '"+y', opts) + +-- copy the current file path +keymap("n", "py", ':let @" = expand("%:p")', opts) + +-- delete to blackhole +keymap({ "n", "v" }, "d", '"_d', opts) + +-- git +keymap("n", "gs", ":tab Git", opts) +keymap("n", "", ":tab Git mergetool", opts) +keymap("n", "gd", ":Gitsign preview_hunk_inline", opts) + +-- indent +keymap("v", "<", "", ">gv", opts) + +-- If I visually select words and paste from clipboard, don't replace my +-- clipboard with the selected word, instead keep my old word in the +-- clipboard +keymap("v", "p", '"_dP', opts) + +-- Move text up and down +keymap("x", "K", ":move '<-2gv-gv", opts) +keymap("x", "J", ":move '>+1gv-gv", opts) + +-- in insert mode, adds new undo points after more some chars: +for _, lhs in ipairs({ "-", "_", ",", ".", ";", ":", "/", "!", "?" }) do + keymap("i", lhs, lhs .. "u", opts) +end + +--- +--- UI +--- + +local bg0 = "#1b1b1b" +require("gruvbox").setup({ + contrast = "hard", + overrides = { + GruvboxBg0 = { fg = bg0 }, + SignColumn = { bg = bg0 }, + GruvboxRedSign = { bg = bg0 }, + GruvboxYellowSign = { bg = bg0 }, + GruvboxGreenSign = { bg = bg0 }, + GruvboxAquaSign = { bg = bg0 }, + GruvboxOrangeSign = { bg = bg0 }, + GruvboxPurpleSign = { bg = bg0 }, + GruvboxBlueSign = { bg = bg0 }, + Normal = { bg = bg0 }, + }, +}) +vim.cmd("colorscheme gruvbox") +-- https://github.com/ellisonleao/gruvbox.nvim/commit/c74e6e523c4827b67af2cb02b636e22dc35fdf70 +-- https://github.com/nvim-lualine/lualine.nvim/issues/1312 +vim.api.nvim_set_hl(0, "StatusLine", { reverse = false }) +vim.api.nvim_set_hl(0, "StatusLineNC", { reverse = false }) + +require("dressing").setup({ input = { insert_only = true } }) + +local notify = require("notify") +notify.setup({ + render = "compact", + stages = "static", +}) +vim.notify = notify + +local section_b = { "branch", "diff", { "diagnostics", sources = { "nvim_workspace_diagnostic" } } } +local section_c = { "%=", { "filename", file_status = false, path = 1 } } +require("lualine").setup({ + options = { + theme = "gruvbox", + component_separators = "", + section_separators = "", + }, + sections = { + lualine_b = section_b, + lualine_c = section_c, + }, + inactive_sections = { + lualine_c = section_c, + lualine_x = { "location" }, + }, +}) + +require("auto-hlsearch").setup({}) +require("gitsigns").setup({}) +require("git-conflict").setup({}) + +-- setup diagnostics +vim.diagnostic.config({ + underline = true, + update_in_insert = false, + severity_sort = true, +}) + +keymap("n", "xx", vim.diagnostic.setqflist, opts) + +-- set up diagnostic signs +local severity = vim.diagnostic.severity +local signs = { + [severity.ERROR] = "", + [severity.WARN] = "", + [severity.INFO] = "", + [severity.HINT] = "󰌶", +} +vim.diagnostic.config({ + signs = { + text = signs, + }, +}) + +require("other-nvim").setup({ mappings = { "golang" } }) +keymap("n", "oo", ":Other", opts) +keymap("n", "ov", ":OtherVSplit", opts) +keymap("n", "os", ":OtherSplit", opts) + +require("neogen").setup({ snippet_engine = "nvim" }) +keymap("n", "gco", ":Neogen", opts) + +require("conform").setup({ + formatters_by_ft = { + css = { "prettier" }, + fish = { "fish_indent" }, + html = { "prettier" }, + javascript = { "prettier" }, + json = { "jq" }, + lua = { "stylua" }, + markdown = { "prettier" }, + sh = { "shfmt" }, + sql = { "pg_format", "sql_formatter" }, + templ = { "templ" }, + tf = { "terraform_fmt" }, + yaml = { "prettier" }, + ["_"] = { "trim_whitespace", "trim_newlines" }, + -- let only the lsp take care of these. + go = {}, + rust = {}, + zig = {}, + }, + format_after_save = { + lsp_fallback = true, + }, +}) + +require("copilot").setup({ + suggestion = { enabled = false }, + panel = { enabled = false }, +}) + +---@module 'blink.cmp' +---@type blink.cmp.Config +require("blink.cmp").setup({ + keymap = { preset = "default" }, + appearance = { + nerd_font_variant = "mono", + kind_icons = { + Array = "", + Boolean = "", + Class = "", + Color = "", + Constant = "", + Constructor = "", + Copilot = "", + Enum = "", + EnumMember = "", + Event = "", + Field = "", + File = "", + Folder = "󰉋", + Function = "", + Interface = "", + Key = "", + Keyword = "", + Method = "", + Module = "", + Namespace = "", + Null = "󰟢", + Number = "", + Object = "", + Operator = "", + Package = "", + Property = "", + Reference = "", + Snippet = "", + String = "", + Struct = "", + Text = "", + TypeParameter = "", + Unit = "", + Value = "", + Variable = "", + }, + }, + signature = { enabled = true }, + cmdline = { + enabled = true, + sources = function() + local type = vim.fn.getcmdtype() + if type == "/" or type == "?" then + return { "buffer" } + end + if type == ":" then + return { "cmdline" } + end + return {} + end, + completion = { + menu = { + draw = { + columns = { + { "kind_icon", "label", gap = 1 }, + { "kind" }, + }, + }, + }, + }, + }, + sources = { + default = { "lsp", "path", "snippets", "buffer", "copilot" }, + providers = { + lsp = { + min_keyword_length = 0, + score_offset = 0, + }, + path = { + min_keyword_length = 0, + }, + snippets = { + min_keyword_length = 2, + }, + buffer = { + min_keyword_length = 5, + max_items = 5, + }, + copilot = { + name = "copilot", + module = "blink-cmp-copilot", + score_offset = -10000, + min_keyword_length = 0, + async = true, + override = { + -- copilot complete on space, new line, etc as well... + get_trigger_characters = function(self) + local trigger_characters = self:get_trigger_characters() + vim.list_extend(trigger_characters, { "\n", "\t", " " }) + return trigger_characters + end, + }, + transform_items = function(_, items) + local CompletionItemKind = require("blink.cmp.types").CompletionItemKind + local kind_idx = #CompletionItemKind + 1 + CompletionItemKind[kind_idx] = "Copilot" + for _, item in ipairs(items) do + item.kind = kind_idx + end + return items + end, + }, + }, + }, + completion = { + accept = { auto_brackets = { enabled = true } }, + keyword = { + range = "full", + }, + trigger = { + show_on_insert_on_trigger_character = true, + show_on_trigger_character = true, + show_on_keyword = true, + }, + documentation = { + auto_show = true, + auto_show_delay_ms = 250, + treesitter_highlighting = false, + }, + menu = { + draw = { + columns = { + { "kind_icon", "label", gap = 1 }, + { "kind" }, + }, + }, + }, + }, +}) + +local function copen() + if vim.fn.getqflist({ size = 0 }).size > 1 then + vim.cmd("copen") + else + vim.cmd("cclose") + end +end + +local function cclear() + vim.fn.setqflist({}, "r") +end + +-- Opens the directory of the current file in Finder/file explorer. +vim.api.nvim_create_user_command("Finder", "!open %:h", {}) + +vim.api.nvim_create_autocmd({ + "BufEnter", + "CursorHold", + "CursorHoldI", + "FocusGained", +}, { + pattern = "*", + command = "if mode() != 'c' | checktime | endif", +}) + +-- resize splits if window got resized +vim.api.nvim_create_autocmd({ "VimResized" }, { + callback = function() + vim.cmd("tabdo wincmd =") + end, +}) + +vim.api.nvim_create_autocmd("FileType", { + pattern = "gitcommit", + command = "startinsert", +}) + +-- ensure the parent folder exists, so it gets properly added to the lsp +-- context and everything just works. +vim.api.nvim_create_autocmd("BufNewFile", { + pattern = "*", + callback = function() + local dir = vim.fn.expand(":p:h") + if vim.fn.isdirectory(dir) == 0 then + vim.fn.mkdir(dir, "p") + vim.cmd([[ :e % ]]) + end + end, +}) + +-- Highlight on yank +-- See `:help vim.highlight.on_yank()` +vim.api.nvim_create_autocmd("TextYankPost", { + pattern = "*", + callback = function() + vim.hl.on_yank() + end, +}) + +-- Open help window in a vertical split to the right. +vim.api.nvim_create_autocmd("BufWinEnter", { + pattern = { "*.txt" }, + callback = function() + if vim.o.filetype == "help" then + vim.cmd.wincmd("L") + end + end, +}) + +vim.api.nvim_create_autocmd("FileType", { + pattern = "git", + callback = function() + local bufnr = vim.api.nvim_get_current_buf() + local buf_opts = { noremap = true, silent = true, buffer = bufnr } + keymap("n", "gq", ":silent! close", buf_opts) + end, +}) + +vim.api.nvim_create_autocmd("FileType", { + pattern = "fugitive", + callback = function() + local bufnr = vim.api.nvim_get_current_buf() + + local function async_git(args, success_msg, error_msg) + vim.system({ "git", unpack(args) }, {}, function(obj) + vim.schedule(function() + if obj.code == 0 then + vim.notify(success_msg, vim.log.levels.INFO) + else + vim.notify(error_msg, vim.log.levels.ERROR) + end + end) + end) + end + + vim.cmd("normal )k=") + + local buf_opts = { noremap = true, silent = true, buffer = bufnr } + keymap("n", "gp", function() + async_git({ "push", "--quiet" }, "Pushed!", "Push failed!") + vim.cmd("silent! close") + end, buf_opts) + + keymap("n", "gP", function() + async_git({ "pull", "--rebase" }, "Pulled!", "Pull failed!") + vim.cmd("silent! close") + end, buf_opts) + + keymap("n", "go", function() + async_git({ "ppr" }, "Pushed and opened PR URL!", "Failed to push or open PR") + vim.cmd("silent! close") + end, buf_opts) + + keymap("n", "cc", ":silent! Git commit -s", buf_opts) + keymap("n", "gq", ":silent! close", buf_opts) + end, +}) + +vim.api.nvim_create_autocmd("FileType", { + pattern = "gitcommit", + callback = function() + vim.opt_local.spell = true + vim.opt_local.textwidth = 72 + end, +}) + +vim.api.nvim_create_autocmd("FileType", { + pattern = { "qf", "help" }, + callback = function() + keymap("n", "q", ":bdelete", { + buffer = vim.api.nvim_get_current_buf(), + noremap = true, + silent = true, + }) + end, +}) + +local get_gopls = function(bufnr) + local clients = vim.lsp.get_clients({ bufnr = bufnr }) + for _, c in ipairs(clients) do + if c.name == "gopls" then + return c + end + end + return nil +end + +vim.api.nvim_create_autocmd("FileType", { + pattern = "go", + callback = function() + local bufnr = vim.api.nvim_get_current_buf() + + vim.opt_local.formatoptions:append("jo") + vim.opt_local.makeprg = "go build ./..." + vim.opt_local.errorformat = "%A%f:%l:%c: %m,%-G%.%#" + + vim.api.nvim_buf_create_user_command(bufnr, "GoModTidy", function() + local gopls = get_gopls(bufnr) + if gopls == nil then + return + end + + vim.cmd([[ noautocmd wall ]]) + + local uri = vim.uri_from_bufnr(bufnr) + local arguments = { { URIs = { uri } } } + + local err = gopls:request_sync("workspace/executeCommand", { + command = "gopls.tidy", + arguments = arguments, + }, 30000, bufnr) + + if err ~= nil and type(err[1]) == "table" then + vim.notify("go mod tidy: " .. vim.inspect(err), vim.log.levels.ERROR) + return + end + end, { desc = "go mod tidy" }) + + local buf_opts = { noremap = true, silent = true, buffer = bufnr } + keymap("n", "", vim.cmd.GoModTidy, buf_opts) + keymap("n", "", function() + cclear() + vim.fn.jobstart("golangci-lint run --max-issues-per-linter=0 --max-same-issues=0 --new", { + stdout_buffered = true, + on_stdout = function(_, data) + if data and #data > 1 then + vim.schedule(function() + vim.fn.setqflist({}, " ", { lines = data }) + copen() + end) + end + end, + }) + end, buf_opts) + end, +}) + +vim.api.nvim_create_autocmd("FileType", { + pattern = "markdown", + callback = function() + vim.opt_local.spell = true + vim.opt_local.textwidth = 80 + vim.opt_local.formatoptions:remove("ct") + end, +}) + +-- syntax, indentation, treesitter, etc. +require("ibl").setup({ + indent = { char = "│" }, + exclude = { filetypes = { "help" } }, + scope = { enabled = false }, +}) + +require("nvim-autopairs").setup({ + check_ts = true, +}) + +require("nvim-ts-autotag").setup() +require("nvim-surround").setup() +require("todo-comments").setup() + +require("treesitter-context").setup({ + multiline_threshold = 1, +}) + +---@diagnostic disable-next-line: missing-fields +require("nvim-treesitter.configs").setup({ + ensure_installed = { + "arduino", + "awk", + "bash", + "cpp", + "css", + "csv", + "diff", + "dockerfile", + "fish", + "git_config", + "git_rebase", + "gitattributes", + "gitcommit", + "gitignore", + "go", + "gomod", + "gosum", + "gowork", + "graphql", + "hcl", + "html", + "http", + "http", + "ini", + "javascript", + "jq", + "json", + "lua", + "make", + "markdown", + "markdown_inline", + "mermaid", + "python", + "query", + "regex", + "ruby", + "scss", + "sql", + "ssh_config", + "templ", + "terraform", + "toml", + "vhs", + "vim", + "vimdoc", + "yaml", + "zig", + }, + highlight = { + enable = true, + }, + indent = { + enable = true, + }, + endwise = { + enable = true, + }, + autopairs = { + enable = true, + }, + context_commentstring = { + enable = true, + enable_autocmd = false, + }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = "", + node_incremental = "", + node_decremental = "", + scope_incremental = "", + }, + }, + auto_install = false, + textobjects = { + enable = true, + lookahead = true, + swap = { + enable = true, + swap_next = { + ["a"] = "@parameter.inner", + }, + swap_previous = { + ["A"] = "@parameter.inner", + }, + }, + move = { + enable = true, + set_jumps = true, + goto_next_start = { + ["]f"] = "@function.inner", + ["]c"] = "@class.inner", + ["]a"] = "@parameter.inner", + }, + goto_next_end = { + ["]F"] = "@function.inner", + ["]C"] = "@class.inner", + ["]A"] = "@parameter.inner", + }, + goto_previous_start = { + ["[f"] = "@function.inner", + ["[c"] = "@class.inner", + ["[a"] = "@parameter.inner", + }, + goto_previous_end = { + ["[F"] = "@function.inner", + ["[C"] = "@class.inner", + ["[A"] = "@parameter.inner", + }, + }, + select = { + enable = true, + keymaps = { + ["af"] = "@function.outer", + ["if"] = "@function.inner", + + ["ac"] = "@conditional.outer", + ["ic"] = "@conditional.inner", + + ["aa"] = "@parameter.outer", + ["ia"] = "@parameter.inner", + + ["av"] = "@variable.outer", + ["iv"] = "@variable.inner", + }, + }, + }, +}) + +local treesj = require("treesj") +treesj.setup({ use_default_keymaps = false }) +keymap("n", "st", treesj.toggle, opts) + +local telescope = require("telescope") +telescope.setup({ + defaults = { + pickers = { + find_files = { + theme = "ivy", + }, + }, + prompt_prefix = "  ", + selection_caret = " ❯ ", + entry_prefix = " ", + multi_icon = "+ ", + path_display = { "filename_first" }, + vimgrep_arguments = { + "rg", + "--color=never", + "--no-heading", + "--with-filename", + "--line-number", + "--column", + "--smart-case", + "--sort=path", + }, + }, +}) +telescope.load_extension("gh") + +local function ivy(iopts) + return require("telescope.themes").get_ivy(iopts) +end + +local builtin = require("telescope.builtin") +vim.keymap.set("n", "", function() + builtin.find_files(ivy({ + find_command = { + "fd", + "--type", + "f", + "--strip-cwd-prefix", + "--hidden", + }, + })) +end, opts) + +keymap("n", "of", function() + builtin.oldfiles(ivy({ + only_cwd = true, + })) +end, opts) + +keymap("n", "lg", function() + builtin.live_grep(ivy()) +end, opts) + +keymap("n", "fb", function() + builtin.buffers(ivy()) +end, opts) + +keymap("n", "fh", function() + builtin.help_tags(ivy()) +end, opts) + +keymap("n", "fc", function() + builtin.commands(ivy()) +end, opts) + +keymap("n", "fr", function() + builtin.resume(ivy()) +end, opts) + +keymap("n", "fq", function() + builtin.quickfix(ivy()) +end, opts) + +keymap("n", "/", function() + builtin.current_buffer_fuzzy_find(ivy()) +end, opts) + +keymap("n", "ghi", function() + telescope.extensions.gh.issues(ivy()) +end, opts) + +-- LSP/autocommands inline replica of caarlos0's modules. +local function setup_lsp_autocommands() + local ms = require("vim.lsp.protocol").Methods + local group = vim.api.nvim_create_augroup("LSP", { clear = true }) + + ---@async + ---@param client vim.lsp.Client + ---@param bufnr number + local function organize_imports(client, bufnr) + ---@type lsp.Handler + ---@diagnostic disable-next-line: unused-local + local handler = function(err, result, context, config) + if err then + return + end + for _, r in pairs(result or {}) do + if r.edit then + local enc = client.offset_encoding or "utf-16" + vim.lsp.util.apply_workspace_edit(r.edit, enc) + elseif r.command and r.command.command then + client:exec_cmd(r.command, { bufnr = bufnr }) + end + end + vim.cmd([[noautocmd write]]) + end + + local win = vim.api.nvim_get_current_win() + local params = vim.lsp.util.make_range_params(win, client.offset_encoding or "utf-16") + params.context = { only = { "source.organizeImports" } } + client:request(ms.textDocument_codeAction, params, handler, bufnr) + end + + local function has_clients_with_method(bufnr, method) + local clients = vim.lsp.get_clients({ bufnr = bufnr, method = method }) + return #clients > 0 + end + + local function on_clients(bufnr, method, apply, filter) + local clients = vim.lsp.get_clients({ bufnr = bufnr, method = method }) + local predicate = filter or function() + return true + end + for _, client in ipairs(clients) do + if predicate(client) then + apply(client, bufnr) + end + end + end + + vim.api.nvim_create_autocmd("LspAttach", { + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + if client == nil then + return + end + if client:supports_method(ms.textDocument_codeLens, vim.api.nvim_get_current_buf()) then + vim.lsp.inlay_hint.enable(true) + end + end, + }) + vim.api.nvim_create_autocmd("LspDetach", { + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + if client == nil then + return + end + if client:supports_method(ms.textDocument_codeLens, vim.api.nvim_get_current_buf()) then + vim.lsp.codelens.clear(client.id) + end + end, + group = group, + }) + + vim.api.nvim_create_autocmd({ "BufWritePre" }, { + callback = function() + local format = function(client, bufnr) + if client.server_capabilities.documentFormattingProvider then + vim.lsp.buf.format({ + bufnr = bufnr, + timeout_ms = 5000, + id = client.id, + }) + end + end + on_clients(vim.api.nvim_get_current_buf(), ms.textDocument_codeAction, format) + end, + group = group, + }) + + vim.api.nvim_create_autocmd({ "BufWritePost" }, { + callback = function() + local bufnr = vim.api.nvim_get_current_buf() + local filter = function(client) + return client.name ~= "lua_ls" + end + on_clients(bufnr, ms.textDocument_codeAction, organize_imports, filter) + end, + group = group, + }) + + vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", "InsertLeave" }, { + callback = function() + if has_clients_with_method(0, ms.textDocument_codeLens) then + vim.lsp.codelens.refresh({ bufnr = 0 }) + end + end, + group = group, + }) + + vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { + callback = function() + if has_clients_with_method(0, ms.textDocument_documentHighlight) then + vim.lsp.buf.document_highlight() + end + end, + group = group, + }) + + vim.api.nvim_create_autocmd({ "CursorMoved" }, { + callback = function() + if has_clients_with_method(0, ms.textDocument_documentHighlight) then + vim.lsp.buf.clear_references() + end + end, + group = group, + }) +end + +setup_lsp_autocommands() + +local capabilities = require("blink.cmp").get_lsp_capabilities({ + workspace = { + didChangeWatchedFiles = { + dynamicRegistration = true, + relativePatternSupport = true, + }, + }, +}, true) + +---@param client vim.lsp.Client +---@param bufnr number +local on_attach = function(client, bufnr) + local keymap_lsp = function(lhs, rhs) + vim.keymap.set("n", lhs, rhs, { + noremap = true, + silent = true, + buffer = bufnr, + }) + end + + local telescope_wrap = function(action) + return function() + local ivy_theme = require("telescope.themes").get_ivy() + require("telescope.builtin")["lsp_" .. action](ivy_theme) + end + end + + keymap_lsp("gd", telescope_wrap("definitions")) + keymap_lsp("grr", telescope_wrap("references")) + keymap_lsp("gO", telescope_wrap("document_symbols")) + keymap_lsp("gri", telescope_wrap("implementations")) + keymap_lsp("gD", vim.lsp.buf.declaration) + keymap_lsp("K", vim.lsp.buf.hover) + keymap_lsp("D", telescope_wrap("type_definitions")) + keymap_lsp("grl", vim.lsp.codelens.run) + keymap_lsp("gl", vim.diagnostic.open_float) + keymap_lsp("[d", function() + vim.diagnostic.jump({ count = -1 }) + vim.cmd("norm zz") + end) + keymap_lsp("]d", function() + vim.diagnostic.jump({ count = 1 }) + vim.cmd("norm zz") + end) + + keymap_lsp("v", function() + vim.cmd("vsplit | lua vim.lsp.buf.definition()") + vim.cmd("norm zz") + end) +end + +local lspconfig = require("lspconfig") +require("lspconfig.ui.windows").default_options.border = "none" +lspconfig.gopls.setup({ + capabilities = capabilities, + on_attach = on_attach, + settings = { + gopls = { + gofumpt = true, + codelenses = { + gc_details = true, + generate = true, + run_govulncheck = true, + test = true, + tidy = true, + upgrade_dependency = true, + }, + hints = { + assignVariableTypes = true, + compositeLiteralFields = true, + compositeLiteralTypes = true, + constantValues = true, + functionTypeParameters = true, + parameterNames = true, + rangeVariableTypes = true, + }, + analyses = { + nilness = true, + unusedparams = true, + unusedvariable = true, + unusedwrite = true, + useany = true, + }, + staticcheck = true, + directoryFilters = { "-.git", "-node_modules" }, + semanticTokens = true, + }, + }, + flags = { + debounce_text_changes = 150, + }, +}) + +lspconfig.ts_ls.setup({ + capabilities = capabilities, + on_attach = on_attach, + settings = { + javascript = { + inlayHints = { + includeInlayEnumMemberValueHints = true, + includeInlayFunctionLikeReturnTypeHints = true, + includeInlayFunctionParameterTypeHints = true, + includeInlayParameterNameHints = "all", + includeInlayParameterNameHintsWhenArgumentMatchesName = true, + includeInlayPropertyDeclarationTypeHints = true, + includeInlayVariableTypeHints = true, + }, + }, + typescript = { + inlayHints = { + includeInlayEnumMemberValueHints = true, + includeInlayFunctionLikeReturnTypeHints = true, + includeInlayFunctionParameterTypeHints = true, + includeInlayParameterNameHints = "all", + includeInlayParameterNameHintsWhenArgumentMatchesName = true, + includeInlayPropertyDeclarationTypeHints = true, + includeInlayVariableTypeHints = true, + }, + }, + }, +}) + +for _, lsp in ipairs({ + "bashls", + "clangd", + "cssls", + "jsonls", + "pylsp", + "rust_analyzer", + "taplo", + "templ", + "terraformls", + "tflint", + "zls", +}) do + lspconfig[lsp].setup({ + on_attach = on_attach, + capabilities = capabilities, + }) +end + +for _, lsp in ipairs({ "html", "htmx" }) do + lspconfig[lsp].setup({ + capabilities = capabilities, + on_attach = on_attach, + filetypes = { "html", "templ" }, + }) +end + +lspconfig.tailwindcss.setup({ + on_attach = on_attach, + capabilities = capabilities, + filetypes = { "html", "templ", "javascript" }, + settings = { + tailwindCSS = { + includeLanguages = { + templ = "html", + }, + }, + }, +}) + +lspconfig.yamlls.setup({ + capabilities = capabilities, + on_attach = on_attach, + settings = { + yaml = { + schemaStore = { + url = "https://www.schemastore.org/api/json/catalog.json", + enable = true, + }, + }, + }, +}) + +local runtime_path = vim.split(package.path, ";", {}) +table.insert(runtime_path, "lua/?.lua") +table.insert(runtime_path, "lua/?/init.lua") +lspconfig.lua_ls.setup({ + capabilities = capabilities, + on_attach = on_attach, + settings = { + Lua = { + completion = { + callSnippet = "Replace", + }, + telemetry = { enable = false }, + hint = { + enable = true, + }, + workspace = { + library = vim.api.nvim_get_runtime_file("", true), + }, + }, + }, +}) diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json new file mode 100644 index 000000000..343b5c8f5 --- /dev/null +++ b/config/nvim/nvim-pack-lock.json @@ -0,0 +1,45 @@ +{ + "plugins": { + "auto-hlsearch.nvim": [], + "blink-cmp-copilot": [], + "blink.cmp": { + "version": "1.0.0 - 2.0.0" + }, + "bufdelete.nvim": [], + "conform.nvim": [], + "copilot.lua": [], + "dressing.nvim": [], + "friendly-snippets": [], + "git-conflict.nvim": [], + "gitsigns.nvim": [], + "gruvbox.nvim": [], + "indent-blankline.nvim": [], + "lualine.nvim": [], + "neogen": [], + "nvim-autopairs": [], + "nvim-colorizer.lua": [], + "nvim-lspconfig": [], + "nvim-notify": [], + "nvim-surround": [], + "nvim-treesitter": [], + "nvim-treesitter-context": [], + "nvim-treesitter-endwise": [], + "nvim-treesitter-textobjects": [], + "nvim-ts-autotag": [], + "nvim-web-devicons": [], + "other.nvim": [], + "plenary.nvim": [], + "telescope-github.nvim": [], + "telescope.nvim": [], + "todo-comments.nvim": [], + "treesj": [], + "vim-abolish": [], + "vim-eunuch": [], + "vim-fugitive": [], + "vim-repeat": [], + "vim-rhubarb": [], + "vim-sleuth": [], + "vim-speeddating": [], + "vim-tmux-navigator": [] + } +} \ No newline at end of file diff --git a/home-manager/programs/neovim/config/init.lua b/home-manager/programs/neovim/config/init.lua deleted file mode 100644 index 4a4590bbf..000000000 --- a/home-manager/programs/neovim/config/init.lua +++ /dev/null @@ -1 +0,0 @@ -require("colorizer").setup() diff --git a/home-manager/programs/neovim/default.nix b/home-manager/programs/neovim/default.nix index fc4441c3b..3c85d38dd 100644 --- a/home-manager/programs/neovim/default.nix +++ b/home-manager/programs/neovim/default.nix @@ -9,11 +9,8 @@ defaultEditor = true; vimAlias = true; vimdiffAlias = true; - plugins = with pkgs.vimPlugins; [ - nvim-colorizer-lua - ]; }; xdg.configFile."nvim" = { - source = config.lib.file.mkOutOfStoreSymlink ./config; + source = config.lib.file.mkOutOfStoreSymlink ../../config/nvim; }; } From 46e8de24a084a6cc681a27c43a8240b81c6b320f Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 08:39:56 -0600 Subject: [PATCH 03/92] feat: add @biomejs/biome as a dependency and trusted dependency --- bun.lock | 21 +++++++++++++++++++++ package.json | 2 ++ 2 files changed, 23 insertions(+) diff --git a/bun.lock b/bun.lock index 0617bf206..72606aed3 100644 --- a/bun.lock +++ b/bun.lock @@ -12,6 +12,9 @@ "cline": "^1.0.5", "open-composer": "^0.8.23", }, + "devDependencies": { + "@biomejs/biome": "^2.3.7", + }, }, }, "trustedDependencies": [ @@ -37,6 +40,24 @@ "@asamuzakjp/css-color": ["@asamuzakjp/css-color@3.2.0", "", { "dependencies": { "@csstools/css-calc": "^2.1.3", "@csstools/css-color-parser": "^3.0.9", "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", "lru-cache": "^10.4.3" } }, "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw=="], + "@biomejs/biome": ["@biomejs/biome@2.3.7", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.3.7", "@biomejs/cli-darwin-x64": "2.3.7", "@biomejs/cli-linux-arm64": "2.3.7", "@biomejs/cli-linux-arm64-musl": "2.3.7", "@biomejs/cli-linux-x64": "2.3.7", "@biomejs/cli-linux-x64-musl": "2.3.7", "@biomejs/cli-win32-arm64": "2.3.7", "@biomejs/cli-win32-x64": "2.3.7" }, "bin": { "biome": "bin/biome" } }, "sha512-CTbAS/jNAiUc6rcq94BrTB8z83O9+BsgWj2sBCQg9rD6Wkh2gjfR87usjx0Ncx0zGXP1NKgT7JNglay5Zfs9jw=="], + + "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.3.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-LirkamEwzIUULhXcf2D5b+NatXKeqhOwilM+5eRkbrnr6daKz9rsBL0kNZ16Hcy4b8RFq22SG4tcLwM+yx/wFA=="], + + "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.3.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-Q4TO633kvrMQkKIV7wmf8HXwF0dhdTD9S458LGE24TYgBjSRbuhvio4D5eOQzirEYg6eqxfs53ga/rbdd8nBKg=="], + + "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.3.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-inHOTdlstUBzgjDcx0ge71U4SVTbwAljmkfi3MC5WzsYCRhancqfeL+sa4Ke6v2ND53WIwCFD5hGsYExoI3EZQ=="], + + "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.3.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-/afy8lto4CB8scWfMdt+NoCZtatBUF62Tk3ilWH2w8ENd5spLhM77zKlFZEvsKJv9AFNHknMl03zO67CiklL2Q=="], + + "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.3.7", "", { "os": "linux", "cpu": "x64" }, "sha512-fJMc3ZEuo/NaMYo5rvoWjdSS5/uVSW+HPRQujucpZqm2ZCq71b8MKJ9U4th9yrv2L5+5NjPF0nqqILCl8HY/fg=="], + + "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.3.7", "", { "os": "linux", "cpu": "x64" }, "sha512-CQUtgH1tIN6e5wiYSJqzSwJumHYolNtaj1dwZGCnZXm2PZU1jOJof9TsyiP3bXNDb+VOR7oo7ZvY01If0W3iFQ=="], + + "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.3.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-aJAE8eCNyRpcfx2JJAtsPtISnELJ0H4xVVSwnxm13bzI8RwbXMyVtxy2r5DV1xT3WiSP+7LxORcApWw0LM8HiA=="], + + "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.3.7", "", { "os": "win32", "cpu": "x64" }, "sha512-pulzUshqv9Ed//MiE8MOUeeEkbkSHVDVY5Cz5wVAnH1DUqliCQG3j6s1POaITTFqFfo7AVIx2sWdKpx/GS+Nqw=="], + "@colors/colors": ["@colors/colors@1.5.0", "", {}, "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ=="], "@csstools/color-helpers": ["@csstools/color-helpers@5.1.0", "", {}, "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA=="], diff --git a/package.json b/package.json index a41d22251..9905e4cde 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "license": "ISC", "packageManager": "bun@1.3.0", "dependencies": { + "@biomejs/biome": "^2.3.7", "@github/copilot": "^0.0.362", "@google/jules": "^0.1.40", "@getgrit/cli": "^0.1.0-alpha.1743007075", @@ -19,6 +20,7 @@ "open-composer": "^0.8.23" }, "trustedDependencies": [ + "@biomejs/biome", "@github/copilot", "@google/jules", "@getgrit/cli", From 0b796f227440f3a6be4b0b03e4c2cf6446aeb684 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 08:50:15 -0600 Subject: [PATCH 04/92] revamp: restructure neovim configuration and add symlink setup --- config/default.nix | 1 + config/nvim/default.nix | 9 +++++++++ home-manager/programs/neovim/default.nix | 8 -------- 3 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 config/nvim/default.nix diff --git a/config/default.nix b/config/default.nix index 538175682..01f73d9cb 100644 --- a/config/default.nix +++ b/config/default.nix @@ -3,5 +3,6 @@ ./direnv ./hammerspoon ./karabiner + ./nvim ./starship ] diff --git a/config/nvim/default.nix b/config/nvim/default.nix new file mode 100644 index 000000000..769156e91 --- /dev/null +++ b/config/nvim/default.nix @@ -0,0 +1,9 @@ +{ config, ... }: +let + dotfilesDir = "${config.home.homeDirectory}/dotfiles"; +in +{ + xdg.configFile."nvim" = { + source = config.lib.file.mkOutOfStoreSymlink "${dotfilesDir}/config/nvim"; + }; +} diff --git a/home-manager/programs/neovim/default.nix b/home-manager/programs/neovim/default.nix index 3c85d38dd..47b71d365 100644 --- a/home-manager/programs/neovim/default.nix +++ b/home-manager/programs/neovim/default.nix @@ -1,8 +1,3 @@ -{ - config, - pkgs, - ... -}: { programs.neovim = { enable = true; @@ -10,7 +5,4 @@ vimAlias = true; vimdiffAlias = true; }; - xdg.configFile."nvim" = { - source = config.lib.file.mkOutOfStoreSymlink ../../config/nvim; - }; } From e3eba55965de195e7480dd57f5e1988864b59a39 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 08:54:03 -0600 Subject: [PATCH 05/92] feat(shell): enhance PATH configuration in bash and zsh - Updated bashrcExtra and initContent to include additional binary paths for improved accessibility. - Consolidated Go and Bun configurations while ensuring compatibility with other tools like Foundry and Nix. --- home-manager/programs/bash/default.nix | 12 +++++++++--- home-manager/programs/zsh/default.nix | 9 +++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/home-manager/programs/bash/default.nix b/home-manager/programs/bash/default.nix index d3b0befe7..97a511edd 100644 --- a/home-manager/programs/bash/default.nix +++ b/home-manager/programs/bash/default.nix @@ -32,11 +32,17 @@ }; bashrcExtra = '' - # Add Go bin to PATH - export PATH="$PATH:$GOPATH/bin" + # Go configuration + export GOPATH="$HOME/go" - # Add Bun bin to PATH + # Add additional bin paths + export PATH="$PATH:$GOPATH/bin" export PATH="$HOME/.bun/bin:$PATH" + export PATH="$HOME/.foundry/bin:$PATH" + export PATH="$HOME/.local/bin:$PATH" + export PATH="$HOME/.nix-profile/bin:$PATH" + export PATH="/nix/var/nix/profiles/default/bin:$PATH" + export PATH="/opt/homebrew/bin:$PATH" ''; profileExtra = '' diff --git a/home-manager/programs/zsh/default.nix b/home-manager/programs/zsh/default.nix index 5d18c5171..2f55f7cdc 100644 --- a/home-manager/programs/zsh/default.nix +++ b/home-manager/programs/zsh/default.nix @@ -20,10 +20,15 @@ initContent = '' # Go configuration export GOPATH="$HOME/go" - export PATH="$PATH:$GOPATH/bin" - # Bun configuration + # Additional bin paths + export PATH="$PATH:$GOPATH/bin" export PATH="$HOME/.bun/bin:$PATH" + export PATH="$HOME/.foundry/bin:$PATH" + export PATH="$HOME/.local/bin:$PATH" + export PATH="$HOME/.nix-profile/bin:$PATH" + export PATH="/nix/var/nix/profiles/default/bin:$PATH" + export PATH="/opt/homebrew/bin:$PATH" # FNM (Fast Node Manager) configuration export FNM_DIR="$HOME/Library/Application Support/fnm" From 19e610314e6e6db993c02633eeeea6483df6a469 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 09:02:42 -0600 Subject: [PATCH 06/92] feat: integrate neovim-nightly-overlay into home-manager and flake configuration - Updated nvim-pack-lock.json to ensure proper formatting. - Enhanced flake.lock with new inputs and locked versions for neovim-nightly-overlay and related dependencies. - Added neovim-nightly-overlay to flake.nix inputs for better package management. - Configured home-manager to utilize neovim-nightly-overlay overlays. - Updated neovim default.nix to specify the neovim package from the new overlay. - Modified darwin default.nix to include neovim-nightly-overlay in the package imports and overlays. --- config/nvim/init.lua | 1716 +++++++++++----------- config/nvim/nvim-pack-lock.json | 2 +- flake.lock | 62 +- flake.nix | 4 + home-manager/default.nix | 2 + home-manager/programs/neovim/default.nix | 2 + hosts/darwin/default.nix | 17 +- 7 files changed, 941 insertions(+), 864 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 095f59015..f0bc8e592 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -69,56 +69,56 @@ inoreabbrev sao são ]]) vim.pack.add({ - -- UI - { src = "https://github.com/nvim-tree/nvim-web-devicons" }, - { src = "https://github.com/ellisonleao/gruvbox.nvim" }, - { src = "https://github.com/nvim-lualine/lualine.nvim" }, - { src = "https://github.com/stevearc/dressing.nvim" }, - { src = "https://github.com/rcarriga/nvim-notify" }, - { src = "https://github.com/christoomey/vim-tmux-navigator" }, - { src = "https://github.com/asiryk/auto-hlsearch.nvim" }, - { src = "https://github.com/famiu/bufdelete.nvim" }, - { src = "https://github.com/norcalli/nvim-colorizer.lua" }, - { src = "https://github.com/lewis6991/gitsigns.nvim" }, - { src = "https://github.com/akinsho/git-conflict.nvim" }, - -- telescope - { src = "https://github.com/nvim-lua/plenary.nvim" }, - { src = "https://github.com/nvim-telescope/telescope-github.nvim" }, - { src = "https://github.com/nvim-telescope/telescope.nvim" }, - - -- CODING - { src = "https://github.com/rgroli/other.nvim" }, - { src = "https://github.com/danymat/neogen" }, - { src = "https://github.com/neovim/nvim-lspconfig" }, - { src = "https://github.com/stevearc/conform.nvim" }, - { src = "https://github.com/zbirenbaum/copilot.lua" }, - { src = "https://github.com/rafamadriz/friendly-snippets" }, - { src = "https://github.com/giuxtaposition/blink-cmp-copilot" }, - { - src = "https://github.com/saghen/blink.cmp", - version = vim.version.range("1.*"), - }, - - -- tpope gang - { src = "https://github.com/tpope/vim-fugitive" }, - { src = "https://github.com/tpope/vim-rhubarb" }, - { src = "https://github.com/tpope/vim-abolish" }, - { src = "https://github.com/tpope/vim-repeat" }, - { src = "https://github.com/tpope/vim-eunuch" }, - { src = "https://github.com/tpope/vim-sleuth" }, - { src = "https://github.com/tpope/vim-speeddating" }, - - -- treesitter and friends - { src = "https://github.com/nvim-treesitter/nvim-treesitter" }, - { src = "https://github.com/lukas-reineke/indent-blankline.nvim" }, - { src = "https://github.com/wansmer/treesj" }, - { src = "https://github.com/windwp/nvim-autopairs" }, - { src = "https://github.com/windwp/nvim-ts-autotag" }, - { src = "https://github.com/kylechui/nvim-surround" }, - { src = "https://github.com/folke/todo-comments.nvim" }, - { src = "https://github.com/nvim-treesitter/nvim-treesitter-context" }, - { src = "https://github.com/nvim-treesitter/nvim-treesitter-textobjects" }, - { src = "https://github.com/RRethy/nvim-treesitter-endwise" }, + -- UI + { src = "https://github.com/nvim-tree/nvim-web-devicons" }, + { src = "https://github.com/ellisonleao/gruvbox.nvim" }, + { src = "https://github.com/nvim-lualine/lualine.nvim" }, + { src = "https://github.com/stevearc/dressing.nvim" }, + { src = "https://github.com/rcarriga/nvim-notify" }, + { src = "https://github.com/christoomey/vim-tmux-navigator" }, + { src = "https://github.com/asiryk/auto-hlsearch.nvim" }, + { src = "https://github.com/famiu/bufdelete.nvim" }, + { src = "https://github.com/norcalli/nvim-colorizer.lua" }, + { src = "https://github.com/lewis6991/gitsigns.nvim" }, + { src = "https://github.com/akinsho/git-conflict.nvim" }, + -- telescope + { src = "https://github.com/nvim-lua/plenary.nvim" }, + { src = "https://github.com/nvim-telescope/telescope-github.nvim" }, + { src = "https://github.com/nvim-telescope/telescope.nvim" }, + + -- CODING + { src = "https://github.com/rgroli/other.nvim" }, + { src = "https://github.com/danymat/neogen" }, + { src = "https://github.com/neovim/nvim-lspconfig" }, + { src = "https://github.com/stevearc/conform.nvim" }, + { src = "https://github.com/zbirenbaum/copilot.lua" }, + { src = "https://github.com/rafamadriz/friendly-snippets" }, + { src = "https://github.com/giuxtaposition/blink-cmp-copilot" }, + { + src = "https://github.com/saghen/blink.cmp", + version = vim.version.range("1.*"), + }, + + -- tpope gang + { src = "https://github.com/tpope/vim-fugitive" }, + { src = "https://github.com/tpope/vim-rhubarb" }, + { src = "https://github.com/tpope/vim-abolish" }, + { src = "https://github.com/tpope/vim-repeat" }, + { src = "https://github.com/tpope/vim-eunuch" }, + { src = "https://github.com/tpope/vim-sleuth" }, + { src = "https://github.com/tpope/vim-speeddating" }, + + -- treesitter and friends + { src = "https://github.com/nvim-treesitter/nvim-treesitter" }, + { src = "https://github.com/lukas-reineke/indent-blankline.nvim" }, + { src = "https://github.com/wansmer/treesj" }, + { src = "https://github.com/windwp/nvim-autopairs" }, + { src = "https://github.com/windwp/nvim-ts-autotag" }, + { src = "https://github.com/kylechui/nvim-surround" }, + { src = "https://github.com/folke/todo-comments.nvim" }, + { src = "https://github.com/nvim-treesitter/nvim-treesitter-context" }, + { src = "https://github.com/nvim-treesitter/nvim-treesitter-textobjects" }, + { src = "https://github.com/RRethy/nvim-treesitter-endwise" }, }) local opts = { noremap = true, silent = true } @@ -175,7 +175,7 @@ keymap("x", "J", ":move '>+1gv-gv", opts) -- in insert mode, adds new undo points after more some chars: for _, lhs in ipairs({ "-", "_", ",", ".", ";", ":", "/", "!", "?" }) do - keymap("i", lhs, lhs .. "u", opts) + keymap("i", lhs, lhs .. "u", opts) end --- @@ -184,19 +184,19 @@ end local bg0 = "#1b1b1b" require("gruvbox").setup({ - contrast = "hard", - overrides = { - GruvboxBg0 = { fg = bg0 }, - SignColumn = { bg = bg0 }, - GruvboxRedSign = { bg = bg0 }, - GruvboxYellowSign = { bg = bg0 }, - GruvboxGreenSign = { bg = bg0 }, - GruvboxAquaSign = { bg = bg0 }, - GruvboxOrangeSign = { bg = bg0 }, - GruvboxPurpleSign = { bg = bg0 }, - GruvboxBlueSign = { bg = bg0 }, - Normal = { bg = bg0 }, - }, + contrast = "hard", + overrides = { + GruvboxBg0 = { fg = bg0 }, + SignColumn = { bg = bg0 }, + GruvboxRedSign = { bg = bg0 }, + GruvboxYellowSign = { bg = bg0 }, + GruvboxGreenSign = { bg = bg0 }, + GruvboxAquaSign = { bg = bg0 }, + GruvboxOrangeSign = { bg = bg0 }, + GruvboxPurpleSign = { bg = bg0 }, + GruvboxBlueSign = { bg = bg0 }, + Normal = { bg = bg0 }, + }, }) vim.cmd("colorscheme gruvbox") -- https://github.com/ellisonleao/gruvbox.nvim/commit/c74e6e523c4827b67af2cb02b636e22dc35fdf70 @@ -208,27 +208,27 @@ require("dressing").setup({ input = { insert_only = true } }) local notify = require("notify") notify.setup({ - render = "compact", - stages = "static", + render = "compact", + stages = "static", }) vim.notify = notify local section_b = { "branch", "diff", { "diagnostics", sources = { "nvim_workspace_diagnostic" } } } local section_c = { "%=", { "filename", file_status = false, path = 1 } } require("lualine").setup({ - options = { - theme = "gruvbox", - component_separators = "", - section_separators = "", - }, - sections = { - lualine_b = section_b, - lualine_c = section_c, - }, - inactive_sections = { - lualine_c = section_c, - lualine_x = { "location" }, - }, + options = { + theme = "gruvbox", + component_separators = "", + section_separators = "", + }, + sections = { + lualine_b = section_b, + lualine_c = section_c, + }, + inactive_sections = { + lualine_c = section_c, + lualine_x = { "location" }, + }, }) require("auto-hlsearch").setup({}) @@ -237,9 +237,9 @@ require("git-conflict").setup({}) -- setup diagnostics vim.diagnostic.config({ - underline = true, - update_in_insert = false, - severity_sort = true, + underline = true, + update_in_insert = false, + severity_sort = true, }) keymap("n", "xx", vim.diagnostic.setqflist, opts) @@ -247,15 +247,15 @@ keymap("n", "xx", vim.diagnostic.setqflist, opts) -- set up diagnostic signs local severity = vim.diagnostic.severity local signs = { - [severity.ERROR] = "", - [severity.WARN] = "", - [severity.INFO] = "", - [severity.HINT] = "󰌶", + [severity.ERROR] = "", + [severity.WARN] = "", + [severity.INFO] = "", + [severity.HINT] = "󰌶", } vim.diagnostic.config({ - signs = { - text = signs, - }, + signs = { + text = signs, + }, }) require("other-nvim").setup({ mappings = { "golang" } }) @@ -267,387 +267,387 @@ require("neogen").setup({ snippet_engine = "nvim" }) keymap("n", "gco", ":Neogen", opts) require("conform").setup({ - formatters_by_ft = { - css = { "prettier" }, - fish = { "fish_indent" }, - html = { "prettier" }, - javascript = { "prettier" }, - json = { "jq" }, - lua = { "stylua" }, - markdown = { "prettier" }, - sh = { "shfmt" }, - sql = { "pg_format", "sql_formatter" }, - templ = { "templ" }, - tf = { "terraform_fmt" }, - yaml = { "prettier" }, - ["_"] = { "trim_whitespace", "trim_newlines" }, - -- let only the lsp take care of these. - go = {}, - rust = {}, - zig = {}, - }, - format_after_save = { - lsp_fallback = true, - }, + formatters_by_ft = { + css = { "prettier" }, + fish = { "fish_indent" }, + html = { "prettier" }, + javascript = { "prettier" }, + json = { "jq" }, + lua = { "stylua" }, + markdown = { "prettier" }, + sh = { "shfmt" }, + sql = { "pg_format", "sql_formatter" }, + templ = { "templ" }, + tf = { "terraform_fmt" }, + yaml = { "prettier" }, + ["_"] = { "trim_whitespace", "trim_newlines" }, + -- let only the lsp take care of these. + go = {}, + rust = {}, + zig = {}, + }, + format_after_save = { + lsp_fallback = true, + }, }) require("copilot").setup({ - suggestion = { enabled = false }, - panel = { enabled = false }, + suggestion = { enabled = false }, + panel = { enabled = false }, }) ---@module 'blink.cmp' ---@type blink.cmp.Config require("blink.cmp").setup({ - keymap = { preset = "default" }, - appearance = { - nerd_font_variant = "mono", - kind_icons = { - Array = "", - Boolean = "", - Class = "", - Color = "", - Constant = "", - Constructor = "", - Copilot = "", - Enum = "", - EnumMember = "", - Event = "", - Field = "", - File = "", - Folder = "󰉋", - Function = "", - Interface = "", - Key = "", - Keyword = "", - Method = "", - Module = "", - Namespace = "", - Null = "󰟢", - Number = "", - Object = "", - Operator = "", - Package = "", - Property = "", - Reference = "", - Snippet = "", - String = "", - Struct = "", - Text = "", - TypeParameter = "", - Unit = "", - Value = "", - Variable = "", - }, - }, - signature = { enabled = true }, - cmdline = { - enabled = true, - sources = function() - local type = vim.fn.getcmdtype() - if type == "/" or type == "?" then - return { "buffer" } - end - if type == ":" then - return { "cmdline" } - end - return {} - end, - completion = { - menu = { - draw = { - columns = { - { "kind_icon", "label", gap = 1 }, - { "kind" }, - }, - }, - }, - }, - }, - sources = { - default = { "lsp", "path", "snippets", "buffer", "copilot" }, - providers = { - lsp = { - min_keyword_length = 0, - score_offset = 0, - }, - path = { - min_keyword_length = 0, - }, - snippets = { - min_keyword_length = 2, - }, - buffer = { - min_keyword_length = 5, - max_items = 5, - }, - copilot = { - name = "copilot", - module = "blink-cmp-copilot", - score_offset = -10000, - min_keyword_length = 0, - async = true, - override = { - -- copilot complete on space, new line, etc as well... - get_trigger_characters = function(self) - local trigger_characters = self:get_trigger_characters() - vim.list_extend(trigger_characters, { "\n", "\t", " " }) - return trigger_characters - end, - }, - transform_items = function(_, items) - local CompletionItemKind = require("blink.cmp.types").CompletionItemKind - local kind_idx = #CompletionItemKind + 1 - CompletionItemKind[kind_idx] = "Copilot" - for _, item in ipairs(items) do - item.kind = kind_idx - end - return items - end, - }, - }, - }, - completion = { - accept = { auto_brackets = { enabled = true } }, - keyword = { - range = "full", - }, - trigger = { - show_on_insert_on_trigger_character = true, - show_on_trigger_character = true, - show_on_keyword = true, - }, - documentation = { - auto_show = true, - auto_show_delay_ms = 250, - treesitter_highlighting = false, - }, - menu = { - draw = { - columns = { - { "kind_icon", "label", gap = 1 }, - { "kind" }, - }, - }, - }, - }, + keymap = { preset = "default" }, + appearance = { + nerd_font_variant = "mono", + kind_icons = { + Array = "", + Boolean = "", + Class = "", + Color = "", + Constant = "", + Constructor = "", + Copilot = "", + Enum = "", + EnumMember = "", + Event = "", + Field = "", + File = "", + Folder = "󰉋", + Function = "", + Interface = "", + Key = "", + Keyword = "", + Method = "", + Module = "", + Namespace = "", + Null = "󰟢", + Number = "", + Object = "", + Operator = "", + Package = "", + Property = "", + Reference = "", + Snippet = "", + String = "", + Struct = "", + Text = "", + TypeParameter = "", + Unit = "", + Value = "", + Variable = "", + }, + }, + signature = { enabled = true }, + cmdline = { + enabled = true, + sources = function() + local type = vim.fn.getcmdtype() + if type == "/" or type == "?" then + return { "buffer" } + end + if type == ":" then + return { "cmdline" } + end + return {} + end, + completion = { + menu = { + draw = { + columns = { + { "kind_icon", "label", gap = 1 }, + { "kind" }, + }, + }, + }, + }, + }, + sources = { + default = { "lsp", "path", "snippets", "buffer", "copilot" }, + providers = { + lsp = { + min_keyword_length = 0, + score_offset = 0, + }, + path = { + min_keyword_length = 0, + }, + snippets = { + min_keyword_length = 2, + }, + buffer = { + min_keyword_length = 5, + max_items = 5, + }, + copilot = { + name = "copilot", + module = "blink-cmp-copilot", + score_offset = -10000, + min_keyword_length = 0, + async = true, + override = { + -- copilot complete on space, new line, etc as well... + get_trigger_characters = function(self) + local trigger_characters = self:get_trigger_characters() + vim.list_extend(trigger_characters, { "\n", "\t", " " }) + return trigger_characters + end, + }, + transform_items = function(_, items) + local CompletionItemKind = require("blink.cmp.types").CompletionItemKind + local kind_idx = #CompletionItemKind + 1 + CompletionItemKind[kind_idx] = "Copilot" + for _, item in ipairs(items) do + item.kind = kind_idx + end + return items + end, + }, + }, + }, + completion = { + accept = { auto_brackets = { enabled = true } }, + keyword = { + range = "full", + }, + trigger = { + show_on_insert_on_trigger_character = true, + show_on_trigger_character = true, + show_on_keyword = true, + }, + documentation = { + auto_show = true, + auto_show_delay_ms = 250, + treesitter_highlighting = false, + }, + menu = { + draw = { + columns = { + { "kind_icon", "label", gap = 1 }, + { "kind" }, + }, + }, + }, + }, }) local function copen() - if vim.fn.getqflist({ size = 0 }).size > 1 then - vim.cmd("copen") - else - vim.cmd("cclose") - end + if vim.fn.getqflist({ size = 0 }).size > 1 then + vim.cmd("copen") + else + vim.cmd("cclose") + end end local function cclear() - vim.fn.setqflist({}, "r") + vim.fn.setqflist({}, "r") end -- Opens the directory of the current file in Finder/file explorer. vim.api.nvim_create_user_command("Finder", "!open %:h", {}) vim.api.nvim_create_autocmd({ - "BufEnter", - "CursorHold", - "CursorHoldI", - "FocusGained", + "BufEnter", + "CursorHold", + "CursorHoldI", + "FocusGained", }, { - pattern = "*", - command = "if mode() != 'c' | checktime | endif", + pattern = "*", + command = "if mode() != 'c' | checktime | endif", }) -- resize splits if window got resized vim.api.nvim_create_autocmd({ "VimResized" }, { - callback = function() - vim.cmd("tabdo wincmd =") - end, + callback = function() + vim.cmd("tabdo wincmd =") + end, }) vim.api.nvim_create_autocmd("FileType", { - pattern = "gitcommit", - command = "startinsert", + pattern = "gitcommit", + command = "startinsert", }) -- ensure the parent folder exists, so it gets properly added to the lsp -- context and everything just works. vim.api.nvim_create_autocmd("BufNewFile", { - pattern = "*", - callback = function() - local dir = vim.fn.expand(":p:h") - if vim.fn.isdirectory(dir) == 0 then - vim.fn.mkdir(dir, "p") - vim.cmd([[ :e % ]]) - end - end, + pattern = "*", + callback = function() + local dir = vim.fn.expand(":p:h") + if vim.fn.isdirectory(dir) == 0 then + vim.fn.mkdir(dir, "p") + vim.cmd([[ :e % ]]) + end + end, }) -- Highlight on yank -- See `:help vim.highlight.on_yank()` vim.api.nvim_create_autocmd("TextYankPost", { - pattern = "*", - callback = function() - vim.hl.on_yank() - end, + pattern = "*", + callback = function() + vim.hl.on_yank() + end, }) -- Open help window in a vertical split to the right. vim.api.nvim_create_autocmd("BufWinEnter", { - pattern = { "*.txt" }, - callback = function() - if vim.o.filetype == "help" then - vim.cmd.wincmd("L") - end - end, + pattern = { "*.txt" }, + callback = function() + if vim.o.filetype == "help" then + vim.cmd.wincmd("L") + end + end, }) vim.api.nvim_create_autocmd("FileType", { - pattern = "git", - callback = function() - local bufnr = vim.api.nvim_get_current_buf() - local buf_opts = { noremap = true, silent = true, buffer = bufnr } - keymap("n", "gq", ":silent! close", buf_opts) - end, + pattern = "git", + callback = function() + local bufnr = vim.api.nvim_get_current_buf() + local buf_opts = { noremap = true, silent = true, buffer = bufnr } + keymap("n", "gq", ":silent! close", buf_opts) + end, }) vim.api.nvim_create_autocmd("FileType", { - pattern = "fugitive", - callback = function() - local bufnr = vim.api.nvim_get_current_buf() - - local function async_git(args, success_msg, error_msg) - vim.system({ "git", unpack(args) }, {}, function(obj) - vim.schedule(function() - if obj.code == 0 then - vim.notify(success_msg, vim.log.levels.INFO) - else - vim.notify(error_msg, vim.log.levels.ERROR) - end - end) - end) - end - - vim.cmd("normal )k=") - - local buf_opts = { noremap = true, silent = true, buffer = bufnr } - keymap("n", "gp", function() - async_git({ "push", "--quiet" }, "Pushed!", "Push failed!") - vim.cmd("silent! close") - end, buf_opts) - - keymap("n", "gP", function() - async_git({ "pull", "--rebase" }, "Pulled!", "Pull failed!") - vim.cmd("silent! close") - end, buf_opts) - - keymap("n", "go", function() - async_git({ "ppr" }, "Pushed and opened PR URL!", "Failed to push or open PR") - vim.cmd("silent! close") - end, buf_opts) - - keymap("n", "cc", ":silent! Git commit -s", buf_opts) - keymap("n", "gq", ":silent! close", buf_opts) - end, + pattern = "fugitive", + callback = function() + local bufnr = vim.api.nvim_get_current_buf() + + local function async_git(args, success_msg, error_msg) + vim.system({ "git", unpack(args) }, {}, function(obj) + vim.schedule(function() + if obj.code == 0 then + vim.notify(success_msg, vim.log.levels.INFO) + else + vim.notify(error_msg, vim.log.levels.ERROR) + end + end) + end) + end + + vim.cmd("normal )k=") + + local buf_opts = { noremap = true, silent = true, buffer = bufnr } + keymap("n", "gp", function() + async_git({ "push", "--quiet" }, "Pushed!", "Push failed!") + vim.cmd("silent! close") + end, buf_opts) + + keymap("n", "gP", function() + async_git({ "pull", "--rebase" }, "Pulled!", "Pull failed!") + vim.cmd("silent! close") + end, buf_opts) + + keymap("n", "go", function() + async_git({ "ppr" }, "Pushed and opened PR URL!", "Failed to push or open PR") + vim.cmd("silent! close") + end, buf_opts) + + keymap("n", "cc", ":silent! Git commit -s", buf_opts) + keymap("n", "gq", ":silent! close", buf_opts) + end, }) vim.api.nvim_create_autocmd("FileType", { - pattern = "gitcommit", - callback = function() - vim.opt_local.spell = true - vim.opt_local.textwidth = 72 - end, + pattern = "gitcommit", + callback = function() + vim.opt_local.spell = true + vim.opt_local.textwidth = 72 + end, }) vim.api.nvim_create_autocmd("FileType", { - pattern = { "qf", "help" }, - callback = function() - keymap("n", "q", ":bdelete", { - buffer = vim.api.nvim_get_current_buf(), - noremap = true, - silent = true, - }) - end, + pattern = { "qf", "help" }, + callback = function() + keymap("n", "q", ":bdelete", { + buffer = vim.api.nvim_get_current_buf(), + noremap = true, + silent = true, + }) + end, }) local get_gopls = function(bufnr) - local clients = vim.lsp.get_clients({ bufnr = bufnr }) - for _, c in ipairs(clients) do - if c.name == "gopls" then - return c - end - end - return nil + local clients = vim.lsp.get_clients({ bufnr = bufnr }) + for _, c in ipairs(clients) do + if c.name == "gopls" then + return c + end + end + return nil end vim.api.nvim_create_autocmd("FileType", { - pattern = "go", - callback = function() - local bufnr = vim.api.nvim_get_current_buf() - - vim.opt_local.formatoptions:append("jo") - vim.opt_local.makeprg = "go build ./..." - vim.opt_local.errorformat = "%A%f:%l:%c: %m,%-G%.%#" - - vim.api.nvim_buf_create_user_command(bufnr, "GoModTidy", function() - local gopls = get_gopls(bufnr) - if gopls == nil then - return - end - - vim.cmd([[ noautocmd wall ]]) - - local uri = vim.uri_from_bufnr(bufnr) - local arguments = { { URIs = { uri } } } - - local err = gopls:request_sync("workspace/executeCommand", { - command = "gopls.tidy", - arguments = arguments, - }, 30000, bufnr) - - if err ~= nil and type(err[1]) == "table" then - vim.notify("go mod tidy: " .. vim.inspect(err), vim.log.levels.ERROR) - return - end - end, { desc = "go mod tidy" }) - - local buf_opts = { noremap = true, silent = true, buffer = bufnr } - keymap("n", "", vim.cmd.GoModTidy, buf_opts) - keymap("n", "", function() - cclear() - vim.fn.jobstart("golangci-lint run --max-issues-per-linter=0 --max-same-issues=0 --new", { - stdout_buffered = true, - on_stdout = function(_, data) - if data and #data > 1 then - vim.schedule(function() - vim.fn.setqflist({}, " ", { lines = data }) - copen() - end) - end - end, - }) - end, buf_opts) - end, + pattern = "go", + callback = function() + local bufnr = vim.api.nvim_get_current_buf() + + vim.opt_local.formatoptions:append("jo") + vim.opt_local.makeprg = "go build ./..." + vim.opt_local.errorformat = "%A%f:%l:%c: %m,%-G%.%#" + + vim.api.nvim_buf_create_user_command(bufnr, "GoModTidy", function() + local gopls = get_gopls(bufnr) + if gopls == nil then + return + end + + vim.cmd([[ noautocmd wall ]]) + + local uri = vim.uri_from_bufnr(bufnr) + local arguments = { { URIs = { uri } } } + + local err = gopls:request_sync("workspace/executeCommand", { + command = "gopls.tidy", + arguments = arguments, + }, 30000, bufnr) + + if err ~= nil and type(err[1]) == "table" then + vim.notify("go mod tidy: " .. vim.inspect(err), vim.log.levels.ERROR) + return + end + end, { desc = "go mod tidy" }) + + local buf_opts = { noremap = true, silent = true, buffer = bufnr } + keymap("n", "", vim.cmd.GoModTidy, buf_opts) + keymap("n", "", function() + cclear() + vim.fn.jobstart("golangci-lint run --max-issues-per-linter=0 --max-same-issues=0 --new", { + stdout_buffered = true, + on_stdout = function(_, data) + if data and #data > 1 then + vim.schedule(function() + vim.fn.setqflist({}, " ", { lines = data }) + copen() + end) + end + end, + }) + end, buf_opts) + end, }) vim.api.nvim_create_autocmd("FileType", { - pattern = "markdown", - callback = function() - vim.opt_local.spell = true - vim.opt_local.textwidth = 80 - vim.opt_local.formatoptions:remove("ct") - end, + pattern = "markdown", + callback = function() + vim.opt_local.spell = true + vim.opt_local.textwidth = 80 + vim.opt_local.formatoptions:remove("ct") + end, }) -- syntax, indentation, treesitter, etc. require("ibl").setup({ - indent = { char = "│" }, - exclude = { filetypes = { "help" } }, - scope = { enabled = false }, + indent = { char = "│" }, + exclude = { filetypes = { "help" } }, + scope = { enabled = false }, }) require("nvim-autopairs").setup({ - check_ts = true, + check_ts = true, }) require("nvim-ts-autotag").setup() @@ -655,139 +655,139 @@ require("nvim-surround").setup() require("todo-comments").setup() require("treesitter-context").setup({ - multiline_threshold = 1, + multiline_threshold = 1, }) ---@diagnostic disable-next-line: missing-fields require("nvim-treesitter.configs").setup({ - ensure_installed = { - "arduino", - "awk", - "bash", - "cpp", - "css", - "csv", - "diff", - "dockerfile", - "fish", - "git_config", - "git_rebase", - "gitattributes", - "gitcommit", - "gitignore", - "go", - "gomod", - "gosum", - "gowork", - "graphql", - "hcl", - "html", - "http", - "http", - "ini", - "javascript", - "jq", - "json", - "lua", - "make", - "markdown", - "markdown_inline", - "mermaid", - "python", - "query", - "regex", - "ruby", - "scss", - "sql", - "ssh_config", - "templ", - "terraform", - "toml", - "vhs", - "vim", - "vimdoc", - "yaml", - "zig", - }, - highlight = { - enable = true, - }, - indent = { - enable = true, - }, - endwise = { - enable = true, - }, - autopairs = { - enable = true, - }, - context_commentstring = { - enable = true, - enable_autocmd = false, - }, - incremental_selection = { - enable = true, - keymaps = { - init_selection = "", - node_incremental = "", - node_decremental = "", - scope_incremental = "", - }, - }, - auto_install = false, - textobjects = { - enable = true, - lookahead = true, - swap = { - enable = true, - swap_next = { - ["a"] = "@parameter.inner", - }, - swap_previous = { - ["A"] = "@parameter.inner", - }, - }, - move = { - enable = true, - set_jumps = true, - goto_next_start = { - ["]f"] = "@function.inner", - ["]c"] = "@class.inner", - ["]a"] = "@parameter.inner", - }, - goto_next_end = { - ["]F"] = "@function.inner", - ["]C"] = "@class.inner", - ["]A"] = "@parameter.inner", - }, - goto_previous_start = { - ["[f"] = "@function.inner", - ["[c"] = "@class.inner", - ["[a"] = "@parameter.inner", - }, - goto_previous_end = { - ["[F"] = "@function.inner", - ["[C"] = "@class.inner", - ["[A"] = "@parameter.inner", - }, - }, - select = { - enable = true, - keymaps = { - ["af"] = "@function.outer", - ["if"] = "@function.inner", - - ["ac"] = "@conditional.outer", - ["ic"] = "@conditional.inner", - - ["aa"] = "@parameter.outer", - ["ia"] = "@parameter.inner", - - ["av"] = "@variable.outer", - ["iv"] = "@variable.inner", - }, - }, - }, + ensure_installed = { + "arduino", + "awk", + "bash", + "cpp", + "css", + "csv", + "diff", + "dockerfile", + "fish", + "git_config", + "git_rebase", + "gitattributes", + "gitcommit", + "gitignore", + "go", + "gomod", + "gosum", + "gowork", + "graphql", + "hcl", + "html", + "http", + "http", + "ini", + "javascript", + "jq", + "json", + "lua", + "make", + "markdown", + "markdown_inline", + "mermaid", + "python", + "query", + "regex", + "ruby", + "scss", + "sql", + "ssh_config", + "templ", + "terraform", + "toml", + "vhs", + "vim", + "vimdoc", + "yaml", + "zig", + }, + highlight = { + enable = true, + }, + indent = { + enable = true, + }, + endwise = { + enable = true, + }, + autopairs = { + enable = true, + }, + context_commentstring = { + enable = true, + enable_autocmd = false, + }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = "", + node_incremental = "", + node_decremental = "", + scope_incremental = "", + }, + }, + auto_install = false, + textobjects = { + enable = true, + lookahead = true, + swap = { + enable = true, + swap_next = { + ["a"] = "@parameter.inner", + }, + swap_previous = { + ["A"] = "@parameter.inner", + }, + }, + move = { + enable = true, + set_jumps = true, + goto_next_start = { + ["]f"] = "@function.inner", + ["]c"] = "@class.inner", + ["]a"] = "@parameter.inner", + }, + goto_next_end = { + ["]F"] = "@function.inner", + ["]C"] = "@class.inner", + ["]A"] = "@parameter.inner", + }, + goto_previous_start = { + ["[f"] = "@function.inner", + ["[c"] = "@class.inner", + ["[a"] = "@parameter.inner", + }, + goto_previous_end = { + ["[F"] = "@function.inner", + ["[C"] = "@class.inner", + ["[A"] = "@parameter.inner", + }, + }, + select = { + enable = true, + keymaps = { + ["af"] = "@function.outer", + ["if"] = "@function.inner", + + ["ac"] = "@conditional.outer", + ["ic"] = "@conditional.inner", + + ["aa"] = "@parameter.outer", + ["ia"] = "@parameter.inner", + + ["av"] = "@variable.outer", + ["iv"] = "@variable.inner", + }, + }, + }, }) local treesj = require("treesj") @@ -796,409 +796,409 @@ keymap("n", "st", treesj.toggle, opts) local telescope = require("telescope") telescope.setup({ - defaults = { - pickers = { - find_files = { - theme = "ivy", - }, - }, - prompt_prefix = "  ", - selection_caret = " ❯ ", - entry_prefix = " ", - multi_icon = "+ ", - path_display = { "filename_first" }, - vimgrep_arguments = { - "rg", - "--color=never", - "--no-heading", - "--with-filename", - "--line-number", - "--column", - "--smart-case", - "--sort=path", - }, - }, + defaults = { + pickers = { + find_files = { + theme = "ivy", + }, + }, + prompt_prefix = "  ", + selection_caret = " ❯ ", + entry_prefix = " ", + multi_icon = "+ ", + path_display = { "filename_first" }, + vimgrep_arguments = { + "rg", + "--color=never", + "--no-heading", + "--with-filename", + "--line-number", + "--column", + "--smart-case", + "--sort=path", + }, + }, }) telescope.load_extension("gh") local function ivy(iopts) - return require("telescope.themes").get_ivy(iopts) + return require("telescope.themes").get_ivy(iopts) end local builtin = require("telescope.builtin") vim.keymap.set("n", "", function() - builtin.find_files(ivy({ - find_command = { - "fd", - "--type", - "f", - "--strip-cwd-prefix", - "--hidden", - }, - })) + builtin.find_files(ivy({ + find_command = { + "fd", + "--type", + "f", + "--strip-cwd-prefix", + "--hidden", + }, + })) end, opts) keymap("n", "of", function() - builtin.oldfiles(ivy({ - only_cwd = true, - })) + builtin.oldfiles(ivy({ + only_cwd = true, + })) end, opts) keymap("n", "lg", function() - builtin.live_grep(ivy()) + builtin.live_grep(ivy()) end, opts) keymap("n", "fb", function() - builtin.buffers(ivy()) + builtin.buffers(ivy()) end, opts) keymap("n", "fh", function() - builtin.help_tags(ivy()) + builtin.help_tags(ivy()) end, opts) keymap("n", "fc", function() - builtin.commands(ivy()) + builtin.commands(ivy()) end, opts) keymap("n", "fr", function() - builtin.resume(ivy()) + builtin.resume(ivy()) end, opts) keymap("n", "fq", function() - builtin.quickfix(ivy()) + builtin.quickfix(ivy()) end, opts) keymap("n", "/", function() - builtin.current_buffer_fuzzy_find(ivy()) + builtin.current_buffer_fuzzy_find(ivy()) end, opts) keymap("n", "ghi", function() - telescope.extensions.gh.issues(ivy()) + telescope.extensions.gh.issues(ivy()) end, opts) -- LSP/autocommands inline replica of caarlos0's modules. local function setup_lsp_autocommands() - local ms = require("vim.lsp.protocol").Methods - local group = vim.api.nvim_create_augroup("LSP", { clear = true }) - - ---@async - ---@param client vim.lsp.Client - ---@param bufnr number - local function organize_imports(client, bufnr) - ---@type lsp.Handler - ---@diagnostic disable-next-line: unused-local - local handler = function(err, result, context, config) - if err then - return - end - for _, r in pairs(result or {}) do - if r.edit then - local enc = client.offset_encoding or "utf-16" - vim.lsp.util.apply_workspace_edit(r.edit, enc) - elseif r.command and r.command.command then - client:exec_cmd(r.command, { bufnr = bufnr }) - end - end - vim.cmd([[noautocmd write]]) - end - - local win = vim.api.nvim_get_current_win() - local params = vim.lsp.util.make_range_params(win, client.offset_encoding or "utf-16") - params.context = { only = { "source.organizeImports" } } - client:request(ms.textDocument_codeAction, params, handler, bufnr) - end - - local function has_clients_with_method(bufnr, method) - local clients = vim.lsp.get_clients({ bufnr = bufnr, method = method }) - return #clients > 0 - end - - local function on_clients(bufnr, method, apply, filter) - local clients = vim.lsp.get_clients({ bufnr = bufnr, method = method }) - local predicate = filter or function() - return true - end - for _, client in ipairs(clients) do - if predicate(client) then - apply(client, bufnr) - end - end - end - - vim.api.nvim_create_autocmd("LspAttach", { - callback = function(args) - local client = vim.lsp.get_client_by_id(args.data.client_id) - if client == nil then - return - end - if client:supports_method(ms.textDocument_codeLens, vim.api.nvim_get_current_buf()) then - vim.lsp.inlay_hint.enable(true) - end - end, - }) - vim.api.nvim_create_autocmd("LspDetach", { - callback = function(args) - local client = vim.lsp.get_client_by_id(args.data.client_id) - if client == nil then - return - end - if client:supports_method(ms.textDocument_codeLens, vim.api.nvim_get_current_buf()) then - vim.lsp.codelens.clear(client.id) - end - end, - group = group, - }) - - vim.api.nvim_create_autocmd({ "BufWritePre" }, { - callback = function() - local format = function(client, bufnr) - if client.server_capabilities.documentFormattingProvider then - vim.lsp.buf.format({ - bufnr = bufnr, - timeout_ms = 5000, - id = client.id, - }) - end - end - on_clients(vim.api.nvim_get_current_buf(), ms.textDocument_codeAction, format) - end, - group = group, - }) - - vim.api.nvim_create_autocmd({ "BufWritePost" }, { - callback = function() - local bufnr = vim.api.nvim_get_current_buf() - local filter = function(client) - return client.name ~= "lua_ls" - end - on_clients(bufnr, ms.textDocument_codeAction, organize_imports, filter) - end, - group = group, - }) - - vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", "InsertLeave" }, { - callback = function() - if has_clients_with_method(0, ms.textDocument_codeLens) then - vim.lsp.codelens.refresh({ bufnr = 0 }) - end - end, - group = group, - }) - - vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { - callback = function() - if has_clients_with_method(0, ms.textDocument_documentHighlight) then - vim.lsp.buf.document_highlight() - end - end, - group = group, - }) - - vim.api.nvim_create_autocmd({ "CursorMoved" }, { - callback = function() - if has_clients_with_method(0, ms.textDocument_documentHighlight) then - vim.lsp.buf.clear_references() - end - end, - group = group, - }) + local ms = require("vim.lsp.protocol").Methods + local group = vim.api.nvim_create_augroup("LSP", { clear = true }) + + ---@async + ---@param client vim.lsp.Client + ---@param bufnr number + local function organize_imports(client, bufnr) + ---@type lsp.Handler + ---@diagnostic disable-next-line: unused-local + local handler = function(err, result, context, config) + if err then + return + end + for _, r in pairs(result or {}) do + if r.edit then + local enc = client.offset_encoding or "utf-16" + vim.lsp.util.apply_workspace_edit(r.edit, enc) + elseif r.command and r.command.command then + client:exec_cmd(r.command, { bufnr = bufnr }) + end + end + vim.cmd([[noautocmd write]]) + end + + local win = vim.api.nvim_get_current_win() + local params = vim.lsp.util.make_range_params(win, client.offset_encoding or "utf-16") + params.context = { only = { "source.organizeImports" } } + client:request(ms.textDocument_codeAction, params, handler, bufnr) + end + + local function has_clients_with_method(bufnr, method) + local clients = vim.lsp.get_clients({ bufnr = bufnr, method = method }) + return #clients > 0 + end + + local function on_clients(bufnr, method, apply, filter) + local clients = vim.lsp.get_clients({ bufnr = bufnr, method = method }) + local predicate = filter or function() + return true + end + for _, client in ipairs(clients) do + if predicate(client) then + apply(client, bufnr) + end + end + end + + vim.api.nvim_create_autocmd("LspAttach", { + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + if client == nil then + return + end + if client:supports_method(ms.textDocument_codeLens, vim.api.nvim_get_current_buf()) then + vim.lsp.inlay_hint.enable(true) + end + end, + }) + vim.api.nvim_create_autocmd("LspDetach", { + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + if client == nil then + return + end + if client:supports_method(ms.textDocument_codeLens, vim.api.nvim_get_current_buf()) then + vim.lsp.codelens.clear(client.id) + end + end, + group = group, + }) + + vim.api.nvim_create_autocmd({ "BufWritePre" }, { + callback = function() + local format = function(client, bufnr) + if client.server_capabilities.documentFormattingProvider then + vim.lsp.buf.format({ + bufnr = bufnr, + timeout_ms = 5000, + id = client.id, + }) + end + end + on_clients(vim.api.nvim_get_current_buf(), ms.textDocument_codeAction, format) + end, + group = group, + }) + + vim.api.nvim_create_autocmd({ "BufWritePost" }, { + callback = function() + local bufnr = vim.api.nvim_get_current_buf() + local filter = function(client) + return client.name ~= "lua_ls" + end + on_clients(bufnr, ms.textDocument_codeAction, organize_imports, filter) + end, + group = group, + }) + + vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", "InsertLeave" }, { + callback = function() + if has_clients_with_method(0, ms.textDocument_codeLens) then + vim.lsp.codelens.refresh({ bufnr = 0 }) + end + end, + group = group, + }) + + vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { + callback = function() + if has_clients_with_method(0, ms.textDocument_documentHighlight) then + vim.lsp.buf.document_highlight() + end + end, + group = group, + }) + + vim.api.nvim_create_autocmd({ "CursorMoved" }, { + callback = function() + if has_clients_with_method(0, ms.textDocument_documentHighlight) then + vim.lsp.buf.clear_references() + end + end, + group = group, + }) end setup_lsp_autocommands() local capabilities = require("blink.cmp").get_lsp_capabilities({ - workspace = { - didChangeWatchedFiles = { - dynamicRegistration = true, - relativePatternSupport = true, - }, - }, + workspace = { + didChangeWatchedFiles = { + dynamicRegistration = true, + relativePatternSupport = true, + }, + }, }, true) ---@param client vim.lsp.Client ---@param bufnr number local on_attach = function(client, bufnr) - local keymap_lsp = function(lhs, rhs) - vim.keymap.set("n", lhs, rhs, { - noremap = true, - silent = true, - buffer = bufnr, - }) - end - - local telescope_wrap = function(action) - return function() - local ivy_theme = require("telescope.themes").get_ivy() - require("telescope.builtin")["lsp_" .. action](ivy_theme) - end - end - - keymap_lsp("gd", telescope_wrap("definitions")) - keymap_lsp("grr", telescope_wrap("references")) - keymap_lsp("gO", telescope_wrap("document_symbols")) - keymap_lsp("gri", telescope_wrap("implementations")) - keymap_lsp("gD", vim.lsp.buf.declaration) - keymap_lsp("K", vim.lsp.buf.hover) - keymap_lsp("D", telescope_wrap("type_definitions")) - keymap_lsp("grl", vim.lsp.codelens.run) - keymap_lsp("gl", vim.diagnostic.open_float) - keymap_lsp("[d", function() - vim.diagnostic.jump({ count = -1 }) - vim.cmd("norm zz") - end) - keymap_lsp("]d", function() - vim.diagnostic.jump({ count = 1 }) - vim.cmd("norm zz") - end) - - keymap_lsp("v", function() - vim.cmd("vsplit | lua vim.lsp.buf.definition()") - vim.cmd("norm zz") - end) + local keymap_lsp = function(lhs, rhs) + vim.keymap.set("n", lhs, rhs, { + noremap = true, + silent = true, + buffer = bufnr, + }) + end + + local telescope_wrap = function(action) + return function() + local ivy_theme = require("telescope.themes").get_ivy() + require("telescope.builtin")["lsp_" .. action](ivy_theme) + end + end + + keymap_lsp("gd", telescope_wrap("definitions")) + keymap_lsp("grr", telescope_wrap("references")) + keymap_lsp("gO", telescope_wrap("document_symbols")) + keymap_lsp("gri", telescope_wrap("implementations")) + keymap_lsp("gD", vim.lsp.buf.declaration) + keymap_lsp("K", vim.lsp.buf.hover) + keymap_lsp("D", telescope_wrap("type_definitions")) + keymap_lsp("grl", vim.lsp.codelens.run) + keymap_lsp("gl", vim.diagnostic.open_float) + keymap_lsp("[d", function() + vim.diagnostic.jump({ count = -1 }) + vim.cmd("norm zz") + end) + keymap_lsp("]d", function() + vim.diagnostic.jump({ count = 1 }) + vim.cmd("norm zz") + end) + + keymap_lsp("v", function() + vim.cmd("vsplit | lua vim.lsp.buf.definition()") + vim.cmd("norm zz") + end) end local lspconfig = require("lspconfig") require("lspconfig.ui.windows").default_options.border = "none" lspconfig.gopls.setup({ - capabilities = capabilities, - on_attach = on_attach, - settings = { - gopls = { - gofumpt = true, - codelenses = { - gc_details = true, - generate = true, - run_govulncheck = true, - test = true, - tidy = true, - upgrade_dependency = true, - }, - hints = { - assignVariableTypes = true, - compositeLiteralFields = true, - compositeLiteralTypes = true, - constantValues = true, - functionTypeParameters = true, - parameterNames = true, - rangeVariableTypes = true, - }, - analyses = { - nilness = true, - unusedparams = true, - unusedvariable = true, - unusedwrite = true, - useany = true, - }, - staticcheck = true, - directoryFilters = { "-.git", "-node_modules" }, - semanticTokens = true, - }, - }, - flags = { - debounce_text_changes = 150, - }, + capabilities = capabilities, + on_attach = on_attach, + settings = { + gopls = { + gofumpt = true, + codelenses = { + gc_details = true, + generate = true, + run_govulncheck = true, + test = true, + tidy = true, + upgrade_dependency = true, + }, + hints = { + assignVariableTypes = true, + compositeLiteralFields = true, + compositeLiteralTypes = true, + constantValues = true, + functionTypeParameters = true, + parameterNames = true, + rangeVariableTypes = true, + }, + analyses = { + nilness = true, + unusedparams = true, + unusedvariable = true, + unusedwrite = true, + useany = true, + }, + staticcheck = true, + directoryFilters = { "-.git", "-node_modules" }, + semanticTokens = true, + }, + }, + flags = { + debounce_text_changes = 150, + }, }) lspconfig.ts_ls.setup({ - capabilities = capabilities, - on_attach = on_attach, - settings = { - javascript = { - inlayHints = { - includeInlayEnumMemberValueHints = true, - includeInlayFunctionLikeReturnTypeHints = true, - includeInlayFunctionParameterTypeHints = true, - includeInlayParameterNameHints = "all", - includeInlayParameterNameHintsWhenArgumentMatchesName = true, - includeInlayPropertyDeclarationTypeHints = true, - includeInlayVariableTypeHints = true, - }, - }, - typescript = { - inlayHints = { - includeInlayEnumMemberValueHints = true, - includeInlayFunctionLikeReturnTypeHints = true, - includeInlayFunctionParameterTypeHints = true, - includeInlayParameterNameHints = "all", - includeInlayParameterNameHintsWhenArgumentMatchesName = true, - includeInlayPropertyDeclarationTypeHints = true, - includeInlayVariableTypeHints = true, - }, - }, - }, + capabilities = capabilities, + on_attach = on_attach, + settings = { + javascript = { + inlayHints = { + includeInlayEnumMemberValueHints = true, + includeInlayFunctionLikeReturnTypeHints = true, + includeInlayFunctionParameterTypeHints = true, + includeInlayParameterNameHints = "all", + includeInlayParameterNameHintsWhenArgumentMatchesName = true, + includeInlayPropertyDeclarationTypeHints = true, + includeInlayVariableTypeHints = true, + }, + }, + typescript = { + inlayHints = { + includeInlayEnumMemberValueHints = true, + includeInlayFunctionLikeReturnTypeHints = true, + includeInlayFunctionParameterTypeHints = true, + includeInlayParameterNameHints = "all", + includeInlayParameterNameHintsWhenArgumentMatchesName = true, + includeInlayPropertyDeclarationTypeHints = true, + includeInlayVariableTypeHints = true, + }, + }, + }, }) for _, lsp in ipairs({ - "bashls", - "clangd", - "cssls", - "jsonls", - "pylsp", - "rust_analyzer", - "taplo", - "templ", - "terraformls", - "tflint", - "zls", + "bashls", + "clangd", + "cssls", + "jsonls", + "pylsp", + "rust_analyzer", + "taplo", + "templ", + "terraformls", + "tflint", + "zls", }) do - lspconfig[lsp].setup({ - on_attach = on_attach, - capabilities = capabilities, - }) + lspconfig[lsp].setup({ + on_attach = on_attach, + capabilities = capabilities, + }) end for _, lsp in ipairs({ "html", "htmx" }) do - lspconfig[lsp].setup({ - capabilities = capabilities, - on_attach = on_attach, - filetypes = { "html", "templ" }, - }) + lspconfig[lsp].setup({ + capabilities = capabilities, + on_attach = on_attach, + filetypes = { "html", "templ" }, + }) end lspconfig.tailwindcss.setup({ - on_attach = on_attach, - capabilities = capabilities, - filetypes = { "html", "templ", "javascript" }, - settings = { - tailwindCSS = { - includeLanguages = { - templ = "html", - }, - }, - }, + on_attach = on_attach, + capabilities = capabilities, + filetypes = { "html", "templ", "javascript" }, + settings = { + tailwindCSS = { + includeLanguages = { + templ = "html", + }, + }, + }, }) lspconfig.yamlls.setup({ - capabilities = capabilities, - on_attach = on_attach, - settings = { - yaml = { - schemaStore = { - url = "https://www.schemastore.org/api/json/catalog.json", - enable = true, - }, - }, - }, + capabilities = capabilities, + on_attach = on_attach, + settings = { + yaml = { + schemaStore = { + url = "https://www.schemastore.org/api/json/catalog.json", + enable = true, + }, + }, + }, }) local runtime_path = vim.split(package.path, ";", {}) table.insert(runtime_path, "lua/?.lua") table.insert(runtime_path, "lua/?/init.lua") lspconfig.lua_ls.setup({ - capabilities = capabilities, - on_attach = on_attach, - settings = { - Lua = { - completion = { - callSnippet = "Replace", - }, - telemetry = { enable = false }, - hint = { - enable = true, - }, - workspace = { - library = vim.api.nvim_get_runtime_file("", true), - }, - }, - }, + capabilities = capabilities, + on_attach = on_attach, + settings = { + Lua = { + completion = { + callSnippet = "Replace", + }, + telemetry = { enable = false }, + hint = { + enable = true, + }, + workspace = { + library = vim.api.nvim_get_runtime_file("", true), + }, + }, + }, }) diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json index 343b5c8f5..825509dcc 100644 --- a/config/nvim/nvim-pack-lock.json +++ b/config/nvim/nvim-pack-lock.json @@ -42,4 +42,4 @@ "vim-speeddating": [], "vim-tmux-navigator": [] } -} \ No newline at end of file +} diff --git a/flake.lock b/flake.lock index 53c2d7eaa..7321d8132 100644 --- a/flake.lock +++ b/flake.lock @@ -66,6 +66,27 @@ } }, "flake-parts_2": { + "inputs": { + "nixpkgs-lib": [ + "neovim-nightly-overlay", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1763759067, + "narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_3": { "inputs": { "nixpkgs-lib": [ "nur", @@ -106,6 +127,44 @@ "type": "github" } }, + "neovim-nightly-overlay": { + "inputs": { + "flake-parts": "flake-parts_2", + "neovim-src": "neovim-src", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1763769887, + "narHash": "sha256-Viyww4Atra7fD4IuhUwFGBtkyIgzuG3lLXu9gdGdEaU=", + "owner": "nix-community", + "repo": "neovim-nightly-overlay", + "rev": "34efe16d64996dca36f9bae9fb954a867f9d2680", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "neovim-nightly-overlay", + "type": "github" + } + }, + "neovim-src": { + "flake": false, + "locked": { + "lastModified": 1763766790, + "narHash": "sha256-GLflfd2+d4KEwvwapZGvjVuYUFAsbpDxEkgmOni89JM=", + "owner": "neovim", + "repo": "neovim", + "rev": "1c12073db6c64eb365748f153f96be9b0fe61070", + "type": "github" + }, + "original": { + "owner": "neovim", + "repo": "neovim", + "type": "github" + } + }, "nix-darwin": { "inputs": { "nixpkgs": [ @@ -159,7 +218,7 @@ }, "nur": { "inputs": { - "flake-parts": "flake-parts_2", + "flake-parts": "flake-parts_3", "nixpkgs": [ "nixpkgs" ] @@ -183,6 +242,7 @@ "agenix": "agenix", "flake-parts": "flake-parts", "home-manager": "home-manager", + "neovim-nightly-overlay": "neovim-nightly-overlay", "nix-darwin": "nix-darwin", "nixpkgs": "nixpkgs", "nur": "nur", diff --git a/flake.nix b/flake.nix index 6d29d35c3..8ec23470e 100644 --- a/flake.nix +++ b/flake.nix @@ -29,6 +29,10 @@ inputs.nixpkgs.follows = "nixpkgs"; inputs.home-manager.follows = "home-manager"; }; + neovim-nightly-overlay = { + url = "github:nix-community/neovim-nightly-overlay"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = diff --git a/home-manager/default.nix b/home-manager/default.nix index aaabbc42c..c52d192bf 100644 --- a/home-manager/default.nix +++ b/home-manager/default.nix @@ -41,6 +41,8 @@ in ]; }; + nixpkgs.overlays = [ inputs.neovim-nightly-overlay.overlays.default ]; + home.username = username; home.homeDirectory = lib.mkIf pkgs.stdenv.isLinux "/home/${username}"; home.packages = packages; diff --git a/home-manager/programs/neovim/default.nix b/home-manager/programs/neovim/default.nix index 47b71d365..193f64d5b 100644 --- a/home-manager/programs/neovim/default.nix +++ b/home-manager/programs/neovim/default.nix @@ -1,6 +1,8 @@ +{ pkgs, ... }: { programs.neovim = { enable = true; + package = pkgs.neovim; defaultEditor = true; vimAlias = true; vimdiffAlias = true; diff --git a/hosts/darwin/default.nix b/hosts/darwin/default.nix index d342eeb8a..2500ece9c 100644 --- a/hosts/darwin/default.nix +++ b/hosts/darwin/default.nix @@ -5,8 +5,18 @@ isRunner ? false, }: let - inherit (inputs) nix-darwin home-manager agenix; + inherit (inputs) + nix-darwin + home-manager + agenix + neovim-nightly-overlay + ; system = "aarch64-darwin"; + pkgs = import inputs.nixpkgs { + inherit system; + overlays = [ neovim-nightly-overlay.overlays.default ]; + config.allowUnfree = true; + }; configuration = { ... }: { @@ -40,9 +50,8 @@ in ]; home-manager.useUserPackages = true; home-manager.users."${username}" = import ../../home-manager { - inherit inputs username; - lib = inputs.nixpkgs.legacyPackages.${system}.lib; - pkgs = inputs.nixpkgs.legacyPackages.${system}; + inherit inputs username pkgs; + lib = pkgs.lib; config = { }; }; } From 4edb9f1c8959b6bcd81320cebbab863fd4159de9 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 09:07:49 -0600 Subject: [PATCH 07/92] feat(nvim): add commands for updating and syncing neovim plugins --- Makefile | 16 +++ config/nvim/nvim-pack-lock.json | 194 +++++++++++++++++++++++++------- 2 files changed, 171 insertions(+), 39 deletions(-) diff --git a/Makefile b/Makefile index 738b9b43e..49070d9eb 100644 --- a/Makefile +++ b/Makefile @@ -108,6 +108,8 @@ help: @echo " encrypt-key-HOST - Encrypt a key for a named host (e.g., make encrypt-key-galactica KEY_FILE=~/.ssh/id_ed25519)" @echo " decrypt-key-HOST - Decrypt a key for a named host (e.g., make decrypt-key-galactica KEY_FILE=id_ed25519)" @echo " rekey-HOST - Rekey all secrets for a named host (e.g., make rekey-galactica)" + @echo " nvim-update - Update neovim plugins and lock file" + @echo " nvim-sync - Sync neovim plugins (install missing, remove unused)" ##@ General @@ -417,6 +419,20 @@ docker-build: @docker build -t $(DOCKER_IMAGE_LATEST) -t $(DOCKER_IMAGE_TAGGED) -f Dockerfile . @echo "✅ Docker image built: $(DOCKER_IMAGE_LATEST) and $(DOCKER_IMAGE_TAGGED)" +##@ Neovim + +.PHONY: nvim-update +nvim-update: + @echo "📦 Updating neovim plugins..." + @nvim --headless +"lua vim.pack.update()" +qa + @echo "✅ Neovim plugins updated" + +.PHONY: nvim-sync +nvim-sync: + @echo "🔄 Syncing neovim plugins..." + @nvim --headless +"lua vim.pack.sync()" +qa + @echo "✅ Neovim plugins synced" + ##@ Git Submodule .PHONY: git-submodule-sync diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json index 825509dcc..a7576cdfd 100644 --- a/config/nvim/nvim-pack-lock.json +++ b/config/nvim/nvim-pack-lock.json @@ -1,45 +1,161 @@ { "plugins": { - "auto-hlsearch.nvim": [], - "blink-cmp-copilot": [], + "auto-hlsearch.nvim": { + "rev": "77502069b22e48ab7736fe9cf53e1fdac1923bca", + "src": "https://github.com/asiryk/auto-hlsearch.nvim" + }, + "blink-cmp-copilot": { + "rev": "439cff78780c033aa23cf061d7315314b347e3c1", + "src": "https://github.com/giuxtaposition/blink-cmp-copilot" + }, "blink.cmp": { + "rev": "b19413d214068f316c78978b08264ed1c41830ec", + "src": "https://github.com/saghen/blink.cmp", "version": "1.0.0 - 2.0.0" }, - "bufdelete.nvim": [], - "conform.nvim": [], - "copilot.lua": [], - "dressing.nvim": [], - "friendly-snippets": [], - "git-conflict.nvim": [], - "gitsigns.nvim": [], - "gruvbox.nvim": [], - "indent-blankline.nvim": [], - "lualine.nvim": [], - "neogen": [], - "nvim-autopairs": [], - "nvim-colorizer.lua": [], - "nvim-lspconfig": [], - "nvim-notify": [], - "nvim-surround": [], - "nvim-treesitter": [], - "nvim-treesitter-context": [], - "nvim-treesitter-endwise": [], - "nvim-treesitter-textobjects": [], - "nvim-ts-autotag": [], - "nvim-web-devicons": [], - "other.nvim": [], - "plenary.nvim": [], - "telescope-github.nvim": [], - "telescope.nvim": [], - "todo-comments.nvim": [], - "treesj": [], - "vim-abolish": [], - "vim-eunuch": [], - "vim-fugitive": [], - "vim-repeat": [], - "vim-rhubarb": [], - "vim-sleuth": [], - "vim-speeddating": [], - "vim-tmux-navigator": [] + "bufdelete.nvim": { + "rev": "f6bcea78afb3060b198125256f897040538bcb81", + "src": "https://github.com/famiu/bufdelete.nvim" + }, + "conform.nvim": { + "rev": "afce105eb47b0869dfafdac90d82f02ef2419d61", + "src": "https://github.com/stevearc/conform.nvim" + }, + "copilot.lua": { + "rev": "4383e05a47493d7ff77b058c0548129eb38ec7fb", + "src": "https://github.com/zbirenbaum/copilot.lua" + }, + "dressing.nvim": { + "rev": "2d7c2db2507fa3c4956142ee607431ddb2828639", + "src": "https://github.com/stevearc/dressing.nvim" + }, + "friendly-snippets": { + "rev": "572f5660cf05f8cd8834e096d7b4c921ba18e175", + "src": "https://github.com/rafamadriz/friendly-snippets" + }, + "git-conflict.nvim": { + "rev": "a1badcd070d176172940eb55d9d59029dad1c5a6", + "src": "https://github.com/akinsho/git-conflict.nvim" + }, + "gitsigns.nvim": { + "rev": "cdafc320f03f2572c40ab93a4eecb733d4016d07", + "src": "https://github.com/lewis6991/gitsigns.nvim" + }, + "gruvbox.nvim": { + "rev": "5e0a460d8e0f7f669c158dedd5f9ae2bcac31437", + "src": "https://github.com/ellisonleao/gruvbox.nvim" + }, + "indent-blankline.nvim": { + "rev": "005b56001b2cb30bfa61b7986bc50657816ba4ba", + "src": "https://github.com/lukas-reineke/indent-blankline.nvim" + }, + "lualine.nvim": { + "rev": "3946f0122255bc377d14a59b27b609fb3ab25768", + "src": "https://github.com/nvim-lualine/lualine.nvim" + }, + "neogen": { + "rev": "d7f9461727751fb07f82011051338a9aba07581d", + "src": "https://github.com/danymat/neogen" + }, + "nvim-autopairs": { + "rev": "7a2c97cccd60abc559344042fefb1d5a85b3e33b", + "src": "https://github.com/windwp/nvim-autopairs" + }, + "nvim-colorizer.lua": { + "rev": "a065833f35a3a7cc3ef137ac88b5381da2ba302e", + "src": "https://github.com/norcalli/nvim-colorizer.lua" + }, + "nvim-lspconfig": { + "rev": "a2a277114dbb93e98f04b5087a9b832918b7da15", + "src": "https://github.com/neovim/nvim-lspconfig" + }, + "nvim-notify": { + "rev": "8701bece920b38ea289b457f902e2ad184131a5d", + "src": "https://github.com/rcarriga/nvim-notify" + }, + "nvim-surround": { + "rev": "fcfa7e02323d57bfacc3a141f8a74498e1522064", + "src": "https://github.com/kylechui/nvim-surround" + }, + "nvim-treesitter": { + "rev": "42fc28ba918343ebfd5565147a42a26580579482", + "src": "https://github.com/nvim-treesitter/nvim-treesitter" + }, + "nvim-treesitter-context": { + "rev": "660861b1849256398f70450afdf93908d28dc945", + "src": "https://github.com/nvim-treesitter/nvim-treesitter-context" + }, + "nvim-treesitter-endwise": { + "rev": "a61a9de7965324d4019fb1637b66bfacdcb01f51", + "src": "https://github.com/RRethy/nvim-treesitter-endwise" + }, + "nvim-treesitter-textobjects": { + "rev": "5ca4aaa6efdcc59be46b95a3e876300cfead05ef", + "src": "https://github.com/nvim-treesitter/nvim-treesitter-textobjects" + }, + "nvim-ts-autotag": { + "rev": "c4ca798ab95b316a768d51eaaaee48f64a4a46bc", + "src": "https://github.com/windwp/nvim-ts-autotag" + }, + "nvim-web-devicons": { + "rev": "8dcb311b0c92d460fac00eac706abd43d94d68af", + "src": "https://github.com/nvim-tree/nvim-web-devicons" + }, + "other.nvim": { + "rev": "1d48e090f6d1d53dda9fb5094af3f2006ebbb858", + "src": "https://github.com/rgroli/other.nvim" + }, + "plenary.nvim": { + "rev": "b9fd5226c2f76c951fc8ed5923d85e4de065e509", + "src": "https://github.com/nvim-lua/plenary.nvim" + }, + "telescope-github.nvim": { + "rev": "ee95c509901c3357679e9f2f9eaac3561c811736", + "src": "https://github.com/nvim-telescope/telescope-github.nvim" + }, + "telescope.nvim": { + "rev": "83a3a713d6b2d2a408491a1b959e55a7fa8678e8", + "src": "https://github.com/nvim-telescope/telescope.nvim" + }, + "todo-comments.nvim": { + "rev": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668", + "src": "https://github.com/folke/todo-comments.nvim" + }, + "treesj": { + "rev": "4770492244ccecdc9b01e0e81fa8f2f6b4a23841", + "src": "https://github.com/wansmer/treesj" + }, + "vim-abolish": { + "rev": "dcbfe065297d31823561ba787f51056c147aa682", + "src": "https://github.com/tpope/vim-abolish" + }, + "vim-eunuch": { + "rev": "e86bb794a1c10a2edac130feb0ea590a00d03f1e", + "src": "https://github.com/tpope/vim-eunuch" + }, + "vim-fugitive": { + "rev": "61b51c09b7c9ce04e821f6cf76ea4f6f903e3cf4", + "src": "https://github.com/tpope/vim-fugitive" + }, + "vim-repeat": { + "rev": "65846025c15494983dafe5e3b46c8f88ab2e9635", + "src": "https://github.com/tpope/vim-repeat" + }, + "vim-rhubarb": { + "rev": "5496d7c94581c4c9ad7430357449bb57fc59f501", + "src": "https://github.com/tpope/vim-rhubarb" + }, + "vim-sleuth": { + "rev": "be69bff86754b1aa5adcbb527d7fcd1635a84080", + "src": "https://github.com/tpope/vim-sleuth" + }, + "vim-speeddating": { + "rev": "c17eb01ebf5aaf766c53bab1f6592710e5ffb796", + "src": "https://github.com/tpope/vim-speeddating" + }, + "vim-tmux-navigator": { + "rev": "c45243dc1f32ac6bcf6068e5300f3b2b237e576a", + "src": "https://github.com/christoomey/vim-tmux-navigator" + } } -} +} \ No newline at end of file From 3b39818ea9b18d94659e8294d76ef1d35e501da3 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 09:09:10 -0600 Subject: [PATCH 08/92] chore: update Makefile to include nvim-update in the update target and remove obsolete nvim commands from help --- Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 49070d9eb..2436c6962 100644 --- a/Makefile +++ b/Makefile @@ -108,8 +108,6 @@ help: @echo " encrypt-key-HOST - Encrypt a key for a named host (e.g., make encrypt-key-galactica KEY_FILE=~/.ssh/id_ed25519)" @echo " decrypt-key-HOST - Decrypt a key for a named host (e.g., make decrypt-key-galactica KEY_FILE=id_ed25519)" @echo " rekey-HOST - Rekey all secrets for a named host (e.g., make rekey-galactica)" - @echo " nvim-update - Update neovim plugins and lock file" - @echo " nvim-sync - Sync neovim plugins (install missing, remove unused)" ##@ General @@ -138,7 +136,7 @@ setup-dev: nix-setup git-submodule-sync shell-install switch: nix-switch .PHONY: update -update: nix-update shell-update +update: nix-update shell-update nvim-update .PHONY: dev dev: nix-develop From b82563ebdcb470809d0382e8f235eb0cd38a72b7 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 09:14:24 -0600 Subject: [PATCH 09/92] feat(nvim): enable automatic installation of treesitter parsers --- config/nvim/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index f0bc8e592..6fc0d94e9 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -734,7 +734,7 @@ require("nvim-treesitter.configs").setup({ scope_incremental = "", }, }, - auto_install = false, + auto_install = true, textobjects = { enable = true, lookahead = true, From dbe83f4842c4e8ee1fd6e25037026651efb1eb23 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 09:17:22 -0600 Subject: [PATCH 10/92] refactor(nvim): switch color scheme from gruvbox to dracula - Updated the Neovim configuration to replace the gruvbox color scheme with dracula. - Adjusted related settings in the lualine plugin to reflect the new theme. --- config/nvim/init.lua | 21 +++------------------ config/nvim/nvim-pack-lock.json | 4 ++++ 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 6fc0d94e9..09d5893a3 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -71,7 +71,7 @@ inoreabbrev sao são vim.pack.add({ -- UI { src = "https://github.com/nvim-tree/nvim-web-devicons" }, - { src = "https://github.com/ellisonleao/gruvbox.nvim" }, + { src = "https://github.com/Mofiqul/dracula.nvim" }, { src = "https://github.com/nvim-lualine/lualine.nvim" }, { src = "https://github.com/stevearc/dressing.nvim" }, { src = "https://github.com/rcarriga/nvim-notify" }, @@ -183,22 +183,7 @@ end --- local bg0 = "#1b1b1b" -require("gruvbox").setup({ - contrast = "hard", - overrides = { - GruvboxBg0 = { fg = bg0 }, - SignColumn = { bg = bg0 }, - GruvboxRedSign = { bg = bg0 }, - GruvboxYellowSign = { bg = bg0 }, - GruvboxGreenSign = { bg = bg0 }, - GruvboxAquaSign = { bg = bg0 }, - GruvboxOrangeSign = { bg = bg0 }, - GruvboxPurpleSign = { bg = bg0 }, - GruvboxBlueSign = { bg = bg0 }, - Normal = { bg = bg0 }, - }, -}) -vim.cmd("colorscheme gruvbox") +vim.cmd("colorscheme dracula") -- https://github.com/ellisonleao/gruvbox.nvim/commit/c74e6e523c4827b67af2cb02b636e22dc35fdf70 -- https://github.com/nvim-lualine/lualine.nvim/issues/1312 vim.api.nvim_set_hl(0, "StatusLine", { reverse = false }) @@ -217,7 +202,7 @@ local section_b = { "branch", "diff", { "diagnostics", sources = { "nvim_workspa local section_c = { "%=", { "filename", file_status = false, path = 1 } } require("lualine").setup({ options = { - theme = "gruvbox", + theme = "dracula", component_separators = "", section_separators = "", }, diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json index a7576cdfd..25de5dc55 100644 --- a/config/nvim/nvim-pack-lock.json +++ b/config/nvim/nvim-pack-lock.json @@ -25,6 +25,10 @@ "rev": "4383e05a47493d7ff77b058c0548129eb38ec7fb", "src": "https://github.com/zbirenbaum/copilot.lua" }, + "dracula.nvim": { + "rev": "ae752c13e95fb7c5f58da4b5123cb804ea7568ee", + "src": "https://github.com/Mofiqul/dracula.nvim" + }, "dressing.nvim": { "rev": "2d7c2db2507fa3c4956142ee607431ddb2828639", "src": "https://github.com/stevearc/dressing.nvim" From 7ff7687722861a797784bd75275aebce19615e88 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 09:17:52 -0600 Subject: [PATCH 11/92] refactor(makefile): rename nvim commands to neovim for consistency - Updated the Makefile to rename nvim-update and nvim-sync to neovim-update and neovim-sync, respectively, for improved clarity and consistency in naming. --- Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 2436c6962..e29fd0f37 100644 --- a/Makefile +++ b/Makefile @@ -136,7 +136,7 @@ setup-dev: nix-setup git-submodule-sync shell-install switch: nix-switch .PHONY: update -update: nix-update shell-update nvim-update +update: nix-update shell-update neovim-update .PHONY: dev dev: nix-develop @@ -419,14 +419,14 @@ docker-build: ##@ Neovim -.PHONY: nvim-update -nvim-update: +.PHONY: neovim-update +neovim-update: @echo "📦 Updating neovim plugins..." @nvim --headless +"lua vim.pack.update()" +qa @echo "✅ Neovim plugins updated" -.PHONY: nvim-sync -nvim-sync: +.PHONY: neovim-sync +neovim-sync: @echo "🔄 Syncing neovim plugins..." @nvim --headless +"lua vim.pack.sync()" +qa @echo "✅ Neovim plugins synced" From beed7d95c1d1f814d6775a5834cfb94e7ffc3cbb Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 09:24:03 -0600 Subject: [PATCH 12/92] feat(nvim): add sidekick.nvim plugin for enhanced functionality --- config/nvim/init.lua | 1 + config/nvim/nvim-pack-lock.json | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 09d5893a3..07ea72e6f 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -72,6 +72,7 @@ vim.pack.add({ -- UI { src = "https://github.com/nvim-tree/nvim-web-devicons" }, { src = "https://github.com/Mofiqul/dracula.nvim" }, + { src = "https://github.com/folke/sidekick.nvim" }, { src = "https://github.com/nvim-lualine/lualine.nvim" }, { src = "https://github.com/stevearc/dressing.nvim" }, { src = "https://github.com/rcarriga/nvim-notify" }, diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json index 25de5dc55..b715ecea2 100644 --- a/config/nvim/nvim-pack-lock.json +++ b/config/nvim/nvim-pack-lock.json @@ -113,6 +113,10 @@ "rev": "b9fd5226c2f76c951fc8ed5923d85e4de065e509", "src": "https://github.com/nvim-lua/plenary.nvim" }, + "sidekick.nvim": { + "rev": "c2bdf8cfcd87a6be5f8b84322c1b5052e78e302e", + "src": "https://github.com/folke/sidekick.nvim" + }, "telescope-github.nvim": { "rev": "ee95c509901c3357679e9f2f9eaac3561c811736", "src": "https://github.com/nvim-telescope/telescope-github.nvim" From 43853b9da3446a7a069d7aeffdb7199382ec8061 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 09:35:25 -0600 Subject: [PATCH 13/92] feat(nvim): add nvim-tree.lua plugin for file navigation --- config/nvim/init.lua | 8 ++++++++ config/nvim/nvim-pack-lock.json | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 07ea72e6f..0f05f5f26 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -73,6 +73,7 @@ vim.pack.add({ { src = "https://github.com/nvim-tree/nvim-web-devicons" }, { src = "https://github.com/Mofiqul/dracula.nvim" }, { src = "https://github.com/folke/sidekick.nvim" }, + { src = "https://github.com/nvim-tree/nvim-tree.lua" }, { src = "https://github.com/nvim-lualine/lualine.nvim" }, { src = "https://github.com/stevearc/dressing.nvim" }, { src = "https://github.com/rcarriga/nvim-notify" }, @@ -1188,3 +1189,10 @@ lspconfig.lua_ls.setup({ }, }, }) + +require("nvim-tree").setup({ + view = { + width = 30, + }, +}) +keymap("n", "", ":NvimTreeToggle", opts) diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json index b715ecea2..9812f3bbf 100644 --- a/config/nvim/nvim-pack-lock.json +++ b/config/nvim/nvim-pack-lock.json @@ -81,6 +81,10 @@ "rev": "fcfa7e02323d57bfacc3a141f8a74498e1522064", "src": "https://github.com/kylechui/nvim-surround" }, + "nvim-tree.lua": { + "rev": "3fb91e18a727ecc0385637895ec397dea90be42a", + "src": "https://github.com/nvim-tree/nvim-tree.lua" + }, "nvim-treesitter": { "rev": "42fc28ba918343ebfd5565147a42a26580579482", "src": "https://github.com/nvim-treesitter/nvim-treesitter" From de4ed09659f3fd6385afb57c75f16a9147a2a276 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 09:37:12 -0600 Subject: [PATCH 14/92] refactor(nvim): remove obsolete color scheme references and clean up status line settings - Removed outdated comments related to previous color schemes. - Ensured status line highlight settings are clear and concise. --- config/nvim/init.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 0f05f5f26..ee0100d6b 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -186,8 +186,6 @@ end local bg0 = "#1b1b1b" vim.cmd("colorscheme dracula") --- https://github.com/ellisonleao/gruvbox.nvim/commit/c74e6e523c4827b67af2cb02b636e22dc35fdf70 --- https://github.com/nvim-lualine/lualine.nvim/issues/1312 vim.api.nvim_set_hl(0, "StatusLine", { reverse = false }) vim.api.nvim_set_hl(0, "StatusLineNC", { reverse = false }) From 2673029242e6189741d72593c81cbdcefc132b71 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 17:19:03 -0600 Subject: [PATCH 15/92] chore: update --- Makefile | 39 ++++++++++++++++++++++++++++++++++ nix-darwin/config/homebrew.nix | 2 +- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e29fd0f37..e46fd10a9 100644 --- a/Makefile +++ b/Makefile @@ -328,6 +328,45 @@ nix-switch-vm: timeout 600 ./result/bin/run-nixos-vm -nographic < vm_commands.txt || exit 1; \ rm -f vm_commands.txt +##@ Nix Offline Mode + +.PHONY: nix-build-offline +nix-build-offline: + @echo "🏗️ Building Nix configuration in offline mode" + @if [ "$(OS)" = "Darwin" ]; then \ + NIX_OFFLINE=1 $(NIX_ALLOW_UNFREE) $(NIX_EXEC) build .#darwinConfigurations.galactica.system $(NIX_FLAGS) --impure --no-update-lock-file --offline --show-trace; \ + elif [ "$(NIX_CONFIG_TYPE)" = "nixosConfigurations" ]; then \ + NIX_OFFLINE=1 $(NIX_ALLOW_UNFREE) $(NIX_EXEC) build .#nixosConfigurations.runner.config.system.build.toplevel $(NIX_FLAGS) --impure --no-update-lock-file --offline --show-trace; \ + elif [ "$(NIX_CONFIG_TYPE)" = "homeConfigurations" ]; then \ + NIX_OFFLINE=1 $(NIX_ALLOW_UNFREE) $(NIX_EXEC) build .#$(NIX_CONFIG_TYPE)."$(NIX_USERNAME)@$(NIX_SYSTEM)".activationPackage $(NIX_FLAGS) --impure --no-update-lock-file --offline --show-trace; \ + else \ + echo "Unsupported OS $(OS) for offline build"; \ + exit 1; \ + fi + @echo "✅ Nix configuration built successfully in offline mode!" + +.PHONY: nix-switch-offline +nix-switch-offline: + @echo "🔧 Activating Nix configuration in offline mode" + @if [ "$(OS)" = "Darwin" ]; then \ + NIX_OFFLINE=1 sudo $(NIX_ALLOW_UNFREE) $(DARWIN_REBUILD) switch --flake .#galactica --impure --offline; \ + elif [ "$(NIX_CONFIG_TYPE)" = "nixosConfigurations" ]; then \ + NIX_OFFLINE=1 sudo $(NIX_ALLOW_UNFREE) $(NIX_EXEC) run $(NIX_FLAGS) --impure nixpkgs#nixos-rebuild -- switch --flake .#runner --no-update-lock-file --offline || exit 0; \ + elif [ "$(NIX_CONFIG_TYPE)" = "homeConfigurations" ]; then \ + NIX_OFFLINE=1 USER=$(NIX_USERNAME) sudo $(NIX_ALLOW_UNFREE) $(NIX_EXEC) run $(NIX_FLAGS) --impure .#$(NIX_CONFIG_TYPE)."$(NIX_USERNAME)@$(NIX_SYSTEM)".activationPackage --offline; \ + else \ + echo "Unsupported OS $(OS) for offline switch"; \ + exit 1; \ + fi + @echo "✅ Nix configuration activated successfully in offline mode!" + +nix-setup-offline: + @echo "🔧 Setting up offline environment" + @mkdir -p ~/.cache/nix + @echo "✅ Offline environment setup complete" + +##@ Offline Mode + ##@ Named Hosts Specific Targets .PHONY: switch-% diff --git a/nix-darwin/config/homebrew.nix b/nix-darwin/config/homebrew.nix index c91fb5928..880644fc1 100644 --- a/nix-darwin/config/homebrew.nix +++ b/nix-darwin/config/homebrew.nix @@ -1,7 +1,7 @@ { isRunner }: { homebrew = { - enable = !isRunner; + enable = !isRunner && (builtins.getEnv "NIX_OFFLINE" != "1"); onActivation = { autoUpdate = true; upgrade = true; From 4a227000ec03312a68be194a8adfc999794f4151 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 17:26:02 -0600 Subject: [PATCH 16/92] chore: update --- home-manager/modules/opencode/opencode.jsonc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/home-manager/modules/opencode/opencode.jsonc b/home-manager/modules/opencode/opencode.jsonc index 743d18542..65dfd0aff 100644 --- a/home-manager/modules/opencode/opencode.jsonc +++ b/home-manager/modules/opencode/opencode.jsonc @@ -24,6 +24,12 @@ "baseURL": "http://127.0.0.1:1234/v1" }, "models": { + "openai/gpt-oss-20b": { + "name": "OpenAI: gpt-oss-20b" + }, + "openai/gpt-oss-120b": { + "name": "OpenAI: gpt-oss-120b" + }, "qwen/qwen3-coder-30b": { "name": "Qwen: Qwen3 Coder 30B A3B Instruct" } From e7970b234500dc494d631f4169f5cb80db2a832c Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 17:42:20 -0600 Subject: [PATCH 17/92] chore: update --- Makefile | 21 + config/nvim/.gitignore | 1 + config/nvim/init.lua | 1197 +--------------------------------------- 3 files changed, 23 insertions(+), 1196 deletions(-) create mode 100644 config/nvim/.gitignore mode change 100644 => 120000 config/nvim/init.lua diff --git a/Makefile b/Makefile index e46fd10a9..083631d31 100644 --- a/Makefile +++ b/Makefile @@ -470,6 +470,27 @@ neovim-sync: @nvim --headless +"lua vim.pack.sync()" +qa @echo "✅ Neovim plugins synced" +##@ Neovim Local Development + +.PHONY: neovim-local-dev +neovim-local-dev: + @echo "🔧 Setting up local Neovim development environment..." + @if [ ! -d "$(HOME)/.config/nvim" ]; then \ + echo "Creating local Neovim config directory..."; \ + mkdir -p "$(HOME)/.config/nvim"; \ + fi + @if [ ! -L "$(HOME)/.config/nvim/init.lua" ]; then \ + if [ -f "$(HOME)/.config/nvim/init.lua" ]; then \ + echo "Backing up existing local config..."; \ + cp "$(HOME)/.config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua.backup.$(shell date +%s)"; \ + fi; \ + echo "Creating symlink to local Neovim config..."; \ + ln -sf "$(HOME)/.config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua"; \ + else \ + echo "Local Neovim config is already a symlink"; \ + fi + @echo "✅ Local Neovim development environment ready" + ##@ Git Submodule .PHONY: git-submodule-sync diff --git a/config/nvim/.gitignore b/config/nvim/.gitignore new file mode 100644 index 000000000..937aa8833 --- /dev/null +++ b/config/nvim/.gitignore @@ -0,0 +1 @@ +init.lua.backup.* \ No newline at end of file diff --git a/config/nvim/init.lua b/config/nvim/init.lua deleted file mode 100644 index ee0100d6b..000000000 --- a/config/nvim/init.lua +++ /dev/null @@ -1,1196 +0,0 @@ -vim.opt.compatible = false -vim.opt.termsync = true -vim.opt.hidden = true -vim.opt.updatetime = 250 -vim.opt.mouse = "" -vim.opt.inccommand = "nosplit" -vim.opt.splitbelow = true -vim.opt.splitright = true -vim.opt.wrap = false -vim.opt.textwidth = 0 -vim.opt.expandtab = true -vim.opt.smartindent = true -vim.opt.shiftwidth = 2 -vim.opt.softtabstop = 2 -vim.opt.tabstop = 2 -vim.opt.signcolumn = "yes" -vim.opt.scrolloff = 10 -vim.opt.sidescrolloff = 10 -vim.opt.number = true -vim.opt.relativenumber = true -vim.opt.smoothscroll = true -vim.opt.swapfile = false -vim.opt.backup = false -vim.opt.undofile = true -vim.opt.undodir = vim.fn.stdpath("data") .. "undodir" -vim.opt.hlsearch = false -vim.opt.ignorecase = true -vim.opt.incsearch = true -vim.opt.ruler = true -vim.opt.wildmenu = true -vim.opt.autoread = true -vim.opt.completeopt = { "menu", "menuone", "noselect" } -vim.opt.colorcolumn = "80" -vim.opt.backspace = { "indent", "eol", "start" } -vim.opt.spelllang = { "en_us" } -vim.opt.spellfile = vim.uv.os_homedir() .. "/.spell.add" -vim.opt.laststatus = 2 -vim.opt.cursorline = true -vim.opt.grepprg = "rg --vimgrep --smart-case --follow" -vim.opt.background = "dark" -vim.opt.termguicolors = true -vim.opt.shortmess:append("c") -vim.opt.timeoutlen = 300 -vim.opt.winborder = "none" - -vim.hl.priorities.semantic_tokens = 10 -vim.g.fugitive_legacy_commands = 0 - -vim.cmd([[ -inoreabbrev Goreleaser GoReleaser -inoreabbrev gorelesaer goreleaser -inoreabbrev carlos0 caarlos0 -inoreabbrev descriptoin description -inoreabbrev fucn func -inoreabbrev sicne since -inoreabbrev emtpy empty -inoreabbrev udpate update -inoreabbrev dont don't -inoreabbrev wont won't -inoreabbrev cant can't -inoreabbrev lenght length -inoreabbrev Lenght Length - -" ptbr -inoreabbrev neh né -inoreabbrev soh só -inoreabbrev nao não -inoreabbrev sao são -]]) - -vim.pack.add({ - -- UI - { src = "https://github.com/nvim-tree/nvim-web-devicons" }, - { src = "https://github.com/Mofiqul/dracula.nvim" }, - { src = "https://github.com/folke/sidekick.nvim" }, - { src = "https://github.com/nvim-tree/nvim-tree.lua" }, - { src = "https://github.com/nvim-lualine/lualine.nvim" }, - { src = "https://github.com/stevearc/dressing.nvim" }, - { src = "https://github.com/rcarriga/nvim-notify" }, - { src = "https://github.com/christoomey/vim-tmux-navigator" }, - { src = "https://github.com/asiryk/auto-hlsearch.nvim" }, - { src = "https://github.com/famiu/bufdelete.nvim" }, - { src = "https://github.com/norcalli/nvim-colorizer.lua" }, - { src = "https://github.com/lewis6991/gitsigns.nvim" }, - { src = "https://github.com/akinsho/git-conflict.nvim" }, - -- telescope - { src = "https://github.com/nvim-lua/plenary.nvim" }, - { src = "https://github.com/nvim-telescope/telescope-github.nvim" }, - { src = "https://github.com/nvim-telescope/telescope.nvim" }, - - -- CODING - { src = "https://github.com/rgroli/other.nvim" }, - { src = "https://github.com/danymat/neogen" }, - { src = "https://github.com/neovim/nvim-lspconfig" }, - { src = "https://github.com/stevearc/conform.nvim" }, - { src = "https://github.com/zbirenbaum/copilot.lua" }, - { src = "https://github.com/rafamadriz/friendly-snippets" }, - { src = "https://github.com/giuxtaposition/blink-cmp-copilot" }, - { - src = "https://github.com/saghen/blink.cmp", - version = vim.version.range("1.*"), - }, - - -- tpope gang - { src = "https://github.com/tpope/vim-fugitive" }, - { src = "https://github.com/tpope/vim-rhubarb" }, - { src = "https://github.com/tpope/vim-abolish" }, - { src = "https://github.com/tpope/vim-repeat" }, - { src = "https://github.com/tpope/vim-eunuch" }, - { src = "https://github.com/tpope/vim-sleuth" }, - { src = "https://github.com/tpope/vim-speeddating" }, - - -- treesitter and friends - { src = "https://github.com/nvim-treesitter/nvim-treesitter" }, - { src = "https://github.com/lukas-reineke/indent-blankline.nvim" }, - { src = "https://github.com/wansmer/treesj" }, - { src = "https://github.com/windwp/nvim-autopairs" }, - { src = "https://github.com/windwp/nvim-ts-autotag" }, - { src = "https://github.com/kylechui/nvim-surround" }, - { src = "https://github.com/folke/todo-comments.nvim" }, - { src = "https://github.com/nvim-treesitter/nvim-treesitter-context" }, - { src = "https://github.com/nvim-treesitter/nvim-treesitter-textobjects" }, - { src = "https://github.com/RRethy/nvim-treesitter-endwise" }, -}) - -local opts = { noremap = true, silent = true } -local keymap = vim.keymap.set - ---Remap space as leader key -keymap("", "", "", opts) -vim.g.mapleader = " " -vim.g.maplocalleader = " " - --- quicklists -keymap("n", "co", ":copen", opts) -keymap("n", "cc", ":cclose", opts) - --- write, buffer killing -keymap("n", "q", ":Bdelete", opts) -keymap("n", "bad", ":%bwipeout!:intro", opts) -keymap("n", "w", ":write", opts) - --- zz -keymap("n", "n", "nzzzv", opts) -keymap("n", "N", "Nzzzv", opts) -keymap("n", "", "zz", opts) -keymap("n", "", "zz", opts) -keymap("n", "", "zz", opts) -keymap("n", "", "zz", opts) - --- system clipboard integration -keymap({ "n", "v" }, "y", '"+y', opts) - --- copy the current file path -keymap("n", "py", ':let @" = expand("%:p")', opts) - --- delete to blackhole -keymap({ "n", "v" }, "d", '"_d', opts) - --- git -keymap("n", "gs", ":tab Git", opts) -keymap("n", "", ":tab Git mergetool", opts) -keymap("n", "gd", ":Gitsign preview_hunk_inline", opts) - --- indent -keymap("v", "<", "", ">gv", opts) - --- If I visually select words and paste from clipboard, don't replace my --- clipboard with the selected word, instead keep my old word in the --- clipboard -keymap("v", "p", '"_dP', opts) - --- Move text up and down -keymap("x", "K", ":move '<-2gv-gv", opts) -keymap("x", "J", ":move '>+1gv-gv", opts) - --- in insert mode, adds new undo points after more some chars: -for _, lhs in ipairs({ "-", "_", ",", ".", ";", ":", "/", "!", "?" }) do - keymap("i", lhs, lhs .. "u", opts) -end - ---- ---- UI ---- - -local bg0 = "#1b1b1b" -vim.cmd("colorscheme dracula") -vim.api.nvim_set_hl(0, "StatusLine", { reverse = false }) -vim.api.nvim_set_hl(0, "StatusLineNC", { reverse = false }) - -require("dressing").setup({ input = { insert_only = true } }) - -local notify = require("notify") -notify.setup({ - render = "compact", - stages = "static", -}) -vim.notify = notify - -local section_b = { "branch", "diff", { "diagnostics", sources = { "nvim_workspace_diagnostic" } } } -local section_c = { "%=", { "filename", file_status = false, path = 1 } } -require("lualine").setup({ - options = { - theme = "dracula", - component_separators = "", - section_separators = "", - }, - sections = { - lualine_b = section_b, - lualine_c = section_c, - }, - inactive_sections = { - lualine_c = section_c, - lualine_x = { "location" }, - }, -}) - -require("auto-hlsearch").setup({}) -require("gitsigns").setup({}) -require("git-conflict").setup({}) - --- setup diagnostics -vim.diagnostic.config({ - underline = true, - update_in_insert = false, - severity_sort = true, -}) - -keymap("n", "xx", vim.diagnostic.setqflist, opts) - --- set up diagnostic signs -local severity = vim.diagnostic.severity -local signs = { - [severity.ERROR] = "", - [severity.WARN] = "", - [severity.INFO] = "", - [severity.HINT] = "󰌶", -} -vim.diagnostic.config({ - signs = { - text = signs, - }, -}) - -require("other-nvim").setup({ mappings = { "golang" } }) -keymap("n", "oo", ":Other", opts) -keymap("n", "ov", ":OtherVSplit", opts) -keymap("n", "os", ":OtherSplit", opts) - -require("neogen").setup({ snippet_engine = "nvim" }) -keymap("n", "gco", ":Neogen", opts) - -require("conform").setup({ - formatters_by_ft = { - css = { "prettier" }, - fish = { "fish_indent" }, - html = { "prettier" }, - javascript = { "prettier" }, - json = { "jq" }, - lua = { "stylua" }, - markdown = { "prettier" }, - sh = { "shfmt" }, - sql = { "pg_format", "sql_formatter" }, - templ = { "templ" }, - tf = { "terraform_fmt" }, - yaml = { "prettier" }, - ["_"] = { "trim_whitespace", "trim_newlines" }, - -- let only the lsp take care of these. - go = {}, - rust = {}, - zig = {}, - }, - format_after_save = { - lsp_fallback = true, - }, -}) - -require("copilot").setup({ - suggestion = { enabled = false }, - panel = { enabled = false }, -}) - ----@module 'blink.cmp' ----@type blink.cmp.Config -require("blink.cmp").setup({ - keymap = { preset = "default" }, - appearance = { - nerd_font_variant = "mono", - kind_icons = { - Array = "", - Boolean = "", - Class = "", - Color = "", - Constant = "", - Constructor = "", - Copilot = "", - Enum = "", - EnumMember = "", - Event = "", - Field = "", - File = "", - Folder = "󰉋", - Function = "", - Interface = "", - Key = "", - Keyword = "", - Method = "", - Module = "", - Namespace = "", - Null = "󰟢", - Number = "", - Object = "", - Operator = "", - Package = "", - Property = "", - Reference = "", - Snippet = "", - String = "", - Struct = "", - Text = "", - TypeParameter = "", - Unit = "", - Value = "", - Variable = "", - }, - }, - signature = { enabled = true }, - cmdline = { - enabled = true, - sources = function() - local type = vim.fn.getcmdtype() - if type == "/" or type == "?" then - return { "buffer" } - end - if type == ":" then - return { "cmdline" } - end - return {} - end, - completion = { - menu = { - draw = { - columns = { - { "kind_icon", "label", gap = 1 }, - { "kind" }, - }, - }, - }, - }, - }, - sources = { - default = { "lsp", "path", "snippets", "buffer", "copilot" }, - providers = { - lsp = { - min_keyword_length = 0, - score_offset = 0, - }, - path = { - min_keyword_length = 0, - }, - snippets = { - min_keyword_length = 2, - }, - buffer = { - min_keyword_length = 5, - max_items = 5, - }, - copilot = { - name = "copilot", - module = "blink-cmp-copilot", - score_offset = -10000, - min_keyword_length = 0, - async = true, - override = { - -- copilot complete on space, new line, etc as well... - get_trigger_characters = function(self) - local trigger_characters = self:get_trigger_characters() - vim.list_extend(trigger_characters, { "\n", "\t", " " }) - return trigger_characters - end, - }, - transform_items = function(_, items) - local CompletionItemKind = require("blink.cmp.types").CompletionItemKind - local kind_idx = #CompletionItemKind + 1 - CompletionItemKind[kind_idx] = "Copilot" - for _, item in ipairs(items) do - item.kind = kind_idx - end - return items - end, - }, - }, - }, - completion = { - accept = { auto_brackets = { enabled = true } }, - keyword = { - range = "full", - }, - trigger = { - show_on_insert_on_trigger_character = true, - show_on_trigger_character = true, - show_on_keyword = true, - }, - documentation = { - auto_show = true, - auto_show_delay_ms = 250, - treesitter_highlighting = false, - }, - menu = { - draw = { - columns = { - { "kind_icon", "label", gap = 1 }, - { "kind" }, - }, - }, - }, - }, -}) - -local function copen() - if vim.fn.getqflist({ size = 0 }).size > 1 then - vim.cmd("copen") - else - vim.cmd("cclose") - end -end - -local function cclear() - vim.fn.setqflist({}, "r") -end - --- Opens the directory of the current file in Finder/file explorer. -vim.api.nvim_create_user_command("Finder", "!open %:h", {}) - -vim.api.nvim_create_autocmd({ - "BufEnter", - "CursorHold", - "CursorHoldI", - "FocusGained", -}, { - pattern = "*", - command = "if mode() != 'c' | checktime | endif", -}) - --- resize splits if window got resized -vim.api.nvim_create_autocmd({ "VimResized" }, { - callback = function() - vim.cmd("tabdo wincmd =") - end, -}) - -vim.api.nvim_create_autocmd("FileType", { - pattern = "gitcommit", - command = "startinsert", -}) - --- ensure the parent folder exists, so it gets properly added to the lsp --- context and everything just works. -vim.api.nvim_create_autocmd("BufNewFile", { - pattern = "*", - callback = function() - local dir = vim.fn.expand(":p:h") - if vim.fn.isdirectory(dir) == 0 then - vim.fn.mkdir(dir, "p") - vim.cmd([[ :e % ]]) - end - end, -}) - --- Highlight on yank --- See `:help vim.highlight.on_yank()` -vim.api.nvim_create_autocmd("TextYankPost", { - pattern = "*", - callback = function() - vim.hl.on_yank() - end, -}) - --- Open help window in a vertical split to the right. -vim.api.nvim_create_autocmd("BufWinEnter", { - pattern = { "*.txt" }, - callback = function() - if vim.o.filetype == "help" then - vim.cmd.wincmd("L") - end - end, -}) - -vim.api.nvim_create_autocmd("FileType", { - pattern = "git", - callback = function() - local bufnr = vim.api.nvim_get_current_buf() - local buf_opts = { noremap = true, silent = true, buffer = bufnr } - keymap("n", "gq", ":silent! close", buf_opts) - end, -}) - -vim.api.nvim_create_autocmd("FileType", { - pattern = "fugitive", - callback = function() - local bufnr = vim.api.nvim_get_current_buf() - - local function async_git(args, success_msg, error_msg) - vim.system({ "git", unpack(args) }, {}, function(obj) - vim.schedule(function() - if obj.code == 0 then - vim.notify(success_msg, vim.log.levels.INFO) - else - vim.notify(error_msg, vim.log.levels.ERROR) - end - end) - end) - end - - vim.cmd("normal )k=") - - local buf_opts = { noremap = true, silent = true, buffer = bufnr } - keymap("n", "gp", function() - async_git({ "push", "--quiet" }, "Pushed!", "Push failed!") - vim.cmd("silent! close") - end, buf_opts) - - keymap("n", "gP", function() - async_git({ "pull", "--rebase" }, "Pulled!", "Pull failed!") - vim.cmd("silent! close") - end, buf_opts) - - keymap("n", "go", function() - async_git({ "ppr" }, "Pushed and opened PR URL!", "Failed to push or open PR") - vim.cmd("silent! close") - end, buf_opts) - - keymap("n", "cc", ":silent! Git commit -s", buf_opts) - keymap("n", "gq", ":silent! close", buf_opts) - end, -}) - -vim.api.nvim_create_autocmd("FileType", { - pattern = "gitcommit", - callback = function() - vim.opt_local.spell = true - vim.opt_local.textwidth = 72 - end, -}) - -vim.api.nvim_create_autocmd("FileType", { - pattern = { "qf", "help" }, - callback = function() - keymap("n", "q", ":bdelete", { - buffer = vim.api.nvim_get_current_buf(), - noremap = true, - silent = true, - }) - end, -}) - -local get_gopls = function(bufnr) - local clients = vim.lsp.get_clients({ bufnr = bufnr }) - for _, c in ipairs(clients) do - if c.name == "gopls" then - return c - end - end - return nil -end - -vim.api.nvim_create_autocmd("FileType", { - pattern = "go", - callback = function() - local bufnr = vim.api.nvim_get_current_buf() - - vim.opt_local.formatoptions:append("jo") - vim.opt_local.makeprg = "go build ./..." - vim.opt_local.errorformat = "%A%f:%l:%c: %m,%-G%.%#" - - vim.api.nvim_buf_create_user_command(bufnr, "GoModTidy", function() - local gopls = get_gopls(bufnr) - if gopls == nil then - return - end - - vim.cmd([[ noautocmd wall ]]) - - local uri = vim.uri_from_bufnr(bufnr) - local arguments = { { URIs = { uri } } } - - local err = gopls:request_sync("workspace/executeCommand", { - command = "gopls.tidy", - arguments = arguments, - }, 30000, bufnr) - - if err ~= nil and type(err[1]) == "table" then - vim.notify("go mod tidy: " .. vim.inspect(err), vim.log.levels.ERROR) - return - end - end, { desc = "go mod tidy" }) - - local buf_opts = { noremap = true, silent = true, buffer = bufnr } - keymap("n", "", vim.cmd.GoModTidy, buf_opts) - keymap("n", "", function() - cclear() - vim.fn.jobstart("golangci-lint run --max-issues-per-linter=0 --max-same-issues=0 --new", { - stdout_buffered = true, - on_stdout = function(_, data) - if data and #data > 1 then - vim.schedule(function() - vim.fn.setqflist({}, " ", { lines = data }) - copen() - end) - end - end, - }) - end, buf_opts) - end, -}) - -vim.api.nvim_create_autocmd("FileType", { - pattern = "markdown", - callback = function() - vim.opt_local.spell = true - vim.opt_local.textwidth = 80 - vim.opt_local.formatoptions:remove("ct") - end, -}) - --- syntax, indentation, treesitter, etc. -require("ibl").setup({ - indent = { char = "│" }, - exclude = { filetypes = { "help" } }, - scope = { enabled = false }, -}) - -require("nvim-autopairs").setup({ - check_ts = true, -}) - -require("nvim-ts-autotag").setup() -require("nvim-surround").setup() -require("todo-comments").setup() - -require("treesitter-context").setup({ - multiline_threshold = 1, -}) - ----@diagnostic disable-next-line: missing-fields -require("nvim-treesitter.configs").setup({ - ensure_installed = { - "arduino", - "awk", - "bash", - "cpp", - "css", - "csv", - "diff", - "dockerfile", - "fish", - "git_config", - "git_rebase", - "gitattributes", - "gitcommit", - "gitignore", - "go", - "gomod", - "gosum", - "gowork", - "graphql", - "hcl", - "html", - "http", - "http", - "ini", - "javascript", - "jq", - "json", - "lua", - "make", - "markdown", - "markdown_inline", - "mermaid", - "python", - "query", - "regex", - "ruby", - "scss", - "sql", - "ssh_config", - "templ", - "terraform", - "toml", - "vhs", - "vim", - "vimdoc", - "yaml", - "zig", - }, - highlight = { - enable = true, - }, - indent = { - enable = true, - }, - endwise = { - enable = true, - }, - autopairs = { - enable = true, - }, - context_commentstring = { - enable = true, - enable_autocmd = false, - }, - incremental_selection = { - enable = true, - keymaps = { - init_selection = "", - node_incremental = "", - node_decremental = "", - scope_incremental = "", - }, - }, - auto_install = true, - textobjects = { - enable = true, - lookahead = true, - swap = { - enable = true, - swap_next = { - ["a"] = "@parameter.inner", - }, - swap_previous = { - ["A"] = "@parameter.inner", - }, - }, - move = { - enable = true, - set_jumps = true, - goto_next_start = { - ["]f"] = "@function.inner", - ["]c"] = "@class.inner", - ["]a"] = "@parameter.inner", - }, - goto_next_end = { - ["]F"] = "@function.inner", - ["]C"] = "@class.inner", - ["]A"] = "@parameter.inner", - }, - goto_previous_start = { - ["[f"] = "@function.inner", - ["[c"] = "@class.inner", - ["[a"] = "@parameter.inner", - }, - goto_previous_end = { - ["[F"] = "@function.inner", - ["[C"] = "@class.inner", - ["[A"] = "@parameter.inner", - }, - }, - select = { - enable = true, - keymaps = { - ["af"] = "@function.outer", - ["if"] = "@function.inner", - - ["ac"] = "@conditional.outer", - ["ic"] = "@conditional.inner", - - ["aa"] = "@parameter.outer", - ["ia"] = "@parameter.inner", - - ["av"] = "@variable.outer", - ["iv"] = "@variable.inner", - }, - }, - }, -}) - -local treesj = require("treesj") -treesj.setup({ use_default_keymaps = false }) -keymap("n", "st", treesj.toggle, opts) - -local telescope = require("telescope") -telescope.setup({ - defaults = { - pickers = { - find_files = { - theme = "ivy", - }, - }, - prompt_prefix = "  ", - selection_caret = " ❯ ", - entry_prefix = " ", - multi_icon = "+ ", - path_display = { "filename_first" }, - vimgrep_arguments = { - "rg", - "--color=never", - "--no-heading", - "--with-filename", - "--line-number", - "--column", - "--smart-case", - "--sort=path", - }, - }, -}) -telescope.load_extension("gh") - -local function ivy(iopts) - return require("telescope.themes").get_ivy(iopts) -end - -local builtin = require("telescope.builtin") -vim.keymap.set("n", "", function() - builtin.find_files(ivy({ - find_command = { - "fd", - "--type", - "f", - "--strip-cwd-prefix", - "--hidden", - }, - })) -end, opts) - -keymap("n", "of", function() - builtin.oldfiles(ivy({ - only_cwd = true, - })) -end, opts) - -keymap("n", "lg", function() - builtin.live_grep(ivy()) -end, opts) - -keymap("n", "fb", function() - builtin.buffers(ivy()) -end, opts) - -keymap("n", "fh", function() - builtin.help_tags(ivy()) -end, opts) - -keymap("n", "fc", function() - builtin.commands(ivy()) -end, opts) - -keymap("n", "fr", function() - builtin.resume(ivy()) -end, opts) - -keymap("n", "fq", function() - builtin.quickfix(ivy()) -end, opts) - -keymap("n", "/", function() - builtin.current_buffer_fuzzy_find(ivy()) -end, opts) - -keymap("n", "ghi", function() - telescope.extensions.gh.issues(ivy()) -end, opts) - --- LSP/autocommands inline replica of caarlos0's modules. -local function setup_lsp_autocommands() - local ms = require("vim.lsp.protocol").Methods - local group = vim.api.nvim_create_augroup("LSP", { clear = true }) - - ---@async - ---@param client vim.lsp.Client - ---@param bufnr number - local function organize_imports(client, bufnr) - ---@type lsp.Handler - ---@diagnostic disable-next-line: unused-local - local handler = function(err, result, context, config) - if err then - return - end - for _, r in pairs(result or {}) do - if r.edit then - local enc = client.offset_encoding or "utf-16" - vim.lsp.util.apply_workspace_edit(r.edit, enc) - elseif r.command and r.command.command then - client:exec_cmd(r.command, { bufnr = bufnr }) - end - end - vim.cmd([[noautocmd write]]) - end - - local win = vim.api.nvim_get_current_win() - local params = vim.lsp.util.make_range_params(win, client.offset_encoding or "utf-16") - params.context = { only = { "source.organizeImports" } } - client:request(ms.textDocument_codeAction, params, handler, bufnr) - end - - local function has_clients_with_method(bufnr, method) - local clients = vim.lsp.get_clients({ bufnr = bufnr, method = method }) - return #clients > 0 - end - - local function on_clients(bufnr, method, apply, filter) - local clients = vim.lsp.get_clients({ bufnr = bufnr, method = method }) - local predicate = filter or function() - return true - end - for _, client in ipairs(clients) do - if predicate(client) then - apply(client, bufnr) - end - end - end - - vim.api.nvim_create_autocmd("LspAttach", { - callback = function(args) - local client = vim.lsp.get_client_by_id(args.data.client_id) - if client == nil then - return - end - if client:supports_method(ms.textDocument_codeLens, vim.api.nvim_get_current_buf()) then - vim.lsp.inlay_hint.enable(true) - end - end, - }) - vim.api.nvim_create_autocmd("LspDetach", { - callback = function(args) - local client = vim.lsp.get_client_by_id(args.data.client_id) - if client == nil then - return - end - if client:supports_method(ms.textDocument_codeLens, vim.api.nvim_get_current_buf()) then - vim.lsp.codelens.clear(client.id) - end - end, - group = group, - }) - - vim.api.nvim_create_autocmd({ "BufWritePre" }, { - callback = function() - local format = function(client, bufnr) - if client.server_capabilities.documentFormattingProvider then - vim.lsp.buf.format({ - bufnr = bufnr, - timeout_ms = 5000, - id = client.id, - }) - end - end - on_clients(vim.api.nvim_get_current_buf(), ms.textDocument_codeAction, format) - end, - group = group, - }) - - vim.api.nvim_create_autocmd({ "BufWritePost" }, { - callback = function() - local bufnr = vim.api.nvim_get_current_buf() - local filter = function(client) - return client.name ~= "lua_ls" - end - on_clients(bufnr, ms.textDocument_codeAction, organize_imports, filter) - end, - group = group, - }) - - vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", "InsertLeave" }, { - callback = function() - if has_clients_with_method(0, ms.textDocument_codeLens) then - vim.lsp.codelens.refresh({ bufnr = 0 }) - end - end, - group = group, - }) - - vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { - callback = function() - if has_clients_with_method(0, ms.textDocument_documentHighlight) then - vim.lsp.buf.document_highlight() - end - end, - group = group, - }) - - vim.api.nvim_create_autocmd({ "CursorMoved" }, { - callback = function() - if has_clients_with_method(0, ms.textDocument_documentHighlight) then - vim.lsp.buf.clear_references() - end - end, - group = group, - }) -end - -setup_lsp_autocommands() - -local capabilities = require("blink.cmp").get_lsp_capabilities({ - workspace = { - didChangeWatchedFiles = { - dynamicRegistration = true, - relativePatternSupport = true, - }, - }, -}, true) - ----@param client vim.lsp.Client ----@param bufnr number -local on_attach = function(client, bufnr) - local keymap_lsp = function(lhs, rhs) - vim.keymap.set("n", lhs, rhs, { - noremap = true, - silent = true, - buffer = bufnr, - }) - end - - local telescope_wrap = function(action) - return function() - local ivy_theme = require("telescope.themes").get_ivy() - require("telescope.builtin")["lsp_" .. action](ivy_theme) - end - end - - keymap_lsp("gd", telescope_wrap("definitions")) - keymap_lsp("grr", telescope_wrap("references")) - keymap_lsp("gO", telescope_wrap("document_symbols")) - keymap_lsp("gri", telescope_wrap("implementations")) - keymap_lsp("gD", vim.lsp.buf.declaration) - keymap_lsp("K", vim.lsp.buf.hover) - keymap_lsp("D", telescope_wrap("type_definitions")) - keymap_lsp("grl", vim.lsp.codelens.run) - keymap_lsp("gl", vim.diagnostic.open_float) - keymap_lsp("[d", function() - vim.diagnostic.jump({ count = -1 }) - vim.cmd("norm zz") - end) - keymap_lsp("]d", function() - vim.diagnostic.jump({ count = 1 }) - vim.cmd("norm zz") - end) - - keymap_lsp("v", function() - vim.cmd("vsplit | lua vim.lsp.buf.definition()") - vim.cmd("norm zz") - end) -end - -local lspconfig = require("lspconfig") -require("lspconfig.ui.windows").default_options.border = "none" -lspconfig.gopls.setup({ - capabilities = capabilities, - on_attach = on_attach, - settings = { - gopls = { - gofumpt = true, - codelenses = { - gc_details = true, - generate = true, - run_govulncheck = true, - test = true, - tidy = true, - upgrade_dependency = true, - }, - hints = { - assignVariableTypes = true, - compositeLiteralFields = true, - compositeLiteralTypes = true, - constantValues = true, - functionTypeParameters = true, - parameterNames = true, - rangeVariableTypes = true, - }, - analyses = { - nilness = true, - unusedparams = true, - unusedvariable = true, - unusedwrite = true, - useany = true, - }, - staticcheck = true, - directoryFilters = { "-.git", "-node_modules" }, - semanticTokens = true, - }, - }, - flags = { - debounce_text_changes = 150, - }, -}) - -lspconfig.ts_ls.setup({ - capabilities = capabilities, - on_attach = on_attach, - settings = { - javascript = { - inlayHints = { - includeInlayEnumMemberValueHints = true, - includeInlayFunctionLikeReturnTypeHints = true, - includeInlayFunctionParameterTypeHints = true, - includeInlayParameterNameHints = "all", - includeInlayParameterNameHintsWhenArgumentMatchesName = true, - includeInlayPropertyDeclarationTypeHints = true, - includeInlayVariableTypeHints = true, - }, - }, - typescript = { - inlayHints = { - includeInlayEnumMemberValueHints = true, - includeInlayFunctionLikeReturnTypeHints = true, - includeInlayFunctionParameterTypeHints = true, - includeInlayParameterNameHints = "all", - includeInlayParameterNameHintsWhenArgumentMatchesName = true, - includeInlayPropertyDeclarationTypeHints = true, - includeInlayVariableTypeHints = true, - }, - }, - }, -}) - -for _, lsp in ipairs({ - "bashls", - "clangd", - "cssls", - "jsonls", - "pylsp", - "rust_analyzer", - "taplo", - "templ", - "terraformls", - "tflint", - "zls", -}) do - lspconfig[lsp].setup({ - on_attach = on_attach, - capabilities = capabilities, - }) -end - -for _, lsp in ipairs({ "html", "htmx" }) do - lspconfig[lsp].setup({ - capabilities = capabilities, - on_attach = on_attach, - filetypes = { "html", "templ" }, - }) -end - -lspconfig.tailwindcss.setup({ - on_attach = on_attach, - capabilities = capabilities, - filetypes = { "html", "templ", "javascript" }, - settings = { - tailwindCSS = { - includeLanguages = { - templ = "html", - }, - }, - }, -}) - -lspconfig.yamlls.setup({ - capabilities = capabilities, - on_attach = on_attach, - settings = { - yaml = { - schemaStore = { - url = "https://www.schemastore.org/api/json/catalog.json", - enable = true, - }, - }, - }, -}) - -local runtime_path = vim.split(package.path, ";", {}) -table.insert(runtime_path, "lua/?.lua") -table.insert(runtime_path, "lua/?/init.lua") -lspconfig.lua_ls.setup({ - capabilities = capabilities, - on_attach = on_attach, - settings = { - Lua = { - completion = { - callSnippet = "Replace", - }, - telemetry = { enable = false }, - hint = { - enable = true, - }, - workspace = { - library = vim.api.nvim_get_runtime_file("", true), - }, - }, - }, -}) - -require("nvim-tree").setup({ - view = { - width = 30, - }, -}) -keymap("n", "", ":NvimTreeToggle", opts) diff --git a/config/nvim/init.lua b/config/nvim/init.lua new file mode 120000 index 000000000..90cd9de9d --- /dev/null +++ b/config/nvim/init.lua @@ -0,0 +1 @@ +/Users/shunkakinoki/.config/nvim/init.lua \ No newline at end of file From 2e9ddd331b039bfe233d7929f4fc74e4e0ae8b63 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 17:46:10 -0600 Subject: [PATCH 18/92] chore: update --- nix-darwin/config/homebrew.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix-darwin/config/homebrew.nix b/nix-darwin/config/homebrew.nix index 880644fc1..89a3e53a8 100644 --- a/nix-darwin/config/homebrew.nix +++ b/nix-darwin/config/homebrew.nix @@ -1,7 +1,7 @@ { isRunner }: { homebrew = { - enable = !isRunner && (builtins.getEnv "NIX_OFFLINE" != "1"); + enable = !isRunner || (builtins.getEnv "NIX_OFFLINE" != "1"); onActivation = { autoUpdate = true; upgrade = true; From 1644066404b6b5f0dc24d0892ede1e8e83f0b521 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 18:04:42 -0600 Subject: [PATCH 19/92] chore: update --- nix-darwin/config/homebrew.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nix-darwin/config/homebrew.nix b/nix-darwin/config/homebrew.nix index 89a3e53a8..7df6ba63a 100644 --- a/nix-darwin/config/homebrew.nix +++ b/nix-darwin/config/homebrew.nix @@ -3,8 +3,8 @@ homebrew = { enable = !isRunner || (builtins.getEnv "NIX_OFFLINE" != "1"); onActivation = { - autoUpdate = true; - upgrade = true; + autoUpdate = builtins.getEnv "NIX_OFFLINE" != "1"; + upgrade = builtins.getEnv "NIX_OFFLINE" != "1"; cleanup = "zap"; extraFlags = [ "--force" ]; }; From c927e12b01cc600e5adc4be3b939c0eb2746b409 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 18:06:42 -0600 Subject: [PATCH 20/92] chore: update From a4c9ea77352e500a83e69f0e6cd8cc100dfa80b0 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 18:06:52 -0600 Subject: [PATCH 21/92] chore: update --- nix-darwin/config/system.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix-darwin/config/system.nix b/nix-darwin/config/system.nix index 57e4b2b11..cb0d1d86f 100644 --- a/nix-darwin/config/system.nix +++ b/nix-darwin/config/system.nix @@ -62,7 +62,7 @@ }; }; activationScripts.extraActivation.text = builtins.toString ( - if !isRunner then + if !isRunner || (builtins.getEnv "NIX_OFFLINE" != "1") then '' softwareupdate --all --install; '' From 06eb162975c673a2733b019fc94e48e5617a5dba Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 18:08:13 -0600 Subject: [PATCH 22/92] chore: update --- nix-darwin/config/homebrew.nix | 2 +- nix-darwin/config/system.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nix-darwin/config/homebrew.nix b/nix-darwin/config/homebrew.nix index 7df6ba63a..f22b1989e 100644 --- a/nix-darwin/config/homebrew.nix +++ b/nix-darwin/config/homebrew.nix @@ -1,7 +1,7 @@ { isRunner }: { homebrew = { - enable = !isRunner || (builtins.getEnv "NIX_OFFLINE" != "1"); + enable = !isRunner && (builtins.getEnv "NIX_OFFLINE" != "1"); onActivation = { autoUpdate = builtins.getEnv "NIX_OFFLINE" != "1"; upgrade = builtins.getEnv "NIX_OFFLINE" != "1"; diff --git a/nix-darwin/config/system.nix b/nix-darwin/config/system.nix index cb0d1d86f..aeaecf6cd 100644 --- a/nix-darwin/config/system.nix +++ b/nix-darwin/config/system.nix @@ -62,7 +62,7 @@ }; }; activationScripts.extraActivation.text = builtins.toString ( - if !isRunner || (builtins.getEnv "NIX_OFFLINE" != "1") then + if !isRunner && (builtins.getEnv "NIX_OFFLINE" != "1") then '' softwareupdate --all --install; '' From 639298dedbceab4cd5ad64a5de5b58849c8a910e Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 18:25:07 -0600 Subject: [PATCH 23/92] chore: update From fa426ec80cc3696cdb5cd700627b9427b3f93870 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 18:25:11 -0600 Subject: [PATCH 24/92] chore: update --- config/nvim/init.lua | 1175 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1174 insertions(+), 1 deletion(-) mode change 120000 => 100644 config/nvim/init.lua diff --git a/config/nvim/init.lua b/config/nvim/init.lua deleted file mode 120000 index 90cd9de9d..000000000 --- a/config/nvim/init.lua +++ /dev/null @@ -1 +0,0 @@ -/Users/shunkakinoki/.config/nvim/init.lua \ No newline at end of file diff --git a/config/nvim/init.lua b/config/nvim/init.lua new file mode 100644 index 000000000..aad839cd0 --- /dev/null +++ b/config/nvim/init.lua @@ -0,0 +1,1174 @@ +vim.opt.compatible = false +vim.opt.termsync = true +vim.opt.hidden = true +vim.opt.updatetime = 250 +vim.opt.mouse = "" +vim.opt.inccommand = "nosplit" +vim.opt.splitbelow = true +vim.opt.splitright = true +vim.opt.wrap = false +vim.opt.textwidth = 0 +vim.opt.expandtab = true +vim.opt.smartindent = true +vim.opt.shiftwidth = 2 +vim.opt.softtabstop = 2 +vim.opt.tabstop = 2 +vim.opt.signcolumn = "yes" +vim.opt.scrolloff = 10 +vim.opt.sidescrolloff = 10 +vim.opt.number = true +vim.opt.relativenumber = true +vim.opt.smoothscroll = true +vim.opt.swapfile = false +vim.opt.backup = false +vim.opt.undofile = true +vim.opt.undodir = vim.fn.stdpath("data") .. "undodir" +vim.opt.hlsearch = false +vim.opt.ignorecase = true +vim.opt.incsearch = true +vim.opt.ruler = true +vim.opt.wildmenu = true +vim.opt.autoread = true +vim.opt.completeopt = { "menu", "menuone", "noselect" } +vim.opt.colorcolumn = "80" +vim.opt.backspace = { "indent", "eol", "start" } +vim.opt.spelllang = { "en_us" } +vim.opt.spellfile = vim.uv.os_homedir() .. "/.spell.add" +vim.opt.laststatus = 2 +vim.opt.cursorline = true +vim.opt.grepprg = "rg --vimgrep --smart-case --follow" +vim.opt.background = "dark" +vim.opt.termguicolors = true +vim.opt.shortmess:append("c") +vim.opt.timeoutlen = 300 +vim.opt.winborder = "none" + +vim.hl.priorities.semantic_tokens = 10 +vim.g.fugitive_legacy_commands = 0 + +vim.pack.add({ + -- UI + { src = "https://github.com/nvim-tree/nvim-web-devicons" }, + { src = "https://github.com/Mofiqul/dracula.nvim" }, + { src = "https://github.com/folke/sidekick.nvim" }, + { src = "https://github.com/nvim-tree/nvim-tree.lua" }, + { src = "https://github.com/nvim-lualine/lualine.nvim" }, + { src = "https://github.com/stevearc/dressing.nvim" }, + { src = "https://github.com/rcarriga/nvim-notify" }, + { src = "https://github.com/christoomey/vim-tmux-navigator" }, + { src = "https://github.com/asiryk/auto-hlsearch.nvim" }, + { src = "https://github.com/famiu/bufdelete.nvim" }, + { src = "https://github.com/norcalli/nvim-colorizer.lua" }, + { src = "https://github.com/lewis6991/gitsigns.nvim" }, + { src = "https://github.com/akinsho/git-conflict.nvim" }, + -- telescope + { src = "https://github.com/nvim-lua/plenary.nvim" }, + { src = "https://github.com/nvim-telescope/telescope-github.nvim" }, + { src = "https://github.com/nvim-telescope/telescope.nvim" }, + + -- CODING + { src = "https://github.com/rgroli/other.nvim" }, + { src = "https://github.com/danymat/neogen" }, + { src = "https://github.com/neovim/nvim-lspconfig" }, + { src = "https://github.com/stevearc/conform.nvim" }, + { src = "https://github.com/zbirenbaum/copilot.lua" }, + { src = "https://github.com/rafamadriz/friendly-snippets" }, + { src = "https://github.com/giuxtaposition/blink-cmp-copilot" }, + { + src = "https://github.com/saghen/blink.cmp", + version = vim.version.range("1.*"), + }, + + -- tpope gang + { src = "https://github.com/tpope/vim-fugitive" }, + { src = "https://github.com/tpope/vim-rhubarb" }, + { src = "https://github.com/tpope/vim-abolish" }, + { src = "https://github.com/tpope/vim-repeat" }, + { src = "https://github.com/tpope/vim-eunuch" }, + { src = "https://github.com/tpope/vim-sleuth" }, + { src = "https://github.com/tpope/vim-speeddating" }, + + -- treesitter and friends + { src = "https://github.com/nvim-treesitter/nvim-treesitter" }, + { src = "https://github.com/lukas-reineke/indent-blankline.nvim" }, + { src = "https://github.com/wansmer/treesj" }, + { src = "https://github.com/windwp/nvim-autopairs" }, + { src = "https://github.com/windwp/nvim-ts-autotag" }, + { src = "https://github.com/kylechui/nvim-surround" }, + { src = "https://github.com/folke/todo-comments.nvim" }, + { src = "https://github.com/nvim-treesitter/nvim-treesitter-context" }, + { src = "https://github.com/nvim-treesitter/nvim-treesitter-textobjects" }, + { src = "https://github.com/RRethy/nvim-treesitter-endwise" }, +}) + +local opts = { noremap = true, silent = true } +local keymap = vim.keymap.set + +--Remap space as leader key +keymap("", "", "", opts) +vim.g.mapleader = " " +vim.g.maplocalleader = " " + +-- quicklists +keymap("n", "co", ":copen", opts) +keymap("n", "cc", ":cclose", opts) + +-- write, buffer killing +keymap("n", "q", ":Bdelete", opts) +keymap("n", "bad", ":%bwipeout!:intro", opts) +keymap("n", "w", ":write", opts) + +-- zz +keymap("n", "n", "nzzzv", opts) +keymap("n", "N", "Nzzzv", opts) +keymap("n", "", "zz", opts) +keymap("n", "", "zz", opts) +keymap("n", "", "zz", opts) +keymap("n", "", "zz", opts) + +-- system clipboard integration +keymap({ "n", "v" }, "y", '"+y', opts) + +-- copy the current file path +keymap("n", "py", ':let @" = expand("%:p")', opts) + +-- delete to blackhole +keymap({ "n", "v" }, "d", '"_d', opts) + +-- git +keymap("n", "gs", ":tab Git", opts) +keymap("n", "", ":tab Git mergetool", opts) +keymap("n", "gd", ":Gitsign preview_hunk_inline", opts) + +-- indent +keymap("v", "<", "", ">gv", opts) + +-- If I visually select words and paste from clipboard, don't replace my +-- clipboard with the selected word, instead keep my old word in the +-- clipboard +keymap("v", "p", '"_dP', opts) + +-- Move text up and down +keymap("x", "K", ":move '<-2gv-gv", opts) +keymap("x", "J", ":move '>+1gv-gv", opts) + +-- in insert mode, adds new undo points after more some chars: +for _, lhs in ipairs({ "-", "_", ",", ".", ";", ":", "/", "!", "?" }) do + keymap("i", lhs, lhs .. "u", opts) +end + +--- +--- UI +--- + +local bg0 = "#1b1b1b" +vim.cmd("colorscheme dracula") +vim.api.nvim_set_hl(0, "StatusLine", { reverse = false }) +vim.api.nvim_set_hl(0, "StatusLineNC", { reverse = false }) + +require("dressing").setup({ input = { insert_only = true } }) + +local notify = require("notify") +notify.setup({ + render = "compact", + stages = "static", +}) +vim.notify = notify + +local section_b = { "branch", "diff", { "diagnostics", sources = { "nvim_workspace_diagnostic" } } } +local section_c = { "%=", { "filename", file_status = false, path = 1 } } +require("lualine").setup({ + options = { + theme = "dracula", + component_separators = "", + section_separators = "", + }, + sections = { + lualine_b = section_b, + lualine_c = section_c, + }, + inactive_sections = { + lualine_c = section_c, + lualine_x = { "location" }, + }, +}) + +require("auto-hlsearch").setup({}) +require("gitsigns").setup({}) +require("git-conflict").setup({}) + +-- setup diagnostics +vim.diagnostic.config({ + underline = true, + update_in_insert = false, + severity_sort = true, +}) + +keymap("n", "xx", vim.diagnostic.setqflist, opts) + +-- set up diagnostic signs +local severity = vim.diagnostic.severity +local signs = { + [severity.ERROR] = "", + [severity.WARN] = "", + [severity.INFO] = "", + [severity.HINT] = "󰌶", +} +vim.diagnostic.config({ + signs = { + text = signs, + }, +}) + +require("other-nvim").setup({ mappings = { "golang" } }) +keymap("n", "oo", ":Other", opts) +keymap("n", "ov", ":OtherVSplit", opts) +keymap("n", "os", ":OtherSplit", opts) + +require("neogen").setup({ snippet_engine = "nvim" }) +keymap("n", "gco", ":Neogen", opts) + +require("conform").setup({ + formatters_by_ft = { + css = { "prettier" }, + fish = { "fish_indent" }, + html = { "prettier" }, + javascript = { "prettier" }, + json = { "jq" }, + lua = { "stylua" }, + markdown = { "prettier" }, + sh = { "shfmt" }, + sql = { "pg_format", "sql_formatter" }, + templ = { "templ" }, + tf = { "terraform_fmt" }, + yaml = { "prettier" }, + ["_"] = { "trim_whitespace", "trim_newlines" }, + -- let only the lsp take care of these. + go = {}, + rust = {}, + zig = {}, + }, + format_after_save = { + lsp_fallback = true, + }, +}) + +require("copilot").setup({ + suggestion = { enabled = false }, + panel = { enabled = false }, +}) + +---@module 'blink.cmp' +---@type blink.cmp.Config +require("blink.cmp").setup({ + keymap = { preset = "default" }, + appearance = { + nerd_font_variant = "mono", + kind_icons = { + Array = "", + Boolean = "", + Class = "", + Color = "", + Constant = "", + Constructor = "", + Copilot = "", + Enum = "", + EnumMember = "", + Event = "", + Field = "", + File = "", + Folder = "󰉋", + Function = "", + Interface = "", + Key = "", + Keyword = "", + Method = "", + Module = "", + Namespace = "", + Null = "󰟢", + Number = "", + Object = "", + Operator = "", + Package = "", + Property = "", + Reference = "", + Snippet = "", + String = "", + Struct = "", + Text = "", + TypeParameter = "", + Unit = "", + Value = "", + Variable = "", + }, + }, + signature = { enabled = true }, + cmdline = { + enabled = true, + sources = function() + local type = vim.fn.getcmdtype() + if type == "/" or type == "?" then + return { "buffer" } + end + if type == ":" then + return { "cmdline" } + end + return {} + end, + completion = { + menu = { + draw = { + columns = { + { "kind_icon", "label", gap = 1 }, + { "kind" }, + }, + }, + }, + }, + }, + sources = { + default = { "lsp", "path", "snippets", "buffer", "copilot" }, + providers = { + lsp = { + min_keyword_length = 0, + score_offset = 0, + }, + path = { + min_keyword_length = 0, + }, + snippets = { + min_keyword_length = 2, + }, + buffer = { + min_keyword_length = 5, + max_items = 5, + }, + copilot = { + name = "copilot", + module = "blink-cmp-copilot", + score_offset = -10000, + min_keyword_length = 0, + async = true, + override = { + -- copilot complete on space, new line, etc as well... + get_trigger_characters = function(self) + local trigger_characters = self:get_trigger_characters() + vim.list_extend(trigger_characters, { "\n", "\t", " " }) + return trigger_characters + end, + }, + transform_items = function(_, items) + local CompletionItemKind = require("blink.cmp.types").CompletionItemKind + local kind_idx = #CompletionItemKind + 1 + CompletionItemKind[kind_idx] = "Copilot" + for _, item in ipairs(items) do + item.kind = kind_idx + end + return items + end, + }, + }, + }, + completion = { + accept = { auto_brackets = { enabled = true } }, + keyword = { + range = "full", + }, + trigger = { + show_on_insert_on_trigger_character = true, + show_on_trigger_character = true, + show_on_keyword = true, + }, + documentation = { + auto_show = true, + auto_show_delay_ms = 250, + treesitter_highlighting = false, + }, + menu = { + draw = { + columns = { + { "kind_icon", "label", gap = 1 }, + { "kind" }, + }, + }, + }, + }, +}) + +local function copen() + if vim.fn.getqflist({ size = 0 }).size > 1 then + vim.cmd("copen") + else + vim.cmd("cclose") + end +end + +local function cclear() + vim.fn.setqflist({}, "r") +end + +-- Opens the directory of the current file in Finder/file explorer. +vim.api.nvim_create_user_command("Finder", "!open %:h", {}) + +vim.api.nvim_create_autocmd({ + "BufEnter", + "CursorHold", + "CursorHoldI", + "FocusGained", +}, { + pattern = "*", + command = "if mode() != 'c' | checktime | endif", +}) + +-- resize splits if window got resized +vim.api.nvim_create_autocmd({ "VimResized" }, { + callback = function() + vim.cmd("tabdo wincmd =") + end, +}) + +vim.api.nvim_create_autocmd("FileType", { + pattern = "gitcommit", + command = "startinsert", +}) + +-- ensure the parent folder exists, so it gets properly added to the lsp +-- context and everything just works. +vim.api.nvim_create_autocmd("BufNewFile", { + pattern = "*", + callback = function() + local dir = vim.fn.expand(":p:h") + if vim.fn.isdirectory(dir) == 0 then + vim.fn.mkdir(dir, "p") + vim.cmd([[ :e % ]]) + end + end, +}) + +-- Highlight on yank +-- See `:help vim.highlight.on_yank()` +vim.api.nvim_create_autocmd("TextYankPost", { + pattern = "*", + callback = function() + vim.hl.on_yank() + end, +}) + +-- Open help window in a vertical split to the right. +vim.api.nvim_create_autocmd("BufWinEnter", { + pattern = { "*.txt" }, + callback = function() + if vim.o.filetype == "help" then + vim.cmd.wincmd("L") + end + end, +}) + +vim.api.nvim_create_autocmd("FileType", { + pattern = "git", + callback = function() + local bufnr = vim.api.nvim_get_current_buf() + local buf_opts = { noremap = true, silent = true, buffer = bufnr } + keymap("n", "gq", ":silent! close", buf_opts) + end, +}) + +vim.api.nvim_create_autocmd("FileType", { + pattern = "fugitive", + callback = function() + local bufnr = vim.api.nvim_get_current_buf() + + local function async_git(args, success_msg, error_msg) + vim.system({ "git", unpack(args) }, {}, function(obj) + vim.schedule(function() + if obj.code == 0 then + vim.notify(success_msg, vim.log.levels.INFO) + else + vim.notify(error_msg, vim.log.levels.ERROR) + end + end) + end) + end + + vim.cmd("normal )k=") + + local buf_opts = { noremap = true, silent = true, buffer = bufnr } + keymap("n", "gp", function() + async_git({ "push", "--quiet" }, "Pushed!", "Push failed!") + vim.cmd("silent! close") + end, buf_opts) + + keymap("n", "gP", function() + async_git({ "pull", "--rebase" }, "Pulled!", "Pull failed!") + vim.cmd("silent! close") + end, buf_opts) + + keymap("n", "go", function() + async_git({ "ppr" }, "Pushed and opened PR URL!", "Failed to push or open PR") + vim.cmd("silent! close") + end, buf_opts) + + keymap("n", "cc", ":silent! Git commit -s", buf_opts) + keymap("n", "gq", ":silent! close", buf_opts) + end, +}) + +vim.api.nvim_create_autocmd("FileType", { + pattern = "gitcommit", + callback = function() + vim.opt_local.spell = true + vim.opt_local.textwidth = 72 + end, +}) + +vim.api.nvim_create_autocmd("FileType", { + pattern = { "qf", "help" }, + callback = function() + keymap("n", "q", ":bdelete", { + buffer = vim.api.nvim_get_current_buf(), + noremap = true, + silent = true, + }) + end, +}) + +local get_gopls = function(bufnr) + local clients = vim.lsp.get_clients({ bufnr = bufnr }) + for _, c in ipairs(clients) do + if c.name == "gopls" then + return c + end + end + return nil +end + +vim.api.nvim_create_autocmd("FileType", { + pattern = "go", + callback = function() + local bufnr = vim.api.nvim_get_current_buf() + + vim.opt_local.formatoptions:append("jo") + vim.opt_local.makeprg = "go build ./..." + vim.opt_local.errorformat = "%A%f:%l:%c: %m,%-G%.%#" + + vim.api.nvim_buf_create_user_command(bufnr, "GoModTidy", function() + local gopls = get_gopls(bufnr) + if gopls == nil then + return + end + + vim.cmd([[ noautocmd wall ]]) + + local uri = vim.uri_from_bufnr(bufnr) + local arguments = { { URIs = { uri } } } + + local err = gopls:request_sync("workspace/executeCommand", { + command = "gopls.tidy", + arguments = arguments, + }, 30000, bufnr) + + if err ~= nil and type(err[1]) == "table" then + vim.notify("go mod tidy: " .. vim.inspect(err), vim.log.levels.ERROR) + return + end + end, { desc = "go mod tidy" }) + + local buf_opts = { noremap = true, silent = true, buffer = bufnr } + keymap("n", "", vim.cmd.GoModTidy, buf_opts) + keymap("n", "", function() + cclear() + vim.fn.jobstart("golangci-lint run --max-issues-per-linter=0 --max-same-issues=0 --new", { + stdout_buffered = true, + on_stdout = function(_, data) + if data and #data > 1 then + vim.schedule(function() + vim.fn.setqflist({}, " ", { lines = data }) + copen() + end) + end + end, + }) + end, buf_opts) + end, +}) + +vim.api.nvim_create_autocmd("FileType", { + pattern = "markdown", + callback = function() + vim.opt_local.spell = true + vim.opt_local.textwidth = 80 + vim.opt_local.formatoptions:remove("ct") + end, +}) + +-- syntax, indentation, treesitter, etc. +require("ibl").setup({ + indent = { char = "│" }, + exclude = { filetypes = { "help" } }, + scope = { enabled = false }, +}) + +require("nvim-autopairs").setup({ + check_ts = true, +}) + +require("nvim-ts-autotag").setup() +require("nvim-surround").setup() +require("todo-comments").setup() + +require("treesitter-context").setup({ + multiline_threshold = 1, +}) + +---@diagnostic disable-next-line: missing-fields +require("nvim-treesitter.configs").setup({ + ensure_installed = { + "arduino", + "awk", + "bash", + "cpp", + "css", + "csv", + "diff", + "dockerfile", + "fish", + "git_config", + "git_rebase", + "gitattributes", + "gitcommit", + "gitignore", + "go", + "gomod", + "gosum", + "gowork", + "graphql", + "hcl", + "html", + "http", + "http", + "ini", + "javascript", + "jq", + "json", + "lua", + "make", + "markdown", + "markdown_inline", + "mermaid", + "python", + "query", + "regex", + "ruby", + "scss", + "sql", + "ssh_config", + "templ", + "terraform", + "toml", + "vhs", + "vim", + "vimdoc", + "yaml", + "zig", + }, + highlight = { + enable = true, + }, + indent = { + enable = true, + }, + endwise = { + enable = true, + }, + autopairs = { + enable = true, + }, + context_commentstring = { + enable = true, + enable_autocmd = false, + }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = "", + node_incremental = "", + node_decremental = "", + scope_incremental = "", + }, + }, + auto_install = true, + textobjects = { + enable = true, + lookahead = true, + swap = { + enable = true, + swap_next = { + ["a"] = "@parameter.inner", + }, + swap_previous = { + ["A"] = "@parameter.inner", + }, + }, + move = { + enable = true, + set_jumps = true, + goto_next_start = { + ["]f"] = "@function.inner", + ["]c"] = "@class.inner", + ["]a"] = "@parameter.inner", + }, + goto_next_end = { + ["]F"] = "@function.inner", + ["]C"] = "@class.inner", + ["]A"] = "@parameter.inner", + }, + goto_previous_start = { + ["[f"] = "@function.inner", + ["[c"] = "@class.inner", + ["[a"] = "@parameter.inner", + }, + goto_previous_end = { + ["[F"] = "@function.inner", + ["[C"] = "@class.inner", + ["[A"] = "@parameter.inner", + }, + }, + select = { + enable = true, + keymaps = { + ["af"] = "@function.outer", + ["if"] = "@function.inner", + + ["ac"] = "@conditional.outer", + ["ic"] = "@conditional.inner", + + ["aa"] = "@parameter.outer", + ["ia"] = "@parameter.inner", + + ["av"] = "@variable.outer", + ["iv"] = "@variable.inner", + }, + }, + }, +}) + +local treesj = require("treesj") +treesj.setup({ use_default_keymaps = false }) +keymap("n", "st", treesj.toggle, opts) + +local telescope = require("telescope") +telescope.setup({ + defaults = { + pickers = { + find_files = { + theme = "ivy", + }, + }, + prompt_prefix = "  ", + selection_caret = " ❯ ", + entry_prefix = " ", + multi_icon = "+ ", + path_display = { "filename_first" }, + vimgrep_arguments = { + "rg", + "--color=never", + "--no-heading", + "--with-filename", + "--line-number", + "--column", + "--smart-case", + "--sort=path", + }, + }, +}) +telescope.load_extension("gh") + +local function ivy(iopts) + return require("telescope.themes").get_ivy(iopts) +end + +local builtin = require("telescope.builtin") +vim.keymap.set("n", "", function() + builtin.find_files(ivy({ + find_command = { + "fd", + "--type", + "f", + "--strip-cwd-prefix", + "--hidden", + }, + })) +end, opts) + +keymap("n", "of", function() + builtin.oldfiles(ivy({ + only_cwd = true, + })) +end, opts) + +keymap("n", "lg", function() + builtin.live_grep(ivy()) +end, opts) + +keymap("n", "fb", function() + builtin.buffers(ivy()) +end, opts) + +keymap("n", "fh", function() + builtin.help_tags(ivy()) +end, opts) + +keymap("n", "fc", function() + builtin.commands(ivy()) +end, opts) + +keymap("n", "fr", function() + builtin.resume(ivy()) +end, opts) + +keymap("n", "fq", function() + builtin.quickfix(ivy()) +end, opts) + +keymap("n", "/", function() + builtin.current_buffer_fuzzy_find(ivy()) +end, opts) + +keymap("n", "ghi", function() + telescope.extensions.gh.issues(ivy()) +end, opts) + +-- LSP/autocommands inline replica of caarlos0's modules. +local function setup_lsp_autocommands() + local ms = require("vim.lsp.protocol").Methods + local group = vim.api.nvim_create_augroup("LSP", { clear = true }) + + ---@async + ---@param client vim.lsp.Client + ---@param bufnr number + local function organize_imports(client, bufnr) + ---@type lsp.Handler + ---@diagnostic disable-next-line: unused-local + local handler = function(err, result, context, config) + if err then + return + end + for _, r in pairs(result or {}) do + if r.edit then + local enc = client.offset_encoding or "utf-16" + vim.lsp.util.apply_workspace_edit(r.edit, enc) + elseif r.command and r.command.command then + client:exec_cmd(r.command, { bufnr = bufnr }) + end + end + vim.cmd([[noautocmd write]]) + end + + local win = vim.api.nvim_get_current_win() + local params = vim.lsp.util.make_range_params(win, client.offset_encoding or "utf-16") + params.context = { only = { "source.organizeImports" } } + client:request(ms.textDocument_codeAction, params, handler, bufnr) + end + + local function has_clients_with_method(bufnr, method) + local clients = vim.lsp.get_clients({ bufnr = bufnr, method = method }) + return #clients > 0 + end + + local function on_clients(bufnr, method, apply, filter) + local clients = vim.lsp.get_clients({ bufnr = bufnr, method = method }) + local predicate = filter or function() + return true + end + for _, client in ipairs(clients) do + if predicate(client) then + apply(client, bufnr) + end + end + end + + vim.api.nvim_create_autocmd("LspAttach", { + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + if client == nil then + return + end + if client:supports_method(ms.textDocument_codeLens, vim.api.nvim_get_current_buf()) then + vim.lsp.inlay_hint.enable(true) + end + end, + }) + vim.api.nvim_create_autocmd("LspDetach", { + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + if client == nil then + return + end + if client:supports_method(ms.textDocument_codeLens, vim.api.nvim_get_current_buf()) then + vim.lsp.codelens.clear(client.id) + end + end, + group = group, + }) + + vim.api.nvim_create_autocmd({ "BufWritePre" }, { + callback = function() + local format = function(client, bufnr) + if client.server_capabilities.documentFormattingProvider then + vim.lsp.buf.format({ + bufnr = bufnr, + timeout_ms = 5000, + id = client.id, + }) + end + end + on_clients(vim.api.nvim_get_current_buf(), ms.textDocument_codeAction, format) + end, + group = group, + }) + + vim.api.nvim_create_autocmd({ "BufWritePost" }, { + callback = function() + local bufnr = vim.api.nvim_get_current_buf() + local filter = function(client) + return client.name ~= "lua_ls" + end + on_clients(bufnr, ms.textDocument_codeAction, organize_imports, filter) + end, + group = group, + }) + + vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", "InsertLeave" }, { + callback = function() + if has_clients_with_method(0, ms.textDocument_codeLens) then + vim.lsp.codelens.refresh({ bufnr = 0 }) + end + end, + group = group, + }) + + vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { + callback = function() + if has_clients_with_method(0, ms.textDocument_documentHighlight) then + vim.lsp.buf.document_highlight() + end + end, + group = group, + }) + + vim.api.nvim_create_autocmd({ "CursorMoved" }, { + callback = function() + if has_clients_with_method(0, ms.textDocument_documentHighlight) then + vim.lsp.buf.clear_references() + end + end, + group = group, + }) +end + +setup_lsp_autocommands() + +local capabilities = require("blink.cmp").get_lsp_capabilities({ + workspace = { + didChangeWatchedFiles = { + dynamicRegistration = true, + relativePatternSupport = true, + }, + }, +}, true) + +---@param client vim.lsp.Client +---@param bufnr number +local on_attach = function(client, bufnr) + local keymap_lsp = function(lhs, rhs) + vim.keymap.set("n", lhs, rhs, { + noremap = true, + silent = true, + buffer = bufnr, + }) + end + + local telescope_wrap = function(action) + return function() + local ivy_theme = require("telescope.themes").get_ivy() + require("telescope.builtin")["lsp_" .. action](ivy_theme) + end + end + + keymap_lsp("gd", telescope_wrap("definitions")) + keymap_lsp("grr", telescope_wrap("references")) + keymap_lsp("gO", telescope_wrap("document_symbols")) + keymap_lsp("gri", telescope_wrap("implementations")) + keymap_lsp("gD", vim.lsp.buf.declaration) + keymap_lsp("K", vim.lsp.buf.hover) + keymap_lsp("D", telescope_wrap("type_definitions")) + keymap_lsp("grl", vim.lsp.codelens.run) + keymap_lsp("gl", vim.diagnostic.open_float) + keymap_lsp("[d", function() + vim.diagnostic.jump({ count = -1 }) + vim.cmd("norm zz") + end) + keymap_lsp("]d", function() + vim.diagnostic.jump({ count = 1 }) + vim.cmd("norm zz") + end) + + keymap_lsp("v", function() + vim.cmd("vsplit | lua vim.lsp.buf.definition()") + vim.cmd("norm zz") + end) +end + +local lspconfig = require("lspconfig") +require("lspconfig.ui.windows").default_options.border = "none" +lspconfig.gopls.setup({ + capabilities = capabilities, + on_attach = on_attach, + settings = { + gopls = { + gofumpt = true, + codelenses = { + gc_details = true, + generate = true, + run_govulncheck = true, + test = true, + tidy = true, + upgrade_dependency = true, + }, + hints = { + assignVariableTypes = true, + compositeLiteralFields = true, + compositeLiteralTypes = true, + constantValues = true, + functionTypeParameters = true, + parameterNames = true, + rangeVariableTypes = true, + }, + analyses = { + nilness = true, + unusedparams = true, + unusedvariable = true, + unusedwrite = true, + useany = true, + }, + staticcheck = true, + directoryFilters = { "-.git", "-node_modules" }, + semanticTokens = true, + }, + }, + flags = { + debounce_text_changes = 150, + }, +}) + +lspconfig.ts_ls.setup({ + capabilities = capabilities, + on_attach = on_attach, + settings = { + javascript = { + inlayHints = { + includeInlayEnumMemberValueHints = true, + includeInlayFunctionLikeReturnTypeHints = true, + includeInlayFunctionParameterTypeHints = true, + includeInlayParameterNameHints = "all", + includeInlayParameterNameHintsWhenArgumentMatchesName = true, + includeInlayPropertyDeclarationTypeHints = true, + includeInlayVariableTypeHints = true, + }, + }, + typescript = { + inlayHints = { + includeInlayEnumMemberValueHints = true, + includeInlayFunctionLikeReturnTypeHints = true, + includeInlayFunctionParameterTypeHints = true, + includeInlayParameterNameHints = "all", + includeInlayParameterNameHintsWhenArgumentMatchesName = true, + includeInlayPropertyDeclarationTypeHints = true, + includeInlayVariableTypeHints = true, + }, + }, + }, +}) + +for _, lsp in ipairs({ + "bashls", + "clangd", + "cssls", + "jsonls", + "pylsp", + "rust_analyzer", + "taplo", + "templ", + "terraformls", + "tflint", + "zls", +}) do + lspconfig[lsp].setup({ + on_attach = on_attach, + capabilities = capabilities, + }) +end + +for _, lsp in ipairs({ "html", "htmx" }) do + lspconfig[lsp].setup({ + capabilities = capabilities, + on_attach = on_attach, + filetypes = { "html", "templ" }, + }) +end + +lspconfig.tailwindcss.setup({ + on_attach = on_attach, + capabilities = capabilities, + filetypes = { "html", "templ", "javascript" }, + settings = { + tailwindCSS = { + includeLanguages = { + templ = "html", + }, + }, + }, +}) + +lspconfig.yamlls.setup({ + capabilities = capabilities, + on_attach = on_attach, + settings = { + yaml = { + schemaStore = { + url = "https://www.schemastore.org/api/json/catalog.json", + enable = true, + }, + }, + }, +}) + +local runtime_path = vim.split(package.path, ";", {}) +table.insert(runtime_path, "lua/?.lua") +table.insert(runtime_path, "lua/?/init.lua") +lspconfig.lua_ls.setup({ + capabilities = capabilities, + on_attach = on_attach, + settings = { + Lua = { + completion = { + callSnippet = "Replace", + }, + telemetry = { enable = false }, + hint = { + enable = true, + }, + workspace = { + library = vim.api.nvim_get_runtime_file("", true), + }, + }, + }, +}) + +require("nvim-tree").setup({ + view = { + width = 30, + }, +}) +keymap("n", "", ":NvimTreeToggle", opts) From 7f46a633d7696c94d03a2ac8a43d4fb56070f93c Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 18:43:47 -0600 Subject: [PATCH 25/92] chore: update --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 083631d31..508fee36f 100644 --- a/Makefile +++ b/Makefile @@ -485,7 +485,7 @@ neovim-local-dev: cp "$(HOME)/.config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua.backup.$(shell date +%s)"; \ fi; \ echo "Creating symlink to local Neovim config..."; \ - ln -sf "$(HOME)/.config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua"; \ + ln -sf "$(PWD)/config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua"; \ else \ echo "Local Neovim config is already a symlink"; \ fi From c4e2489fdd6da04f4c9e3a357bb64261fad398e8 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 18:47:21 -0600 Subject: [PATCH 26/92] chore: update --- config/nvim/default.nix | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config/nvim/default.nix b/config/nvim/default.nix index 769156e91..a7968ee82 100644 --- a/config/nvim/default.nix +++ b/config/nvim/default.nix @@ -1,9 +1,9 @@ { config, ... }: -let - dotfilesDir = "${config.home.homeDirectory}/dotfiles"; -in { - xdg.configFile."nvim" = { - source = config.lib.file.mkOutOfStoreSymlink "${dotfilesDir}/config/nvim"; + home.file.".config/nvim/init.lua" = { + source = config.lib.file.mkOutOfStoreSymlink ./init.lua; + }; + home.file.".config/nvim/nvim-pack-lock.json" = { + source = config.lib.file.mkOutOfStoreSymlink ./nvim-pack-lock.json; }; } From 23b8f1a5ffb8a260de51f043bd79365030f71ae4 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sat, 22 Nov 2025 18:55:30 -0600 Subject: [PATCH 27/92] chore: update --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 508fee36f..91eb9f473 100644 --- a/Makefile +++ b/Makefile @@ -479,8 +479,8 @@ neovim-local-dev: echo "Creating local Neovim config directory..."; \ mkdir -p "$(HOME)/.config/nvim"; \ fi - @if [ ! -L "$(HOME)/.config/nvim/init.lua" ]; then \ - if [ -f "$(HOME)/.config/nvim/init.lua" ]; then \ + @if [ ! -L "$(PWD)/config/nvim/init.lua" ]; then \ + if [ -f "$(PWD)/config/nvim/init.lua" ]; then \ echo "Backing up existing local config..."; \ cp "$(HOME)/.config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua.backup.$(shell date +%s)"; \ fi; \ From eda9a1cd7f146fed495f1c162941bb79b323a430 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 16:10:10 +0900 Subject: [PATCH 28/92] fix: change keymap for NvimTreeToggle from Ctrl+n to Ctrl+b --- config/nvim/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index aad839cd0..fbbf7cd5b 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -1171,4 +1171,4 @@ require("nvim-tree").setup({ width = 30, }, }) -keymap("n", "", ":NvimTreeToggle", opts) +keymap("b", "", ":NvimTreeToggle", opts) From 7e9647eaa370524416eafd99c473a79e729b9d16 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 16:21:42 +0900 Subject: [PATCH 29/92] feat: enhance neovim-local-dev setup with backup restoration and logging --- Makefile | 51 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 91eb9f473..bac42ba5b 100644 --- a/Makefile +++ b/Makefile @@ -475,21 +475,54 @@ neovim-sync: .PHONY: neovim-local-dev neovim-local-dev: @echo "🔧 Setting up local Neovim development environment..." + @echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Starting neovim-local-dev","data":{"pwd":"$(PWD)","home":"$(HOME)","source_file":"$(PWD)/config/nvim/init.lua","target_file":"$(HOME)/.config/nvim/init.lua"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true + @if [ -L "$(PWD)/config/nvim/init.lua" ]; then \ + echo "⚠️ WARNING: Source file $(PWD)/config/nvim/init.lua is a symlink! This should be a regular file."; \ + echo "Restoring from backup..."; \ + if [ -f "$(PWD)/config/nvim/init.lua.backup.1763882146" ]; then \ + rm -f "$(PWD)/config/nvim/init.lua"; \ + cp "$(PWD)/config/nvim/init.lua.backup.1763882146" "$(PWD)/config/nvim/init.lua"; \ + echo "✅ Source file restored from backup"; \ + echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Restored source file from backup","data":{"backup":"init.lua.backup.1763882146"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ + else \ + echo "❌ No backup found! Cannot restore."; \ + exit 1; \ + fi; \ + fi @if [ ! -d "$(HOME)/.config/nvim" ]; then \ echo "Creating local Neovim config directory..."; \ mkdir -p "$(HOME)/.config/nvim"; \ + echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Created nvim config directory","data":{"dir":"$(HOME)/.config/nvim"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ fi - @if [ ! -L "$(PWD)/config/nvim/init.lua" ]; then \ - if [ -f "$(PWD)/config/nvim/init.lua" ]; then \ - echo "Backing up existing local config..."; \ - cp "$(HOME)/.config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua.backup.$(shell date +%s)"; \ - fi; \ - echo "Creating symlink to local Neovim config..."; \ - ln -sf "$(PWD)/config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua"; \ - else \ - echo "Local Neovim config is already a symlink"; \ + @if [ -e "$(HOME)/.config/nvim/init.lua" ]; then \ + echo "Removing existing Nix-managed config..."; \ + rm -f "$(HOME)/.config/nvim/init.lua"; \ + echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Removed existing target file","data":{"target":"$(HOME)/.config/nvim/init.lua"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ + fi + @echo "Creating symlink to local Neovim config at $(PWD)/config/nvim/init.lua..."; \ + @echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Before ln command","data":{"source":"$(PWD)/config/nvim/init.lua","target":"$(HOME)/.config/nvim/init.lua","pwd":"$(PWD)"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ + ln -sf "$(PWD)/config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua"; \ + echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"After ln command","data":{"source":"$(PWD)/config/nvim/init.lua","target":"$(HOME)/.config/nvim/init.lua"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true + @if [ -L "$(PWD)/config/nvim/init.lua" ]; then \ + echo "❌ ERROR: Source file became a symlink after ln command!"; \ + echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"ERROR: Source file is symlink after ln","data":{},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ + exit 1; \ fi @echo "✅ Local Neovim development environment ready" + @echo "Run 'make neovim-local-dev-restore' to restore the Nix-managed version." + +.PHONY: neovim-local-dev-restore +neovim-local-dev-restore: + @echo "🔄 Restoring Nix-managed Neovim configuration..." + @if [ -L "$(HOME)/.config/nvim/init.lua" ]; then \ + echo "Removing local development symlink..."; \ + rm -f "$(HOME)/.config/nvim/init.lua"; \ + else \ + echo "No local symlink found at $(HOME)/.config/nvim/init.lua"; \ + fi + @echo "Restoring Nix-managed version via 'make switch'..." + @$(MAKE) switch + @echo "✅ Nix-managed Neovim configuration restored" ##@ Git Submodule From 03fa4eb594dbc7bf2580a8a2c1aa7d800c4b557c Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 16:31:33 +0900 Subject: [PATCH 30/92] chore: update .gitignore and Makefile for neovim setup; remove nvim-pack-lock.json --- .gitignore | 3 + Makefile | 16 ++- config/nvim/nvim-pack-lock.json | 174 +------------------------------- 3 files changed, 16 insertions(+), 177 deletions(-) mode change 100644 => 120000 config/nvim/nvim-pack-lock.json diff --git a/.gitignore b/.gitignore index 5a154206b..31e02e131 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # AI .claude +# Nix +*.hm-backup + # General .DS_Store .AppleDouble diff --git a/Makefile b/Makefile index bac42ba5b..f1b678906 100644 --- a/Makefile +++ b/Makefile @@ -489,6 +489,14 @@ neovim-local-dev: exit 1; \ fi; \ fi + @if [ -L "$(HOME)/.config/nvim" ]; then \ + nvim_resolved=$$(readlink -f "$(HOME)/.config/nvim" 2>/dev/null || echo ""); \ + if [ "$$nvim_resolved" = "$(PWD)/config/nvim" ]; then \ + echo "⚠️ WARNING: $(HOME)/.config/nvim is a symlink pointing to source directory. Removing it..."; \ + rm -f "$(HOME)/.config/nvim"; \ + echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Removed nvim symlink directory pointing to source","data":{"dir":"$(HOME)/.config/nvim","resolved":"$$nvim_resolved"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ + fi; \ + fi @if [ ! -d "$(HOME)/.config/nvim" ]; then \ echo "Creating local Neovim config directory..."; \ mkdir -p "$(HOME)/.config/nvim"; \ @@ -499,10 +507,10 @@ neovim-local-dev: rm -f "$(HOME)/.config/nvim/init.lua"; \ echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Removed existing target file","data":{"target":"$(HOME)/.config/nvim/init.lua"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ fi - @echo "Creating symlink to local Neovim config at $(PWD)/config/nvim/init.lua..."; \ - @echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Before ln command","data":{"source":"$(PWD)/config/nvim/init.lua","target":"$(HOME)/.config/nvim/init.lua","pwd":"$(PWD)"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ - ln -sf "$(PWD)/config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua"; \ - echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"After ln command","data":{"source":"$(PWD)/config/nvim/init.lua","target":"$(HOME)/.config/nvim/init.lua"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true + @echo "Creating symlink to local Neovim config at $(PWD)/config/nvim/init.lua..." + @echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Before ln command","data":{"source":"$(PWD)/config/nvim/init.lua","target":"$(HOME)/.config/nvim/init.lua","pwd":"$(PWD)","nvim_dir_is_link":"'$$([ -L "$(HOME)/.config/nvim" ] && echo true || echo false)'","nvim_dir_resolved":"'$$(readlink -f "$(HOME)/.config/nvim" 2>/dev/null || echo "N/A")'"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true + @ln -sf "$(PWD)/config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua" + @echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"After ln command","data":{"source":"$(PWD)/config/nvim/init.lua","target":"$(HOME)/.config/nvim/init.lua","source_is_link":"'$$([ -L "$(PWD)/config/nvim/init.lua" ] && echo true || echo false)'","target_is_link":"'$$([ -L "$(HOME)/.config/nvim/init.lua" ] && echo true || echo false)'","target_readlink":"'$$(readlink "$(HOME)/.config/nvim/init.lua" 2>/dev/null || echo "N/A")'"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true @if [ -L "$(PWD)/config/nvim/init.lua" ]; then \ echo "❌ ERROR: Source file became a symlink after ln command!"; \ echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"ERROR: Source file is symlink after ln","data":{},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json deleted file mode 100644 index 9812f3bbf..000000000 --- a/config/nvim/nvim-pack-lock.json +++ /dev/null @@ -1,173 +0,0 @@ -{ - "plugins": { - "auto-hlsearch.nvim": { - "rev": "77502069b22e48ab7736fe9cf53e1fdac1923bca", - "src": "https://github.com/asiryk/auto-hlsearch.nvim" - }, - "blink-cmp-copilot": { - "rev": "439cff78780c033aa23cf061d7315314b347e3c1", - "src": "https://github.com/giuxtaposition/blink-cmp-copilot" - }, - "blink.cmp": { - "rev": "b19413d214068f316c78978b08264ed1c41830ec", - "src": "https://github.com/saghen/blink.cmp", - "version": "1.0.0 - 2.0.0" - }, - "bufdelete.nvim": { - "rev": "f6bcea78afb3060b198125256f897040538bcb81", - "src": "https://github.com/famiu/bufdelete.nvim" - }, - "conform.nvim": { - "rev": "afce105eb47b0869dfafdac90d82f02ef2419d61", - "src": "https://github.com/stevearc/conform.nvim" - }, - "copilot.lua": { - "rev": "4383e05a47493d7ff77b058c0548129eb38ec7fb", - "src": "https://github.com/zbirenbaum/copilot.lua" - }, - "dracula.nvim": { - "rev": "ae752c13e95fb7c5f58da4b5123cb804ea7568ee", - "src": "https://github.com/Mofiqul/dracula.nvim" - }, - "dressing.nvim": { - "rev": "2d7c2db2507fa3c4956142ee607431ddb2828639", - "src": "https://github.com/stevearc/dressing.nvim" - }, - "friendly-snippets": { - "rev": "572f5660cf05f8cd8834e096d7b4c921ba18e175", - "src": "https://github.com/rafamadriz/friendly-snippets" - }, - "git-conflict.nvim": { - "rev": "a1badcd070d176172940eb55d9d59029dad1c5a6", - "src": "https://github.com/akinsho/git-conflict.nvim" - }, - "gitsigns.nvim": { - "rev": "cdafc320f03f2572c40ab93a4eecb733d4016d07", - "src": "https://github.com/lewis6991/gitsigns.nvim" - }, - "gruvbox.nvim": { - "rev": "5e0a460d8e0f7f669c158dedd5f9ae2bcac31437", - "src": "https://github.com/ellisonleao/gruvbox.nvim" - }, - "indent-blankline.nvim": { - "rev": "005b56001b2cb30bfa61b7986bc50657816ba4ba", - "src": "https://github.com/lukas-reineke/indent-blankline.nvim" - }, - "lualine.nvim": { - "rev": "3946f0122255bc377d14a59b27b609fb3ab25768", - "src": "https://github.com/nvim-lualine/lualine.nvim" - }, - "neogen": { - "rev": "d7f9461727751fb07f82011051338a9aba07581d", - "src": "https://github.com/danymat/neogen" - }, - "nvim-autopairs": { - "rev": "7a2c97cccd60abc559344042fefb1d5a85b3e33b", - "src": "https://github.com/windwp/nvim-autopairs" - }, - "nvim-colorizer.lua": { - "rev": "a065833f35a3a7cc3ef137ac88b5381da2ba302e", - "src": "https://github.com/norcalli/nvim-colorizer.lua" - }, - "nvim-lspconfig": { - "rev": "a2a277114dbb93e98f04b5087a9b832918b7da15", - "src": "https://github.com/neovim/nvim-lspconfig" - }, - "nvim-notify": { - "rev": "8701bece920b38ea289b457f902e2ad184131a5d", - "src": "https://github.com/rcarriga/nvim-notify" - }, - "nvim-surround": { - "rev": "fcfa7e02323d57bfacc3a141f8a74498e1522064", - "src": "https://github.com/kylechui/nvim-surround" - }, - "nvim-tree.lua": { - "rev": "3fb91e18a727ecc0385637895ec397dea90be42a", - "src": "https://github.com/nvim-tree/nvim-tree.lua" - }, - "nvim-treesitter": { - "rev": "42fc28ba918343ebfd5565147a42a26580579482", - "src": "https://github.com/nvim-treesitter/nvim-treesitter" - }, - "nvim-treesitter-context": { - "rev": "660861b1849256398f70450afdf93908d28dc945", - "src": "https://github.com/nvim-treesitter/nvim-treesitter-context" - }, - "nvim-treesitter-endwise": { - "rev": "a61a9de7965324d4019fb1637b66bfacdcb01f51", - "src": "https://github.com/RRethy/nvim-treesitter-endwise" - }, - "nvim-treesitter-textobjects": { - "rev": "5ca4aaa6efdcc59be46b95a3e876300cfead05ef", - "src": "https://github.com/nvim-treesitter/nvim-treesitter-textobjects" - }, - "nvim-ts-autotag": { - "rev": "c4ca798ab95b316a768d51eaaaee48f64a4a46bc", - "src": "https://github.com/windwp/nvim-ts-autotag" - }, - "nvim-web-devicons": { - "rev": "8dcb311b0c92d460fac00eac706abd43d94d68af", - "src": "https://github.com/nvim-tree/nvim-web-devicons" - }, - "other.nvim": { - "rev": "1d48e090f6d1d53dda9fb5094af3f2006ebbb858", - "src": "https://github.com/rgroli/other.nvim" - }, - "plenary.nvim": { - "rev": "b9fd5226c2f76c951fc8ed5923d85e4de065e509", - "src": "https://github.com/nvim-lua/plenary.nvim" - }, - "sidekick.nvim": { - "rev": "c2bdf8cfcd87a6be5f8b84322c1b5052e78e302e", - "src": "https://github.com/folke/sidekick.nvim" - }, - "telescope-github.nvim": { - "rev": "ee95c509901c3357679e9f2f9eaac3561c811736", - "src": "https://github.com/nvim-telescope/telescope-github.nvim" - }, - "telescope.nvim": { - "rev": "83a3a713d6b2d2a408491a1b959e55a7fa8678e8", - "src": "https://github.com/nvim-telescope/telescope.nvim" - }, - "todo-comments.nvim": { - "rev": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668", - "src": "https://github.com/folke/todo-comments.nvim" - }, - "treesj": { - "rev": "4770492244ccecdc9b01e0e81fa8f2f6b4a23841", - "src": "https://github.com/wansmer/treesj" - }, - "vim-abolish": { - "rev": "dcbfe065297d31823561ba787f51056c147aa682", - "src": "https://github.com/tpope/vim-abolish" - }, - "vim-eunuch": { - "rev": "e86bb794a1c10a2edac130feb0ea590a00d03f1e", - "src": "https://github.com/tpope/vim-eunuch" - }, - "vim-fugitive": { - "rev": "61b51c09b7c9ce04e821f6cf76ea4f6f903e3cf4", - "src": "https://github.com/tpope/vim-fugitive" - }, - "vim-repeat": { - "rev": "65846025c15494983dafe5e3b46c8f88ab2e9635", - "src": "https://github.com/tpope/vim-repeat" - }, - "vim-rhubarb": { - "rev": "5496d7c94581c4c9ad7430357449bb57fc59f501", - "src": "https://github.com/tpope/vim-rhubarb" - }, - "vim-sleuth": { - "rev": "be69bff86754b1aa5adcbb527d7fcd1635a84080", - "src": "https://github.com/tpope/vim-sleuth" - }, - "vim-speeddating": { - "rev": "c17eb01ebf5aaf766c53bab1f6592710e5ffb796", - "src": "https://github.com/tpope/vim-speeddating" - }, - "vim-tmux-navigator": { - "rev": "c45243dc1f32ac6bcf6068e5300f3b2b237e576a", - "src": "https://github.com/christoomey/vim-tmux-navigator" - } - } -} \ No newline at end of file diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json new file mode 120000 index 000000000..7151117eb --- /dev/null +++ b/config/nvim/nvim-pack-lock.json @@ -0,0 +1 @@ +/nix/store/92bskscyqff37sjb5b5lxbmy1apf5a3x-home-manager-files/.config/nvim/nvim-pack-lock.json \ No newline at end of file From cfcc8ea9362ee874d6ff34cc336f49cb561255c0 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 16:32:13 +0900 Subject: [PATCH 31/92] chore: recreate nvim-pack-lock.json with updated plugin configurations --- config/nvim/nvim-pack-lock.json | 174 +++++++++++++++++++++++++++++++- 1 file changed, 173 insertions(+), 1 deletion(-) mode change 120000 => 100644 config/nvim/nvim-pack-lock.json diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json deleted file mode 120000 index 7151117eb..000000000 --- a/config/nvim/nvim-pack-lock.json +++ /dev/null @@ -1 +0,0 @@ -/nix/store/92bskscyqff37sjb5b5lxbmy1apf5a3x-home-manager-files/.config/nvim/nvim-pack-lock.json \ No newline at end of file diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json new file mode 100644 index 000000000..9812f3bbf --- /dev/null +++ b/config/nvim/nvim-pack-lock.json @@ -0,0 +1,173 @@ +{ + "plugins": { + "auto-hlsearch.nvim": { + "rev": "77502069b22e48ab7736fe9cf53e1fdac1923bca", + "src": "https://github.com/asiryk/auto-hlsearch.nvim" + }, + "blink-cmp-copilot": { + "rev": "439cff78780c033aa23cf061d7315314b347e3c1", + "src": "https://github.com/giuxtaposition/blink-cmp-copilot" + }, + "blink.cmp": { + "rev": "b19413d214068f316c78978b08264ed1c41830ec", + "src": "https://github.com/saghen/blink.cmp", + "version": "1.0.0 - 2.0.0" + }, + "bufdelete.nvim": { + "rev": "f6bcea78afb3060b198125256f897040538bcb81", + "src": "https://github.com/famiu/bufdelete.nvim" + }, + "conform.nvim": { + "rev": "afce105eb47b0869dfafdac90d82f02ef2419d61", + "src": "https://github.com/stevearc/conform.nvim" + }, + "copilot.lua": { + "rev": "4383e05a47493d7ff77b058c0548129eb38ec7fb", + "src": "https://github.com/zbirenbaum/copilot.lua" + }, + "dracula.nvim": { + "rev": "ae752c13e95fb7c5f58da4b5123cb804ea7568ee", + "src": "https://github.com/Mofiqul/dracula.nvim" + }, + "dressing.nvim": { + "rev": "2d7c2db2507fa3c4956142ee607431ddb2828639", + "src": "https://github.com/stevearc/dressing.nvim" + }, + "friendly-snippets": { + "rev": "572f5660cf05f8cd8834e096d7b4c921ba18e175", + "src": "https://github.com/rafamadriz/friendly-snippets" + }, + "git-conflict.nvim": { + "rev": "a1badcd070d176172940eb55d9d59029dad1c5a6", + "src": "https://github.com/akinsho/git-conflict.nvim" + }, + "gitsigns.nvim": { + "rev": "cdafc320f03f2572c40ab93a4eecb733d4016d07", + "src": "https://github.com/lewis6991/gitsigns.nvim" + }, + "gruvbox.nvim": { + "rev": "5e0a460d8e0f7f669c158dedd5f9ae2bcac31437", + "src": "https://github.com/ellisonleao/gruvbox.nvim" + }, + "indent-blankline.nvim": { + "rev": "005b56001b2cb30bfa61b7986bc50657816ba4ba", + "src": "https://github.com/lukas-reineke/indent-blankline.nvim" + }, + "lualine.nvim": { + "rev": "3946f0122255bc377d14a59b27b609fb3ab25768", + "src": "https://github.com/nvim-lualine/lualine.nvim" + }, + "neogen": { + "rev": "d7f9461727751fb07f82011051338a9aba07581d", + "src": "https://github.com/danymat/neogen" + }, + "nvim-autopairs": { + "rev": "7a2c97cccd60abc559344042fefb1d5a85b3e33b", + "src": "https://github.com/windwp/nvim-autopairs" + }, + "nvim-colorizer.lua": { + "rev": "a065833f35a3a7cc3ef137ac88b5381da2ba302e", + "src": "https://github.com/norcalli/nvim-colorizer.lua" + }, + "nvim-lspconfig": { + "rev": "a2a277114dbb93e98f04b5087a9b832918b7da15", + "src": "https://github.com/neovim/nvim-lspconfig" + }, + "nvim-notify": { + "rev": "8701bece920b38ea289b457f902e2ad184131a5d", + "src": "https://github.com/rcarriga/nvim-notify" + }, + "nvim-surround": { + "rev": "fcfa7e02323d57bfacc3a141f8a74498e1522064", + "src": "https://github.com/kylechui/nvim-surround" + }, + "nvim-tree.lua": { + "rev": "3fb91e18a727ecc0385637895ec397dea90be42a", + "src": "https://github.com/nvim-tree/nvim-tree.lua" + }, + "nvim-treesitter": { + "rev": "42fc28ba918343ebfd5565147a42a26580579482", + "src": "https://github.com/nvim-treesitter/nvim-treesitter" + }, + "nvim-treesitter-context": { + "rev": "660861b1849256398f70450afdf93908d28dc945", + "src": "https://github.com/nvim-treesitter/nvim-treesitter-context" + }, + "nvim-treesitter-endwise": { + "rev": "a61a9de7965324d4019fb1637b66bfacdcb01f51", + "src": "https://github.com/RRethy/nvim-treesitter-endwise" + }, + "nvim-treesitter-textobjects": { + "rev": "5ca4aaa6efdcc59be46b95a3e876300cfead05ef", + "src": "https://github.com/nvim-treesitter/nvim-treesitter-textobjects" + }, + "nvim-ts-autotag": { + "rev": "c4ca798ab95b316a768d51eaaaee48f64a4a46bc", + "src": "https://github.com/windwp/nvim-ts-autotag" + }, + "nvim-web-devicons": { + "rev": "8dcb311b0c92d460fac00eac706abd43d94d68af", + "src": "https://github.com/nvim-tree/nvim-web-devicons" + }, + "other.nvim": { + "rev": "1d48e090f6d1d53dda9fb5094af3f2006ebbb858", + "src": "https://github.com/rgroli/other.nvim" + }, + "plenary.nvim": { + "rev": "b9fd5226c2f76c951fc8ed5923d85e4de065e509", + "src": "https://github.com/nvim-lua/plenary.nvim" + }, + "sidekick.nvim": { + "rev": "c2bdf8cfcd87a6be5f8b84322c1b5052e78e302e", + "src": "https://github.com/folke/sidekick.nvim" + }, + "telescope-github.nvim": { + "rev": "ee95c509901c3357679e9f2f9eaac3561c811736", + "src": "https://github.com/nvim-telescope/telescope-github.nvim" + }, + "telescope.nvim": { + "rev": "83a3a713d6b2d2a408491a1b959e55a7fa8678e8", + "src": "https://github.com/nvim-telescope/telescope.nvim" + }, + "todo-comments.nvim": { + "rev": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668", + "src": "https://github.com/folke/todo-comments.nvim" + }, + "treesj": { + "rev": "4770492244ccecdc9b01e0e81fa8f2f6b4a23841", + "src": "https://github.com/wansmer/treesj" + }, + "vim-abolish": { + "rev": "dcbfe065297d31823561ba787f51056c147aa682", + "src": "https://github.com/tpope/vim-abolish" + }, + "vim-eunuch": { + "rev": "e86bb794a1c10a2edac130feb0ea590a00d03f1e", + "src": "https://github.com/tpope/vim-eunuch" + }, + "vim-fugitive": { + "rev": "61b51c09b7c9ce04e821f6cf76ea4f6f903e3cf4", + "src": "https://github.com/tpope/vim-fugitive" + }, + "vim-repeat": { + "rev": "65846025c15494983dafe5e3b46c8f88ab2e9635", + "src": "https://github.com/tpope/vim-repeat" + }, + "vim-rhubarb": { + "rev": "5496d7c94581c4c9ad7430357449bb57fc59f501", + "src": "https://github.com/tpope/vim-rhubarb" + }, + "vim-sleuth": { + "rev": "be69bff86754b1aa5adcbb527d7fcd1635a84080", + "src": "https://github.com/tpope/vim-sleuth" + }, + "vim-speeddating": { + "rev": "c17eb01ebf5aaf766c53bab1f6592710e5ffb796", + "src": "https://github.com/tpope/vim-speeddating" + }, + "vim-tmux-navigator": { + "rev": "c45243dc1f32ac6bcf6068e5300f3b2b237e576a", + "src": "https://github.com/christoomey/vim-tmux-navigator" + } + } +} \ No newline at end of file From 7ed0778fb40746c97329269cc1b41b611eab6286 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 16:33:07 +0900 Subject: [PATCH 32/92] fix: add symlink check and backup restoration for nvim-pack-lock.json in Makefile --- Makefile | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Makefile b/Makefile index f1b678906..67ebf2dcb 100644 --- a/Makefile +++ b/Makefile @@ -489,6 +489,24 @@ neovim-local-dev: exit 1; \ fi; \ fi + @if [ -L "$(PWD)/config/nvim/nvim-pack-lock.json" ]; then \ + echo "⚠️ WARNING: Source file $(PWD)/config/nvim/nvim-pack-lock.json is a symlink! This should be a regular file."; \ + echo "Restoring from backup..."; \ + if [ -f "$(PWD)/config/nvim/nvim-pack-lock.json.hm-backup" ]; then \ + rm -f "$(PWD)/config/nvim/nvim-pack-lock.json"; \ + cp "$(PWD)/config/nvim/nvim-pack-lock.json.hm-backup" "$(PWD)/config/nvim/nvim-pack-lock.json"; \ + echo "✅ nvim-pack-lock.json restored from backup"; \ + echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Restored nvim-pack-lock.json from backup","data":{"backup":"nvim-pack-lock.json.hm-backup"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ + elif [ -f "$(PWD)/config/nvim/nvim-pack-lock.json" ]; then \ + echo "⚠️ Backup not found, but file exists. Checking if it's a valid JSON file..."; \ + if ! file "$(PWD)/config/nvim/nvim-pack-lock.json" | grep -q "JSON"; then \ + echo "❌ File is not valid JSON. Cannot proceed."; \ + exit 1; \ + fi; \ + else \ + echo "⚠️ No backup found and file doesn't exist. This is okay - it will be created by Neovim."; \ + fi; \ + fi @if [ -L "$(HOME)/.config/nvim" ]; then \ nvim_resolved=$$(readlink -f "$(HOME)/.config/nvim" 2>/dev/null || echo ""); \ if [ "$$nvim_resolved" = "$(PWD)/config/nvim" ]; then \ From 14cea7a7b34a4409b838028f82c88af0a555fdf0 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 16:34:56 +0900 Subject: [PATCH 33/92] refactor: simplify neovim-local-dev setup by removing symlink checks and backup restoration logic --- Makefile | 72 ++------------------------------------------------------ 1 file changed, 2 insertions(+), 70 deletions(-) diff --git a/Makefile b/Makefile index 67ebf2dcb..9d64875b1 100644 --- a/Makefile +++ b/Makefile @@ -475,80 +475,12 @@ neovim-sync: .PHONY: neovim-local-dev neovim-local-dev: @echo "🔧 Setting up local Neovim development environment..." - @echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Starting neovim-local-dev","data":{"pwd":"$(PWD)","home":"$(HOME)","source_file":"$(PWD)/config/nvim/init.lua","target_file":"$(HOME)/.config/nvim/init.lua"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true - @if [ -L "$(PWD)/config/nvim/init.lua" ]; then \ - echo "⚠️ WARNING: Source file $(PWD)/config/nvim/init.lua is a symlink! This should be a regular file."; \ - echo "Restoring from backup..."; \ - if [ -f "$(PWD)/config/nvim/init.lua.backup.1763882146" ]; then \ - rm -f "$(PWD)/config/nvim/init.lua"; \ - cp "$(PWD)/config/nvim/init.lua.backup.1763882146" "$(PWD)/config/nvim/init.lua"; \ - echo "✅ Source file restored from backup"; \ - echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Restored source file from backup","data":{"backup":"init.lua.backup.1763882146"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ - else \ - echo "❌ No backup found! Cannot restore."; \ - exit 1; \ - fi; \ - fi - @if [ -L "$(PWD)/config/nvim/nvim-pack-lock.json" ]; then \ - echo "⚠️ WARNING: Source file $(PWD)/config/nvim/nvim-pack-lock.json is a symlink! This should be a regular file."; \ - echo "Restoring from backup..."; \ - if [ -f "$(PWD)/config/nvim/nvim-pack-lock.json.hm-backup" ]; then \ - rm -f "$(PWD)/config/nvim/nvim-pack-lock.json"; \ - cp "$(PWD)/config/nvim/nvim-pack-lock.json.hm-backup" "$(PWD)/config/nvim/nvim-pack-lock.json"; \ - echo "✅ nvim-pack-lock.json restored from backup"; \ - echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Restored nvim-pack-lock.json from backup","data":{"backup":"nvim-pack-lock.json.hm-backup"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ - elif [ -f "$(PWD)/config/nvim/nvim-pack-lock.json" ]; then \ - echo "⚠️ Backup not found, but file exists. Checking if it's a valid JSON file..."; \ - if ! file "$(PWD)/config/nvim/nvim-pack-lock.json" | grep -q "JSON"; then \ - echo "❌ File is not valid JSON. Cannot proceed."; \ - exit 1; \ - fi; \ - else \ - echo "⚠️ No backup found and file doesn't exist. This is okay - it will be created by Neovim."; \ - fi; \ - fi @if [ -L "$(HOME)/.config/nvim" ]; then \ - nvim_resolved=$$(readlink -f "$(HOME)/.config/nvim" 2>/dev/null || echo ""); \ - if [ "$$nvim_resolved" = "$(PWD)/config/nvim" ]; then \ - echo "⚠️ WARNING: $(HOME)/.config/nvim is a symlink pointing to source directory. Removing it..."; \ - rm -f "$(HOME)/.config/nvim"; \ - echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Removed nvim symlink directory pointing to source","data":{"dir":"$(HOME)/.config/nvim","resolved":"$$nvim_resolved"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ - fi; \ - fi - @if [ ! -d "$(HOME)/.config/nvim" ]; then \ - echo "Creating local Neovim config directory..."; \ - mkdir -p "$(HOME)/.config/nvim"; \ - echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Created nvim config directory","data":{"dir":"$(HOME)/.config/nvim"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ + rm "$(HOME)/.config/nvim"; \ fi - @if [ -e "$(HOME)/.config/nvim/init.lua" ]; then \ - echo "Removing existing Nix-managed config..."; \ - rm -f "$(HOME)/.config/nvim/init.lua"; \ - echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Removed existing target file","data":{"target":"$(HOME)/.config/nvim/init.lua"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ - fi - @echo "Creating symlink to local Neovim config at $(PWD)/config/nvim/init.lua..." - @echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"Before ln command","data":{"source":"$(PWD)/config/nvim/init.lua","target":"$(HOME)/.config/nvim/init.lua","pwd":"$(PWD)","nvim_dir_is_link":"'$$([ -L "$(HOME)/.config/nvim" ] && echo true || echo false)'","nvim_dir_resolved":"'$$(readlink -f "$(HOME)/.config/nvim" 2>/dev/null || echo "N/A")'"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true + @mkdir -p "$(HOME)/.config/nvim" @ln -sf "$(PWD)/config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua" - @echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"After ln command","data":{"source":"$(PWD)/config/nvim/init.lua","target":"$(HOME)/.config/nvim/init.lua","source_is_link":"'$$([ -L "$(PWD)/config/nvim/init.lua" ] && echo true || echo false)'","target_is_link":"'$$([ -L "$(HOME)/.config/nvim/init.lua" ] && echo true || echo false)'","target_readlink":"'$$(readlink "$(HOME)/.config/nvim/init.lua" 2>/dev/null || echo "N/A")'"},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true - @if [ -L "$(PWD)/config/nvim/init.lua" ]; then \ - echo "❌ ERROR: Source file became a symlink after ln command!"; \ - echo '{"timestamp":'$$(date +%s000)',"location":"Makefile:neovim-local-dev","message":"ERROR: Source file is symlink after ln","data":{},"sessionId":"debug-session","runId":"run1","hypothesisId":"A"}' >> /Users/shunkakinoki/dotfiles/.cursor/debug.log || true; \ - exit 1; \ - fi @echo "✅ Local Neovim development environment ready" - @echo "Run 'make neovim-local-dev-restore' to restore the Nix-managed version." - -.PHONY: neovim-local-dev-restore -neovim-local-dev-restore: - @echo "🔄 Restoring Nix-managed Neovim configuration..." - @if [ -L "$(HOME)/.config/nvim/init.lua" ]; then \ - echo "Removing local development symlink..."; \ - rm -f "$(HOME)/.config/nvim/init.lua"; \ - else \ - echo "No local symlink found at $(HOME)/.config/nvim/init.lua"; \ - fi - @echo "Restoring Nix-managed version via 'make switch'..." - @$(MAKE) switch - @echo "✅ Nix-managed Neovim configuration restored" ##@ Git Submodule From 427da991298153a3018748d7faaae39992b12406 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 16:35:26 +0900 Subject: [PATCH 34/92] chore: add symlink for nvim-pack-lock.json in neovim-local-dev setup --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 9d64875b1..a2c450f0c 100644 --- a/Makefile +++ b/Makefile @@ -480,6 +480,7 @@ neovim-local-dev: fi @mkdir -p "$(HOME)/.config/nvim" @ln -sf "$(PWD)/config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua" + @ln -sf "$(PWD)/config/nvim/nvim-pack-lock.json" "$(HOME)/.config/nvim/nvim-pack-lock.json" @echo "✅ Local Neovim development environment ready" ##@ Git Submodule From 1de97c6a459cb86e3e5450cfed03dc207da59e83 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 16:37:47 +0900 Subject: [PATCH 35/92] chore: rename neovim-local-dev to neovim-dev and clean up setup process --- Makefile | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index a2c450f0c..e6cf2702d 100644 --- a/Makefile +++ b/Makefile @@ -458,6 +458,17 @@ docker-build: ##@ Neovim +.PHONY: neovim-dev +neovim-dev: + @echo "🔧 Setting up local Neovim development environment..." + @if [ -L "$(HOME)/.config/nvim" ]; then \ + rm "$(HOME)/.config/nvim"; \ + fi + @mkdir -p "$(HOME)/.config/nvim" + @ln -sf "$(PWD)/config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua" + @ln -sf "$(PWD)/config/nvim/nvim-pack-lock.json" "$(HOME)/.config/nvim/nvim-pack-lock.json" + @echo "✅ Local Neovim development environment ready" + .PHONY: neovim-update neovim-update: @echo "📦 Updating neovim plugins..." @@ -470,18 +481,6 @@ neovim-sync: @nvim --headless +"lua vim.pack.sync()" +qa @echo "✅ Neovim plugins synced" -##@ Neovim Local Development - -.PHONY: neovim-local-dev -neovim-local-dev: - @echo "🔧 Setting up local Neovim development environment..." - @if [ -L "$(HOME)/.config/nvim" ]; then \ - rm "$(HOME)/.config/nvim"; \ - fi - @mkdir -p "$(HOME)/.config/nvim" - @ln -sf "$(PWD)/config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua" - @ln -sf "$(PWD)/config/nvim/nvim-pack-lock.json" "$(HOME)/.config/nvim/nvim-pack-lock.json" - @echo "✅ Local Neovim development environment ready" ##@ Git Submodule From 588d2c01500d56d12a4583dcf145eac39f71d9b3 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 16:38:16 +0900 Subject: [PATCH 36/92] chore: add instruction to restore Nix-managed version in neovim-dev setup --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index e6cf2702d..5c7bc2efe 100644 --- a/Makefile +++ b/Makefile @@ -468,6 +468,7 @@ neovim-dev: @ln -sf "$(PWD)/config/nvim/init.lua" "$(HOME)/.config/nvim/init.lua" @ln -sf "$(PWD)/config/nvim/nvim-pack-lock.json" "$(HOME)/.config/nvim/nvim-pack-lock.json" @echo "✅ Local Neovim development environment ready" + @echo "🚧 To restore the Nix-managed version, run 'make switch'" .PHONY: neovim-update neovim-update: From 83ca274094353e808a6564488ae7e8164be9560e Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 16:39:22 +0900 Subject: [PATCH 37/92] refactor: update comments and remove unused Lua language server configuration in init.lua --- config/nvim/init.lua | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index fbbf7cd5b..0ee2e6b5d 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -79,7 +79,7 @@ vim.pack.add({ version = vim.version.range("1.*"), }, - -- tpope gang + -- TPOPE { src = "https://github.com/tpope/vim-fugitive" }, { src = "https://github.com/tpope/vim-rhubarb" }, { src = "https://github.com/tpope/vim-abolish" }, @@ -1144,28 +1144,6 @@ lspconfig.yamlls.setup({ }, }) -local runtime_path = vim.split(package.path, ";", {}) -table.insert(runtime_path, "lua/?.lua") -table.insert(runtime_path, "lua/?/init.lua") -lspconfig.lua_ls.setup({ - capabilities = capabilities, - on_attach = on_attach, - settings = { - Lua = { - completion = { - callSnippet = "Replace", - }, - telemetry = { enable = false }, - hint = { - enable = true, - }, - workspace = { - library = vim.api.nvim_get_runtime_file("", true), - }, - }, - }, -}) - require("nvim-tree").setup({ view = { width = 30, From 54f35e69bea76b1efbedba83cd9351873ba482bd Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 16:40:21 +0900 Subject: [PATCH 38/92] fix: enable line wrapping in Neovim configuration --- config/nvim/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 0ee2e6b5d..1cac75178 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -6,7 +6,7 @@ vim.opt.mouse = "" vim.opt.inccommand = "nosplit" vim.opt.splitbelow = true vim.opt.splitright = true -vim.opt.wrap = false +vim.opt.wrap = true vim.opt.textwidth = 0 vim.opt.expandtab = true vim.opt.smartindent = true @@ -1149,4 +1149,4 @@ require("nvim-tree").setup({ width = 30, }, }) -keymap("b", "", ":NvimTreeToggle", opts) +keymap("n", "b", ":NvimTreeToggle", opts) From 24869d916990d822384a9ebf2423a8580b2cd13b Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 16:40:56 +0900 Subject: [PATCH 39/92] feat: add key mapping to reload Neovim configuration --- config/nvim/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 1cac75178..1533885de 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -117,6 +117,7 @@ keymap("n", "cc", ":cclose", opts) keymap("n", "q", ":Bdelete", opts) keymap("n", "bad", ":%bwipeout!:intro", opts) keymap("n", "w", ":write", opts) +keymap("n", "r", ":source $MYVIMRC", opts) -- zz keymap("n", "n", "nzzzv", opts) From 8b12d9fcd4575b55c44598448f0f548dd85ae599 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 16:48:36 +0900 Subject: [PATCH 40/92] feat: add key mappings for exiting insert mode and navigating completion menu --- config/nvim/init.lua | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 1533885de..87d1603cc 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -159,6 +159,9 @@ for _, lhs in ipairs({ "-", "_", ",", ".", ";", ":", "/", "!", "?" }) do keymap("i", lhs, lhs .. "u", opts) end +-- exit insert mode with jj +keymap("i", "jj", "", opts) + --- --- UI --- @@ -262,7 +265,8 @@ require("copilot").setup({ ---@module 'blink.cmp' ---@type blink.cmp.Config -require("blink.cmp").setup({ +local cmp = require("blink.cmp") +cmp.setup({ keymap = { preset = "default" }, appearance = { nerd_font_variant = "mono", @@ -397,6 +401,24 @@ require("blink.cmp").setup({ }, }) +-- Use Tab to accept copilot/completions +keymap("i", "", function() + if vim.fn.pumvisible() == 1 then + return vim.api.nvim_replace_termcodes("", true, false, true) + else + return vim.api.nvim_replace_termcodes("", true, false, true) + end +end, { expr = true, noremap = true }) + +-- Shift+Tab to navigate up in completion menu +keymap("i", "", function() + if vim.fn.pumvisible() == 1 then + return vim.api.nvim_replace_termcodes("", true, false, true) + else + return vim.api.nvim_replace_termcodes("", true, false, true) + end +end, { expr = true, noremap = true }) + local function copen() if vim.fn.getqflist({ size = 0 }).size > 1 then vim.cmd("copen") From 8679a444db89e1e06c17045287f9514bc1255b06 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 16:51:02 +0900 Subject: [PATCH 41/92] fix: adjust copilot score offset and improve completion key mappings in init.lua --- config/nvim/init.lua | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 87d1603cc..5c80e2213 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -352,7 +352,7 @@ cmp.setup({ copilot = { name = "copilot", module = "blink-cmp-copilot", - score_offset = -10000, + score_offset = 1000, min_keyword_length = 0, async = true, override = { @@ -403,21 +403,22 @@ cmp.setup({ -- Use Tab to accept copilot/completions keymap("i", "", function() + -- Check if completion menu is visible (works for blink.cmp and built-in) if vim.fn.pumvisible() == 1 then - return vim.api.nvim_replace_termcodes("", true, false, true) - else - return vim.api.nvim_replace_termcodes("", true, false, true) - end -end, { expr = true, noremap = true }) - --- Shift+Tab to navigate up in completion menu -keymap("i", "", function() - if vim.fn.pumvisible() == 1 then - return vim.api.nvim_replace_termcodes("", true, false, true) - else - return vim.api.nvim_replace_termcodes("", true, false, true) + -- Since noselect is enabled, first select the first item, then accept + -- This ensures we accept the top suggestion (or navigate to copilot if needed) + local current_selection = vim.fn.complete_info({ "selected" }).selected + if current_selection == -1 then + -- Nothing selected, select first item + return vim.api.nvim_replace_termcodes("", true, false, true) + else + -- Something is selected, just accept it + return vim.api.nvim_replace_termcodes("", true, false, true) + end end -end, { expr = true, noremap = true }) + -- No completion menu visible, insert tab normally + return vim.api.nvim_replace_termcodes("", true, false, true) +end, { expr = true, noremap = true, silent = true }) local function copen() if vim.fn.getqflist({ size = 0 }).size > 1 then From 08085d28011d7939858a1b888dac7283352480ba Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 20:04:40 +0900 Subject: [PATCH 42/92] fix: update Neovim configuration to increase updatetime and enable backup --- config/nvim/init.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 5c80e2213..7af56a05c 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -1,7 +1,7 @@ vim.opt.compatible = false vim.opt.termsync = true vim.opt.hidden = true -vim.opt.updatetime = 250 +vim.opt.updatetime = 300 vim.opt.mouse = "" vim.opt.inccommand = "nosplit" vim.opt.splitbelow = true @@ -20,7 +20,7 @@ vim.opt.number = true vim.opt.relativenumber = true vim.opt.smoothscroll = true vim.opt.swapfile = false -vim.opt.backup = false +vim.opt.backup = true vim.opt.undofile = true vim.opt.undodir = vim.fn.stdpath("data") .. "undodir" vim.opt.hlsearch = false @@ -33,7 +33,6 @@ vim.opt.completeopt = { "menu", "menuone", "noselect" } vim.opt.colorcolumn = "80" vim.opt.backspace = { "indent", "eol", "start" } vim.opt.spelllang = { "en_us" } -vim.opt.spellfile = vim.uv.os_homedir() .. "/.spell.add" vim.opt.laststatus = 2 vim.opt.cursorline = true vim.opt.grepprg = "rg --vimgrep --smart-case --follow" From ce3ebdad4693d9b4fda61597505abbdc7855d4c7 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 20:10:13 +0900 Subject: [PATCH 43/92] refactor: remove unused gopls configuration and related key mappings from Neovim init.lua --- config/nvim/init.lua | 99 -------------------------------------------- 1 file changed, 99 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 7af56a05c..ec3862bc1 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -556,65 +556,6 @@ vim.api.nvim_create_autocmd("FileType", { end, }) -local get_gopls = function(bufnr) - local clients = vim.lsp.get_clients({ bufnr = bufnr }) - for _, c in ipairs(clients) do - if c.name == "gopls" then - return c - end - end - return nil -end - -vim.api.nvim_create_autocmd("FileType", { - pattern = "go", - callback = function() - local bufnr = vim.api.nvim_get_current_buf() - - vim.opt_local.formatoptions:append("jo") - vim.opt_local.makeprg = "go build ./..." - vim.opt_local.errorformat = "%A%f:%l:%c: %m,%-G%.%#" - - vim.api.nvim_buf_create_user_command(bufnr, "GoModTidy", function() - local gopls = get_gopls(bufnr) - if gopls == nil then - return - end - - vim.cmd([[ noautocmd wall ]]) - - local uri = vim.uri_from_bufnr(bufnr) - local arguments = { { URIs = { uri } } } - - local err = gopls:request_sync("workspace/executeCommand", { - command = "gopls.tidy", - arguments = arguments, - }, 30000, bufnr) - - if err ~= nil and type(err[1]) == "table" then - vim.notify("go mod tidy: " .. vim.inspect(err), vim.log.levels.ERROR) - return - end - end, { desc = "go mod tidy" }) - - local buf_opts = { noremap = true, silent = true, buffer = bufnr } - keymap("n", "", vim.cmd.GoModTidy, buf_opts) - keymap("n", "", function() - cclear() - vim.fn.jobstart("golangci-lint run --max-issues-per-linter=0 --max-same-issues=0 --new", { - stdout_buffered = true, - on_stdout = function(_, data) - if data and #data > 1 then - vim.schedule(function() - vim.fn.setqflist({}, " ", { lines = data }) - copen() - end) - end - end, - }) - end, buf_opts) - end, -}) vim.api.nvim_create_autocmd("FileType", { pattern = "markdown", @@ -1045,46 +986,6 @@ end local lspconfig = require("lspconfig") require("lspconfig.ui.windows").default_options.border = "none" -lspconfig.gopls.setup({ - capabilities = capabilities, - on_attach = on_attach, - settings = { - gopls = { - gofumpt = true, - codelenses = { - gc_details = true, - generate = true, - run_govulncheck = true, - test = true, - tidy = true, - upgrade_dependency = true, - }, - hints = { - assignVariableTypes = true, - compositeLiteralFields = true, - compositeLiteralTypes = true, - constantValues = true, - functionTypeParameters = true, - parameterNames = true, - rangeVariableTypes = true, - }, - analyses = { - nilness = true, - unusedparams = true, - unusedvariable = true, - unusedwrite = true, - useany = true, - }, - staticcheck = true, - directoryFilters = { "-.git", "-node_modules" }, - semanticTokens = true, - }, - }, - flags = { - debounce_text_changes = 150, - }, -}) - lspconfig.ts_ls.setup({ capabilities = capabilities, on_attach = on_attach, From 3470ff3f647d62c08eb435c1287ed626952e8134 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 20:12:05 +0900 Subject: [PATCH 44/92] refactor: remove conform formatter configuration from Neovim init.lua --- config/nvim/init.lua | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index ec3862bc1..0a0e99985 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -232,31 +232,6 @@ keymap("n", "os", ":OtherSplit", opts) require("neogen").setup({ snippet_engine = "nvim" }) keymap("n", "gco", ":Neogen", opts) -require("conform").setup({ - formatters_by_ft = { - css = { "prettier" }, - fish = { "fish_indent" }, - html = { "prettier" }, - javascript = { "prettier" }, - json = { "jq" }, - lua = { "stylua" }, - markdown = { "prettier" }, - sh = { "shfmt" }, - sql = { "pg_format", "sql_formatter" }, - templ = { "templ" }, - tf = { "terraform_fmt" }, - yaml = { "prettier" }, - ["_"] = { "trim_whitespace", "trim_newlines" }, - -- let only the lsp take care of these. - go = {}, - rust = {}, - zig = {}, - }, - format_after_save = { - lsp_fallback = true, - }, -}) - require("copilot").setup({ suggestion = { enabled = false }, panel = { enabled = false }, From 083c46bf0c862642bfe874a5a1e054eb2ede9231 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 20:22:06 +0900 Subject: [PATCH 45/92] feat: add key mapping to open terminal in Neovim --- config/nvim/init.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 0a0e99985..be72e28ea 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -118,6 +118,9 @@ keymap("n", "bad", ":%bwipeout!:intro", opts) keymap("n", "w", ":write", opts) keymap("n", "r", ":source $MYVIMRC", opts) +-- terminal +keymap("n", "j", ":terminal", opts) + -- zz keymap("n", "n", "nzzzv", opts) keymap("n", "N", "Nzzzv", opts) From 64bcfbf0b52a6185b5b20bdf572867828878ab6c Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 20:23:48 +0900 Subject: [PATCH 46/92] chore: add force option to symlinks for Neovim configuration files --- config/nvim/default.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/nvim/default.nix b/config/nvim/default.nix index a7968ee82..0cf4b5807 100644 --- a/config/nvim/default.nix +++ b/config/nvim/default.nix @@ -2,8 +2,10 @@ { home.file.".config/nvim/init.lua" = { source = config.lib.file.mkOutOfStoreSymlink ./init.lua; + force = true; }; home.file.".config/nvim/nvim-pack-lock.json" = { source = config.lib.file.mkOutOfStoreSymlink ./nvim-pack-lock.json; + force = true; }; } From 4da65707cd677f0c1e033796dc796034a6053244 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 20:24:05 +0900 Subject: [PATCH 47/92] feat: add key mapping to delete buffer in terminal mode for Neovim --- config/nvim/init.lua | 10 ++++++++++ home-manager/modules/codex/default.nix | 1 + 2 files changed, 11 insertions(+) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index be72e28ea..6f6d27ba5 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -534,6 +534,16 @@ vim.api.nvim_create_autocmd("FileType", { end, }) +vim.api.nvim_create_autocmd("TermOpen", { + callback = function() + keymap("t", "j", [[:bdelete!]], { + buffer = vim.api.nvim_get_current_buf(), + noremap = true, + silent = true, + }) + end, +}) + vim.api.nvim_create_autocmd("FileType", { pattern = "markdown", diff --git a/home-manager/modules/codex/default.nix b/home-manager/modules/codex/default.nix index 9daa0a939..a3336e7ba 100644 --- a/home-manager/modules/codex/default.nix +++ b/home-manager/modules/codex/default.nix @@ -2,5 +2,6 @@ { home.file.".codex/config.toml" = { source = config.lib.file.mkOutOfStoreSymlink ./config.toml; + force = true; }; } From 2a1f81bf7ad50d46540e6070804850400582740e Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 20:24:42 +0900 Subject: [PATCH 48/92] fix: update terminal key mapping to switch to previous window in Neovim --- config/nvim/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 6f6d27ba5..31e25a6f0 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -536,7 +536,7 @@ vim.api.nvim_create_autocmd("FileType", { vim.api.nvim_create_autocmd("TermOpen", { callback = function() - keymap("t", "j", [[:bdelete!]], { + keymap("t", "j", [[p]], { buffer = vim.api.nvim_get_current_buf(), noremap = true, silent = true, From 3c121a488cb8d4520e95b8be28f539eb5ca15e3b Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 20:25:01 +0900 Subject: [PATCH 49/92] fix: update terminal key mapping to open terminal in a split window in Neovim --- config/nvim/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 31e25a6f0..b35ee885f 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -119,7 +119,7 @@ keymap("n", "w", ":write", opts) keymap("n", "r", ":source $MYVIMRC", opts) -- terminal -keymap("n", "j", ":terminal", opts) +keymap("n", "j", ":10split | terminal", opts) -- zz keymap("n", "n", "nzzzv", opts) From d83fae2fc6459c02be95c8fd7872262531a83681 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 21:10:39 +0900 Subject: [PATCH 50/92] refactor: remove unused LSP autocommands and related configurations from Neovim init.lua --- config/nvim/init.lua | 263 ------------------------------------------- 1 file changed, 263 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index b35ee885f..7fe4a04c4 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -68,7 +68,6 @@ vim.pack.add({ -- CODING { src = "https://github.com/rgroli/other.nvim" }, { src = "https://github.com/danymat/neogen" }, - { src = "https://github.com/neovim/nvim-lspconfig" }, { src = "https://github.com/stevearc/conform.nvim" }, { src = "https://github.com/zbirenbaum/copilot.lua" }, { src = "https://github.com/rafamadriz/friendly-snippets" }, @@ -791,270 +790,8 @@ keymap("n", "ghi", function() telescope.extensions.gh.issues(ivy()) end, opts) --- LSP/autocommands inline replica of caarlos0's modules. -local function setup_lsp_autocommands() - local ms = require("vim.lsp.protocol").Methods - local group = vim.api.nvim_create_augroup("LSP", { clear = true }) - - ---@async - ---@param client vim.lsp.Client - ---@param bufnr number - local function organize_imports(client, bufnr) - ---@type lsp.Handler - ---@diagnostic disable-next-line: unused-local - local handler = function(err, result, context, config) - if err then - return - end - for _, r in pairs(result or {}) do - if r.edit then - local enc = client.offset_encoding or "utf-16" - vim.lsp.util.apply_workspace_edit(r.edit, enc) - elseif r.command and r.command.command then - client:exec_cmd(r.command, { bufnr = bufnr }) - end - end - vim.cmd([[noautocmd write]]) - end - - local win = vim.api.nvim_get_current_win() - local params = vim.lsp.util.make_range_params(win, client.offset_encoding or "utf-16") - params.context = { only = { "source.organizeImports" } } - client:request(ms.textDocument_codeAction, params, handler, bufnr) - end - - local function has_clients_with_method(bufnr, method) - local clients = vim.lsp.get_clients({ bufnr = bufnr, method = method }) - return #clients > 0 - end - - local function on_clients(bufnr, method, apply, filter) - local clients = vim.lsp.get_clients({ bufnr = bufnr, method = method }) - local predicate = filter or function() - return true - end - for _, client in ipairs(clients) do - if predicate(client) then - apply(client, bufnr) - end - end - end - - vim.api.nvim_create_autocmd("LspAttach", { - callback = function(args) - local client = vim.lsp.get_client_by_id(args.data.client_id) - if client == nil then - return - end - if client:supports_method(ms.textDocument_codeLens, vim.api.nvim_get_current_buf()) then - vim.lsp.inlay_hint.enable(true) - end - end, - }) - vim.api.nvim_create_autocmd("LspDetach", { - callback = function(args) - local client = vim.lsp.get_client_by_id(args.data.client_id) - if client == nil then - return - end - if client:supports_method(ms.textDocument_codeLens, vim.api.nvim_get_current_buf()) then - vim.lsp.codelens.clear(client.id) - end - end, - group = group, - }) - - vim.api.nvim_create_autocmd({ "BufWritePre" }, { - callback = function() - local format = function(client, bufnr) - if client.server_capabilities.documentFormattingProvider then - vim.lsp.buf.format({ - bufnr = bufnr, - timeout_ms = 5000, - id = client.id, - }) - end - end - on_clients(vim.api.nvim_get_current_buf(), ms.textDocument_codeAction, format) - end, - group = group, - }) - - vim.api.nvim_create_autocmd({ "BufWritePost" }, { - callback = function() - local bufnr = vim.api.nvim_get_current_buf() - local filter = function(client) - return client.name ~= "lua_ls" - end - on_clients(bufnr, ms.textDocument_codeAction, organize_imports, filter) - end, - group = group, - }) - - vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", "InsertLeave" }, { - callback = function() - if has_clients_with_method(0, ms.textDocument_codeLens) then - vim.lsp.codelens.refresh({ bufnr = 0 }) - end - end, - group = group, - }) - - vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { - callback = function() - if has_clients_with_method(0, ms.textDocument_documentHighlight) then - vim.lsp.buf.document_highlight() - end - end, - group = group, - }) - - vim.api.nvim_create_autocmd({ "CursorMoved" }, { - callback = function() - if has_clients_with_method(0, ms.textDocument_documentHighlight) then - vim.lsp.buf.clear_references() - end - end, - group = group, - }) -end -setup_lsp_autocommands() -local capabilities = require("blink.cmp").get_lsp_capabilities({ - workspace = { - didChangeWatchedFiles = { - dynamicRegistration = true, - relativePatternSupport = true, - }, - }, -}, true) - ----@param client vim.lsp.Client ----@param bufnr number -local on_attach = function(client, bufnr) - local keymap_lsp = function(lhs, rhs) - vim.keymap.set("n", lhs, rhs, { - noremap = true, - silent = true, - buffer = bufnr, - }) - end - - local telescope_wrap = function(action) - return function() - local ivy_theme = require("telescope.themes").get_ivy() - require("telescope.builtin")["lsp_" .. action](ivy_theme) - end - end - - keymap_lsp("gd", telescope_wrap("definitions")) - keymap_lsp("grr", telescope_wrap("references")) - keymap_lsp("gO", telescope_wrap("document_symbols")) - keymap_lsp("gri", telescope_wrap("implementations")) - keymap_lsp("gD", vim.lsp.buf.declaration) - keymap_lsp("K", vim.lsp.buf.hover) - keymap_lsp("D", telescope_wrap("type_definitions")) - keymap_lsp("grl", vim.lsp.codelens.run) - keymap_lsp("gl", vim.diagnostic.open_float) - keymap_lsp("[d", function() - vim.diagnostic.jump({ count = -1 }) - vim.cmd("norm zz") - end) - keymap_lsp("]d", function() - vim.diagnostic.jump({ count = 1 }) - vim.cmd("norm zz") - end) - - keymap_lsp("v", function() - vim.cmd("vsplit | lua vim.lsp.buf.definition()") - vim.cmd("norm zz") - end) -end - -local lspconfig = require("lspconfig") -require("lspconfig.ui.windows").default_options.border = "none" -lspconfig.ts_ls.setup({ - capabilities = capabilities, - on_attach = on_attach, - settings = { - javascript = { - inlayHints = { - includeInlayEnumMemberValueHints = true, - includeInlayFunctionLikeReturnTypeHints = true, - includeInlayFunctionParameterTypeHints = true, - includeInlayParameterNameHints = "all", - includeInlayParameterNameHintsWhenArgumentMatchesName = true, - includeInlayPropertyDeclarationTypeHints = true, - includeInlayVariableTypeHints = true, - }, - }, - typescript = { - inlayHints = { - includeInlayEnumMemberValueHints = true, - includeInlayFunctionLikeReturnTypeHints = true, - includeInlayFunctionParameterTypeHints = true, - includeInlayParameterNameHints = "all", - includeInlayParameterNameHintsWhenArgumentMatchesName = true, - includeInlayPropertyDeclarationTypeHints = true, - includeInlayVariableTypeHints = true, - }, - }, - }, -}) - -for _, lsp in ipairs({ - "bashls", - "clangd", - "cssls", - "jsonls", - "pylsp", - "rust_analyzer", - "taplo", - "templ", - "terraformls", - "tflint", - "zls", -}) do - lspconfig[lsp].setup({ - on_attach = on_attach, - capabilities = capabilities, - }) -end - -for _, lsp in ipairs({ "html", "htmx" }) do - lspconfig[lsp].setup({ - capabilities = capabilities, - on_attach = on_attach, - filetypes = { "html", "templ" }, - }) -end - -lspconfig.tailwindcss.setup({ - on_attach = on_attach, - capabilities = capabilities, - filetypes = { "html", "templ", "javascript" }, - settings = { - tailwindCSS = { - includeLanguages = { - templ = "html", - }, - }, - }, -}) - -lspconfig.yamlls.setup({ - capabilities = capabilities, - on_attach = on_attach, - settings = { - yaml = { - schemaStore = { - url = "https://www.schemastore.org/api/json/catalog.json", - enable = true, - }, - }, - }, -}) require("nvim-tree").setup({ view = { From be543b531b9d614f9c1631d5440c1996b91e0d77 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Sun, 23 Nov 2025 21:11:01 +0900 Subject: [PATCH 51/92] refactor: clean up whitespace in Neovim init.lua --- config/nvim/init.lua | 3 --- 1 file changed, 3 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 7fe4a04c4..ae63aff45 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -790,9 +790,6 @@ keymap("n", "ghi", function() telescope.extensions.gh.issues(ivy()) end, opts) - - - require("nvim-tree").setup({ view = { width = 30, From fed681c6ceefb89662c541c9873f28c76f2b0c72 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 11:16:27 +0900 Subject: [PATCH 52/92] refactor: enhance Makefile help documentation and streamline target descriptions --- .github/workflows/lua.yml | 55 ++++++++++++ Makefile | 170 ++++++++++++++++++++++++-------------- 2 files changed, 165 insertions(+), 60 deletions(-) create mode 100644 .github/workflows/lua.yml diff --git a/.github/workflows/lua.yml b/.github/workflows/lua.yml new file mode 100644 index 000000000..2d84811f3 --- /dev/null +++ b/.github/workflows/lua.yml @@ -0,0 +1,55 @@ +name: Lua +on: + push: + branches: + - main + pull_request: + branches: + - main +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.sha }} + cancel-in-progress: true +jobs: + lua-neovim: + runs-on: ubuntu-latest + timeout-minutes: 300 + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@v1.3.1 + with: + tool-cache: false + - name: Install Nix + uses: cachix/install-nix-action@v31 + with: + github_access_token: ${{ secrets.GITHUB_TOKEN }} + - name: Install Neovim + run: nix profile install nixpkgs#neovim + - name: Validate Neovim Configuration + run: make lua-check-neovim + lua-hammerspoon: + runs-on: macos-latest + timeout-minutes: 300 + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Install Nix + uses: cachix/install-nix-action@v31 + with: + github_access_token: ${{ secrets.GITHUB_TOKEN }} + - name: Validate Hammerspoon Configuration + run: make lua-check-hammerspoon + lua-check: + if: always() + needs: + - lua-neovim + - lua-hammerspoon + runs-on: ubuntu-latest + timeout-minutes: 3 + steps: + - name: Alls Green + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} + diff --git a/Makefile b/Makefile index 5c7bc2efe..9b3483e10 100644 --- a/Makefile +++ b/Makefile @@ -88,66 +88,61 @@ DARWIN_REBUILD := $(shell command -v darwin-rebuild 2>/dev/null || echo "./resul # Default target .PHONY: default -default: help +default: help ## Default target (shows help). -# Help target +# ==================================================================================== +# HELP +# ==================================================================================== .PHONY: help -help: - @echo "Available targets:" - @echo " install - Set up full environment" - @echo " setup - Basic Nix setup" - @echo " setup-dev - Set up local development environment (Nix + submodules + shell)" - @echo " dev - Enter the Nix dev shell" - @echo " build - Build Nix configuration" - @echo " switch - Apply Nix configuration" - @echo " update - Update Nix flake and configurations" - @echo " format - Format Nix files" - @echo " format-check - Check Nix formatting" - @echo " docker-build - Build the Docker image" - @echo " switch-HOST - Switch to a named host configuration (e.g., make switch-galactica)" - @echo " encrypt-key-HOST - Encrypt a key for a named host (e.g., make encrypt-key-galactica KEY_FILE=~/.ssh/id_ed25519)" - @echo " decrypt-key-HOST - Decrypt a key for a named host (e.g., make decrypt-key-galactica KEY_FILE=id_ed25519)" - @echo " rekey-HOST - Rekey all secrets for a named host (e.g., make rekey-galactica)" +help: ## Show this help message. + @echo "Usage: make " + @echo + @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z0-9_-]+:.*?## / {printf " \033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) ##@ General .PHONY: install -install: setup update shell-install +install: setup update shell-install ## Set up full environment (setup, update, shell-install). .PHONY: build -build: nix-build +build: nix-build ## Build Nix configuration. .PHONY: check -check: nix-check +check: ## Run all validation checks (nix, format, lua). + @echo "🔍 Running all validation checks..." + @$(MAKE) nix-flake-check + @$(MAKE) nix-format-check + @$(MAKE) lua-check + @echo "✅ All checks passed" .PHONY: flake-check -flake-check: nix-flake-check +flake-check: nix-flake-check ## Check Nix flake configuration (alias for nix-flake-check). .PHONY: format -format: nix-format +format: nix-format ## Format Nix files (alias for nix-format). .PHONY: setup -setup: nix-setup +setup: nix-setup ## Basic Nix setup (alias for nix-setup). .PHONY: setup-dev -setup-dev: nix-setup git-submodule-sync shell-install +setup-dev: nix-setup git-submodule-sync shell-install ## Set up local development environment (Nix + submodules + shell). .PHONY: switch -switch: nix-switch +switch: nix-switch ## Apply Nix configuration (alias for nix-switch). .PHONY: update -update: nix-update shell-update neovim-update +update: nix-update shell-update neovim-update ## Update Nix flake and configurations. .PHONY: dev -dev: nix-develop +dev: nix-develop ## Enter the Nix dev shell (alias for nix-develop). ##@ Nix Setup .PHONY: nix-setup -nix-setup: nix-install nix-check nix-connect +nix-setup: nix-install nix-check nix-connect ## Set up Nix environment (install, check, connect). .PHONY: nix-connect -nix-connect: +nix-connect: ## Ensure Nix daemon is running. @echo "🔌 Ensuring Nix daemon is running for $(NIX_CONFIG_TYPE) on $(OS) $(ARCH) for USER=$(NIX_USERNAME)" @if [ "$(OS)" = "Darwin" ]; then \ sudo launchctl unload /Library/LaunchDaemons/org.nixos.nix-daemon.plist 2>/dev/null || true; \ @@ -176,7 +171,7 @@ nix-connect: @echo "✅ Nix daemon should now be active!" .PHONY: nix-check -nix-check: +nix-check: ## Verify Nix environment setup. @echo "🔍 Verifying Nix environment setup for $(NIX_CONFIG_TYPE) on $(OS) $(ARCH) for USER=$(NIX_USERNAME)" @if [ "$(NIX_ENV)" = "not_found" ]; then \ echo "❌ Nix environment not found. Please ensure Nix is installed and run:"; \ @@ -185,11 +180,11 @@ nix-check: @echo "✅ Nix environment found!" .PHONY: nix-develop -nix-develop: +nix-develop: ## Enter the Nix development shell. $(NIX_ALLOW_UNFREE) $(NIX_EXEC) develop $(NIX_FLAGS) .PHONY: nix-install -nix-install: +nix-install: ## Install Nix if not already installed. @if [ "$(NIX_ENV)" = "not_found" ]; then \ echo "🚀 Installing Nix environment for $(NIX_CONFIG_TYPE) on $(OS) $(ARCH) for USER=$(NIX_USERNAME)"; \ curl -L https://nixos.org/nix/install | sh; \ @@ -199,10 +194,10 @@ nix-install: ##@ Nix .PHONY: nix-update -nix-update: nix-flake-update nix-build nix-switch +nix-update: nix-flake-update nix-build nix-switch ## Update Nix flake, build, and switch. .PHONY: nix-backup -nix-backup: +nix-backup: ## Backup configuration files. @echo "🗄️ Backing up configuration files for $(NIX_CONFIG_TYPE) on $(OS) $(ARCH) for USER=$(NIX_USERNAME)" @backup_dir="$$HOME/.config/backups/$(shell date +%Y%m%d_%H%M%S)"; \ mkdir -p "$$backup_dir"; \ @@ -212,7 +207,7 @@ nix-backup: fi .PHONY: nix-build -nix-build: nix-connect +nix-build: nix-connect ## Build Nix configuration. @echo "🏗️ Building Nix configuration for $(NIX_CONFIG_TYPE) on $(OS) $(ARCH) for USER=$(NIX_USERNAME)" @if [ "$$CI" = "true" ] || [ "$$IN_DOCKER" = "true" ]; then \ echo "🤖 Running in CI/Docker environment"; \ @@ -244,13 +239,13 @@ nix-build: nix-connect @echo "✅ Nix configuration built successfully!" .PHONY: nix-flake-check -nix-flake-check: +nix-flake-check: ## Check Nix flake configuration. @echo "🔍 Checking Nix flake configuration..." @$(NIX_ALLOW_UNFREE) $(NIX_EXEC) flake check --all-systems --impure $(NIX_FLAGS) @echo "✅ Nix flake check completed successfully" .PHONY: nix-flake-update -nix-flake-update: nix-connect +nix-flake-update: nix-connect ## Update flake.lock file. @echo "♻️ Refreshing flake.lock file..." @if [ "$$CI" = "true" ] || [ "$$IN_DOCKER" = "true" ]; then \ echo "Bypassing flake update in CI/Docker"; \ @@ -260,25 +255,25 @@ nix-flake-update: nix-connect @echo "✅ flake.lock updated!" .PHONY: nix-format -nix-format: nix-format-clear-cache +nix-format: nix-format-clear-cache ## Format Nix files. @echo "🧹 Formatting Nix files..." @$(NIX_EXEC) fmt -- --clear-cache @echo "✅ Formatting complete" .PHONY: nix-format-clear-cache -nix-format-clear-cache: +nix-format-clear-cache: ## Clear Nix format cache. @echo "🧹 Clearing Nix cache..." @$(NIX_EXEC) fmt -- --clear-cache @echo "✅ Cache cleared" .PHONY: nix-format-check -nix-format-check: nix-format-clear-cache +nix-format-check: nix-format-clear-cache ## Check Nix file formatting. @echo "🔍 Checking Nix file formatting..." @$(NIX_EXEC) fmt -- --fail-on-change @echo "✅ All Nix files are properly formatted" .PHONY: nix-switch -nix-switch: +nix-switch: ## Activate Nix configuration. @echo "🔧 Activating Nix configuration for $(NIX_CONFIG_TYPE) on $(OS) $(ARCH) for USER=$(NIX_USERNAME)" @if [ "$$CI" = "true" ] || [ "$$IN_DOCKER" = "true" ]; then \ if [ "$(OS)" = "Darwin" ]; then \ @@ -318,7 +313,7 @@ nix-switch: @echo "✅ Nix configuration activated successfully!" .PHONY: nix-switch-vm -nix-switch-vm: +nix-switch-vm: ## Switch NixOS configuration in VM. @if [ ! -f "./result/bin/run-nixos-vm" ]; then \ echo "❌ VM binary not found at ./result/bin/run-nixos-vm"; \ exit 0; \ @@ -331,7 +326,7 @@ nix-switch-vm: ##@ Nix Offline Mode .PHONY: nix-build-offline -nix-build-offline: +nix-build-offline: ## Build Nix configuration in offline mode. @echo "🏗️ Building Nix configuration in offline mode" @if [ "$(OS)" = "Darwin" ]; then \ NIX_OFFLINE=1 $(NIX_ALLOW_UNFREE) $(NIX_EXEC) build .#darwinConfigurations.galactica.system $(NIX_FLAGS) --impure --no-update-lock-file --offline --show-trace; \ @@ -346,7 +341,7 @@ nix-build-offline: @echo "✅ Nix configuration built successfully in offline mode!" .PHONY: nix-switch-offline -nix-switch-offline: +nix-switch-offline: ## Activate Nix configuration in offline mode. @echo "🔧 Activating Nix configuration in offline mode" @if [ "$(OS)" = "Darwin" ]; then \ NIX_OFFLINE=1 sudo $(NIX_ALLOW_UNFREE) $(DARWIN_REBUILD) switch --flake .#galactica --impure --offline; \ @@ -360,7 +355,8 @@ nix-switch-offline: fi @echo "✅ Nix configuration activated successfully in offline mode!" -nix-setup-offline: +.PHONY: nix-setup-offline +nix-setup-offline: ## Set up offline environment. @echo "🔧 Setting up offline environment" @mkdir -p ~/.cache/nix @echo "✅ Offline environment setup complete" @@ -370,25 +366,25 @@ nix-setup-offline: ##@ Named Hosts Specific Targets .PHONY: switch-% -switch-%: +switch-%: ## Switch to a named host configuration (e.g., make switch-galactica). @$(MAKE) nix-switch HOST=$* .PHONY: encrypt-key-% -encrypt-key-%: +encrypt-key-%: ## Encrypt a key for a named host (e.g., make encrypt-key-galactica KEY_FILE=~/.ssh/id_ed25519). @$(MAKE) encrypt-key HOST=$* KEY_FILE=$(KEY_FILE) .PHONY: decrypt-key-% -decrypt-key-%: +decrypt-key-%: ## Decrypt a key for a named host (e.g., make decrypt-key-galactica KEY_FILE=id_ed25519). @$(MAKE) decrypt-key HOST=$* KEY_FILE=$(KEY_FILE) .PHONY: rekey-% -rekey-%: +rekey-%: ## Rekey all secrets for a named host (e.g., make rekey-galactica). @$(MAKE) rekey HOST=$* ##@ Agenix Secrets Management .PHONY: encrypt-key -encrypt-key: +encrypt-key: ## Encrypt a key file for a host (requires HOST and KEY_FILE variables). @if [ -z "$(HOST)" ]; then \ echo "❌ HOST variable is not set. Usage: make encrypt-key HOST= KEY_FILE="; \ exit 1; \ @@ -402,7 +398,7 @@ encrypt-key: @echo "✅ Key encrypted to named-hosts/$(HOST)/keys/$(shell basename $(KEY_FILE)).age" .PHONY: decrypt-key -decrypt-key: +decrypt-key: ## Decrypt a key file for a host (requires HOST variable, optional KEY_FILE). @if [ -z "$(HOST)" ]; then \ echo "❌ HOST variable is not set. Usage: make decrypt-key HOST= KEY_FILE="; \ exit 1; \ @@ -414,7 +410,7 @@ decrypt-key: @cd named-hosts/$(HOST) && agenix -d keys/$(KEY_FILE).age .PHONY: rekey -rekey: +rekey: ## Rekey all secrets for a host (requires HOST variable). @if [ -z "$(HOST)" ]; then \ echo "❌ HOST variable is not set. Usage: make rekey HOST="; \ exit 1; \ @@ -426,7 +422,7 @@ rekey: ##@ Shell Installation .PHONY: shell-install -shell-install: +shell-install: ## Set up Fish shell as default shell. @echo "🐠 Setting up Fish shell..." @if command -v fish > /dev/null; then \ fish_path=$$(command -v fish); \ @@ -446,12 +442,12 @@ shell-install: fi .PHONY: shell-update -shell-update: shell-install +shell-update: shell-install ## Update Fish shell setup (alias for shell-install). ##@ Docker .PHONY: docker-build -docker-build: +docker-build: ## Build Docker image. @echo "🐳 Building Docker image: $(DOCKER_IMAGE_LATEST) and $(DOCKER_IMAGE_TAGGED)..." @docker build -t $(DOCKER_IMAGE_LATEST) -t $(DOCKER_IMAGE_TAGGED) -f Dockerfile . @echo "✅ Docker image built: $(DOCKER_IMAGE_LATEST) and $(DOCKER_IMAGE_TAGGED)" @@ -459,7 +455,7 @@ docker-build: ##@ Neovim .PHONY: neovim-dev -neovim-dev: +neovim-dev: ## Set up local Neovim development environment. @echo "🔧 Setting up local Neovim development environment..." @if [ -L "$(HOME)/.config/nvim" ]; then \ rm "$(HOME)/.config/nvim"; \ @@ -471,22 +467,76 @@ neovim-dev: @echo "🚧 To restore the Nix-managed version, run 'make switch'" .PHONY: neovim-update -neovim-update: +neovim-update: ## Update Neovim plugins. @echo "📦 Updating neovim plugins..." @nvim --headless +"lua vim.pack.update()" +qa @echo "✅ Neovim plugins updated" .PHONY: neovim-sync -neovim-sync: +neovim-sync: ## Sync Neovim plugins. @echo "🔄 Syncing neovim plugins..." @nvim --headless +"lua vim.pack.sync()" +qa @echo "✅ Neovim plugins synced" +##@ Lua + +.PHONY: lua-check +lua-check: lua-check-neovim lua-check-hammerspoon ## Check all Lua configurations (Neovim and Hammerspoon). + @echo "✅ All Lua configurations validated" + +.PHONY: lua-check-neovim +lua-check-neovim: ## Check Neovim configuration. + @echo "🔍 Checking Neovim configuration..." + @if ! command -v nvim >/dev/null 2>&1; then \ + echo "⚠️ Neovim is not installed or not in PATH"; \ + exit 1; \ + fi + @NVIM_CONFIG="$(PWD)/config/nvim/init.lua"; \ + if [ ! -f "$$NVIM_CONFIG" ]; then \ + echo "⚠️ Could not find Neovim configuration at $$NVIM_CONFIG"; \ + exit 1; \ + fi + @echo "📝 Validating Neovim configuration syntax..." + @mkdir -p ~/.config/nvim + @ln -sf "$(PWD)/config/nvim/init.lua" ~/.config/nvim/init.lua + @if [ -f "$(PWD)/config/nvim/nvim-pack-lock.json" ]; then \ + ln -sf "$(PWD)/config/nvim/nvim-pack-lock.json" ~/.config/nvim/nvim-pack-lock.json; \ + fi + @nvim --headless -c "lua dofile('$(PWD)/config/nvim/init.lua')" -c "qa" 2>&1; \ + EXIT_CODE=$$?; \ + if [ $$EXIT_CODE -eq 0 ]; then \ + echo "✅ Neovim configuration is valid"; \ + else \ + echo "❌ Neovim configuration has errors (exit code: $$EXIT_CODE)"; \ + exit $$EXIT_CODE; \ + fi + +.PHONY: lua-check-hammerspoon +lua-check-hammerspoon: ## Check Hammerspoon configuration. + @echo "🔍 Checking Hammerspoon configuration..." + @HAMMERSPOON_CONFIG="$(PWD)/config/hammerspoon/init.lua"; \ + if [ ! -f "$$HAMMERSPOON_CONFIG" ]; then \ + echo "⚠️ Could not find Hammerspoon configuration at $$HAMMERSPOON_CONFIG"; \ + exit 1; \ + fi + @echo "📝 Validating Hammerspoon configuration syntax..." + @if command -v lua >/dev/null 2>&1; then \ + lua -e "assert(loadfile('$(PWD)/config/hammerspoon/init.lua'))" && \ + echo "✅ Hammerspoon configuration is valid" || \ + (echo "❌ Hammerspoon configuration has syntax errors" && exit 1); \ + elif command -v nix >/dev/null 2>&1; then \ + nix run nixpkgs#lua -- -e "assert(loadfile('$(PWD)/config/hammerspoon/init.lua'))" && \ + echo "✅ Hammerspoon configuration is valid" || \ + (echo "❌ Hammerspoon configuration has syntax errors" && exit 1); \ + else \ + echo "⚠️ Neither lua nor nix is available for syntax checking"; \ + exit 1; \ + fi ##@ Git Submodule .PHONY: git-submodule-sync -git-submodule-sync: +git-submodule-sync: ## Sync and update git submodules. @echo "🔁 Syncing and updating git submodules..." @git submodule sync @git submodule update --init --recursive From 109891f3568570eca0fe71d05b9b41cc2f4ec892 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 11:16:46 +0900 Subject: [PATCH 53/92] chore: remove trailing whitespace in GitHub Actions workflow file --- .github/workflows/lua.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/lua.yml b/.github/workflows/lua.yml index 2d84811f3..ae3ba508b 100644 --- a/.github/workflows/lua.yml +++ b/.github/workflows/lua.yml @@ -52,4 +52,3 @@ jobs: uses: re-actors/alls-green@release/v1 with: jobs: ${{ toJSON(needs) }} - From 3d7885d4cd505b5eb8c84f663ed7df9f282c8a4d Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 11:22:39 +0900 Subject: [PATCH 54/92] refactor: clean up whitespace and ensure newline at end of nvim-pack-lock.json --- config/nvim/init.lua | 7 +++---- config/nvim/nvim-pack-lock.json | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index ae63aff45..3709683f0 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -543,7 +543,6 @@ vim.api.nvim_create_autocmd("TermOpen", { end, }) - vim.api.nvim_create_autocmd("FileType", { pattern = "markdown", callback = function() @@ -791,8 +790,8 @@ keymap("n", "ghi", function() end, opts) require("nvim-tree").setup({ - view = { - width = 30, - }, + view = { + width = 30, + }, }) keymap("n", "b", ":NvimTreeToggle", opts) diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json index 9812f3bbf..4fb3a4189 100644 --- a/config/nvim/nvim-pack-lock.json +++ b/config/nvim/nvim-pack-lock.json @@ -170,4 +170,4 @@ "src": "https://github.com/christoomey/vim-tmux-navigator" } } -} \ No newline at end of file +} From f209774304ddcc60601cd34b926c0bfecbd0dcea Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 11:35:45 +0900 Subject: [PATCH 55/92] feat: enhance Neovim init.lua with organized sections and comprehensive key mappings --- config/nvim/init.lua | 245 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 237 insertions(+), 8 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 3709683f0..608d278d4 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -1,3 +1,6 @@ +-- ==================================================================================== +-- VIM OPTIONS +-- ==================================================================================== vim.opt.compatible = false vim.opt.termsync = true vim.opt.hidden = true @@ -45,6 +48,9 @@ vim.opt.winborder = "none" vim.hl.priorities.semantic_tokens = 10 vim.g.fugitive_legacy_commands = 0 +-- ==================================================================================== +-- PLUGIN INSTALLATION +-- ==================================================================================== vim.pack.add({ -- UI { src = "https://github.com/nvim-tree/nvim-web-devicons" }, @@ -99,27 +105,52 @@ vim.pack.add({ { src = "https://github.com/RRethy/nvim-treesitter-endwise" }, }) +-- ==================================================================================== +-- KEYMAPS +-- ==================================================================================== local opts = { noremap = true, silent = true } local keymap = vim.keymap.set +-- @keymap : Set as leader key --Remap space as leader key keymap("", "", "", opts) vim.g.mapleader = " " vim.g.maplocalleader = " " +-- ==================================================================================== +-- QUICKFIX LISTS +-- ==================================================================================== +-- @keymap co: Open quickfix list +-- @keymap cc: Close quickfix list -- quicklists keymap("n", "co", ":copen", opts) keymap("n", "cc", ":cclose", opts) +-- ==================================================================================== +-- BUFFER AND FILE OPERATIONS +-- ==================================================================================== +-- @keymap q: Close current buffer +-- @keymap bad: Wipe all buffers +-- @keymap w: Write file +-- @keymap r: Reload Neovim configuration +-- @keymap h: Show help (all keymaps and commands) -- write, buffer killing keymap("n", "q", ":Bdelete", opts) keymap("n", "bad", ":%bwipeout!:intro", opts) keymap("n", "w", ":write", opts) keymap("n", "r", ":source $MYVIMRC", opts) +keymap("n", "h", ":Help", opts) +-- ==================================================================================== +-- TERMINAL +-- ==================================================================================== +-- @keymap j: Open terminal in split -- terminal keymap("n", "j", ":10split | terminal", opts) +-- ==================================================================================== +-- NAVIGATION +-- ==================================================================================== -- zz keymap("n", "n", "nzzzv", opts) keymap("n", "N", "Nzzzv", opts) @@ -128,20 +159,35 @@ keymap("n", "", "zz", opts) keymap("n", "", "zz", opts) keymap("n", "", "zz", opts) +-- ==================================================================================== +-- CLIPBOARD OPERATIONS +-- ==================================================================================== +-- @keymap y: Yank to system clipboard -- system clipboard integration keymap({ "n", "v" }, "y", '"+y', opts) +-- @keymap py: Copy current file path to clipboard -- copy the current file path keymap("n", "py", ':let @" = expand("%:p")', opts) +-- @keymap d: Delete to blackhole register -- delete to blackhole keymap({ "n", "v" }, "d", '"_d', opts) +-- ==================================================================================== +-- GIT OPERATIONS +-- ==================================================================================== +-- @keymap gs: Open Git status in new tab +-- @keymap : Open Git mergetool in new tab +-- @keymap gd: Preview hunk inline -- git keymap("n", "gs", ":tab Git", opts) keymap("n", "", ":tab Git mergetool", opts) keymap("n", "gd", ":Gitsign preview_hunk_inline", opts) +-- ==================================================================================== +-- VISUAL MODE OPERATIONS +-- ==================================================================================== -- indent keymap("v", "<", "", ">gv", opts) @@ -155,17 +201,21 @@ keymap("v", "p", '"_dP', opts) keymap("x", "K", ":move '<-2gv-gv", opts) keymap("x", "J", ":move '>+1gv-gv", opts) +-- ==================================================================================== +-- INSERT MODE OPERATIONS +-- ==================================================================================== -- in insert mode, adds new undo points after more some chars: for _, lhs in ipairs({ "-", "_", ",", ".", ";", ":", "/", "!", "?" }) do keymap("i", lhs, lhs .. "u", opts) end +-- @keymap jj: Exit insert mode -- exit insert mode with jj keymap("i", "jj", "", opts) ---- ---- UI ---- +-- ==================================================================================== +-- UI CONFIGURATION +-- ==================================================================================== local bg0 = "#1b1b1b" vim.cmd("colorscheme dracula") @@ -203,6 +253,9 @@ require("auto-hlsearch").setup({}) require("gitsigns").setup({}) require("git-conflict").setup({}) +-- ==================================================================================== +-- DIAGNOSTICS +-- ==================================================================================== -- setup diagnostics vim.diagnostic.config({ underline = true, @@ -210,6 +263,7 @@ vim.diagnostic.config({ severity_sort = true, }) +-- @keymap xx: Open diagnostics in quickfix keymap("n", "xx", vim.diagnostic.setqflist, opts) -- set up diagnostic signs @@ -226,14 +280,24 @@ vim.diagnostic.config({ }, }) +-- ==================================================================================== +-- CODE NAVIGATION +-- ==================================================================================== +-- @keymap oo: Navigate to related file (other.nvim) +-- @keymap ov: Navigate to related file in vertical split +-- @keymap os: Navigate to related file in horizontal split require("other-nvim").setup({ mappings = { "golang" } }) keymap("n", "oo", ":Other", opts) keymap("n", "ov", ":OtherVSplit", opts) keymap("n", "os", ":OtherSplit", opts) +-- @keymap gco: Generate code annotation (neogen) require("neogen").setup({ snippet_engine = "nvim" }) keymap("n", "gco", ":Neogen", opts) +-- ==================================================================================== +-- COMPLETION AND COPILOT +-- ==================================================================================== require("copilot").setup({ suggestion = { enabled = false }, panel = { enabled = false }, @@ -377,6 +441,7 @@ cmp.setup({ }, }) +-- @keymap : Accept copilot/completion (selects first if none selected) -- Use Tab to accept copilot/completions keymap("i", "", function() -- Check if completion menu is visible (works for blink.cmp and built-in) @@ -396,6 +461,9 @@ keymap("i", "", function() return vim.api.nvim_replace_termcodes("", true, false, true) end, { expr = true, noremap = true, silent = true }) +-- ==================================================================================== +-- UTILITY FUNCTIONS +-- ==================================================================================== local function copen() if vim.fn.getqflist({ size = 0 }).size > 1 then vim.cmd("copen") @@ -408,9 +476,14 @@ local function cclear() vim.fn.setqflist({}, "r") end +-- @command Finder: Open current file directory in Finder/file explorer -- Opens the directory of the current file in Finder/file explorer. vim.api.nvim_create_user_command("Finder", "!open %:h", {}) +-- ==================================================================================== +-- AUTOCMDS +-- ==================================================================================== +-- Check for file changes on BufEnter, CursorHold, CursorHoldI, and FocusGained vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", @@ -421,20 +494,20 @@ vim.api.nvim_create_autocmd({ command = "if mode() != 'c' | checktime | endif", }) --- resize splits if window got resized +-- Resize splits if window got resized vim.api.nvim_create_autocmd({ "VimResized" }, { callback = function() vim.cmd("tabdo wincmd =") end, }) +-- Start in insert mode when opening git commit messages vim.api.nvim_create_autocmd("FileType", { pattern = "gitcommit", command = "startinsert", }) --- ensure the parent folder exists, so it gets properly added to the lsp --- context and everything just works. +-- Ensure the parent folder exists when creating new files (for LSP context) vim.api.nvim_create_autocmd("BufNewFile", { pattern = "*", callback = function() @@ -446,7 +519,7 @@ vim.api.nvim_create_autocmd("BufNewFile", { end, }) --- Highlight on yank +-- Highlight on yank (briefly highlight yanked text) -- See `:help vim.highlight.on_yank()` vim.api.nvim_create_autocmd("TextYankPost", { pattern = "*", @@ -455,7 +528,7 @@ vim.api.nvim_create_autocmd("TextYankPost", { end, }) --- Open help window in a vertical split to the right. +-- Open help window in a vertical split to the right vim.api.nvim_create_autocmd("BufWinEnter", { pattern = { "*.txt" }, callback = function() @@ -465,6 +538,7 @@ vim.api.nvim_create_autocmd("BufWinEnter", { end, }) +-- Add keymaps for git filetype buffers vim.api.nvim_create_autocmd("FileType", { pattern = "git", callback = function() @@ -474,6 +548,7 @@ vim.api.nvim_create_autocmd("FileType", { end, }) +-- Configure fugitive buffers with git keymaps (push, pull, commit, etc.) vim.api.nvim_create_autocmd("FileType", { pattern = "fugitive", callback = function() @@ -514,6 +589,7 @@ vim.api.nvim_create_autocmd("FileType", { end, }) +-- Enable spell check and set textwidth for git commit messages vim.api.nvim_create_autocmd("FileType", { pattern = "gitcommit", callback = function() @@ -522,6 +598,7 @@ vim.api.nvim_create_autocmd("FileType", { end, }) +-- Add q keymap to close quickfix and help buffers vim.api.nvim_create_autocmd("FileType", { pattern = { "qf", "help" }, callback = function() @@ -533,6 +610,7 @@ vim.api.nvim_create_autocmd("FileType", { end, }) +-- Add keymap to exit terminal mode and switch to previous window vim.api.nvim_create_autocmd("TermOpen", { callback = function() keymap("t", "j", [[p]], { @@ -543,6 +621,7 @@ vim.api.nvim_create_autocmd("TermOpen", { end, }) +-- Enable spell check and set textwidth for markdown files vim.api.nvim_create_autocmd("FileType", { pattern = "markdown", callback = function() @@ -552,6 +631,9 @@ vim.api.nvim_create_autocmd("FileType", { end, }) +-- ==================================================================================== +-- TREESITTER AND SYNTAX +-- ==================================================================================== -- syntax, indentation, treesitter, etc. require("ibl").setup({ indent = { char = "│" }, @@ -571,6 +653,9 @@ require("treesitter-context").setup({ multiline_threshold = 1, }) +-- ==================================================================================== +-- TREESITTER CONFIGURATION +-- ==================================================================================== ---@diagnostic disable-next-line: missing-fields require("nvim-treesitter.configs").setup({ ensure_installed = { @@ -654,9 +739,11 @@ require("nvim-treesitter.configs").setup({ swap = { enable = true, swap_next = { + -- @keymap a: Swap next parameter (treesitter) ["a"] = "@parameter.inner", }, swap_previous = { + -- @keymap A: Swap previous parameter (treesitter) ["A"] = "@parameter.inner", }, }, @@ -664,21 +751,33 @@ require("nvim-treesitter.configs").setup({ enable = true, set_jumps = true, goto_next_start = { + -- @keymap ]f: Go to next function start (treesitter) + -- @keymap ]c: Go to next class start (treesitter) + -- @keymap ]a: Go to next parameter start (treesitter) ["]f"] = "@function.inner", ["]c"] = "@class.inner", ["]a"] = "@parameter.inner", }, goto_next_end = { + -- @keymap ]F: Go to next function end (treesitter) + -- @keymap ]C: Go to next class end (treesitter) + -- @keymap ]A: Go to next parameter end (treesitter) ["]F"] = "@function.inner", ["]C"] = "@class.inner", ["]A"] = "@parameter.inner", }, goto_previous_start = { + -- @keymap [f: Go to previous function start (treesitter) + -- @keymap [c: Go to previous class start (treesitter) + -- @keymap [a: Go to previous parameter start (treesitter) ["[f"] = "@function.inner", ["[c"] = "@class.inner", ["[a"] = "@parameter.inner", }, goto_previous_end = { + -- @keymap [F: Go to previous function end (treesitter) + -- @keymap [C: Go to previous class end (treesitter) + -- @keymap [A: Go to previous parameter end (treesitter) ["[F"] = "@function.inner", ["[C"] = "@class.inner", ["[A"] = "@parameter.inner", @@ -687,6 +786,14 @@ require("nvim-treesitter.configs").setup({ select = { enable = true, keymaps = { + -- @keymap af: Select function outer (treesitter) + -- @keymap if: Select function inner (treesitter) + -- @keymap ac: Select conditional outer (treesitter) + -- @keymap ic: Select conditional inner (treesitter) + -- @keymap aa: Select parameter outer (treesitter) + -- @keymap ia: Select parameter inner (treesitter) + -- @keymap av: Select variable outer (treesitter) + -- @keymap iv: Select variable inner (treesitter) ["af"] = "@function.outer", ["if"] = "@function.inner", @@ -703,10 +810,14 @@ require("nvim-treesitter.configs").setup({ }, }) +-- @keymap st: Toggle treesitter split/join local treesj = require("treesj") treesj.setup({ use_default_keymaps = false }) keymap("n", "st", treesj.toggle, opts) +-- ==================================================================================== +-- TELESCOPE CONFIGURATION +-- ==================================================================================== local telescope = require("telescope") telescope.setup({ defaults = { @@ -739,6 +850,7 @@ local function ivy(iopts) end local builtin = require("telescope.builtin") +-- @keymap : Find files (Telescope) vim.keymap.set("n", "", function() builtin.find_files(ivy({ find_command = { @@ -751,47 +863,164 @@ vim.keymap.set("n", "", function() })) end, opts) +-- @keymap of: Open old files (Telescope) keymap("n", "of", function() builtin.oldfiles(ivy({ only_cwd = true, })) end, opts) +-- @keymap lg: Live grep (Telescope) keymap("n", "lg", function() builtin.live_grep(ivy()) end, opts) +-- @keymap fb: Find buffers (Telescope) keymap("n", "fb", function() builtin.buffers(ivy()) end, opts) +-- @keymap fh: Find help tags (Telescope) keymap("n", "fh", function() builtin.help_tags(ivy()) end, opts) +-- @keymap fc: Find commands (Telescope) keymap("n", "fc", function() builtin.commands(ivy()) end, opts) +-- @keymap fr: Resume last Telescope search keymap("n", "fr", function() builtin.resume(ivy()) end, opts) +-- @keymap fq: Find in quickfix (Telescope) keymap("n", "fq", function() builtin.quickfix(ivy()) end, opts) +-- @keymap /: Fuzzy find in current buffer (Telescope) keymap("n", "/", function() builtin.current_buffer_fuzzy_find(ivy()) end, opts) +-- @keymap ghi: Find GitHub issues (Telescope) keymap("n", "ghi", function() telescope.extensions.gh.issues(ivy()) end, opts) +-- ==================================================================================== +-- FILE TREE +-- ==================================================================================== +-- @keymap b: Toggle file tree (nvim-tree) require("nvim-tree").setup({ view = { width = 30, }, }) keymap("n", "b", ":NvimTreeToggle", opts) + +-- ==================================================================================== +-- HELP COMMAND +-- ==================================================================================== +-- @command Help: Show all keymaps and commands from init.lua +vim.api.nvim_create_user_command("Help", function() + local config_file = vim.fn.stdpath("config") .. "/init.lua" + local file = io.open(config_file, "r") + if not file then + vim.notify("Could not read config file: " .. config_file, vim.log.levels.ERROR) + return + end + + local keymaps = {} + local commands = {} + local plugins = {} + local current_section = "General" + + for line in file:lines() do + -- Parse @keymap comments + local key, desc = line:match("^%s*%-%-%s*@keymap%s+(.+):%s*(.+)$") + if key and desc then + table.insert(keymaps, { key = key, desc = desc, section = current_section }) + end + + -- Parse @command comments + local cmd, cmd_desc = line:match("^%s*%-%-%s*@command%s+(.+):%s*(.+)$") + if cmd and cmd_desc then + table.insert(commands, { cmd = cmd, desc = cmd_desc }) + end + + -- Parse @plugin comments + local plugin, plugin_desc = line:match("^%s*%-%-%s*@plugin%s+(.+):%s*(.+)$") + if plugin and plugin_desc then + table.insert(plugins, { plugin = plugin, desc = plugin_desc }) + end + + -- Track sections + if line:match("^%-%-%s*@section") or line:match("^%-%-%s*%-%-%-") then + current_section = line:match("UI") and "UI" + or line:match("CODING") and "Coding" + or line:match("TPOPE") and "Plugins" + or line:match("treesitter") and "Treesitter" + or "General" + end + end + + file:close() + + -- Create help buffer + local buf = vim.api.nvim_create_buf(false, true) + local lines = {} + + table.insert(lines, "Neovim Configuration Help") + table.insert(lines, "=" .. string.rep("=", 50)) + table.insert(lines, "") + + -- Keymaps section + table.insert(lines, "KEYMAPS") + table.insert(lines, string.rep("-", 50)) + table.insert(lines, "") + for _, km in ipairs(keymaps) do + local key = km.key:gsub("", "") + table.insert(lines, string.format(" %-25s %s", key, km.desc)) + end + table.insert(lines, "") + + -- Commands section + if #commands > 0 then + table.insert(lines, "COMMANDS") + table.insert(lines, string.rep("-", 50)) + table.insert(lines, "") + for _, cmd in ipairs(commands) do + table.insert(lines, string.format(" :%-24s %s", cmd.cmd, cmd.desc)) + end + table.insert(lines, "") + end + + -- Plugins section + if #plugins > 0 then + table.insert(lines, "PLUGINS") + table.insert(lines, string.rep("-", 50)) + table.insert(lines, "") + for _, plugin in ipairs(plugins) do + table.insert(lines, string.format(" %-25s %s", plugin.plugin, plugin.desc)) + end + table.insert(lines, "") + end + + table.insert(lines, "=" .. string.rep("=", 50)) + table.insert(lines, "Press 'q' to close") + + vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines) + vim.api.nvim_buf_set_option(buf, "filetype", "help") + vim.api.nvim_buf_set_option(buf, "modifiable", false) + vim.api.nvim_buf_set_name(buf, "neovim-config-help") + + -- Open in split + vim.cmd("split") + vim.api.nvim_set_current_buf(buf) + + -- Map q to close + vim.keymap.set("n", "q", ":close", { buffer = buf, silent = true }) +end, { desc = "Show all keymaps and commands from init.lua" }) From 2898a65b59f4ec7065ca1817effca8512f20c5c7 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 11:49:39 +0900 Subject: [PATCH 56/92] docs: add detailed key mapping comments to Neovim init.lua for improved usability --- config/nvim/init.lua | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 608d278d4..d789110d4 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -151,7 +151,12 @@ keymap("n", "j", ":10split | terminal", opts) -- ==================================================================================== -- NAVIGATION -- ==================================================================================== --- zz +-- @keymap n: Next search result and center screen +-- @keymap N: Previous search result and center screen +-- @keymap : Scroll up and center screen +-- @keymap : Scroll down and center screen +-- @keymap : Jump to older position and center screen +-- @keymap : Jump to newer position and center screen keymap("n", "n", "nzzzv", opts) keymap("n", "N", "Nzzzv", opts) keymap("n", "", "zz", opts) @@ -188,15 +193,19 @@ keymap("n", "gd", ":Gitsign preview_hunk_inline", opts) -- ==================================================================================== -- VISUAL MODE OPERATIONS -- ==================================================================================== --- indent +-- @keymap <: Decrease indent (visual mode) +-- @keymap >: Increase indent (visual mode) keymap("v", "<", "", ">gv", opts) +-- @keymap p: Paste without replacing clipboard (visual mode) -- If I visually select words and paste from clipboard, don't replace my -- clipboard with the selected word, instead keep my old word in the -- clipboard keymap("v", "p", '"_dP', opts) +-- @keymap K: Move selected text up (visual mode) +-- @keymap J: Move selected text down (visual mode) -- Move text up and down keymap("x", "K", ":move '<-2gv-gv", opts) keymap("x", "J", ":move '>+1gv-gv", opts) @@ -204,6 +213,7 @@ keymap("x", "J", ":move '>+1gv-gv", opts) -- ==================================================================================== -- INSERT MODE OPERATIONS -- ==================================================================================== +-- @keymap -/_/,/./;/:/!/?: Add undo breakpoints after punctuation -- in insert mode, adds new undo points after more some chars: for _, lhs in ipairs({ "-", "_", ",", ".", ";", ":", "/", "!", "?" }) do keymap("i", lhs, lhs .. "u", opts) @@ -544,6 +554,7 @@ vim.api.nvim_create_autocmd("FileType", { callback = function() local bufnr = vim.api.nvim_get_current_buf() local buf_opts = { noremap = true, silent = true, buffer = bufnr } + -- @keymap gq: Close git buffer keymap("n", "gq", ":silent! close", buf_opts) end, }) @@ -569,21 +580,26 @@ vim.api.nvim_create_autocmd("FileType", { vim.cmd("normal )k=") local buf_opts = { noremap = true, silent = true, buffer = bufnr } + -- @keymap gp: Git push (fugitive buffer) keymap("n", "gp", function() async_git({ "push", "--quiet" }, "Pushed!", "Push failed!") vim.cmd("silent! close") end, buf_opts) + -- @keymap gP: Git pull with rebase (fugitive buffer) keymap("n", "gP", function() async_git({ "pull", "--rebase" }, "Pulled!", "Pull failed!") vim.cmd("silent! close") end, buf_opts) + -- @keymap go: Git push and open PR (fugitive buffer) keymap("n", "go", function() async_git({ "ppr" }, "Pushed and opened PR URL!", "Failed to push or open PR") vim.cmd("silent! close") end, buf_opts) + -- @keymap cc: Git commit with sign-off (fugitive buffer) + -- @keymap gq: Close fugitive buffer keymap("n", "cc", ":silent! Git commit -s", buf_opts) keymap("n", "gq", ":silent! close", buf_opts) end, @@ -602,6 +618,7 @@ vim.api.nvim_create_autocmd("FileType", { vim.api.nvim_create_autocmd("FileType", { pattern = { "qf", "help" }, callback = function() + -- @keymap q: Close quickfix/help buffer keymap("n", "q", ":bdelete", { buffer = vim.api.nvim_get_current_buf(), noremap = true, @@ -613,6 +630,7 @@ vim.api.nvim_create_autocmd("FileType", { -- Add keymap to exit terminal mode and switch to previous window vim.api.nvim_create_autocmd("TermOpen", { callback = function() + -- @keymap j: Exit terminal and switch to previous window keymap("t", "j", [[p]], { buffer = vim.api.nvim_get_current_buf(), noremap = true, @@ -930,7 +948,7 @@ vim.api.nvim_create_user_command("Help", function() local file = io.open(config_file, "r") if not file then vim.notify("Could not read config file: " .. config_file, vim.log.levels.ERROR) - return + return end local keymaps = {} @@ -964,8 +982,8 @@ vim.api.nvim_create_user_command("Help", function() or line:match("TPOPE") and "Plugins" or line:match("treesitter") and "Treesitter" or "General" - end - end + end + end file:close() @@ -1021,6 +1039,7 @@ vim.api.nvim_create_user_command("Help", function() vim.cmd("split") vim.api.nvim_set_current_buf(buf) + -- @keymap q: Close help buffer -- Map q to close vim.keymap.set("n", "q", ":close", { buffer = buf, silent = true }) end, { desc = "Show all keymaps and commands from init.lua" }) From 79639dbb556aab45d98d6431e3a3f46f5be446f5 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 11:55:22 +0900 Subject: [PATCH 57/92] refactor: clean up whitespace and improve indentation in Neovim init.lua --- config/nvim/init.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index d789110d4..dd1505c6f 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -948,7 +948,7 @@ vim.api.nvim_create_user_command("Help", function() local file = io.open(config_file, "r") if not file then vim.notify("Could not read config file: " .. config_file, vim.log.levels.ERROR) - return + return end local keymaps = {} @@ -982,8 +982,8 @@ vim.api.nvim_create_user_command("Help", function() or line:match("TPOPE") and "Plugins" or line:match("treesitter") and "Treesitter" or "General" - end - end + end + end file:close() From 1f03584791d0aed6ab7dc969acf699ea0a32680c Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 12:06:34 +0900 Subject: [PATCH 58/92] feat: add key mapping for saving all buffers and quitting in Neovim init.lua --- config/nvim/init.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index dd1505c6f..3d418e1c3 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -134,12 +134,14 @@ keymap("n", "cc", ":cclose", opts) -- @keymap w: Write file -- @keymap r: Reload Neovim configuration -- @keymap h: Show help (all keymaps and commands) +-- @keymap ZZ: Save all buffers and quit -- write, buffer killing keymap("n", "q", ":Bdelete", opts) keymap("n", "bad", ":%bwipeout!:intro", opts) keymap("n", "w", ":write", opts) keymap("n", "r", ":source $MYVIMRC", opts) keymap("n", "h", ":Help", opts) +keymap("n", "ZZ", ":wa:q", opts) -- ==================================================================================== -- TERMINAL From 59b56185ff488f6b540fac7fbf872c2905c69760 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 12:24:18 +0900 Subject: [PATCH 59/92] fix: update Neovim sync command to source init.lua for plugin synchronization --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9b3483e10..c235a9fde 100644 --- a/Makefile +++ b/Makefile @@ -475,7 +475,7 @@ neovim-update: ## Update Neovim plugins. .PHONY: neovim-sync neovim-sync: ## Sync Neovim plugins. @echo "🔄 Syncing neovim plugins..." - @nvim --headless +"lua vim.pack.sync()" +qa + @nvim --headless +"lua vim.cmd('source ' .. vim.fn.stdpath('config') .. '/init.lua')" +qa @echo "✅ Neovim plugins synced" ##@ Lua From 3ffcf612ac3d8349ebba3d9eb30973137474f56e Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 12:26:14 +0900 Subject: [PATCH 60/92] refactor: update key mappings and improve comments in Neovim init.lua for clarity --- config/nvim/init.lua | 46 ++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 3d418e1c3..217cd947e 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -121,26 +121,24 @@ vim.g.maplocalleader = " " -- QUICKFIX LISTS -- ==================================================================================== -- @keymap co: Open quickfix list --- @keymap cc: Close quickfix list --- quicklists keymap("n", "co", ":copen", opts) +-- @keymap cc: Close quickfix list keymap("n", "cc", ":cclose", opts) -- ==================================================================================== -- BUFFER AND FILE OPERATIONS -- ==================================================================================== -- @keymap q: Close current buffer --- @keymap bad: Wipe all buffers --- @keymap w: Write file --- @keymap r: Reload Neovim configuration --- @keymap h: Show help (all keymaps and commands) --- @keymap ZZ: Save all buffers and quit --- write, buffer killing keymap("n", "q", ":Bdelete", opts) +-- @keymap bad: Wipe all buffers keymap("n", "bad", ":%bwipeout!:intro", opts) +-- @keymap w: Write file keymap("n", "w", ":write", opts) +-- @keymap r: Reload Neovim configuration keymap("n", "r", ":source $MYVIMRC", opts) +-- @keymap h: Show help (all keymaps and commands) keymap("n", "h", ":Help", opts) +-- @keymap ZZ: Save all buffers and quit keymap("n", "ZZ", ":wa:q", opts) -- ==================================================================================== @@ -154,16 +152,16 @@ keymap("n", "j", ":10split | terminal", opts) -- NAVIGATION -- ==================================================================================== -- @keymap n: Next search result and center screen --- @keymap N: Previous search result and center screen --- @keymap : Scroll up and center screen --- @keymap : Scroll down and center screen --- @keymap : Jump to older position and center screen --- @keymap : Jump to newer position and center screen keymap("n", "n", "nzzzv", opts) +-- @keymap N: Previous search result and center screen keymap("n", "N", "Nzzzv", opts) +-- @keymap : Scroll up and center screen keymap("n", "", "zz", opts) +-- @keymap : Scroll down and center screen keymap("n", "", "zz", opts) +-- @keymap : Jump to older position and center screen keymap("n", "", "zz", opts) +-- @keymap : Jump to newer position and center screen keymap("n", "", "zz", opts) -- ==================================================================================== @@ -185,19 +183,18 @@ keymap({ "n", "v" }, "d", '"_d', opts) -- GIT OPERATIONS -- ==================================================================================== -- @keymap gs: Open Git status in new tab --- @keymap : Open Git mergetool in new tab --- @keymap gd: Preview hunk inline --- git keymap("n", "gs", ":tab Git", opts) +-- @keymap : Open Git mergetool in new tab keymap("n", "", ":tab Git mergetool", opts) +-- @keymap gd: Preview hunk inline keymap("n", "gd", ":Gitsign preview_hunk_inline", opts) -- ==================================================================================== -- VISUAL MODE OPERATIONS -- ==================================================================================== -- @keymap <: Decrease indent (visual mode) --- @keymap >: Increase indent (visual mode) keymap("v", "<", ": Increase indent (visual mode) keymap("v", ">", ">gv", opts) -- @keymap p: Paste without replacing clipboard (visual mode) @@ -207,9 +204,8 @@ keymap("v", ">", ">gv", opts) keymap("v", "p", '"_dP', opts) -- @keymap K: Move selected text up (visual mode) --- @keymap J: Move selected text down (visual mode) --- Move text up and down keymap("x", "K", ":move '<-2gv-gv", opts) +-- @keymap J: Move selected text down (visual mode) keymap("x", "J", ":move '>+1gv-gv", opts) -- ==================================================================================== @@ -295,12 +291,12 @@ vim.diagnostic.config({ -- ==================================================================================== -- CODE NAVIGATION -- ==================================================================================== --- @keymap oo: Navigate to related file (other.nvim) --- @keymap ov: Navigate to related file in vertical split --- @keymap os: Navigate to related file in horizontal split require("other-nvim").setup({ mappings = { "golang" } }) +-- @keymap oo: Navigate to related file (other.nvim) keymap("n", "oo", ":Other", opts) +-- @keymap ov: Navigate to related file in vertical split keymap("n", "ov", ":OtherVSplit", opts) +-- @keymap os: Navigate to related file in horizontal split keymap("n", "os", ":OtherSplit", opts) -- @keymap gco: Generate code annotation (neogen) @@ -950,7 +946,7 @@ vim.api.nvim_create_user_command("Help", function() local file = io.open(config_file, "r") if not file then vim.notify("Could not read config file: " .. config_file, vim.log.levels.ERROR) - return + return end local keymaps = {} @@ -984,8 +980,8 @@ vim.api.nvim_create_user_command("Help", function() or line:match("TPOPE") and "Plugins" or line:match("treesitter") and "Treesitter" or "General" - end - end + end + end file:close() From 5dfa36a67040f97dcea91ef613877a7d540ed558 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 12:28:58 +0900 Subject: [PATCH 61/92] style: standardize section headers in Neovim init.lua for improved readability --- config/nvim/init.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 217cd947e..366b7946a 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -66,7 +66,8 @@ vim.pack.add({ { src = "https://github.com/norcalli/nvim-colorizer.lua" }, { src = "https://github.com/lewis6991/gitsigns.nvim" }, { src = "https://github.com/akinsho/git-conflict.nvim" }, - -- telescope + + -- TELESCOPE { src = "https://github.com/nvim-lua/plenary.nvim" }, { src = "https://github.com/nvim-telescope/telescope-github.nvim" }, { src = "https://github.com/nvim-telescope/telescope.nvim" }, @@ -92,7 +93,7 @@ vim.pack.add({ { src = "https://github.com/tpope/vim-sleuth" }, { src = "https://github.com/tpope/vim-speeddating" }, - -- treesitter and friends + -- TREESITTER { src = "https://github.com/nvim-treesitter/nvim-treesitter" }, { src = "https://github.com/lukas-reineke/indent-blankline.nvim" }, { src = "https://github.com/wansmer/treesj" }, From 8d93f019b565f5cad1c06c4b338e6853811270c4 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 12:30:30 +0900 Subject: [PATCH 62/92] fix: ensure newline at end of nvim-pack-lock.json during Neovim sync --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index c235a9fde..b525555a8 100644 --- a/Makefile +++ b/Makefile @@ -476,6 +476,9 @@ neovim-update: ## Update Neovim plugins. neovim-sync: ## Sync Neovim plugins. @echo "🔄 Syncing neovim plugins..." @nvim --headless +"lua vim.cmd('source ' .. vim.fn.stdpath('config') .. '/init.lua')" +qa + @if [ -f "$(PWD)/config/nvim/nvim-pack-lock.json" ]; then \ + sed -i '' -e '$ { /^$$/d; }' "$(PWD)/config/nvim/nvim-pack-lock.json" && printf '\n' >> "$(PWD)/config/nvim/nvim-pack-lock.json"; \ + fi @echo "✅ Neovim plugins synced" ##@ Lua From 4355aba718b56bc6ed16833ea35d83bc52d57e8d Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 12:32:18 +0900 Subject: [PATCH 63/92] refactor: simplify Neovim plugin configurations by removing unnecessary options in init.lua --- config/nvim/init.lua | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 366b7946a..91ee5a8e4 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -301,7 +301,7 @@ keymap("n", "ov", ":OtherVSplit", opts) keymap("n", "os", ":OtherSplit", opts) -- @keymap gco: Generate code annotation (neogen) -require("neogen").setup({ snippet_engine = "nvim" }) +require("neogen").setup() keymap("n", "gco", ":Neogen", opts) -- ==================================================================================== @@ -316,7 +316,6 @@ require("copilot").setup({ ---@type blink.cmp.Config local cmp = require("blink.cmp") cmp.setup({ - keymap = { preset = "default" }, appearance = { nerd_font_variant = "mono", kind_icons = { @@ -357,9 +356,7 @@ cmp.setup({ Variable = "", }, }, - signature = { enabled = true }, cmdline = { - enabled = true, sources = function() local type = vim.fn.getcmdtype() if type == "/" or type == "?" then @@ -429,16 +426,6 @@ cmp.setup({ keyword = { range = "full", }, - trigger = { - show_on_insert_on_trigger_character = true, - show_on_trigger_character = true, - show_on_keyword = true, - }, - documentation = { - auto_show = true, - auto_show_delay_ms = 250, - treesitter_highlighting = false, - }, menu = { draw = { columns = { @@ -658,17 +645,13 @@ require("ibl").setup({ scope = { enabled = false }, }) -require("nvim-autopairs").setup({ - check_ts = true, -}) +require("nvim-autopairs").setup() require("nvim-ts-autotag").setup() require("nvim-surround").setup() require("todo-comments").setup() -require("treesitter-context").setup({ - multiline_threshold = 1, -}) +require("treesitter-context").setup() -- ==================================================================================== -- TREESITTER CONFIGURATION From 71d675c977b072b7b88268e97a77f43286041130 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 14:26:24 +0900 Subject: [PATCH 64/92] fix: correct indentation and whitespace in Neovim init.lua for better readability --- config/nvim/init.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 91ee5a8e4..20c012e5b 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -930,7 +930,7 @@ vim.api.nvim_create_user_command("Help", function() local file = io.open(config_file, "r") if not file then vim.notify("Could not read config file: " .. config_file, vim.log.levels.ERROR) - return + return end local keymaps = {} @@ -964,8 +964,8 @@ vim.api.nvim_create_user_command("Help", function() or line:match("TPOPE") and "Plugins" or line:match("treesitter") and "Treesitter" or "General" - end - end + end + end file:close() From 83fca8153601785685e0e6cb1060ed79ccbf716b Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 14:50:07 +0900 Subject: [PATCH 65/92] fix: enhance Neovim sync command to handle newline removal in nvim-pack-lock.json across different OS --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b525555a8..8dd21143d 100644 --- a/Makefile +++ b/Makefile @@ -477,7 +477,12 @@ neovim-sync: ## Sync Neovim plugins. @echo "🔄 Syncing neovim plugins..." @nvim --headless +"lua vim.cmd('source ' .. vim.fn.stdpath('config') .. '/init.lua')" +qa @if [ -f "$(PWD)/config/nvim/nvim-pack-lock.json" ]; then \ - sed -i '' -e '$ { /^$$/d; }' "$(PWD)/config/nvim/nvim-pack-lock.json" && printf '\n' >> "$(PWD)/config/nvim/nvim-pack-lock.json"; \ + if [ "$$(uname)" = "Darwin" ]; then \ + sed -i '' -e '$$ { /^$$/d; }' "$(PWD)/config/nvim/nvim-pack-lock.json"; \ + else \ + sed -i -e '$$ { /^$$/d; }' "$(PWD)/config/nvim/nvim-pack-lock.json"; \ + fi && \ + printf '\n' >> "$(PWD)/config/nvim/nvim-pack-lock.json"; \ fi @echo "✅ Neovim plugins synced" From d31cc4e477977533470647bc0c3d04fe35149939 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 14:57:34 +0900 Subject: [PATCH 66/92] fix: add lua attribute to neovim-unwrapped in home-manager overlay for compatibility --- home-manager/default.nix | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/home-manager/default.nix b/home-manager/default.nix index c52d192bf..1e52e1277 100644 --- a/home-manager/default.nix +++ b/home-manager/default.nix @@ -41,7 +41,28 @@ in ]; }; - nixpkgs.overlays = [ inputs.neovim-nightly-overlay.overlays.default ]; + # Apply nightly overlay first, then fix the lua attribute issue for the wrapper + nixpkgs.overlays = [ + inputs.neovim-nightly-overlay.overlays.default + (final: prev: { + # Fix neovim-unwrapped to add lua attribute if missing (required by home-manager wrapper) + neovim-unwrapped = + let + nvim = prev.neovim-unwrapped; + in + if nvim ? lua then + nvim + else + nvim.overrideAttrs (oldAttrs: { + passthru = (oldAttrs.passthru or { }) // { + lua = prev.lua5_4; + }; + }) + // { + lua = prev.lua5_4; + }; + }) + ]; home.username = username; home.homeDirectory = lib.mkIf pkgs.stdenv.isLinux "/home/${username}"; From 694f731a28c3fa2ea4e8d8e047c0fe31d4dfb236 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 15:08:28 +0900 Subject: [PATCH 67/92] refactor: remove neovim-nightly-overlay from Darwin configuration for simplification --- hosts/darwin/default.nix | 2 -- 1 file changed, 2 deletions(-) diff --git a/hosts/darwin/default.nix b/hosts/darwin/default.nix index 2500ece9c..4030690d9 100644 --- a/hosts/darwin/default.nix +++ b/hosts/darwin/default.nix @@ -9,12 +9,10 @@ let nix-darwin home-manager agenix - neovim-nightly-overlay ; system = "aarch64-darwin"; pkgs = import inputs.nixpkgs { inherit system; - overlays = [ neovim-nightly-overlay.overlays.default ]; config.allowUnfree = true; }; configuration = From 1f5e93ed95215cd70929d537188804c886fe1f17 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 15:24:15 +0900 Subject: [PATCH 68/92] fix: change nvim-pack-lock.json from symlink to copy to allow Neovim write access --- config/nvim/default.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config/nvim/default.nix b/config/nvim/default.nix index 0cf4b5807..9074ae0b2 100644 --- a/config/nvim/default.nix +++ b/config/nvim/default.nix @@ -4,8 +4,10 @@ source = config.lib.file.mkOutOfStoreSymlink ./init.lua; force = true; }; + # Copy nvim-pack-lock.json instead of symlinking so Neovim can write to it + # Use make neovim-sync to sync changes back to the repo home.file.".config/nvim/nvim-pack-lock.json" = { - source = config.lib.file.mkOutOfStoreSymlink ./nvim-pack-lock.json; + source = ./nvim-pack-lock.json; force = true; }; } From 433d388a833e749384d56e870513a20ac64c841a Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 15:26:10 +0900 Subject: [PATCH 69/92] fix: change nvim-pack-lock.json handling to read file content directly for Neovim write access --- config/nvim/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/nvim/default.nix b/config/nvim/default.nix index 9074ae0b2..8c66e64ba 100644 --- a/config/nvim/default.nix +++ b/config/nvim/default.nix @@ -7,7 +7,7 @@ # Copy nvim-pack-lock.json instead of symlinking so Neovim can write to it # Use make neovim-sync to sync changes back to the repo home.file.".config/nvim/nvim-pack-lock.json" = { - source = ./nvim-pack-lock.json; + text = builtins.readFile ./nvim-pack-lock.json; force = true; }; } From 00397c7b7bb567e94783b33f7055f53946fca51e Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 15:28:41 +0900 Subject: [PATCH 70/92] fix: update nvim-pack-lock.json handling to use activation script for direct file copy, ensuring Neovim write access --- config/nvim/default.nix | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/config/nvim/default.nix b/config/nvim/default.nix index 8c66e64ba..09aea663f 100644 --- a/config/nvim/default.nix +++ b/config/nvim/default.nix @@ -1,13 +1,18 @@ -{ config, ... }: +{ config, lib, ... }: +let + nvimPackLockJson = ./nvim-pack-lock.json; +in { home.file.".config/nvim/init.lua" = { source = config.lib.file.mkOutOfStoreSymlink ./init.lua; force = true; }; - # Copy nvim-pack-lock.json instead of symlinking so Neovim can write to it - # Use make neovim-sync to sync changes back to the repo - home.file.".config/nvim/nvim-pack-lock.json" = { - text = builtins.readFile ./nvim-pack-lock.json; - force = true; - }; + # Copy nvim-pack-lock.json via activation script instead of symlinking + # so Neovim can write to it. Home Manager always creates symlinks for + # managed files, so we handle this file separately. + home.activation.copyNvimPackLock = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + $DRY_RUN_CMD mkdir -p "$HOME/.config/nvim" + $DRY_RUN_CMD cp -f ${nvimPackLockJson} "$HOME/.config/nvim/nvim-pack-lock.json" + $DRY_RUN_CMD chmod 644 "$HOME/.config/nvim/nvim-pack-lock.json" + ''; } From 898c20582b72bfe2bbcb45cb5be60e6b0fcf7795 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 15:38:23 +0900 Subject: [PATCH 71/92] feat: implement dynamic theme detection and refresh in Neovim configuration --- config/nvim/init.lua | 81 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 5 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 20c012e5b..7055ac4e6 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -39,7 +39,7 @@ vim.opt.spelllang = { "en_us" } vim.opt.laststatus = 2 vim.opt.cursorline = true vim.opt.grepprg = "rg --vimgrep --smart-case --follow" -vim.opt.background = "dark" +-- Background will be set automatically based on system theme vim.opt.termguicolors = true vim.opt.shortmess:append("c") vim.opt.timeoutlen = 300 @@ -136,7 +136,10 @@ keymap("n", "bad", ":%bwipeout!:intro", opts) -- @keymap w: Write file keymap("n", "w", ":write", opts) -- @keymap r: Reload Neovim configuration -keymap("n", "r", ":source $MYVIMRC", opts) +keymap("n", "r", function() + vim.cmd("source $MYVIMRC") + set_theme() -- Refresh theme on reload +end, opts) -- @keymap h: Show help (all keymaps and commands) keymap("n", "h", ":Help", opts) -- @keymap ZZ: Save all buffers and quit @@ -226,8 +229,72 @@ keymap("i", "jj", "", opts) -- UI CONFIGURATION -- ==================================================================================== -local bg0 = "#1b1b1b" -vim.cmd("colorscheme dracula") +-- Detect system theme and set colorscheme accordingly +local function detect_system_theme() + local is_dark = false + if vim.fn.has("mac") == 1 then + -- macOS: Check AppleInterfaceStyle + local handle = io.popen("defaults read -g AppleInterfaceStyle 2>/dev/null") + if handle then + local result = handle:read("*a") + handle:close() + is_dark = result:match("Dark") ~= nil + else + -- Default to dark if detection fails + is_dark = true + end + elseif vim.fn.has("unix") == 1 then + -- Linux: Check gsettings or environment variable + local handle = io.popen("gsettings get org.gnome.desktop.interface color-scheme 2>/dev/null | grep -q dark || echo ''") + if handle then + local result = handle:read("*a") + handle:close() + is_dark = result:match("dark") ~= nil + else + -- Fallback: Check GTK_THEME or default to dark + local gtk_theme = os.getenv("GTK_THEME") or "" + is_dark = gtk_theme:match("dark") ~= nil or true + end + else + -- Default to dark for other systems + is_dark = true + end + return is_dark +end + +local function set_theme() + local is_dark = detect_system_theme() + if is_dark then + vim.opt.background = "dark" + vim.cmd("colorscheme dracula") + else + vim.opt.background = "light" + -- Use a light theme - you can change this to your preferred light theme + vim.cmd("colorscheme default") + end + -- Refresh lualine theme if it's already loaded + if package.loaded["lualine"] then + require("lualine").setup({ + options = { + theme = vim.o.background == "dark" and "dracula" or "auto", + component_separators = "", + section_separators = "", + }, + sections = { + lualine_b = section_b, + lualine_c = section_c, + }, + inactive_sections = { + lualine_c = section_c, + lualine_x = { "location" }, + }, + }) + end +end + +-- Set initial theme +set_theme() + vim.api.nvim_set_hl(0, "StatusLine", { reverse = false }) vim.api.nvim_set_hl(0, "StatusLineNC", { reverse = false }) @@ -244,7 +311,7 @@ local section_b = { "branch", "diff", { "diagnostics", sources = { "nvim_workspa local section_c = { "%=", { "filename", file_status = false, path = 1 } } require("lualine").setup({ options = { - theme = "dracula", + theme = vim.o.background == "dark" and "dracula" or "auto", component_separators = "", section_separators = "", }, @@ -476,6 +543,10 @@ end -- Opens the directory of the current file in Finder/file explorer. vim.api.nvim_create_user_command("Finder", "!open %:h", {}) +-- @command ThemeRefresh: Refresh theme based on system appearance +-- Refreshes the colorscheme based on current system theme (dark/light). +vim.api.nvim_create_user_command("ThemeRefresh", set_theme, { desc = "Refresh theme based on system appearance" }) + -- ==================================================================================== -- AUTOCMDS -- ==================================================================================== From 0827fed9f5d01a1eb64fed5b4b00d4b614e44489 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 15:38:40 +0900 Subject: [PATCH 72/92] refactor: remove lualine theme refresh logic from Neovim init.lua for cleaner configuration --- config/nvim/init.lua | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 7055ac4e6..ad6f3a302 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -272,24 +272,6 @@ local function set_theme() -- Use a light theme - you can change this to your preferred light theme vim.cmd("colorscheme default") end - -- Refresh lualine theme if it's already loaded - if package.loaded["lualine"] then - require("lualine").setup({ - options = { - theme = vim.o.background == "dark" and "dracula" or "auto", - component_separators = "", - section_separators = "", - }, - sections = { - lualine_b = section_b, - lualine_c = section_c, - }, - inactive_sections = { - lualine_c = section_c, - lualine_x = { "location" }, - }, - }) - end end -- Set initial theme From c06c640b315e2d3acabfd6caadaf614615b59bf5 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 15:48:10 +0900 Subject: [PATCH 73/92] feat: integrate auto-dark-mode plugin for dynamic theme switching based on system appearance --- config/nvim/init.lua | 86 ++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 52 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index ad6f3a302..15a32c5ec 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -55,6 +55,10 @@ vim.pack.add({ -- UI { src = "https://github.com/nvim-tree/nvim-web-devicons" }, { src = "https://github.com/Mofiqul/dracula.nvim" }, + { + src = "https://github.com/f-person/auto-dark-mode.nvim", + priority = 1000, + }, { src = "https://github.com/folke/sidekick.nvim" }, { src = "https://github.com/nvim-tree/nvim-tree.lua" }, { src = "https://github.com/nvim-lualine/lualine.nvim" }, @@ -138,7 +142,6 @@ keymap("n", "w", ":write", opts) -- @keymap r: Reload Neovim configuration keymap("n", "r", function() vim.cmd("source $MYVIMRC") - set_theme() -- Refresh theme on reload end, opts) -- @keymap h: Show help (all keymaps and commands) keymap("n", "h", ":Help", opts) @@ -229,54 +232,6 @@ keymap("i", "jj", "", opts) -- UI CONFIGURATION -- ==================================================================================== --- Detect system theme and set colorscheme accordingly -local function detect_system_theme() - local is_dark = false - if vim.fn.has("mac") == 1 then - -- macOS: Check AppleInterfaceStyle - local handle = io.popen("defaults read -g AppleInterfaceStyle 2>/dev/null") - if handle then - local result = handle:read("*a") - handle:close() - is_dark = result:match("Dark") ~= nil - else - -- Default to dark if detection fails - is_dark = true - end - elseif vim.fn.has("unix") == 1 then - -- Linux: Check gsettings or environment variable - local handle = io.popen("gsettings get org.gnome.desktop.interface color-scheme 2>/dev/null | grep -q dark || echo ''") - if handle then - local result = handle:read("*a") - handle:close() - is_dark = result:match("dark") ~= nil - else - -- Fallback: Check GTK_THEME or default to dark - local gtk_theme = os.getenv("GTK_THEME") or "" - is_dark = gtk_theme:match("dark") ~= nil or true - end - else - -- Default to dark for other systems - is_dark = true - end - return is_dark -end - -local function set_theme() - local is_dark = detect_system_theme() - if is_dark then - vim.opt.background = "dark" - vim.cmd("colorscheme dracula") - else - vim.opt.background = "light" - -- Use a light theme - you can change this to your preferred light theme - vim.cmd("colorscheme default") - end -end - --- Set initial theme -set_theme() - vim.api.nvim_set_hl(0, "StatusLine", { reverse = false }) vim.api.nvim_set_hl(0, "StatusLineNC", { reverse = false }) @@ -291,9 +246,12 @@ vim.notify = notify local section_b = { "branch", "diff", { "diagnostics", sources = { "nvim_workspace_diagnostic" } } } local section_c = { "%=", { "filename", file_status = false, path = 1 } } -require("lualine").setup({ +local lualine_config = { options = { - theme = vim.o.background == "dark" and "dracula" or "auto", + theme = function() + -- Dynamically determine theme based on background + return vim.o.background == "dark" and "dracula" or "auto" + end, component_separators = "", section_separators = "", }, @@ -305,6 +263,28 @@ require("lualine").setup({ lualine_c = section_c, lualine_x = { "location" }, }, +} +require("lualine").setup(lualine_config) + +-- Auto theme switching based on system appearance +require("auto-dark-mode").setup({ + update_interval = 1000, -- Check for theme changes every second + set_dark_mode = function() + vim.api.nvim_set_option_value("background", "dark", {}) + vim.cmd("colorscheme dracula") + -- Refresh lualine to update theme + if package.loaded["lualine"] then + require("lualine").setup(lualine_config) + end + end, + set_light_mode = function() + vim.api.nvim_set_option_value("background", "light", {}) + vim.cmd("colorscheme default") + -- Refresh lualine to update theme + if package.loaded["lualine"] then + require("lualine").setup(lualine_config) + end + end, }) require("auto-hlsearch").setup({}) @@ -527,7 +507,9 @@ vim.api.nvim_create_user_command("Finder", "!open %:h", {}) -- @command ThemeRefresh: Refresh theme based on system appearance -- Refreshes the colorscheme based on current system theme (dark/light). -vim.api.nvim_create_user_command("ThemeRefresh", set_theme, { desc = "Refresh theme based on system appearance" }) +vim.api.nvim_create_user_command("ThemeRefresh", function() + require("auto-dark-mode").update() +end, { desc = "Refresh theme based on system appearance" }) -- ==================================================================================== -- AUTOCMDS From 1fdbc73c3f0dcc202f944a9943fae16cf206ce3d Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 15:48:24 +0900 Subject: [PATCH 74/92] chore: add newline at the end of nvim-pack-lock.json for consistency --- config/nvim/nvim-pack-lock.json | 1 + 1 file changed, 1 insertion(+) diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json index 4fb3a4189..95f41b66b 100644 --- a/config/nvim/nvim-pack-lock.json +++ b/config/nvim/nvim-pack-lock.json @@ -171,3 +171,4 @@ } } } + From c633a0713d955f18b3b519ce44f0015503c72517 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 15:48:45 +0900 Subject: [PATCH 75/92] feat: add auto-dark-mode.nvim plugin to nvim-pack-lock.json for enhanced theme support --- config/nvim/nvim-pack-lock.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json index 95f41b66b..cba19a7cd 100644 --- a/config/nvim/nvim-pack-lock.json +++ b/config/nvim/nvim-pack-lock.json @@ -1,5 +1,9 @@ { "plugins": { + "auto-dark-mode.nvim": { + "rev": "e300259ec777a40b4b9e3c8e6ade203e78d15881", + "src": "https://github.com/f-person/auto-dark-mode.nvim" + }, "auto-hlsearch.nvim": { "rev": "77502069b22e48ab7736fe9cf53e1fdac1923bca", "src": "https://github.com/asiryk/auto-hlsearch.nvim" @@ -170,5 +174,4 @@ "src": "https://github.com/christoomey/vim-tmux-navigator" } } -} - +} \ No newline at end of file From 1f16113d46bf6ced41f8fd9a3e876456fb702c9f Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 15:49:01 +0900 Subject: [PATCH 76/92] fix: add missing newline at the end of nvim-pack-lock.json for proper formatting --- config/nvim/nvim-pack-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json index cba19a7cd..75f97bbd5 100644 --- a/config/nvim/nvim-pack-lock.json +++ b/config/nvim/nvim-pack-lock.json @@ -174,4 +174,4 @@ "src": "https://github.com/christoomey/vim-tmux-navigator" } } -} \ No newline at end of file +} From 30d2999453778c9e36624b2e4f6c514a7db558f5 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 15:56:11 +0900 Subject: [PATCH 77/92] feat: implement toggle terminal functionality in Neovim configuration for improved terminal management --- config/nvim/init.lua | 94 ++++++++++++++++++++++++++++++--- config/nvim/nvim-pack-lock.json | 2 +- 2 files changed, 88 insertions(+), 8 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 15a32c5ec..1842287f9 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -151,9 +151,52 @@ keymap("n", "ZZ", ":wa:q", opts) -- ==================================================================================== -- TERMINAL -- ==================================================================================== --- @keymap j: Open terminal in split --- terminal -keymap("n", "j", ":10split | terminal", opts) +-- Terminal toggle state +local terminal_bufnr = nil +local terminal_winid = nil + +-- Toggle terminal function +local function toggle_terminal() + -- Check if terminal window is currently visible + if terminal_winid and vim.api.nvim_win_is_valid(terminal_winid) then + -- Terminal is visible, hide it (but keep the buffer) + vim.api.nvim_win_hide(terminal_winid) + terminal_winid = nil + return + end + + -- Check if terminal buffer exists + if terminal_bufnr and vim.api.nvim_buf_is_valid(terminal_bufnr) then + -- Check if buffer is already displayed in any window + local existing_winid = nil + for _, winid in ipairs(vim.api.nvim_list_wins()) do + if vim.api.nvim_win_get_buf(winid) == terminal_bufnr then + existing_winid = winid + break + end + end + + if existing_winid then + -- Buffer is already displayed, focus that window + vim.api.nvim_set_current_win(existing_winid) + terminal_winid = existing_winid + else + -- Terminal buffer exists but window is hidden, show it + vim.cmd("10split") + vim.api.nvim_set_current_buf(terminal_bufnr) + terminal_winid = vim.api.nvim_get_current_win() + end + return + end + + -- Terminal doesn't exist, create it + vim.cmd("10split | terminal") + terminal_bufnr = vim.api.nvim_get_current_buf() + terminal_winid = vim.api.nvim_get_current_win() +end + +-- @keymap j: Toggle terminal (show/hide) +keymap("n", "j", toggle_terminal, opts) -- ==================================================================================== -- NAVIGATION @@ -648,18 +691,55 @@ vim.api.nvim_create_autocmd("FileType", { end, }) --- Add keymap to exit terminal mode and switch to previous window +-- Track terminal buffer and window, and set up terminal mode keymap vim.api.nvim_create_autocmd("TermOpen", { callback = function() - -- @keymap j: Exit terminal and switch to previous window - keymap("t", "j", [[p]], { - buffer = vim.api.nvim_get_current_buf(), + local bufnr = vim.api.nvim_get_current_buf() + local winid = vim.api.nvim_get_current_win() + + -- Update terminal tracking if this is our managed terminal + if terminal_bufnr == nil or terminal_bufnr == bufnr then + terminal_bufnr = bufnr + terminal_winid = winid + end + + -- @keymap j: Exit terminal mode and hide terminal + keymap("t", "j", function() + -- Exit terminal mode properly + vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("", true, false, true), "n", false) + -- Hide the terminal window but keep the buffer + vim.schedule(function() + if vim.api.nvim_win_is_valid(terminal_winid) then + vim.api.nvim_win_hide(terminal_winid) + terminal_winid = nil + end + end) + end, { + buffer = bufnr, + noremap = true, + silent = true, + }) + + -- @keymap : Exit terminal mode (keeps terminal visible) + -- Standard Neovim way: also works + keymap("t", "", vim.api.nvim_replace_termcodes("", true, false, true), { + buffer = bufnr, noremap = true, silent = true, }) end, }) +-- Clean up terminal tracking when terminal buffer is closed +vim.api.nvim_create_autocmd("BufDelete", { + callback = function(args) + if args.buf == terminal_bufnr then + terminal_bufnr = nil + terminal_winid = nil + end + end, +}) + -- Enable spell check and set textwidth for markdown files vim.api.nvim_create_autocmd("FileType", { pattern = "markdown", diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json index 75f97bbd5..cba19a7cd 100644 --- a/config/nvim/nvim-pack-lock.json +++ b/config/nvim/nvim-pack-lock.json @@ -174,4 +174,4 @@ "src": "https://github.com/christoomey/vim-tmux-navigator" } } -} +} \ No newline at end of file From 6276a105f4b24e93b197c0c497d3dc69ad276b0d Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 15:56:57 +0900 Subject: [PATCH 78/92] feat: add terminal completion sources and keymap instructions in Neovim configuration for enhanced terminal usability --- config/nvim/init.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 1842287f9..5bf1c8488 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -452,6 +452,8 @@ cmp.setup({ }, sources = { default = { "lsp", "path", "snippets", "buffer", "copilot" }, + -- Terminal buffers: path and buffer (command history) completions + terminal = { "path", "buffer" }, providers = { lsp = { min_keyword_length = 0, @@ -727,6 +729,10 @@ vim.api.nvim_create_autocmd("TermOpen", { noremap = true, silent = true, }) + + -- @keymap : Trigger completion in terminal mode + -- Note: Terminal completion works differently - you may need to use for file completion + -- or configure your shell's completion (e.g., fish, zsh with completion plugins) end, }) From 48e84f96f10f931923664a4d00ec77b3491bd8dd Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 15:59:38 +0900 Subject: [PATCH 79/92] feat: enhance nvim-tree configuration with custom key mappings for improved file navigation and management --- config/nvim/init.lua | 74 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 5bf1c8488..79c7aa501 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -1039,6 +1039,80 @@ require("nvim-tree").setup({ view = { width = 30, }, + actions = { + open_file = { + quit_on_open = false, + }, + }, + on_attach = function(bufnr) + local api = require("nvim-tree.api") + + local function opts(desc) + return { desc = "nvim-tree: " .. desc, buffer = bufnr, noremap = true, silent = true, nowait = true } + end + + -- Default mappings. You can override them in the mappings table below + -- @keymap l: Open file/folder (nvim-tree) + vim.keymap.set("n", "l", api.node.open.edit, opts("Open")) + -- @keymap : Open file/folder (nvim-tree) + vim.keymap.set("n", "", api.node.open.edit, opts("Open")) + -- @keymap o: Open file/folder (nvim-tree) + vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) + -- @keymap h: Close folder (nvim-tree) + vim.keymap.set("n", "h", api.node.navigate.parent_close, opts("Close Directory")) + -- @keymap v: Open in vertical split (nvim-tree) + vim.keymap.set("n", "v", api.node.open.vertical, opts("Open: Vertical Split")) + -- @keymap s: Open in horizontal split (nvim-tree) + vim.keymap.set("n", "s", api.node.open.horizontal, opts("Open: Horizontal Split")) + -- @keymap t: Open in new tab (nvim-tree) + vim.keymap.set("n", "t", api.node.open.tab, opts("Open: New Tab")) + -- @keymap i: Open in horizontal split (nvim-tree) + vim.keymap.set("n", "i", api.node.open.horizontal, opts("Open: Horizontal Split")) + -- @keymap a: Add file/folder (nvim-tree) + vim.keymap.set("n", "a", api.fs.create, opts("Create")) + -- @keymap d: Delete file/folder (nvim-tree) + vim.keymap.set("n", "d", api.fs.remove, opts("Delete")) + -- @keymap r: Rename file/folder (nvim-tree) + vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) + -- @keymap y: Copy absolute path (nvim-tree) + vim.keymap.set("n", "y", api.fs.copy.absolute_path, opts("Copy Absolute Path")) + -- @keymap Y: Copy relative path (nvim-tree) + vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) + -- @keymap c: Change directory (nvim-tree) + vim.keymap.set("n", "c", api.tree.change_root_to_node, opts("CD")) + -- @keymap u: Go to parent directory (nvim-tree) + vim.keymap.set("n", "u", api.tree.change_root_to_parent, opts("Up")) + -- @keymap q: Close tree (nvim-tree) + vim.keymap.set("n", "q", api.tree.close, opts("Close")) + -- @keymap R: Refresh tree (nvim-tree) + vim.keymap.set("n", "R", api.tree.reload, opts("Refresh")) + -- @keymap ?: Toggle help (nvim-tree) + vim.keymap.set("n", "?", api.tree.toggle_help, opts("Help")) + -- @keymap .: Run file command (nvim-tree) + vim.keymap.set("n", ".", api.node.run.cmd, opts("Run Command")) + -- @keymap : Rename file/folder (nvim-tree) + vim.keymap.set("n", "", api.fs.rename_basename, opts("Rename: Basename")) + -- @keymap : Cut file/folder (nvim-tree) + vim.keymap.set("n", "", api.fs.cut, opts("Cut")) + -- @keymap : Copy file/folder (nvim-tree) + vim.keymap.set("n", "", api.fs.copy.node, opts("Copy")) + -- @keymap : Paste file/folder (nvim-tree) + vim.keymap.set("n", "", api.fs.paste, opts("Paste")) + -- @keymap [c: Navigate to previous sibling (nvim-tree) + vim.keymap.set("n", "[c", api.node.navigate.sibling.prev, opts("Prev Sibling")) + -- @keymap ]c: Navigate to next sibling (nvim-tree) + vim.keymap.set("n", "]c", api.node.navigate.sibling.next, opts("Next Sibling")) + -- @keymap p: Preview file (nvim-tree) + vim.keymap.set("n", "p", api.node.open.preview, opts("Open Preview")) + -- @keymap : Close folder (nvim-tree) + vim.keymap.set("n", "", api.node.navigate.parent_close, opts("Close Directory")) + -- @keymap : Open preview and keep focus (nvim-tree) + vim.keymap.set("n", "", api.node.open.preview, opts("Open Preview")) + -- @keymap H: Toggle dotfiles (nvim-tree) + vim.keymap.set("n", "H", api.tree.toggle_gitignore_filter, opts("Toggle Git Ignore")) + -- @keymap I: Toggle dotfiles (nvim-tree) + vim.keymap.set("n", "I", api.tree.toggle_hidden_filter, opts("Toggle Dotfiles")) + end, }) keymap("n", "b", ":NvimTreeToggle", opts) From ae62a49a5a2250c9beeb4eedc9be3891264f9c48 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 16:01:36 +0900 Subject: [PATCH 80/92] feat: add key mappings for cycling through buffers in Neovim configuration to enhance navigation --- config/nvim/init.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 79c7aa501..68021172a 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -133,6 +133,10 @@ keymap("n", "cc", ":cclose", opts) -- ==================================================================================== -- BUFFER AND FILE OPERATIONS -- ==================================================================================== +-- @keymap : Cycle to next buffer +keymap("n", "", ":bnext", opts) +-- @keymap : Cycle to previous buffer +keymap("n", "", ":bprevious", opts) -- @keymap q: Close current buffer keymap("n", "q", ":Bdelete", opts) -- @keymap bad: Wipe all buffers From 91ed6f4c132f6c5dd68e46d0ef9e221935a3839b Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 20:00:45 +0900 Subject: [PATCH 81/92] feat: implement buffer cycling functionality with custom key mappings in Neovim configuration for improved navigation --- config/nvim/init.lua | 106 +++++++++++++++++++++++++++++--- config/nvim/nvim-pack-lock.json | 2 +- 2 files changed, 99 insertions(+), 9 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 68021172a..4581554ec 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -133,10 +133,102 @@ keymap("n", "cc", ":cclose", opts) -- ==================================================================================== -- BUFFER AND FILE OPERATIONS -- ==================================================================================== +-- Helper function to cycle buffers (includes unlisted buffers like nvim-tree) +local function cycle_buffer(direction) + local current_buf = vim.api.nvim_get_current_buf() + + -- Get buffers from all windows (includes nvim-tree and other unlisted buffers) + local buffer_set = {} + local buffers = {} + + for _, win in ipairs(vim.api.nvim_list_wins()) do + local buf = vim.api.nvim_win_get_buf(win) + if vim.api.nvim_buf_is_valid(buf) and not buffer_set[buf] then + buffer_set[buf] = true + table.insert(buffers, buf) + end + end + + -- Also include all loaded buffers (in case some aren't in windows) + for _, buf in ipairs(vim.api.nvim_list_bufs()) do + if vim.api.nvim_buf_is_valid(buf) and vim.api.nvim_buf_is_loaded(buf) and not buffer_set[buf] then + buffer_set[buf] = true + table.insert(buffers, buf) + end + end + + if #buffers <= 1 then + return + end + + -- Find current buffer index + local current_idx = nil + for i, buf in ipairs(buffers) do + if buf == current_buf then + current_idx = i + break + end + end + + if not current_idx then + return + end + + -- Calculate next/previous index + local next_idx + if direction == "next" then + next_idx = current_idx + 1 + if next_idx > #buffers then + next_idx = 1 + end + else + next_idx = current_idx - 1 + if next_idx < 1 then + next_idx = #buffers + end + end + + -- Find or create a window for the target buffer + local target_buf = buffers[next_idx] + local target_win = nil + + -- Check if buffer is already in a window + for _, win in ipairs(vim.api.nvim_list_wins()) do + if vim.api.nvim_win_get_buf(win) == target_buf then + target_win = win + break + end + end + + if target_win then + -- Buffer is in a window, switch to it + vim.api.nvim_set_current_win(target_win) + else + -- Buffer not in any window, switch to it in current window + vim.api.nvim_set_current_buf(target_buf) + end +end + -- @keymap : Cycle to next buffer -keymap("n", "", ":bnext", opts) +vim.keymap.set("n", "", function() + cycle_buffer("next") +end, { noremap = true, silent = true }) + -- @keymap : Cycle to previous buffer -keymap("n", "", ":bprevious", opts) +vim.keymap.set("n", "", function() + cycle_buffer("prev") +end, { noremap = true, silent = true }) + +-- Alternative: ]b and [b for buffer navigation (vim convention) +-- @keymap ]b: Cycle to next buffer +keymap("n", "]b", function() + cycle_buffer("next") +end, opts) + +-- @keymap [b: Cycle to previous buffer +keymap("n", "[b", function() + cycle_buffer("prev") +end, opts) -- @keymap q: Close current buffer keymap("n", "q", ":Bdelete", opts) -- @keymap bad: Wipe all buffers @@ -456,8 +548,6 @@ cmp.setup({ }, sources = { default = { "lsp", "path", "snippets", "buffer", "copilot" }, - -- Terminal buffers: path and buffer (command history) completions - terminal = { "path", "buffer" }, providers = { lsp = { min_keyword_length = 0, @@ -702,13 +792,13 @@ vim.api.nvim_create_autocmd("TermOpen", { callback = function() local bufnr = vim.api.nvim_get_current_buf() local winid = vim.api.nvim_get_current_win() - + -- Update terminal tracking if this is our managed terminal if terminal_bufnr == nil or terminal_bufnr == bufnr then terminal_bufnr = bufnr terminal_winid = winid end - + -- @keymap j: Exit terminal mode and hide terminal keymap("t", "j", function() -- Exit terminal mode properly @@ -725,7 +815,7 @@ vim.api.nvim_create_autocmd("TermOpen", { noremap = true, silent = true, }) - + -- @keymap : Exit terminal mode (keeps terminal visible) -- Standard Neovim way: also works keymap("t", "", vim.api.nvim_replace_termcodes("", true, false, true), { @@ -733,7 +823,7 @@ vim.api.nvim_create_autocmd("TermOpen", { noremap = true, silent = true, }) - + -- @keymap : Trigger completion in terminal mode -- Note: Terminal completion works differently - you may need to use for file completion -- or configure your shell's completion (e.g., fish, zsh with completion plugins) diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json index cba19a7cd..75f97bbd5 100644 --- a/config/nvim/nvim-pack-lock.json +++ b/config/nvim/nvim-pack-lock.json @@ -174,4 +174,4 @@ "src": "https://github.com/christoomey/vim-tmux-navigator" } } -} \ No newline at end of file +} From 2cc92ff13e82b02174584755edbe0745d8b4cf40 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 20:02:17 +0900 Subject: [PATCH 82/92] refactor: clean up buffer cycling function in Neovim configuration for improved readability and performance --- config/nvim/init.lua | 39 ++++++++++++++++----------------- config/nvim/nvim-pack-lock.json | 2 +- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 4581554ec..cc5b3d244 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -136,11 +136,11 @@ keymap("n", "cc", ":cclose", opts) -- Helper function to cycle buffers (includes unlisted buffers like nvim-tree) local function cycle_buffer(direction) local current_buf = vim.api.nvim_get_current_buf() - + -- Get buffers from all windows (includes nvim-tree and other unlisted buffers) local buffer_set = {} local buffers = {} - + for _, win in ipairs(vim.api.nvim_list_wins()) do local buf = vim.api.nvim_win_get_buf(win) if vim.api.nvim_buf_is_valid(buf) and not buffer_set[buf] then @@ -148,7 +148,7 @@ local function cycle_buffer(direction) table.insert(buffers, buf) end end - + -- Also include all loaded buffers (in case some aren't in windows) for _, buf in ipairs(vim.api.nvim_list_bufs()) do if vim.api.nvim_buf_is_valid(buf) and vim.api.nvim_buf_is_loaded(buf) and not buffer_set[buf] then @@ -156,11 +156,12 @@ local function cycle_buffer(direction) table.insert(buffers, buf) end end - - if #buffers <= 1 then + + -- Need at least 2 buffers to cycle + if #buffers < 2 then return end - + -- Find current buffer index local current_idx = nil for i, buf in ipairs(buffers) do @@ -169,39 +170,37 @@ local function cycle_buffer(direction) break end end - + + -- If current buffer not found, use first buffer as fallback if not current_idx then - return + current_idx = 1 end - - -- Calculate next/previous index + + -- Calculate next/previous index with wrapping local next_idx if direction == "next" then - next_idx = current_idx + 1 - if next_idx > #buffers then - next_idx = 1 - end + next_idx = (current_idx % #buffers) + 1 else next_idx = current_idx - 1 if next_idx < 1 then next_idx = #buffers end end - - -- Find or create a window for the target buffer + + -- Get target buffer local target_buf = buffers[next_idx] + + -- Find window containing target buffer local target_win = nil - - -- Check if buffer is already in a window for _, win in ipairs(vim.api.nvim_list_wins()) do if vim.api.nvim_win_get_buf(win) == target_buf then target_win = win break end end - + if target_win then - -- Buffer is in a window, switch to it + -- Buffer is in a window, switch to that window vim.api.nvim_set_current_win(target_win) else -- Buffer not in any window, switch to it in current window diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json index 75f97bbd5..cba19a7cd 100644 --- a/config/nvim/nvim-pack-lock.json +++ b/config/nvim/nvim-pack-lock.json @@ -174,4 +174,4 @@ "src": "https://github.com/christoomey/vim-tmux-navigator" } } -} +} \ No newline at end of file From 6217496d8b3bb182a6fdaae90b19eb8deb3b57e5 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 20:05:05 +0900 Subject: [PATCH 83/92] refactor: enhance buffer cycling function in Neovim configuration with additional safety checks and improved logic for better performance --- config/nvim/init.lua | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index cc5b3d244..cd883f04a 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -137,19 +137,20 @@ keymap("n", "cc", ":cclose", opts) local function cycle_buffer(direction) local current_buf = vim.api.nvim_get_current_buf() - -- Get buffers from all windows (includes nvim-tree and other unlisted buffers) + -- Get all loaded buffers (this includes buffers in windows and loaded but not visible) local buffer_set = {} local buffers = {} + -- First, get buffers from windows (includes nvim-tree) for _, win in ipairs(vim.api.nvim_list_wins()) do local buf = vim.api.nvim_win_get_buf(win) - if vim.api.nvim_buf_is_valid(buf) and not buffer_set[buf] then + if vim.api.nvim_buf_is_valid(buf) and vim.api.nvim_buf_is_loaded(buf) and not buffer_set[buf] then buffer_set[buf] = true table.insert(buffers, buf) end end - -- Also include all loaded buffers (in case some aren't in windows) + -- Then add all other loaded buffers (files that aren't in windows) for _, buf in ipairs(vim.api.nvim_list_bufs()) do if vim.api.nvim_buf_is_valid(buf) and vim.api.nvim_buf_is_loaded(buf) and not buffer_set[buf] then buffer_set[buf] = true @@ -157,6 +158,12 @@ local function cycle_buffer(direction) end end + -- Ensure current buffer is in the list + if not buffer_set[current_buf] then + table.insert(buffers, current_buf) + buffer_set[current_buf] = true + end + -- Need at least 2 buffers to cycle if #buffers < 2 then return @@ -171,7 +178,7 @@ local function cycle_buffer(direction) end end - -- If current buffer not found, use first buffer as fallback + -- This should never happen now, but safety check if not current_idx then current_idx = 1 end @@ -179,8 +186,11 @@ local function cycle_buffer(direction) -- Calculate next/previous index with wrapping local next_idx if direction == "next" then - next_idx = (current_idx % #buffers) + 1 - else + next_idx = current_idx + 1 + if next_idx > #buffers then + next_idx = 1 + end + else -- prev next_idx = current_idx - 1 if next_idx < 1 then next_idx = #buffers @@ -190,10 +200,15 @@ local function cycle_buffer(direction) -- Get target buffer local target_buf = buffers[next_idx] + -- Safety check + if not vim.api.nvim_buf_is_valid(target_buf) then + return + end + -- Find window containing target buffer local target_win = nil for _, win in ipairs(vim.api.nvim_list_wins()) do - if vim.api.nvim_win_get_buf(win) == target_buf then + if vim.api.nvim_win_is_valid(win) and vim.api.nvim_win_get_buf(win) == target_buf then target_win = win break end From 84460d3b55e35c3ab158429be0d835541b3bb498 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Mon, 24 Nov 2025 20:23:21 +0900 Subject: [PATCH 84/92] fix: ensure neovim-unwrapped always includes lua attribute for compatibility with home-manager wrapper --- home-manager/default.nix | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/home-manager/default.nix b/home-manager/default.nix index 1e52e1277..7e76a5ad8 100644 --- a/home-manager/default.nix +++ b/home-manager/default.nix @@ -45,22 +45,15 @@ in nixpkgs.overlays = [ inputs.neovim-nightly-overlay.overlays.default (final: prev: { - # Fix neovim-unwrapped to add lua attribute if missing (required by home-manager wrapper) - neovim-unwrapped = - let - nvim = prev.neovim-unwrapped; - in - if nvim ? lua then - nvim - else - nvim.overrideAttrs (oldAttrs: { - passthru = (oldAttrs.passthru or { }) // { - lua = prev.lua5_4; - }; - }) - // { - lua = prev.lua5_4; - }; + # Fix neovim-unwrapped to add lua attribute (required by home-manager wrapper) + # Always add lua attribute to ensure compatibility with home-manager's wrapper + neovim-unwrapped = (prev.neovim-unwrapped.overrideAttrs (oldAttrs: { + passthru = (oldAttrs.passthru or { }) // { + lua = prev.lua5_4; + }; + })) // { + lua = prev.lua5_4; + }; }) ]; From e92eb58f6ddafb2fe2616726012d78b0d48c140f Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Tue, 25 Nov 2025 15:39:00 +0900 Subject: [PATCH 85/92] fix: ensure neovim-unwrapped includes lua attribute for compatibility with home-manager wrapper --- config/nvim/init.lua | 24 ++++++++++++------------ config/nvim/nvim-pack-lock.json | 2 +- home-manager/default.nix | 12 +++++++----- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/config/nvim/init.lua b/config/nvim/init.lua index cd883f04a..17f24ee99 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -136,11 +136,11 @@ keymap("n", "cc", ":cclose", opts) -- Helper function to cycle buffers (includes unlisted buffers like nvim-tree) local function cycle_buffer(direction) local current_buf = vim.api.nvim_get_current_buf() - + -- Get all loaded buffers (this includes buffers in windows and loaded but not visible) local buffer_set = {} local buffers = {} - + -- First, get buffers from windows (includes nvim-tree) for _, win in ipairs(vim.api.nvim_list_wins()) do local buf = vim.api.nvim_win_get_buf(win) @@ -149,7 +149,7 @@ local function cycle_buffer(direction) table.insert(buffers, buf) end end - + -- Then add all other loaded buffers (files that aren't in windows) for _, buf in ipairs(vim.api.nvim_list_bufs()) do if vim.api.nvim_buf_is_valid(buf) and vim.api.nvim_buf_is_loaded(buf) and not buffer_set[buf] then @@ -157,18 +157,18 @@ local function cycle_buffer(direction) table.insert(buffers, buf) end end - + -- Ensure current buffer is in the list if not buffer_set[current_buf] then table.insert(buffers, current_buf) buffer_set[current_buf] = true end - + -- Need at least 2 buffers to cycle if #buffers < 2 then return end - + -- Find current buffer index local current_idx = nil for i, buf in ipairs(buffers) do @@ -177,12 +177,12 @@ local function cycle_buffer(direction) break end end - + -- This should never happen now, but safety check if not current_idx then current_idx = 1 end - + -- Calculate next/previous index with wrapping local next_idx if direction == "next" then @@ -196,15 +196,15 @@ local function cycle_buffer(direction) next_idx = #buffers end end - + -- Get target buffer local target_buf = buffers[next_idx] - + -- Safety check if not vim.api.nvim_buf_is_valid(target_buf) then return end - + -- Find window containing target buffer local target_win = nil for _, win in ipairs(vim.api.nvim_list_wins()) do @@ -213,7 +213,7 @@ local function cycle_buffer(direction) break end end - + if target_win then -- Buffer is in a window, switch to that window vim.api.nvim_set_current_win(target_win) diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json index cba19a7cd..75f97bbd5 100644 --- a/config/nvim/nvim-pack-lock.json +++ b/config/nvim/nvim-pack-lock.json @@ -174,4 +174,4 @@ "src": "https://github.com/christoomey/vim-tmux-navigator" } } -} \ No newline at end of file +} diff --git a/home-manager/default.nix b/home-manager/default.nix index 7e76a5ad8..a24e4879f 100644 --- a/home-manager/default.nix +++ b/home-manager/default.nix @@ -47,13 +47,15 @@ in (final: prev: { # Fix neovim-unwrapped to add lua attribute (required by home-manager wrapper) # Always add lua attribute to ensure compatibility with home-manager's wrapper - neovim-unwrapped = (prev.neovim-unwrapped.overrideAttrs (oldAttrs: { - passthru = (oldAttrs.passthru or { }) // { + neovim-unwrapped = + (prev.neovim-unwrapped.overrideAttrs (oldAttrs: { + passthru = (oldAttrs.passthru or { }) // { + lua = prev.lua5_4; + }; + })) + // { lua = prev.lua5_4; }; - })) // { - lua = prev.lua5_4; - }; }) ]; From 48b3ede1bb803e57ffd5fae78aea630d23bf4f8f Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Tue, 25 Nov 2025 16:04:06 +0900 Subject: [PATCH 86/92] feat: refactor Nix configuration to streamline system handling and ensure lua attribute compatibility for neovim-unwrapped --- flake.nix | 15 +++++---------- home-manager/default.nix | 18 ------------------ hosts/darwin/default.nix | 4 +++- hosts/linux/default.nix | 14 +++++++------- hosts/nixos/default.nix | 3 ++- overlays/default.nix | 16 ++++++++++++++++ 6 files changed, 33 insertions(+), 37 deletions(-) create mode 100644 overlays/default.nix diff --git a/flake.nix b/flake.nix index 8ec23470e..7051f2e8a 100644 --- a/flake.nix +++ b/flake.nix @@ -90,34 +90,29 @@ "ubuntu@x86_64-linux" = import ./hosts/linux { inherit inputs; username = "ubuntu"; - pkgs = inputs.nixpkgs.legacyPackages."x86_64-linux"; - lib = inputs.nixpkgs.legacyPackages."x86_64-linux".lib; + system = "x86_64-linux"; }; "root@x86_64-linux" = import ./hosts/linux { inherit inputs; username = "root"; - pkgs = inputs.nixpkgs.legacyPackages."x86_64-linux"; - lib = inputs.nixpkgs.legacyPackages."x86_64-linux".lib; + system = "x86_64-linux"; }; "root@aarch64-linux" = import ./hosts/linux { inherit inputs; username = "root"; - pkgs = inputs.nixpkgs.legacyPackages."aarch64-linux"; - lib = inputs.nixpkgs.legacyPackages."aarch64-linux".lib; + system = "aarch64-linux"; }; "runner@x86_64-linux" = import ./hosts/linux { inherit inputs; isRunner = true; username = "runner"; - pkgs = inputs.nixpkgs.legacyPackages."x86_64-linux"; - lib = inputs.nixpkgs.legacyPackages."x86_64-linux".lib; + system = "x86_64-linux"; }; "runner@aarch64-linux" = import ./hosts/linux { inherit inputs; isRunner = true; username = "runner"; - pkgs = inputs.nixpkgs.legacyPackages."aarch64-linux"; - lib = inputs.nixpkgs.legacyPackages."aarch64-linux".lib; + system = "aarch64-linux"; }; }; }; diff --git a/home-manager/default.nix b/home-manager/default.nix index a24e4879f..aaabbc42c 100644 --- a/home-manager/default.nix +++ b/home-manager/default.nix @@ -41,24 +41,6 @@ in ]; }; - # Apply nightly overlay first, then fix the lua attribute issue for the wrapper - nixpkgs.overlays = [ - inputs.neovim-nightly-overlay.overlays.default - (final: prev: { - # Fix neovim-unwrapped to add lua attribute (required by home-manager wrapper) - # Always add lua attribute to ensure compatibility with home-manager's wrapper - neovim-unwrapped = - (prev.neovim-unwrapped.overrideAttrs (oldAttrs: { - passthru = (oldAttrs.passthru or { }) // { - lua = prev.lua5_4; - }; - })) - // { - lua = prev.lua5_4; - }; - }) - ]; - home.username = username; home.homeDirectory = lib.mkIf pkgs.stdenv.isLinux "/home/${username}"; home.packages = packages; diff --git a/hosts/darwin/default.nix b/hosts/darwin/default.nix index 4030690d9..68d303972 100644 --- a/hosts/darwin/default.nix +++ b/hosts/darwin/default.nix @@ -11,8 +11,9 @@ let agenix ; system = "aarch64-darwin"; + overlays = import ../../overlays { inherit inputs; }; pkgs = import inputs.nixpkgs { - inherit system; + inherit system overlays; config.allowUnfree = true; }; configuration = @@ -33,6 +34,7 @@ in home-manager.darwinModules.home-manager agenix.darwinModules.default { + nixpkgs.pkgs = pkgs; home-manager.backupFileExtension = "hm-backup"; home-manager.extraSpecialArgs = { inherit inputs; }; home-manager.sharedModules = [ diff --git a/hosts/linux/default.nix b/hosts/linux/default.nix index 2fb39ff48..52322db9f 100644 --- a/hosts/linux/default.nix +++ b/hosts/linux/default.nix @@ -1,12 +1,12 @@ -{ - inputs, - username, - pkgs, - lib, - isRunner ? false, -}: +{ inputs, username, system ? "x86_64-linux", isRunner ? false }: let inherit (inputs) home-manager; + overlays = import ../../overlays { inherit inputs; }; + pkgs = import inputs.nixpkgs { + inherit system overlays; + config.allowUnfree = true; + }; + lib = pkgs.lib; in home-manager.lib.homeManagerConfiguration { inherit pkgs; diff --git a/hosts/nixos/default.nix b/hosts/nixos/default.nix index 30225e3c8..48288b9a5 100644 --- a/hosts/nixos/default.nix +++ b/hosts/nixos/default.nix @@ -7,8 +7,9 @@ let inherit (inputs) nixpkgs home-manager; system = "x86_64-linux"; + overlays = import ../../overlays { inherit inputs; }; pkgs = import nixpkgs { - inherit system; + inherit system overlays; config.allowUnfree = true; }; configuration = diff --git a/overlays/default.nix b/overlays/default.nix new file mode 100644 index 000000000..b0ce62714 --- /dev/null +++ b/overlays/default.nix @@ -0,0 +1,16 @@ +{ inputs }: +[ + inputs.neovim-nightly-overlay.overlays.default + (final: prev: { + # Ensure neovim-unwrapped exposes a lua attribute for wrapper consumers (e.g., home-manager) + neovim-unwrapped = + (prev.neovim-unwrapped.overrideAttrs (oldAttrs: { + passthru = (oldAttrs.passthru or { }) // { + lua = prev.lua5_4; + }; + })) + // { + lua = prev.lua5_4; + }; + }) +] From 0172a7a0f96a7aed210042c87b777b6ee92b41dc Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Tue, 25 Nov 2025 16:05:10 +0900 Subject: [PATCH 87/92] fix: correct formatting of function parameters in default.nix --- hosts/linux/default.nix | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hosts/linux/default.nix b/hosts/linux/default.nix index 52322db9f..98d9ea284 100644 --- a/hosts/linux/default.nix +++ b/hosts/linux/default.nix @@ -1,4 +1,9 @@ -{ inputs, username, system ? "x86_64-linux", isRunner ? false }: +{ + inputs, + username, + system ? "x86_64-linux", + isRunner ? false, +}: let inherit (inputs) home-manager; overlays = import ../../overlays { inherit inputs; }; From 1b46d4b2984b535c3eab76a2d75bd96eceb5ee52 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Tue, 25 Nov 2025 16:11:40 +0900 Subject: [PATCH 88/92] fix: update package references in Nix configuration for consistency and clarity --- home-manager/packages/default.nix | 2 +- nix-darwin/config/nix.nix | 1 - overlays/default.nix | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/home-manager/packages/default.nix b/home-manager/packages/default.nix index c40957318..e77d45b84 100644 --- a/home-manager/packages/default.nix +++ b/home-manager/packages/default.nix @@ -8,7 +8,7 @@ in with pkgs; [ inputs.agenix.packages.${stdenv.hostPlatform.system}.default - inputs.nur.legacyPackages.${stdenv.hostPlatform.system}.repos.charmbracelet.crush + pkgs.nur.repos.charmbracelet.crush age aichat # aider-chat # FIXME: pyarrow 20.0.0 has malloc issues on macOS, uncomment when fixed diff --git a/nix-darwin/config/nix.nix b/nix-darwin/config/nix.nix index acaf57546..802454173 100644 --- a/nix-darwin/config/nix.nix +++ b/nix-darwin/config/nix.nix @@ -7,5 +7,4 @@ }; }; - nixpkgs.config.allowUnfree = true; } diff --git a/overlays/default.nix b/overlays/default.nix index b0ce62714..52463655d 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -1,5 +1,6 @@ { inputs }: [ + inputs.nur.overlay inputs.neovim-nightly-overlay.overlays.default (final: prev: { # Ensure neovim-unwrapped exposes a lua attribute for wrapper consumers (e.g., home-manager) From 02a0518753dfdc6f8b354f0f724a50af4e7717e6 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Tue, 25 Nov 2025 16:52:17 +0900 Subject: [PATCH 89/92] feat: refactor Nix configuration to centralize unfree package settings and improve modularity --- home-manager/default.nix | 11 ----------- hosts/darwin/default.nix | 6 +++++- hosts/linux/default.nix | 5 ++++- hosts/nixos/default.nix | 6 +++++- lib/nixpkgs-config.nix | 11 +++++++++++ overlays/default.nix | 2 +- 6 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 lib/nixpkgs-config.nix diff --git a/home-manager/default.nix b/home-manager/default.nix index aaabbc42c..d321a8bc6 100644 --- a/home-manager/default.nix +++ b/home-manager/default.nix @@ -30,17 +30,6 @@ in inputs.agenix.homeManagerModules.default ]; - nixpkgs.config = { - allowUnfree = true; - allowUnfreePredicate = - pkg: - builtins.elem (lib.getName pkg) [ - "claude-code" - "qwen-code" - "crush" - ]; - }; - home.username = username; home.homeDirectory = lib.mkIf pkgs.stdenv.isLinux "/home/${username}"; home.packages = packages; diff --git a/hosts/darwin/default.nix b/hosts/darwin/default.nix index 68d303972..e85e63498 100644 --- a/hosts/darwin/default.nix +++ b/hosts/darwin/default.nix @@ -12,9 +12,12 @@ let ; system = "aarch64-darwin"; overlays = import ../../overlays { inherit inputs; }; + nixpkgsConfig = import ../../lib/nixpkgs-config.nix { + nixpkgsLib = inputs.nixpkgs.lib; + }; pkgs = import inputs.nixpkgs { inherit system overlays; - config.allowUnfree = true; + config = nixpkgsConfig; }; configuration = { ... }: @@ -37,6 +40,7 @@ in nixpkgs.pkgs = pkgs; home-manager.backupFileExtension = "hm-backup"; home-manager.extraSpecialArgs = { inherit inputs; }; + home-manager.useGlobalPkgs = true; home-manager.sharedModules = [ { home.activation.removeBackups = { diff --git a/hosts/linux/default.nix b/hosts/linux/default.nix index 98d9ea284..d72c7078a 100644 --- a/hosts/linux/default.nix +++ b/hosts/linux/default.nix @@ -7,9 +7,12 @@ let inherit (inputs) home-manager; overlays = import ../../overlays { inherit inputs; }; + nixpkgsConfig = import ../../lib/nixpkgs-config.nix { + nixpkgsLib = inputs.nixpkgs.lib; + }; pkgs = import inputs.nixpkgs { inherit system overlays; - config.allowUnfree = true; + config = nixpkgsConfig; }; lib = pkgs.lib; in diff --git a/hosts/nixos/default.nix b/hosts/nixos/default.nix index 48288b9a5..50ddab6d7 100644 --- a/hosts/nixos/default.nix +++ b/hosts/nixos/default.nix @@ -7,10 +7,13 @@ let inherit (inputs) nixpkgs home-manager; system = "x86_64-linux"; + nixpkgsConfig = import ../../lib/nixpkgs-config.nix { + nixpkgsLib = nixpkgs.lib; + }; overlays = import ../../overlays { inherit inputs; }; pkgs = import nixpkgs { inherit system overlays; - config.allowUnfree = true; + config = nixpkgsConfig; }; configuration = { config, lib, ... }: @@ -117,6 +120,7 @@ nixpkgs.lib.nixosSystem { home-manager.nixosModules.home-manager { home-manager.backupFileExtension = "hm-backup"; + home-manager.useGlobalPkgs = true; home-manager.useUserPackages = true; home-manager.users."${username}" = import ../../home-manager { inherit inputs username; diff --git a/lib/nixpkgs-config.nix b/lib/nixpkgs-config.nix new file mode 100644 index 000000000..da9d28d9f --- /dev/null +++ b/lib/nixpkgs-config.nix @@ -0,0 +1,11 @@ +{ nixpkgsLib }: +{ + allowUnfree = true; + allowUnfreePredicate = + pkg: + builtins.elem (nixpkgsLib.getName pkg) [ + "claude-code" + "qwen-code" + "crush" + ]; +} diff --git a/overlays/default.nix b/overlays/default.nix index 52463655d..183b8906e 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -1,6 +1,6 @@ { inputs }: [ - inputs.nur.overlay + inputs.nur.overlays.default inputs.neovim-nightly-overlay.overlays.default (final: prev: { # Ensure neovim-unwrapped exposes a lua attribute for wrapper consumers (e.g., home-manager) From 24727320bc851f389ea1abfff0557d8fbb6098f2 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Tue, 25 Nov 2025 17:11:38 +0900 Subject: [PATCH 90/92] feat: add vscodium to Homebrew casks for enhanced code editing options --- nix-darwin/config/homebrew.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nix-darwin/config/homebrew.nix b/nix-darwin/config/homebrew.nix index f22b1989e..ab56b3c06 100644 --- a/nix-darwin/config/homebrew.nix +++ b/nix-darwin/config/homebrew.nix @@ -78,6 +78,7 @@ "sf-symbols" "slack" "visual-studio-code" + "vscodium" "warp" "wezterm" "windsurf" From bbd0fe68251e1760642a38d71fdf4d0e11c92504 Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Tue, 25 Nov 2025 18:08:30 +0900 Subject: [PATCH 91/92] feat: enhance install target to include nix-flake-update and nix-build for improved environment setup --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8dd21143d..964d875df 100644 --- a/Makefile +++ b/Makefile @@ -102,7 +102,7 @@ help: ## Show this help message. ##@ General .PHONY: install -install: setup update shell-install ## Set up full environment (setup, update, shell-install). +install: setup nix-flake-update nix-build nix-switch shell-install ## Set up full environment (setup, flake-update, build, switch, shell-install). .PHONY: build build: nix-build ## Build Nix configuration. From dd932a122c87062880a53cdef2db02d713eabb0d Mon Sep 17 00:00:00 2001 From: Shun Kakinoki Date: Tue, 25 Nov 2025 18:10:49 +0900 Subject: [PATCH 92/92] fix: add non-deprecated alias for system to prevent warnings in upstream modules --- overlays/default.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/overlays/default.nix b/overlays/default.nix index 183b8906e..39265f679 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -14,4 +14,8 @@ lua = prev.lua5_4; }; }) + (final: prev: { + # Provide non-deprecated alias so upstream modules using pkgs.system don't emit warnings. + system = prev.stdenv.hostPlatform.system; + }) ]