diff --git a/lua/keymaps.lua b/lua/keymaps.lua index 223c2f2..b976881 100644 --- a/lua/keymaps.lua +++ b/lua/keymaps.lua @@ -15,3 +15,11 @@ map({ 'n', 'i' }, '', 'redo') -- redo with STRG + y map({ 'n', 'i' }, '', '<') map({ 'n', 'i' }, '', 'Telescope', { noremap = true }) + +-- Scroll sideways with Shift + Scrollwheel like in browsers/other text editors +map({ 'n', 'i' }, '', '', { noremap = true }) +map({ 'n', 'i' }, '', '', { noremap = true }) + +map({ 'n' }, "q", "bd", { desc = "Close buffer" }) + + diff --git a/lua/options.lua b/lua/options.lua index 0fcde68..229e10b 100644 --- a/lua/options.lua +++ b/lua/options.lua @@ -18,6 +18,18 @@ return { termguicolors = true, -- True color support virtualedit = "block", -- Allow cursor to move where there is no text in visual block mode wrap = false, + foldcolumn = '1', + foldlevel = 99, + foldlevelstart = 99, + foldenable = true, + fillchars = { + foldopen = "", + foldclose = "", + fold = " ", + foldsep = " ", + diff = "╱", + eob = " ", + } }, ui = { theme = "vscode", diff --git a/lua/plugins/cmp.lua b/lua/plugins/cmp.lua new file mode 100644 index 0000000..c8466b5 --- /dev/null +++ b/lua/plugins/cmp.lua @@ -0,0 +1,59 @@ +return { + { + 'hrsh7th/nvim-cmp', + dependencies = { + -- extra completion plugins + 'hrsh7th/cmp-cmdline', + 'hrsh7th/cmp-path', + 'hrsh7th/cmp-buffer', + 'hrsh7th/cmp-nvim-lsp', + 'hrsh7th/cmp-calc', + 'hrsh7th/cmp-emoji', + 'kdheepak/cmp-latex-symbols', + -- snippets + 'hrsh7th/cmp-vsnip', + 'hrsh7th/vim-vsnip', + 'onsails/lspkind.nvim' + }, + config = function(_, opts) + local cmp = require("cmp"); + cmp.setup({ + snippet = { + expand = function(args) + vim.fn["vsnip#anonymous"](args.body) + end, + }, + completion = { + completeopt = "menu,menuone,noinsert", + }, + sources = cmp.config.sources({ + { name = 'nvim_lsp' }, + { name = 'vsnip' }, + { name = 'buffer' }, + { name = 'calc' }, + { name = 'emoji' }, + { name = "path" }, + { name = "cmdline" }, + { name = "latex_symbols" } + }), + 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 = false }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. + }), + formatting = { + fields = { "kind", "abbr", "menu" }, + format = function(entry, item) + local kind = require("lspkind").cmp_format({ mode = "symbol_text", maxwidth = 50 })(entry, item) + local strings = vim.split(kind.kind, "%s", { trimempty = true }) + kind.kind = " " .. (strings[1] or "") .. " " + kind.menu = " (" .. (strings[2] or "") .. ")" + return kind + end + } + }) + end + } +} diff --git a/lua/plugins/cokeline.lua b/lua/plugins/cokeline.lua index 2f6c28b..274bc12 100644 --- a/lua/plugins/cokeline.lua +++ b/lua/plugins/cokeline.lua @@ -3,7 +3,7 @@ return { "willothy/nvim-cokeline", config = true, opts = { - fill_hl = "BufferInactive", + fill_hl = "NeoTreeTabInactive", show_if_buffers_are_at_least = 1, buffers = { focus_on_delete = "next", @@ -15,53 +15,123 @@ return { default_hl = { bg = function(buffer) if buffer.is_focused then - return "Normal" + return "NeoTreeTabActive" end - return "BufferInactive" + return "NeoTreeTabInactive" end, fg = function(buffer) if buffer.is_focused then - return "Normal" + return "NeoTreeTabActive" end - return "BufferInactive" + return "NeoTreeTabInactive" end, }, components = { { - text = ' ', - }, - { - text = function(_) - return " " + text = function (buffer) + local text = ' ' + if buffer.is_focused then + text = '▎' + end + return text end, - fg = "Normal" + fg = function(buffer) return buffer.devicon.color end }, { text = function(buffer) return buffer.devicon.icon end, fg = function(buffer) return buffer.devicon.color end, }, { - text = function(buffer) return ' ' .. buffer.filename .. ' ' end, + text = function(buffer) return buffer.filename .. ' ' end, + fg = function (buffer) + if buffer.is_focused then + if buffer.diagnostics.errors > 0 then + return "DiagnosticError" + elseif buffer.diagnostics.warnings > 0 then + return "DiagnosticWarn" + elseif buffer.diagnostics.infos > 0 then + return "DiagnosticInfo" + elseif buffer.diagnostics.hints > 0 then + return "DiagnosticHint" + end + else + return 'NeoTreeTabInactive' + end + end + }, + -- show icon and number of diagnostics if there are more than one + { + text = function (buffer) + local errors = buffer.diagnostics.errors + if errors > 0 then + return require("options").lsp.icons.Error .. errors .. ' ' + end + return '' + end, + fg = "DiagnosticError" + }, + { + text = function (buffer) + local warns = buffer.diagnostics.warnings + if warns > 0 then + return require("options").lsp.icons.Warn .. warns .. ' ' + end + return '' + end, + fg = function (buffer) + if not buffer.is_focused then + return 'NeoTreeTabInactive' + end + return "DiagnosticWarn" + end + }, + { + text = function (buffer) + local infos = buffer.diagnostics.infos + if infos > 0 then + return require("options").lsp.icons.Info .. infos .. ' ' + end + return '' + end, + fg = function (buffer) + if not buffer.is_focused then + return 'NeoTreeTabInactive' + end + return "DiagnosticInfo" + end + }, + { + text = function (buffer) + local hints = buffer.diagnostics.hints + if hints > 0 then + return require("options").lsp.icons.Hint .. hints .. ' ' + end + return '' + end, + fg = function (buffer) + if not buffer.is_focused then + return 'NeoTreeTabInactive' + end + return "DiagnosticHint" + end }, { text = ' ', }, { text = function(buffer) + local text = "󰅖" if buffer.is_modified then - return '' + text = '' elseif buffer.is_readonly then - return '' - else - return '󰅖' + text = '' end + + return text .. ' ' end, on_click = function(_, _, _, _, buffer) buffer:delete() end - }, - { - text = ' ', } }, tabs = { @@ -73,15 +143,15 @@ return { end, bg = function(tabpage) if tabpage.is_active then - return "Normal" + return "NeoTreeTabActive" end - return "BufferInactive" + return "NeoTreeTabInactive" end, fg = function(tabpage) if tabpage.is_active then - return "Normal" + return "NeoTreeTabActive" end - return "BufferInactive" + return "NeoTreeTabInactive" end }, { @@ -95,10 +165,10 @@ return { tabpage:close() end, bg = function(_) - return "Normal" + return "NeoTreeTabActive" end, fg = function(_) - return "Normal" + return "NeoTreeTabActive" end } }, @@ -108,8 +178,8 @@ return { components = { { text = "", - bg = "Normal", - fg = "Normal" + bg = "NeoTreeTabInactive", + fg = "NeoTreeTabInactive" } }, }, diff --git a/lua/plugins/lsp.lua b/lua/plugins/lsp.lua index 8731425..f21e291 100644 --- a/lua/plugins/lsp.lua +++ b/lua/plugins/lsp.lua @@ -29,18 +29,18 @@ return { local options = require("options") require("mason").setup() - require("mason-lspconfig").setup() - -- automatically register lsp handler installed with mason - require("mason-lspconfig").setup_handlers { + local handlers = { -- The first entry (without a key) will be the default handler - -- and will be called for each installed server that doesn't have + -- and will be called for each installed server that doesn't have -- a dedicated handler. function (server_name) -- default handler (optional) require("lspconfig")[server_name].setup {} end, } + require("mason-lspconfig").setup({ handlers = handlers }) + -- set custom icons for name, icon in pairs(options.lsp.icons) do name = "DiagnosticSign" .. name diff --git a/lua/plugins/lualine.lua b/lua/plugins/lualine.lua index 4ca3bae..598756f 100644 --- a/lua/plugins/lualine.lua +++ b/lua/plugins/lualine.lua @@ -23,7 +23,9 @@ return { modified = '~', removed = '-', } - }, + } + }, + lualine_c = { { 'diagnostics', symbols = { @@ -36,14 +38,12 @@ return { 'nvim_diagnostic' }, update_in_insert = true - } - }, - lualine_c = { + }, { 'filename', symbols = { - modified = '[+]', -- Text to show when the file is modified. - readonly = '[-]', -- Text to show when the file is non-modifiable or readonly. + modified = '', -- Text to show when the file is modified. + readonly = '', -- Text to show when the file is non-modifiable or readonly. unnamed = '', -- Text to show for unnamed buffers. newfile = '[New]', -- Text to show for newly created file before first write } @@ -79,7 +79,17 @@ return { inactive_sections = { lualine_a = {}, lualine_b = {}, - lualine_c = {'filename'}, + lualine_c = { + { + 'filename', + symbols = { + modified = '', -- Text to show when the file is modified. + readonly = '', -- Text to show when the file is non-modifiable or readonly. + unnamed = '', -- Text to show for unnamed buffers. + newfile = '[New]', -- Text to show for newly created file before first write + } + } + }, lualine_x = {'location'}, lualine_y = {}, lualine_z = {} diff --git a/lua/plugins/neotree.lua b/lua/plugins/neotree.lua index 13d9ad3..c111f0c 100644 --- a/lua/plugins/neotree.lua +++ b/lua/plugins/neotree.lua @@ -11,6 +11,15 @@ return { local options = require("options") return { + sources = { + "filesystem", + "buffers", + "document_symbols" + }, + source_selector = { + winbar = true, + statusline = false + }, popup_border_style = options.ui.border, default_component_configs = { container = { @@ -60,7 +69,13 @@ return { enabled = true, leave_dirs_open = true } - } + }, + buffers = { + follow_current_file = { + enabled = true, -- This will find and focus the file in the active buffer every time + leave_dirs_open = false, -- `false` closes auto expanded dirs, such as with `:Neotree reveal` + }, + }, } end } diff --git a/lua/plugins/telescope.lua b/lua/plugins/telescope.lua index 3d6f91d..80d0ab5 100644 --- a/lua/plugins/telescope.lua +++ b/lua/plugins/telescope.lua @@ -16,6 +16,7 @@ return { winblend = 0, }, extensions = { + 'fzf' } } }, diff --git a/lua/plugins/treesitter.lua b/lua/plugins/treesitter.lua index 72bebc7..f07e41c 100644 --- a/lua/plugins/treesitter.lua +++ b/lua/plugins/treesitter.lua @@ -5,6 +5,9 @@ return { event = { "VeryLazy" }, + dependencies = { + "nvim-treesitter/nvim-treesitter-textobjects", + }, init = function(plugin) -- PERF: add nvim-treesitter queries to the rtp and it's custom query predicates early -- This is needed because a bunch of plugins no longer `require("nvim-treesitter")`, which @@ -25,7 +28,22 @@ return { return true end end, - } + }, + indent = { + enable = true + }, + autotag = { + enable = true + }, + textobjects = { + move = { + enable = true, + goto_next_start = { ["]f"] = "@function.outer", ["]c"] = "@class.outer" }, + goto_next_end = { ["]F"] = "@function.outer", ["]C"] = "@class.outer" }, + goto_previous_start = { ["[f"] = "@function.outer", ["[c"] = "@class.outer" }, + goto_previous_end = { ["[F"] = "@function.outer", ["[C"] = "@class.outer" }, + }, + }, }, config = function(_, opts) require("nvim-treesitter.configs").setup(opts) diff --git a/lua/plugins/ufo.lua b/lua/plugins/ufo.lua new file mode 100644 index 0000000..469c7ce --- /dev/null +++ b/lua/plugins/ufo.lua @@ -0,0 +1,25 @@ +return { + { + "kevinhwang91/nvim-ufo", + event = { + "InsertEnter" + }, + dependencies = { + "kevinhwang91/promise-async" + }, + opts = { + preview = { + mappings = { + scrollB = "", + scrollF = "", + scrollU = "", + scrollD = "", + }, + }, + -- register treesitter as source for scopes + provider_selector = function(_, _, _) + return { 'treesitter', 'indent' } + end + } + } +}