-- To install everything run `:PackerSync` -- https://dev.to/voyeg3r/writing-useful-lua-functions-to-my-neovim-14ki -- function to remove whitespace and preserve spot on save function _G.preserve(cmd) cmd = string.format('keepjumps keeppatterns execute %q', cmd) local original_cursor = vim.fn.winsaveview() vim.api.nvim_command(cmd) vim.fn.winrestview(original_cursor) end vim.cmd([[autocmd BufWritePre,FileWritePre,FileAppendPre,FilterWritePre * :lua preserve('%s/\\s\\+$//ge')]]) -- Bootstrap packer if not installed local fn = vim.fn local install_path = fn.stdpath('data')..'/site/pack/packer/start/packer.nvim' if fn.empty(fn.glob(install_path)) > 0 then fn.system({'git', 'clone', '--depth', '1', 'https://github.com/wbthomason/packer.nvim', install_path}) vim.cmd 'packadd packer.nvim' end -- Debug function for printing lua tables function _G.print_table(mytable) for k,v in pairs(mytable) do if (type(v) == "table") then print(k) print_table(v) else print(k, v) end end end -- https://old.reddit.com/r/neovim/comments/lrz18i/how_to_change_colorscheme_in_lua_without_any/ vim.g.colors_name = "nord" -- Set up spacebar as leader -- https://icyphox.sh/blog/nvim-lua/ vim.api.nvim_set_keymap('n', '', '', {}) vim.g.mapleader = ' ' -- Set spaces > tabs, 4 as default vim.o.expandtab = true vim.o.tabstop = 4 vim.o.shiftwidth = 0 vim.o.relativenumber = true -- Distable word wrap vim.o.wrap = false vim.o.history = 1000 -- Wildmode show list, complete to first result vim.o.wildignore = "*/app/cache,*/vendor,*/env,*.pyc,*/venv,*/__pycache__,*/venv" -- Default split directions vim.o.splitright = true vim.o.splitbelow = true -- set spelling language vim.o.spelllang = "en_ca" local highlights = { "Search ctermfg=166", "DiffAdd cterm=BOLD ctermfg=NONE ctermbg=22", "DiffDelete cterm=BOLD ctermfg=NONE ctermbg=52", "DiffChange cterm=BOLD ctermfg=NONE ctermbg=23", "DiffText cterm=BOLD ctermfg=NONE ctermbg=23", "Normal guibg=NONE ctermbg=NONE", "Search ctermbg=None ctermfg=166", "PrimaryBlock ctermfg=06 ctermbg=NONE", "SecondaryBlock ctermfg=06 ctermbg=NONE", "Blanks ctermfg=07 ctermbg=NONE", "ColorColumn ctermbg=cyan", "IndentBlanklineIndent1 ctermbg=234 ctermfg=NONE", "IndentBlanklineIndent2 ctermbg=235 ctermfg=NONE", } for i, highlight in ipairs(highlights) do vim.cmd('au VimEnter * hi ' .. highlight) end -- Along with the highlight definition for ColorColumn above, these options -- will set colored marks at certain line lengths vim.cmd [[ au BufEnter *.py let w:m1=matchadd('ColorColumn', '\%81v', 100) au BufEnter *.py let w:m2=matchadd('Error', '\%121v', 100) au BufLeave *.py call clearmatches() ]] -- Custom commands vim.cmd [[ command! MakeTagsPython !ctags --exclude=venv --languages=python --python-kinds=-i -R . ]] -- When using tab, enter will accept the current selection and close the window -- instead of inserting a newline vim.cmd [[ inoremap pumvisible() ? "\" : "\" ]] -- Keymaps --noh gets rid of highlighted search results vim.api.nvim_set_keymap('n', '', ':noh', { noremap = true }) -- `jj` maps to escape vim.api.nvim_set_keymap('i', 'jj', '', { noremap = true }) -- Visually select last copied text vim.api.nvim_set_keymap('n', 'gp', "`[v`]", { noremap = true }) -- Changelist navigation vim.api.nvim_set_keymap('n', '_', '[c', { noremap = true }) vim.api.nvim_set_keymap('n', '=', ']c', { noremap = true }) vim.api.nvim_set_keymap('n', 'co', 'copen', { noremap = true }) vim.api.nvim_set_keymap('n', 'cc', 'cclose', { noremap = true }) -- Visually select line without ending vim.api.nvim_set_keymap('n', 'v', '^v$h', { noremap = true }) -- Ledger Shortcuts -- Copy the last entry vim.api.nvim_set_keymap('n', 'll', 'G{jV}y}p10l', { noremap = true }) -- Copy the current entry to the bottom, copy date from last entry vim.api.nvim_set_keymap('n', 'lb', '{jV}yGp10l{{jvEy}jvEpl', { noremap = true }) -- Copy the current entry to the next position vim.api.nvim_set_keymap('n', 'ln', '{jV}y}p10l', { noremap = true }) -- Jump down from line to replace dollar ammount vim.api.nvim_set_keymap('n', 'ld', 'j^f$lC', { noremap = true }) -- After searching pull entry to current position vim.api.nvim_set_keymap('n', 'ly', 'vapyp{{jvEy}jvEpl', { noremap = true }) -- Shorcut to insert pudb statements for python vim.api.nvim_set_keymap('n', 'ep', 'ofrom pudb import set_trace; set_trace()', { noremap = true }) -- Easy new tab creation vim.api.nvim_set_keymap('n', 't', "tabnew", { noremap = true }) vim.api.nvim_set_keymap('n', '', 'fT', { noremap = true }) vim.api.nvim_set_keymap('n', '', 'vT', { noremap = true }) vim.api.nvim_set_keymap('n', '', 'vT', { noremap = true }) vim.api.nvim_set_keymap('n', '', 'w', { noremap = true }) vim.api.nvim_set_keymap('n', 'ee', 'e!', { noremap = true }) vim.api.nvim_set_keymap('n', ' k', [[(v:count > 1 ? "m'" . v:count : '') . 'k']], { noremap = true }) vim.api.nvim_set_keymap('n', ' j', [[(v:count > 1 ? "m'" . v:count : '') . 'j']], { noremap = true }) -- Build a custom status line local status_line = { '%#PrimaryBlock#', '%#SecondaryBlock#', '%#Blanks#', '%f', '%m', '%=', '%#SecondaryBlock#', '%l,%c ', '%#PrimaryBlock#', '%{&filetype}', } vim.o.statusline = table.concat(status_line) -- Packer package manage return require('packer').startup(function() use { 'wbthomason/packer.nvim', config = function() vim.api.nvim_set_keymap('n', 'ps', 'source ~/.config/nvim/init.luaPackerSync', { noremap = true }) end } use 'Thornycrackers-Forks/nord-vim' use 'p00f/nvim-ts-rainbow' use { 'nvim-treesitter/nvim-treesitter', run = ':TSUpdate', config = function() require('nvim-treesitter.configs').setup { ensure_installed = { "python", "lua", "nix", "json", "bash", "html", "toml", }, highlight = { enable = true, }, indent = { enable = true, }, rainbow = { enable = true, -- I use termcolors but this errors if left blank colors = { "#000000", "#000000", "#000000", "#000000", }, termcolors = { 'darkblue', 'magenta', 'yellow', 'darkcyan', } } } end, } use { "neovim/nvim-lspconfig", requires = { {'hrsh7th/nvim-cmp'}, {'hrsh7th/cmp-nvim-lsp'}, }, config = function() nvim_lsp = require('lspconfig') -- Use an on_attach function to only map the following keys -- after the language server attaches to the current buffer local on_attach = function(client, bufnr) local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end -- Enable completion triggered by buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc') -- Mappings. local opts = { noremap=true, silent=true } -- See `:help vim.lsp.*` for documentation on any of the below functions buf_set_keymap('n', 'gD', 'lua vim.lsp.buf.declaration()', opts) buf_set_keymap('n', 'gd', 'lua vim.lsp.buf.definition()', opts) buf_set_keymap('n', 'K', 'lua vim.lsp.buf.hover()', opts) buf_set_keymap('n', 'gi', 'lua vim.lsp.buf.implementation()', opts) buf_set_keymap('n', '', 'lua vim.lsp.buf.signature_help()', opts) buf_set_keymap('n', 'wa', 'lua vim.lsp.buf.add_workspace_folder()', opts) buf_set_keymap('n', 'wr', 'lua vim.lsp.buf.remove_workspace_folder()', opts) buf_set_keymap('n', 'wl', 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', opts) buf_set_keymap('n', 'D', 'lua vim.lsp.buf.type_definition()', opts) buf_set_keymap('n', 'rn', 'lua vim.lsp.buf.rename()', opts) buf_set_keymap('n', 'ca', 'lua vim.lsp.buf.code_action()', opts) buf_set_keymap('n', 'gr', 'lua vim.lsp.buf.references()', opts) buf_set_keymap('n', 'e', 'lua vim.lsp.diagnostic.show_line_diagnostics()', opts) buf_set_keymap('n', '[d', 'lua vim.lsp.diagnostic.goto_prev()', opts) buf_set_keymap('n', ']d', 'lua vim.lsp.diagnostic.goto_next()', opts) buf_set_keymap('n', 'q', 'lua vim.lsp.diagnostic.set_loclist()', opts) buf_set_keymap('n', 'f', 'lua vim.lsp.buf.formatting()', opts) end -- Use a loop to conveniently call 'setup' on multiple servers and -- map buffer local keybindings when the language server attaches -- local servers = { 'pyls', 'rust_analyzer', 'tsserver' } local servers = { 'pyright', 'bashls' } -- Add additional capabilities supported by nvim-cmp local capabilities = vim.lsp.protocol.make_client_capabilities() capabilities = require('cmp_nvim_lsp').update_capabilities(capabilities) -- Setup language servers for _, lsp in ipairs(servers) do nvim_lsp[lsp].setup { on_attach = on_attach, flags = { debounce_text_changes = 150, }, capabilities = capabilities, } end -- Set completeopt to have a better completion experience vim.o.completeopt = 'menuone,noselect' -- nvim-cmp setup local cmp = require 'cmp' cmp.setup { mapping = { [''] = cmp.mapping.select_prev_item(), [''] = cmp.mapping.select_next_item(), [''] = cmp.mapping.scroll_docs(-4), [''] = cmp.mapping.scroll_docs(4), [''] = cmp.mapping.complete(), [''] = cmp.mapping.close(), [''] = cmp.mapping.confirm { behavior = cmp.ConfirmBehavior.Replace, select = true, }, [''] = function(fallback) if cmp.visible() then cmp.select_next_item() else fallback() end end, [''] = function(fallback) if cmp.visible() then cmp.select_prev_item() else fallback() end end, }, sources = { { name = 'nvim_lsp' }, }, } end, } use 'nvim-treesitter/playground' use 'tpope/vim-commentary' use 'tpope/vim-surround' use 'tpope/vim-repeat' use { 'nvim-telescope/telescope.nvim', requires = { {'nvim-lua/plenary.nvim'}, {'glepnir/lspsaga.nvim'}, {'nvim-telescope/telescope-fzf-native.nvim', run = 'make' }, }, config = function() vim.api.nvim_set_keymap('n', 'ff', "lua require('telescope.builtin').find_files({hidden=true})", { noremap = true }) vim.api.nvim_set_keymap('n', 'fb', 'Telescope buffers', { noremap = true }) vim.api.nvim_set_keymap('n', 'fj', 'Telescope jumplist', { noremap = true }) vim.api.nvim_set_keymap('n', 'f/', 'Telescope live_grep', { noremap = true }) vim.api.nvim_set_keymap('n', 'fa', 'Telescope grep_string', { noremap = true }) vim.api.nvim_set_keymap('n', 'fg', "lua require('telescope.builtin').git_status()", { noremap = true }) vim.api.nvim_set_keymap('n', 'ft', "lua require('telescope.builtin').tags({layout_strategy='center', only_sort_tags=true, show_line=true})", { noremap = true }) actions = require("telescope.actions") require("telescope").setup{ extensions = { fzf = { fuzzy = false, -- false will only do exact matching override_generic_sorter = true, -- override the generic sorter override_file_sorter = true, -- override the file sorter case_mode = "smart_case", -- or "ignore_case" or "respect_case" -- the default case_mode is "smart_case" } }, defaults = { mappings = { i = { [""] = actions.close, [''] = false, }, }, vimgrep_arguments = { 'rg', '--color=never', '--no-heading', '--with-filename', '--line-number', '--column', '--smart-case' }, prompt_prefix = "> ", selection_caret = "> ", entry_prefix = " ", initial_mode = "insert", selection_strategy = "reset", sorting_strategy = "descending", layout_strategy = "horizontal", layout_config = { horizontal = { mirror = false, }, vertical = { mirror = false, }, }, file_sorter = require'telescope.sorters'.get_fuzzy_file, file_ignore_patterns = {}, generic_sorter = require'telescope.sorters'.get_generic_fuzzy_sorter, winblend = 0, border = {}, borderchars = { '─', '│', '─', '│', '╭', '╮', '╯', '╰' }, color_devicons = true, use_less = true, path_display = {}, set_env = { ['COLORTERM'] = 'truecolor' }, -- default = nil, file_previewer = require'telescope.previewers'.vim_buffer_cat.new, grep_previewer = require'telescope.previewers'.vim_buffer_vimgrep.new, qflist_previewer = require'telescope.previewers'.vim_buffer_qflist.new, -- Developer configurations: Not meant for general override buffer_previewer_maker = require'telescope.previewers'.buffer_previewer_maker } } require('telescope').load_extension('fzf') end, } use { 'FooSoft/vim-argwrap', config = function() vim.api.nvim_set_keymap('n', 'ew', 'ArgWrap', { noremap = true }) end } use { 'tpope/vim-fugitive', config = function() vim.api.nvim_set_keymap('n', 'du', 'diffupdate', { noremap = true }) vim.api.nvim_set_keymap('n', 'dd', 'diffget', { noremap = true }) vim.api.nvim_set_keymap('n', 'df', 'diffput', { noremap = true }) vim.api.nvim_set_keymap('n', 'gs', 'Git', { noremap = true }) end } use { 'lukas-reineke/indent-blankline.nvim', config = function() require("indent_blankline").setup { char = " ", char_highlight_list = { "IndentBlanklineIndent1", "IndentBlanklineIndent2", }, show_trailing_blankline_indent = false, } end, } use { 'francoiscabrol/ranger.vim', -- bclose gets rid of "[Process exited 0]" annoyance requires = { {'rbgrouleff/bclose.vim'} }, } use { 'ptzz/lf.vim', -- Adds a floating window requires = { {'voldikss/vim-floaterm'} }, config = function() vim.g.floaterm_opener = "edit" vim.g.lf_replace_netrw = 1; vim.api.nvim_set_keymap('n', 'm', 'Lf', { noremap = true }); vim.api.nvim_set_keymap('n', 'n', 'LfWorkingDirectory', { noremap = true}); end } use 'bkad/CamelCaseMotion' use { 'phaazon/hop.nvim', as = 'hop', config = function() -- you can configure Hop the way you like here; see :h hop-config vim.api.nvim_set_keymap('', 's', 'HopChar2', { noremap = true }) require'hop'.setup { keys = 'etovxqpdygfblzhckisuran' } end } -- The treesitter for nix doesn't do indents use 'LnL7/vim-nix' use { 'dense-analysis/ale', config = function() vim.g.ale_linters = { shell = { "shellcheck", }, } end } end)