{ pkgs, ... }: { programs.nixvim = { enable = true; defaultEditor = true; # Global settings globals.mapleader = " "; # Vim options opts = { number = true; relativenumber = false; expandtab = true; shiftwidth = 2; tabstop = 2; smartindent = true; wrap = false; linebreak = true; # Don't break words when wrapping breakindent = true; # Preserve indentation when wrapping termguicolors = true; autoread = true; # Automatically reload files when changed externally }; # Enable filetype detection viAlias = true; vimAlias = true; # Gruvbox colorscheme with hard contrast colorschemes.gruvbox = { enable = true; settings = { contrast = "hard"; # Makes background much darker (#1d2021 instead of #282828) background = "dark"; }; }; # Plugins plugins = { # File explorer nvim-tree = { enable = true; # NixVim nvim-tree uses extraConfig for detailed settings }; # Syntax highlighting treesitter = { enable = true; settings = { highlight = { enable = true; additional_vim_regex_highlighting = true; }; indent = { enable = true; }; ensure_installed = []; # Managed by Nix auto_install = false; }; grammarPackages = with pkgs.vimPlugins.nvim-treesitter.builtGrammars; [ bash c cpp css dockerfile go html javascript json lua markdown nix python rust typescript yaml ]; }; # Status line with gruvbox theme and relative paths lualine = { enable = true; settings = { options = { theme = "gruvbox_dark"; component_separators = { left = "|"; right = "|"; }; section_separators = { left = " "; right = " "; }; }; sections = { lualine_c = [{ __unkeyed-1 = "filename"; path = 1; }]; }; }; }; # Web dev icons web-devicons = { enable = true; }; # Markdown rendering render-markdown = { enable = true; }; # Basic auto-completion cmp = { enable = true; autoEnableSources = true; settings = { sources = [ { name = "buffer"; } # Words from open buffers { name = "path"; } # File system paths ]; mapping = { "" = "cmp.mapping.complete()"; # Trigger completion manually "" = "cmp.mapping.close()"; # Close completion menu "" = "cmp.mapping.confirm({ select = true })"; # Accept selected completion "" = "cmp.mapping.select_next_item()"; # Navigate down in menu "" = "cmp.mapping.select_prev_item()"; # Navigate up in menu }; }; }; }; # Extra plugins that don't have dedicated modules extraPlugins = with pkgs.vimPlugins; [ vim-fugitive ]; # Keymaps keymaps = [ # File explorer { mode = "n"; key = "e"; action = ":NvimTreeToggle"; options = { desc = "Toggle file explorer"; }; } # Basic keymaps { mode = "n"; key = "w"; action = ":w"; options = { desc = "Save file"; }; } { mode = "n"; key = "q"; action = ":q"; options = { desc = "Quit"; }; } # System clipboard keymaps { mode = ["n" "v"]; key = "y"; action = "\"+y"; options = { desc = "Copy to system clipboard"; }; } { mode = "n"; key = "p"; action = "\"+p"; options = { desc = "Paste from system clipboard"; }; } { mode = "v"; key = "p"; action = "\"+p"; options = { desc = "Replace selection with system clipboard"; }; } # System integration { mode = "n"; key = "o"; action = ":lua open_file_with_system_app()"; options = { desc = "Open file with system default app"; }; } { mode = "n"; key = "f"; action = ":lua show_file_in_finder()"; options = { desc = "Show current file in Finder"; }; } # Git keymaps (vim-fugitive) { mode = "n"; key = "gs"; action = ":Git"; options = { desc = "Git status"; }; } { mode = "n"; key = "gd"; action = ":Git diff"; options = { desc = "Git diff"; }; } { mode = "n"; key = "gc"; action = ":Git commit"; options = { desc = "Git commit"; }; } { mode = "n"; key = "gp"; action = ":Git push"; options = { desc = "Git push"; }; } # Markdown rendering { mode = "n"; key = "md"; action = ":RenderMarkdown toggle"; options = { desc = "Toggle markdown rendering"; }; } ]; # Additional Lua configuration for plugins that need custom setup extraConfigLua = '' -- Nvim-tree setup with filters require("nvim-tree").setup({ filters = { dotfiles = true, -- Hide dotfiles by default (H to toggle) git_ignored = false, -- Show gitignored files by default (I to toggle) custom = { -- Hide macOS system files ".DS_Store", }, }, }) -- Unicode-safe file operations for macOS function open_file_with_system_app() local filepath = vim.fn.expand('%:p') if filepath ~= "" then local escaped_path = vim.fn.shellescape(filepath) vim.fn.system('open ' .. escaped_path) else print("No file to open") end end function show_file_in_finder() local filepath = vim.fn.expand('%:p') if filepath ~= "" then local escaped_path = vim.fn.shellescape(filepath) vim.fn.system('open -R ' .. escaped_path) else print("No file to show") end end ''; }; }