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..978975e --- /dev/null +++ b/nvim/lua/keymaps.lua @@ -0,0 +1,49 @@ +-- 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", ":Git") + +-- 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 +function _G.set_terminal_keymaps() + 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 + +vim.cmd('autocmd! TermOpen term://* lua set_terminal_keymaps()') + +-- buffer closing +nnoremap("q", ":Bdelete") diff --git a/nvim/lua/options.lua b/nvim/lua/options.lua new file mode 100644 index 0000000..b865a1d --- /dev/null +++ b/nvim/lua/options.lua @@ -0,0 +1,57 @@ +-- 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" + +-- set cursorline in active window +vim.cmd([[ + augroup CursorLine + autocmd! + autocmd VimEnter,WinEnter,BufWinEnter * setlocal cursorline + autocmd WinLeave * setlocal nocursorline + augroup END +]]) + +-- coq.nvim +vim.g.coq_settings = { + auto_start = "shut-up", + keymap = { + jump_to_mark = "" -- prevent remapping + } +} diff --git a/nvim/lua/plugins.lua b/nvim/lua/plugins.lua new file mode 100644 index 0000000..ff10760 --- /dev/null +++ b/nvim/lua/plugins.lua @@ -0,0 +1,135 @@ +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("tpope/vim-commentary") + + -- session handling + use('tpope/vim-obsession') + use('dhruvasagar/vim-prosession') + + -- status line + use { + 'nvim-lualine/lualine.nvim', + requires = {'kyazdani42/nvim-web-devicons', opt = true}, + config = function() require('lualine').setup() end + } + + -- tabline + use { + 'kdheepak/tabline.nvim', + config = function() + require'tabline'.setup { + enable = true, + options = {show_filename_only = true} + } + end, + requires = { + {'hoob3rt/lualine.nvim'}, + {'kyazdani42/nvim-web-devicons', opt = true} + } + } + + -- 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 + }) + + -- autocompletion + use({ + "ms-jpq/coq_nvim", + branch = "coq", + requires = {{'ms-jpq/coq.artifacts', branch = 'artifacts'}} + }) + + -- highlight current symbol + use({"RRethy/vim-illuminate"}) + + -- language server + use({ + "neovim/nvim-lspconfig", + config = function() require("plugins.lspconfig") end + }) + + use('williamboman/nvim-lsp-installer') + + -- 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'}}, + config = function() require('plugins.telescope') end + }) + use({'nvim-telescope/telescope-fzf-native.nvim', run = 'make'}) + + -- automatic pairs + use({"Raimondi/delimitMate"}) + + -- markdown preview + use({'iamcco/markdown-preview.nvim'}) + + -- 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"}) + + 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/lspconfig.lua b/nvim/lua/plugins/lspconfig.lua new file mode 100644 index 0000000..ca2faf9 --- /dev/null +++ b/nvim/lua/plugins/lspconfig.lua @@ -0,0 +1,123 @@ +local coq = require("coq") +local lsp_installer = require("nvim-lsp-installer") + +local nvim_runtime_path = vim.split(package.path, ';') +table.insert(nvim_runtime_path, "lua/?.lua") +table.insert(nvim_runtime_path, "lua/?/init.lua") + +local language_servers = { + "ansiblels", "bashls", "dockerls", "efm", "eslint", "html", "pyright", + "rust_analyzer", "sumneko_lua", "svelte", "taplo", "tsserver", "volar" +} + +for _, server_name in pairs(language_servers) do + local server_found, server = lsp_installer.get_server(server_name) + if server_found and not server:is_installed() then + print("Installing " .. server_name) + server:install() + end + +end + +local extra_server_opts = { + ["efm"] = function(opts) + opts.filetypes = { + "lua", "html", "markdown", "typescript", "typescriptreact" + } + opts.init_options = {documentFormatting = true} + opts.settings = { + rootMarkers = {".git/"}, + languages = { + lua = {{formatCommand = "lua-format -i", formatStdin = true}}, + html = { + {formatCommand = "yarn run --silent prettier --parser html"} + }, + typescript = { + { + formatCommand = "yarn run --silent prettier --parser typescript" + } + }, + typescriptreact = { + { + formatCommand = "yarn run --silent prettier --parser typescript" + } + }, + markdown = { + { + formatCommand = "yarn run --silent prettier --parser markdown" + } + } + } + -- prettier-parser + -- flow|babel|babel-flow|babel-ts|typescript|espree|meriyah|css| + -- less|scss|json|json5|json-stringify|graphql|markdown|mdx|vue|yaml|glimmer|html|angular|lwc + } + end, + ["sumneko_lua"] = function(opts) + opts.settings = { + Lua = { + runtime = {version = 'LuaJIT', path = nvim_runtime_path}, + diagnostics = {globals = {'vim'}}, + workspace = {library = vim.api.nvim_get_runtime_file("", true)}, + telemetry = {enable = false} + } + } + end +} + +local function custom_on_attach(client, buffer_nr) + -- onmifunc + vim.api.nvim_buf_set_option(buffer_nr, "omnifunc", "v:lua.vim.lsp.omnifunc") + + -- Helper function + local opts = {noremap = true, silent = true} + local function bufnnoremap(key, action) + vim.api.nvim_buf_set_keymap(buffer_nr, 'n', key, action, opts) + end + + -- Inspect function + bufnnoremap("K", "lua vim.lsp.buf.hover()") + bufnnoremap("", "lua vim.lsp.buf.signature_help()") + + -- Navigation + bufnnoremap("gd", "lua vim.lsp.buf.definition()") + bufnnoremap("gD", "lua vim.lsp.buf.declaration()") + bufnnoremap("gi", "lua vim.lsp.buf.implementation()") + bufnnoremap("gr", "lua vim.lsp.buf.references()") + bufnnoremap("ga", "Telescope lsp_code_actions theme=cursor") + + -- Rename all references of symbol + bufnnoremap("R", "lua vim.lsp.buf.rename()") + + -- Navigate diagnostics + bufnnoremap("", "lua vim.diagnostic.goto_next()") + bufnnoremap("", "lua vim.diagnostic.goto_prev()") + + -- Open diagnostics + bufnnoremap("d", "Telescope diagnostics") + + -- disable conflicting formatters + if client.name == "tsserver" or client.name == "html" then + client.resolved_capabilities.document_formatting = false + end + + if client.resolved_capabilities.document_formatting then + vim.cmd("autocmd BufWritePre lua vim.lsp.buf.formatting_sync()") + end + + -- vim-illuminate + require("illuminate").on_attach(client) +end + +lsp_installer.on_server_ready(function(server) + local opts = coq.lsp_ensure_capabilities({ + on_attach = custom_on_attach, + capabilities = vim.lsp.protocol.make_client_capabilities() + }) + + if extra_server_opts[server.name] then + extra_server_opts[server.name](opts) + end + + server:setup(opts) +end) diff --git a/nvim/lua/plugins/telescope.lua b/nvim/lua/plugins/telescope.lua new file mode 100644 index 0000000..7d3479e --- /dev/null +++ b/nvim/lua/plugins/telescope.lua @@ -0,0 +1,22 @@ +local actions = require("telescope.actions") + +require('telescope').setup({ + defaults = { + mappings = { + i = { + [""] = actions.move_selection_next, + [""] = actions.move_selection_previous + }, + n = {[''] = actions.close} + } + }, + extensions = { + fzf = { + fuzzy = true, + override_generic_sorter = true, + override_file_sorter = true + } + } +}) + +require('telescope').load_extension('fzf') diff --git a/nvim/lua/plugins/treesitter.lua b/nvim/lua/plugins/treesitter.lua new file mode 100644 index 0000000..ddcbd67 --- /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", "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")