diff --git a/home-mandlm.nix b/home-mandlm.nix index ef7cbe9..4729896 100644 --- a/home-mandlm.nix +++ b/home-mandlm.nix @@ -12,8 +12,24 @@ htop ripgrep pavucontrol + gcc + nodejs + unzip + cargo + rustc + gcc ]; + file = { + ".config/nvim/init.lua" = { + source = nvim/init.lua; + }; + ".config/nvim/lua" = { + source = nvim/lua; + recursive = true; + }; + }; + stateVersion = "22.05"; }; @@ -63,9 +79,6 @@ neovim = { enable = true; - plugins = with pkgs.vimPlugins; [ - vim-fugitive - ]; }; tmux = { diff --git a/nvim/.gitignore b/nvim/.gitignore new file mode 100644 index 0000000..87553b2 --- /dev/null +++ b/nvim/.gitignore @@ -0,0 +1 @@ +/plugin/ diff --git a/nvim/init.lua b/nvim/init.lua new file mode 100644 index 0000000..49b81ae --- /dev/null +++ b/nvim/init.lua @@ -0,0 +1,4 @@ +require("keymaps") +require('options') +require('plugins') +require('themes') diff --git a/nvim/lua/keymaps.lua b/nvim/lua/keymaps.lua new file mode 100644 index 0000000..3b40c13 --- /dev/null +++ b/nvim/lua/keymaps.lua @@ -0,0 +1,55 @@ +-- source file everytime it changes +vim.cmd([[ + augroup user_keymaps + autocmd! + autocmd BufWritePost keymaps.lua source + augroup end +]]) + +local function nnoremap(key, command) + vim.api.nvim_set_keymap("n", key, command, { noremap = true }) +end + +vim.g.mapleader = " " +vim.g.maplocalleader = " " + +-- Move around windows +nnoremap("", "h") +nnoremap("", "j") +nnoremap("", "k") +nnoremap("", "l") + +-- Switch buffers +nnoremap("", ":TablineBufferNext") +nnoremap("", ":TablineBufferPrevious") + +-- fugitive +nnoremap("g", ":0Git") +nnoremap("G", ":GV --all") + +-- telescope +nnoremap("ff", "Telescope find_files theme=dropdown") +nnoremap("fb", "Telescope buffers theme=dropdown") +nnoremap("fg", "Telescope git_files theme=dropdown") +nnoremap("", "Telescope grep_string") +nnoremap("", "Telescope live_grep") + +-- terminal +vim.api.nvim_create_autocmd("TermOpen", { + pattern = "term://*", + callback = function() + local opts = { noremap = true } + vim.api.nvim_buf_set_keymap(0, 't', '', [[]], opts) + vim.api.nvim_buf_set_keymap(0, 't', '', [[h]], opts) + vim.api.nvim_buf_set_keymap(0, 't', '', [[j]], opts) + vim.api.nvim_buf_set_keymap(0, 't', '', [[k]], opts) + vim.api.nvim_buf_set_keymap(0, 't', '', [[l]], opts) + end, + desc = "Map terminal esc and window switch keys", +}) + +-- buffer closing +nnoremap("q", ":Bdelete") + +-- toggle search highlighting +vim.cmd('nnoremap * v:hlsearch ? ":nohlsearch" : "*"') diff --git a/nvim/lua/options.lua b/nvim/lua/options.lua new file mode 100644 index 0000000..87fde64 --- /dev/null +++ b/nvim/lua/options.lua @@ -0,0 +1,62 @@ +-- source file everytime it changes +vim.cmd([[ + augroup user_options + autocmd! + autocmd BufWritePost options.lua source + augroup end +]]) + +-- termguicolors +vim.opt.termguicolors = true + +-- line numbers +vim.opt.number = true + +-- tabwidth +vim.opt.tabstop = 4 +vim.opt.shiftwidth = 4 + +-- indent with spaces +vim.opt.expandtab = true + +-- scroll offset +vim.opt.scrolloff = 4 + +-- don't warp lines +vim.opt.wrap = false + +-- split to right/below +vim.opt.splitright = true +vim.opt.splitbelow = true + +-- presistent undo +vim.opt.undofile = true + +-- searching +vim.opt.ignorecase = true +vim.opt.smartcase = true + +-- preview commands +vim.opt.inccommand = "split" + +-- completion +vim.opt.completeopt = "menu,menuone,noselect" + +-- set cursorline in active window +vim.cmd([[ + augroup CursorLine + autocmd! + autocmd VimEnter,WinEnter,BufWinEnter * setlocal cursorline + autocmd WinLeave * setlocal nocursorline + augroup END +]]) + +-- configure terminal +vim.cmd([[ + augroup terminal_setup + autocmd! + autocmd TermOpen * startinsert + autocmd TermOpen * setlocal nonumber norelativenumber + augroup END +]]) + diff --git a/nvim/lua/plugins.lua b/nvim/lua/plugins.lua new file mode 100644 index 0000000..62edcb0 --- /dev/null +++ b/nvim/lua/plugins.lua @@ -0,0 +1,203 @@ +local fn = vim.fn + +-- boostrap packer +local install_path = fn.stdpath('data') .. '/site/pack/packer/opt/packer.nvim' +local packer_bootstrap +if fn.empty(fn.glob(install_path)) > 0 then + packer_bootstrap = fn.system({ + 'git', 'clone', 'https://github.com/wbthomason/packer.nvim', + install_path + }) +end + +-- run PackerSync everytime plugins.lua is updated +vim.cmd([[ + augroup packer_user_config + autocmd! + autocmd BufWritePost plugins.lua source | PackerSync + augroup end +]]) + +vim.cmd([[packadd packer.nvim]]) + +-- initialize plugins +return require('packer').startup(function(use) + -- let packer manage itself + use({ 'wbthomason/packer.nvim', opt = true }) + + -- theme + use("ishan9299/nvim-solarized-lua") + + -- commenting + use { + 'numToStr/Comment.nvim', + config = function() require('Comment').setup({}) end + } + + -- session handling + use('tpope/vim-obsession') + use('dhruvasagar/vim-prosession') + + -- tabline + use { + 'kdheepak/tabline.nvim', + config = function() + require 'tabline'.setup { + enable = true, + options = { show_bufnr = true, show_filename_only = true } + } + end, + requires = { + { 'hoob3rt/lualine.nvim' }, + { 'kyazdani42/nvim-web-devicons', opt = true } + } + } + + -- status line + use { + 'nvim-lualine/lualine.nvim', + requires = { 'kyazdani42/nvim-web-devicons', opt = true }, + config = function() + require('lualine').setup({ + options = { globalstatus = true }, + sections = { + lualine_c = { { "filename", path = 1 }, "require('lsp-status').status()" } + }, + extensions = { "toggleterm" } + }) + end + } + + -- blankline + use({ + "lukas-reineke/indent-blankline.nvim", + config = function() + require("indent_blankline").setup { + char = "┊", + buftype_exclude = { "terminal", "help", "nofile" }, + filetype_exclude = { 'help', 'packer' }, + show_trailing_blankline_indent = false + } + end + }) + + -- git + use('tpope/vim-fugitive') + use({ + 'lewis6991/gitsigns.nvim', + requires = { 'nvim-lua/plenary.nvim' }, + config = function() require('gitsigns').setup() end + }) + use("junegunn/gv.vim") + + -- autocompletion + use({ + "L3MON4D3/LuaSnip", + requires = { "rafamadriz/friendly-snippets" }, + config = function() + require("luasnip.loaders.from_vscode").lazy_load() + end + }) + use({ + "hrsh7th/nvim-cmp", + requires = { + "hrsh7th/cmp-nvim-lsp", "hrsh7th/cmp-buffer", "hrsh7th/cmp-path", + "hrsh7th/cmp-cmdline", "hrsh7th/cmp-git", "hrsh7th/cmp-nvim-lua", + "saadparwaiz1/cmp_luasnip", "hrsh7th/cmp-nvim-lsp-signature-help", + "davidsierradz/cmp-conventionalcommits", "hrsh7th/cmp-nvim-lua", + "hrsh7th/cmp-calc" + }, + config = function() require('plugins.nvim-cmp') end, + }) + + -- language server + use { + 'junnplus/nvim-lsp-setup', + requires = { + 'neovim/nvim-lspconfig', + 'williamboman/nvim-lsp-installer', + + -- additional rust tools + "simrat39/rust-tools.nvim", + + -- highlight current symbol + "RRethy/vim-illuminate", + + -- lua plugin development + "folke/lua-dev.nvim", + + -- lsp status + "nvim-lua/lsp-status.nvim", + }, + config = function() require('plugins.nvim-lsp-setup') end, + } + + -- null-ls + use { + "jose-elias-alvarez/null-ls.nvim", + requres = { + { "nvim-lua/plenary.nvim" }, + }, + config = function() + require("null-ls").setup({ + sources = { + require("null-ls").builtins.formatting.prettier, + }, + on_attach = function(client) + local utils = require("nvim-lsp-setup.utils") + utils.format_on_save(client) + end, + }) + end, + } + + -- treesitter + use({ + 'nvim-treesitter/nvim-treesitter', + config = function() require('plugins.treesitter') end, + run = ':TSUpdate' + }) + + -- Telescope + use({ + "nvim-telescope/telescope.nvim", + requires = { + { "nvim-lua/plenary.nvim" }, + { "nvim-telescope/telescope-fzf-native.nvim", run = "make" }, + { "nvim-telescope/telescope-ui-select.nvim" }, + }, + config = function() require("plugins.telescope") end + }) + + -- automatic pairs + use({ "Raimondi/delimitMate" }) + + -- markdown preview + use({ "iamcco/markdown-preview.nvim", run = ":call mkdp#util#install()" }) + + -- terminal + use({ + "akinsho/nvim-toggleterm.lua", + config = function() + require("toggleterm").setup({ size = 32, open_mapping = [[]] }) + end + }) + + -- buffer closing + use({ "sar/bbye.nvim" }) + + -- ansible filetype + use({ "pearofducks/ansible-vim" }) + + -- nvim-notify + use({ "rcarriga/nvim-notify", + config = function() + require("notify").setup({ + stages = "fade", + }) + vim.notify = require("notify") + end + }) + + if packer_bootstrap then require('packer').sync() end +end) diff --git a/nvim/lua/plugins/bufferline.lua b/nvim/lua/plugins/bufferline.lua new file mode 100644 index 0000000..6d4163d --- /dev/null +++ b/nvim/lua/plugins/bufferline.lua @@ -0,0 +1,19 @@ +require('bufferline') + +-- format as ". " +local tabname_format = function (opts) + return string.format('%s.', opts.ordinal) +end + +require('bufferline').setup({ + options = { + always_show_bufferline = true, + numbers = tabname_format, + show_buffer_icons = true, + show_buffer_close_icons = false, + show_close_icon = false, + --separator_style = 'slant', + }, + -- Don't use italic on current buffer + highlights = {buffer_selected = { gui = "bold" },}, +}) diff --git a/nvim/lua/plugins/nvim-cmp.lua b/nvim/lua/plugins/nvim-cmp.lua new file mode 100644 index 0000000..9261548 --- /dev/null +++ b/nvim/lua/plugins/nvim-cmp.lua @@ -0,0 +1,61 @@ +local has_words_before = function() + local line, col = unpack(vim.api.nvim_win_get_cursor(0)) + return col ~= 0 and + vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub( + col, col):match("%s") == nil +end + +local cmp = require('cmp') +local luasnip = require("luasnip") + +cmp.setup({ + snippet = { + expand = function(args) + require("luasnip").lsp_expand(args.body) + end + }, + sources = require("cmp").config.sources({ + { name = "nvim_lsp" }, { name = "luasnip" }, { name = "path" }, + { name = "buffer" }, { name = "git" }, + { name = 'nvim_lsp_signature_help' }, + { name = "conventionalcommits" }, { name = "nvim-lua" }, + { name = "calc" } + }), + mapping = cmp.mapping.preset.insert({ + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.complete(), + [''] = cmp.mapping.abort(), + [''] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif luasnip.expand_or_jumpable() then + luasnip.expand_or_jump() + elseif has_words_before() then + cmp.complete() + else + fallback() + end + end, { "i", "s" }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { "i", "s" }), + }), + experimental = { ghost_text = true } +}) + +-- `/` cmdline setup. +cmp.setup.cmdline('/', { sources = { { name = 'buffer' } } }) + +-- `:` cmdline setup. +cmp.setup.cmdline(':', { + sources = cmp.config + .sources({ { name = 'path' } }, { { name = 'cmdline' } }) +}) diff --git a/nvim/lua/plugins/nvim-lsp-setup.lua b/nvim/lua/plugins/nvim-lsp-setup.lua new file mode 100644 index 0000000..8373633 --- /dev/null +++ b/nvim/lua/plugins/nvim-lsp-setup.lua @@ -0,0 +1,64 @@ +local lsp_status = require("lsp-status") +lsp_status.config({ + current_function = false, + show_filename = false, + diagnostics = true, +}) +lsp_status.register_progress() + +local utils = require("nvim-lsp-setup.utils") + +require("nvim-lsp-setup").setup({ + default_mappings = false, + mappings = { + gD = "lua vim.lsp.buf.declaration()", + gd = "Telescope lsp_definitions", + gt = "Telescope lsp_type_definitions", + gi = "Telescope lsp_implementations", + gr = "Telescope lsp_references", + K = "lua vim.lsp.buf.hover()", + [""] = "lua vim.lsp.buf.signature_help()", + ["rn"] = "lua vim.lsp.buf.rename()", + ["ca"] = "lua vim.lsp.buf.code_action()", + ["f"] = "lua vim.lsp.buf.formatting()", + ["e"] = "lua vim.lsp.diagnostic.show_line_diagnostics()", + ["d"] = "Telescope diagnostics", + [""] = "lua vim.diagnostic.goto_prev()", + [""] = "lua vim.diagnostic.goto_next()", + }, + on_attach = function(client) + utils.format_on_save(client) + require("illuminate").on_attach(client) + lsp_status.on_attach(client) + end, + capabilities = vim.tbl_extend("keep", vim.lsp.protocol.make_client_capabilities(), lsp_status.capabilities), + servers = { + ansiblels = {}, + bashls = {}, + dockerls = {}, + eslint = {}, + jsonls = {}, + pylsp = {}, + rust_analyzer = require("nvim-lsp-setup.rust-tools").setup({ + server = { + settings = { + ["rust-analyzer"] = { + cargo = { + loadOutDirsFromCheck = true, + }, + checkOnSave = { command = "clippy" }, + procMacro = { + enable = true, + }, + }, + }, + }, + }), + sumneko_lua = require('lua-dev').setup({}), + taplo = {}, + terraformls = {}, + tflint = {}, + volar = {}, + yamlls = {}, + }, +}) diff --git a/nvim/lua/plugins/telescope.lua b/nvim/lua/plugins/telescope.lua new file mode 100644 index 0000000..836d7a9 --- /dev/null +++ b/nvim/lua/plugins/telescope.lua @@ -0,0 +1,33 @@ +local telescope = require("telescope") +local actions = require("telescope.actions") +local themes = require("telescope.themes") + +telescope.setup({ + defaults = { + mappings = { + i = { + [""] = actions.move_selection_next, + [""] = actions.move_selection_previous, + [""] = actions.close, + [""] = actions.close + }, + n = { + [""] = actions.close, + [""] = actions.close + } + } + }, + extensions = { + fzf = { + fuzzy = true, + override_generic_sorter = true, + override_file_sorter = true + }, + ["ui-select"] = { + themes.get_dropdown({}) + }, + } +}) + +telescope.load_extension("fzf") +telescope.load_extension("ui-select") diff --git a/nvim/lua/plugins/treesitter.lua b/nvim/lua/plugins/treesitter.lua new file mode 100644 index 0000000..45571c9 --- /dev/null +++ b/nvim/lua/plugins/treesitter.lua @@ -0,0 +1,9 @@ +require('nvim-treesitter.configs').setup({ + highlight = {enable = true, additional_vim_regex_highlighting = false}, + indent = {enable = true}, + ensure_installed = { + "bash", "c", "cpp", "css", "dockerfile", "hcl", "html", "javascript", + "json", "latex", "lua", "markdown", "python", "rust", "svelte", "toml", + "tsx", "typescript", "vim", "vue", "yaml" + } +}) diff --git a/nvim/lua/themes.lua b/nvim/lua/themes.lua new file mode 100644 index 0000000..53bc916 --- /dev/null +++ b/nvim/lua/themes.lua @@ -0,0 +1,10 @@ +-- source file everytime it changes +vim.cmd([[ + augroup user_theme_config + autocmd! + autocmd BufWritePost themes.lua source + augroup end +]]) + +vim.opt.background = 'dark' +vim.cmd("colorscheme solarized")