-- Install packer local install_path = vim.fn.stdpath 'data' .. '/site/pack/packer/start/packer.nvim' if vim.fn.empty(vim.fn.glob(install_path)) > 0 then vim.fn.execute('!git clone https://github.com/wbthomason/packer.nvim ' .. install_path) end vim.api.nvim_exec( [[ augroup Packer autocmd! autocmd BufWritePost init.lua PackerCompile augroup end ]], false ) local use = require('packer').use require('packer').startup(function() -- Package manager use 'wbthomason/packer.nvim' -- UI to select things (files, grep results, open buffers...) use { 'nvim-telescope/telescope.nvim', requires = { { 'nvim-lua/popup.nvim' }, { 'nvim-lua/plenary.nvim' }, { 'nvim-telescope/telescope-fzf-native.nvim', run = "make" }, { 'nvim-telescope/telescope-media-files.nvim' } } } -- Add indentation guides even on blank lines use 'lukas-reineke/indent-blankline.nvim' -- Add git related info in the signs columns and popups -- use { -- 'lewis6991/gitsigns.nvim', -- config = function() -- require('gitsigns').setup() -- end -- } -- Highlight, edit, and navigate code using a fast incremental parsing library use 'nvim-treesitter/nvim-treesitter' -- LSP use 'neovim/nvim-lspconfig' -- Autocompletion use 'hrsh7th/nvim-compe' -- Snippets use 'L3MON4D3/LuaSnip' -- Bufferline for tabs use { 'akinsho/nvim-bufferline.lua', requires = 'kyazdani42/nvim-web-devicons'} -- Remember last edit location in file use 'ethanholz/nvim-lastplace' -- File manager use { 'kyazdani42/nvim-tree.lua', requires = { 'kyazdani42/nvim-web-devicons', }, config = function() require'nvim-tree'.setup{} end } -- lualine use { 'nvim-lualine/lualine.nvim', requires = { 'kyazdan42/nvim-web-devicons', opt = true } } -- Editorconfig use 'editorconfig/editorconfig-vim' -- nvim-commenter use 'terrortylor/nvim-comment' -- sloum/gemini-vim-syntax use 'https://tildegit.org/sloum/gemini-vim-syntax' -- catppuccin theme use { 'catppuccin/nvim', as = 'catppuccin' } end) -- Local map function local function map(mode, lhs, rhs, opts) local options = { noremap = true, silent = true } if opts then options = vim.tbl_extend("force", options, opts) end vim.api.nvim_set_keymap(mode, lhs, rhs, options) end local opt = {} --Remap space as leader key map('', '', '', { noremap = true, silent = true }) vim.g.mapleader = ' ' vim.g.maplocalleader = ' ' --Incremental live completion vim.o.inccommand = 'split' --Set highlight on search vim.o.hlsearch = true --Make line numbers default vim.wo.number = true -- Relative line numbers vim.wo.relativenumber = true --Do not save when switching buffers vim.o.hidden = true --Enable mouse mode vim.o.mouse = 'a' --Enable break indent vim.o.breakindent = true --Save undo history vim.cmd [[set undofile]] --Case insensitive searching UNLESS /C or capital in search vim.o.ignorecase = true vim.o.smartcase = true --Decrease update time vim.o.updatetime = 250 vim.wo.signcolumn = 'yes' --Set colorscheme (order is important here) vim.o.termguicolors = true vim.g.catppuccin_flavour = "mocha" require("catppuccin").setup() vim.cmd("colorscheme catppuccin") --Highlight column 88 vim.cmd("set colorcolumn=88") --Set splits vim.o.splitbelow = true vim.o.splitright = true --Clipboard vim.o.clipboard = "unnamedplus" -- Press ESC to turn off search highlight map("n", "", ":noh", opt) --Tabs and indents vim.o.shiftwidth = 4 vim.o.smartindent = true vim.o.softtabstop = 4 vim.o.tabstop = 4 vim.o.autoindent = true -- Lualine require('lualine').setup{ options = { theme = "catppuccin" } } -- Sometimes I don't let go of the shift key in time vim.cmd("command! WQ wq") vim.cmd("command! Wq wq") vim.cmd("command! Wqa wqa") vim.cmd("command! WQa wqa") vim.cmd("command! W w") vim.cmd("command! Q q") -- Sometimes I accidentally undo a change when trying to enter INSERT mode map("n", "u", "", opt) -- Don't copy deleted text map("n", "dd", [=[ "_dd ]=], opt) map("v", "dd", [=[ "_dd ]=], opt) map("v", "x", [=[ "_x ]=], opt) -- Copy whole file content map("n", "", [[ %y+]], opt) -- Commenter keybinding require('nvim_comment').setup() map("n", "/", ":CommentToggle", opt) map("v", "/", ":CommentToggle", opt) --Remap for dealing with word wrap map('n', 'k', "v:count == 0 ? 'gk' : 'k'", { noremap = true, expr = true, silent = true }) map('n', 'j', "v:count == 0 ? 'gj' : 'j'", { noremap = true, expr = true, silent = true }) --Map blankline vim.g.indent_blankline_char = '┊' vim.g.indent_blankline_filetype_exclude = { 'help', 'packer' } vim.g.indent_blankline_buftype_exclude = { 'terminal', 'nofile' } vim.g.indent_blankline_char_highlight = 'LineNr' vim.g.indent_blankline_show_trailing_blankline_indent = false -- Ansible-flavorited YAML vim.g.ansible_unindent_after_newline = true -- nvim-lastplace require'nvim-lastplace'.setup{} -- nvim-bufferline.lua require("bufferline").setup{ options = { separator_style = "slant" } } map("n", "", ":enew", opt) -- new buffer map("n", "b", ":tabnew", opt) -- new tab map("n", "", ":bd!", opt) -- close tab map("n", "", ":BufferLineCycleNext", opt) map("n", "", ":BufferLineCyclePrev", opt) -- Telescope require('telescope').setup { defaults = { mappings = { i = { [''] = false, [''] = false, }, }, }, } --Add leader shortcuts map('n', '', [[lua require('telescope.builtin').buffers()]], { noremap = true, silent = true }) map('n', 'sf', [[lua require('telescope.builtin').find_files({previewer = false})]], { noremap = true, silent = true }) map('n', 'sb', [[lua require('telescope.builtin').current_buffer_fuzzy_find()]], { noremap = true, silent = true }) map('n', 'sh', [[lua require('telescope.builtin').help_tags()]], { noremap = true, silent = true }) map('n', 'st', [[lua require('telescope.builtin').tags()]], { noremap = true, silent = true }) map('n', 'sd', [[lua require('telescope.builtin').grep_string()]], { noremap = true, silent = true }) map('n', 'sp', [[lua require('telescope.builtin').live_grep()]], { noremap = true, silent = true }) map('n', 'so', [[lua require('telescope.builtin').tags{ only_current_buffer = true }]], { noremap = true, silent = true }) map('n', '?', [[lua require('telescope.builtin').oldfiles()]], { noremap = true, silent = true }) -- Highlight on yank vim.api.nvim_exec( [[ augroup YankHighlight autocmd! autocmd TextYankPost * silent! lua vim.highlight.on_yank() augroup end ]], false ) -- Y yank until the end of line map('n', 'Y', 'y$', { noremap = true }) -- Nvim Tree map('n', '', ':NvimTreeToggle', opt) map('n', 'r', ':NvimTreeRefresh', opt) map('n', 'n', ':NvimTreeFindFile', opt) -- LSP settings local nvim_lsp = require 'lspconfig' local on_attach = function(_, bufnr) vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') local opts = { noremap = true, silent = true } vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gD', 'lua vim.lsp.buf.declaration()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gd', 'lua vim.lsp.buf.definition()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'K', 'lua vim.lsp.buf.hover()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gi', 'lua vim.lsp.buf.implementation()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', '', 'lua vim.lsp.buf.signature_help()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'wa', 'lua vim.lsp.buf.add_workspace_folder()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'wr', 'lua vim.lsp.buf.remove_workspace_folder()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'wl', 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'D', 'lua vim.lsp.buf.type_definition()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'rn', 'lua vim.lsp.buf.rename()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gr', 'lua vim.lsp.buf.references()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'ca', 'lua vim.lsp.buf.code_action()', opts) -- vim.api.nvim_buf_set_keymap(bufnr, 'v', 'ca', 'lua vim.lsp.buf.range_code_action()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'e', 'lua vim.lsp.diagnostic.show_line_diagnostics()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', '[d', 'lua vim.lsp.diagnostic.goto_prev()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', ']d', 'lua vim.lsp.diagnostic.goto_next()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'q', 'lua vim.lsp.diagnostic.set_loclist()', opts) vim.api.nvim_buf_set_keymap(bufnr, 'n', 'so', [[lua require('telescope.builtin').lsp_document_symbols()]], opts) vim.cmd [[ command! Format execute 'lua vim.lsp.buf.formatting()' ]] end local capabilities = vim.lsp.protocol.make_client_capabilities() capabilities.textDocument.completion.completionItem.snippetSupport = true -- Enable the following language servers local servers = { 'ansiblels', 'bashls', 'dockerls', 'jsonls', 'pyright', 'yamlls' } for _, lsp in ipairs(servers) do nvim_lsp[lsp].setup { on_attach = on_attach, capabilities = capabilities, } end -- Sumneko Lua Language Server local sumneko_root_path local sumneko_binary sumneko_root_path = vim.fn.getenv("HOME").."/.local/share/lua-language-server" sumneko_binary = sumneko_root_path .. "/bin/lua-language-server" -- Make runtime files discoverable to the server local runtime_path = vim.split(package.path, ';') table.insert(runtime_path, 'lua/?.lua') table.insert(runtime_path, 'lua/?/init.lua') require('lspconfig').sumneko_lua.setup { cmd = { sumneko_binary, '-E', sumneko_root_path .. '/main.lua' }, on_attach = on_attach, capabilities = capabilities, settings = { Lua = { runtime = { -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim) version = 'LuaJIT', -- Setup your lua path path = runtime_path, }, diagnostics = { -- Get the language server to recognize the `vim` global globals = { 'vim' }, }, workspace = { -- Make the server aware of Neovim runtime files library = vim.api.nvim_get_runtime_file('', true), preloadFileSize = 1000, checkThirdParty = false, }, -- Do not send telemetry data containing a randomized but unique identifier telemetry = { enable = false, }, }, }, } -- Ansible LSP require('lspconfig').ansiblels.setup{} -- Bash LSP require('lspconfig').bashls.setup{} -- Docker LSP require('lspconfig').dockerls.setup{} -- JSON LSP require('lspconfig').jsonls.setup{} -- Pyright (Python) LSP require('lspconfig').pyright.setup{} -- Treesitter configuration -- Parsers must be installed manually via :TSInstall require('nvim-treesitter.configs').setup { highlight = { enable = true, -- false will disable the whole extension }, incremental_selection = { enable = true, keymaps = { init_selection = 'gnn', node_incremental = 'grn', scope_incremental = 'grc', node_decremental = 'grm', }, }, indent = { enable = true, }, 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 ['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', }, }, }, } -- Set completeopt to have a better completion experience vim.o.completeopt = 'menuone,noinsert' -- Compe setup require('compe').setup { source = { path = true, nvim_lsp = true, luasnip = true, buffer = false, calc = false, nvim_lua = false, vsnip = false, ultisnips = false, }, } -- Utility functions for compe and luasnip local t = function(str) return vim.api.nvim_replace_termcodes(str, true, true, true) end local check_back_space = function() local col = vim.fn.col '.' - 1 if col == 0 or vim.fn.getline('.'):sub(col, col):match '%s' then return true else return false end end -- Use (s-)tab to: --- move to prev/next item in completion menuone --- jump to prev/next snippet's placeholder local luasnip = require 'luasnip' _G.tab_complete = function() if vim.fn.pumvisible() == 1 then return t '' elseif luasnip.expand_or_jumpable() then return t 'luasnip-expand-or-jump' elseif check_back_space() then return t '' else return vim.fn['compe#complete']() end end _G.s_tab_complete = function() if vim.fn.pumvisible() == 1 then return t '' elseif luasnip.jumpable(-1) then return t 'luasnip-jump-prev' else return t '' end end -- Map tab to the above tab complete functiones map('i', '', 'v:lua.tab_complete()', { expr = true }) map('s', '', 'v:lua.tab_complete()', { expr = true }) map('i', '', 'v:lua.s_tab_complete()', { expr = true }) map('s', '', 'v:lua.s_tab_complete()', { expr = true }) -- Map compe confirm and complete functions map('i', '', 'compe#confirm("")', { expr = true }) map('i', '', 'compe#complete()', { expr = true })