diff options
author | Freya Murphy <freya@freyacat.org> | 2025-06-23 22:33:44 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-06-23 22:33:44 -0400 |
commit | 328c741b1aac74020412e99e0dca7c728dbc92fa (patch) | |
tree | 461f4ebcd3252d542749a34668defd62de356c73 /home/neovim | |
parent | removed unused packages (diff) | |
download | dotfiles-nix-328c741b1aac74020412e99e0dca7c728dbc92fa.tar.gz dotfiles-nix-328c741b1aac74020412e99e0dca7c728dbc92fa.tar.bz2 dotfiles-nix-328c741b1aac74020412e99e0dca7c728dbc92fa.zip |
refactor
Diffstat (limited to 'home/neovim')
-rw-r--r-- | home/neovim/config.nix | 94 | ||||
-rw-r--r-- | home/neovim/default.nix | 74 | ||||
-rw-r--r-- | home/neovim/init.lua | 359 |
3 files changed, 527 insertions, 0 deletions
diff --git a/home/neovim/config.nix b/home/neovim/config.nix new file mode 100644 index 0000000..ae10243 --- /dev/null +++ b/home/neovim/config.nix @@ -0,0 +1,94 @@ +{ + config, + inputs, +}: +inputs.self.lib.lua.fmt { + # Width of tabs in the editor + tabwidth = 4; + # If tabs should be expanded to spaces + expandtab = false; + keys = { + # NeoVIM leader key + leader = " "; + # Keybind to remove active hilighted content + noh = "<leader>h"; + menus = { + # Open file browser + browser = "<leader>e"; + # Show active buffers + buffers = "<leader>fb"; + # Show LSP errors + error = "<leader>t"; + # Find files in working directory + find = "<leader>ff"; + # Grep files in working directory + grep = "<leader>fg"; + # Search help menu + help = "<leader>fh"; + # Voew undo tree + undo = "<leader>u"; + }; + lsp = { + # Open LSP hover menu on a value + hover = "K"; + # Perform an LSP action on a value + action = "<leader>la"; + # View all references of a value + references = "<leader>lr"; + # Rename current and all references of a value + rename = "<leader>ln"; + }; + cmp = { + # Select previous value in completion engine + prev = "<C-p>"; + # Select next value in completion engine + next = "<C-n>"; + # Confirm current value in completion engine + confirm = "<CR>"; + # Auto complete using completion engine + complete = "<C-space>"; + }; + }; + # list of lsp servers to load + lsps = { + clangd = {}; + jdtls = {}; + kotlin_language_server = {}; + phpactor = {}; + rust_analyzer = {}; + ts_ls = {}; + zls = {}; + }; + highlight = { + # max file size in KiB to attempt to parse + max_size = 1024; + }; + # colorscheme + theme = { + colors = { + base00 = "#${config.theme.colors.bg}"; + base01 = "#${config.theme.colors.surface.bg}"; + base02 = "#${config.theme.colors.surface.bg}"; + base03 = "#${config.theme.colors.bright.white}"; + base04 = "#${config.theme.colors.bright.black}"; + base05 = "#${config.theme.colors.fg}"; + base06 = "#${config.theme.colors.bright.white}"; + base07 = "#${config.theme.colors.hover.bg}"; + base08 = "#${config.theme.colors.bright.red}"; + base09 = "#${config.theme.colors.bright.yellow}"; + base0A = "#${config.theme.colors.bright.yellow}"; + base0B = "#${config.theme.colors.bright.green}"; + base0C = "#${config.theme.colors.bright.cyan}"; + base0D = "#${config.theme.colors.bright.blue}"; + base0E = "#${config.theme.colors.bright.magenta}"; + base0F = "#${config.theme.colors.normal.yellow}"; + }; + transparent = true; + }; + # max column width + col = { + # show a bar at `width` characters + show = true; + width = 80; + }; +} diff --git a/home/neovim/default.nix b/home/neovim/default.nix new file mode 100644 index 0000000..c1ed000 --- /dev/null +++ b/home/neovim/default.nix @@ -0,0 +1,74 @@ +{ + inputs, + config, + lib, + pkgs, + ... +}: let + lua_cfg = import ./config.nix {inherit config inputs;}; + lua = builtins.readFile ./init.lua; +in { + environment.variables.EDITOR = "nvim"; + + home-manager.users.${config.user} = { + programs.neovim = { + enable = true; + viAlias = true; + vimAlias = true; + + extraLuaConfig = '' + local config = ${lua_cfg} + + ${lua} + ''; + + plugins = with pkgs.vimPlugins; [ + # Dependencies + vim-devicons + nvim-web-devicons + plenary-nvim + # Colorscheme + base16-nvim + # Mode line + lualine-nvim + # Buffer line + bufferline-nvim + # File browser + nvim-tree-lua + # Undo tree + undotree + # Trouble (error menu) + trouble-nvim + # Telescope (buffers/find/grep/help) + telescope-nvim + # Snippets + vim-vsnip + vim-vsnip-integ + friendly-snippets + # Completion + cmp-buffer + cmp-nvim-lsp + cmp-vsnip + nvim-cmp + # Sourround delimiters + nvim-surround + # Comment functions + nerdcommenter + # Treesitter + nvim-treesitter.withAllGrammars + # Syntax hilighting + vim-illuminate + # Todo comments + todo-comments-nvim + # Lsp server + nvim-lspconfig + # Notifications + fidget-nvim + # Auto indentation + indent-o-matic + # 80 column width + virt-column-nvim + ]; + }; + }; +} diff --git a/home/neovim/init.lua b/home/neovim/init.lua new file mode 100644 index 0000000..2be7fee --- /dev/null +++ b/home/neovim/init.lua @@ -0,0 +1,359 @@ +--[[ + + NeoVIM Configuration + Copyright (c) Freya Murphy 2025 + +]]-- + +--[[ LIB ]]-- + +local function bind(key, action, opts) + opts = opts or {} + vim.keymap.set('n', key, action, opts) +end + +local function join(left, right) + if not left then return right end + if not right then return left end + for k,v in pairs(right) do + local lv, rv = left[k], right[k] + if type(rv) == "table" then + left[k] = join(lv, rv) + else + left[k] = rv + end + end + return left +end + +--[[ VIM ]]-- + +vim.opt.tabstop = config.tabwidth +vim.opt.softtabstop = config.tabwidth +vim.opt.shiftwidth = config.tabwidth +vim.opt.expandtab = config.expandtab +vim.opt.mouse = "a" +vim.opt.clipboard = "unnamedplus" +vim.opt.hlsearch = true +vim.opt.autoindent = true +vim.opt.ttyfast = true +vim.opt.number = true +vim.opt.relativenumber = true +vim.opt.rnu = true +vim.opt.swapfile = false +vim.opt.fillchars = { eob = " "} + + +--[[ BUF ]]-- + +-- remove trailing whitespace on save +vim.api.nvim_create_autocmd({ "BufWritePre" }, { + pattern = { "*" }, + command = [[%s/\s\+$//e]], +}) + +--[[ KEYBINDS ]]-- + +-- leader +vim.g.mapleader = config.keys.leader +vim.g.maplocalleader = config.keys.leader +vim.keymap.set("", '<leader>', '<Nop>', { noremap = true, silent = true }) + +-- lsp +bind(config.keys.noh, vim.cmd.noh) +vim.api.nvim_create_autocmd('LspAttach', { + desc = 'LSP actions', + callback = function(event) + local opts = {buffer = event.buf} + bind(config.keys.lsp.hover, function() vim.lsp.buf.hover() end, opts) + bind(config.keys.lsp.action, function() vim.lsp.buf.code_action() end, opts) + bind(config.keys.lsp.references, function() vim.lsp.buf.references() end, opts) + bind(config.keys.lsp.rename, function() vim.lsp.buf.rename() end, opts) + end +}) + +--[[ COLORSCHEME ]]-- + +vim.opt.termguicolors = true +if config.theme.transparent then + vim.g.base16_transparent_background = 1 +end + +local colorscheme = require('base16-colorscheme') +colorscheme.setup({ + base00 = config.theme.colors.base00, + base01 = config.theme.colors.base01, + base02 = config.theme.colors.base02, + base03 = config.theme.colors.base03, + base04 = config.theme.colors.base04, + base05 = config.theme.colors.base05, + base06 = config.theme.colors.base06, + base07 = config.theme.colors.base07, + base08 = config.theme.colors.base08, + base09 = config.theme.colors.base09, + base0A = config.theme.colors.base0A, + base0B = config.theme.colors.base0B, + base0C = config.theme.colors.base0C, + base0D = config.theme.colors.base0D, + base0E = config.theme.colors.base0E, + base0F = config.theme.colors.base0F, +}) + +-- make transparent background +if config.theme.transparent then + local colors = { + -- Text + "Normal", "NormalNC", "NormalFloat", + -- Line Numbers + "LineNr", "EndOfBuffer", "SignColumn", + -- Floating + "FloatBorder", + -- Mode/Buffer Lines + "TabLine", "TabLineFill", "StatusLine", + } + for _,color in pairs(colors) do + vim.api.nvim_set_hl(0, color, { bg = "none" }) + end +end +-- identifiers should not be colored +vim.api.nvim_set_hl(0, "Identifier", { fg = config.theme.colors.base05 }) +vim.api.nvim_set_hl(0, "TSVariable", { fg = config.theme.colors.base05 }) +-- macro should be colored as a keyword +vim.api.nvim_set_hl(0, "TSFuncMacro", { fg = config.theme.colors.base0E }) +-- comments are too dark +vim.api.nvim_set_hl(0, "Comment", { fg = config.theme.colors.base07 }) +vim.api.nvim_set_hl(0, "@comment", { link = "Comment" }) + +--[[ MODE LINE ]]-- + +local lualine_theme = require('lualine.themes.base16') +if config.theme.transparent then + lualine_theme.normal.c = { fg = config.theme.colors.base05, bg = "none" } +end + +require('lualine').setup { + options = { + theme = lualine_theme, + icons_enabled = true, + globalstatus = true, + }, +} + +--[[ BUFFER LINE ]]-- + +require('bufferline').setup {} + +--[[ FILE BROWSER ]]-- + +vim.g.loaded_netrw = 1 +vim.g.loaded_netrwPlugin = 1 + +require('nvim-tree').setup { + sort = { + sorter = "case_sensitive", + }, + view = { + centralize_selection = true, + signcolumn = "yes", + float = { + enable = true, + quit_on_focus_loss = true, + open_win_config = { + relative = "editor", + border = "rounded", + width = 80, + height = 30, + row = 1, + col = 1, + }, + } + }, + renderer = { + group_empty = true, + }, + actions = { + use_system_clipboard = true, + change_dir = { + enable = true, + global = false, + restrict_above_cwd = false, + }, + expand_all = { + max_folder_discovery = 300, + exclude = {}, + }, + file_popup = { + open_win_config = { + col = 1, + row = 1, + relative = "cursor", + border = "shadow", + style = "minimal", + }, + }, + open_file = { + quit_on_open = true, + window_picker = { + enable = false, + picker = "default", + chars = "abcdefghijklmnopqrstuvwxyz1234567890", + exclude = { + filetype = { "notify", "lazy", "qf", "diff", "fugitive", "fugitiveblame" }, + buftype = { "nofile", "terminal", "help" }, + }, + }, + }, + remove_file = { + close_window = true, + }, + }, + filters = { + dotfiles = false, + }, + tab = { + sync = { + open = false, + close = false, + ignore = {}, + }, + }, + git = { + enable = false, + }, + update_cwd = true, + respect_buf_cwd = true, + update_focused_file = { + enable = true, + update_cwd = true + }, +} + +bind(config.keys.menus.browser, vim.cmd.NvimTreeToggle) + +--[[ UNDO TREE ]]-- + +bind(config.keys.menus.undo, vim.cmd.UndotreeToggle) + +--[[ ERROR MENU ]]-- + +bind(config.keys.menus.error, function() require('trouble').toggle() end) + +--[[ TELESCOPE ]]-- + +local telescope = require('telescope.builtin') +bind(config.keys.menus.buffers, telescope.buffers) +bind(config.keys.menus.find, telescope.find_files) +bind(config.keys.menus.grep, telescope.live_grep) +bind(config.keys.menus.help, telescope.help_tags) +if config.theme.transparent then + vim.api.nvim_set_hl(0, 'TelescopeNormal', { bg = "none" }) + vim.api.nvim_set_hl(0, 'TelescopeBorder', { bg = "none" }) + vim.api.nvim_set_hl(0, 'TelescopeResultsTitle', { bg = "none" }) + vim.api.nvim_set_hl(0, 'TelescopePromptTitle', { bg = "none" }) + vim.api.nvim_set_hl(0, 'TelescopePreviewTitle', { bg = "none" }) + vim.api.nvim_set_hl(0, 'TelescopePromptNormal', { bg = "none" }) + vim.api.nvim_set_hl(0, 'TelescopePromptBorder', { bg = "none" }) +end + +--[[ COMPLETION ]]-- + +local cmp = require('cmp') +local cmp_select = {behavior = cmp.SelectBehavior.select} +local cmp_mappings = cmp.mapping.preset.insert({ + [config.keys.cmp.prev] = cmp.mapping.select_prev_item(cmp_select), + [config.keys.cmp.next] = cmp.mapping.select_next_item(cmp_select), + [config.keys.cmp.confirm] = cmp.mapping.confirm({ select = true }), + [config.keys.cmp.complete] = cmp.mapping.complete(), +}) + +cmp_mappings['<Tab>'] = nil +cmp_mappings['<S-Tab>'] = nil + +cmp.setup { + snippet = { + expand = function(args) + vim.fn["vsnip#anonymous"](args.body) + end, + }, + sources = cmp.config.sources { + { name = 'nvim_lsp' }, + { name = 'vsnip' }, + { name = 'buffer' }, + }, + mapping = cmp_mappings, +} + +--[[ Surround Delimiters ]]-- + +require('nvim-surround').setup {} + +--[[ SYNTAX HIGHLIGHTING ]]-- + +require('nvim-treesitter.configs').setup { + highlight = { + enable = true, + disable = function(lang, buf) + local max_filesize = config.highlight.max_size * 1024 + local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf)) + if ok and stats and stats.size > max_filesize then + return true + end + end, + additional_vim_regex_highlighting = true, + }, +} + +require('illuminate').configure { + providers = { + 'lsp', + 'treesitter', + 'regex', + }, +} + +--[[ TODO COMMENTS ]]-- + +require('todo-comments').setup() + +--[[ LSP SERVER ]]-- + +local lspconfig = require('lspconfig') +local capabilities = require('cmp_nvim_lsp').default_capabilities() + +for lsp,config in pairs(config.lsps) do + local config = join(capabilities, config) + lspconfig[lsp].setup { + capabilities = config, + } +end + +vim.diagnostic.config({ + virtual_lines = true, +}) + +--[[ NOTIFICATIONS ]]-- + +require('fidget').setup { + notification = { + window = { + winblend = 0, + }, + }, +} + +--[[ AUTO INDENTATION ]]-- + +require('indent-o-matic').setup { + max_lines = 2048, + standard_widths = { 2, 4, 8 }, + skip_multiline = true, +} + +--[[ 80 COLUMN WIDTH ]]-- + +if config.col.show then + require('virt-column').setup { + enabled = true, + virtcolumn = tostring(config.col.width), + } +end |