This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

superconfig / tools / nvim / flake-module.nix
13 kB 415 lines
1{ inputs, ... }: 2{ 3 perSystem = 4 { system, pkgs, ... }: 5 { 6 packages.nvim = inputs.nixvim.legacyPackages.${system}.makeNixvim { 7 # The options-reference manpage builds via nixvim's docs/pkgs.nix, which 8 # patches nixos-render-docs with nixpkgs PR#538502 (admonition support). 9 # That PR is already merged in our nixpkgs, so the patch fails to apply 10 # and breaks the build. We follow a single nixpkgs, so we can't feed 11 # nixvim an older one — just drop the manpage (irrelevant to the editor). 12 enableMan = false; 13 vimAlias = true; 14 # Closure budget: ~100 MB. Everything below that isn't the editor or a 15 # plugin comes from PATH (project devshell / system) instead of being 16 # baked in: no python/ruby/node providers (no remote plugins are used), 17 # no git/bat/wl-clipboard on the wrapper PATH (desktops install 18 # wl-clipboard themselves; xdg-utils behind it costs 120 MB of perl), 19 # language servers unset (taken from the project devshell), and only 20 # the grammars we edit. 21 withPython3 = false; 22 withRuby = false; 23 withNodeJs = false; 24 waylandSupport = false; 25 enablePrintInit = false; 26 dependencies.git.enable = false; 27 dependencies.bat.enable = false; 28 colorschemes = { 29 ayu = { 30 enable = true; 31 settings = { 32 mirage = false; 33 dark = true; 34 }; 35 settings.overrides = { 36 EoLSpace = { 37 bg = "#883333"; 38 }; 39 }; 40 }; 41 everforest = { 42 enable = true; 43 settings.overrides = { 44 EoLSpace = { 45 bg = "#FF2222"; # doesn't work 46 }; 47 }; 48 }; 49 }; 50 extraConfigLua = '' 51 -- Cross-platform background detection and colorscheme switching 52 local last_theme = nil 53 54 local function detect_and_set_theme() 55 local is_dark = false 56 57 if vim.fn.has("mac") == 1 then 58 -- macOS: check system appearance 59 local result = vim.fn.system("defaults read -g AppleInterfaceStyle 2>/dev/null") 60 is_dark = result:match("Dark") ~= nil 61 elseif vim.fn.has("unix") == 1 then 62 -- Linux: check if running under a dark theme 63 -- Check NixOS theme system first (always check this fresh) 64 local f = io.open("/var/theme/current_theme", "r") 65 if f then 66 local content = f:read("*all"):gsub("^%s+", ""):gsub("%s+$", "") 67 f:close() 68 is_dark = (content == "dark") 69 else 70 -- Fallback to other methods if theme file doesn't exist 71 local methods = { 72 -- GNOME/GTK 73 "gsettings get org.gnome.desktop.interface gtk-theme 2>/dev/null", 74 "gsettings get org.gnome.desktop.interface color-scheme 2>/dev/null", 75 -- KDE 76 "kreadconfig5 --file kdeglobals --group General --key ColorScheme 2>/dev/null", 77 -- Check if COLORFGBG suggests dark background 78 function() 79 local colorfgbg = vim.env.COLORFGBG 80 if colorfgbg then 81 local fg, bg = colorfgbg:match("(%d+);(%d+)") 82 if fg and bg then 83 -- If foreground is lighter than background, likely dark theme 84 return tonumber(fg) > tonumber(bg) 85 end 86 end 87 return false 88 end 89 } 90 91 for _, method in ipairs(methods) do 92 if type(method) == "function" then 93 is_dark = method() 94 if is_dark then break end 95 else 96 local result = vim.fn.system(method) 97 if result:match("[Dd]ark") or result:match("prefer%-dark") then 98 is_dark = true 99 break 100 end 101 end 102 end 103 end 104 end 105 106 local new_theme = is_dark and "dark" or "light" 107 108 if new_theme ~= last_theme then 109 last_theme = new_theme 110 vim.o.background = new_theme 111 112 if is_dark then 113 vim.cmd("colorscheme ayu") 114 else 115 vim.cmd("colorscheme everforest") 116 end 117 end 118 end 119 120 -- Set initial theme 121 vim.defer_fn(detect_and_set_theme, 100) 122 123 -- Check for theme changes every 3 seconds (less frequent to be less resource intensive) 124 local timer = vim.loop.new_timer() 125 timer:start(3000, 3000, vim.schedule_wrap(detect_and_set_theme)) 126 127 -- Create a command to manually refresh theme 128 vim.api.nvim_create_user_command("RefreshTheme", detect_and_set_theme, {}) 129 130 -- Configure lsp_lines to always show and disable default virtual_text 131 vim.diagnostic.config({ 132 virtual_text = false, 133 virtual_lines = true, 134 }) 135 ''; 136 globals = { 137 mapleader = " "; 138 }; 139 opts = { 140 mouse = "a"; 141 number = true; 142 shiftwidth = 2; 143 clipboard = "unnamedplus"; 144 # undo stuff 145 undofile = true; 146 undolevels = 10000; 147 undoreload = 10000; 148 listchars = "tab:⇥ ,extends:❯,precedes:❮,nbsp:␣,trail:·,eol:↲"; 149 }; 150 extraConfigVim = '' 151 set et 152 153 " show special characters 154 set list 155 156 " match trailing whitespace 157 match EoLSpace /\s\+$/ 158 159 " need to use lua to expand $HOME 160 lua vim.o.undodir = vim.fs.normalize('$HOME/.vim/undodir') 161 ''; 162 extraPlugins = [ 163 pkgs.vimPlugins.vim-fetch 164 ]; 165 keymaps = [ 166 { 167 mode = "i"; 168 key = "<C-p>"; 169 action = "<Nop>"; 170 } 171 { 172 mode = "i"; 173 key = "<C-n>"; 174 action = "<Nop>"; 175 } 176 { 177 mode = "n"; 178 key = "<C-c>"; 179 action = ":q<cr>"; 180 } 181 { 182 mode = "n"; 183 key = "<Space>"; 184 action = "<Nop>"; 185 } 186 { 187 mode = [ 188 "n" 189 "v" 190 ]; 191 key = "<leader>cc"; 192 action = ":CopilotChatOpen<cr>"; 193 } 194 { 195 mode = [ 196 "n" 197 "v" 198 ]; 199 key = "<leader>ce"; 200 action = ":CopilotChatExplain<cr>"; 201 } 202 { 203 mode = [ 204 "n" 205 "v" 206 ]; 207 key = "<leader>cr"; 208 action = ":CopilotChatReview<cr>"; 209 } 210 { 211 mode = [ 212 "n" 213 "v" 214 ]; 215 key = "<leader>cf"; 216 action = ":CopilotChatFix<cr>"; 217 } 218 { 219 mode = [ 220 "n" 221 "v" 222 ]; 223 key = "<leader>cd"; 224 action = ":CopilotChatDocs<cr>"; 225 } 226 { 227 mode = [ 228 "n" 229 "x" 230 ]; 231 key = "p"; 232 action = "<Plug>(YankyPutAfter)"; 233 } 234 { 235 mode = [ 236 "n" 237 "x" 238 ]; 239 key = "P"; 240 action = "<Plug>(YankyPutBefore)"; 241 } 242 { 243 mode = [ 244 "c" 245 "i" 246 "n" 247 "x" 248 ]; 249 key = "<M-CR>"; 250 action = ":lua vim.lsp.buf.code_action()<CR>"; 251 } 252 { 253 mode = [ 254 "n" 255 ]; 256 key = "gd"; 257 action = ":lua vim.lsp.buf.definition()<CR>"; 258 } 259 { 260 mode = [ 261 "n" 262 ]; 263 key = "gD"; 264 action = ":lua vim.lsp.buf.declaration()<CR>"; 265 } 266 { 267 mode = "n"; 268 key = "<leader>ll"; 269 action = ":lua require('lsp_lines').toggle()<CR>"; 270 options.desc = "Toggle lsp_lines"; 271 } 272 ]; 273 # autoCmd = [ 274 # { 275 # event = "BufWritePost"; 276 # desc = "run treefmt on save"; 277 # # https://stackoverflow.com/questions/77466697/how-to-automatically-format-on-save 278 # callback.__raw = '' 279 # function() 280 # vim.cmd("silent !treefmt %") 281 # vim.cmd("edit") 282 # end 283 # ''; 284 # } 285 # ]; 286 plugins.none-ls = { 287 enable = true; 288 # sources.formatting.treefmt = { 289 # enable = true; 290 # package = pkgs.emptyDirectory; 291 # }; 292 # package = pkgs.vimPlugins.none-ls-nvim.overrideAttrs (_old: { 293 # src = pkgs.fetchFromGitHub { 294 # owner = "lassulus"; 295 # repo = "none-ls.nvim"; 296 # rev = "292c2b5eadea0a097b9a01804aea70f5c8125200"; 297 # sha256 = "sha256-nbzqXsxmYfxngdJH3NXMLmGgygh6reSEnruoc6l8t/s="; 298 # }; 299 # }); 300 sources.formatting.nix_flake_fmt.enable = true; 301 }; 302 plugins.web-devicons.enable = true; 303 plugins.telescope.extensions.undo.enable = true; 304 plugins.telescope = { 305 enable = true; 306 keymaps = { 307 "<leader>b" = "buffers"; 308 "<leader>u" = "undo"; 309 "<leader>ff" = "find_files"; 310 "<leader>fg" = "live_grep"; 311 "<leader>fh" = "help_tags"; 312 "<leader>fp" = "yank_history"; 313 }; 314 }; 315 plugins.lsp-format.enable = true; 316 plugins.lsp = { 317 enable = true; 318 servers = { 319 bashls = { 320 enable = true; # bash 321 package = null; 322 }; 323 nixd = { 324 enable = true; # nix 325 package = null; 326 extraOptions.offset_encoding = "utf-8"; # workaround https://github.com/nix-community/nixvim/issues/2390#issuecomment-2408101568 327 }; 328 ruff = { 329 enable = true; # python 330 package = null; 331 }; 332 pyright = { 333 enable = true; # python 334 package = null; 335 }; 336 jsonls = { 337 enable = true; # json 338 package = null; 339 }; 340 }; 341 }; 342 plugins.treesitter = { 343 enable = true; 344 grammarPackages = with pkgs.vimPlugins.nvim-treesitter.builtGrammars; [ 345 bash 346 json 347 lua 348 markdown 349 markdown_inline 350 nix 351 python 352 toml 353 vim 354 vimdoc 355 yaml 356 ]; 357 }; 358 plugins.cmp_yanky.enable = true; 359 plugins.cmp = { 360 enable = true; 361 autoEnableSources = true; 362 settings = { 363 experimental = { 364 ghost_text = true; 365 }; 366 sources = [ 367 { name = "nvim_lsp"; } 368 { 369 name = "buffer"; # text within current buffer 370 option.get_bufnrs.__raw = "vim.api.nvim_list_bufs"; 371 keywordLength = 2; 372 } 373 { 374 name = "path"; # file system paths 375 keywordLength = 3; 376 } 377 { name = "cmp_yanky"; } 378 ]; 379 380 mapping = { 381 "<Tab>" = "cmp.mapping.select_next_item()"; 382 "<S-Tab>" = "cmp.mapping.select_prev_item()"; 383 "<C-n>" = "cmp.mapping.select_next_item()"; 384 "<C-p>" = "cmp.mapping.select_prev_item()"; 385 "<C-e>" = "cmp.mapping.abort()"; 386 "<C-b>" = "cmp.mapping.scroll_docs(-4)"; 387 "<C-f>" = "cmp.mapping.scroll_docs(4)"; 388 "<CR>" = '' 389 cmp.mapping({ 390 i = function(fallback) 391 if cmp.visible() and cmp.get_active_entry() then 392 cmp.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = false }) 393 else 394 fallback() 395 end 396 end, 397 s = cmp.mapping.confirm({ select = true }), 398 c = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = true }), 399 }) 400 ''; 401 }; 402 }; 403 }; 404 plugins.bufferline.enable = true; 405 plugins.which-key.enable = true; 406 plugins.yanky = { 407 enable = true; 408 enableTelescope = true; 409 }; 410 plugins.comment.enable = true; 411 plugins.undotree.enable = true; # seems to be needed for undo history in telescope 412 plugins.gitsigns.enable = true; 413 }; 414 }; 415}