diff options
author | Gustaf Rydholm <gustaf.rydholm@gmail.com> | 2021-08-10 23:15:04 +0200 |
---|---|---|
committer | Gustaf Rydholm <gustaf.rydholm@gmail.com> | 2021-08-10 23:15:04 +0200 |
commit | 540268d618627079c9b958a955b586e1888b46a8 (patch) | |
tree | 1a22a5feb457135178b9d4fe8b6c1755f5ca66bc /.config/nvim/lua | |
parent | e79bd3273f58ba38e8fcd716090b89326791afbb (diff) |
Major refactor of nvim
Diffstat (limited to '.config/nvim/lua')
70 files changed, 3339 insertions, 2846 deletions
diff --git a/.config/nvim/lua/core/autocmds.lua b/.config/nvim/lua/core/autocmds.lua new file mode 100644 index 0000000..959ae15 --- /dev/null +++ b/.config/nvim/lua/core/autocmds.lua @@ -0,0 +1,114 @@ +local autocommands = {} + +options.autocommands = { + _general_settings = { + { + "Filetype", + "*", + "lua require('utils.ft').do_filetype(vim.fn.expand(\"<amatch>\"))", + }, + { + "TextYankPost", + "*", + "lua require('vim.highlight').on_yank({higroup = 'Search', timeout = 200})", + }, + { + "BufWinEnter", + "*", + "setlocal formatoptions-=c formatoptions-=r formatoptions-=o", + }, + { + "BufWinEnter", + "dashboard", + "setlocal cursorline signcolumn=yes cursorcolumn number", + }, + { + "BufRead", + "*", + "setlocal formatoptions-=c formatoptions-=r formatoptions-=o", + }, + { + "BufNewFile", + "*", + "setlocal formatoptions-=c formatoptions-=r formatoptions-=o", + }, + { "BufWritePost", USER_CONFIG_PATH, "lua require('utils').reload_config()" }, + { + "FileType", + "qf", + "set nobuflisted", + }, + -- { "VimLeavePre", "*", "set title set titleold=" }, + }, + _filetypechanges = { + { "BufWinEnter", ".tf", "setlocal filetype=terraform" }, + { "BufRead", "*.tf", "setlocal filetype=terraform" }, + { "BufNewFile", "*.tf", "setlocal filetype=terraform" }, + { "BufWinEnter", ".zsh", "setlocal filetype=sh" }, + { "BufRead", "*.zsh", "setlocal filetype=sh" }, + { "BufNewFile", "*.zsh", "setlocal filetype=sh" }, + }, + -- _solidity = { + -- {'BufWinEnter', '.sol', 'setlocal filetype=solidity'}, {'BufRead', '*.sol', 'setlocal filetype=solidity'}, + -- {'BufNewFile', '*.sol', 'setlocal filetype=solidity'} + -- }, + -- _gemini = { + -- {'BufWinEnter', '.gmi', 'setlocal filetype=markdown'}, {'BufRead', '*.gmi', 'setlocal filetype=markdown'}, + -- {'BufNewFile', '*.gmi', 'setlocal filetype=markdown'} + -- }, + _markdown = { + { "FileType", "markdown", "setlocal wrap" }, + { "FileType", "markdown", "setlocal spell" }, + }, + _buffer_bindings = { + { "FileType", "floaterm", "nnoremap <silent> <buffer> q :q<CR>" }, + }, + _auto_resize = { + -- will cause split windows to be resized evenly if main window is resized + { "VimResized", "*", "wincmd =" }, + }, + _packer_compile = { + -- will run PackerCompile after writing plugins.lua + { "BufWritePost", "plugins.lua", "PackerCompile" }, + }, + _general_lsp = { + { "FileType", "lspinfo", "nnoremap <silent> <buffer> q :q<CR>" }, + }, + + -- _fterm_lazygit = { + -- -- will cause esc key to exit lazy git + -- {"TermEnter", "*", "call LazyGitNativation()"} + -- }, + -- _mode_switching = { + -- -- will switch between absolute and relative line numbers depending on mode + -- {'InsertEnter', '*', 'if &relativenumber | let g:ms_relativenumberoff = 1 | setlocal number norelativenumber | endif'}, + -- {'InsertLeave', '*', 'if exists("g:ms_relativenumberoff") | setlocal relativenumber | endif'}, + -- {'InsertEnter', '*', 'if &cursorline | let g:ms_cursorlineoff = 1 | setlocal nocursorline | endif'}, + -- {'InsertLeave', '*', 'if exists("g:ms_cursorlineoff") | setlocal cursorline | endif'}, + -- }, + custom_groups = {}, +} + +function autocommands.define_augroups(definitions) -- {{{1 + -- Create autocommand groups based on the passed definitions + -- + -- The key will be the name of the group, and each definition + -- within the group should have: + -- 1. Trigger + -- 2. Pattern + -- 3. Text + -- just like how they would normally be defined from Vim itself + for group_name, definition in pairs(definitions) do + vim.cmd("augroup " .. group_name) + vim.cmd "autocmd!" + + for _, def in pairs(definition) do + local command = table.concat(vim.tbl_flatten { "autocmd", def }, " ") + vim.cmd(command) + end + + vim.cmd "augroup END" + end +end + +return autocommands diff --git a/.config/nvim/lua/core/autopairs.lua b/.config/nvim/lua/core/autopairs.lua index f0111db..afd6e28 100644 --- a/.config/nvim/lua/core/autopairs.lua +++ b/.config/nvim/lua/core/autopairs.lua @@ -1,8 +1,10 @@ -- if not package.loaded['nvim-autopairs'] then -- return -- end +local Log = require "core.log" local status_ok, _ = pcall(require, "nvim-autopairs") if not status_ok then + Log:get_default().error "Failed to load autopairs" return end local npairs = require "nvim-autopairs" diff --git a/.config/nvim/lua/core/bufferline.lua b/.config/nvim/lua/core/bufferline.lua index d4e4b4f..6306614 100644 --- a/.config/nvim/lua/core/bufferline.lua +++ b/.config/nvim/lua/core/bufferline.lua @@ -1,28 +1,20 @@ -vim.api.nvim_set_keymap("n", "<S-x>", ":BufferClose<CR>", { noremap = true, silent = true }) -vim.api.nvim_set_keymap("n", "<S-l>", ":BufferNext<CR>", { noremap = true, silent = true }) -vim.api.nvim_set_keymap("n", "<S-h>", ":BufferPrevious<CR>", { noremap = true, silent = true }) -vim.api.nvim_set_keymap("n", "<leader>c", ":BufferClose<CR>", { noremap = true, silent = true }) +local M = {} -O.plugin.which_key.mappings["b"] = { - name = "Buffers", - j = { "<cmd>BufferPick<cr>", "jump to buffer" }, - f = { "<cmd>Telescope buffers<cr>", "Find buffer" }, - w = { "<cmd>BufferWipeout<cr>", "wipeout buffer" }, - e = { - "<cmd>BufferCloseAllButCurrent<cr>", - "close all but current buffer", - }, - h = { "<cmd>BufferCloseBuffersLeft<cr>", "close all buffers to the left" }, - l = { - "<cmd>BufferCloseBuffersRight<cr>", - "close all BufferLines to the right", - }, - D = { - "<cmd>BufferOrderByDirectory<cr>", - "sort BufferLines automatically by directory", - }, - L = { - "<cmd>BufferOrderByLanguage<cr>", - "sort BufferLines automatically by language", - }, -} +M.config = function() + options.builtin.bufferline = { + active = true, + keymap = { + normal_mode = { + ["<S-l>"] = ":BufferNext<CR>", + ["<S-h>"] = ":BufferPrevious<CR>", + }, + }, + } +end + +M.setup = function() + local keymap = require "keymappings" + keymap.append_to_defaults(options.builtin.bufferline.keymap) +end + +return M diff --git a/.config/nvim/lua/core/colorizer.lua b/.config/nvim/lua/core/colorizer.lua deleted file mode 100644 index c6a2a27..0000000 --- a/.config/nvim/lua/core/colorizer.lua +++ /dev/null @@ -1,17 +0,0 @@ -local M = {} - -M.config = function() - O.plugin.hop = { - active = false, - } -end - -M.setup = function() - local status_ok, colorizer = pcall(require, "colorizer") - if not status_ok then - return - end - colorizer.setup(O.plugin.hop) -end - -return M diff --git a/.config/nvim/lua/core/commands.lua b/.config/nvim/lua/core/commands.lua new file mode 100644 index 0000000..c42b385 --- /dev/null +++ b/.config/nvim/lua/core/commands.lua @@ -0,0 +1,21 @@ +local M = {} + +M.defaults = { + [[ + function! QuickFixToggle() + if empty(filter(getwininfo(), 'v:val.quickfix')) + copen + else + cclose + endif + endfunction + ]], +} + +M.load = function(commands) + for _, command in ipairs(commands) do + vim.cmd(command) + end +end + +return M diff --git a/.config/nvim/lua/core/compe.lua b/.config/nvim/lua/core/compe.lua index c8152ad..3291918 100644 --- a/.config/nvim/lua/core/compe.lua +++ b/.config/nvim/lua/core/compe.lua @@ -1,6 +1,7 @@ local M = {} +local Log = require "core.log" M.config = function() - O.completion = { + options.builtin.compe = { enabled = true, autocomplete = true, debug = false, @@ -12,7 +13,15 @@ M.config = function() max_abbr_width = 100, max_kind_width = 100, max_menu_width = 100, - documentation = true, + documentation = { + border = "single", + winhighlight = "NormalFloat:CompeDocumentation,FloatBorder:CompeDocumentationBorder", + max_width = 120, + min_width = 60, + max_height = math.floor(vim.o.lines * 0.3), + min_height = 1, + }, + -- documentation = true, source = { path = { kind = " (Path)" }, @@ -30,18 +39,35 @@ M.config = function() emoji = { kind = " ﲃ (Emoji)", filetypes = { "markdown", "text" } }, -- for emoji press : (idk if that in compe tho) }, + + keymap = { + values = { + insert_mode = { + -- ["<Tab>"] = { 'pumvisible() ? "<C-n>" : "<Tab>"', { silent = true, noremap = true, expr = true } }, + -- ["<S-Tab>"] = { 'pumvisible() ? "<C-p>" : "<S-Tab>"', { silent = true, noremap = true, expr = true } }, + ["<C-Space>"] = { "compe#complete()", { silent = true, noremap = true, expr = true } }, + ["<C-e>"] = { "compe#close('<C-e>')", { silent = true, noremap = true, expr = true } }, + ["<C-f>"] = { "compe#scroll({ 'delta': +4 })", { silent = true, noremap = true, expr = true } }, + ["<C-d>"] = { "compe#scroll({ 'delta': -4 })", { silent = true, noremap = true, expr = true } }, + }, + }, + opts = { + insert_mode = { noremap = true, silent = true, expr = true }, + }, + }, } end M.setup = function() - vim.g.vsnip_snippet_dir = O.vsnip_dir + vim.g.vsnip_snippet_dir = options.vsnip_dir local status_ok, compe = pcall(require, "compe") if not status_ok then + Log:get_default().error "Failed to load compe" return end - compe.setup(O.completion) + compe.setup(options.builtin.compe) local t = function(str) return vim.api.nvim_replace_termcodes(str, true, true, true) @@ -62,12 +88,13 @@ M.setup = function() _G.tab_complete = function() if vim.fn.pumvisible() == 1 then return t "<C-n>" - elseif vim.fn.call("vsnip#available", { 1 }) == 1 then - return t "<Plug>(vsnip-expand-or-jump)" + elseif vim.fn.call("vsnip#jumpable", { 1 }) == 1 then + return t "<Plug>(vsnip-jump-next)" elseif check_back_space() then return t "<Tab>" else - return vim.fn["compe#complete"]() + -- return vim.fn["compe#complete"]() -- < use this if you want <tab> to always offer completion + return t "<Tab>" end end @@ -81,16 +108,13 @@ M.setup = function() end end + local keymap = require "keymappings" + keymap.load(options.builtin.compe.keymap.values, options.builtin.compe.keymap.opts) + vim.api.nvim_set_keymap("i", "<Tab>", "v:lua.tab_complete()", { expr = true }) vim.api.nvim_set_keymap("s", "<Tab>", "v:lua.tab_complete()", { expr = true }) vim.api.nvim_set_keymap("i", "<S-Tab>", "v:lua.s_tab_complete()", { expr = true }) vim.api.nvim_set_keymap("s", "<S-Tab>", "v:lua.s_tab_complete()", { expr = true }) - - vim.api.nvim_set_keymap("i", "<C-Space>", "compe#complete()", { noremap = true, silent = true, expr = true }) - vim.api.nvim_set_keymap("i", "<CR>", "compe#confirm('<CR>')", { noremap = true, silent = true, expr = true }) - vim.api.nvim_set_keymap("i", "<C-e>", "compe#close('<C-e>')", { noremap = true, silent = true, expr = true }) - vim.api.nvim_set_keymap("i", "<C-f>", "compe#scroll({ 'delta': +4 })", { noremap = true, silent = true, expr = true }) - vim.api.nvim_set_keymap("i", "<C-d>", "compe#scroll({ 'delta': -4 })", { noremap = true, silent = true, expr = true }) end return M diff --git a/.config/nvim/lua/core/dap.lua b/.config/nvim/lua/core/dap.lua index bc76e22..a325c7c 100644 --- a/.config/nvim/lua/core/dap.lua +++ b/.config/nvim/lua/core/dap.lua @@ -1,6 +1,7 @@ local M = {} +local Log = require "core.log" M.config = function() - O.plugin.dap = { + options.builtin.dap = { active = false, breakpoint = { text = "", @@ -14,13 +15,14 @@ end M.setup = function() local status_ok, dap = pcall(require, "dap") if not status_ok then + Log:get_default().error "Failed to load dap" return end - vim.fn.sign_define("DapBreakpoint", O.plugin.dap.breakpoint) + vim.fn.sign_define("DapBreakpoint", options.builtin.dap.breakpoint) dap.defaults.fallback.terminal_win_cmd = "50vsplit new" - O.user_which_key["d"] = { + options.builtin.which_key.mappings["d"] = { name = "Debug", t = { "<cmd>lua require'dap'.toggle_breakpoint()<cr>", "Toggle Breakpoint" }, b = { "<cmd>lua require'dap'.step_back()<cr>", "Step Back" }, @@ -34,7 +36,7 @@ M.setup = function() p = { "<cmd>lua require'dap'.pause.toggle()<cr>", "Pause" }, r = { "<cmd>lua require'dap'.repl.toggle()<cr>", "Toggle Repl" }, s = { "<cmd>lua require'dap'.continue()<cr>", "Start" }, - q = { "<cmd>lua require'dap'.stop()<cr>", "Quit" }, + q = { "<cmd>lua require'dap'.close()<cr>", "Quit" }, } end diff --git a/.config/nvim/lua/core/dashboard.lua b/.config/nvim/lua/core/dashboard.lua index 4c7ecc3..c868540 100644 --- a/.config/nvim/lua/core/dashboard.lua +++ b/.config/nvim/lua/core/dashboard.lua @@ -1,6 +1,6 @@ local M = {} M.config = function() - O.plugin.dashboard = { + options.builtin.dashboard = { active = false, search_handler = "telescope", custom_header = { @@ -49,26 +49,26 @@ end M.setup = function() vim.g.dashboard_disable_at_vimenter = 0 - vim.g.dashboard_custom_header = O.plugin.dashboard.custom_header + vim.g.dashboard_custom_header = options.builtin.dashboard.custom_header - vim.g.dashboard_default_executive = O.plugin.dashboard.search_handler + vim.g.dashboard_default_executive = options.builtin.dashboard.search_handler - vim.g.dashboard_custom_section = O.plugin.dashboard.custom_section + vim.g.dashboard_custom_section = options.builtin.dashboard.custom_section - O.plugin.which_key.mappings[";"] = { "<cmd>Dashboard<CR>", "Dashboard" } + options.builtin.which_key.mappings[";"] = { "<cmd>Dashboard<CR>", "Dashboard" } -- f = { -- description = { " Neovim Config Files" }, - -- command = "Telescope find_files cwd=" .. CONFIG_PATH, + -- command = "Telescope find_files cwd=" .. CoptionsFIG_PATH, -- }, -- e = {description = {' Marks '}, command = 'Telescope marks'} - vim.cmd "let g:dashboard_session_directory = $HOME..'/.config/nvim/.sessions'" + vim.cmd "let g:dashboard_session_directory = $HoptionsE..'/.config/nvim/.sessions'" vim.cmd "let packages = len(globpath('~/.local/share/nvim/site/pack/packer/start', '*', 0, 1))" vim.api.nvim_exec( [[ - let g:dashboard_custom_footer = ['LuaJIT loaded '..packages..' plugins'] + let g:dashboard_custom_footer = ['LuaJIT loaded '..packages..' builtins'] ]], false ) @@ -76,10 +76,10 @@ M.setup = function() -- file_browser = {description = {' File Browser'}, command = 'Telescope find_files'}, -- vim.g.dashboard_session_directory = CACHE_PATH..'/session' - -- vim.g.dashboard_custom_footer = O.dashboard.footer - require("utils").define_augroups { + -- vim.g.dashboard_custom_footer = optionsdashboard.footer + require("core.autocmds").define_augroups { _dashboard = { - -- seems to be nobuflisted that makes my stuff disapear will do more testing + -- seems to be nobuflisted that makes my stuff disappear will do more testing { "FileType", "dashboard", @@ -88,7 +88,7 @@ M.setup = function() { "FileType", "dashboard", - "set showtabline=0 | autocmd BufLeave <buffer> set showtabline=" .. O.default_options.showtabline, + "set showtabline=0 | autocmd BufLeave <buffer> set showtabline=" .. vim.opt.showtabline._value, }, { "FileType", "dashboard", "nnoremap <silent> <buffer> q :q<CR>" }, }, diff --git a/.config/nvim/lua/core/formatter.lua b/.config/nvim/lua/core/formatter.lua deleted file mode 100644 index 04c078a..0000000 --- a/.config/nvim/lua/core/formatter.lua +++ /dev/null @@ -1,60 +0,0 @@ --- autoformat -if O.format_on_save then - require("utils").define_augroups { - autoformat = { - { - "BufWritePost", - "*", - ":silent FormatWrite", - }, - }, - } -end - --- -- check if formatter has been defined for the language or not --- local function formatter_exists(lang_formatter) --- if lang_formatter == nil then --- return false --- end --- if lang_formatter.exe == nil or lang_formatter.args == nil then --- return false --- end --- return true --- end - --- returns default formatter for given language --- local function formatter_return(lang_formatter) --- return { --- exe = lang_formatter.exe, --- args = lang_formatter.args, --- stdin = not (lang_formatter.stdin ~= nil), --- } --- end - --- fill a table like this -> {rust: {exe:"sth",args:{"a","b"},stdin=true},go: {}...} --- local formatter_filetypes = {} --- for k, v in pairs(O.lang) do --- if formatter_exists(v.formatter) then --- local keys = v.filetypes --- if keys == nil then --- keys = { k } --- end --- for _, l in pairs(keys) do --- formatter_filetypes[l] = { --- function() --- return formatter_return(v.formatter) --- end, --- } --- end --- end --- end -local status_ok, _ = pcall(require, "formatter") -if not status_ok then - return -end - -if not O.format_on_save then - vim.cmd [[if exists('#autoformat#BufWritePost') - :autocmd! autoformat - endif]] -end diff --git a/.config/nvim/lua/core/galaxyline.lua b/.config/nvim/lua/core/galaxyline.lua index 1f9f781..ff8c59a 100644 --- a/.config/nvim/lua/core/galaxyline.lua +++ b/.config/nvim/lua/core/galaxyline.lua @@ -1,15 +1,17 @@ -- if not package.loaded['galaxyline'] then -- return -- end +local Log = require "core.log" local status_ok, gl = pcall(require, "galaxyline") if not status_ok then + Log:get_default().error "Failed to load galaxyline" return end -- NOTE: if someone defines colors but doesn't have them then this will break -local palette_status_ok, colors = pcall(require, O.colorscheme .. ".palette") +local palette_status_ok, colors = pcall(require, options.colorscheme .. ".palette") if not palette_status_ok then - colors = O.plugin.galaxyline.colors + colors = options.builtin.galaxyline.colors end local condition = require "galaxyline.condition" @@ -189,39 +191,27 @@ table.insert(gls.right, { }, }) -local get_lsp_client = function(msg) +local function get_attached_provider_name(msg) msg = msg or "LSP Inactive" - local buf_ft = vim.api.nvim_buf_get_option(0, "filetype") - local clients = vim.lsp.get_active_clients() - if next(clients) == nil then + local buf_clients = vim.lsp.buf_get_clients() + if next(buf_clients) == nil then return msg end - local lsps = "" - for _, client in ipairs(clients) do - local filetypes = client.config.filetypes - if filetypes and vim.fn.index(filetypes, buf_ft) ~= -1 then - -- print(client.name) - if lsps == "" then - -- print("first", lsps) - lsps = client.name - else - if not string.find(lsps, client.name) then - lsps = lsps .. ", " .. client.name - end - -- print("more", lsps) - end + local buf_ft = vim.bo.filetype + local buf_client_names = {} + local null_ls_providers = require("lsp.null-ls").get_registered_providers_by_filetype(buf_ft) + for _, client in pairs(buf_clients) do + if client.name ~= "null-ls" then + table.insert(buf_client_names, client.name) end end - if lsps == "" then - return msg - else - return lsps - end + vim.list_extend(buf_client_names, null_ls_providers) + return table.concat(buf_client_names, ", ") end table.insert(gls.right, { ShowLspClient = { - provider = get_lsp_client, + provider = get_attached_provider_name, condition = function() local tbl = { ["dashboard"] = true, [" "] = true } if tbl[vim.bo.filetype] then @@ -255,7 +245,11 @@ table.insert(gls.right, { table.insert(gls.right, { Tabstop = { provider = function() - return "Spaces: " .. vim.api.nvim_buf_get_option(0, "shiftwidth") .. " " + local label = "Spaces: " + if not vim.api.nvim_buf_get_option(0, "expandtab") then + label = "Tab size: " + end + return label .. vim.api.nvim_buf_get_option(0, "shiftwidth") .. " " end, condition = condition.hide_in_width, separator = " ", @@ -311,5 +305,3 @@ table.insert(gls.short_line_left, { highlight = { colors.alt_bg, colors.alt_bg }, }, }) - ---table.insert(gls.short_line_right[1] = {BufferIcon = {provider = 'BufferIcon', highlight = {colors.grey, colors.alt_bg}}}) diff --git a/.config/nvim/lua/core/gitsigns.lua b/.config/nvim/lua/core/gitsigns.lua index bc310ad..0b72689 100644 --- a/.config/nvim/lua/core/gitsigns.lua +++ b/.config/nvim/lua/core/gitsigns.lua @@ -1,6 +1,7 @@ local M = {} +local Log = require "core.log" M.config = function() - O.plugin.gitsigns = { + options.builtin.gitsigns = { signs = { add = { hl = "GitSignsAdd", @@ -44,16 +45,16 @@ M.config = function() sign_priority = 6, update_debounce = 200, status_formatter = nil, -- Use default - use_decoration_api = false, } end M.setup = function() local status_ok, gitsigns = pcall(require, "gitsigns") if not status_ok then + Log:get_default().error "Failed to load gitsigns" return end - gitsigns.setup(O.plugin.gitsigns) + gitsigns.setup(options.builtin.gitsigns) end return M diff --git a/.config/nvim/lua/core/hop.lua b/.config/nvim/lua/core/hop.lua deleted file mode 100644 index d3dd90d..0000000 --- a/.config/nvim/lua/core/hop.lua +++ /dev/null @@ -1,20 +0,0 @@ -vim.api.nvim_set_keymap('n', 's', ":HopChar2<cr>", { noremap = true, silent = true }) -vim.api.nvim_set_keymap('n', 'S', ":HopWord<cr>", { noremap = true, silent = true }) - -local M = {} - -M.config = function() - O.plugin.hop = { - active = false, - } -end - -M.setup = function() - local status_ok, hop = pcall(require, "hop") - if not status_ok then - return - end - hop.setup(O.plugin.hop) -end - -return M diff --git a/.config/nvim/lua/core/info.lua b/.config/nvim/lua/core/info.lua new file mode 100644 index 0000000..c9d34ce --- /dev/null +++ b/.config/nvim/lua/core/info.lua @@ -0,0 +1,180 @@ +local M = {} +local u = require "utils" +local null_ls_handler = require "lsp.null-ls" +local indent = " " + +M.banner = { + "", + "", + " ⠀⠀⠀ ⠀⠀ ⣺⡿⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀", + " ⣿⣯ ⣿⡟⠀ ⣤⣤⠀⠀⠀⠀⣠⣤⣤⣤⣄⣤⣤", + "⠀⣿⣿⠀⣰⡟⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⣿⡟⢸⣿⡇⢀⣿", + "⠀⢻⣿⢰⣿⠀⠀⠀⠀⠀⠀⣾⡇⠀⠀⠀⢸⣿⠇⢸⣿⠀⢸⡏", + "⠀⢸⣿⣿⠋⠀⠀⠀⢠⣤⣤⣿⣥⣤⡄⠀⣼⣿⠀⣸⡏⠀⣿⠃", + "⠀⠈⠉⠉⠀⠀⠀⠀⠈⠉⠉⠉⠉⠉⠁⠀⠉⠁⠀⠉⠁⠀⠉⠀", + "", + "", +} + +local function str_list(list) + return "[ " .. table.concat(list, ", ") .. " ]" +end + +local function get_formatter_suggestion_msg(ft) + local supported_formatters = u.get_supported_formatters_by_filetype(ft) + return { + "-------------------------------------------------------------------", + "", + " HINT ", + "", + indent .. "* List of supported formatters: " .. str_list(supported_formatters), + "", + indent .. "You can enable a supported formatter by adding this to your config.lua", + "", + indent + .. "options.lang." + .. tostring(ft) + .. [[.formatting = { { exe = ']] + .. table.concat(supported_formatters, "|") + .. [[' } }]], + "", + "-------------------------------------------------------------------", + } +end + +local function get_linter_suggestion_msg(ft) + local supported_linters = u.get_supported_linters_by_filetype(ft) + return { + "-------------------------------------------------------------------", + "", + " HINT ", + "", + indent .. "* List of supported linters: " .. str_list(supported_linters), + "", + indent .. "You can enable a supported linter by adding this to your config.lua", + "", + indent + .. "options.lang." + .. tostring(ft) + .. [[.linters = { { exe = ']] + .. table.concat(supported_linters, "|") + .. [[' } }]], + "", + "-------------------------------------------------------------------", + } +end + +---creates an average size popup +---@param buf_lines a list of lines to print +---@param callback could be used to set syntax highlighting rules for example +---@return bufnr buffer number of the created buffer +---@return win_id window ID of the created popup +function M.create_simple_popup(buf_lines, callback) + -- runtime/lua/vim/lsp/util.lua + local bufnr = vim.api.nvim_create_buf(false, true) + local height_percentage = 0.7 + local width_percentage = 0.8 + local row_start_percentage = (1 - height_percentage) / 2 + local col_start_percentage = (1 - width_percentage) / 2 + local opts = {} + opts.relative = "editor" + opts.height = math.ceil(vim.o.lines * height_percentage) + opts.row = math.ceil(vim.o.lines * row_start_percentage) + opts.col = math.floor(vim.o.columns * col_start_percentage) + opts.width = math.floor(vim.o.columns * width_percentage) + opts.border = { + "┌", + "-", + "┐", + "|", + "┘", + "-", + "└", + "|", + } + + local win_id = vim.api.nvim_open_win(bufnr, true, opts) + + vim.api.nvim_win_set_buf(win_id, bufnr) + -- this needs to be window option! + vim.api.nvim_win_set_option(win_id, "number", false) + vim.cmd "setlocal nocursorcolumn" + vim.cmd "setlocal wrap" + -- set buffer options + vim.api.nvim_buf_set_option(bufnr, "filetype", "lspinfo") + vim.lsp.util.close_preview_autocmd({ "BufHidden", "BufLeave" }, win_id) + buf_lines = vim.lsp.util._trim(buf_lines, {}) + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, buf_lines) + vim.api.nvim_buf_set_option(bufnr, "modifiable", false) + if type(callback) == "function" then + callback() + end + return bufnr, win_id +end + +function M.toggle_popup(ft) + local client = u.get_active_client_by_ft(ft) + local is_client_active = not client.is_stopped() + local client_enabled_caps = require("lsp").get_ls_capabilities(client.id) + local num_caps = vim.tbl_count(client_enabled_caps) + local null_ls_providers = null_ls_handler.get_registered_providers_by_filetype(ft) + + local missing_linters = options.lang[ft].linters._failed_requests or {} + local missing_formatters = options.lang[ft].formatters._failed_requests or {} + + local buf_lines = {} + vim.list_extend(buf_lines, M.banner) + + local header = { + "Detected filetype is: " .. tostring(ft), + "", + "Treesitter active: " .. tostring(next(vim.treesitter.highlighter.active) ~= nil), + "", + "", + } + vim.list_extend(buf_lines, header) + + local lsp_info = { + "Associated language-server: " .. client.name, + indent .. "* Active: " .. tostring(is_client_active) .. ", id: " .. tostring(client.id), + indent .. "* Formatting support: " .. tostring(client.resolved_capabilities.document_formatting), + indent .. "* Capabilities list: " .. table.concat(vim.list_slice(client_enabled_caps, 1, num_caps / 2), ", "), + indent .. indent .. indent .. table.concat(vim.list_slice(client_enabled_caps, ((num_caps / 2) + 1)), ", "), + "", + } + vim.list_extend(buf_lines, lsp_info) + + local null_ls_info = { + "Configured providers: " .. table.concat(null_ls_providers, " , ") .. " ", + "", + } + vim.list_extend(buf_lines, null_ls_info) + + local missing_formatters_status + if vim.tbl_count(missing_formatters) > 0 then + missing_formatters_status = { "Missing formatters: " .. table.concat(missing_formatters, " , ") .. " ", "" } + vim.list_extend(buf_lines, missing_formatters_status) + end + + local missing_linters_status + if vim.tbl_count(missing_linters) > 0 then + missing_linters_status = { "Missing linters: " .. table.concat(missing_linters, " , ") .. " ", "" } + vim.list_extend(buf_lines, missing_linters_status) + end + + vim.list_extend(buf_lines, get_formatter_suggestion_msg(ft)) + + vim.list_extend(buf_lines, get_linter_suggestion_msg(ft)) + + local function set_syntax_hl() + --TODO: highlighting is either inconsistent or not working :\ + vim.cmd("syntax match Identifier /filetype is: .*\\zs\\<" .. ft .. "\\>/") + vim.cmd("syntax match Identifier /server: .*\\zs\\<" .. client.name .. "\\>/") + vim.cmd("syntax match Identifier /providers: .*\\zs\\<" .. table.concat(null_ls_providers, ", ") .. "\\>/") + vim.cmd("syntax match Identifier /formatters: .*\\zs\\<" .. table.concat(missing_formatters, ", ") .. "\\>/") + vim.cmd("syntax match Identifier /linters: .*\\zs\\<" .. table.concat(missing_linters, ", ") .. "\\>/") + end + + return M.create_simple_popup(buf_lines, set_syntax_hl) +end +return M diff --git a/.config/nvim/lua/core/linter.lua b/.config/nvim/lua/core/linter.lua deleted file mode 100644 index 94dff93..0000000 --- a/.config/nvim/lua/core/linter.lua +++ /dev/null @@ -1,33 +0,0 @@ -local M = {} - -M.setup = function() - if O.lint_on_save then - require("utils").define_augroups { - autolint = { - { - "BufWritePost", - "<buffer>", - ":silent lua require('lint').try_lint()", - }, - { - "BufEnter", - "<buffer>", - ":silent lua require('lint').try_lint()", - }, - }, - } - end -end - -local status_ok, _ = pcall(require, "lint") -if not status_ok then - return -end - -if not O.lint_on_save then - vim.cmd [[if exists('#autolint#BufWritePost') - :autocmd! autolint - endif]] -end - -return M diff --git a/.config/nvim/lua/core/log.lua b/.config/nvim/lua/core/log.lua new file mode 100644 index 0000000..d364ffb --- /dev/null +++ b/.config/nvim/lua/core/log.lua @@ -0,0 +1,29 @@ +local Log = {} + +--- Creates a log handle based on Plenary.log +---@param opts these are passed verbatim to Plenary.log +---@return log handle +function Log:new(opts) + local status_ok, _ = pcall(require, "plenary.log") + if not status_ok then + return nil + end + + local obj = require("plenary.log").new(opts) + local path = string.format("%s/%s.log", vim.api.nvim_call_function("stdpath", { "cache" }), opts.plugin) + + obj.get_path = function() + return path + end + + return obj +end + +--- Creates or retrieves a log handle for the default logfile +--- based on Plenary.log +---@return log handle +function Log:get_default() + return Log:new { plugin = "nvim", level = options.log.level } +end + +return Log diff --git a/.config/nvim/lua/core/nvimtree.lua b/.config/nvim/lua/core/nvimtree.lua index a763c71..698bd6e 100644 --- a/.config/nvim/lua/core/nvimtree.lua +++ b/.config/nvim/lua/core/nvimtree.lua @@ -1,8 +1,10 @@ local M = {} +local Log = require "core.log" -- M.config = function() - O.plugin.nvimtree = { + options.builtin.nvimtree = { side = "left", + width = 30, show_icons = { git = 1, folders = 1, @@ -48,23 +50,54 @@ end M.setup = function() local status_ok, nvim_tree_config = pcall(require, "nvim-tree.config") if not status_ok then + Log:get_default().error "Failed to load nvim-tree.config" return end local g = vim.g - for opt, val in pairs(O.plugin.nvimtree) do + for opt, val in pairs(options.builtin.nvimtree) do g["nvim_tree_" .. opt] = val end local tree_cb = nvim_tree_config.nvim_tree_callback - g.nvim_tree_bindings = { - { key = { "l", "<CR>", "o" }, cb = tree_cb "edit" }, - { key = "h", cb = tree_cb "close_node" }, - { key = "v", cb = tree_cb "vsplit" }, - } + if not g.nvim_tree_bindings then + g.nvim_tree_bindings = { + { key = { "l", "<CR>", "o" }, cb = tree_cb "edit" }, + { key = "h", cb = tree_cb "close_node" }, + { key = "v", cb = tree_cb "vsplit" }, + } + end end -- +M.focus_or_close = function() + local view_status_ok, view = pcall(require, "nvim-tree.view") + if not view_status_ok then + return + end + local a = vim.api + + local curwin = a.nvim_get_current_win() + local curbuf = a.nvim_win_get_buf(curwin) + local bufnr = view.View.bufnr + local winnr = view.get_winnr() + + if view.win_open() then + if curwin == winnr and curbuf == bufnr then + view.close() + if package.loaded["bufferline.state"] then + require("bufferline.state").set_offset(0) + end + else + view.focus() + end + else + view.open() + if package.loaded["bufferline.state"] and options.builtin.nvimtree.side == "left" then + require("bufferline.state").set_offset(options.builtin.nvimtree.width + 1, "") + end + end +end -- M.toggle_tree = function() local view_status_ok, view = pcall(require, "nvim-tree.view") @@ -77,12 +110,17 @@ M.toggle_tree = function() require("bufferline.state").set_offset(0) end else - if package.loaded["bufferline.state"] then - -- require'bufferline.state'.set_offset(31, 'File Explorer') - require("bufferline.state").set_offset(31, "") + if package.loaded["bufferline.state"] and options.builtin.nvimtree.side == "left" then + require("bufferline.state").set_offset(options.builtin.nvimtree.width + 1, "") end require("nvim-tree").toggle() end end -- +function M.change_tree_dir(dir) + if vim.g.loaded_tree then + require("nvim-tree.lib").change_dir(dir) + end +end +-- return M diff --git a/.config/nvim/lua/core/status_colors.lua b/.config/nvim/lua/core/status_colors.lua index 9a70ddd..71b6277 100644 --- a/.config/nvim/lua/core/status_colors.lua +++ b/.config/nvim/lua/core/status_colors.lua @@ -1,4 +1,4 @@ -O.plugin.galaxyline = { +options.builtin.galaxyline = { active = true, colors = { alt_bg = "#0A0A0A", diff --git a/.config/nvim/lua/core/telescope.lua b/.config/nvim/lua/core/telescope.lua index 48157bc..2b0a013 100644 --- a/.config/nvim/lua/core/telescope.lua +++ b/.config/nvim/lua/core/telescope.lua @@ -1,11 +1,12 @@ local M = {} +local Log = require "core.log" M.config = function() local status_ok, actions = pcall(require, "telescope.actions") if not status_ok then return end - O.plugin.telescope = { + options.builtin.telescope = { active = false, defaults = { find_command = { @@ -39,7 +40,7 @@ M.config = function() borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" }, color_devicons = true, use_less = true, - set_env = { ["COLORTERM"] = "truecolor" }, -- default = nil, + set_env = { ["CoptionsLoptionsRTERM"] = "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, @@ -61,7 +62,7 @@ M.config = function() -- ["<c-t>"] = trouble.open_with_trouble, -- ["<c-x>"] = false, -- ["<esc>"] = actions.close, - -- Otherwise, just set the mapping to the function that you want it to be. + -- optionstherwise, just set the mapping to the function that you want it to be. -- ["<C-i>"] = actions.select_horizontal, -- Add up multiple actions -- You can perform as many actions in a row as you like @@ -88,10 +89,10 @@ end M.setup = function() local status_ok, telescope = pcall(require, "telescope") if not status_ok then + Log:get_default().error "Failed to load telescope" return end - telescope.setup(O.plugin.telescope) - vim.api.nvim_set_keymap("n", "<Leader>f", ":Telescope find_files<CR>", { noremap = true, silent = true }) + telescope.setup(options.builtin.telescope) end return M diff --git a/.config/nvim/lua/core/terminal.lua b/.config/nvim/lua/core/terminal.lua index 0f93045..2793da2 100644 --- a/.config/nvim/lua/core/terminal.lua +++ b/.config/nvim/lua/core/terminal.lua @@ -1,8 +1,11 @@ local M = {} +local Log = require "core.log" +local utils = require "utils" + M.config = function() - O.plugin["terminal"] = { + options.builtin["terminal"] = { -- size can be a number or function which is passed the current terminal - size = 5, + size = 20, -- open_mapping = [[<c-\>]], open_mapping = [[<c-t>]], hide_numbers = true, -- hide the number column in toggleterm buffers @@ -11,7 +14,7 @@ M.config = function() shading_factor = 2, -- the degree by which to darken to terminal colour, default: 1 for dark backgrounds, 3 for light start_in_insert = true, insert_mappings = true, -- whether or not the open mapping applies in insert mode - persist_size = true, + persist_size = false, -- direction = 'vertical' | 'horizontal' | 'window' | 'float', direction = "float", close_on_exit = true, -- close the terminal window when the process exits @@ -26,43 +29,105 @@ M.config = function() border = "curved", -- width = <value>, -- height = <value>, - winblend = 3, + winblend = 0, highlights = { border = "Normal", background = "Normal", }, }, + -- Add executables on the config.lua + -- { exec, keymap, name} + -- options.builtin.terminal.execs = {{}} to overwrite + -- options.builtin.terminal.execs[#options.builtin.terminal.execs+1] = {"gdb", "tg", "GNU Debugger"} + execs = { + { "lazygit", "gg", "LazyGit" }, + }, } end M.setup = function() local status_ok, terminal = pcall(require, "toggleterm") if not status_ok then + Log:get_default().error "Failed to load toggleterm" print(terminal) return end + for _, exec in pairs(options.builtin.terminal.execs) do + require("core.terminal").add_exec(exec[1], exec[2], exec[3]) + end + terminal.setup(options.builtin.terminal) +end + +local function is_installed(exe) + return vim.fn.executable(exe) == 1 +end + +M.add_exec = function(exec, keymap, name) vim.api.nvim_set_keymap( "n", - "<leader>gg", - "<cmd>lua require('core.terminal')._lazygit_toggle()<CR>", + "<leader>" .. keymap, + "<cmd>lua require('core.terminal')._exec_toggle('" .. exec .. "')<CR>", { noremap = true, silent = true } ) - O.plugin.which_key.mappings["gg"] = "LazyGit" - terminal.setup(O.plugin.terminal) + options.builtin.which_key.mappings[keymap] = name end -local function is_installed(exe) - return vim.fn.executable(exe) == 1 +M._split = function(inputstr, sep) + if sep == nil then + sep = "%s" + end + local t = {} + for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do + table.insert(t, str) + end + return t end -M._lazygit_toggle = function() - if is_installed "lazygit" ~= true then - print "Please install lazygit. Check documentation for more information" +M._exec_toggle = function(exec) + local binary = M._split(exec)[1] + if is_installed(binary) ~= true then + print("Please install executable " .. binary .. ". Check documentation for more information") return end local Terminal = require("toggleterm.terminal").Terminal - local lazygit = Terminal:new { cmd = "lazygit", hidden = true } - lazygit:toggle() + local exec_term = Terminal:new { cmd = exec, hidden = true } + exec_term:toggle() +end + +local function get_log_path(name) + --handle custom paths not managed by Plenary.log + local logger = require "core.log" + local file + if name == "nvim" then + file = CACHE_PATH .. "/log" + else + file = logger:new({ plugin = name }):get_path() + end + if utils.is_file(file) then + return file + end +end + +---Toggles a log viewer according to log.viewer.layout_config +---@param name can be the name of any of the managed logs, e,g. "lunarvim" or the default ones {"nvim", "lsp", "packer.nvim"} +M.toggle_log_view = function(name) + local logfile = get_log_path(name) + if not logfile then + return + end + local term_opts = vim.tbl_deep_extend("force", options.builtin.terminal, { + cmd = options.log.viewer.cmd .. " " .. logfile, + open_mapping = options.log.viewer.layout_config.open_mapping, + direction = options.log.viewer.layout_config.direction, + -- TODO: this might not be working as expected + size = options.log.viewer.layout_config.size, + float_opts = options.log.viewer.layout_config.float_opts, + }) + + local Terminal = require("toggleterm.terminal").Terminal + local log_view = Terminal:new(term_opts) + -- require("core.log"):get_default().debug("term", vim.inspect(term_opts)) + log_view:toggle() end return M diff --git a/.config/nvim/lua/core/treesitter.lua b/.config/nvim/lua/core/treesitter.lua index 2b7a2d5..ba70b70 100644 --- a/.config/nvim/lua/core/treesitter.lua +++ b/.config/nvim/lua/core/treesitter.lua @@ -1,6 +1,7 @@ local M = {} +local Log = require "core.log" M.config = function() - O.treesitter = { + options.builtin.treesitter = { ensure_installed = {}, -- one of "all", "maintained" (parsers with maintainers), or a list of languages ignore_install = {}, matchup = { @@ -18,7 +19,7 @@ M.config = function() }, -- indent = {enable = true, disable = {"python", "html", "javascript"}}, -- TODO seems to be broken - indent = { enable = { "javascriptreact" } }, + indent = { enable = true, disable = { "yaml" } }, autotag = { enable = false }, textobjects = { swap = { @@ -59,129 +60,16 @@ M.config = function() max_file_lines = 1000, -- Do not enable for files with more than 1000 lines, int }, } - - -- -- TODO refactor treesitter - -- -- @usage pass a table with your desired languages - -- treesitter = { - -- ensure_installed = "all", - -- ignore_install = { "haskell" }, - -- highlight = { enabled = true }, - -- -- The below are for treesitter-textobjects plugin - -- textobj_prefixes = { - -- goto_next = "]", -- Go to next - -- goto_previous = "[", -- Go to previous - -- inner = "i", -- Select inside - -- outer = "a", -- Selct around - -- swap = "<leader>a", -- Swap with next - -- }, - -- textobj_suffixes = { - -- -- Start and End respectively for the goto keys - -- -- for other keys it only uses the first - -- ["function"] = { "f", "F" }, - -- ["class"] = { "m", "M" }, - -- ["parameter"] = { "a", "A" }, - -- ["block"] = { "k", "K" }, - -- ["conditional"] = { "i", "I" }, - -- ["call"] = { "c", "C" }, - -- ["loop"] = { "l", "L" }, - -- ["statement"] = { "s", "S" }, - -- ["comment"] = { "/", "?" }, - -- }, - -- -- The below is for treesitter hint textobjects plugin - -- hint_labels = { "h", "j", "f", "d", "n", "v", "s", "l", "a" }, - -- }, end M.setup = function() - -- TODO: refacor this whole file and treesitter in general - -- if not package.loaded['nvim-treesitter'] then return end - -- - -- Custom parsers - -- local parser_config = require("nvim-treesitter.parsers").get_parser_configs() - -- parser_config.make = { - -- install_info = { - -- url = "https://github.com/alemuller/tree-sitter-make", -- local path or git repo - -- files = {"src/parser.c"}, - -- requires_generate_from_grammar = true - -- } - -- } - -- parser_config.just = { - -- install_info = { - -- url = "~/dev/tree-sitter-just", -- local path or git repo - -- files = {"src/parser.c"} - -- } - -- -- filetype = "just", -- if filetype does not agrees with parser name - -- -- used_by = {"bar", "baz"} -- additional filetypes that use this parser - -- } - -- Custom text objects - -- local textobj_prefixes = O.treesitter.textobj_prefixes - -- local textobj_suffixes = O.treesitter.textobj_suffixes - -- local textobj_sel_keymaps = {} - -- local textobj_swap_keymaps = {} - -- local textobj_move_keymaps = { - -- enable = O.plugin.ts_textobjects, - -- set_jumps = true, -- whether to set jumps in the jumplist - -- goto_next_start = {}, - -- goto_next_end = {}, - -- goto_previous_start = {}, - -- goto_previous_end = {}, - -- } - -- for obj, suffix in pairs(textobj_suffixes) do - -- if textobj_prefixes["goto_next"] ~= nil then - -- textobj_move_keymaps["goto_next_start"][textobj_prefixes["goto_next"] .. suffix[1]] = "@" .. obj .. ".outer" - -- textobj_move_keymaps["goto_next_end"][textobj_prefixes["goto_next"] .. suffix[2]] = "@" .. obj .. ".outer" - -- end - -- if textobj_prefixes["goto_previous"] ~= nil then - -- textobj_move_keymaps["goto_previous_start"][textobj_prefixes["goto_previous"] .. suffix[2]] = "@" .. obj .. ".outer" - -- textobj_move_keymaps["goto_previous_end"][textobj_prefixes["goto_previous"] .. suffix[1]] = "@" .. obj .. ".outer" - -- end - -- - -- if textobj_prefixes["inner"] ~= nil then - -- textobj_sel_keymaps[textobj_prefixes["inner"] .. suffix[1]] = "@" .. obj .. ".inner" - -- end - -- if textobj_prefixes["outer"] ~= nil then - -- textobj_sel_keymaps[textobj_prefixes["outer"] .. suffix[1]] = "@" .. obj .. ".outer" - -- end - -- - -- if textobj_prefixes["swap"] ~= nil then - -- textobj_swap_keymaps[textobj_prefixes["swap"] .. suffix[1]] = "@" .. obj .. ".outer" - -- end - -- end - -- vim.g.ts_hint_textobject_keys = O.treesitter.hint_labels -- Requires https://github.com/mfussenegger/nvim-ts-hint-textobject/pull/2 - -- - -- -- Add which key menu entries - -- local status, wk = pcall(require, "which-key") - -- if status then - -- local normal = { - -- mode = "n", -- Normal mode - -- } - -- local operators = { - -- mode = "o", -- Operator mode - -- } - -- wk.register(textobj_sel_keymaps, operators) - -- wk.register({ - -- ["m"] = "Hint Objects", - -- ["."] = "Textsubject", - -- [";"] = "Textsubject-big", - -- }, operators) - -- wk.register(textobj_swap_keymaps, normal) - -- wk.register({ - -- [textobj_prefixes["swap"]] = "Swap", - -- -- [textobj_prefixes["goto_next"]] = "Jump [", - -- -- [textobj_prefixes["goto_previous"]] = "Jump ]" - -- }, normal) - -- wk.register(textobj_move_keymaps["goto_next_start"], normal) - -- wk.register(textobj_move_keymaps["goto_next_end"], normal) - -- wk.register(textobj_move_keymaps["goto_previous_start"], normal) - -- wk.register(textobj_move_keymaps["goto_previous_end"], normal) - -- end - local status_ok, treesitter_configs = pcall(require, "nvim-treesitter.configs") if not status_ok then + Log:get_default().error "Failed to load nvim-treesitter.configs" return end - treesitter_configs.setup(O.treesitter) + treesitter_configs.setup(options.builtin.treesitter) end return M diff --git a/.config/nvim/lua/core/which-key.lua b/.config/nvim/lua/core/which-key.lua index dabf832..6227a8e 100644 --- a/.config/nvim/lua/core/which-key.lua +++ b/.config/nvim/lua/core/which-key.lua @@ -1,6 +1,7 @@ local M = {} +local Log = require "core.log" M.config = function() - O.plugin.which_key = { + options.builtin.which_key = { active = false, setup = { plugins = { @@ -58,7 +59,7 @@ M.config = function() -- NOTE: Prefer using : over <cmd> as the latter avoids going back in normal-mode. -- see https://neovim.io/doc/user/map.html#:map-cmd vmappings = { - ["/"] = { ":CommentToggle<CR>", "Comment" }, + ["k"] = { ":CommentToggle<CR>", "Comment" }, }, mappings = { ["w"] = { "<cmd>w!<CR>", "Save" }, @@ -68,14 +69,36 @@ M.config = function() ["e"] = { "<cmd>lua require'core.nvimtree'.toggle_tree()<CR>", "Explorer" }, ["f"] = { "<cmd>Telescope find_files<CR>", "Find File" }, ["n"] = { '<cmd>let @/=""<CR>', "No Highlight" }, - ["h"] = { "<cmd>vsplit<CR>", "Vertical Split" }, - ["v"] = { '<cmd>split<CR>', "Horizontal Split" }, + b = { + name = "Buffers", + j = { "<cmd>BufferPick<cr>", "jump to buffer" }, + f = { "<cmd>Telescope buffers<cr>", "Find buffer" }, + w = { "<cmd>BufferWipeout<cr>", "wipeout buffer" }, + e = { + "<cmd>BufferCloseAllButCurrent<cr>", + "close all but current buffer", + }, + h = { "<cmd>BufferCloseBuffersLeft<cr>", "close all buffers to the left" }, + l = { + "<cmd>BufferCloseBuffersRight<cr>", + "close all BufferLines to the right", + }, + D = { + "<cmd>BufferOrderByDirectory<cr>", + "sort BufferLines automatically by directory", + }, + L = { + "<cmd>BufferOrderByLanguage<cr>", + "sort BufferLines automatically by language", + }, + }, p = { name = "Packer", c = { "<cmd>PackerCompile<cr>", "Compile" }, i = { "<cmd>PackerInstall<cr>", "Install" }, - r = { "<cmd>lua require('utils').reload_config()<cr>", "Reload" }, + r = { "<cmd>lua require('utils').reload_lv_config()<cr>", "Reload" }, s = { "<cmd>PackerSync<cr>", "Sync" }, + S = { "<cmd>PackerStatus<cr>", "Status" }, u = { "<cmd>PackerUpdate<cr>", "Update" }, }, @@ -119,18 +142,24 @@ M.config = function() "<cmd>Telescope lsp_workspace_diagnostics<cr>", "Workspace Diagnostics", }, - f = { "<cmd>silent FormatWrite<cr>", "Format" }, + -- f = { "<cmd>silent FormatWrite<cr>", "Format" }, + f = { "<cmd>lua vim.lsp.buf.formatting()<cr>", "Format" }, i = { "<cmd>LspInfo<cr>", "Info" }, j = { - "<cmd>lua vim.lsp.diagnostic.goto_next({popup_opts = {border = O.lsp.popup_border}})<cr>", + "<cmd>lua vim.lsp.diagnostic.goto_next({popup_opts = {border = options.lsp.popup_border}})<cr>", "Next Diagnostic", }, k = { - "<cmd>lua vim.lsp.diagnostic.goto_prev({popup_opts = {border = O.lsp.popup_border}})<cr>", + "<cmd>lua vim.lsp.diagnostic.goto_prev({popup_opts = {border = options.lsp.popup_border}})<cr>", "Prev Diagnostic", }, - l = { "<cmd>silent lua require('lint').try_lint()<cr>", "Lint" }, - q = { "<cmd>Telescope quickfix<cr>", "Quickfix" }, + p = { + name = "Peek", + d = { "<cmd>lua require('lsp.peek').Peek('definition')<cr>", "Definition" }, + t = { "<cmd>lua require('lsp.peek').Peek('typeDefinition')<cr>", "Type Definition" }, + i = { "<cmd>lua require('lsp.peek').Peek('implementation')<cr>", "Implementation" }, + }, + q = { "<cmd>lua vim.lsp.diagnostic.set_loclist()<cr>", "Quickfix" }, r = { "<cmd>lua vim.lsp.buf.rename()<cr>", "Rename" }, s = { "<cmd>Telescope lsp_document_symbols<cr>", "Document Symbols" }, S = { @@ -138,6 +167,14 @@ M.config = function() "Workspace Symbols", }, }, + I = { + name = "+nvim", + k = { "<cmd>lua require('keymappings').print()<cr>", "View nvim's default keymappings" }, + i = { + "<cmd>lua require('core.info').toggle_popup(vim.bo.filetype)<cr>", + "Toggle nvim Info", + }, + }, s = { name = "Search", @@ -170,32 +207,22 @@ M.setup = function() -- end local status_ok, which_key = pcall(require, "which-key") if not status_ok then + Log:get_default "Failed to load whichkey" return end - which_key.setup(O.plugin.which_key.setup) - - local opts = O.plugin.which_key.opts - local vopts = O.plugin.which_key.vopts + which_key.setup(options.builtin.which_key.setup) - local mappings = O.plugin.which_key.mappings - local vmappings = O.plugin.which_key.vmappings + local opts = options.builtin.which_key.opts + local vopts = options.builtin.which_key.vopts - -- if O.plugin.ts_playground.active then - -- vim.api.nvim_set_keymap("n", "<leader>Th", ":TSHighlightCapturesUnderCursor<CR>", { noremap = true, silent = true }) - -- mappings[""] = "Highlight Capture" - -- end - - if O.plugin.zen.active then - vim.api.nvim_set_keymap("n", "<leader>z", ":ZenMode<CR>", { noremap = true, silent = true }) - mappings["z"] = "Zen" - end + local mappings = options.builtin.which_key.mappings + local vmappings = options.builtin.which_key.vmappings local wk = require "which-key" wk.register(mappings, opts) wk.register(vmappings, vopts) - wk.register(O.user_which_key, opts) end return M diff --git a/.config/nvim/lua/default-config.lua b/.config/nvim/lua/default-config.lua index 941738a..e906da1 100644 --- a/.config/nvim/lua/default-config.lua +++ b/.config/nvim/lua/default-config.lua @@ -3,205 +3,1294 @@ DATA_PATH = vim.fn.stdpath "data" CACHE_PATH = vim.fn.stdpath "cache" TERMINAL = vim.fn.expand "$TERMINAL" USER = vim.fn.expand "$USER" +vim.cmd [[ set spellfile=~/.config/nvim/spell/en.utf-8.add ]] -O = { - keys = { - leader_key = "space", - }, +options = { + leader_key = "space", colorscheme = "dark", line_wrap_cursor_movement = true, transparent_window = false, format_on_save = true, - lint_on_save = true, vsnip_dir = os.getenv "HOME" .. "/.config/snippets", + database = { save_location = "~/.config/nvim_db", auto_execute = 1 }, + keys = {}, - default_options = { - backup = false, -- creates a backup file - clipboard = "unnamedplus", -- allows neovim to access the system clipboard - cmdheight = 2, -- more space in the neovim command line for displaying messages - colorcolumn = "99999", -- fixes indentline for now - completeopt = { "menuone", "noselect" }, - conceallevel = 0, -- so that `` is visible in markdown files - fileencoding = "utf-8", -- the encoding written to a file - foldmethod = "manual", -- folding, set to "expr" for treesitter based foloding - foldexpr = "", -- set to "nvim_treesitter#foldexpr()" for treesitter based folding - guifont = "monospace:h17", -- the font used in graphical neovim applications - hidden = true, -- required to keep multiple buffers and open multiple buffers - hlsearch = true, -- highlight all matches on previous search pattern - ignorecase = true, -- ignore case in search patterns - mouse = "a", -- allow the mouse to be used in neovim - pumheight = 10, -- pop up menu height - showmode = false, -- we don't need to see things like -- INSERT -- anymore - showtabline = 2, -- always show tabs - smartcase = true, -- smart case - smartindent = true, -- make indenting smarter again - splitbelow = true, -- force all horizontal splits to go below current window - splitright = true, -- force all vertical splits to go to the right of current window - swapfile = false, -- creates a swapfile - termguicolors = true, -- set term gui colors (most terminals support this) - timeoutlen = 100, -- time to wait for a mapped sequence to complete (in milliseconds) - title = true, -- set the title of window to the value of the titlestring - -- opt.titlestring = "%<%F%=%l/%L - nvim" -- what the title of the window will be set to - undodir = CACHE_PATH .. "/undo", -- set an undo directory - undofile = true, -- enable persisten undo - updatetime = 300, -- faster completion - writebackup = false, -- if a file is being edited by another program (or was written to file while editing with another program), it is not allowed to be edited - expandtab = true, -- convert tabs to spaces - shiftwidth = 2, -- the number of spaces inserted for each indentation - tabstop = 2, -- insert 2 spaces for a tab - cursorline = true, -- highlight the current line - number = true, -- set numbered lines - relativenumber = false, -- set relative numbered lines - numberwidth = 4, -- set number column width to 2 {default 4} - signcolumn = "yes", -- always show the sign column, otherwise it would shift the text each time - wrap = false, -- display lines as one long line - spell = false, - spelllang = "en", - scrolloff = 8, -- is one of my fav - sidescrolloff = 8, + -- TODO: might remove later + builtin = { + lspinstall = {}, + telescope = {}, + compe = {}, + autopairs = {}, + treesitter = {}, + nvimtree = {}, + gitsigns = {}, + which_key = {}, + comment = {}, + galaxyline = {}, + bufferline = {}, + dap = {}, + dashboard = {}, + terminal = {}, + rooter = {}, + }, + + log = { + ---@usage can be { "trace", "debug", "info", "warn", "error", "fatal" }, + level = "warn", + viewer = { + ---@usage this will fallback on "less +F" if not found + cmd = "lnav", + layout_config = { + ---@usage direction = 'vertical' | 'horizontal' | 'window' | 'float', + direction = "horizontal", + open_mapping = "", + size = 40, + float_opts = {}, + }, + }, }, lsp = { + completion = { + item_kind = { + " (Text) ", + " (Method)", + " (Function)", + " (Constructor)", + " ﴲ (Field)", + "[] (Variable)", + " (Class)", + " ﰮ (Interface)", + " (Module)", + " 襁 (Property)", + " (Unit)", + " (Value)", + " 練 (Enum)", + " (Keyword)", + " (Snippet)", + " (Color)", + " (File)", + " (Reference)", + " (Folder)", + " (EnumMember)", + " ﲀ (Constant)", + " ﳤ (Struct)", + " (Event)", + " (Operator)", + " (TypeParameter)", + }, + }, diagnostics = { + signs = { + active = true, + values = { + { name = "LspDiagnosticsSignError", text = "" }, + { name = "LspDiagnosticsSignWarning", text = "" }, + { name = "LspDiagnosticsSignHint", text = "" }, + { name = "LspDiagnosticsSignInformation", text = "" }, + }, + }, virtual_text = { prefix = "", spacing = 0, }, - signs = true, underline = true, + severity_sort = true, }, + override = {}, document_highlight = true, popup_border = "single", - default_keybinds = true, on_attach_callback = nil, + on_init_callback = nil, + ---@usage query the project directory from the language server and use it to set the CWD + smart_cwd = true, }, - disabled_built_ins = { - "netrw", - "netrwPlugin", - "netrwSettings", - "netrwFileHandlers", - "gzip", - "zip", - "zipPlugin", - "tar", - "tarPlugin", -- 'man', - "getscript", - "getscriptPlugin", - "vimball", - "vimballPlugin", - "2html_plugin", - "logipat", - "rrhelper", - "spellfile_plugin", - -- 'matchit', 'matchparen', 'shada_plugin', + plugins = { + -- use config.lua for this not put here }, - plugin = { - lspinstall = {}, - telescope = {}, - compe = {}, - autopairs = {}, - treesitter = {}, - formatter = {}, - lint = {}, - nvimtree = {}, - gitsigns = {}, - which_key = {}, - comment = {}, - rooter = {}, - galaxyline = {}, - bufferline = {}, - dap = {}, - dashboard = {}, - terminal = {}, - zen = {}, - hop = {}, - colorizer = {}, - }, + autocommands = {}, +} - -- TODO: refactor for tree - auto_clos_tree = 0, - nvim_tree_disable_netrw = 0, +local schemas = nil +local lsp = require "lsp" +local common_on_attach = lsp.common_on_attach +local common_capabilities = lsp.common_capabilities() +local common_on_init = lsp.common_on_init +local status_ok, jsonls_settings = pcall(require, "nlspsettings.jsonls") +if status_ok then + schemas = jsonls_settings.get_default_schemas() +end - database = { save_location = "~/.config/nvim_db", auto_execute = 1 }, +-- TODO move all of this into lang specific files, only require when using +options.lang = { + asm = { + formatters = { + { + -- @usage can be asmfmt + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "", + setup = {}, + }, + }, + beancount = { + formatters = { + { + -- @usage can be bean_format + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "beancount", + setup = { + cmd = { "beancount-langserver" }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + c = { + formatters = { + { + -- @usage can be clang_format or uncrustify + exe = "", + args = {}, + stdin = true, + }, + }, + linters = {}, + lsp = { + provider = "clangd", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/cpp/clangd/bin/clangd", + "--background-index", + "--header-insertion=never", + "--cross-file-rename", + "--clang-tidy", + "--clang-tidy-checks=-*,llvm-*,clang-analyzer-*", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + cpp = { + formatters = { + { + -- @usage can be clang_format or uncrustify + exe = "", + args = {}, + stdin = true, + }, + }, + linters = {}, + lsp = { + provider = "clangd", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/cpp/clangd/bin/clangd", + "--background-index", + "--header-insertion=never", + "--cross-file-rename", + "--clang-tidy", + "--clang-tidy-checks=-*,llvm-*,clang-analyzer-*", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + crystal = { + formatters = { + { + -- @usage can be crystal_format + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "crystalline", + setup = { + cmd = { "crystalline" }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + cs = { + formatters = { + { + -- @usage can be clang_format or uncrustify + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "omnisharp", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/csharp/omnisharp/run", + "--languageserver", + "--hostPID", + tostring(vim.fn.getpid()), + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + cmake = { + formatters = { + { + -- @usage can be cmake_format + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "cmake", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/cmake/venv/bin/cmake-language-server", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + clojure = { + formatters = { { + exe = "", + args = {}, + } }, + linters = {}, + lsp = { + provider = "clojure_lsp", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/clojure/clojure-lsp", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + css = { + formatters = { + { + -- @usage can be prettier or prettierd + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "cssls", + setup = { + cmd = { + "node", + DATA_PATH .. "/lspinstall/css/vscode-css/css-language-features/server/dist/node/cssServerMain.js", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + less = { + formatters = { + { + -- @usage can be prettier or prettierd + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "cssls", + setup = { + cmd = { + "node", + DATA_PATH .. "/lspinstall/css/vscode-css/css-language-features/server/dist/node/cssServerMain.js", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + d = { + formatters = { + { + -- @usage can be dfmt + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "serve_d", + setup = { + cmd = { "serve-d" }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + dart = { + formatters = { + { + -- @usage can be dart_format + exe = "", + args = {}, + stdin = true, + }, + }, + linters = {}, + lsp = { + provider = "dartls", + setup = { + cmd = { + "dart", + "/usr/lib/dart/bin/snapshots/analysis_server.dart.snapshot", + "--lsp", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + docker = { + formatters = { + { + exe = "", + args = {}, + }, + -- @usage can be {"hadolint"} + }, + linters = {}, + lsp = { + provider = "dockerls", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/dockerfile/node_modules/.bin/docker-langserver", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + elixir = { + formatters = { + { + -- @usage can be mix + exe = "", + args = {}, + stdin = true, + }, + }, + linters = {}, + lsp = { + provider = "elixirls", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/elixir/elixir-ls/language_server.sh", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + elm = { + formatters = { + { + -- @usage can be elm_format + exe = "", + args = {}, + stdin = true, + }, + }, + linters = {}, + lsp = { + provider = "elmls", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/elm/node_modules/.bin/elm-language-server", + }, + on_attach = common_on_attach, + on_init = common_on_init, + -- init_options = { + -- elmAnalyseTrigger = "change", + -- elmFormatPath = DATA_PATH .. "/lspinstall/elm/node_modules/.bin/elm-format", + -- elmPath = DATA_PATH .. "/lspinstall/elm/node_modules/.bin/", + -- elmTestPath = DATA_PATH .. "/lspinstall/elm/node_modules/.bin/elm-test", + -- }, + }, + }, + }, + erlang = { + formatters = { + { + -- @usage can be erlfmt + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "erlangls", + setup = { + cmd = { + "erlang_ls", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + emmet = { active = false }, + fish = { + formatters = { + { + -- @usage can be fish_indent + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "", + setup = { + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + go = { + formatters = { + { + -- @usage can be gofmt or goimports or gofumpt + exe = "", + args = {}, + stdin = true, + }, + }, + linters = {}, + lsp = { + provider = "gopls", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/go/gopls", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + graphql = { + formatters = { { + exe = "", + args = {}, + } }, + linters = {}, + lsp = { + provider = "graphql", + setup = { + cmd = { + "graphql-lsp", + "server", + "-m", + "stream", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + haskell = { + formatters = { { + exe = "", + args = {}, + } }, + linters = {}, + lsp = { + provider = "hls", + setup = { + cmd = { DATA_PATH .. "/lspinstall/haskell/hls" }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + html = { + formatters = { + { + -- @usage can be prettier or prettierd + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "html", + setup = { + cmd = { + "node", + DATA_PATH .. "/lspinstall/html/vscode-html/html-language-features/server/dist/node/htmlServerMain.js", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + java = { + formatters = { + { + -- @usage can be clang_format or uncrustify + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "jdtls", + setup = { + cmd = { DATA_PATH .. "/lspinstall/java/jdtls.sh" }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + json = { + formatters = { + { + -- @usage can be json_tool or prettier or prettierd + exe = "", + args = {}, + stdin = true, + }, + }, + linters = {}, + lsp = { + provider = "jsonls", + setup = { + cmd = { + "node", + DATA_PATH .. "/lspinstall/json/vscode-json/json-language-features/server/dist/node/jsonServerMain.js", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + settings = { + json = { + schemas = schemas, + -- = { + -- { + -- fileMatch = { "package.json" }, + -- url = "https://json.schemastore.org/package.json", + -- }, + -- }, + }, + }, + commands = { + Format = { + function() + vim.lsp.buf.range_formatting({}, { 0, 0 }, { vim.fn.line "$", 0 }) + end, + }, + }, + }, + }, + }, + julia = { + formatters = { { + exe = "", + args = {}, + } }, + linters = {}, + lsp = { + provider = "julials", + setup = { + { + "julia", + "--startup-file=no", + "--history-file=no", + -- vim.fn.expand "~/.config/nvim/lua/lsp/julia/run.jl", + CONFIG_PATH .. "/utils/julia/run.jl", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + kotlin = { + formatters = { { + exe = "", + args = {}, + } }, + linters = {}, + lsp = { + provider = "kotlin_language_server", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/kotlin/server/bin/kotlin-language-server", + }, + on_attach = common_on_attach, + on_init = common_on_init, + root_dir = function(fname) + local util = require "lspconfig/util" - -- TODO: just using mappings (leader mappings) - user_which_key = {}, + local root_files = { + "settings.gradle", -- Gradle (multi-project) + "settings.gradle.kts", -- Gradle (multi-project) + "build.xml", -- Ant + "pom.xml", -- Maven + } - user_plugins = { - -- use lv-config.lua for this not put here + local fallback_root_files = { + "build.gradle", -- Gradle + "build.gradle.kts", -- Gradle + } + return util.root_pattern(unpack(root_files))(fname) or util.root_pattern(unpack(fallback_root_files))(fname) + end, + }, + }, }, - - user_autocommands = { - { "FileType", "qf", "set nobuflisted" }, + lua = { + formatters = { + { + -- @usage can be stylua or lua_format + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "sumneko_lua", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/lua/sumneko-lua-language-server", + "-E", + DATA_PATH .. "/lspinstall/lua/main.lua", + }, + capabilities = common_capabilities, + on_attach = common_on_attach, + on_init = common_on_init, + 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 = vim.split(package.path, ";"), + }, + diagnostics = { + -- Get the language server to recognize the `vim` global + globals = { "vim", "nvim" }, + }, + workspace = { + -- Make the server aware of Neovim runtime files + library = { + [vim.fn.expand "~/.config/nvim/lua"] = true, + [vim.fn.expand "$VIMRUNTIME/lua"] = true, + [vim.fn.expand "$VIMRUNTIME/lua/vim/lsp"] = true, + }, + maxPreload = 100000, + preloadFileSize = 1000, + }, + }, + }, + }, + }, }, - - formatters = { - filetype = {}, + nginx = { + formatters = { + { + -- @usage can be nginx_beautifier + exe = "", + args = { + provider = "", + setup = {}, + }, + }, + }, + linters = {}, + lsp = {}, }, - - -- TODO move all of this into lang specific files, only require when using - lang = { - efm = {}, - emmet = { active = false }, - svelte = {}, - tailwindcss = { - active = false, - filetypes = { - "html", - "css", - "scss", - "javascript", - "javascriptreact", - "typescript", - "typescriptreact", + perl = { + formatters = { + { + -- @usage can be perltidy + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "", + setup = {}, + }, + }, + sql = { + formatters = { + { + -- @usage can be sqlformat + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "sqls", + setup = { + cmd = { "sqls" }, + }, + }, + }, + php = { + formatters = { + { + -- @usage can be phpcbf + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "intelephense", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/php/node_modules/.bin/intelephense", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + filetypes = { "php", "phtml" }, + settings = { + intelephense = { + environment = { + phpVersion = "7.4", + }, + }, + }, + }, + }, + }, + puppet = { + formatters = { { + exe = "", + args = {}, + } }, + linters = {}, + lsp = { + provider = "puppet", + setup = { + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + javascript = { + -- @usage can be prettier or prettier_d_slim or prettierd + formatters = { + { + exe = "", + args = {}, + }, + }, + -- @usage can be {"eslint"} or {"eslint_d"} + linters = {}, + lsp = { + provider = "tsserver", + setup = { + cmd = { + -- TODO: + DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + javascriptreact = { + formatters = { + { + -- @usage can be prettier or prettier_d_slim or prettierd + exe = "", + args = {}, }, }, - tsserver = { - -- @usage can be 'eslint' or 'eslint_d' - linter = "", - diagnostics = { - virtual_text = { spacing = 0, prefix = "" }, - signs = true, - underline = true, + -- @usage can be {"eslint"} or {"eslint_d"} + linters = {}, + lsp = { + provider = "tsserver", + setup = { + cmd = { + -- TODO: + DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, }, - formatter = { - exe = "prettier", + }, + }, + python = { + formatters = { + { + -- @usage can be black or yapf or isort + exe = "", args = {}, }, }, + linters = {}, + lsp = { + provider = "pyright", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/python/node_modules/.bin/pyright-langserver", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + -- R -e 'install.packages("formatR",repos = "http://cran.us.r-project.org")' + -- R -e 'install.packages("readr",repos = "http://cran.us.r-project.org")' + r = { + formatters = { + { + -- @usage can be format_r + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "r_language_server", + setup = { + cmd = { + "R", + "--slave", + "-e", + "languageserver::run()", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + ruby = { + formatters = { + { + -- @usage can be rufo + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "solargraph", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/ruby/solargraph/solargraph", + "stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + filetypes = { "ruby" }, + init_options = { + formatting = true, + }, + root_dir = function(fname) + local util = require("lspconfig").util + return util.root_pattern("Gemfile", ".git")(fname) + end, + settings = { + solargraph = { + diagnostics = true, + }, + }, + }, + }, + }, + rust = { + formatters = { + { + -- @usage can be rustfmt + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "rust_analyzer", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/rust/rust-analyzer", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + scala = { + formatters = { + { + -- @usage can be scalafmt + exe = "", + args = {}, + }, + }, + linters = { "" }, + lsp = { + provider = "metals", + setup = { + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + sh = { + formatters = { + { + -- @usage can be shfmt + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "bashls", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/bash/node_modules/.bin/bash-language-server", + "start", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + svelte = { + formatters = { { + exe = "", + args = {}, + } }, + linters = {}, + lsp = { + provider = "svelte", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/svelte/node_modules/.bin/svelteserver", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + swift = { + formatters = { + { + -- @usage can be swiftformat + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "sourcekit", + setup = { + cmd = { + "xcrun", + "sourcekit-lsp", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + tailwindcss = { + active = false, + filetypes = { + "html", + "css", + "scss", + "javascript", + "javascriptreact", + "typescript", + "typescriptreact", + }, + }, + terraform = { + formatters = { + { + -- @usage can be terraform_fmt + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "terraformls", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/terraform/terraform-ls", + "serve", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + tex = { + formatters = { + { + exe = "", + args = {}, + stdin = false, + }, + -- @usage can be chktex or vale + }, + linters = {}, + lsp = { + provider = "texlab", + setup = { + cmd = { DATA_PATH .. "/lspinstall/latex/texlab" }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + typescript = { + formatters = { + { + -- @usage can be prettier or prettierd or prettier_d_slim + exe = "", + args = {}, + }, + -- @usage can be {"eslint"} or {"eslint_d"} + }, + linters = {}, + lsp = { + provider = "tsserver", + setup = { + cmd = { + -- TODO: + DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + typescriptreact = { + formatters = { + { + -- @usage can be prettier or prettierd or prettier_d_slim + exe = "", + args = {}, + }, + }, + -- @usage can be {"eslint"} or {"eslint_d"} + linters = {}, + lsp = { + provider = "tsserver", + setup = { + cmd = { + -- TODO: + DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + vim = { + formatters = { + { + exe = "", + args = {}, + }, + }, + -- @usage can be {"vint"} + linters = { "" }, + lsp = { + provider = "vimls", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/vim/node_modules/.bin/vim-language-server", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + vue = { + formatters = { + { + -- @usage can be prettier or prettierd or prettier_d_slim + exe = "", + args = {}, + }, + }, + -- @usage can be {"eslint"} or {"eslint_d"} + linters = {}, + lsp = { + provider = "vuels", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/vue/node_modules/.bin/vls", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + yaml = { + formatters = { + { + -- @usage can be prettier or prettierd + exe = "", + args = {}, + }, + }, + linters = {}, + lsp = { + provider = "yamlls", + setup = { + cmd = { + DATA_PATH .. "/lspinstall/yaml/node_modules/.bin/yaml-language-server", + "--stdio", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + zig = { + formatters = { { + exe = "", + args = {}, + stdin = false, + } }, + linters = {}, + lsp = { + provider = "zls", + setup = { + cmd = { + "zls", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + gdscript = { + formatters = {}, + linters = {}, + lsp = { + provider = "gdscript", + setup = { + cmd = { + "nc", + "localhost", + "6008", + }, + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, + }, + ps1 = { + formatters = {}, + linters = {}, + lsp = { + provider = "powershell_es", + setup = { + bundle_path = "", + on_attach = common_on_attach, + on_init = common_on_init, + capabilities = common_capabilities, + }, + }, }, } +require("keymappings").config() +require("core.which-key").config() require "core.status_colors" require("core.gitsigns").config() require("core.compe").config() require("core.dashboard").config() require("core.dap").config() require("core.terminal").config() -require("core.zen").config() require("core.telescope").config() require("core.treesitter").config() -require("core.which-key").config() require("core.nvimtree").config() - -require("lang.clang").config() -require("lang.dart").config() -require("lang.dockerfile").config() -require("lang.elixir").config() -require("lang.go").config() -require("lang.graphql").config() -require("lang.html").config() -require("lang.json").config() -require("lang.kotlin").config() -require("lang.lua").config() -require("lang.python").config() -require("lang.rust").config() -require("lang.sh").config() -require("lang.swift").config() -require("lang.tex").config() -require("lang.vim").config() -require("lang.yaml").config() -require("lang.zig").config() -require("lang.zsh").config() +-- require("core.rooter").config() +require("core.bufferline").config() diff --git a/.config/nvim/lua/extra/colorizer.lua b/.config/nvim/lua/extra/colorizer.lua new file mode 100644 index 0000000..04b7367 --- /dev/null +++ b/.config/nvim/lua/extra/colorizer.lua @@ -0,0 +1,22 @@ +local M = {} +local Log = require "core.log" + +M.config = function() + local status_ok, colorizer = pcall(require, "colorizer") + if not status_ok then + Log:get_default().error "Failed to load colorizer" + return + end + + colorizer.setup({ "*" }, { + RGB = true, -- #RGB hex codes + RRGGBB = true, -- #RRGGBB hex codes + RRGGBBAA = true, -- #RRGGBBAA hex codes + rgb_fn = true, -- CSS rgb() and rgba() functions + hsl_fn = true, -- CSS hsl() and hsla() functions + css = true, -- Enable all CSS features: rgb_fn, hsl_fn, names, RGB, RRGGBB + css_fn = true, -- Enable all CSS *functions*: rgb_fn, hsl_fn + }) +end + +return M diff --git a/.config/nvim/lua/extra/hop.lua b/.config/nvim/lua/extra/hop.lua new file mode 100644 index 0000000..834f97a --- /dev/null +++ b/.config/nvim/lua/extra/hop.lua @@ -0,0 +1,15 @@ +local M = {} +local Log = require "core.log" + +M.config = function() + local status_ok, hop = pcall(require, "hop") + if not status_ok then + Log:get_default().error "Failed to load hop" + return + end + hop.setup() + vim.api.nvim_set_keymap("n", "s", ":HopChar2<cr>", { silent = true }) + vim.api.nvim_set_keymap("n", "S", ":HopWord<cr>", { silent = true }) +end + +return M diff --git a/.config/nvim/lua/extra/json_schemas.lua b/.config/nvim/lua/extra/json_schemas.lua new file mode 100644 index 0000000..590547b --- /dev/null +++ b/.config/nvim/lua/extra/json_schemas.lua @@ -0,0 +1,99 @@ +-- https://www.schemastore.org/json/ +local M = {} + +M.setup = function() + local schemas = { + { + description = "Package JSON file", + fileMatch = { "package.json" }, + url = "https://json.schemastore.org/package.json", + }, + { + description = "TypeScript compiler configuration file", + fileMatch = { "tsconfig.json", "tsconfig.*.json" }, + url = "http://json.schemastore.org/tsconfig", + }, + { + description = "Lerna config", + fileMatch = { "lerna.json" }, + url = "http://json.schemastore.org/lerna", + }, + { + description = "Babel configuration", + fileMatch = { ".babelrc.json", ".babelrc", "babel.config.json" }, + url = "http://json.schemastore.org/lerna", + }, + { + description = "ESLint config", + fileMatch = { ".eslintrc.json", ".eslintrc" }, + url = "http://json.schemastore.org/eslintrc", + }, + { + description = "Bucklescript config", + fileMatch = { "bsconfig.json" }, + url = "https://bucklescript.github.io/bucklescript/docson/build-schema.json", + }, + { + description = "Prettier config", + fileMatch = { ".prettierrc", ".prettierrc.json", "prettier.config.json" }, + url = "http://json.schemastore.org/prettierrc", + }, + { + description = "Vercel Now config", + fileMatch = { "now.json" }, + url = "http://json.schemastore.org/now", + }, + { + description = "Stylelint config", + fileMatch = { ".stylelintrc", ".stylelintrc.json", "stylelint.config.json" }, + url = "http://json.schemastore.org/stylelintrc", + }, + { + name = "Helm Chart.yaml", + description = "The Chart.lock file locks dependencies from Chart.yaml", + fileMatch = { "Chart.lock" }, + url = "https://json.schemastore.org/chart-lock.json" + }, + { + name = "CircleCI config.yml", + description = "Schema for CircleCI 2.0 config files", + fileMatch = { ".circleci/config.yml" }, + url = "https://json.schemastore.org/circleciconfig.json" + }, + { + name = "yamllint", + description = "yamllint uses a set of rules to check source files for problems", + fileMatch = { "**/.yamllint", "**/.yamllint.yaml", "**/.yamllint.yml" }, + url = "https://json.schemastore.org/yamllint.json" + }, + { + name = "Hadolint", + description = "A smarter Dockerfile linter that helps you build best practice Docker images.", + fileMatch = { ".hadolint.yaml", "hadolint.yaml", ".hadolint.yml", "hadolint.yml" }, + url = "https://raw.githubusercontent.com/hadolint/hadolint/master/contrib/hadolint.json" + }, + { + name = "kustomization.yaml", + description = "Kubernetes native configuration management", + fileMatch = { "kustomization.yaml", "kustomization.yml" }, + url = "https://json.schemastore.org/kustomization.json" + }, + } + + local function extend(tab1, tab2) + for _, value in ipairs(tab2) do + table.insert(tab1, value) + end + return tab1 + end + + local extended_schemas = extend(schemas, require("nlspsettings.jsonls").get_default_schemas()) + + options.lang.json.lsp.setup.settings = { + json = { + schemas = extended_schemas, + }, + } +end + +return M diff --git a/.config/nvim/lua/extra/lir.lua b/.config/nvim/lua/extra/lir.lua new file mode 100644 index 0000000..271afb1 --- /dev/null +++ b/.config/nvim/lua/extra/lir.lua @@ -0,0 +1,96 @@ +local status_ok, lir = pcall(require, "lir") +if not status_ok then + return +end +local actions = require "lir.actions" +local mark_actions = require "lir.mark.actions" +local clipboard_actions = require "lir.clipboard.actions" + +lir.setup { + show_hidden_files = false, + devicons_enable = true, + mappings = { + ["l"] = actions.edit, + ["<cr>"] = actions.edit, + ["<C-s>"] = actions.split, + ["v"] = actions.vsplit, + ["<C-t>"] = actions.tabedit, + + ["h"] = actions.up, + ["q"] = actions.quit, + + ["A"] = actions.mkdir, + ["a"] = actions.newfile, + ["r"] = actions.rename, + ["@"] = actions.cd, + ["Y"] = actions.yank_path, + ["."] = actions.toggle_show_hidden, + ["D"] = actions.delete, + + ["J"] = function() + mark_actions.toggle_mark() + vim.cmd "normal! j" + end, + ["C"] = clipboard_actions.copy, + ["X"] = clipboard_actions.cut, + ["P"] = clipboard_actions.paste, + }, + float = { + winblend = 0, + + -- -- You can define a function that returns a table to be passed as the third + -- -- argument of nvim_open_win(). + win_opts = function() + -- local width = math.floor(vim.o.columns * 0.8) + -- local height = math.floor(vim.o.lines * 0.8) + return { + border = "single", + -- border = require("lir.float.helper").make_border_opts({ + -- "+", + -- "─", + -- "+", + -- "│", + -- "+", + -- "─", + -- "+", + -- "│", + -- }, "Normal"), + -- width = width, + -- height = height, + -- row = 1, + -- col = math.floor((vim.o.columns - width) / 2), + } + end, + }, + hide_cursor = false, +} + +-- custom folder icon +require("nvim-web-devicons").setup { + override = { + lir_folder_icon = { + icon = "", + color = "#569CD6", + name = "LirFolderNode", + }, + }, +} + +-- use visual mode +function _G.LirSettings() + vim.api.nvim_buf_set_keymap( + 0, + "x", + "J", + ':<C-u>lua require"lir.mark.actions".toggle_mark("v")<CR>', + { noremap = true, silent = true } + ) + + -- echo cwd + vim.api.nvim_echo({ { vim.fn.expand "%:p", "Normal" } }, false, {}) +end + +vim.cmd [[augroup lir-settings]] +vim.cmd [[ autocmd!]] +vim.cmd [[ autocmd Filetype lir :lua LirSettings()]] +vim.cmd [[augroup END]] diff --git a/.config/nvim/lua/extra/lsp_signature.lua b/.config/nvim/lua/extra/lsp_signature.lua new file mode 100644 index 0000000..7e67a4d --- /dev/null +++ b/.config/nvim/lua/extra/lsp_signature.lua @@ -0,0 +1,14 @@ +local M = {} +local Log = require "core.log" + +M.config = function() + local status_ok, lsp_signature = pcall(require, "lsp_signature") + if not status_ok then + Log:get_default().error "Failed to load lsp_signature" + return + end + + lsp_signature.on_attach() +end + +return M diff --git a/.config/nvim/lua/extra/neoscroll.lua b/.config/nvim/lua/extra/neoscroll.lua new file mode 100644 index 0000000..65f486b --- /dev/null +++ b/.config/nvim/lua/extra/neoscroll.lua @@ -0,0 +1,25 @@ +local M = {} +local Log = require "core.log" + +M.config = function() + local status_ok, neoscroll = pcall(require, "neoscroll") + if not status_ok then + Log:get_default().error "Failed to load hop" + return + end + + neoscroll.setup { + -- All these keys will be mapped to their corresponding default scrolling animation + mappings = { "<C-u>", "<C-d>", "<C-b>", "<C-f>", "<C-y>", "<C-e>", "zt", "zz", "zb" }, + hide_cursor = true, -- Hide cursor while scrolling + stop_eof = true, -- Stop at <EOF> when scrolling downwards + use_local_scrolloff = false, -- Use the local scope of scrolloff instead of the global scope + respect_scrolloff = false, -- Stop scrolling when the cursor reaches the scrolloff margin of the file + cursor_scrolls_alone = true, -- The cursor will keep on scrolling even if the window cannot scroll further + easing_function = nil, -- Default easing function + pre_hook = nil, -- Function to run before the scrolling animation starts + post_hook = nil, -- Function to run after the scrolling animation ends + } +end + +return M diff --git a/.config/nvim/lua/extra/numb.lua b/.config/nvim/lua/extra/numb.lua new file mode 100644 index 0000000..17d9f6b --- /dev/null +++ b/.config/nvim/lua/extra/numb.lua @@ -0,0 +1,17 @@ +local M = {} +local Log = require "core.log" + +M.config = function() + local status_ok, numb = pcall(require, "numb") + if not status_ok then + Log:get_default().error "Failed to load numb" + return + end + + numb.setup { + show_numbers = true, -- Enable 'number' for the window while peeking + show_cursorline = true, -- Enable 'cursorline' for the window while peeking + } +end + +return M diff --git a/.config/nvim/lua/extra/octo.lua b/.config/nvim/lua/extra/octo.lua new file mode 100644 index 0000000..5a110df --- /dev/null +++ b/.config/nvim/lua/extra/octo.lua @@ -0,0 +1,139 @@ +local M = {} + +local Log = require "core.log" + +M.config = function() + local status_ok, octo = pcall(require, "octo") + if not status_ok then + Log:get_default().error "Failed to load octo" + return + end + + octo.setup { + default_remote = { "upstream", "origin" }, -- order to try remotes + reaction_viewer_hint_icon = "", -- marker for user reactions + user_icon = " ", -- user icon + timeline_marker = "", -- timeline marker + timeline_indent = "2", -- timeline indentation + right_bubble_delimiter = "", -- Bubble delimiter + left_bubble_delimiter = "", -- Bubble delimiter + github_hostname = "", -- GitHub Enterprise host + snippet_context_lines = 4, -- number or lines around commented lines + file_panel = { + size = 10, -- changed files panel rows + use_icons = true, -- use web-devicons in file panel + }, + mappings = { + issue = { + close_issue = "<space>ic", -- close issue + reopen_issue = "<space>io", -- reopen issue + list_issues = "<space>il", -- list open issues on same repo + reload = "<C-r>", -- reload issue + open_in_browser = "<C-b>", -- open issue in browser + copy_url = "<C-y>", -- copy url to system clipboard + add_assignee = "<space>aa", -- add assignee + remove_assignee = "<space>ad", -- remove assignee + create_label = "<space>lc", -- create label + add_label = "<space>la", -- add label + remove_label = "<space>ld", -- remove label + goto_issue = "<space>gi", -- navigate to a local repo issue + add_comment = "<space>ca", -- add comment + delete_comment = "<space>cd", -- delete comment + next_comment = "]c", -- go to next comment + prev_comment = "[c", -- go to previous comment + react_hooray = "<space>rp", -- add/remove 🎉 reaction + react_heart = "<space>rh", -- add/remove ❤️ reaction + react_eyes = "<space>re", -- add/remove 👀 reaction + react_thumbs_up = "<space>r+", -- add/remove 👍 reaction + react_thumbs_down = "<space>r-", -- add/remove 👎 reaction + react_rocket = "<space>rr", -- add/remove 🚀 reaction + react_laugh = "<space>rl", -- add/remove 😄 reaction + react_confused = "<space>rc", -- add/remove 😕 reaction + }, + pull_request = { + checkout_pr = "<space>po", -- checkout PR + merge_pr = "<space>pm", -- merge PR + list_commits = "<space>pc", -- list PR commits + list_changed_files = "<space>pf", -- list PR changed files + show_pr_diff = "<space>pd", -- show PR diff + add_reviewer = "<space>va", -- add reviewer + remove_reviewer = "<space>vd", -- remove reviewer request + close_issue = "<space>ic", -- close PR + reopen_issue = "<space>io", -- reopen PR + list_issues = "<space>il", -- list open issues on same repo + reload = "<C-r>", -- reload PR + open_in_browser = "<C-b>", -- open PR in browser + copy_url = "<C-y>", -- copy url to system clipboard + add_assignee = "<space>aa", -- add assignee + remove_assignee = "<space>ad", -- remove assignee + create_label = "<space>lc", -- create label + add_label = "<space>la", -- add label + remove_label = "<space>ld", -- remove label + goto_issue = "<space>gi", -- navigate to a local repo issue + add_comment = "<space>ca", -- add comment + delete_comment = "<space>cd", -- delete comment + next_comment = "]c", -- go to next comment + prev_comment = "[c", -- go to previous comment + react_hooray = "<space>rp", -- add/remove 🎉 reaction + react_heart = "<space>rh", -- add/remove ❤️ reaction + react_eyes = "<space>re", -- add/remove 👀 reaction + react_thumbs_up = "<space>r+", -- add/remove 👍 reaction + react_thumbs_down = "<space>r-", -- add/remove 👎 reaction + react_rocket = "<space>rr", -- add/remove 🚀 reaction + react_laugh = "<space>rl", -- add/remove 😄 reaction + react_confused = "<space>rc", -- add/remove 😕 reaction + }, + review_thread = { + goto_issue = "<space>gi", -- navigate to a local repo issue + add_comment = "<space>ca", -- add comment + add_suggestion = "<space>sa", -- add suggestion + delete_comment = "<space>cd", -- delete comment + next_comment = "]c", -- go to next comment + prev_comment = "[c", -- go to previous comment + select_next_entry = "]q", -- move to previous changed file + select_prev_entry = "[q", -- move to next changed file + close_review_tab = "<C-c>", -- close review tab + react_hooray = "<space>rp", -- add/remove 🎉 reaction + react_heart = "<space>rh", -- add/remove ❤️ reaction + react_eyes = "<space>re", -- add/remove 👀 reaction + react_thumbs_up = "<space>r+", -- add/remove 👍 reaction + react_thumbs_down = "<space>r-", -- add/remove 👎 reaction + react_rocket = "<space>rr", -- add/remove 🚀 reaction + react_laugh = "<space>rl", -- add/remove 😄 reaction + react_confused = "<space>rc", -- add/remove 😕 reaction + }, + submit_win = { + approve_review = "<C-a>", -- approve review + comment_review = "<C-m>", -- comment review + request_changes = "<C-r>", -- request changes review + close_review_tab = "<C-c>", -- close review tab + }, + review_diff = { + add_review_comment = "<space>ca", -- add a new review comment + add_review_suggestion = "<space>sa", -- add a new review suggestion + focus_files = "<leader>e", -- move focus to changed file panel + toggle_files = "<leader>b", -- hide/show changed files panel + next_thread = "]t", -- move to next thread + prev_thread = "[t", -- move to previous thread + select_next_entry = "]q", -- move to previous changed file + select_prev_entry = "[q", -- move to next changed file + close_review_tab = "<C-c>", -- close review tab + toggle_viewed = "<leader><space>", -- toggle viewer viewed state + }, + file_panel = { + next_entry = "j", -- move to next changed file + prev_entry = "k", -- move to previous changed file + select_entry = "<cr>", -- show selected changed file diffs + refresh_files = "R", -- refresh changed files panel + focus_files = "<leader>e", -- move focus to changed file panel + toggle_files = "<leader>b", -- hide/show changed files panel + select_next_entry = "]q", -- move to previous changed file + select_prev_entry = "[q", -- move to next changed file + close_review_tab = "<C-c>", -- close review tab + toggle_viewed = "<leader><space>", -- toggle viewer viewed state + }, + }, + } +end + +return M diff --git a/.config/nvim/lua/extra/quickscope.lua b/.config/nvim/lua/extra/quickscope.lua new file mode 100644 index 0000000..99b4196 --- /dev/null +++ b/.config/nvim/lua/extra/quickscope.lua @@ -0,0 +1,3 @@ +vim.cmd [[ + let g:qs_highlight_on_keys = ['f', 'F', 't', 'T'] + ]] diff --git a/.config/nvim/lua/extra/spectre.lua b/.config/nvim/lua/extra/spectre.lua new file mode 100644 index 0000000..12133d8 --- /dev/null +++ b/.config/nvim/lua/extra/spectre.lua @@ -0,0 +1,144 @@ +local M = {} +local Log = require "core.log" + +M.config = function() + local status_ok, spectre = pcall(require, "spectre") + if not status_ok then + Log:get_default().error "Failed to load hop" + return + end + + spectre.setup { + + color_devicons = true, + highlight = { + ui = "String", + search = "DiffChange", + replace = "DiffDelete", + }, + mapping = { + ["toggle_line"] = { + map = "t", + cmd = "<cmd>lua require('spectre').toggle_line()<CR>", + desc = "toggle current item", + }, + ["enter_file"] = { + map = "<cr>", + cmd = "<cmd>lua require('spectre.actions').select_entry()<CR>", + desc = "goto current file", + }, + ["send_to_qf"] = { + map = "Q", + cmd = "<cmd>lua require('spectre.actions').send_to_qf()<CR>", + desc = "send all item to quickfix", + }, + ["replace_cmd"] = { + map = "c", + cmd = "<cmd>lua require('spectre.actions').replace_cmd()<CR>", + desc = "input replace vim command", + }, + ["show_option_menu"] = { + map = "o", + cmd = "<cmd>lua require('spectre').show_options()<CR>", + desc = "show option", + }, + ["run_replace"] = { + map = "R", + cmd = "<cmd>lua require('spectre.actions').run_replace()<CR>", + desc = "replace all", + }, + ["change_view_mode"] = { + map = "m", + cmd = "<cmd>lua require('spectre').change_view()<CR>", + desc = "change result view mode", + }, + ["toggle_ignore_case"] = { + map = "I", + cmd = "<cmd>lua require('spectre').change_options('ignore-case')<CR>", + desc = "toggle ignore case", + }, + ["toggle_ignore_hidden"] = { + map = "H", + cmd = "<cmd>lua require('spectre').change_options('hidden')<CR>", + desc = "toggle search hidden", + }, + -- you can put your mapping here it only use normal mode + }, + find_engine = { + -- rg is map with finder_cmd + ["rg"] = { + cmd = "rg", + -- default args + args = { + "--color=never", + "--no-heading", + "--with-filename", + "--line-number", + "--column", + }, + options = { + ["ignore-case"] = { + value = "--ignore-case", + icon = "[I]", + desc = "ignore case", + }, + ["hidden"] = { + value = "--hidden", + desc = "hidden file", + icon = "[H]", + }, + -- you can put any option you want here it can toggle with + -- show_option function + }, + }, + ["ag"] = { + cmd = "ag", + args = { + "--vimgrep", + "-s", + }, + options = { + ["ignore-case"] = { + value = "-i", + icon = "[I]", + desc = "ignore case", + }, + ["hidden"] = { + value = "--hidden", + desc = "hidden file", + icon = "[H]", + }, + }, + }, + }, + replace_engine = { + ["sed"] = { + cmd = "sed", + args = nil, + }, + options = { + ["ignore-case"] = { + value = "--ignore-case", + icon = "[I]", + desc = "ignore case", + }, + }, + }, + default = { + find = { + --pick one of item in find_engine + cmd = "rg", + options = { "ignore-case" }, + }, + replace = { + --pick one of item in replace_engine + cmd = "sed", + }, + }, + replace_vim_cmd = "cdo", + is_open_target_win = true, --open file on opener window + is_insert_mode = false, -- start open panel on is_insert_mode + } +end + +return M diff --git a/.config/nvim/lua/extra/twilight.lua b/.config/nvim/lua/extra/twilight.lua new file mode 100644 index 0000000..b76563a --- /dev/null +++ b/.config/nvim/lua/extra/twilight.lua @@ -0,0 +1,30 @@ +local M = {} +local Log = require "core.log" + +M.config = function() + local status_ok, twilight = pcall(require, "twilight") + if not status_ok then + Log:get_default().error "Failed to load twilight" + return + end + + twilight.setup { + dimming = { + alpha = 0.25, -- amount of dimming + -- we try to get the foreground from the highlight groups or fallback color + color = { "Normal", "#ffffff" }, + }, + context = 15, -- amount of lines we will try to show around the current line + -- treesitter is used to automatically expand the visible text, + -- but you can further control the types of nodes that should always be fully expanded + expand = { + "function", + "method", + "table", + "if_statement", + }, + exclude = {}, -- exclude these filetypes + } +end + +return M diff --git a/.config/nvim/lua/core/zen.lua b/.config/nvim/lua/extra/zen.lua index 99a5d76..9bfaf1a 100644 --- a/.config/nvim/lua/core/zen.lua +++ b/.config/nvim/lua/extra/zen.lua @@ -1,9 +1,18 @@ local M = {} +local Log = require "core.log" + M.config = function() - O.plugin["zen"] = { + local status_ok, zen_mode = pcall(require, "zen-mode") + if not status_ok then + Log:get_default().error "Failed to load zen-mode" + return + end + + zen_mode.setup { window = { backdrop = 1, - height = 0.85, -- height of the Zen window + height = 0.9, -- height of the Zen window + width = 0.65, options = { signcolumn = "no", -- disable signcolumn number = false, -- disable number column @@ -16,19 +25,24 @@ M.config = function() }, plugins = { gitsigns = { enabled = false }, -- disables git signs - -- your configuration comes here - -- or leave it empty to use the default settings - -- refer to the configuration section below + tmux = { enabled = true }, + twilight = { enabled = true }, }, + -- on_open = function() + -- vim.lsp.diagnostic.disable() + -- vim.cmd [[ + -- set foldlevel=10 + -- IndentBlanklineDisable + -- ]] + -- end, + -- on_close = function() + -- vim.lsp.diagnostic.enable() + -- vim.cmd [[ + -- set foldlevel=5 + -- IndentBlanklineEnable + -- ]] + -- end, } end -M.setup = function() - local status_ok, zen_mode = pcall(require, "zen-mode") - if not status_ok then - return - end - zen_mode.setup(O.plugin.zen) -end - return M diff --git a/.config/nvim/lua/keymappings.lua b/.config/nvim/lua/keymappings.lua index e8e3f42..c76d0e8 100644 --- a/.config/nvim/lua/keymappings.lua +++ b/.config/nvim/lua/keymappings.lua @@ -1,115 +1,171 @@ -local utils = require "utils" - -local opts = { - nnoremap = { noremap = true, silent = true }, - inoremap = { noremap = true, silent = true }, - vnoremap = { noremap = true, silent = true }, - xnoremap = { noremap = true, silent = true }, - generic = { silent = true }, +local M = {} + +local generic_opts_any = { noremap = true, silent = true } + +local generic_opts = { + insert_mode = generic_opts_any, + normal_mode = generic_opts_any, + visual_mode = generic_opts_any, + visual_block_mode = generic_opts_any, + term_mode = { silent = true }, } -local default_keys = { - insert_mode = { - -- I hate escape - { "jk", "<ESC>" }, - { "kj", "<ESC>" }, - { "jj", "<ESC>" }, - -- Move current line / block with Alt-j/k ala vscode. - { "<A-j>", "<Esc>:m .+1<CR>==gi" }, - { "<A-k>", "<Esc>:m .-2<CR>==gi" }, - -- navigation - { "<A-Up>", "<C-\\><C-N><C-w>h" }, - { "<A-Down>", "<C-\\><C-N><C-w>j" }, - { "<A-Left>", "<C-\\><C-N><C-w>k" }, - { "<A-Right>", "<C-\\><C-N><C-w>l" }, - }, - - normal_mode = { - -- Better window movement - { "<C-h>", "<C-w>h" }, - { "<C-j>", "<C-w>j" }, - { "<C-k>", "<C-w>k" }, - { "<C-l>", "<C-w>l" }, - - -- Resize with arrows - { "<C-Up>", ":resize -2<CR>" }, - { "<C-Down>", ":resize +2<CR>" }, - { "<C-Left>", ":vertical resize -2<CR>" }, - { "<C-Right>", ":vertical resize +2<CR>" }, - - -- Tab switch buffer - -- { "<TAB>", ":bnext<CR>" }, - -- { "<S-TAB>", ":bprevious<CR>" }, - - -- Move current line / block with Alt-j/k a la vscode. - { "<A-j>", ":m .+1<CR>==" }, - { "<A-k>", ":m .-2<CR>==" }, - - -- QuickFix - { "]q", ":cnext<CR>" }, - { "[q", ":cprev<CR>" }, - { "<C-q>", ":call QuickFixToggle()<CR>" }, - - -- {'<C-TAB>', 'compe#complete()', {noremap = true, silent = true, expr = true}}, - }, - - term_mode = { - -- Terminal window navigation - { "<C-h>", "<C-\\><C-N><C-w>h" }, - { "<C-j>", "<C-\\><C-N><C-w>j" }, - { "<C-k>", "<C-\\><C-N><C-w>k" }, - { "<C-l>", "<C-\\><C-N><C-w>l" }, - }, - - visual_mode = { - -- Better indenting - { "<", "<gv" }, - { ">", ">gv" }, - - -- { "p", '"0p', { silent = true } }, - -- { "P", '"0P', { silent = true } }, - }, - - visual_block_mode = { - -- Move selected line / block of text in visual mode - { "K", ":move '<-2<CR>gv-gv" }, - { "J", ":move '>+1<CR>gv-gv" }, - - -- Move current line / block with Alt-j/k ala vscode. - { "<A-j>", ":m '>+1<CR>gv-gv" }, - { "<A-k>", ":m '<-2<CR>gv-gv" }, - }, +local mode_adapters = { + insert_mode = "i", + normal_mode = "n", + term_mode = "t", + visual_mode = "v", + visual_block_mode = "x", } -if vim.fn.has "mac" == 1 then - -- TODO: fix this - default_keys.normal_mode[5][1] = "<A-Up>" - default_keys.normal_mode[6][1] = "<A-Down>" - default_keys.normal_mode[7][1] = "<A-Left>" - default_keys.normal_mode[8][1] = "<A-Right>" +-- Append key mappings to lunarvim's defaults for a given mode +-- @param keymaps The table of key mappings containing a list per mode (normal_mode, insert_mode, ..) +function M.append_to_defaults(keymaps) + for mode, mappings in pairs(keymaps) do + for k, v in ipairs(mappings) do + options.keys[mode][k] = v + end + end +end + +-- Set key mappings individually +-- @param mode The keymap mode, can be one of the keys of mode_adapters +-- @param key The key of keymap +-- @param val Can be form as a mapping or tuple of mapping and user defined opt +function M.set_keymaps(mode, key, val) + local opt = generic_opts[mode] and generic_opts[mode] or generic_opts_any + if type(val) == "table" then + opt = val[2] + val = val[1] + end + vim.api.nvim_set_keymap(mode, key, val, opt) +end + +-- Load key mappings for a given mode +-- @param mode The keymap mode, can be one of the keys of mode_adapters +-- @param keymaps The list of key mappings +function M.load_mode(mode, keymaps) + mode = mode_adapters[mode] and mode_adapters[mode] or mode + for k, v in pairs(keymaps) do + M.set_keymaps(mode, k, v) + end end -if O.keys.leader_key == " " or O.keys.leader_key == "space" then - vim.g.mapleader = " " -else - vim.g.mapleader = O.keys.leader_key +-- Load key mappings for all provided modes +-- @param keymaps A list of key mappings for each mode +function M.load(keymaps) + for mode, mapping in pairs(keymaps) do + M.load_mode(mode, mapping) + end end -local function get_user_keys(mode) - if O.keys[mode] == nil then - return default_keys[mode] +function M.config() + options.keys = { + ---@usage change or add keymappings for insert mode + insert_mode = { + -- 'jk' for quitting insert mode + ["jk"] = "<ESC>", + -- 'kj' for quitting insert mode + ["kj"] = "<ESC>", + -- 'jj' for quitting insert mode + ["jj"] = "<ESC>", + -- Move current line / block with Alt-j/k ala vscode. + ["<A-j>"] = "<Esc>:m .+1<CR>==gi", + -- Move current line / block with Alt-j/k ala vscode. + ["<A-k>"] = "<Esc>:m .-2<CR>==gi", + -- navigation + ["<A-Up>"] = "<C-\\><C-N><C-w>k", + ["<A-Down>"] = "<C-\\><C-N><C-w>j", + ["<A-Left>"] = "<C-\\><C-N><C-w>h", + ["<A-Right>"] = "<C-\\><C-N><C-w>l", + -- navigate tab completion with <c-j> and <c-k> + -- runs conditionally + ["<C-j>"] = { 'pumvisible() ? "\\<C-n>" : "\\<C-j>"', { expr = true, noremap = true } }, + ["<C-k>"] = { 'pumvisible() ? "\\<C-p>" : "\\<C-k>"', { expr = true, noremap = true } }, + }, + + ---@usage change or add keymappings for normal mode + normal_mode = { + -- Better window movement + ["<C-h>"] = "<C-w>h", + ["<C-j>"] = "<C-w>j", + ["<C-k>"] = "<C-w>k", + ["<C-l>"] = "<C-w>l", + + -- Resize with arrows + ["<C-Up>"] = ":resize -2<CR>", + ["<C-Down>"] = ":resize +2<CR>", + ["<C-Left>"] = ":vertical resize -2<CR>", + ["<C-Right>"] = ":vertical resize +2<CR>", + + -- Tab switch buffer + ["<S-l>"] = ":BufferNext<CR>", + ["<S-h>"] = ":BufferPrevious<CR>", + + -- Move current line / block with Alt-j/k a la vscode. + ["<A-j>"] = ":m .+1<CR>==", + ["<A-k>"] = ":m .-2<CR>==", + + -- QuickFix + ["]q"] = ":cnext<CR>", + ["[q"] = ":cprev<CR>", + ["<C-q>"] = ":call QuickFixToggle()<CR>", + }, + + ---@usage change or add keymappings for terminal mode + term_mode = { + -- Terminal window navigation + ["<C-h>"] = "<C-\\><C-N><C-w>h", + ["<C-j>"] = "<C-\\><C-N><C-w>j", + ["<C-k>"] = "<C-\\><C-N><C-w>k", + ["<C-l>"] = "<C-\\><C-N><C-w>l", + }, + + ---@usage change or add keymappings for visual mode + visual_mode = { + -- Better indenting + ["<"] = "<gv", + [">"] = ">gv", + + -- ["p"] = '"0p', + -- ["P"] = '"0P', + }, + + ---@usage change or add keymappings for visual block mode + visual_block_mode = { + -- Move selected line / block of text in visual mode + ["K"] = ":move '<-2<CR>gv-gv", + ["J"] = ":move '>+1<CR>gv-gv", + + -- Move current line / block with Alt-j/k ala vscode. + ["<A-j>"] = ":m '>+1<CR>gv-gv", + ["<A-k>"] = ":m '<-2<CR>gv-gv", + }, + } + + if vim.fn.has "mac" == 1 then + lvim.keys.normal_mode["<A-Up>"] = lvim.keys.normal_mode["<C-Up>"] + lvim.keys.normal_mode["<A-Down>"] = lvim.keys.normal_mode["<C-Down>"] + lvim.keys.normal_mode["<A-Left>"] = lvim.keys.normal_mode["<C-Left>"] + lvim.keys.normal_mode["<A-Right>"] = lvim.keys.normal_mode["<C-Right>"] + if Log:get_default() then + Log:get_default().info "Activated mac keymappings" + end + end +end + +function M.print(mode) + print "List of LunarVim's default keymappings (not including which-key)" + if mode then + print(vim.inspect(options.keys[mode])) else - return O.keys[mode] + print(vim.inspect(options.keys)) end end -utils.add_keymap_normal_mode(opts.nnoremap, get_user_keys "normal_mode") -utils.add_keymap_insert_mode(opts.inoremap, get_user_keys "insert_mode") -utils.add_keymap_visual_mode(opts.vnoremap, get_user_keys "visual_mode") -utils.add_keymap_visual_block_mode(opts.xnoremap, get_user_keys "visual_block_mode") -utils.add_keymap_term_mode(opts.generic, get_user_keys "term_mode") +function M.setup() + vim.g.mapleader = (options.leader == "space" and " ") or options.leader + M.load(options.keys) +end --- navigate tab completion with <c-j> and <c-k> --- runs conditionally -vim.cmd 'inoremap <expr> <C-j> pumvisible() ? "\\<C-n>" : "\\<C-j>"' -vim.cmd 'inoremap <expr> <C-k> pumvisible() ? "\\<C-p>" : "\\<C-k>"' +return M diff --git a/.config/nvim/lua/lang/clang.lua b/.config/nvim/lua/lang/clang.lua deleted file mode 100644 index 702d6f4..0000000 --- a/.config/nvim/lua/lang/clang.lua +++ /dev/null @@ -1,156 +0,0 @@ -local M = {} - -M.config = function() - O.lang.clang = { - diagnostics = { - virtual_text = { spacing = 0, prefix = "" }, - signs = true, - underline = true, - }, - cross_file_rename = true, - header_insertion = "never", - filetypes = { "c", "cpp", "objc" }, - formatter = { - exe = "clang-format", - args = {}, - stdin = true, - }, - linters = { - "cppcheck", - "clangtidy", - }, - debug = { - adapter = { - command = "/usr/bin/lldb-vscode", - }, - stop_on_entry = false, - }, - } -end - -M.format = function() - local shared_config = { - function() - return { - exe = O.lang.clang.formatter.exe, - args = O.lang.clang.formatter.args, - stdin = O.lang.clang.formatter.stdin, - cwd = vim.fn.expand "%:h:p", - } - end, - } - O.formatters.filetype["c"] = shared_config - O.formatters.filetype["cpp"] = shared_config - O.formatters.filetype["objc"] = shared_config - - require("formatter.config").set_defaults { - logging = false, - filetype = O.formatters.filetype, - } -end - -M.lint = function() - require("lint").linters_by_ft = { - c = O.lang.clang.linters, - cpp = O.lang.clang.linters, - } -end - -M.lsp = function() - if require("utils").check_lsp_client_active "clangd" then - return - end - local clangd_flags = { "--background-index" } - - if O.lang.clang.cross_file_rename then - table.insert(clangd_flags, "--cross-file-rename") - end - - table.insert(clangd_flags, "--header-insertion=" .. O.lang.clang.header_insertion) - - require("lspconfig").clangd.setup { - cmd = { DATA_PATH .. "/lspinstall/cpp/clangd/bin/clangd", unpack(clangd_flags) }, - on_attach = require("lsp").common_on_attach, - handlers = { - ["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { - virtual_text = O.lang.clang.diagnostics.virtual_text, - signs = O.lang.clang.diagnostics.signs, - underline = O.lang.clang.diagnostics.underline, - update_in_insert = true, - }), - }, - } -end - -M.dap = function() - if O.plugin.dap.active then - local dap_install = require "dap-install" - local dap = require "dap" - dap_install.config("ccppr_vsc_dbg", {}) - dap.adapters.lldb = { - type = "executable", - command = O.lang.clang.debug.adapter.command, - name = "lldb", - } - local shared_dap_config = { - { - name = "Launch", - type = "lldb", - request = "launch", - program = function() - return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/", "file") - end, - cwd = "${workspaceFolder}", - stopOnEntry = O.lang.clang.debug.stop_on_entry, - args = {}, - env = function() - local variables = {} - for k, v in pairs(vim.fn.environ()) do - table.insert(variables, string.format("%s=%s", k, v)) - end - return variables - end, - runInTerminal = false, - }, - { - -- If you get an "Operation not permitted" error using this, try disabling YAMA: - -- echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope - name = "Attach to process", - type = "lldb", -- Adjust this to match your adapter name (`dap.adapters.<name>`) - request = "attach", - pid = function() - local output = vim.fn.system { "ps", "a" } - local lines = vim.split(output, "\n") - local procs = {} - for _, line in pairs(lines) do - -- output format - -- " 107021 pts/4 Ss 0:00 /bin/zsh <args>" - local parts = vim.fn.split(vim.fn.trim(line), " \\+") - local pid = parts[1] - local name = table.concat({ unpack(parts, 5) }, " ") - if pid and pid ~= "PID" then - pid = tonumber(pid) - if pid ~= vim.fn.getpid() then - table.insert(procs, { pid = tonumber(pid), name = name }) - end - end - end - local choices = { "Select process" } - for i, proc in ipairs(procs) do - table.insert(choices, string.format("%d: pid=%d name=%s", i, proc.pid, proc.name)) - end - local choice = vim.fn.inputlist(choices) - if choice < 1 or choice > #procs then - return nil - end - return procs[choice].pid - end, - args = {}, - }, - } - dap.configurations.c = shared_dap_config - dap.configurations.cpp = shared_dap_config - end -end - -return M diff --git a/.config/nvim/lua/lang/dart.lua b/.config/nvim/lua/lang/dart.lua deleted file mode 100644 index 2ed5c33..0000000 --- a/.config/nvim/lua/lang/dart.lua +++ /dev/null @@ -1,59 +0,0 @@ -local M = {} - -M.config = function() - O.lang.dart = { - sdk_path = "/usr/lib/dart/bin/snapshots/analysis_server.dart.snapshot", - formatter = { - exe = "dart", - args = { "format" }, - stdin = true, - }, - } -end - -M.format = function() - O.formatters.filetype["dart"] = { - function() - return { - exe = O.lang.dart.formatter.exe, - args = O.lang.dart.formatter.args, - stdin = O.lang.dart.formatter.stdin, - } - end, - } - - require("formatter.config").set_defaults { - logging = false, - filetype = O.formatters.filetype, - } -end - -M.lint = function() - -- TODO: implement linters (if applicable) - return "No linters configured!" -end - -M.lsp = function() - if require("utils").check_lsp_client_active "dartls" then - return - end - - require("lspconfig").dartls.setup { - cmd = { "dart", O.lang.dart.sdk_path, "--lsp" }, - on_attach = require("lsp").common_on_attach, - init_options = { - closingLabels = false, - flutterOutline = false, - onlyAnalyzeProjectsWithOpenFiles = false, - outline = false, - suggestFromUnimportedLibraries = true, - }, - } -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/dockerfile.lua b/.config/nvim/lua/lang/dockerfile.lua deleted file mode 100644 index 0009c30..0000000 --- a/.config/nvim/lua/lang/dockerfile.lua +++ /dev/null @@ -1,35 +0,0 @@ -local M = {} - -M.config = function() - O.lang.docker = {} -end - -M.format = function() - -- TODO: implement formatter for language - return "No formatter available!" -end - -M.lint = function() - -- TODO: implement linters (if applicable) - return "No linters configured!" -end - -M.lsp = function() - if require("utils").check_lsp_client_active "dockerls" then - return - end - - -- npm install -g dockerfile-language-server-nodejs - require("lspconfig").dockerls.setup { - cmd = { DATA_PATH .. "/lspinstall/dockerfile/node_modules/.bin/docker-langserver", "--stdio" }, - on_attach = require("lsp").common_on_attach, - root_dir = vim.loop.cwd, - } -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/elixir.lua b/.config/nvim/lua/lang/elixir.lua deleted file mode 100644 index 0959809..0000000 --- a/.config/nvim/lua/lang/elixir.lua +++ /dev/null @@ -1,61 +0,0 @@ -local M = {} - -M.config = function() - O.lang.elixir = { - formatter = { - exe = "mix", - args = { "format" }, - stdin = true, - }, - lsp = { - path = DATA_PATH .. "/lspinstall/elixir/elixir-ls/language_server.sh", - }, - } -end - -M.format = function() - O.formatters.filetype["elixir"] = { - function() - return { - exe = O.lang.elixir.formatter.exe, - args = O.lang.elixir.formatter.args, - stdin = O.lang.elixir.formatter.stdin, - } - end, - } - - require("formatter.config").set_defaults { - logging = false, - filetype = O.formatters.filetype, - } -end - -M.lint = function() - -- TODO: implement linters (if applicable) - return "No linters configured!" -end - -M.lsp = function() - if require("utils").check_lsp_client_active "elixirls" then - return - end - - require("lspconfig").elixirls.setup { - cmd = { O.lang.elixir.lsp.path }, - on_attach = require("lsp").common_on_attach, - } -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - --- needed for the LSP to recognize elixir files (alternativly just use elixir-editors/vim-elixir) --- vim.cmd [[ --- au BufRead,BufNewFile *.ex,*.exs set filetype=elixir --- au BufRead,BufNewFile *.eex,*.leex,*.sface set filetype=eelixir --- au BufRead,BufNewFile mix.lock set filetype=elixir --- ]] - -return M diff --git a/.config/nvim/lua/lang/go.lua b/.config/nvim/lua/lang/go.lua deleted file mode 100644 index 880e56d..0000000 --- a/.config/nvim/lua/lang/go.lua +++ /dev/null @@ -1,57 +0,0 @@ -local M = {} - -M.config = function() - O.lang.go = { - formatter = { - exe = "gofmt", - args = {}, - stdin = true, - }, - linters = { - "golangcilint", - "revive", - }, - } -end - -M.format = function() - O.formatters.filetype["go"] = { - function() - return { - exe = O.lang.go.formatter.exe, - args = O.lang.go.formatter.args, - stdin = O.lang.go.formatter.stdin, - } - end, - } - - require("formatter.config").set_defaults { - logging = false, - filetype = O.formatters.filetype, - } -end - -M.lint = function() - require("lint").linters_by_ft = { - go = O.lang.go.linters, - } -end - -M.lsp = function() - if not require("utils").check_lsp_client_active "gopls" then - require("lspconfig").gopls.setup { - cmd = { DATA_PATH .. "/lspinstall/go/gopls" }, - settings = { gopls = { analyses = { unusedparams = true }, staticcheck = true } }, - root_dir = require("lspconfig").util.root_pattern(".git", "go.mod"), - init_options = { usePlaceholders = true, completeUnimported = true }, - on_attach = require("lsp").common_on_attach, - } - end -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/graphql.lua b/.config/nvim/lua/lang/graphql.lua deleted file mode 100644 index a3425a0..0000000 --- a/.config/nvim/lua/lang/graphql.lua +++ /dev/null @@ -1,31 +0,0 @@ -local M = {} - -M.config = function() - O.lang.graphql = {} -end - -M.format = function() - -- TODO: implement formatter for language - return "No formatter available!" -end - -M.lint = function() - -- TODO: implement linters (if applicable) - return "No linters configured!" -end - -M.lsp = function() - if require("utils").check_lsp_client_active "graphql" then - return - end - - -- npm install -g graphql-language-service-cli - require("lspconfig").graphql.setup { on_attach = require("lsp").common_on_attach } -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/html.lua b/.config/nvim/lua/lang/html.lua deleted file mode 100644 index d5a02b6..0000000 --- a/.config/nvim/lua/lang/html.lua +++ /dev/null @@ -1,47 +0,0 @@ -local M = {} - -M.config = function() - O.lang.html = { - linters = { - "tidy", - -- https://docs.errata.ai/vale/scoping#html - "vale", - }, - } -end - -M.format = function() - -- TODO: implement formatters (if applicable) - return "No formatters configured!" -end - -M.lint = function() - require("lint").linters_by_ft = { - html = O.lang.html.linters, - } -end - -M.lsp = function() - if not require("utils").check_lsp_client_active "html" then - -- npm install -g vscode-html-languageserver-bin - local capabilities = vim.lsp.protocol.make_client_capabilities() - capabilities.textDocument.completion.completionItem.snippetSupport = true - - require("lspconfig").html.setup { - cmd = { - "node", - DATA_PATH .. "/lspinstall/html/vscode-html/html-language-features/server/dist/node/htmlServerMain.js", - "--stdio", - }, - on_attach = require("lsp").common_on_attach, - capabilities = capabilities, - } - end -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/javascript.lua b/.config/nvim/lua/lang/javascript.lua deleted file mode 100644 index 178c6f5..0000000 --- a/.config/nvim/lua/lang/javascript.lua +++ /dev/null @@ -1,25 +0,0 @@ -local M = {} - -M.config = function() - -- TODO: implement config for language - return "No config available!" -end - -M.format = function() - -- TODO: implement formatter for language - return "No formatter available!" -end - -M.lint = function() - -- TODO: implement linters (if applicable) - return "No linters configured!" -end - -M.lsp = function() end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/javascriptreact.lua b/.config/nvim/lua/lang/javascriptreact.lua deleted file mode 100644 index 178c6f5..0000000 --- a/.config/nvim/lua/lang/javascriptreact.lua +++ /dev/null @@ -1,25 +0,0 @@ -local M = {} - -M.config = function() - -- TODO: implement config for language - return "No config available!" -end - -M.format = function() - -- TODO: implement formatter for language - return "No formatter available!" -end - -M.lint = function() - -- TODO: implement linters (if applicable) - return "No linters configured!" -end - -M.lsp = function() end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/json.lua b/.config/nvim/lua/lang/json.lua deleted file mode 100644 index 78bf669..0000000 --- a/.config/nvim/lua/lang/json.lua +++ /dev/null @@ -1,69 +0,0 @@ -local M = {} - -M.config = function() - O.lang.json = { - diagnostics = { - virtual_text = { spacing = 0, prefix = "" }, - signs = true, - underline = true, - }, - formatter = { - exe = "python", - args = { "-m", "json.tool" }, - stdin = true, - }, - } -end - -M.format = function() - O.formatters.filetype["json"] = { - function() - return { - exe = O.lang.json.formatter.exe, - args = O.lang.json.formatter.args, - stdin = O.lang.json.formatter.stdin, - } - end, - } - - require("formatter.config").set_defaults { - logging = false, - filetype = O.formatters.filetype, - } -end - -M.lint = function() - -- TODO: implement linters (if applicable) - return "No linters configured!" -end - -M.lsp = function() - if require("utils").check_lsp_client_active "jsonls" then - return - end - - -- npm install -g vscode-json-languageserver - require("lspconfig").jsonls.setup { - cmd = { - "node", - DATA_PATH .. "/lspinstall/json/vscode-json/json-language-features/server/dist/node/jsonServerMain.js", - "--stdio", - }, - on_attach = require("lsp").common_on_attach, - - commands = { - Format = { - function() - vim.lsp.buf.range_formatting({}, { 0, 0 }, { vim.fn.line "$", 0 }) - end, - }, - }, - } -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/kotlin.lua b/.config/nvim/lua/lang/kotlin.lua deleted file mode 100644 index 3fe1dc9..0000000 --- a/.config/nvim/lua/lang/kotlin.lua +++ /dev/null @@ -1,63 +0,0 @@ -local M = {} - -M.config = function() - O.lang.kotlin = {} -end - -M.format = function() - -- TODO: implement formatter for language - return "No formatter available!" -end - -M.lint = function() - -- TODO: implement linters (if applicable) - return "No linters configured!" -end - -M.lsp = function() - if require("utils").check_lsp_client_active "kotlin_language_server" then - return - end - - --- default config for gradle-projects of the - --- kotlin-language-server: https://github.com/fwcd/kotlin-language-server - --- - --- This server requires vim to be aware of the kotlin-filetype. - --- You could refer for this capability to: - --- https://github.com/udalov/kotlin-vim (recommended) - --- Note that there is no LICENSE specified yet. - - local util = require "lspconfig/util" - - local bin_name = DATA_PATH .. "/lspinstall/kotlin/server/bin/kotlin-language-server" - if vim.fn.has "win32" == 1 then - bin_name = bin_name .. ".bat" - end - - local root_files = { - "settings.gradle", -- Gradle (multi-project) - "settings.gradle.kts", -- Gradle (multi-project) - "build.xml", -- Ant - "pom.xml", -- Maven - } - - local fallback_root_files = { - "build.gradle", -- Gradle - "build.gradle.kts", -- Gradle - } - - require("lspconfig").kotlin_language_server.setup { - cmd = { bin_name }, - on_attach = require("lsp").common_on_attach, - root_dir = function(fname) - return util.root_pattern(unpack(root_files))(fname) or util.root_pattern(unpack(fallback_root_files))(fname) - end, - } -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/lua.lua b/.config/nvim/lua/lang/lua.lua deleted file mode 100644 index c7305d0..0000000 --- a/.config/nvim/lua/lang/lua.lua +++ /dev/null @@ -1,88 +0,0 @@ - -local M = {} - -M.config = function() - O.lang.lua = { - diagnostics = { - virtual_text = { spacing = 0, prefix = "" }, - signs = true, - underline = true, - }, - formatter = { - exe = "stylua", - args = {}, - stdin = false, - }, - linters = { "luacheck" }, - lsp = { - path = DATA_PATH .. "/lspinstall/lua/sumneko-lua-language-server", - }, - } -end - -M.format = function() - O.formatters.filetype["lua"] = { - function() - return { - exe = O.lang.lua.formatter.exe, - args = O.lang.lua.formatter.args, - stdin = O.lang.lua.formatter.stdin, - tempfile_prefix = ".formatter", - } - end, - } - - require("formatter.config").set_defaults { - logging = false, - filetype = O.formatters.filetype, - } -end - -M.lint = function() - require("lint").linters_by_ft = { - lua = O.lang.lua.linters, - } -end - -M.lsp = function() - if not require("utils").check_lsp_client_active "sumneko_lua" then - -- https://github.com/sumneko/lua-language-server/wiki/Build-and-Run-(Standalone) - local sumneko_root_path = DATA_PATH .. "/lspinstall/lua" - local sumneko_binary = sumneko_root_path .. "/sumneko-lua-language-server" - - require("lspconfig").sumneko_lua.setup { - cmd = { sumneko_binary, "-E", sumneko_root_path .. "/main.lua" }, - on_attach = require("lsp").common_on_attach, - 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 = vim.split(package.path, ";"), - }, - diagnostics = { - -- Get the language server to recognize the `vim` global - globals = { "vim", "O" }, - }, - workspace = { - -- Make the server aware of Neovim runtime files - library = { - [vim.fn.expand "$VIMRUNTIME/lua"] = true, - [vim.fn.expand "$VIMRUNTIME/lua/vim/lsp"] = true, - }, - maxPreload = 100000, - preloadFileSize = 1000, - }, - }, - }, - } - end -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/python.lua b/.config/nvim/lua/lang/python.lua deleted file mode 100644 index b421e82..0000000 --- a/.config/nvim/lua/lang/python.lua +++ /dev/null @@ -1,92 +0,0 @@ -local M = {} - -M.config = function() - O.lang.python = { - -- @usage can be flake8 or yapf - linter = "", - isort = false, - diagnostics = { - virtual_text = { spacing = 0, prefix = "" }, - signs = true, - underline = true, - }, - analysis = { - type_checking = "basic", - auto_search_paths = true, - use_library_code_types = true, - }, - formatter = { - exe = "yapf", - args = {}, - stdin = true, - }, - linters = { - "flake8", - "pylint", - "mypy", - }, - } -end - -M.format = function() - O.formatters.filetype["python"] = { - function() - return { - exe = O.lang.python.formatter.exe, - args = O.lang.python.formatter.args, - stdin = O.lang.python.formatter.stdin, - } - end, - } - - require("formatter.config").set_defaults { - logging = false, - filetype = O.formatters.filetype, - } -end - -M.lint = function() - require("lint").linters_by_ft = { - python = O.lang.python.linters, - } -end - -M.lsp = function() - if require("utils").check_lsp_client_active "pyright" then - return - end - -- npm i -g pyright - require("lspconfig").pyright.setup { - cmd = { - DATA_PATH .. "/lspinstall/python/node_modules/.bin/pyright-langserver", - "--stdio", - }, - on_attach = require("lsp").common_on_attach, - handlers = { - ["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { - virtual_text = O.lang.python.diagnostics.virtual_text, - signs = O.lang.python.diagnostics.signs, - underline = O.lang.python.diagnostics.underline, - update_in_insert = true, - }), - }, - settings = { - python = { - analysis = { - typeCheckingMode = O.lang.python.analysis.type_checking, - autoSearchPaths = O.lang.python.analysis.auto_search_paths, - useLibraryCodeForTypes = O.lang.python.analysis.use_library_code_types, - }, - }, - }, - } -end - -M.dap = function() - if O.plugin.dap.active then - local dap_install = require "dap-install" - dap_install.config("python_dbg", {}) - end -end - -return M diff --git a/.config/nvim/lua/lang/rust.lua b/.config/nvim/lua/lang/rust.lua deleted file mode 100644 index 8726059..0000000 --- a/.config/nvim/lua/lang/rust.lua +++ /dev/null @@ -1,152 +0,0 @@ -local M = {} - -M.config = function() - O.lang.rust = { - rust_tools = { - active = false, - parameter_hints_prefix = "<-", - other_hints_prefix = "=>", -- prefix for all the other hints (type, chaining) - }, - -- @usage can be clippy - formatter = { - exe = "rustfmt", - args = { "--emit=stdout", "--edition=2018" }, - stdin = true, - }, - linter = "", - diagnostics = { - virtual_text = { spacing = 0, prefix = "" }, - signs = true, - underline = true, - }, - } -end - -M.format = function() - O.formatters.filetype["rust"] = { - function() - return { - exe = O.lang.rust.formatter.exe, - args = O.lang.rust.formatter.args, - stdin = O.lang.rust.formatter.stdin, - } - end, - } - - require("formatter.config").set_defaults { - logging = false, - filetype = O.formatters.filetype, - } -end - -M.lint = function() - -- TODO: implement linters (if applicable) - return "No linters configured!" -end - -M.lsp = function() - if require("utils").check_lsp_client_active "rust_analyzer" then - return - end - - if O.lang.rust.rust_tools.active then - local opts = { - tools = { -- rust-tools options - -- automatically set inlay hints (type hints) - -- There is an issue due to which the hints are not applied on the first - -- opened file. For now, write to the file to trigger a reapplication of - -- the hints or just run :RustSetInlayHints. - -- default: true - autoSetHints = true, - - -- whether to show hover actions inside the hover window - -- this overrides the default hover handler - -- default: true - hover_with_actions = true, - - runnables = { - -- whether to use telescope for selection menu or not - -- default: true - use_telescope = true, - - -- rest of the opts are forwarded to telescope - }, - - inlay_hints = { - -- wheter to show parameter hints with the inlay hints or not - -- default: true - show_parameter_hints = true, - - -- prefix for parameter hints - -- default: "<-" - parameter_hints_prefix = O.lang.rust.rust_tools.parameter_hints_prefix, - - -- prefix for all the other hints (type, chaining) - -- default: "=>" - other_hints_prefix = O.lang.rust.rust_tools.other_hints_prefix, - - -- whether to align to the lenght of the longest line in the file - max_len_align = false, - - -- padding from the left if max_len_align is true - max_len_align_padding = 1, - - -- whether to align to the extreme right or not - right_align = false, - - -- padding from the right if right_align is true - right_align_padding = 7, - }, - - hover_actions = { - -- the border that is used for the hover window - -- see vim.api.nvim_open_win() - border = { - { "╭", "FloatBorder" }, - { "─", "FloatBorder" }, - { "╮", "FloatBorder" }, - { "│", "FloatBorder" }, - { "╯", "FloatBorder" }, - { "─", "FloatBorder" }, - { "╰", "FloatBorder" }, - { "│", "FloatBorder" }, - }, - }, - }, - - -- all the opts to send to nvim-lspconfig - -- these override the defaults set by rust-tools.nvim - -- see https://github.com/neovim/nvim-lspconfig/blob/master/CONFIG.md#rust_analyzer - server = { - cmd = { DATA_PATH .. "/lspinstall/rust/rust-analyzer" }, - on_attach = require("lsp").common_on_attach, - }, -- rust-analyser options - } - require("rust-tools").setup(opts) - else - require("lspconfig").rust_analyzer.setup { - cmd = { DATA_PATH .. "/lspinstall/rust/rust-analyzer" }, - on_attach = require("lsp").common_on_attach, - filetypes = { "rust" }, - root_dir = require("lspconfig.util").root_pattern("Cargo.toml", "rust-project.json"), - } - end - - -- TODO: fix these mappings - vim.api.nvim_exec( - [[ - autocmd Filetype rust nnoremap <leader>lm <Cmd>RustExpandMacro<CR> - autocmd Filetype rust nnoremap <leader>lH <Cmd>RustToggleInlayHints<CR> - autocmd Filetype rust nnoremap <leader>le <Cmd>RustRunnables<CR> - autocmd Filetype rust nnoremap <leader>lh <Cmd>RustHoverActions<CR> - ]], - true - ) -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/sh.lua b/.config/nvim/lua/lang/sh.lua deleted file mode 100644 index 2301e44..0000000 --- a/.config/nvim/lua/lang/sh.lua +++ /dev/null @@ -1,62 +0,0 @@ -local M = {} - -M.config = function() - O.lang.sh = { - -- @usage can be 'shellcheck' - linter = "", - -- @usage can be 'shfmt' - diagnostics = { - virtual_text = { spacing = 0, prefix = "" }, - signs = true, - underline = true, - }, - formatter = { - exe = "shfmt", - args = { "-w" }, - stdin = false, - }, - linters = { "shellcheck" }, - } -end - -M.format = function() - O.formatters.filetype["sh"] = { - function() - return { - exe = O.lang.sh.formatter.exe, - args = O.lang.sh.formatter.args, - stdin = O.lang.sh.formatter.stdin, - tempfile_prefix = ".formatter", - } - end, - } - - require("formatter.config").set_defaults { - logging = false, - filetype = O.formatters.filetype, - } -end - -M.lint = function() - require("lint").linters_by_ft = { - sh = O.lang.sh.linters, - } -end - -M.lsp = function() - if not require("utils").check_lsp_client_active "bashls" then - -- npm i -g bash-language-server - require("lspconfig").bashls.setup { - cmd = { DATA_PATH .. "/lspinstall/bash/node_modules/.bin/bash-language-server", "start" }, - on_attach = require("lsp").common_on_attach, - filetypes = { "sh", "zsh" }, - } - end -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/swift.lua b/.config/nvim/lua/lang/swift.lua deleted file mode 100644 index 25c13f9..0000000 --- a/.config/nvim/lua/lang/swift.lua +++ /dev/null @@ -1,55 +0,0 @@ -local M = {} - -M.config = function() - O.lang.swift = { - formatter = { - exe = "swiftformat", - args = {}, - stdin = true, - }, - lsp = { - path = "sourcekit-lsp", - }, - } -end - -M.format = function() - -- TODO: implement formatter (if applicable) - return "No formatter configured!" -end - -M.lint = function() - O.formatters.filetype["swift"] = { - function() - return { - exe = O.lang.swift.formatter.exe, - args = O.lang.swift.formatter.args, - stdin = O.lang.swift.formatter.stdin, - } - end, - } - - require("formatter.config").set_defaults { - logging = false, - filetype = O.formatters.filetype, - } -end - -M.lsp = function() - if require("utils").check_lsp_client_active "sourcekit" then - return - end - - require("lspconfig").sourcekit.setup { - cmd = { "xcrun", O.lang.swift.lsp.path }, - on_attach = require("lsp").common_on_attach, - filetypes = { "swift" }, - } -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/tex.lua b/.config/nvim/lua/lang/tex.lua deleted file mode 100644 index 9ebf05f..0000000 --- a/.config/nvim/lua/lang/tex.lua +++ /dev/null @@ -1,159 +0,0 @@ -local M = {} - -M.config = function() - O.lang.latex = { - filetypes = { "tex", "bib" }, - aux_directory = nil, - bibtex_formatter = "texlab", - diagnostics_delay = 300, - formatter_line_length = 80, - latex_formatter = "latexindent", - lsp = { - path = DATA_PATH .. "/lspinstall/latex/texlab", - }, - build = { - executable = "latexmk", - args = { "-pdf", "-interaction=nonstopmode", "-synctex=1", "%f" }, - on_save = false, - forward_search_after = false, - }, - chktex = { - on_open_and_save = false, - on_edit = false, - }, - forward_search = { - executable = nil, - args = {}, - }, - latexindent = { - ["local"] = nil, - modify_line_breaks = false, - }, - diagnostics = { - virtual_text = { spacing = 0, prefix = "" }, - signs = true, - underline = true, - }, - linters = { "chktex" }, - auto_save = false, - ignore_errors = {}, - } -end - -M.format = function() - -- TODO: implement formatter for language - return "No formatter available!" -end - -M.lint = function() - require("lint").linters_by_ft = { - tex = O.lang.latex.linters, - } -end - -M.lsp = function() - if require("utils").check_lsp_client_active "texlab" then - return - end - - local preview_settings = {} - - local sumatrapdf_args = { "-reuse-instance", "%p", "-forward-search", "%f", "%l" } - local evince_args = { "-f", "%l", "%p", '"code -g %f:%l"' } - local okular_args = { "--unique", "file:%p#src:%l%f" } - local zathura_args = { "--synctex-forward", "%l:1:%f", "%p" } - local qpdfview_args = { "--unique", "%p#src:%f:%l:1" } - local skim_args = { "%l", "%p", "%f" } - - if O.lang.latex.forward_search.executable == "C:/Users/{User}/AppData/Local/SumatraPDF/SumatraPDF.exe" then - preview_settings = sumatrapdf_args - elseif O.lang.latex.forward_search.executable == "evince-synctex" then - preview_settings = evince_args - elseif O.lang.latex.forward_search.executable == "okular" then - preview_settings = okular_args - elseif O.lang.latex.forward_search.executable == "zathura" then - preview_settings = zathura_args - elseif O.lang.latex.forward_search.executable == "qpdfview" then - preview_settings = qpdfview_args - elseif O.lang.latex.forward_search.executable == "/Applications/Skim.app/Contents/SharedSupport/displayline" then - preview_settings = skim_args - end - - require("lspconfig").texlab.setup { - cmd = { O.lang.latex.lsp.path }, - on_attach = require("lsp").common_on_attach, - handlers = { - ["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { - virtual_text = O.lang.latex.diagnostics.virtual_text, - signs = O.lang.latex.diagnostics.signs, - underline = O.lang.latex.diagnostics.underline, - update_in_insert = true, - }), - }, - filetypes = { "tex", "bib" }, - settings = { - texlab = { - auxDirectory = O.lang.latex.aux_directory, - bibtexFormatter = O.lang.latex.bibtex_formatter, - build = { - args = O.lang.latex.build.args, - executable = O.lang.latex.build.executable, - forwardSearchAfter = O.lang.latex.build.forward_search_after, - onSave = O.lang.latex.build.on_save, - }, - chktex = { - onEdit = O.lang.latex.chktex.on_edit, - onOpenAndSave = O.lang.latex.chktex.on_open_and_save, - }, - diagnosticsDelay = O.lang.latex.diagnostics_delay, - formatterLineLength = O.lang.latex.formatter_line_length, - forwardSearch = { - args = preview_settings, - executable = O.lang.latex.forward_search.executable, - }, - latexFormatter = O.lang.latex.latex_formatter, - latexindent = { - modifyLineBreaks = O.lang.latex.latexindent.modify_line_breaks, - }, - }, - }, - } - vim.g.vimtex_compiler_method = "latexmk" - vim.g.vimtex_view_method = "zathura" - vim.g.vimtex_fold_enabled = 0 - vim.g.vimtex_quickfix_ignore_filters = O.lang.latex.ignore_errors - - O.plugin.which_key.mappings["t"] = { - name = "+Latex", - c = { "<cmd>VimtexCompile<cr>", "Toggle Compilation Mode" }, - f = { "<cmd>call vimtex#fzf#run()<cr>", "Fzf Find" }, - i = { "<cmd>VimtexInfo<cr>", "Project Information" }, - s = { "<cmd>VimtexStop<cr>", "Stop Project Compilation" }, - t = { "<cmd>VimtexTocToggle<cr>", "Toggle Table Of Content" }, - v = { "<cmd>VimtexView<cr>", "View PDF" }, - b = { "<cmd>TexlabBuild<cr>", "Build with Texlab" }, - p = { "<cmd>TexlabForward<cr>", "Preview with Texlab" }, - } - - -- Compile on initialization, cleanup on quit - vim.api.nvim_exec( - [[ - augroup vimtex_event_1 - au! - au User VimtexEventQuit call vimtex#compiler#clean(0) - au User VimtexEventInitPost call vimtex#compiler#compile() - augroup END - ]], - false - ) - if O.lang.latex.auto_save then - vim.api.nvim_exec([[au FocusLost * :wa]], false) - end -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/typescript.lua b/.config/nvim/lua/lang/typescript.lua deleted file mode 100644 index 178c6f5..0000000 --- a/.config/nvim/lua/lang/typescript.lua +++ /dev/null @@ -1,25 +0,0 @@ -local M = {} - -M.config = function() - -- TODO: implement config for language - return "No config available!" -end - -M.format = function() - -- TODO: implement formatter for language - return "No formatter available!" -end - -M.lint = function() - -- TODO: implement linters (if applicable) - return "No linters configured!" -end - -M.lsp = function() end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/typescriptreact.lua b/.config/nvim/lua/lang/typescriptreact.lua deleted file mode 100644 index 178c6f5..0000000 --- a/.config/nvim/lua/lang/typescriptreact.lua +++ /dev/null @@ -1,25 +0,0 @@ -local M = {} - -M.config = function() - -- TODO: implement config for language - return "No config available!" -end - -M.format = function() - -- TODO: implement formatter for language - return "No formatter available!" -end - -M.lint = function() - -- TODO: implement linters (if applicable) - return "No linters configured!" -end - -M.lsp = function() end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/vim.lua b/.config/nvim/lua/lang/vim.lua deleted file mode 100644 index bab91e6..0000000 --- a/.config/nvim/lua/lang/vim.lua +++ /dev/null @@ -1,40 +0,0 @@ -local M = {} - -M.config = function() - O.lang.vim = { - linters = { "vint" }, - lsp = { - path = DATA_PATH .. "/lspinstall/vim/node_modules/.bin/vim-language-server", - }, - } -end - -M.format = function() - -- TODO: implement formatter for language - return "No formatter available!" -end - -M.lint = function() - require("lint").linters_by_ft = { - vim = O.lang.vim.linters, - } -end - -M.lsp = function() - if require("utils").check_lsp_client_active "vimls" then - return - end - - -- npm install -g vim-language-server - require("lspconfig").vimls.setup { - cmd = { DATA_PATH .. "/lspinstall/vim/node_modules/.bin/vim-language-server", "--stdio" }, - on_attach = require("lsp").common_on_attach, - } -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/yaml.lua b/.config/nvim/lua/lang/yaml.lua deleted file mode 100644 index 7f9eb71..0000000 --- a/.config/nvim/lua/lang/yaml.lua +++ /dev/null @@ -1,54 +0,0 @@ -local M = {} - -M.config = function() - O.lang.yaml = { - formatter = { - exe = "prettier", - args = { "--stdin-filepath", vim.api.nvim_buf_get_name(0), "--single-quote" }, - stdin = true, - }, - lsp = { - path = DATA_PATH .. "/lspinstall/yaml/node_modules/.bin/yaml-language-server", - }, - } -end - -M.format = function() - O.formatters.filetype["yaml"] = { - function() - return { - exe = O.lang.yaml.formatter.exe, - args = O.lang.yaml.formatter.args, - stdin = O.lang.yaml.formatter.stdin, - } - end, - } - require("formatter.config").set_defaults { - logging = false, - filetype = O.formatters.filetype, - } -end - -M.lint = function() - -- TODO: implement linters (if applicable) - return "No linters configured!" -end - -M.lsp = function() - if require("utils").check_lsp_client_active "yamlls" then - return - end - - -- npm install -g yaml-language-server - require("lspconfig").yamlls.setup { - cmd = { O.lang.yaml.lsp.path, "--stdio" }, - on_attach = require("lsp").common_on_attach, - } -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/zig.lua b/.config/nvim/lua/lang/zig.lua deleted file mode 100644 index e000cfe..0000000 --- a/.config/nvim/lua/lang/zig.lua +++ /dev/null @@ -1,58 +0,0 @@ -local M = {} - -M.config = function() - O.lang.zig = { - formatter = { - exe = "zig", - args = { "fmt" }, - stdin = false, - }, - lsp = { - path = "zls", - }, - } -end - -M.format = function() - O.formatters.filetype["zig"] = { - function() - return { - exe = O.lang.zig.formatter.exe, - args = O.lang.zig.formatter.args, - stdin = O.lang.zig.formatter.stdin, - } - end, - } - - require("formatter.config").set_defaults { - logging = false, - filetype = O.formatters.filetype, - } -end - -M.lint = function() - -- TODO: implement linters (if applicable) - return "No linters configured!" -end - -M.lsp = function() - if require("utils").check_lsp_client_active "zls" then - return - end - -- Because lspinstall don't support zig yet, - -- So we need zls preset in global lib - -- Further custom install zls in - -- https://github.com/zigtools/zls/wiki/Downloading-and-Building-ZLS - require("lspconfig").zls.setup { - cmd = { O.lang.zig.lsp.path }, - root_dir = require("lspconfig").util.root_pattern(".git", "build.zig", "zls.json"), - on_attach = require("lsp").common_on_attach, - } -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lang/zsh.lua b/.config/nvim/lua/lang/zsh.lua deleted file mode 100644 index 31e9bf3..0000000 --- a/.config/nvim/lua/lang/zsh.lua +++ /dev/null @@ -1,53 +0,0 @@ -local M = {} - -M.config = function() - O.lang.zsh = { - lsp = { - path = DATA_PATH .. "/lspinstall/bash/node_modules/.bin/bash-language-server", - }, - } -end - -M.format = function() - -- TODO: implement format for language - return "No format available!" -end - -M.lint = function() - -- zsh - local zsh_arguments = {} - - if not require("utils").check_lsp_client_active "efm" then - require("lspconfig").efm.setup { - -- init_options = {initializationOptions}, - cmd = { DATA_PATH .. "/lspinstall/efm/efm-langserver" }, - init_options = { documentFormatting = true, codeAction = false }, - root_dir = require("lspconfig").util.root_pattern ".git/", - filetypes = { "zsh" }, - settings = { - rootMarkers = { ".git/" }, - languages = { - zsh = zsh_arguments, - }, - }, - } - end -end - -M.lsp = function() - if not require("utils").check_lsp_client_active "bashls" then - -- npm i -g bash-language-server - require("lspconfig").bashls.setup { - cmd = { O.lang.zsh.lsp.path, "start" }, - on_attach = require("lsp").common_on_attach, - filetypes = { "sh", "zsh" }, - } - end -end - -M.dap = function() - -- TODO: implement dap - return "No DAP configured!" -end - -return M diff --git a/.config/nvim/lua/lsp/emmet-ls.lua b/.config/nvim/lua/lsp/emmet-ls.lua deleted file mode 100644 index e38747a..0000000 --- a/.config/nvim/lua/lsp/emmet-ls.lua +++ /dev/null @@ -1,23 +0,0 @@ --- if not package.loaded['lspconfig'] then --- return --- end - -local nvim_lsp = require "lspconfig" -local configs = require "lspconfig/configs" -local capabilities = vim.lsp.protocol.make_client_capabilities() -capabilities.textDocument.completion.completionItem.snippetSupport = true - -configs.emmet_ls = { - default_config = { - cmd = { "emmet-ls", "--stdio" }, - filetypes = { "html", "css", "javascript", "typescript", "vue" }, - root_dir = function() - return vim.loop.cwd() - end, - settings = {}, - }, -} - -nvim_lsp.emmet_ls.setup { - -- on_attach = on_attach; -} diff --git a/.config/nvim/lua/lsp/handlers.lua b/.config/nvim/lua/lsp/handlers.lua new file mode 100644 index 0000000..c869d79 --- /dev/null +++ b/.config/nvim/lua/lsp/handlers.lua @@ -0,0 +1,63 @@ +-- Set Default Prefix. +-- Note: You can set a prefix per lsp server in the lv-globals.lua file +local M = {} + +function M.setup() + vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { + virtual_text = options.lsp.diagnostics.virtual_text, + signs = options.lsp.diagnostics.signs.active, + underline = options.lsp.document_highlight, + }) + + vim.lsp.handlers["textDocument/publishDiagnostics"] = function(_, _, params, client_id, _) + local config = { -- your config + virtual_text = options.lsp.diagnostics.virtual_text, + signs = options.lsp.diagnostics.signs, + underline = options.lsp.diagnostics.underline, + update_in_insert = options.lsp.diagnostics.update_in_insert, + severity_sort = options.lsp.diagnostics.severity_sort, + } + local uri = params.uri + local bufnr = vim.uri_to_bufnr(uri) + + if not bufnr then + return + end + + local diagnostics = params.diagnostics + + for i, v in ipairs(diagnostics) do + local source = v.source + if source then + if string.find(source, "/") then + source = string.sub(v.source, string.find(v.source, "([%w-_]+)$")) + end + diagnostics[i].message = string.format("%s: %s", source, v.message) + else + diagnostics[i].message = string.format("%s", v.message) + end + + if vim.tbl_contains(vim.tbl_keys(v), "code") then + diagnostics[i].message = diagnostics[i].message .. string.format(" [%s]", v.code) + end + end + + vim.lsp.diagnostic.save(diagnostics, bufnr, client_id) + + if not vim.api.nvim_buf_is_loaded(bufnr) then + return + end + + vim.lsp.diagnostic.display(diagnostics, bufnr, client_id, config) + end + + vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { + border = options.lsp.popup_border, + }) + + vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, { + border = options.lsp.popup_border, + }) +end + +return M diff --git a/.config/nvim/lua/lsp/init.lua b/.config/nvim/lua/lsp/init.lua index 6a52b9d..0c830f5 100644 --- a/.config/nvim/lua/lsp/init.lua +++ b/.config/nvim/lua/lsp/init.lua @@ -1,118 +1,17 @@ --- TODO: figure out why this don't work -vim.fn.sign_define( - "LspDiagnosticsSignError", - { texthl = "LspDiagnosticsSignError", text = "", numhl = "LspDiagnosticsSignError" } -) -vim.fn.sign_define( - "LspDiagnosticsSignWarning", - { texthl = "LspDiagnosticsSignWarning", text = "", numhl = "LspDiagnosticsSignWarning" } -) -vim.fn.sign_define( - "LspDiagnosticsSignHint", - { texthl = "LspDiagnosticsSignHint", text = "", numhl = "LspDiagnosticsSignHint" } -) -vim.fn.sign_define( - "LspDiagnosticsSignInformation", - { texthl = "LspDiagnosticsSignInformation", text = "", numhl = "LspDiagnosticsSignInformation" } -) +local M = {} +local Log = require "core.log" +function M.config() + vim.lsp.protocol.CompletionItemKind = options.lsp.completion.item_kind --- local opts = { border = "single" } --- TODO revisit this --- local border = { --- { "🭽", "FloatBorder" }, --- { "▔", "FloatBorder" }, --- { "🭾", "FloatBorder" }, --- { "▕", "FloatBorder" }, --- { "🭿", "FloatBorder" }, --- { "▁", "FloatBorder" }, --- { "🭼", "FloatBorder" }, --- { "▏", "FloatBorder" }, --- } - --- My font didn't like this :/ --- vim.api.nvim_set_keymap( --- "n", --- "gl", --- '<cmd>lua vim.lsp.diagnostic.show_line_diagnostics({ show_header = false, border = { { "🭽", "FloatBorder" }, { "▔", "FloatBorder" }, { "🭾", "FloatBorder" }, { "▕", "FloatBorder" }, { "🭿", "FloatBorder" }, { "▁", "FloatBorder" }, { "🭼", "FloatBorder" }, { "▏", "FloatBorder" }, } })<CR>', --- { noremap = true, silent = true } --- ) - -if O.lsp.default_keybinds then - vim.cmd "nnoremap <silent> gd <cmd>lua vim.lsp.buf.definition()<CR>" - vim.cmd "nnoremap <silent> gD <cmd>lua vim.lsp.buf.declaration()<CR>" - vim.cmd "nnoremap <silent> gr <cmd>lua vim.lsp.buf.references()<CR>" - vim.cmd "nnoremap <silent> gi <cmd>lua vim.lsp.buf.implementation()<CR>" - vim.api.nvim_set_keymap( - "n", - "gl", - '<cmd>lua vim.lsp.diagnostic.show_line_diagnostics({ show_header = false, border = "single" })<CR>', - { noremap = true, silent = true } - ) + for _, sign in ipairs(options.lsp.diagnostics.signs.values) do + vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name }) + end - vim.cmd "nnoremap <silent> gp <cmd>lua require'lsp'.PeekDefinition()<CR>" - vim.cmd "nnoremap <silent> K :lua vim.lsp.buf.hover()<CR>" - vim.cmd "nnoremap <silent> <C-p> :lua vim.lsp.diagnostic.goto_prev({popup_opts = {border = O.lsp.popup_border}})<CR>" - vim.cmd "nnoremap <silent> <C-n> :lua vim.lsp.diagnostic.goto_next({popup_opts = {border = O.lsp.popup_border}})<CR>" - vim.cmd "nnoremap <silent> <tab> <cmd>lua vim.lsp.buf.signature_help()<CR>" - -- scroll down hover doc or scroll in definition preview - -- scroll up hover doc - vim.cmd 'command! -nargs=0 LspVirtualTextToggle lua require("lsp/virtual_text").toggle()' + require("lsp.handlers").setup() end --- Set Default Prefix. --- Note: You can set a prefix per lsp server in the lv-globals.lua file -vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { - virtual_text = O.lsp.diagnostics.virtual_text, - signs = O.lsp.diagnostics.signs, - underline = O.lsp.document_highlight, -}) - -vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { - border = O.lsp.popup_border, -}) - -vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, { - border = O.lsp.popup_border, -}) - --- symbols for autocomplete -vim.lsp.protocol.CompletionItemKind = { - " (Text) ", - " (Method)", - " (Function)", - " (Constructor)", - " ﴲ (Field)", - "[] (Variable)", - " (Class)", - " ﰮ (Interface)", - " (Module)", - " 襁 (Property)", - " (Unit)", - " (Value)", - " 練 (Enum)", - " (Keyword)", - " (Snippet)", - " (Color)", - " (File)", - " (Reference)", - " (Folder)", - " (EnumMember)", - " ﲀ (Constant)", - " ﳤ (Struct)", - " (Event)", - " (Operator)", - " (TypeParameter)", -} - ---[[ " autoformat -autocmd BufWritePre *.js lua vim.lsp.buf.formatting_sync(nil, 100) -autocmd BufWritePre *.jsx lua vim.lsp.buf.formatting_sync(nil, 100) -autocmd BufWritePre *.lua lua vim.lsp.buf.formatting_sync(nil, 100) ]] --- Java --- autocmd FileType java nnoremap ca <Cmd>lua require('jdtls').code_action()<CR> - local function lsp_highlight_document(client) - if O.lsp.document_highlight == false then + if options.lsp.document_highlight == false then return -- we don't need further end -- Set autocommands conditional on server_capabilities @@ -132,133 +31,117 @@ local function lsp_highlight_document(client) ) end end -local lsp_config = {} --- Taken from https://www.reddit.com/r/neovim/comments/gyb077/nvimlsp_peek_defination_javascript_ttserver/ -function lsp_config.preview_location(location, context, before_context) - -- location may be LocationLink or Location (more useful for the former) - context = context or 15 - before_context = before_context or 0 - local uri = location.targetUri or location.uri - if uri == nil then - return - end - local bufnr = vim.uri_to_bufnr(uri) - if not vim.api.nvim_buf_is_loaded(bufnr) then - vim.fn.bufload(bufnr) +local function add_lsp_buffer_keybindings(bufnr) + local wk = require "which-key" + local keys = { + ["K"] = { "<cmd>lua vim.lsp.buf.hover()<CR>", "Show hover" }, + ["gd"] = { "<cmd>lua vim.lsp.buf.definition()<CR>", "Goto Definition" }, + ["gD"] = { "<cmd>lua vim.lsp.buf.declaration()<CR>", "Goto declaration" }, + ["gr"] = { "<cmd>lua vim.lsp.buf.references()<CR>", "Goto references" }, + ["gi"] = { "<cmd>lua vim.lsp.buf.implementation()<CR>", "Goto implementation" }, + ["gs"] = { "<cmd>lua vim.lsp.buf.signature_help()<CR>", "show signature help" }, + ["gp"] = { "<cmd>lua require'lsp.peek'.Peek('definition')<CR>", "Peek definition" }, + ["gl"] = { + "<cmd>lua vim.lsp.diagnostic.show_line_diagnostics({ show_header = false, border = 'single' })<CR>", + "Show line diagnostics", + }, + } + wk.register(keys, { mode = "n", buffer = bufnr }) +end + +local function set_smart_cwd(client) + local proj_dir = client.config.root_dir + if options.lsp.smart_cwd and proj_dir ~= "/" then + vim.api.nvim_set_current_dir(proj_dir) + require("core.nvimtree").change_tree_dir(proj_dir) end +end - local range = location.targetRange or location.range - local contents = vim.api.nvim_buf_get_lines( - bufnr, - range.start.line - before_context, - range["end"].line + 1 + context, - false - ) - local filetype = vim.api.nvim_buf_get_option(bufnr, "filetype") - return vim.lsp.util.open_floating_preview(contents, filetype, { border = O.lsp.popup_border }) +function M.common_capabilities() + local capabilities = vim.lsp.protocol.make_client_capabilities() + capabilities.textDocument.completion.completionItem.snippetSupport = true + capabilities.textDocument.completion.completionItem.resolveSupport = { + properties = { + "documentation", + "detail", + "additionalTextEdits", + }, + } + return capabilities end -function lsp_config.preview_location_callback(_, method, result) - local context = 15 - if result == nil or vim.tbl_isempty(result) then - print("No location found: " .. method) - return nil +function M.get_ls_capabilities(client_id) + local client + if not client_id then + local buf_clients = vim.lsp.buf_get_clients() + for _, buf_client in ipairs(buf_clients) do + if buf_client.name ~= "null-ls" then + client_id = buf_client.id + break + end + end end - if vim.tbl_islist(result) then - lsp_config.floating_buf, lsp_config.floating_win = lsp_config.preview_location(result[1], context) - else - lsp_config.floating_buf, lsp_config.floating_win = lsp_config.preview_location(result, context) + if not client_id then + error "Unable to determine client_id" end -end -function lsp_config.PeekDefinition() - if vim.tbl_contains(vim.api.nvim_list_wins(), lsp_config.floating_win) then - vim.api.nvim_set_current_win(lsp_config.floating_win) - else - local params = vim.lsp.util.make_position_params() - return vim.lsp.buf_request(0, "textDocument/definition", params, lsp_config.preview_location_callback) + client = vim.lsp.get_client_by_id(tonumber(client_id)) + + local enabled_caps = {} + + for k, v in pairs(client.resolved_capabilities) do + if v == true then + table.insert(enabled_caps, k) + end end + + return enabled_caps end -function lsp_config.PeekTypeDefinition() - if vim.tbl_contains(vim.api.nvim_list_wins(), lsp_config.floating_win) then - vim.api.nvim_set_current_win(lsp_config.floating_win) - else - local params = vim.lsp.util.make_position_params() - return vim.lsp.buf_request(0, "textDocument/typeDefinition", params, lsp_config.preview_location_callback) +function M.common_on_init(client, bufnr) + if options.lsp.on_init_callback then + options.lsp.on_init_callback(client, bufnr) + Log:get_default().info "Called lsp.on_init_callback" + return end -end -function lsp_config.PeekImplementation() - if vim.tbl_contains(vim.api.nvim_list_wins(), lsp_config.floating_win) then - vim.api.nvim_set_current_win(lsp_config.floating_win) - else - local params = vim.lsp.util.make_position_params() - return vim.lsp.buf_request(0, "textDocument/implementation", params, lsp_config.preview_location_callback) + local formatters = options.lang[vim.bo.filetype].formatters + if not vim.tbl_isempty(formatters) and formatters[1]["exe"] ~= nil and formatters[1].exe ~= "" then + client.resolved_capabilities.document_formatting = false + Log:get_default().info( + string.format("Overriding language server [%s] with format provider [%s]", client.name, formatters[1].exe) + ) end end -function lsp_config.common_on_attach(client, bufnr) - if O.lsp.on_attach_callback then - O.lsp.on_attach_callback(client, bufnr) +function M.common_on_attach(client, bufnr) + if options.lsp.on_attach_callback then + options.lsp.on_attach_callback(client, bufnr) + Log:get_default().info "Called lsp.on_init_callback" end lsp_highlight_document(client) + add_lsp_buffer_keybindings(bufnr) + set_smart_cwd(client) + require("lsp.null-ls").setup(vim.bo.filetype) end -function lsp_config.tsserver_on_attach(client, _) - -- lsp_config.common_on_attach(client, bufnr) - client.resolved_capabilities.document_formatting = false - - local ts_utils = require "nvim-lsp-ts-utils" - - -- defaults - ts_utils.setup { - debug = false, - disable_commands = false, - enable_import_on_completion = false, - import_all_timeout = 5000, -- ms - - -- eslint - eslint_enable_code_actions = true, - eslint_enable_disable_comments = true, - -- eslint_bin = O.lang.tsserver.linter, - eslint_config_fallback = nil, - eslint_enable_diagnostics = true, - - -- formatting - enable_formatting = O.lang.tsserver.autoformat, - formatter = O.lang.tsserver.formatter.exe, - formatter_config_fallback = nil, - - -- parentheses completion - complete_parens = false, - signature_help_in_parens = false, +function M.setup(lang) + local lsp = options.lang[lang].lsp + if require("utils").check_lsp_client_active(lsp.provider) then + return + end - -- update imports on file move - update_imports_on_move = false, - require_confirmation_on_move = false, - watch_dir = nil, - } + local overrides = options.lsp.override - -- required to fix code action ranges - ts_utils.setup_client(client) + if type(overrides) == "table" then + if vim.tbl_contains(overrides, lang) then + return + end + end - -- TODO: keymap these? - -- vim.api.nvim_buf_set_keymap(bufnr, "n", "gs", ":TSLspOrganize<CR>", {silent = true}) - -- vim.api.nvim_buf_set_keymap(bufnr, "n", "qq", ":TSLspFixCurrent<CR>", {silent = true}) - -- vim.api.nvim_buf_set_keymap(bufnr, "n", "gr", ":TSLspRenameFile<CR>", {silent = true}) - -- vim.api.nvim_buf_set_keymap(bufnr, "n", "gi", ":TSLspImportAll<CR>", {silent = true}) + local lspconfig = require "lspconfig" + lspconfig[lsp.provider].setup(lsp.setup) end -require("utils").define_augroups { - _general_lsp = { - { "FileType", "lspinfo", "nnoremap <silent> <buffer> q :q<CR>" }, - }, -} - --- Use a loop to conveniently both setup defined servers --- and map buffer local keybindings when the language server attaches --- local servers = {"pyright", "tsserver"} --- for _, lsp in ipairs(servers) do nvim_lsp[lsp].setup {on_attach = on_attach} end -return lsp_config +return M diff --git a/.config/nvim/lua/lsp/null-ls.lua b/.config/nvim/lua/lsp/null-ls.lua new file mode 100644 index 0000000..81c6648 --- /dev/null +++ b/.config/nvim/lua/lsp/null-ls.lua @@ -0,0 +1,141 @@ +local M = {} +local Log = require "core.log" + +local null_ls = require "null-ls" + +local nodejs_local_providers = { "prettier", "prettierd", "prettier_d_slim", "eslint_d", "eslint" } + +M.requested_providers = {} + +function M.get_registered_providers_by_filetype(ft) + local matches = {} + for _, provider in pairs(M.requested_providers) do + if vim.tbl_contains(provider.filetypes, ft) then + local provider_name = provider.name + -- special case: show "eslint_d" instead of eslint + -- https://github.com/jose-elias-alvarez/null-ls.nvim/blob/9b8458bd1648e84169a7e8638091ba15c2f20fc0/doc/BUILTINS.md#eslint + if string.find(provider._opts.command, "eslint_d") then + provider_name = "eslint_d" + end + table.insert(matches, provider_name) + end + end + + return matches +end + +function M.get_missing_providers_by_filetype(ft) + local matches = {} + for _, provider in pairs(M.requested_providers) do + if vim.tbl_contains(provider.filetypes, ft) then + local provider_name = provider.name + + table.insert(matches, provider_name) + end + end + + return matches +end + +local function register_failed_request(ft, provider, operation) + if not options.lang[ft][operation]._failed_requests then + options.lang[ft][operation]._failed_requests = {} + end + table.insert(options.lang[ft][operation]._failed_requests, provider) +end + +local function validate_nodejs_provider(provider) + local command_path + local root_dir + if options.builtin.rooter.active then + --- use vim-rooter to set root_dir + vim.cmd "let root_dir = FindRootDirectory()" + root_dir = vim.api.nvim_get_var "root_dir" + else + --- use LSP to set root_dir + local ts_client = require("utils").get_active_client_by_ft "typescript" + if ts_client == nil then + Log:get_default().error "Unable to determine root directory since tsserver didn't start correctly" + return + end + root_dir = ts_client.config.root_dir + end + local local_nodejs_command = root_dir .. "/node_modules/.bin/" .. provider._opts.command + Log:get_default().debug("checking for local node module: ", vim.inspect(provider)) + + if vim.fn.executable(local_nodejs_command) == 1 then + command_path = local_nodejs_command + elseif vim.fn.executable(provider._opts.command) == 1 then + Log:get_default().debug("checking in global path instead for node module", provider._opts.command) + command_path = provider._opts.command + else + Log:get_default().debug("Unable to find node module", provider._opts.command) + end + return command_path +end + +local function validate_provider_request(provider) + if provider == "" or provider == nil then + return + end + -- NOTE: we can't use provider.name because eslint_d uses eslint name + if vim.tbl_contains(nodejs_local_providers, provider._opts.command) then + return validate_nodejs_provider(provider) + end + if vim.fn.executable(provider._opts.command) ~= 1 then + Log:get_default().warn("Unable to find the path for", vim.inspect(provider)) + return + end + return provider._opts.command +end + +-- TODO: for linters and formatters with spaces and '-' replace with '_' +function M.setup(filetype) + for _, formatter in pairs(options.lang[filetype].formatters) do + Log:get_default().debug("validating format provider: ", formatter.exe) + local builtin_formatter = null_ls.builtins.formatting[formatter.exe] + if not vim.tbl_contains(M.requested_providers, builtin_formatter) then + -- FIXME: why doesn't this work? + -- builtin_formatter._opts.args = formatter.args or builtin_formatter._opts.args + -- builtin_formatter._opts.to_stdin = formatter.stdin or builtin_formatter._opts.to_stdin + local resolved_path = validate_provider_request(builtin_formatter) + if resolved_path then + builtin_formatter._opts.command = resolved_path + table.insert(M.requested_providers, builtin_formatter) + Log:get_default().info("Using format provider", builtin_formatter.name) + else + -- mark it here to avoid re-doing the lookup again + register_failed_request(filetype, formatter.exe, "formatters") + end + end + end + + for _, linter in pairs(options.lang[filetype].linters) do + local builtin_diagnoser = null_ls.builtins.diagnostics[linter.exe] + Log:get_default().debug("validating lint provider: ", linter.exe) + -- special case: fallback to "eslint" + -- https://github.com/jose-elias-alvarez/null-ls.nvim/blob/9b8458bd1648e84169a7e8638091ba15c2f20fc0/doc/BUILTINS.md#eslint + -- if provider.exe + if linter.exe == "eslint_d" then + builtin_diagnoser = null_ls.builtins.diagnostics.eslint.with { command = "eslint_d" } + end + if not vim.tbl_contains(M.requested_providers, builtin_diagnoser) then + -- FIXME: why doesn't this work? + -- builtin_diagnoser._opts.args = linter.args or builtin_diagnoser._opts.args + -- builtin_diagnoser._opts.to_stdin = linter.stdin or builtin_diagnoser._opts.to_stdin + local resolved_path = validate_provider_request(builtin_diagnoser) + if resolved_path then + builtin_diagnoser._opts.command = resolved_path + table.insert(M.requested_providers, builtin_diagnoser) + Log:get_default().info("Using linter provider", builtin_diagnoser.name) + else + -- mark it here to avoid re-doing the lookup again + register_failed_request(filetype, linter.exe, "linters") + end + end + end + + null_ls.register { sources = M.requested_providers } +end + +return M diff --git a/.config/nvim/lua/lsp/peek.lua b/.config/nvim/lua/lsp/peek.lua new file mode 100644 index 0000000..cc8e57a --- /dev/null +++ b/.config/nvim/lua/lsp/peek.lua @@ -0,0 +1,140 @@ +local M = { + floating_buf = nil, + floating_win = nil, + prev_result = nil, +} + +local function create_floating_file(location, opts) + vim.validate { + location = { location, "t" }, + opts = { opts, "t", true }, + } + + -- Set some defaults + opts = opts or {} + local close_events = opts.close_events or { "CursorMoved", "CursorMovedI", "BufHidden", "InsertCharPre" } + + -- location may be LocationLink or Location + local uri = location.targetUri or location.uri + if uri == nil then + return + end + local bufnr = vim.uri_to_bufnr(uri) + if not vim.api.nvim_buf_is_loaded(bufnr) then + vim.fn.bufload(bufnr) + end + + local range = location.targetRange or location.range + + local contents = vim.api.nvim_buf_get_lines( + bufnr, + range.start.line, + math.min(range["end"].line + 1 + (opts.context or 10), range.start.line + (opts.max_height or 15)), -- Don't let the window be more that 15 lines long(height) + false + ) + local width, height = vim.lsp.util._make_floating_popup_size(contents, opts) + opts = vim.lsp.util.make_floating_popup_options(width, height, opts) + -- Don't make it minimal as it is meant to be fully featured + opts["style"] = nil + + vim.api.nvim_buf_set_option(bufnr, "bufhidden", "wipe") + + local winnr = vim.api.nvim_open_win(bufnr, false, opts) + vim.api.nvim_win_set_option(winnr, "winblend", 0) + + vim.api.nvim_buf_set_var(bufnr, "lsp_floating_window", winnr) + + -- Set some autocmds to close the window + vim.api.nvim_command( + "autocmd QuitPre <buffer> ++nested ++once lua pcall(vim.api.nvim_win_close, " .. winnr .. ", true)" + ) + vim.lsp.util.close_preview_autocmd(close_events, winnr) + + return bufnr, winnr +end + +local function preview_location_callback(_, method, result) + if result == nil or vim.tbl_isempty(result) then + print("peek: No location found: " .. method) + return nil + end + + local opts = { + border = "rounded", + context = 10, + } + + if vim.tbl_islist(result) then + M.prev_result = result[1] + M.floating_buf, M.floating_win = create_floating_file(result[1], opts) + else + M.prev_result = result + M.floating_buf, M.floating_win = create_floating_file(result, opts) + end +end + +function M.open_file() + -- Get the file currently open in the floating window + local filepath = vim.fn.expand "%:." + + if not filepath then + print "peek: Unable to open the file!" + return + end + + -- Close the floating window + pcall(vim.api.nvim_win_close, M.floating_win, true) + + -- Edit the file + vim.cmd("edit " .. filepath) + + local winnr = vim.api.nvim_get_current_win() + + -- Set the cursor at the right position + M.set_cursor_to_prev_pos(winnr) +end + +function M.set_cursor_to_prev_pos(winnr) + -- Get position of the thing to peek at + local location = M.prev_result + local range = location.targetRange or location.range + local cursor_pos = { range.start.line + 1, range.start.character } + + -- Set the winnr to the floating window if none was passed in + winnr = winnr or M.floating_win + -- Set the cursor at the correct position in the floating window + vim.api.nvim_win_set_cursor(winnr, cursor_pos) +end + +function M.Peek(what) + -- If a window already exists, focus it at the right position! + if vim.tbl_contains(vim.api.nvim_list_wins(), M.floating_win) then + local success_1, _ = pcall(vim.api.nvim_set_current_win, M.floating_win) + if not success_1 then + print "peek: You cannot edit the current file in a preview!" + return + end + + -- Set the cursor at the correct position in the floating window + M.set_cursor_to_prev_pos() + + vim.api.nvim_buf_set_keymap( + M.floating_buf, + "n", + "<CR>", + ":lua require('lsp.peek').open_file()<CR>", + { noremap = true, silent = true } + ) + else + -- Make a new request and then create the new window in the callback + local params = vim.lsp.util.make_position_params() + local success, _ = pcall(vim.lsp.buf_request, 0, "textDocument/" .. what, params, preview_location_callback) + if not success then + print( + 'peek: Error calling LSP method "textDocument/' .. what .. '". The current language lsp might not support it.' + ) + end + end +end + +return M diff --git a/.config/nvim/lua/lsp/tailwindcss-ls.lua b/.config/nvim/lua/lsp/tailwindcss-ls.lua deleted file mode 100644 index 38c1e7c..0000000 --- a/.config/nvim/lua/lsp/tailwindcss-ls.lua +++ /dev/null @@ -1,13 +0,0 @@ --- TODO: what is a tailwindcss filetype -local lspconfig = require "lspconfig" - -lspconfig.tailwindcss.setup { - cmd = { - "node", - DATA_PATH .. "/lspinstall/tailwindcss/tailwindcss-intellisense/extension/dist/server/tailwindServer.js", - "--stdio", - }, - filetypes = O.lang.tailwindcss.filetypes, - root_dir = require("lspconfig/util").root_pattern("tailwind.config.js", "postcss.config.ts", ".postcssrc"), - on_attach = require("lsp").common_on_attach, -} diff --git a/.config/nvim/lua/lsp/ts-fmt-lint.lua b/.config/nvim/lua/lsp/ts-fmt-lint.lua deleted file mode 100644 index 7cebfd8..0000000 --- a/.config/nvim/lua/lsp/ts-fmt-lint.lua +++ /dev/null @@ -1,72 +0,0 @@ --- Example configuations here: https://github.com/mattn/efm-langserver -local M = {} - -M.setup = function() - vim.cmd "let proj = FindRootDirectory()" - local root_dir = vim.api.nvim_get_var "proj" - - local get_linter_instance = function() - -- prioritize local instance over global - local local_instance = root_dir .. "/node_modules/.bin/" .. O.lang.tsserver.linter - if vim.fn.executable(local_instance) == 1 then - return local_instance - end - return O.lang.tsserver.linter - end - - local tsserver_args = {} - local formattingSupported = false - - if O.lang.tsserver.linter == "eslint" or O.lang.tsserver.linter == "eslint_d" then - local eslint = { - lintCommand = get_linter_instance() .. " -f visualstudio --stdin --stdin-filename ${INPUT}", - lintStdin = true, - lintFormats = { - "%f(%l,%c): %tarning %m", - "%f(%l,%c): %trror %m", - }, - lintSource = O.lang.tsserver.linter, - lintIgnoreExitCode = true, - } - table.insert(tsserver_args, eslint) - -- Only eslint_d supports --fix-to-stdout - if string.find(get_linter_instance(), "eslint_d") then - formattingSupported = true - local eslint_fix = { - formatCommand = get_linter_instance() .. " --fix-to-stdout --stdin --stdin-filename ${INPUT}", - formatStdin = true, - } - table.insert(tsserver_args, eslint_fix) - end - end - - require("lspconfig").efm.setup { - -- init_options = {initializationOptions}, - cmd = { DATA_PATH .. "/lspinstall/efm/efm-langserver" }, - init_options = { documentFormatting = formattingSupported, codeAction = false }, - root_dir = require("lspconfig").util.root_pattern(".git/", "package.json"), - filetypes = { - "vue", - "javascript", - "javascriptreact", - "typescript", - "typescriptreact", - "javascript.jsx", - "typescript.tsx", - }, - settings = { - rootMarkers = { ".git/", "package.json" }, - languages = { - vue = tsserver_args, - javascript = tsserver_args, - javascriptreact = tsserver_args, - ["javascript.jsx"] = tsserver_args, - typescript = tsserver_args, - ["typescript.tsx"] = tsserver_args, - typescriptreact = tsserver_args, - }, - }, - } -end - -return M diff --git a/.config/nvim/lua/lsp/tsserver-ls.lua b/.config/nvim/lua/lsp/tsserver-ls.lua deleted file mode 100644 index c687dfc..0000000 --- a/.config/nvim/lua/lsp/tsserver-ls.lua +++ /dev/null @@ -1,83 +0,0 @@ -vim.cmd "let proj = FindRootDirectory()" -local root_dir = vim.api.nvim_get_var "proj" - --- use the global prettier if you didn't find the local one -local prettier_instance = root_dir .. "/node_modules/.bin/prettier" -if vim.fn.executable(prettier_instance) ~= 1 then - prettier_instance = O.lang.tsserver.formatter.exe -end - -O.formatters.filetype["javascriptreact"] = { - function() - local args = { "--stdin-filepath", vim.fn.fnameescape(vim.api.nvim_buf_get_name(0)) } - local extend_args = O.lang.tsserver.formatter.args - - if extend_args then - for i = 1, #extend_args do - table.insert(args, extend_args[i]) - end - end - - return { - exe = prettier_instance, - args = args, - stdin = true, - } - end, -} -O.formatters.filetype["javascript"] = O.formatters.filetype["javascriptreact"] -O.formatters.filetype["typescript"] = O.formatters.filetype["javascriptreact"] -O.formatters.filetype["typescriptreact"] = O.formatters.filetype["javascriptreact"] - -require("formatter.config").set_defaults { - logging = false, - filetype = O.formatters.filetype, -} - -if require("utils").check_lsp_client_active "tsserver" then - return -end - --- npm install -g typescript typescript-language-server --- require'snippets'.use_suggested_mappings() --- local capabilities = vim.lsp.protocol.make_client_capabilities() --- capabilities.textDocument.completion.completionItem.snippetSupport = true; --- local on_attach_common = function(client) --- print("LSP Initialized") --- require'completion'.on_attach(client) --- require'illuminate'.on_attach(client) --- end - -local on_attach = function(client, bufnr) - local lsp = require "lsp" - lsp.common_on_attach(client, bufnr) - lsp.tsserver_on_attach(client, bufnr) -end - -require("lspconfig").tsserver.setup { - cmd = { - DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server", - "--stdio", - }, - filetypes = { - "javascript", - "javascriptreact", - "javascript.jsx", - "typescript", - "typescriptreact", - "typescript.tsx", - }, - on_attach = on_attach, - -- This makes sure tsserver is not used for formatting (I prefer prettier) - settings = { documentFormatting = false }, - handlers = { - -- ["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { - -- virtual_text = O.lang.tsserver.diagnostics.virtual_text, - -- signs = O.lang.tsserver.diagnostics.signs, - -- underline = O.lang.tsserver.diagnostics.underline, - -- update_in_insert = true, - -- }), - }, -} - -require("lsp.ts-fmt-lint").setup() diff --git a/.config/nvim/lua/plugins.lua b/.config/nvim/lua/plugins.lua index e019fbd..14960ee 100644 --- a/.config/nvim/lua/plugins.lua +++ b/.config/nvim/lua/plugins.lua @@ -1,17 +1,17 @@ return { -- Packer can manage itself as an optional plugin { "wbthomason/packer.nvim" }, - - -- TODO: refactor all of this (for now it works, but yes I know it could be wrapped in a simpler function) { "neovim/nvim-lspconfig" }, + { "tamago324/nlsp-settings.nvim" }, + { "jose-elias-alvarez/null-ls.nvim" }, { "kabouzeid/nvim-lspinstall", event = "VimEnter", config = function() local lspinstall = require "lspinstall" lspinstall.setup() - if O.plugin.lspinstall.on_config_done then - O.plugin.lspinstall.on_config_done(lspinstall) + if options.builtin.lspinstall.on_config_done then + options.builtin.lspinstall.on_config_done(lspinstall) end end, }, @@ -25,8 +25,8 @@ return { "nvim-telescope/telescope.nvim", config = function() require("core.telescope").setup() - if O.plugin.telescope.on_config_done then - O.plugin.telescope.on_config_done(require "telescope") + if options.builtin.telescope.on_config_done then + options.builtin.telescope.on_config_done(require "telescope") end end, }, @@ -37,8 +37,8 @@ return { -- event = "InsertEnter", config = function() require("core.compe").setup() - if O.plugin.compe.on_config_done then - O.plugin.compe.on_config_done(require "compe") + if options.builtin.compe.on_config_done then + options.builtin.compe.on_config_done(require "compe") end end, }, @@ -49,8 +49,8 @@ return { -- event = "InsertEnter", config = function() require "core.autopairs" - if O.plugin.autopairs.on_config_done then - O.plugin.autopairs.on_config_done(require "nvim-autopairs") + if options.builtin.autopairs.on_config_done then + options.builtin.autopairs.on_config_done(require "nvim-autopairs") end end, }, @@ -65,30 +65,8 @@ return { "nvim-treesitter/nvim-treesitter", config = function() require("core.treesitter").setup() - if O.plugin.treesitter.on_config_done then - O.plugin.treesitter.on_config_done(require "nvim-treesitter.configs") - end - end, - }, - - -- Formatter.nvim - { - "mhartington/formatter.nvim", - config = function() - require "core.formatter" - if O.plugin.formatter.on_config_done then - O.plugin.formatter.on_config_done(require "formatter") - end - end, - }, - - -- Linter - { - "mfussenegger/nvim-lint", - config = function() - require("core.linter").setup() - if O.plugin.lint.on_config_done then - O.plugin.lint.on_config_done(require "lint") + if options.builtin.treesitter.on_config_done then + options.builtin.treesitter.on_config_done(require "nvim-treesitter.configs") end end, }, @@ -101,19 +79,18 @@ return { -- commit = "fd7f60e242205ea9efc9649101c81a07d5f458bb", config = function() require("core.nvimtree").setup() - if O.plugin.nvimtree.on_config_done then - O.plugin.nvimtree.on_config_done(require "nvim-tree.config") + if options.builtin.nvimtree.on_config_done then + options.builtin.nvimtree.on_config_done(require "nvim-tree.config") end end, }, { "lewis6991/gitsigns.nvim", - config = function() require("core.gitsigns").setup() - if O.plugin.gitsigns.on_config_done then - O.plugin.gitsigns.on_config_done(require "gitsigns") + if options.builtin.gitsigns.on_config_done then + options.builtin.gitsigns.on_config_done(require "gitsigns") end end, event = "BufRead", @@ -124,8 +101,8 @@ return { "folke/which-key.nvim", config = function() require("core.which-key").setup() - if O.plugin.which_key.on_config_done then - O.plugin.which_key.on_config_done(require "which-key") + if options.builtin.which_key.on_config_done then + options.builtin.which_key.on_config_done(require "which-key") end end, event = "BufWinEnter", @@ -138,11 +115,13 @@ return { config = function() local status_ok, nvim_comment = pcall(require, "nvim_comment") if not status_ok then + local Log = require "core.log" + Log:get_default().error "Failed to load nvim-comment" return end nvim_comment.setup() - if O.plugin.comment.on_config_done then - O.plugin.comment.on_config_done(nvim_comment) + if options.builtin.comment.on_config_done then + options.builtin.comment.on_config_done(nvim_comment) end end, }, @@ -150,8 +129,8 @@ return { { "ahmedkhalf/lsp-rooter.nvim", config = function() - if O.plugin.rooter.on_config_done then - O.plugin.rooter.on_config_done() + if options.builtin.rooter.on_config_done then + options.builtin.rooter.on_config_done() end end, }, @@ -164,20 +143,20 @@ return { "glepnir/galaxyline.nvim", config = function() require "core.galaxyline" - if O.plugin.galaxyline.on_config_done then - O.plugin.galaxyline.on_config_done(require "galaxyline") + if options.builtin.galaxyline.on_config_done then + options.builtin.galaxyline.on_config_done(require "galaxyline") end end, event = "BufWinEnter", - disable = not O.plugin.galaxyline.active, + disable = not options.builtin.galaxyline.active, }, { "romgrk/barbar.nvim", config = function() require "core.bufferline" - if O.plugin.bufferline.on_config_done then - O.plugin.bufferline.on_config_done() + if options.builtin.bufferline.on_config_done then + options.builtin.bufferline.on_config_done() end end, event = "BufWinEnter", @@ -189,11 +168,11 @@ return { -- event = "BufWinEnter", config = function() require("core.dap").setup() - if O.plugin.dap.on_config_done then - O.plugin.dap.on_config_done(require "dap") + if options.builtin.dap.on_config_done then + options.builtin.dap.on_config_done(require "dap") end end, - disable = not O.plugin.dap.active, + disable = not options.builtin.dap.active, }, -- Debugger management @@ -201,7 +180,7 @@ return { "Pocco81/DAPInstall.nvim", -- event = "BufWinEnter", -- event = "BufRead", - disable = not O.plugin.dap.active, + disable = not options.builtin.dap.active, }, -- Builtins, these do not load by default @@ -212,11 +191,11 @@ return { event = "BufWinEnter", config = function() require("core.dashboard").setup() - if O.plugin.dashboard.on_config_done then - O.plugin.dashboard.on_config_done(require "dashboard") + if options.builtin.dashboard.on_config_done then + options.builtin.dashboard.on_config_done(require "dashboard") end end, - disable = not O.plugin.dashboard.active, + disable = not options.builtin.dashboard.active, }, { @@ -224,81 +203,10 @@ return { event = "BufWinEnter", config = function() require("core.terminal").setup() - if O.plugin.terminal.on_config_done then - O.plugin.terminal.on_config_done(require "toggleterm") - end - end, - disable = not O.plugin.terminal.active, - }, - - -- Zen Mode - { - "folke/zen-mode.nvim", - cmd = "ZenMode", - event = "BufRead", - config = function() - require("core.zen").setup() - if O.plugin.zen.on_config_done then - O.plugin.zen.on_config_done(require "zen-mode") + if options.builtin.terminal.on_config_done then + options.builtin.terminal.on_config_done(require "toggleterm") end end, - disable = not O.plugin.zen.active, + disable = not options.builtin.terminal.active, }, - - -- Hop - { - "phaazon/hop.nvim", - event = "BufWinEnter", - config = function() - require("core.hop").config() - if O.plugin.hop.on_config_done then - O.plugin.hop.on_config_done(require "hop") - end - end, - disable = not O.plugin.hop.active, - }, - - { - "norcalli/nvim-colorizer.lua", - event = "BufWinEnter", - config = function() - require("core.colorizer").config() - if O.plugin.colorizer.on_config_done then - O.plugin.colorizer.on_config_done(require "nvim-colorizer") - end - end, - disable = not O.plugin.colorizer.active, - }, - - --------------------------------------------------------------------------------- - - -- LANGUAGE SPECIFIC GOES HERE - { - "lervag/vimtex", - ft = "tex", - }, - - -- Rust tools - -- TODO: use lazy loading maybe? - { - "simrat39/rust-tools.nvim", - disable = not O.lang.rust.rust_tools.active, - }, - - -- Elixir - { "elixir-editors/vim-elixir", ft = { "elixir", "eelixir", "euphoria3" } }, - - -- Javascript / Typescript - { - "jose-elias-alvarez/nvim-lsp-ts-utils", - ft = { - "javascript", - "javascriptreact", - "javascript.jsx", - "typescript", - "typescriptreact", - "typescript.tsx", - }, - }, - } diff --git a/.config/nvim/lua/settings.lua b/.config/nvim/lua/settings.lua index aa2bdd8..9295999 100644 --- a/.config/nvim/lua/settings.lua +++ b/.config/nvim/lua/settings.lua @@ -1,37 +1,78 @@ ---- HELPERS --- +local M = {} -local cmd = vim.cmd -local opt = vim.opt +M.load_options = function() + local opt = vim.opt ---- VIM ONLY COMMANDS --- + local default_options = { + backup = false, -- creates a backup file + clipboard = "unnamedplus", -- allows neovim to access the system clipboard + cmdheight = 2, -- more space in the neovim command line for displaying messages + colorcolumn = "99999", -- fixes indentline for now + completeopt = { "menuone", "noselect" }, + conceallevel = 0, -- so that `` is visible in markdown files + fileencoding = "utf-8", -- the encoding written to a file + foldmethod = "manual", -- folding, set to "expr" for treesitter based folding + foldexpr = "", -- set to "nvim_treesitter#foldexpr()" for treesitter based folding + guifont = "monospace:h17", -- the font used in graphical neovim applications + hidden = true, -- required to keep multiple buffers and open multiple buffers + hlsearch = true, -- highlight all matches on previous search pattern + ignorecase = true, -- ignore case in search patterns + mouse = "a", -- allow the mouse to be used in neovim + pumheight = 10, -- pop up menu height + showmode = false, -- we don't need to see things like -- INSERT -- anymore + showtabline = 2, -- always show tabs + smartcase = true, -- smart case + smartindent = true, -- make indenting smarter again + splitbelow = true, -- force all horizontal splits to go below current window + splitright = true, -- force all vertical splits to go to the right of current window + swapfile = false, -- creates a swapfile + termguicolors = true, -- set term gui colors (most terminals support this) + timeoutlen = 100, -- time to wait for a mapped sequence to complete (in milliseconds) + title = true, -- set the title of window to the value of the titlestring + -- opt.titlestring = "%<%F%=%l/%L - nvim" -- what the title of the window will be set to + undodir = CACHE_PATH .. "/undo", -- set an undo directory + undofile = true, -- enable persistent undo + updatetime = 300, -- faster completion + writebackup = false, -- if a file is being edited by another program (or was written to file while editing with another program), it is not allowed to be edited + expandtab = true, -- convert tabs to spaces + shiftwidth = 2, -- the number of spaces inserted for each indentation + tabstop = 2, -- insert 2 spaces for a tab + cursorline = true, -- highlight the current line + number = true, -- set numbered lines + relativenumber = true, -- set relative numbered lines + numberwidth = 4, -- set number column width to 2 {default 4} + signcolumn = "yes", -- always show the sign column, otherwise it would shift the text each time + wrap = false, -- display lines as one long line + spell = false, + spelllang = "en", + scrolloff = 8, -- is one of my fav + sidescrolloff = 8, + } --- VIM ONLY COMMANDS ---cmd "filetype plugin on"cmd('let &titleold="' .. TERMINAL .. '"')cmd "set inccommand=split"cmd "set iskeyword+=-" -cmd "filetype plugin on" -cmd('let &titleold="' .. TERMINAL .. '"') -cmd "set inccommand=split" -cmd "set iskeyword+=-" + --- SETTINGS --- -if O.line_wrap_cursor_movement then - cmd "set whichwrap+=<,>,[,],h,l" -end + opt.shortmess:append "c" -if O.transparent_window then - cmd "au ColorScheme * hi Normal ctermbg=none guibg=none" - cmd "au ColorScheme * hi SignColumn ctermbg=none guibg=none" - cmd "au ColorScheme * hi NormalNC ctermbg=none guibg=none" - cmd "au ColorScheme * hi MsgArea ctermbg=none guibg=none" - cmd "au ColorScheme * hi TelescopeBorder ctermbg=none guibg=none" - cmd "au ColorScheme * hi NvimTreeNormal ctermbg=none guibg=none" - cmd "let &fcs='eob: '" + for k, v in pairs(default_options) do + vim.opt[k] = v + end end ---- SETTINGS --- - -opt.shortmess:append "c" +M.load_commands = function() + local cmd = vim.cmd + if options.line_wrap_cursor_movement then + cmd "set whichwrap+=<,>,[,],h,l" + end -for _, plugin in pairs(O.disabled_built_ins) do - vim.g["loaded_" .. plugin] = 1 + if options.transparent_window then + cmd "au ColorScheme * hi Normal ctermbg=none guibg=none" + cmd "au ColorScheme * hi SignColumn ctermbg=none guibg=none" + cmd "au ColorScheme * hi NormalNC ctermbg=none guibg=none" + cmd "au ColorScheme * hi MsgArea ctermbg=none guibg=none" + cmd "au ColorScheme * hi TelescopeBorder ctermbg=none guibg=none" + cmd "au ColorScheme * hi NvimTreeNormal ctermbg=none guibg=none" + cmd "let &fcs='eob: '" + end end -for k, v in pairs(O.default_options) do - vim.opt[k] = v -end +return M diff --git a/.config/nvim/lua/utils/ft.lua b/.config/nvim/lua/utils/ft.lua new file mode 100644 index 0000000..fcebd1e --- /dev/null +++ b/.config/nvim/lua/utils/ft.lua @@ -0,0 +1,45 @@ +local ft = {} + +ft.find_lua_ftplugins = function(filetype) + local patterns = { + string.format("ftplugin/%s.lua", filetype), + + -- Looks like we don't need this, because the first one works + -- string.format("after/ftplugin/%s.lua", filetype), + } + + local result = {} + for _, pat in ipairs(patterns) do + vim.list_extend(result, vim.api.nvim_get_runtime_file(pat, true)) + end + + return result +end + +ft.do_filetype = function(filetype) + local ftplugins = ft.find_lua_ftplugins(filetype) + + local f_env = setmetatable({ + -- Override print, so the prints still go through, otherwise it's confusing for people + print = vim.schedule_wrap(print), + }, { + -- Buf default back read/write to whatever is going on in the global landscape + __index = _G, + __newindex = _G, + }) + + for _, file in ipairs(ftplugins) do + local f = loadfile(file) + if not f then + vim.api.nvim_err_writeln("Unable to load file: " .. file) + else + local ok, msg = pcall(setfenv(f, f_env)) + + if not ok then + vim.api.nvim_err_writeln("Error while processing file: " .. file .. "\n" .. msg) + end + end + end +end + +return ft diff --git a/.config/nvim/lua/utils/init.lua b/.config/nvim/lua/utils/init.lua index bad55ce..1176e3b 100644 --- a/.config/nvim/lua/utils/init.lua +++ b/.config/nvim/lua/utils/init.lua @@ -1,4 +1,6 @@ local utils = {} +local Log = require "core.log" +local uv = vim.loop -- recursive Print (structure, limit, separator) local function r_inspect_settings(structure, limit, separator) @@ -16,7 +18,7 @@ local function r_inspect_settings(structure, limit, separator) if ts == "table" then for k, v in pairs(structure) do - -- replace non alpha keys wih ["key"] + -- replace non alpha keys with ["key"] if tostring(k):match "[^%a_]" then k = '["' .. tostring(k) .. '"]' end @@ -35,9 +37,9 @@ local function r_inspect_settings(structure, limit, separator) separator = separator:gsub("%.%[", "%[") if type(structure) == "function" then -- don't print functions - io.write("-- O", separator:sub(2), " = function ()\n") + io.write("-- options", separator:sub(2), " = function ()\n") else - io.write("O", separator:sub(2), " = ", tostring(structure), "\n") + io.write("options", separator:sub(2), " = ", tostring(structure), "\n") end return limit - 1 end @@ -49,24 +51,55 @@ function utils.generate_settings() -- sets the default output file as test.lua io.output(file) - -- write all `O` related settings to `settings.lua` file - r_inspect_settings(O, 10000, ".") + -- write all `options` related settings to `lv-settings.lua` file + r_inspect_settings(options, 10000, ".") -- closes the open file io.close(file) end +-- autoformat +function utils.toggle_autoformat() + if options.format_on_save then + require("core.autocmds").define_augroups { + autoformat = { + { + "BufWritePre", + "*", + ":silent lua vim.lsp.buf.formatting_sync()", + }, + }, + } + if Log:get_default() then + Log:get_default().info "Format on save active" + end + end + + if not options.format_on_save then + vim.cmd [[ + if exists('#autoformat#BufWritePre') + :autocmd! autoformat + endif + ]] + if Log:get_default() then + Log:get_default().info "Format on save off" + end + end +end + function utils.reload_config() - vim.cmd "source ~/.config/nvim/config.lua" + vim.cmd "source ~/.config/nvim/lua/settings.lua" + vim.cmd("source " .. USER_CONFIG_PATH) + require("keymappings").setup() vim.cmd "source ~/.config/nvim/lua/plugins.lua" local plugins = require "plugins" local plugin_loader = require("plugin-loader").init() - plugin_loader:load { plugins, O.user_plugins } - vim.cmd "source ~/.config/nvim/lua/settings.lua" - vim.cmd "source ~/.config/nvim/lua/core/formatter.lua" + utils.toggle_autoformat() + plugin_loader:load { plugins, options.plugins } vim.cmd ":PackerCompile" vim.cmd ":PackerInstall" -- vim.cmd ":PackerClean" + Log:get_default().info "Reloaded configuration" end function utils.check_lsp_client_active(name) @@ -79,52 +112,42 @@ function utils.check_lsp_client_active(name) return false end -function utils.add_keymap(mode, opts, keymaps) - for _, keymap in ipairs(keymaps) do - vim.api.nvim_set_keymap(mode, keymap[1], keymap[2], opts) +function utils.get_active_client_by_ft(filetype) + local clients = vim.lsp.get_active_clients() + for _, client in pairs(clients) do + if client.name == options.lang[filetype].lsp.provider then + return client + end end + return nil end -function utils.add_keymap_normal_mode(opts, keymaps) - utils.add_keymap("n", opts, keymaps) -end +-- TODO: consider porting this logic to null-ls instead +function utils.get_supported_linters_by_filetype(filetype) + local null_ls = require "null-ls" + local matches = {} + for _, provider in pairs(null_ls.builtins.diagnostics) do + if vim.tbl_contains(provider.filetypes, filetype) then + local provider_name = provider.name -function utils.add_keymap_visual_mode(opts, keymaps) - utils.add_keymap("v", opts, keymaps) -end - -function utils.add_keymap_visual_block_mode(opts, keymaps) - utils.add_keymap("x", opts, keymaps) -end - -function utils.add_keymap_insert_mode(opts, keymaps) - utils.add_keymap("i", opts, keymaps) -end + table.insert(matches, provider_name) + end + end -function utils.add_keymap_term_mode(opts, keymaps) - utils.add_keymap("t", opts, keymaps) + return matches end -function utils.define_augroups(definitions) -- {{{1 - -- Create autocommand groups based on the passed definitions - -- - -- The key will be the name of the group, and each definition - -- within the group should have: - -- 1. Trigger - -- 2. Pattern - -- 3. Text - -- just like how they would normally be defined from Vim itself - for group_name, definition in pairs(definitions) do - vim.cmd("augroup " .. group_name) - vim.cmd "autocmd!" - - for _, def in pairs(definition) do - local command = table.concat(vim.tbl_flatten { "autocmd", def }, " ") - vim.cmd(command) +function utils.get_supported_formatters_by_filetype(filetype) + local null_ls = require "null-ls" + local matches = {} + for _, provider in pairs(null_ls.builtins.formatting) do + if provider.filetypes and vim.tbl_contains(provider.filetypes, filetype) then + -- table.insert(matches, { provider.name, ft }) + table.insert(matches, provider.name) end - - vim.cmd "augroup END" end + + return matches end function utils.unrequire(m) @@ -132,80 +155,6 @@ function utils.unrequire(m) _G[m] = nil end -utils.define_augroups { - - _general_settings = { - { - "TextYankPost", - "*", - "lua require('vim.highlight').on_yank({higroup = 'Search', timeout = 200})", - }, - { - "BufWinEnter", - "*", - "setlocal formatoptions-=c formatoptions-=r formatoptions-=o", - }, - { - "BufWinEnter", - "dashboard", - "setlocal cursorline signcolumn=yes cursorcolumn number", - }, - { - "BufRead", - "*", - "setlocal formatoptions-=c formatoptions-=r formatoptions-=o", - }, - { - "BufNewFile", - "*", - "setlocal formatoptions-=c formatoptions-=r formatoptions-=o", - }, - { "BufWritePost", "config.lua", "lua require('utils').reload_config()" }, - -- { "VimLeavePre", "*", "set title set titleold=" }, - }, - _solidity = { - { "BufWinEnter", ".tf", "setlocal filetype=hcl" }, - { "BufRead", "*.tf", "setlocal filetype=hcl" }, - { "BufNewFile", "*.tf", "setlocal filetype=hcl" }, - }, - -- _solidity = { - -- {'BufWinEnter', '.sol', 'setlocal filetype=solidity'}, {'BufRead', '*.sol', 'setlocal filetype=solidity'}, - -- {'BufNewFile', '*.sol', 'setlocal filetype=solidity'} - -- }, - -- _gemini = { - -- {'BufWinEnter', '.gmi', 'setlocal filetype=markdown'}, {'BufRead', '*.gmi', 'setlocal filetype=markdown'}, - -- {'BufNewFile', '*.gmi', 'setlocal filetype=markdown'} - -- }, - _markdown = { - { "FileType", "markdown", "setlocal wrap" }, - { "FileType", "markdown", "setlocal spell" }, - }, - _buffer_bindings = { - { "FileType", "floaterm", "nnoremap <silent> <buffer> q :q<CR>" }, - }, - _auto_resize = { - -- will cause split windows to be resized evenly if main window is resized - { "VimResized", "*", "wincmd =" }, - }, - _packer_compile = { - -- will cause split windows to be resized evenly if main window is resized - { "BufWritePost", "plugins.lua", "PackerCompile" }, - }, - - -- _fterm_lazygit = { - -- -- will cause esc key to exit lazy git - -- {"TermEnter", "*", "call LazyGitNativation()"} - -- }, - -- _mode_switching = { - -- -- will switch between absolute and relative line numbers depending on mode - -- {'InsertEnter', '*', 'if &relativenumber | let g:ms_relativenumberoff = 1 | setlocal number norelativenumber | endif'}, - -- {'InsertLeave', '*', 'if exists("g:ms_relativenumberoff") | setlocal relativenumber | endif'}, - -- {'InsertEnter', '*', 'if &cursorline | let g:ms_cursorlineoff = 1 | setlocal nocursorline | endif'}, - -- {'InsertLeave', '*', 'if exists("g:ms_cursorlineoff") | setlocal cursorline | endif'}, - -- }, - _user_autocommands = O.user_autocommands, -} - function utils.gsub_args(args) if args == nil or type(args) ~= "table" then return args @@ -217,16 +166,12 @@ function utils.gsub_args(args) return args end -vim.cmd [[ - function! QuickFixToggle() - if empty(filter(getwininfo(), 'v:val.quickfix')) - copen - else - cclose - endif -endfunction -]] +--- Checks whether a given path exists and is a file. +--@param filename (string) path to check +--@returns (bool) +function utils.is_file(filename) + local stat = uv.fs_stat(filename) + return stat and stat.type == "file" or false +end return utils - --- TODO: find a new home for these autocommands" |