diff --git a/flake.nix b/flake.nix index 1eef6d3..69b55fb 100644 --- a/flake.nix +++ b/flake.nix @@ -20,8 +20,9 @@ outputs = { self, nixpkgs, home-manager, ... }@inputs: let inherit (self) outputs; - system = "x86_64-linux"; + systems = [ "x86_64-linux" "aarch64-linux" ]; lib = nixpkgs.lib // home-manager.lib; + forEachSystem = f: lib.genAttrs systems (sys: f pkgsFor.${sys}); pkgsFor = nixpkgs.legacyPackages; in { @@ -29,6 +30,8 @@ homeManagerModules = import ./modules/home-manager; + packages = forEachSystem (pkgs: import ./pkgs { inherit pkgs; }); + nixosConfigurations = { # X1 Carbon ooksx1 = lib.nixosSystem { diff --git a/home/ooks/opt/nvim/default.nix b/home/ooks/opt/nvim/default.nix index b4ca427..340aeb0 100644 --- a/home/ooks/opt/nvim/default.nix +++ b/home/ooks/opt/nvim/default.nix @@ -1,14 +1,62 @@ -{ pkgs, ... }: +{ config, pkgs, lib, ... }: +# Let-In ----------------------------------------------------------------------------------------{{{ +let + inherit (lib) concatStringsSep optional; + inherit (config.lib.file) mkOutOfStoreSymlink; + # customNvChad = ./nvchad-custom; + populateEnv = ./populate-nvim-env.py; + + populateEnvScript = '' + mkdir -p ${config.xdg.dataHome}/nvim/site/plugin + ${pkgs.python39}/bin/python ${populateEnv} -o ${config.xdg.dataHome}/nvim/site/plugin + ''; + # }}} +in { + # Neovim + # https://rycee.gitlab.io/home-manager/options.html#opt-programs.neovim.enable + programs.neovim.enable = true; - home.sessionVariables.EDITOR = "nvim"; + programs.neovim.viAlias = true; + programs.neovim.vimAlias = true; - programs = { - neovim = { - enable = true; - viAlias = true; - }; + # Config and plugins ------------------------------------------------------------------------- {{{ + + xdg.configFile."nvim" = { + source = "${pkgs.nvchad}"; }; + home.packages = with pkgs; [ + nvchad + (pkgs.writeShellScriptBin "update-nvim-env" '' + # + # update-nvim-env + # + # Update neovim env such that it can be used in neovide or other GUIs. + ${populateEnvScript} + '') + ]; + + home.activation.neovim = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + echo "Populating neovim env..." + ${populateEnvScript} + ''; + + programs.bash.initExtra = lib.mkAfter '' + export EDITOR="${config.programs.neovim.package}/bin/nvim" + ''; + + programs.zsh.initExtra = lib.mkAfter '' + export EDITOR="${config.programs.neovim.package}/bin/nvim" + ''; + + # Required packages -------------------------------------------------------------------------- {{{ + + programs.neovim.extraPackages = with pkgs; [ + nodejs_20 + gcc + ]; + # }}} } +# vim: foldmethod=marker diff --git a/home/ooks/opt/nvim/populate-nvim-env.py b/home/ooks/opt/nvim/populate-nvim-env.py new file mode 100644 index 0000000..8e9ae19 --- /dev/null +++ b/home/ooks/opt/nvim/populate-nvim-env.py @@ -0,0 +1,72 @@ +#!/bin/env python3 + +import os +from collections import OrderedDict +import argparse + +KEYS = [ + # PATH + "PATH", + "CS154_ADMIN", + "BREW_PREFIX", + "CONDA_PYTHON_EXE", + "SPACESHIP_ROOT", + "COLORFGBG", + "XPC_SERVICE_NAME", + "_CE_M", + "XPC_FLAGS", + "LANG", + # terminal + "VISUAL", + "LESS", + "LOGNAME", + "COLORTERM", + "HISTFILE", + "LC_TERMINAL", + "LC_TERMINAL_VERSION", + "ITERM_SESSION_ID", + "ITERM_PROFILE", + "TERM_SESSION_ID", + "TERM_PROGRAM", + "STARSHIP_SESSION_KEY", + "STARSHIP_CONFIG", + "VI_MODE_SET_CURSOR", + "_", + "LSCOLORS", + "ZSH", + "EDITOR", + # XDG + "XDG_DATA_HOME", + "XDG_STATE_HOME", + "XDG_CACHE_HOME", + "XDG_CONFIG_HOME", +] + + +def main(output_path): + env = os.environ.copy() + env = OrderedDict(sorted(env.items())) + dst_file = "{}/env.lua".format(output_path) + with open(dst_file, "w") as f: + for key, value in env.items(): + if key in KEYS: + if key == "PATH": + f.write('vim.env.PATH = vim.env.PATH .. ":{}"\n'.format(value)) + continue + f.write('vim.fn.setenv("{}", "{}")\n'.format(key, value)) + f.close() + + +if __name__ == "__main__": + home_directory = os.path.expanduser("~") + parser = argparse.ArgumentParser("Neovim Populate Env") + parser.add_argument( + "-o", + "--output", + required=False, + help="Output Path", + type=str, + default="{}/.config/nvim/lua/toutaboc".format(home_directory), + ) + args = parser.parse_args() + main(args.output) diff --git a/home/ooks/opt/shell/default.nix b/home/ooks/opt/shell/default.nix index c8e2d32..c52a61d 100644 --- a/home/ooks/opt/shell/default.nix +++ b/home/ooks/opt/shell/default.nix @@ -23,6 +23,7 @@ tldr # Community maintained help pages tmux # Terminal multiplexer tre-command # Better tree + unzip ]; programs = { diff --git a/pkgs/default.nix b/pkgs/default.nix new file mode 100644 index 0000000..a505f5c --- /dev/null +++ b/pkgs/default.nix @@ -0,0 +1,4 @@ +{ pkgs ? (import ../nixpkgs.nix) { } }: { + # example = pkgs.callPackage ./example { }; + nvchad = pkgs.callPackage ./nvchad { }; +} diff --git a/pkgs/nvchad/custom/chadrc.lua b/pkgs/nvchad/custom/chadrc.lua new file mode 100644 index 0000000..e316284 --- /dev/null +++ b/pkgs/nvchad/custom/chadrc.lua @@ -0,0 +1,30 @@ +---@type ChadrcConfig +local M = {} + +M.ui = { + theme_toggle = {}, + theme = "gruvbox", + transparency = false, + + changed_themes = { + everforest = { + base_30 = { + darker_black = "#272f35", + black = "#252e34", -- nvim bg + black2 = "#323a40", + one_bg = "#363e44", + one_bg2 = "#363e44", + one_bg3 = "#3a4248", + }, + }, + }, +} + +M.plugins = "custom.plugins" +M.mappings = require("custom.mappings") + +M.lazy_nvim = { + lockfile = vim.fn.stdpath("data") .. "/lazy-lock.json", +} + +return M diff --git a/pkgs/nvchad/custom/init.lua b/pkgs/nvchad/custom/init.lua new file mode 100644 index 0000000..bb906cf --- /dev/null +++ b/pkgs/nvchad/custom/init.lua @@ -0,0 +1,37 @@ +local autocmd = vim.api.nvim_create_autocmd + +vim.api.nvim_create_autocmd("BufWritePre", { + pattern = "*", + command = ":%s/s+$//e", +}) + +-- remove trailing whitespace +local remove_spaces_group = vim.api.nvim_create_augroup("RemoveSpaces", { clear = true }) +vim.api.nvim_create_autocmd("BufWritePre", { + pattern = "*", + command = ":%s/s+$//e", + group = remove_spaces_group, +}) + +-- [[ Highlight on yank ]] +-- See `:help vim.highlight.on_yank()` +local highlight_group = vim.api.nvim_create_augroup("YankHighlight", { clear = true }) +vim.api.nvim_create_autocmd("TextYankPost", { + callback = function() + vim.highlight.on_yank() + end, + group = highlight_group, + pattern = "*", +}) + +-- Options + +-- Relative number +vim.wo.relativenumber = true +vim.opt.relativenumber = true + +-- Notify me for line length +vim.opt.colorcolumn = "80" + +-- Cursor +vim.opt.guicursor = "" diff --git a/pkgs/nvchad/custom/mappings.lua b/pkgs/nvchad/custom/mappings.lua new file mode 100644 index 0000000..84dd3f1 --- /dev/null +++ b/pkgs/nvchad/custom/mappings.lua @@ -0,0 +1,187 @@ +---@type MappingsConfig +local M = {} + +M.general = { + n = { + [";"] = { ":", "enter command mode", opts = { nowait = true } }, + ["gc"] = { + function() + require("Comment.api").toggle.linewise.current() + end, + "toggle comment", + }, + ["gcc"] = { + function() + require("Comment.api").toggle.linewise.current() + end, + "toggle comment", + }, + }, + v = { + ["gc"] = { + "lua require('Comment.api').toggle.linewise(vim.fn.visualmode())", + "toggle comment", + }, + ["gcc"] = { + "lua require('Comment.api').toggle.linewise(vim.fn.visualmode())", + "toggle comment", + }, + }, +} + +M.file = { + n = { + -- file / directory + ["fF"] = { + function() + require("telescope.builtin").find_files({ cwd = vim.fn.expand("%:p:h") }) + end, + "[F]ind [F]iles in current directory", + }, + ["fo"] = { + function() + require("telescope.builtin").oldfiles() + end, + "[F]ind recently [o]pened files", + }, + ["fs"] = { " :w ", "[F]ile [S]ave" }, + ["fw"] = { function() end, "Nothing" }, + }, +} + +M.search = { + n = { + -- search + ["sd"] = { + function() + require("telescope.builtin").diagnostics() + end, + "[S]earch [D]iagnostics", + }, + ["sf"] = { + function() + require("telescope.builtin").find_files() + end, + "[S]earch [F]iles", + }, + ["sh"] = { + function() + require("telescope.builtin").help_tags() + end, + "[S]earch [H]elp", + }, + ["sw"] = { + function() + require("telescope.builtin").grep_string() + end, + "[S]earch current [W]ord", + }, + ["sp"] = { + function() + require("telescope.builtin").live_grep() + end, + "[S]earch by gre[p]", + }, + ["sg"] = { + function() + require("telescope.builtin").live_grep() + end, + "[S]earch by [g]rep", + }, + ["so"] = { + function() + require("telescope.builtin").oldfiles() + end, + "[S]earch recently [o]pened files", + }, + ["sG"] = { + function() + require("telescope").extensions.live_grep_args.live_grep_args({ cwd = vim.fn.expand("%:p:h") }) + end, + "[S]earch by [G]rep in current directory", + }, + }, +} + +M.buffer = { + n = { + ["bd"] = { "bpspbnbd", "[B]uffer [D]elete" }, + ["bb"] = { + function() + require("telescope.builtin").buffers() + end, + "[B]rowse [B]uffers", + }, + }, +} + +M.window = { + n = { + ["ws"] = { " :split ", "[W]indow Horizontal [S]plit" }, -- split horizontal + ["wv"] = { " :vsplit ", "[W]indow [V]ertical Split" }, -- split vertical + ["wh"] = { " :TmuxNavigateLeft", "Go to Left [W]indow" }, + ["wj"] = { " :TmuxNavigateDown", "Go to [W]indow Below" }, + ["wk"] = { " :TmuxNavigateUp", "Go to Top [W]indow" }, + ["wl"] = { " :TmuxNavigateRight", "Go to Right [W]indow" }, + ["wq"] = { "q", "[W]indow [Q]uit" }, -- quit + }, +} + +M.term = { + n = { + ["tf"] = { " :ToggleTerm direction=float", "[T]erm [F]loat" }, + ["tt"] = { " :ToggleTerm direction=tab", "[T]erm [T]ab" }, + ["th"] = { " :ToggleTerm direction=horizontal", "[T]erm [H]orizontal" }, + ["tv"] = { " :ToggleTerm direction=vertical", "[T]erm [V]ertical" }, + ["ht"] = { + function() + require("custom.term").htop:toggle() + end, + "[H]top", + }, + [""] = { " :ToggleTerm direction=horizontal", "[T]erm [H]orizontal" }, + }, +} + +M.git = { + n = { + ["gg"] = { + function() + require("custom.term").lazygit:toggle() + end, + "Lazy[G]it", + }, + ["gl"] = { + function() + require("custom.term").lazygit:toggle() + end, + "[L]azy[G]it", + }, + }, +} + +M.lsp = { + n = { + -- ["gD"] = { + -- function() + -- vim.lsp.buf.declaration() + -- end, + -- "lsp declaration", + -- }, + -- + -- ["gd"] = { + -- function() + -- vim.lsp.buf.definition() + -- end, + -- "lsp definition", + -- }, + + ["gh"] = { "Lspsaga lsp_finder" }, + -- ["K"] = { "Lspsaga hover_doc", "Hover Documentation" }, + ["ld"] = { "Lspsaga show_line_diagnostics", "[L]ine [D]iagnostics" }, + ["cd"] = { "Lspsaga show_cursor_diagnostics", "[C]ursor [D]iagnostics" }, + ["ad"] = { "Lspsaga show_buffer_diagnostics", "Buffer [D]iagnostics" }, + }, +} + +return M diff --git a/pkgs/nvchad/custom/plugins.lua b/pkgs/nvchad/custom/plugins.lua new file mode 100644 index 0000000..2c0d145 --- /dev/null +++ b/pkgs/nvchad/custom/plugins.lua @@ -0,0 +1,396 @@ +return { + { "preservim/vimux" }, + { + "christoomey/vim-tmux-navigator", + cmd = { "TmuxNavigateLeft", "TmuxNavigateDown", "TmuxNavigateUp", "TmuxNavigateRight" }, + keys = { "", "", "", "" }, + }, + { "JoosepAlviste/nvim-ts-context-commentstring" }, + { "nvim-treesitter/nvim-treesitter-textobjects" }, + { "mrjones2014/nvim-ts-rainbow" }, + { "nvim-treesitter/nvim-treesitter-context" }, + + { + "glepnir/lspsaga.nvim", + event = "BufRead", + cmd = { "Lspsaga" }, + config = function() + require("lspsaga").setup({}) + end, + dependencies = { + { "nvim-tree/nvim-web-devicons" }, + { "nvim-treesitter/nvim-treesitter" }, + }, + }, + + -- Copilot + { + "zbirenbaum/copilot.lua", + event = "VimEnter", + config = function() + vim.defer_fn(function() + require("copilot").setup({ + suggestion = { + keymap = { + accept = "", + accept_word = false, + accept_line = false, + next = "", + prev = "", + dismiss = "", + }, + -- auto_trigger = true, + }, + }) + end, 100) + end, + }, + { + "zbirenbaum/copilot-cmp", + event = "VeryLazy", + dependencies = { "zbirenbaum/copilot.lua" }, + config = function() + require("copilot_cmp").setup() + end, + }, + + -- Git + { "tpope/vim-fugitive" }, + { "tpope/vim-rhubarb" }, + { "lewis6991/gitsigns.nvim" }, + + -- theme + -- { + -- "sainnhe/everforest", + -- lazy = false, + -- priority = 1000, + -- config = function() + -- vim.g.everforest_background = "hard" + -- vim.cmd([[colorscheme everforest]]) + -- end, + -- }, + + -- Others + { + "Pocco81/TrueZen.nvim", + cmd = { "TZNarrow", "TZFocus", "TZMinimalist", "TZAtaraxis" }, + config = true, + }, + { + "nathom/filetype.nvim", + opts = function() + return { + overrides = { + extensions = { + mdx = "markdown", + }, + function_complex = { + [".*blade.php"] = function() + vim.bo.filetype = "blade" + end, + }, + }, + } + end, + }, + { + "mg979/vim-visual-multi", + -- keys = { "" }, + lazy = false, + init = function(_) + vim.g.VM_Mono_hl = "Substitute" + vim.g.VM_Cursor_hl = "IncSearch" + + vim.g.VM_maps = { + ["Find Under"] = "", + ["Find Subword Under"] = "", + ["Next"] = "n", + ["Previous"] = "N", + ["Skip"] = "q", + -- ["Add Cursor Down"] = "", + -- ["Add Cursor Up"] = "", + -- ["Select l"] = "", + -- ["Select r"] = "", + -- ["Add Cursor at Position"] = [[\\\]], + ["Select All"] = "", + ["Visual All"] = "", + ["Exit"] = "", + } + end, + }, + { + "akinsho/toggleterm.nvim", + event = "VeryLazy", + cmd = { "ToggleTerm" }, + version = "*", + config = true, + --opts = function() + -- require("toggleterm").setup() + --end, + }, + { + "tpope/vim-surround", + dependencies = { + "tpope/vim-repeat", + }, + }, + { + "iamcco/markdown-preview.nvim", + build = "cd app && npm install", + config = function() + vim.g.mkdp_filetypes = { "markdown" } + end, + ft = { "markdown" }, + }, + { + "ggandor/leap.nvim", + config = function() + require("leap").add_default_mappings() + end, + }, + + -- LSPs + { + "neovim/nvim-lspconfig", + config = function(_, _) + require("plugins.configs.lspconfig") + local on_attach = require("plugins.configs.lspconfig").on_attach + local capabilities = require("plugins.configs.lspconfig").capabilities + + local lspconfig = require("lspconfig") + local servers = { + -- lua stuff + "lua_ls", + + -- shell + "bashls", + -- "awk_ls", + + -- c + "clangd", + + -- rust + "rust_analyzer", + + -- web dev + "cssls", + "html", + "tsserver", + "jsonls", + "tailwindcss", + "eslint", + + -- python + "pyright", + + -- yaml + "yamlls", + } + + for _, lsp in ipairs(servers) do + lspconfig[lsp].setup({ + on_attach = on_attach, + capabilities = capabilities, + }) + end + end, + }, + { + "jose-elias-alvarez/null-ls.nvim", + event = { "BufReadPre", "BufNewFile" }, + dependencies = { + "neovim/nvim-lspconfig", + "mason.nvim", + }, + opts = function() + -- null-ls + -- to setup format on save + local null_ls = require("null-ls") + + local formatting = null_ls.builtins.formatting -- to setup formatters + local diagnostics = null_ls.builtins.diagnostics -- to setup linters + local code_actions = null_ls.builtins.code_actions -- to setup code actions + local completion = null_ls.builtins.completion -- to setup completions + + local lsp_formatting_group = vim.api.nvim_create_augroup("LspFormatting", {}) + + -- configure null_ls + return { + debug = false, + -- setup formatters & linters + sources = { + completion.spell, + code_actions.gitsigns, + + -- lua + formatting.stylua, + + -- web stuffs + formatting.prettier.with({ + extra_filetypes = { "svelte" }, + }), -- js/ts formatter + diagnostics.eslint_d.with({ -- js/ts linter + -- only enable eslint if root has .eslintrc.js (not in youtube nvim video) + condition = function(utils) + return utils.root_has_file(".eslintrc.js") or utils.root_has_file(".eslintrc.cjs") -- change file extension if you use something else + end, + filetypes = { + "javascript", + "javascriptreact", + "typescript", + "typescriptreact", + "vue", + "svelte", + }, + }), + code_actions.eslint_d.with({ + filetypes = { + "javascript", + "javascriptreact", + "typescript", + "typescriptreact", + "vue", + "svelte", + }, + }), + + -- php + diagnostics.php, + formatting.blade_formatter, + -- formatting.pint, + + -- python + formatting.black, + + -- shell + formatting.shfmt, + formatting.jq, + + -- rust + formatting.rustfmt, + + -- c / c++ + formatting.clang_format, + + -- nix + formatting.nixpkgs_fmt, + -- formatting.nixfmt, + + -- config + formatting.taplo, + }, + -- configure format on save + on_attach = function(current_client, bufnr) + if current_client.supports_method("textDocument/formatting") then + vim.api.nvim_clear_autocmds({ group = lsp_formatting_group, buffer = bufnr }) + vim.api.nvim_create_autocmd("BufWritePre", { + group = lsp_formatting_group, + buffer = bufnr, + callback = function() + -- print("HERE 1", current_client.name) + -- vim.lsp.buf.formatting_sync() + vim.lsp.buf.format({ + bufnr = bufnr, + filter = function(client) + -- print("HERE 2", current_client.name, client.name) + -- only use null-ls for formatting instead of lsp server + return client.name == "null-ls" + end, + }) + end, + }) + end + end, + } + end, + }, + + { + "williamboman/mason.nvim", + opts = function() + return { + ensure_installed = { + -- lua stuff + "lua-language-server", + "stylua", + + -- shell + "bash-language-server", + -- "awk-language-server", + "shfmt", + "shellcheck", + + -- c + "clangd", + + -- rust + "rust-analyzer", + "rustfmt", + + -- web dev + "css-lsp", + "html-lsp", + "typescript-language-server", + "json-lsp", + "tailwindcss-language-server", + "eslint-lsp", + + -- python + "pyright", + + -- javascript + "prettier", + "prettierd", + + -- yaml + "yaml-language-server", + + -- toml + "taplo", + }, + } + end, + }, + { + "nvim-treesitter/nvim-treesitter", + opts = function(_, opts) + + opts.ignore_install = { 'help' } + + return vim.tbl_deep_extend("force", require("plugins.configs.treesitter"), { + ensure_installed = { + "c", + "cpp", + "css", + "go", + "lua", + "python", + "rust", + "typescript", + "svelte", + "html", + "java", + "help", + "nix", + "markdown", + "markdown_inline", + }, + }) + end, + }, + { + "hrsh7th/nvim-cmp", + opts = function() + return vim.tbl_deep_extend("force", require("plugins.configs.cmp"), { + sources = { + { name = "luasnip" }, + { name = "copilot" }, + { name = "nvim_lsp" }, + { name = "buffer" }, + { name = "nvim_lua" }, + { name = "path" }, + }, + }) + end, + }, +} diff --git a/pkgs/nvchad/custom/term.lua b/pkgs/nvchad/custom/term.lua new file mode 100644 index 0000000..d66e590 --- /dev/null +++ b/pkgs/nvchad/custom/term.lua @@ -0,0 +1,29 @@ +local Terminal = require("toggleterm.terminal").Terminal + +local M = {} + +M.lazygit = Terminal:new({ + cmd = "lazygit", + hidden = true, + direction = "float", + float_opts = { + border = "double", + }, + -- function to run on opening the terminal + on_open = function(term) + vim.cmd("startinsert!") + vim.api.nvim_buf_set_keymap(term.bufnr, "n", "q", "close", { noremap = true, silent = true }) + end, + -- function to run on closing the terminal + on_close = function(_) + vim.cmd("startinsert!") + end, +}) + +M.htop = Terminal:new({ + cmd = "htop", + hidden = true, + direction = "float", +}) + +return M diff --git a/pkgs/nvchad/default.nix b/pkgs/nvchad/default.nix new file mode 100644 index 0000000..3927b00 --- /dev/null +++ b/pkgs/nvchad/default.nix @@ -0,0 +1,30 @@ +{ lib, stdenv, pkgs }: + +let + custom = ./custom; +in +stdenv.mkDerivation { + pname = "nvchad"; + version = "2.0.0"; + + src = pkgs.fetchFromGitHub { + owner = "NvChad"; + repo = "NvChad"; + rev = "refs/heads/v2.0"; + sha256 = "sha256-tKMvKdB3jPSvcyewaOe8oak3pXhjAcLyyxgGMiMeqeU="; + }; + + installPhase = '' + mkdir $out + cp -r * "$out/" + mkdir -p "$out/lua/custom" + cp -r ${custom}/* "$out/lua/custom/" + ''; + + meta = with lib; { + description = "NvChad"; + homepage = "https://github.com/NvChad/NvChad"; + platforms = platforms.all; + license = licenses.gpl3; + }; +}