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