diff --git a/.config/nvim/init.lua b/.config/nvim/init.lua new file mode 100644 index 0000000..4b4fff6 --- /dev/null +++ b/.config/nvim/init.lua @@ -0,0 +1,566 @@ +--[[ + +===================================================================== +==================== READ THIS BEFORE CONTINUING ==================== +===================================================================== + +Kickstart.nvim is *not* a distribution. + +Kickstart.nvim is a template for your own configuration. + The goal is that you can read every line of code, top-to-bottom, understand + what your configuration is doing, and modify it to suit your needs. + + Once you've done that, you should start exploring, configuring and tinkering to + explore Neovim! + + If you don't know anything about Lua, I recommend taking some time to read through + a guide. One possible example: + - https://learnxinyminutes.com/docs/lua/ + + And then you can explore or search through `:help lua-guide` + + +Kickstart Guide: + +I have left several `:help X` comments throughout the init.lua +You should run that command and read that help section for more information. + +In addition, I have some `NOTE:` items throughout the file. +These are for you, the reader to help understand what is happening. Feel free to delete +them once you know what you're doing, but they should serve as a guide for when you +are first encountering a few different constructs in your nvim config. + +--]] +-- Set as the leader key +-- See `:help mapleader` +-- NOTE: Must happen before plugins are required (otherwise wrong leader will be used) +vim.g.mapleader = ' ' +vim.g.maplocalleader = ' ' + +-- Install package manager +-- https://github.com/folke/lazy.nvim +-- `:help lazy.nvim.txt` for more info +local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim' +if not vim.loop.fs_stat(lazypath) then + vim.fn.system { + 'git', + 'clone', + '--filter=blob:none', + 'https://github.com/folke/lazy.nvim.git', + '--branch=stable', -- latest stable release + lazypath, + } +end +vim.opt.rtp:prepend(lazypath) + +-- NOTE: Here is where you install your plugins. +-- You can configure plugins using the `config` key. +-- +-- You can also configure plugins after the setup call, +-- as they will be available in your neovim runtime. +require('lazy').setup({ + -- NOTE: First, some plugins that don't require any configuration + + -- Git related plugins + 'tpope/vim-fugitive', + 'tpope/vim-rhubarb', + + -- Detect tabstop and shiftwidth automatically + 'tpope/vim-sleuth', + + -- NOTE: This is where your plugins related to LSP can be installed. + -- The configuration is done below. Search for lspconfig to find it below. + { + -- LSP Configuration & Plugins + 'neovim/nvim-lspconfig', + dependencies = { + -- Automatically install LSPs to stdpath for neovim + { 'williamboman/mason.nvim', config = true }, + 'williamboman/mason-lspconfig.nvim', + + -- Useful status updates for LSP + -- NOTE: `opts = {}` is the same as calling `require('fidget').setup({})` + { 'j-hui/fidget.nvim', tag = 'legacy', opts = {} }, + + -- Additional lua configuration, makes nvim stuff amazing! + 'folke/neodev.nvim', + }, + }, + + { + -- Autocompletion + 'hrsh7th/nvim-cmp', + dependencies = { + -- Snippet Engine & its associated nvim-cmp source + 'L3MON4D3/LuaSnip', + 'saadparwaiz1/cmp_luasnip', + + -- Adds LSP completion capabilities + 'hrsh7th/cmp-nvim-lsp', + + -- Adds a number of user-friendly snippets + 'rafamadriz/friendly-snippets', + }, + }, + + -- Useful plugin to show you pending keybinds. + { 'folke/which-key.nvim', opts = {} }, + { + -- Adds git releated signs to the gutter, as well as utilities for managing changes + 'lewis6991/gitsigns.nvim', + opts = { + -- See `:help gitsigns.txt` + signs = { + add = { text = '+' }, + change = { text = '~' }, + delete = { text = '_' }, + topdelete = { text = '‾' }, + changedelete = { text = '~' }, + }, + on_attach = function(bufnr) + vim.keymap.set('n', 'gp', require('gitsigns').prev_hunk, + { buffer = bufnr, desc = '[G]o to [P]revious Hunk' }) + vim.keymap.set('n', 'gn', require('gitsigns').next_hunk, { buffer = bufnr, desc = '[G]o to [N]ext Hunk' }) + vim.keymap.set('n', 'ph', require('gitsigns').preview_hunk, { buffer = bufnr, desc = '[P]review [H]unk' }) + end, + }, + }, + + { + -- Theme inspired by Atom + 'navarasu/onedark.nvim', + priority = 1000, + config = function() + vim.cmd.colorscheme 'onedark' + end, + }, + + { + -- Set lualine as statusline + 'nvim-lualine/lualine.nvim', + -- See `:help lualine.txt` + opts = { + options = { + icons_enabled = false, + theme = 'onedark', + component_separators = '|', + section_separators = '', + }, + }, + }, + + { + -- Add indentation guides even on blank lines + 'lukas-reineke/indent-blankline.nvim', + version = "2.20.8", + -- Enable `lukas-reineke/indent-blankline.nvim` + -- See `:help indent_blankline.txt` + opts = { + char = '┊', + show_trailing_blankline_indent = false, + }, + }, + + -- "gc" to comment visual regions/lines + { 'numToStr/Comment.nvim', opts = {} }, + + -- Fuzzy Finder (files, lsp, etc) + { + 'nvim-telescope/telescope.nvim', + branch = '0.1.x', + dependencies = { + 'nvim-lua/plenary.nvim' } + }, + + -- Fuzzy Finder Algorithm which requires local dependencies to be built. + -- Only load if `make` is available. Make sure you have the system + -- requirements installed. + { + 'nvim-telescope/telescope-fzf-native.nvim', + build = + 'cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release && cmake --build build --config Release && cmake --install build --prefix build' + }, + { + -- Highlight, edit, and navigate code + 'nvim-treesitter/nvim-treesitter', + dependencies = { + 'nvim-treesitter/nvim-treesitter-textobjects', + }, + build = ':TSUpdate', + }, + {'romgrk/barbar.nvim', + dependencies = { + 'lewis6991/gitsigns.nvim', -- OPTIONAL: for git status + 'nvim-tree/nvim-web-devicons', -- OPTIONAL: for file icons + }, + init = function() vim.g.barbar_auto_setup = false end, + opts = { + -- lazy.nvim will automatically call setup for you. put your options here, anything missing will use the default: + -- animation = true, + -- insert_at_start = true, + -- …etc. + }, + version = '^1.0.0', -- optional: only update when a new 1.x version is released + }, + + -- NOTE: Next Step on Your Neovim Journey: Add/Configure additional "plugins" for kickstart + -- These are some example plugins that I've included in the kickstart repository. + -- Uncomment any of the lines below to enable them. + require 'kickstart.plugins.autoformat', + require 'kickstart.plugins.debug', + + -- NOTE: The import below can automatically add your own plugins, configuration, etc from `lua/custom/plugins/*.lua` + -- You can use this folder to prevent any conflicts with this init.lua if you're interested in keeping + -- up-to-date with whatever is in the kickstart repo. + -- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going. + -- + -- For additional information see: https://github.com/folke/lazy.nvim#-structuring-your-plugins + { import = 'custom.plugins' }, +}, {}) + +-- [[ Setting options ]] +-- See `:help vim.o` +-- NOTE: You can change these options as you wish! +vim.cmd [[highlight Normal ctermbg=none guibg=none]] +vim.cmd [[highlight EndOfBuffer ctermbg=none guibg=none]] +vim.cmd [[highlight NvimTreeEndOfBuffer ctermbg=none guibg=none]] +vim.cmd [[highlight NvimTreeNormal ctermbg=none guibg=none]] + + +-- Set highlight on search +vim.o.hlsearch = false + +-- Make line numbers default +vim.wo.number = true +vim.wo.relativenumber = true + +-- Enable mouse mode +vim.o.mouse = 'a' + +-- Sync clipboard between OS and Neovim. +-- Remove this option if you want your OS clipboard to remain independent. +-- See `:help 'clipboard'` +vim.o.clipboard = 'unnamedplus' + +-- Enable break indent +vim.o.breakindent = true + +-- Save undo history +vim.o.undofile = true + +-- Case-insensitive searching UNLESS \C or capital in search +vim.o.ignorecase = true +vim.o.smartcase = true + +-- Keep signcolumn on by default +vim.wo.signcolumn = 'yes' + +-- Decrease update time +vim.o.updatetime = 250 +vim.o.timeoutlen = 300 + +-- Set completeopt to have a better completion experience +vim.o.completeopt = 'menuone,noselect' + +-- NOTE: You should make sure your terminal supports this +vim.o.termguicolors = true +vim.o.smartindent = true +vim.o.scrolloff = 8 +vim.o.list = false +vim.opt.listchars = { + tab = "→ ", + space = "·", + nbsp = "␣", + trail = "•", + precedes = "«", + extends = "»", +} + +-- [[ Basic Keymaps ]] + +-- Keymaps for better default experience +-- See `:help vim.keymap.set()` +vim.keymap.set({ 'n', 'v' }, '', '', { silent = true }) + +-- Remap for dealing with word wrap +vim.keymap.set('n', 'k', "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true }) +vim.keymap.set('n', 'j', "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true }) + +vim.keymap.set("n", "ss", [[:%s/\<\>//gI]]) +vim.keymap.set("x", "p", [["_dP]]) +vim.keymap.set("n", "J", "mzJ`z") +vim.keymap.set("v", "J", ":m '>+1gv=gv") +vim.keymap.set("v", "K", ":m '<-2gv=gv") +vim.keymap.set("n", "Y", "yy"); +-- nvim-tree +vim.keymap.set("n", "f", ":NvimTreeToggle"); + +-- [[ 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 = '*', +}) + +-- [[ Configure Telescope ]] +-- See `:help telescope` and `:help telescope.setup()` +require('telescope').setup { + defaults = { + mappings = { + n = { + [''] = require('telescope.actions').delete_buffer + }, + i = { + [''] = false, + [''] = false, + }, + }, + }, +} + +-- Enable telescope fzf native, if installed +pcall(require('telescope').load_extension, 'fzf') + +-- See `:help telescope.builtin` +vim.keymap.set('n', '?', require('telescope.builtin').oldfiles, { desc = '[?] Find recently opened files' }) +vim.keymap.set('n', '', require('telescope.builtin').buffers, { desc = '[ ] Find existing buffers' }) +vim.keymap.set('n', '/', function() + -- You can pass additional configuration to telescope to change theme, layout, etc. + require('telescope.builtin').current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { + winblend = 10, + previewer = false, + }) +end, { desc = '[/] Fuzzily search in current buffer' }) + +vim.keymap.set('n', 'gf', require('telescope.builtin').git_files, { desc = 'Search [G]it [F]iles' }) +vim.keymap.set('n', 'sf', require('telescope.builtin').find_files, { desc = '[S]earch [F]iles' }) +vim.keymap.set('n', 'sh', require('telescope.builtin').help_tags, { desc = '[S]earch [H]elp' }) +vim.keymap.set('n', 'sw', require('telescope.builtin').grep_string, { desc = '[S]earch current [W]ord' }) +vim.keymap.set('n', 'sg', require('telescope.builtin').live_grep, { desc = '[S]earch by [G]rep' }) +vim.keymap.set('n', 'sd', require('telescope.builtin').diagnostics, { desc = '[S]earch [D]iagnostics' }) +vim.keymap.set('n', 'sr', require('telescope.builtin').lsp_references, { desc = '[S]earch [R]eferences' }) + +-- [[ Configure Treesitter ]] +-- See `:help nvim-treesitter` +require('nvim-treesitter.configs').setup { + -- Add languages to be installed here that you want installed for treesitter + ensure_installed = { 'c', 'cpp', 'go', 'lua', 'python', 'rust', 'tsx', 'typescript', 'vimdoc', 'vim' }, + + -- Autoinstall languages that are not installed. Defaults to false (but you can change for yourself!) + auto_install = true, + + highlight = { enable = true }, + indent = { enable = true }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = '', + node_incremental = '', + scope_incremental = '', + node_decremental = '', + }, + }, + textobjects = { + select = { + enable = true, + lookahead = true, -- Automatically jump forward to textobj, similar to targets.vim + keymaps = { + -- You can use the capture groups defined in textobjects.scm + ['aa'] = '@parameter.outer', + ['ia'] = '@parameter.inner', + ['af'] = '@function.outer', + ['if'] = '@function.inner', + ['ac'] = '@class.outer', + ['ic'] = '@class.inner', + }, + }, + move = { + enable = true, + set_jumps = true, -- whether to set jumps in the jumplist + goto_next_start = { + [']m'] = '@function.outer', + [']]'] = '@class.outer', + }, + goto_next_end = { + [']M'] = '@function.outer', + [']['] = '@class.outer', + }, + goto_previous_start = { + ['[m'] = '@function.outer', + ['[['] = '@class.outer', + }, + goto_previous_end = { + ['[M'] = '@function.outer', + ['[]'] = '@class.outer', + }, + }, + swap = { + enable = true, + swap_next = { + ['a'] = '@parameter.inner', + }, + swap_previous = { + ['A'] = '@parameter.inner', + }, + }, + }, +} + +-- Diagnostic keymaps +vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, { desc = 'Go to previous diagnostic message' }) +vim.keymap.set('n', ']d', vim.diagnostic.goto_next, { desc = 'Go to next diagnostic message' }) +vim.keymap.set('n', 'e', vim.diagnostic.open_float, { desc = 'Open floating diagnostic message' }) +vim.keymap.set('n', 'q', vim.diagnostic.setloclist, { desc = 'Open diagnostics list' }) + +-- [[ Configure LSP ]] +-- This function gets run when an LSP connects to a particular buffer. +local on_attach = function(_, bufnr) + -- NOTE: Remember that lua is a real programming language, and as such it is possible + -- to define small helper and utility functions so you don't have to repeat yourself + -- many times. + -- + -- In this case, we create a function that lets us more easily define mappings specific + -- for LSP related items. It sets the mode, buffer and description for us each time. + local nmap = function(keys, func, desc) + if desc then + desc = 'LSP: ' .. desc + end + + vim.keymap.set('n', keys, func, { buffer = bufnr, desc = desc }) + end + + nmap('rn', vim.lsp.buf.rename, '[R]e[n]ame') + nmap('ca', vim.lsp.buf.code_action, '[C]ode [A]ction') + + nmap('gd', vim.lsp.buf.definition, '[G]oto [D]efinition') + nmap('gr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences') + nmap('gI', vim.lsp.buf.implementation, '[G]oto [I]mplementation') + nmap('D', vim.lsp.buf.type_definition, 'Type [D]efinition') + nmap('ds', require('telescope.builtin').lsp_document_symbols, '[D]ocument [S]ymbols') + nmap('ws', require('telescope.builtin').lsp_dynamic_workspace_symbols, '[W]orkspace [S]ymbols') + + -- See `:help K` for why this keymap + nmap('K', vim.lsp.buf.hover, 'Hover Documentation') + nmap('', vim.lsp.buf.signature_help, 'Signature Documentation') + + -- Lesser used LSP functionality + nmap('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') + nmap('wa', vim.lsp.buf.add_workspace_folder, '[W]orkspace [A]dd Folder') + nmap('wr', vim.lsp.buf.remove_workspace_folder, '[W]orkspace [R]emove Folder') + nmap('wl', function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, '[W]orkspace [L]ist Folders') + + -- Create a command `:Format` local to the LSP buffer + vim.api.nvim_buf_create_user_command(bufnr, 'Format', function(_) + vim.lsp.buf.format() + end, { desc = 'Format current buffer with LSP' }) +end + +-- Enable the following language servers +-- Feel free to add/remove any LSPs that you want here. They will automatically be installed. +-- +-- Add any additional override configuration in the following tables. They will be passed to +-- the `settings` field of the server config. You must look up that documentation yourself. +local servers = { + -- clangd = {}, + -- gopls = {}, + -- pyright = {}, + rust_analyzer = {}, + jdtls = {}, + -- tsserver = {}, + + lua_ls = { + Lua = { + workspace = { checkThirdParty = false }, + telemetry = { enable = false }, + }, + }, +} + +-- Setup neovim lua configuration +require('neodev').setup() + +-- nvim-cmp supports additional completion capabilities, so broadcast that to servers +local capabilities = vim.lsp.protocol.make_client_capabilities() +capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities) + +-- Ensure the servers above are installed +local mason_lspconfig = require 'mason-lspconfig' + +mason_lspconfig.setup { + ensure_installed = vim.tbl_keys(servers), +} + +mason_lspconfig.setup_handlers { + function(server_name) + require('lspconfig')[server_name].setup { + capabilities = capabilities, + on_attach = on_attach, + settings = servers[server_name], + } + end, +} + +-- [[ Configure nvim-cmp ]] +-- See `:help cmp` +local cmp = require 'cmp' +local luasnip = require 'luasnip' +require('luasnip.loaders.from_vscode').lazy_load() +luasnip.config.setup {} + +cmp.setup { + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, + mapping = cmp.mapping.preset.insert { + [''] = cmp.mapping.select_next_item(), + [''] = cmp.mapping.select_prev_item(), + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.complete {}, + [''] = cmp.mapping.confirm { + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }, + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif luasnip.expand_or_locally_jumpable() then + luasnip.expand_or_jump() + else + fallback() + end + end, { 'i', 's' }), + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.locally_jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { 'i', 's' }), + }, + sources = { + { name = 'nvim_lsp' }, + { name = 'luasnip' }, + }, +} + +-- disable netrw at the very start of your init.lua +vim.g.loaded_netrw = 1 +vim.g.loaded_netrwPlugin = 1 + +-- set termguicolors to enable highlight groups +vim.opt.termguicolors = true + +-- The line beneath this is called `modeline`. See `:help modeline` +-- vim: ts=2 sts=2 sw=2 et + diff --git a/.config/nvim/lua/custom/plugins/copilot.lua b/.config/nvim/lua/custom/plugins/copilot.lua new file mode 100644 index 0000000..4bd9e84 --- /dev/null +++ b/.config/nvim/lua/custom/plugins/copilot.lua @@ -0,0 +1,25 @@ +return { + { + "zbirenbaum/copilot.lua", + enabled = false, + cmd = "Copilot", + event = "InsertEnter", + config = function() + require("copilot").setup({ + suggestion = { + enabled = true, + auto_trigger = true, + debounce = 75, + keymap = { + accept = "", + next = "", + prev = "" + } + }, + filetypes = { + ["."] = true + } + }) + end, + } +} diff --git a/.config/nvim/lua/custom/plugins/init.lua b/.config/nvim/lua/custom/plugins/init.lua new file mode 100644 index 0000000..be0eb9d --- /dev/null +++ b/.config/nvim/lua/custom/plugins/init.lua @@ -0,0 +1,5 @@ +-- You can add your own plugins here or in other files in this directory! +-- I promise not to create any merge conflicts in this directory :) +-- +-- See the kickstart.nvim README for more information +return {} diff --git a/.config/nvim/lua/custom/plugins/llm.lua b/.config/nvim/lua/custom/plugins/llm.lua new file mode 100644 index 0000000..84abb2d --- /dev/null +++ b/.config/nvim/lua/custom/plugins/llm.lua @@ -0,0 +1,28 @@ +return { + cond = false, + 'huggingface/llm.nvim', + opts = { + api_token = "monkey", + -- cf Setup + model = "http://localhost:8080/generate", + query_params = { + max_new_tokens = 60, + temperature = 0.2, + top_p = 0.95, + stop_token = "", + }, + fim = { + enabled = true, + prefix = "
",
+      middle = "",
+      suffix = "",
+    },
+    debounce_ms = 150,
+    accept_keymap = "",
+    dismiss_keymap = "",
+    max_context_after = 5000,
+    max_context_before = 5000,
+    tls_skip_verify_insecure = false,
+    context_window = 8192, -- max number of tokens for the context window
+  }
+};
diff --git a/.config/nvim/lua/custom/plugins/nvim-tree.lua b/.config/nvim/lua/custom/plugins/nvim-tree.lua
new file mode 100644
index 0000000..347f3c1
--- /dev/null
+++ b/.config/nvim/lua/custom/plugins/nvim-tree.lua
@@ -0,0 +1,90 @@
+local function my_on_attach(bufnr)
+  local api = require('nvim-tree.api')
+
+  local function opts(desc)
+    return { desc = 'nvim-tree: ' .. desc, buffer = bufnr, noremap = true, silent = true, nowait = true }
+  end
+
+  -- copy default mappings here from defaults in next section
+  vim.keymap.set('n', 'tc', api.tree.change_root_to_node, opts('CD'))
+  vim.keymap.set('n', 'te', api.node.open.replace_tree_buffer, opts('Open: In Place'))
+  vim.keymap.set('n', 'tk', api.node.show_info_popup, opts('Info'))
+  vim.keymap.set('n', 'tr', api.fs.rename_sub, opts('Rename: Omit Filename'))
+  vim.keymap.set('n', 'tt', api.node.open.tab, opts('Open: New Tab'))
+  vim.keymap.set('n', 'tv', api.node.open.vertical, opts('Open: Vertical Split'))
+  vim.keymap.set('n', 'th', api.node.open.horizontal, opts('Open: Horizontal Split'))
+  vim.keymap.set('n', '', api.node.navigate.parent_close, opts('Close Directory'))
+  vim.keymap.set('n', '', api.node.open.edit, opts('Open'))
+  vim.keymap.set('n', '', api.node.open.preview, opts('Open Preview'))
+  vim.keymap.set('n', '>', api.node.navigate.sibling.next, opts('Next Sibling'))
+  vim.keymap.set('n', '<', api.node.navigate.sibling.prev, opts('Previous Sibling'))
+  vim.keymap.set('n', '.', api.node.run.cmd, opts('Run Command'))
+  vim.keymap.set('n', '-', api.tree.change_root_to_parent, opts('Up'))
+  vim.keymap.set('n', 'a', api.fs.create, opts('Create'))
+  vim.keymap.set('n', 'bd', api.marks.bulk.delete, opts('Delete Bookmarked'))
+  vim.keymap.set('n', 'bmv', api.marks.bulk.move, opts('Move Bookmarked'))
+  vim.keymap.set('n', 'B', api.tree.toggle_no_buffer_filter, opts('Toggle Filter: No Buffer'))
+  vim.keymap.set('n', 'c', api.fs.copy.node, opts('Copy'))
+  vim.keymap.set('n', 'C', api.tree.toggle_git_clean_filter, opts('Toggle Filter: Git Clean'))
+  vim.keymap.set('n', '[c', api.node.navigate.git.prev, opts('Prev Git'))
+  vim.keymap.set('n', ']c', api.node.navigate.git.next, opts('Next Git'))
+  vim.keymap.set('n', 'd', api.fs.remove, opts('Delete'))
+  vim.keymap.set('n', 'D', api.fs.trash, opts('Trash'))
+  vim.keymap.set('n', 'E', api.tree.expand_all, opts('Expand All'))
+  vim.keymap.set('n', 'e', api.fs.rename_basename, opts('Rename: Basename'))
+  vim.keymap.set('n', ']e', api.node.navigate.diagnostics.next, opts('Next Diagnostic'))
+  vim.keymap.set('n', '[e', api.node.navigate.diagnostics.prev, opts('Prev Diagnostic'))
+  vim.keymap.set('n', 'F', api.live_filter.clear, opts('Clean Filter'))
+  vim.keymap.set('n', 'f', api.live_filter.start, opts('Filter'))
+  vim.keymap.set('n', 'g?', api.tree.toggle_help, opts('Help'))
+  vim.keymap.set('n', 'gy', api.fs.copy.absolute_path, opts('Copy Absolute Path'))
+  vim.keymap.set('n', 't.', api.tree.toggle_hidden_filter, opts('Toggle Filter: Dotfiles'))
+  vim.keymap.set('n', 'ti', api.tree.toggle_gitignore_filter, opts('Toggle Filter: Git Ignore'))
+  vim.keymap.set('n', 'J', api.node.navigate.sibling.last, opts('Last Sibling'))
+  vim.keymap.set('n', 'K', api.node.navigate.sibling.first, opts('First Sibling'))
+  vim.keymap.set('n', 'm', api.marks.toggle, opts('Toggle Bookmark'))
+  vim.keymap.set('n', 'o', api.node.open.edit, opts('Open'))
+  vim.keymap.set('n', 'O', api.node.open.no_window_picker, opts('Open: No Window Picker'))
+  vim.keymap.set('n', 'p', api.fs.paste, opts('Paste'))
+  vim.keymap.set('n', 'P', api.node.navigate.parent, opts('Parent Directory'))
+  vim.keymap.set('n', 'q', api.tree.close, opts('Close'))
+  vim.keymap.set('n', 'r', api.fs.rename, opts('Rename'))
+  vim.keymap.set('n', 'R', api.tree.reload, opts('Refresh'))
+  vim.keymap.set('n', 's', api.node.run.system, opts('Run System'))
+  vim.keymap.set('n', 'S', api.tree.search_node, opts('Search'))
+  vim.keymap.set('n', 'U', api.tree.toggle_custom_filter, opts('Toggle Filter: Hidden'))
+  vim.keymap.set('n', 'W', api.tree.collapse_all, opts('Collapse'))
+  vim.keymap.set('n', 'x', api.fs.cut, opts('Cut'))
+  vim.keymap.set('n', 'y', api.fs.copy.filename, opts('Copy Name'))
+  vim.keymap.set('n', 'Y', api.fs.copy.relative_path, opts('Copy Relative Path'))
+  vim.keymap.set('n', '<2-LeftMouse>', api.node.open.edit, opts('Open'))
+end
+
+
+
+return {
+  "nvim-tree/nvim-tree.lua",
+  version = "*",
+  lazy = false,
+  dependencies = {
+    "nvim-tree/nvim-web-devicons",
+  },
+  config = function()
+    require("nvim-tree").setup({
+      sort_by = "case_sensitive",
+      on_attach = my_on_attach,
+      view = {
+        width = 30,
+      },
+      renderer = {
+        group_empty = true,
+      },
+      filters = {
+        dotfiles = true,
+      },
+      update_focused_file = {
+        enable = true,
+      },
+    })
+  end,
+}
diff --git a/.config/nvim/lua/custom/plugins/nvterm.lua b/.config/nvim/lua/custom/plugins/nvterm.lua
new file mode 100644
index 0000000..53be1e9
--- /dev/null
+++ b/.config/nvim/lua/custom/plugins/nvterm.lua
@@ -0,0 +1,17 @@
+local toggle_modes = { 'n', 't' }
+local mappings = {
+  { toggle_modes, '', function() require("nvterm.terminal").toggle('horizontal') end },
+  { toggle_modes, '', function() require("nvterm.terminal").toggle('vertical') end },
+  { toggle_modes, '', function() require("nvterm.terminal").toggle('float') end },
+}
+local opts = { noremap = true, silent = true }
+for _, mapping in ipairs(mappings) do
+  vim.keymap.set(mapping[1], mapping[2], mapping[3], opts)
+end
+
+return {
+  "NvChad/nvterm",
+  config = function()
+    require("nvterm").setup()
+  end,
+}
diff --git a/.config/nvim/lua/custom/plugins/treesitter-context.lua b/.config/nvim/lua/custom/plugins/treesitter-context.lua
new file mode 100644
index 0000000..934eaef
--- /dev/null
+++ b/.config/nvim/lua/custom/plugins/treesitter-context.lua
@@ -0,0 +1,21 @@
+return {
+  "nvim-treesitter/nvim-treesitter-context",
+  version = "*",
+  lazy = false,
+  config = function()
+  require('treesitter-context').setup{
+    enable = true, -- Enable this plugin (Can be enabled/disabled later via commands)
+    max_lines = 0, -- How many lines the window should span. Values <= 0 mean no limit.
+    min_window_height = 0, -- Minimum editor window height to enable context. Values <= 0 mean no limit.
+    line_numbers = true,
+    multiline_threshold = 20, -- Maximum number of lines to collapse for a single context line
+    trim_scope = 'outer', -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer'
+    mode = 'cursor',  -- Line used to calculate context. Choices: 'cursor', 'topline'
+    -- Separator between context and content. Should be a single character string, like '-'.
+    -- When separator is set, the context will only show up when there are at least 2 lines above cursorline.
+    separator = nil,
+    zindex = 20, -- The Z-index of the context window
+    on_attach = nil, -- (fun(buf: integer): boolean) return false to disable attaching
+  }
+  end,
+}
\ No newline at end of file
diff --git a/.config/nvim/lua/custom/plugins/undotree.lua b/.config/nvim/lua/custom/plugins/undotree.lua
new file mode 100644
index 0000000..d9076e8
--- /dev/null
+++ b/.config/nvim/lua/custom/plugins/undotree.lua
@@ -0,0 +1 @@
+return {}
diff --git a/.config/nvim/lua/kickstart/plugins/autoformat.lua b/.config/nvim/lua/kickstart/plugins/autoformat.lua
new file mode 100644
index 0000000..bc56b15
--- /dev/null
+++ b/.config/nvim/lua/kickstart/plugins/autoformat.lua
@@ -0,0 +1,74 @@
+-- autoformat.lua
+--
+-- Use your language server to automatically format your code on save.
+-- Adds additional commands as well to manage the behavior
+
+return {
+  'neovim/nvim-lspconfig',
+  config = function()
+    -- Switch for controlling whether you want autoformatting.
+    --  Use :KickstartFormatToggle to toggle autoformatting on or off
+    local format_is_enabled = true
+    vim.api.nvim_create_user_command('KickstartFormatToggle', function()
+      format_is_enabled = not format_is_enabled
+      print('Setting autoformatting to: ' .. tostring(format_is_enabled))
+    end, {})
+
+    -- Create an augroup that is used for managing our formatting autocmds.
+    --      We need one augroup per client to make sure that multiple clients
+    --      can attach to the same buffer without interfering with each other.
+    local _augroups = {}
+    local get_augroup = function(client)
+      if not _augroups[client.id] then
+        local group_name = 'kickstart-lsp-format-' .. client.name
+        local id = vim.api.nvim_create_augroup(group_name, { clear = true })
+        _augroups[client.id] = id
+      end
+
+      return _augroups[client.id]
+    end
+
+    -- Whenever an LSP attaches to a buffer, we will run this function.
+    --
+    -- See `:help LspAttach` for more information about this autocmd event.
+    vim.api.nvim_create_autocmd('LspAttach', {
+      group = vim.api.nvim_create_augroup('kickstart-lsp-attach-format', { clear = true }),
+      -- This is where we attach the autoformatting for reasonable clients
+      callback = function(args)
+        local client_id = args.data.client_id
+        local client = vim.lsp.get_client_by_id(client_id)
+        local bufnr = args.buf
+
+        -- Only attach to clients that support document formatting
+        if not client.server_capabilities.documentFormattingProvider then
+          return
+        end
+
+        -- Tsserver usually works poorly. Sorry you work with bad languages
+        -- You can remove this line if you know what you're doing :)
+        if client.name == 'tsserver' then
+          return
+        end
+
+        -- Create an autocmd that will run *before* we save the buffer.
+        --  Run the formatting command for the LSP that has just attached.
+        vim.api.nvim_create_autocmd('BufWritePre', {
+          group = get_augroup(client),
+          buffer = bufnr,
+          callback = function()
+            if not format_is_enabled then
+              return
+            end
+
+            vim.lsp.buf.format {
+              async = false,
+              filter = function(c)
+                return c.id == client.id
+              end,
+            }
+          end,
+        })
+      end,
+    })
+  end,
+}
diff --git a/.config/nvim/lua/kickstart/plugins/debug.lua b/.config/nvim/lua/kickstart/plugins/debug.lua
new file mode 100644
index 0000000..7fc783f
--- /dev/null
+++ b/.config/nvim/lua/kickstart/plugins/debug.lua
@@ -0,0 +1,87 @@
+-- debug.lua
+--
+-- Shows how to use the DAP plugin to debug your code.
+--
+-- Primarily focused on configuring the debugger for Go, but can
+-- be extended to other languages as well. That's why it's called
+-- kickstart.nvim and not kitchen-sink.nvim ;)
+
+return {
+  -- NOTE: Yes, you can install new plugins here!
+  'mfussenegger/nvim-dap',
+  -- NOTE: And you can specify dependencies as well
+  dependencies = {
+    -- Creates a beautiful debugger UI
+    'rcarriga/nvim-dap-ui',
+
+    -- Installs the debug adapters for you
+    'williamboman/mason.nvim',
+    'jay-babu/mason-nvim-dap.nvim',
+
+    -- Add your own debuggers here
+    'leoluz/nvim-dap-go',
+  },
+  config = function()
+    local dap = require 'dap'
+    local dapui = require 'dapui'
+
+    require('mason-nvim-dap').setup {
+      -- Makes a best effort to setup the various debuggers with
+      -- reasonable debug configurations
+      automatic_setup = true,
+
+      -- You can provide additional configuration to the handlers,
+      -- see mason-nvim-dap README for more information
+      handlers = {},
+
+      -- You'll need to check that you have the required things installed
+      -- online, please don't ask me how to install them :)
+      ensure_installed = {
+        -- Update this to ensure that you have the debuggers for the langs you want
+        'delve',
+      },
+    }
+
+    -- Basic debugging keymaps, feel free to change to your liking!
+    vim.keymap.set('n', '', dap.continue, { desc = 'Debug: Start/Continue' })
+    vim.keymap.set('n', '', dap.step_into, { desc = 'Debug: Step Into' })
+    vim.keymap.set('n', '', dap.step_over, { desc = 'Debug: Step Over' })
+    vim.keymap.set('n', '', dap.step_out, { desc = 'Debug: Step Out' })
+    vim.keymap.set('n', 'b', dap.toggle_breakpoint, { desc = 'Debug: Toggle Breakpoint' })
+    vim.keymap.set('n', 'B', function()
+      dap.set_breakpoint(vim.fn.input 'Breakpoint condition: ')
+    end, { desc = 'Debug: Set Breakpoint' })
+
+    -- Dap UI setup
+    -- For more information, see |:help nvim-dap-ui|
+    dapui.setup {
+      -- Set icons to characters that are more likely to work in every terminal.
+      --    Feel free to remove or use ones that you like more! :)
+      --    Don't feel like these are good choices.
+      icons = { expanded = '▾', collapsed = '▸', current_frame = '*' },
+      controls = {
+        icons = {
+          pause = '⏸',
+          play = '▶',
+          step_into = '⏎',
+          step_over = '⏭',
+          step_out = '⏮',
+          step_back = 'b',
+          run_last = '▶▶',
+          terminate = '⏹',
+          disconnect = '⏏',
+        },
+      },
+    }
+
+    -- Toggle to see last session result. Without this, you can't see session output in case of unhandled exception.
+    vim.keymap.set('n', '', dapui.toggle, { desc = 'Debug: See last session result.' })
+
+    dap.listeners.after.event_initialized['dapui_config'] = dapui.open
+    dap.listeners.before.event_terminated['dapui_config'] = dapui.close
+    dap.listeners.before.event_exited['dapui_config'] = dapui.close
+
+    -- Install golang specific config
+    require('dap-go').setup()
+  end,
+}
diff --git a/users/home-manager/nvim/config.lua b/users/home-manager/nvim/config.lua
deleted file mode 100644
index 726b756..0000000
--- a/users/home-manager/nvim/config.lua
+++ /dev/null
@@ -1,29 +0,0 @@
--- -------
--- Library
--- -------
-
-function map (mode, shortcut, command)
-vim.api.nvim_set_keymap(mode, shortcut, command, { noremap = true, silent = true })
-end
-function nmap(shortcut, command)
-map('n', shortcut, command)
-end
-function imap(shortcut, command)
-map('i', shortcut, command)
-end
-
--- ------
--- Config
--- ------
-
-vim.cmd([[
-set autoindent expandtab tabstop=4 shiftwidth=4
-set clipboard=unnamed
-syntax on
-set cc=80
-colorscheme habamax
-set list
-set listchars=tab:→\ ,space:·,nbsp:␣,trail:•,precedes:«,extends:»
-map  
-]])
-
diff --git a/users/home-manager/nvim/nvim.nix b/users/home-manager/nvim/nvim.nix
index 3a03a1a..0a865f2 100644
--- a/users/home-manager/nvim/nvim.nix
+++ b/users/home-manager/nvim/nvim.nix
@@ -1,72 +1,24 @@
 { user, pkgs, ... }:
 {
   home-manager.users.${user} = { pkgs, ...}: {
+    home.file.".config/nvim" = {
+      enable = true;
+      recursive = true;
+      source = ../../../.config/nvim;
+      target = ".config/nvim";
+    };
     programs.neovim = {
       enable = true;
-      defaultEditor = true;
-      viAlias = true;
-      vimAlias = true;
-
-      plugins = with pkgs.vimPlugins; [
-        (nvim-treesitter.withAllGrammars)
-        vim-nix
-        # Buffer tabs
-        {
-            plugin = bufferline-nvim;
-            type = "lua";
-            config = ''
-                require("bufferline").setup{ }
-                nmap("b", ":BufferLineCycleNext")
-                nmap("B", ":BufferLineCyclePrev")
-            '';
-        }
-        # File browser
-        {
-            plugin = nvim-tree-lua;
-            type = "lua";
-            config = ''
-                require("nvim-tree").setup()
-            '';
-        }
-      {
-        plugin = vim-which-key;
-        type = "lua";
-        # TODO: How to port this to Lua?
-        config = ''
-          vim.cmd([[
-          map  
-          let g:mapleader = "\"
-          let g:maplocalleader = ','
-          nnoremap        :WhichKey ''
-          nnoremap   :WhichKey  ','
-          ]])
-        '';
-      }
-      ];
       extraPackages = with pkgs; [
-        nodejs
-        nil
+        rnix-lsp
+        gcc
+        ripgrep
+        fd
+        cmake
+        nodePackages.pyright
+        nodePackages.eslint
+        ccls
       ];
-      extraConfig = ''
-      lua << EOF
-      ${builtins.readFile ./config.lua}
-      EOF
-      '';
-      coc.enable = true;
-      coc.settings = ''
-        "suggest.noselect" = true;
-        "suggest.enablePreview" = true;
-        "suggest.enablePreselect" = false;
-        "suggest.disableKind" = true;
-        "coc.preferences.formatOnSave" = true;
-        "languageserver": {
-            "nix": {
-            "command": "${pkgs.nil}/bin/nil",
-            "filetypes": ["nix"],
-            "rootPatterns":  ["flake.nix"],
-            }
-        }
-      '';
     };
   };
 }