diff --git a/flake.nix b/flake.nix index c639f64..1c7bbcc 100644 --- a/flake.nix +++ b/flake.nix @@ -35,6 +35,15 @@ picokontroller.url = "git+https://git.ghoscht.com/ghoscht/picoKontroller"; sops-nix.url = "github:Mic92/sops-nix"; arion.url = "github:hercules-ci/arion"; + + + + + + nixvim = { + url = "github:nix-community/nixvim/nixos-24.11"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = { diff --git a/home/features/coding/default.nix b/home/features/coding/default.nix index 006bbeb..1558324 100644 --- a/home/features/coding/default.nix +++ b/home/features/coding/default.nix @@ -1,6 +1,7 @@ {pkgs, ...}: { imports = [ - ./nvim + # ./nvim + ./nixvim ./vscode.nix ./intellij.nix ./tmux.nix diff --git a/home/features/coding/nixvim/cmp.nix b/home/features/coding/nixvim/cmp.nix new file mode 100644 index 0000000..4d0d005 --- /dev/null +++ b/home/features/coding/nixvim/cmp.nix @@ -0,0 +1,95 @@ +{ + programs.nixvim.plugins = { + cmp-emoji = { + enable = true; + }; + + cmp = { + enable = true; + settings = { + completion = { + completeopt = "menu,menuone,noinsert"; + }; + autoEnableSources = true; + experimental = {ghost_text = true;}; + performance = { + debounce = 60; + fetchingTimeout = 200; + maxViewEntries = 30; + }; + snippet = { + expand = '' + function(args) + require('luasnip').lsp_expand(args.body) + end + ''; + }; + formatting = {fields = ["kind" "abbr" "menu"];}; + sources = [ + {name = "nvim_lsp";} + {name = "emoji";} + { + name = "buffer"; # text within current buffer + option.get_bufnrs.__raw = "vim.api.nvim_list_bufs"; + keywordLength = 3; + } + # { name = "copilot"; } # enable/disable copilot + { + name = "path"; # file system paths + keywordLength = 3; + } + { + name = "luasnip"; # snippets + keywordLength = 3; + } + ]; + + window = { + completion = {border = "solid";}; + documentation = {border = "solid";}; + }; + + mapping = { + "" = "cmp.mapping(cmp.mapping.select_next_item(), {'i', 's'})"; + "" = "cmp.mapping.select_next_item()"; + "" = "cmp.mapping.select_prev_item()"; + "" = "cmp.mapping.abort()"; + "" = "cmp.mapping.scroll_docs(-4)"; + "" = "cmp.mapping.scroll_docs(4)"; + "" = "cmp.mapping.complete()"; + "" = "cmp.mapping.confirm({ select = true })"; + "" = "cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = true })"; + "" = '' + cmp.mapping(function() + if luasnip.expand_or_locally_jumpable() then + luasnip.expand_or_jump() + end + end, { 'i', 's' }) + ''; + "" = '' + cmp.mapping(function() + if luasnip.locally_jumpable(-1) then + luasnip.jump(-1) + end + end, { 'i', 's' }) + ''; + }; + }; + }; + cmp-nvim-lsp = { + enable = true; # LSP + }; + cmp-buffer = { + enable = true; + }; + cmp-path = { + enable = true; # file system paths + }; + cmp_luasnip = { + enable = true; # snippets + }; + cmp-cmdline = { + enable = true; # autocomplete for cmdline + }; + }; +} diff --git a/home/features/coding/nixvim/default.nix b/home/features/coding/nixvim/default.nix new file mode 100644 index 0000000..321ee8a --- /dev/null +++ b/home/features/coding/nixvim/default.nix @@ -0,0 +1,12 @@ +{inputs, ...}: { + imports = [ + inputs.nixvim.homeManagerModules.nixvim + ./options.nix + ./plugins.nix + ./cmp.nix + ./lsp.nix + ./none-ls.nix + ./keymaps.nix + ]; + programs.nixvim.enable = true; +} diff --git a/home/features/coding/nixvim/keymaps.nix b/home/features/coding/nixvim/keymaps.nix new file mode 100644 index 0000000..8071b65 --- /dev/null +++ b/home/features/coding/nixvim/keymaps.nix @@ -0,0 +1,112 @@ +{ + programs.nixvim.keymaps = [ + { + mode = [ + "n" + "v" + ]; + key = "fc"; + action = "lua vim.lsp.buf.format()"; + options = { + silent = true; + desc = "Format Code"; + }; + } + { + mode = "n"; + key = "ch"; + action = "noh"; + options = { + desc = "Clear Highlighting"; + }; + } + { + mode = "n"; + key = ""; + action = "Telescope live_grep"; + options = { + desc = "Telescope LiveGrep"; + }; + } + { + mode = "n"; + key = "fg"; + action = "Telescope find_files"; + options = { + desc = "Telescope File Search"; + }; + } + { + mode = "n"; + key = ""; + action = "Neotree toggle"; + options = { + desc = "Toggle Neotree"; + }; + } + { + mode = "n"; + key = ""; + action = "tabnew"; + options = { + desc = "New Tab"; + }; + } + { + mode = "n"; + key = "]"; + action = "BufferNext"; + options = { + desc = "Next Tab"; + }; + } + { + mode = "n"; + key = "d"; + action = "BufferClose"; + options = { + desc = "Close Tab"; + }; + } + { + mode = "n"; + key = "["; + action = "BufferPrevious"; + options = { + desc = "Previous Tab"; + }; + } + { + mode = "n"; + key = ""; + action = ":wincmd k"; + options = { + desc = "Go Up"; + }; + } + { + mode = "n"; + key = ""; + action = ":wincmd j"; + options = { + desc = "Go Down"; + }; + } + { + mode = "n"; + key = ""; + action = ":wincmd h"; + options = { + desc = "Go Left"; + }; + } + { + mode = "n"; + key = ""; + action = ":wincmd l"; + options = { + desc = "Go Right"; + }; + } + ]; +} diff --git a/home/features/coding/nixvim/lsp.nix b/home/features/coding/nixvim/lsp.nix new file mode 100644 index 0000000..6149c0f --- /dev/null +++ b/home/features/coding/nixvim/lsp.nix @@ -0,0 +1,25 @@ +{ + programs.nixvim.plugins.lsp = { + enable = true; + inlayHints = true; + + servers = { + ts_ls.enable = true; # TS/JS + cssls.enable = true; # CSS + html.enable = true; # HTML + pyright.enable = true; # Python + marksman.enable = true; # Markdown + nil_ls.enable = true; # Nix + dockerls.enable = true; # Docker + bashls.enable = true; # Bash + clangd.enable = true; # C/C++ + yamlls.enable = true; # YAML + + lua_ls = { + # Lua + enable = true; + settings.telemetry.enable = false; + }; + }; + }; +} diff --git a/home/features/coding/nixvim/none-ls.nix b/home/features/coding/nixvim/none-ls.nix new file mode 100644 index 0000000..eefc92b --- /dev/null +++ b/home/features/coding/nixvim/none-ls.nix @@ -0,0 +1,42 @@ +{ + programs.nixvim.plugins = { + none-ls = { + enable = true; + sources = { + code_actions = { + statix.enable = true; + gitsigns.enable = true; + }; + diagnostics = { + statix.enable = true; + deadnix.enable = true; + pylint.enable = true; + checkstyle.enable = true; + }; + formatting = { + alejandra.enable = true; + stylua.enable = true; + shfmt.enable = true; + nixpkgs_fmt.enable = true; + google_java_format.enable = false; + prettier = { + enable = true; + disableTsServerFormatter = true; + }; + black = { + enable = true; + settings = '' + { + extra_args = { "--fast" }, + } + ''; + }; + }; + completion = { + luasnip.enable = true; + spell.enable = true; + }; + }; + }; + }; +} diff --git a/home/features/coding/nixvim/options.nix b/home/features/coding/nixvim/options.nix new file mode 100644 index 0000000..8ae2eba --- /dev/null +++ b/home/features/coding/nixvim/options.nix @@ -0,0 +1,52 @@ +{ + programs.nixvim = { + config = { + # System clipboard support, needs xclip/wl-clipboard + clipboard = { + providers = { + wl-copy.enable = true; # Wayland + xsel.enable = true; # For X11 + }; + register = "unnamedplus"; + }; + globals.mapleader = " "; + opts = { + number = true; # Show line numbers + relativenumber = true; # Show relative line numbers + shiftwidth = 2; # Tab width should be 2 + + # Always show the signcolumn, otherwise text would be shifted when displaying error icons + signcolumn = "yes"; + + # Enable mouse + mouse = "a"; + + # Search + ignorecase = true; + smartcase = true; + + # Save undo history + undofile = true; + + # Global substitution by default + gdefault = true; + + # Start scrolling when the cursor is X lines away from the top/bottom + scrolloff = 8; + + # Enable 24-bit RGB color in the TUI + termguicolors = true; + + # Wrap long lines at a character in 'breakat' + linebreak = true; + + smartindent = true; + + # Remove EOB + fillchars = { + eob = " "; + }; + }; + }; + }; +} diff --git a/home/features/coding/nixvim/plugins.nix b/home/features/coding/nixvim/plugins.nix new file mode 100644 index 0000000..f5d5660 --- /dev/null +++ b/home/features/coding/nixvim/plugins.nix @@ -0,0 +1,112 @@ +{ pkgs, ... }: { + programs.nixvim.plugins = { + lualine.enable = true; + oil.enable = true; + nvim-surround.enable = true; + + treesitter = { + enable = true; + grammarPackages = with pkgs.vimPlugins.nvim-treesitter.builtGrammars; [ + markdown + # nix + vim + bash + lua + python + json + java + rust + cpp + c + css + csv + dockerfile + diff + gitignore + git_config + gitattributes + make + yaml + toml + typescript + xml + ]; + }; + + # Autopairs + nvim-autopairs = { + enable = true; + }; + + luasnip.enable = true; + lazygit.enable = true; + barbar.enable = true; + rainbow-delimiters.enable = true; + web-devicons.enable = true; + + telescope = { + enable = true; + extensions = { + fzf-native = { + enable = true; + }; + }; + }; + + # Dashboard + alpha = { + enable = true; + theme = "dashboard"; + }; + # File tree + neo-tree = { + enable = true; + enableDiagnostics = false; + enableGitStatus = true; + enableModifiedMarkers = true; + enableRefreshOnWrite = true; + closeIfLastWindow = true; + popupBorderStyle = "rounded"; # Type: null or one of “NC”, “double”, “none”, “rounded”, “shadow”, “single”, “solid” or raw lua code + buffers = { + bindToCwd = false; + followCurrentFile = { + enabled = true; + }; + }; + window = { + width = 40; + height = 15; + autoExpandWidth = false; + mappings = { + "" = "none"; + }; + }; + }; + + # Todo comments + todo-comments = { + enable = true; + settings.colors = { + error = [ "DiagnosticError" "ErrorMsg" "#DC2626" ]; + warning = [ "DiagnosticWarn" "WarningMsg" "#FBBF24" ]; + info = [ "DiagnosticInfo" "#2563EB" ]; + hint = [ "DiagnosticHint" "#10B981" ]; + default = [ "Identifier" "#7C3AED" ]; + test = [ "Identifier" "#FF00FF" ]; + }; + }; + + # Highlight word under cursor + illuminate = { + enable = true; + underCursor = false; + filetypesDenylist = [ + "Outline" + "TelescopePrompt" + "alpha" + "harpoon" + "reason" + ]; + }; + }; +} diff --git a/home/features/coding/nvim/plugin/lsp.lua b/home/features/coding/nvim/plugin/lsp.lua index fdcbe72..f2cc50a 100644 --- a/home/features/coding/nvim/plugin/lsp.lua +++ b/home/features/coding/nvim/plugin/lsp.lua @@ -44,7 +44,7 @@ require("lspconfig").nixd.setup({ capabilities = capabilities, }) -require("lspconfig").tsserver.setup({ +require("lspconfig").ts_lsp.setup({ on_attach = on_attach, capabilities = capabilities, })