summaryrefslogtreecommitdiff
path: root/home/neovim/init.lua
diff options
context:
space:
mode:
Diffstat (limited to 'home/neovim/init.lua')
-rw-r--r--home/neovim/init.lua359
1 files changed, 359 insertions, 0 deletions
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