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