diff --git a/cli/vim/neovim/init.lua b/cli/vim/neovim/init.lua index db7edd2..af031c0 100644 --- a/cli/vim/neovim/init.lua +++ b/cli/vim/neovim/init.lua @@ -24,16 +24,19 @@ vim.o.list = true vim.o.mouse = "a" vim.o.ignorecase = true vim.o.smartcase = true +vim.o.swapfile = false -- window options vim.wo.number = true vim.wo.relativenumber = true +vim.cmd "set colorcolumn=120" + -- more require("keybindings") require("plugins") -gruvbox_ok, gruvbox = pcall(require, "gruvbox") +local gruvbox_ok, _ = pcall(require, "gruvbox") if gruvbox_ok then vim.o.background = "dark" vim.cmd [[ @@ -42,3 +45,6 @@ if gruvbox_ok then highlight CursorLine ctermbg=240 ]] end + + +vim.cmd [[autocmd BufWritePre * lua vim.lsp.buf.formatting_sync()]] diff --git a/cli/vim/neovim/lua/keybindings.lua b/cli/vim/neovim/lua/keybindings.lua index 29f9437..47c614f 100644 --- a/cli/vim/neovim/lua/keybindings.lua +++ b/cli/vim/neovim/lua/keybindings.lua @@ -5,6 +5,19 @@ local VISUAL = 'v' local COMMAND = 'c' +vim.api.nvim_create_user_command("CloseOtherBuffers", function() + local current_buffer_name = vim.api.nvim_buf_get_name(0) + for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do + if vim.api.nvim_buf_is_loaded(bufnr) then + local bufname = vim.api.nvim_buf_get_name(bufnr) + if bufname ~= current_buffer_name then + vim.cmd(":bd " .. bufnr) + end + end + end +end, {}) + + keymap(NORMAL, '', ':bnext', { noremap = true }) keymap(NORMAL, '', ':bprev', { noremap = true }) keymap(INSERT, '', ':bnext', { noremap = true }) @@ -44,9 +57,13 @@ keymap(NORMAL, 'gg', ':Git pull', { noremap = true }) keymap(NORMAL, 'gb', ':Git blame', { noremap = true }) keymap(NORMAL, 'gl', ':Git log', { noremap = true }) keymap(NORMAL, 'gpr', ':!gpr', { noremap = true }) +keymap(NORMAL, 'gp', ':GotoParent', { noremap = true }) keymap(NORMAL, 'cn', ':cnext', { noremap = true }) keymap(NORMAL, 'cp', ':cprev', { noremap = true }) -keymap(NORMAL, 'bo', ':%bd | e#', { noremap = true }) +keymap(NORMAL, 'bo', ':CloseOtherBuffers', { noremap = true }) +keymap(NORMAL, 'sif', ':SearchInFolder', { noremap = true }) +keymap(NORMAL, 'cx', ':ToggleExecutable', { noremap = true }) +keymap(NORMAL, 'rs', ':RunScript', { noremap = true }) -- command mode @@ -65,3 +82,5 @@ keymap(COMMAND, '', '', { noremap = true }) -- keymap(INSERT, '', '', { noremap = true }) -- keymap(INSERT, '', '', { noremap = true }) -- keymap(INSERT, '', '', { noremap = true }) + +vim.g.AutoPairsShortcutToggle = "ap" diff --git a/cli/vim/neovim/lua/plugins.lua b/cli/vim/neovim/lua/plugins.lua index 7a2586c..9dbd239 100644 --- a/cli/vim/neovim/lua/plugins.lua +++ b/cli/vim/neovim/lua/plugins.lua @@ -1,58 +1,69 @@ - - require("packer").startup(function(use) - use "wbthomason/packer.nvim" -- this is essential. + use "wbthomason/packer.nvim" -- this is essential. - use "jiangmiao/auto-pairs" - use "tpope/vim-fugitive" - use "ellisonleao/gruvbox.nvim" - use "editorconfig/editorconfig-vim" + use "jiangmiao/auto-pairs" + use "tpope/vim-fugitive" + use "tpope/vim-rhubarb" + use "ellisonleao/gruvbox.nvim" + use "editorconfig/editorconfig-vim" - -- nvim-surround - use({ - "kylechui/nvim-surround", - config = function() require("nvim-surround").setup({}) end - }) + -- nvim-surround + use({ + "kylechui/nvim-surround", + config = function() require("nvim-surround").setup({}) end + }) - -- telescope - use { - "nvim-telescope/telescope.nvim", - requires = { {"nvim-lua/plenary.nvim"} }, - } - -- use "nvim-telescope/telescope-file-browser.nvim" - use "nvim-telescope/telescope-media-files.nvim" + -- telescope + use { + "nvim-telescope/telescope.nvim", + requires = { { "nvim-lua/plenary.nvim" } }, + } + -- use "nvim-telescope/telescope-file-browser.nvim" + use "nvim-telescope/telescope-media-files.nvim" - -- bufferline - use { - "akinsho/bufferline.nvim", - tag = "v2.*", - requires = "kyazdani42/nvim-web-devicons", - } + -- bufferline + use { + "akinsho/bufferline.nvim", + tag = "v2.*", + requires = "kyazdani42/nvim-web-devicons", + } - -- lsp - use "neovim/nvim-lspconfig" + -- lsp + use "neovim/nvim-lspconfig" + use "jose-elias-alvarez/null-ls.nvim" - -- nvim-cmp - use "hrsh7th/nvim-cmp" -- The completion plugin - use "hrsh7th/cmp-nvim-lsp" -- LSP source for nvim-cmp - use "hrsh7th/cmp-buffer" -- buffer completions - use "hrsh7th/cmp-path" -- path completions - -- use "hrsh7th/cmp-cmdline" -- cmdline completions - use "saadparwaiz1/cmp_luasnip" -- snippet completions + -- nvim-cmp + use "hrsh7th/nvim-cmp" -- The completion plugin + use "hrsh7th/cmp-nvim-lsp" -- LSP source for nvim-cmp + use "hrsh7th/cmp-buffer" -- buffer completions + use "hrsh7th/cmp-path" -- path completions + -- use "hrsh7th/cmp-cmdline" -- cmdline completions + use "saadparwaiz1/cmp_luasnip" -- snippet completions - -- snippets - use "L3MON4D3/LuaSnip" --snippet engine - use "rafamadriz/friendly-snippets" -- a bunch of snippets to use + -- snippets + use "L3MON4D3/LuaSnip" --snippet engine + use "rafamadriz/friendly-snippets" -- a bunch of snippets to use - -- statusline - use "ojroques/nvim-hardline" + -- statusline + use "ojroques/nvim-hardline" - -- comment - use "numToStr/Comment.nvim" + -- comment + use "numToStr/Comment.nvim" - -- filetree - use "kyazdani42/nvim-tree.lua" + -- filetree + use "klesh/nvim-tree.lua" + + + -- treesitter + use "nvim-treesitter/nvim-treesitter" + use "nvim-treesitter/playground" + use "acarapetis/vim-sh-heredoc-highlighting" + + use { + "/home/klesh/Projects/klesh/nvim-runscript", + config = function() require("nvim-runscript").setup({}) end + } end) @@ -63,3 +74,4 @@ require("plugins/statusline") require("plugins/comment") require("plugins/tree") require("plugins/searchinfolder") +require("plugins/treesitter") diff --git a/cli/vim/neovim/lua/plugins/lsp.lua b/cli/vim/neovim/lua/plugins/lsp.lua index b5c3720..9e83075 100644 --- a/cli/vim/neovim/lua/plugins/lsp.lua +++ b/cli/vim/neovim/lua/plugins/lsp.lua @@ -1,34 +1,62 @@ local lspconfig_ok, lspconfig = pcall(require, "lspconfig") if not lspconfig_ok then - return + return end -local language_servers = { 'gopls' } +local language_servers = { + gopls = {}, + -- grammarly = {}, + -- marksman = {}, + jsonls = {}, + tsserver = {}, + sumneko_lua = { + settings = { + Lua = { + runtime = { + -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim) + version = 'LuaJIT', + }, + 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), + }, + -- Do not send telemetry data containing a randomized but unique identifier + telemetry = { + enable = false, + }, + }, + }, + } +} -- 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) - -- Enable completion triggered by - vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') + -- Enable completion triggered by + vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') - -- Mappings. - -- See `:help vim.lsp.*` for documentation on any of the below functions - local bufopts = { noremap=true, silent=true, buffer=bufnr } - vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts) - vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts) - vim.keymap.set('n', 'od', vim.lsp.buf.hover, bufopts) - vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, bufopts) - vim.keymap.set('n', '', vim.lsp.buf.signature_help, bufopts) - vim.keymap.set('n', 'wa', vim.lsp.buf.add_workspace_folder, bufopts) - vim.keymap.set('n', 'wr', vim.lsp.buf.remove_workspace_folder, bufopts) - vim.keymap.set('n', 'wl', function() - print(vim.inspect(vim.lsp.buf.list_workspace_folders())) - end, bufopts) - vim.keymap.set('n', 'D', vim.lsp.buf.type_definition, bufopts) - vim.keymap.set('n', 'rn', vim.lsp.buf.rename, bufopts) - vim.keymap.set('n', 'ca', vim.lsp.buf.code_action, bufopts) - vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts) - vim.keymap.set('n', 'fd', vim.lsp.buf.formatting, bufopts) + -- Mappings. + -- See `:help vim.lsp.*` for documentation on any of the below functions + local bufopts = { noremap = true, silent = true, buffer = bufnr } + vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts) + vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts) + vim.keymap.set('n', 'od', vim.lsp.buf.hover, bufopts) + vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, bufopts) + vim.keymap.set('n', '', vim.lsp.buf.signature_help, bufopts) + vim.keymap.set('n', 'wa', vim.lsp.buf.add_workspace_folder, bufopts) + vim.keymap.set('n', 'wr', vim.lsp.buf.remove_workspace_folder, bufopts) + vim.keymap.set('n', 'wl', function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, bufopts) + vim.keymap.set('n', 'D', vim.lsp.buf.type_definition, bufopts) + vim.keymap.set('n', 'rn', vim.lsp.buf.rename, bufopts) + vim.keymap.set('n', 'ca', vim.lsp.buf.code_action, bufopts) + vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts) + vim.keymap.set('n', 'fd', vim.lsp.buf.formatting, bufopts) end local capabilities = vim.lsp.protocol.make_client_capabilities() @@ -36,65 +64,79 @@ local capabilities = vim.lsp.protocol.make_client_capabilities() local cmp_status_ok, cmp = pcall(require, "cmp") if cmp_status_ok then - local cmp_nvim_lsp_status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp") - if cmp_nvim_lsp_status_ok then - capabilities = cmp_nvim_lsp.update_capabilities(capabilities) - end + local cmp_nvim_lsp_status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp") + if cmp_nvim_lsp_status_ok then + capabilities = cmp_nvim_lsp.update_capabilities(capabilities) + end end -for _, langsvr in ipairs(language_servers) do - lspconfig[langsvr].setup({ - on_attach = on_attach, - capabilities = capabilities, - }) +for langsvr, settings in pairs(language_servers) do + settings["on_attach"] = on_attach + settings["capabilities"] = capabilities + lspconfig[langsvr].setup(settings) end - if not cmp_status_ok then - return + return end local luasnip_status_ok, luasnip = pcall(require, "luasnip") cmp.setup { - snippet = { - expand = function(args) - if luasnip_status_ok then - luasnip.lsp_expand(args.body) - end - end, - }, - mapping = cmp.mapping.preset.insert({ - [''] = 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_status_ok and luasnip.expand_or_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_status_ok and luasnip.jumpable(-1) then - luasnip.jump(-1) - else - fallback() - end - end, { 'i', 's' }), - }), - sources = { - { name = 'nvim_lsp' }, - { name = 'luasnip' }, - { name = 'buffer' }, - { name = 'path' }, + snippet = { + expand = function(args) + if luasnip_status_ok then + luasnip.lsp_expand(args.body) + end + end, + }, + mapping = cmp.mapping.preset.insert({ + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.confirm { + behavior = cmp.ConfirmBehavior.Replace, + select = true, }, + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif luasnip_status_ok and luasnip.expand_or_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_status_ok and luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { 'i', 's' }), + }), + sources = { + { name = 'nvim_lsp' }, + { name = 'luasnip' }, + { name = 'buffer' }, + { name = 'path' }, + }, } + +local null_ls_ok, null_ls = pcall(require, "null_ls") +if not null_ls_ok then + return +end + +null_ls.setup({ + sources = { + null_ls.builtins.formatting.stylua, + null_ls.builtins.diagnostics.eslint, + null_ls.builtins.completion.spell, + null_ls.builtins.formatting.goimports, + null_ls.builtins.formatting.gofumpt, + }, +}) + + diff --git a/cli/vim/neovim/lua/plugins/searchinfolder.lua b/cli/vim/neovim/lua/plugins/searchinfolder.lua index 1c81f1f..0599816 100644 --- a/cli/vim/neovim/lua/plugins/searchinfolder.lua +++ b/cli/vim/neovim/lua/plugins/searchinfolder.lua @@ -7,19 +7,23 @@ if not telescope_builtin_ok then return end -function search_in_folder(folder_path) +function SearchInFolder(folder_path) if folder_path == "" then - folder = nvim_tree_lib.get_node_at_cursor() - if folder.fs_stat.type == "file" then - folder = folder.parent + local folder = nvim_tree_lib.get_node_at_cursor() + if folder == nil then + folder_path = vim.fn.expand("%:p:h") + else + if assert(folder.fs_stat).type == "file" then + folder = folder.parent + end + folder_path = folder.absolute_path end - folder_path = folder.absolute_path end telescope_builtin.live_grep{cwd = folder_path} -- print(vim.inspect(folder_path)) end vim.api.nvim_create_user_command("SearchInFolder", function(res) - search_in_folder(res.args) + SearchInFolder(res.args) end, { nargs = "?" }) diff --git a/cli/vim/neovim/lua/plugins/tree.lua b/cli/vim/neovim/lua/plugins/tree.lua index f863b51..2954bd1 100644 --- a/cli/vim/neovim/lua/plugins/tree.lua +++ b/cli/vim/neovim/lua/plugins/tree.lua @@ -1,13 +1,59 @@ local nvim_tree_ok, nvim_tree = pcall(require, "nvim-tree") -if not nvim_tree_ok then - return +if nvim_tree_ok then + nvim_tree.setup { + actions = { + change_dir = { + global = true + } + }, + git = { + ignore = false + } + } end -nvim_tree.setup{ - actions = { - change_dir = { - global = true - } - } -} +local _, nvim_tree_view = pcall(require, "nvim-tree/view") +local _, nvim_tree_lib = pcall(require, "nvim-tree/lib") +-- local _, nvim_tree_reloaders = pcall(require, "nvim-tree/actions/reloaders/reloaders") +local function is_in_nvim_tree_buf() + if not nvim_tree_ok then + return false + end + local curwin = vim.api.nvim_get_current_win() + local curbuf = vim.api.nvim_win_get_buf(curwin) + local bufname = vim.api.nvim_buf_get_name(curbuf) + return bufname:match "NvimTree" +end + +local function get_absolute_path(absolute_path) + if absolute_path == "" then + if is_in_nvim_tree_buf() then + absolute_path = nvim_tree_lib.get_node_at_cursor().absolute_path + else + absolute_path = vim.fn.expand("%:p") + end + end + return absolute_path +end + +-- ToggleExecutable +function ToggleExecutable(absolute_path, executable) + absolute_path = get_absolute_path(absolute_path) + if executable == nil then + executable = not vim.loop.fs_access(absolute_path, "X") + end + if executable then + vim.cmd(":!chmod +x " .. absolute_path) + else + vim.cmd(":!chmod -x " .. absolute_path) + end + if nvim_tree_ok then + -- nvim_tree_reloaders + vim.cmd(":NvimTreeRefresh") + end +end + +vim.api.nvim_create_user_command("ToggleExecutable", function(res) + ToggleExecutable(res.args) +end, { nargs = "?" }) diff --git a/cli/vim/neovim/lua/plugins/treesitter.lua b/cli/vim/neovim/lua/plugins/treesitter.lua new file mode 100644 index 0000000..ebab78c --- /dev/null +++ b/cli/vim/neovim/lua/plugins/treesitter.lua @@ -0,0 +1,108 @@ +local treesitter_ok, treesitter = pcall(require, "nvim-treesitter/configs") +if not treesitter_ok then + return +end + +treesitter.setup({ + ensure_installed = "all", + sync_install = false, + ignore_install = { "" }, + highlight = { + enable = true, + disable = { "" }, + additional_vim_regex_highlighting = true, + }, + indent = { + enable = true, + disable = { "yaml" }, + }, + playground = { + enable = true, + disable = {}, + updatetime = 25, -- Debounced time for highlighting nodes in the playground from source code + persist_queries = false, -- Whether the query persists across vim sessions + keybindings = { + toggle_query_editor = 'o', + toggle_hl_groups = 'i', + toggle_injected_languages = 't', + toggle_anonymous_nodes = 'a', + toggle_language_display = 'I', + focus_language = 'f', + unfocus_language = 'F', + update = 'R', + goto_node = '', + show_help = '?', + }, + } +}) + +vim.o.foldmethod = "expr" +vim.o.foldexpr = "nvim_treesitter#foldexpr()" +vim.cmd "set nofoldenable" + + +local ts_utils = require("nvim-treesitter.ts_utils") +local M = {} +local api = vim.api + +local get_parent = function(node) + local prev = assert(ts_utils.get_previous_node(node, true, true)) + while (prev:parent() == node:parent()) do + node = prev + if (ts_utils.get_previous_node(prev, true, true) == nil) then + -- If we're at the last node... + return node + end + prev = ts_utils.get_previous_node(prev, true, true) + end + return node +end + +local get_master_node = function() + local node = ts_utils.get_node_at_cursor() + if node == nil then + error("No Treesitter parser found.") + end + + local start_row = node:start() + local parent = node:parent() + + while (parent ~= nil and parent:start() == start_row) do + node = parent + parent = node:parent() + end + + return node +end + +M.parent = function() + local node = get_master_node() + local parent = get_parent(node) + ts_utils.goto_node(parent) +end + +-- function to create a list of commands and convert them to autocommands +-------- This function is taken from https://github.com/norcalli/nvim_utils +function M.nvim_create_augroups(definitions) + for group_name, definition in pairs(definitions) do + api.nvim_command('augroup ' .. group_name) + api.nvim_command('autocmd!') + for _, def in ipairs(definition) do + local command = table.concat(vim.tbl_flatten { 'autocmd', def }, ' ') + api.nvim_command(command) + end + api.nvim_command('augroup END') + end +end + +M.nvim_create_augroups({ + open_folds = { + -- { "BufReadPost,FileReadPost,VimEnter", "*", "normal zR" }, + { "BufReadPost,FileReadPost,VimEnter", "*", "TSBufEnable highlight" }, + } +}) + + +api.nvim_create_user_command("GotoParent", M.parent, {}) + +return M