diff --git a/lua/lsp-toggle.lua b/lua/lsp-toggle.lua index 8c2ea0e..9aaddc4 100644 --- a/lua/lsp-toggle.lua +++ b/lua/lsp-toggle.lua @@ -5,6 +5,11 @@ local M = {} ---@param opts? LspToggle.Opts function M.setup(opts) + if vim.fn.has('nvim-0.11') == 1 then + vim.validate('opts', opts, 'table', true, 'LspToggle.Opts?') + else + vim.validate({ opts = { opts, { 'table', 'nil' } } }) + end config.setup(opts or {}) end diff --git a/lua/lsp-toggle/config.lua b/lua/lsp-toggle/config.lua index ca4247d..d2012d5 100644 --- a/lua/lsp-toggle/config.lua +++ b/lua/lsp-toggle/config.lua @@ -5,9 +5,11 @@ local utils = require('lsp-toggle.utils') ---@class LspToggle.Opts local defaults = { --- If less than `1`, this will revert back to `20` + ---@type integer max_height = 20, --- If less than `1`, this will revert back to `30` + ---@type integer max_width = 30, --- A list of LSP server names to exclude, @@ -18,11 +20,12 @@ local defaults = { ---@type string[]|'double'|'none'|'rounded'|'shadow'|'single'|'solid' border = { '╔', '-', '╗', '║', '╝', '═', '╚', '║' }, - -- Enable/Disable caching + --- Enable/Disable caching + ---@type boolean cache = true, } ----@class LspToggleConfig +---@class LspToggle.Config local M = {} ---@type LspToggle.Opts @@ -30,56 +33,57 @@ M.options = {} ---@param opts? LspToggle.Opts function M.setup(opts) + if vim.fn.has('nvim-0.11') == 1 then + vim.validate('opts', opts, 'table', true, 'LspToggle.Opts?') + else + vim.validate({ opts = { opts, { 'table', 'nil' } } }) + end opts = opts or {} M.options = vim.tbl_deep_extend('keep', opts, defaults) - if M.options.max_height <= 0 then + if not M.options.max_height or M.options.max_height <= 0 then M.options.max_height = defaults.max_height end - if M.options.max_width <= 0 then + if not M.options.max_width or M.options.max_width <= 0 then M.options.max_width = defaults.max_width end M.setup_autocmds() end -function M.setup_autocmds() - local load_cache = function() - local opts = require('lsp-toggle.config').options - if not opts.cache then - return - end - utils.merge_table_pf() -- merge saved data before enabling/disabling clients - for _, tb_server in pairs(utils.clients) do - vim.lsp.enable(tb_server.server_name, tb_server.enabled) - end +function M.load_cache() + if not M.options.cache then + return + end + utils.merge_table_pf() -- merge saved data before enabling/disabling clients + for _, tb_server in pairs(utils.clients) do + vim.lsp.enable(tb_server.server_name, tb_server.enabled) + end +end + +---@param args vim.api.keyset.create_autocmd.callback_args +local function callback(args) + if vim.bo[args.buf].buftype ~= '' then + return end - local augroup = vim.api.nvim_create_augroup('lsp-toggle', { clear = false }) + fileutils.set_file_path(vim.api.nvim_buf_get_name(args.buf)) + M.load_cache() +end + +function M.setup_autocmds() + local augroup = vim.api.nvim_create_augroup('lsp-toggle', { clear = true }) vim.api.nvim_create_autocmd('LspAttach', { group = augroup, - callback = function() - if vim.bo.buftype ~= '' then - return - end - - fileutils.set_file_path(vim.api.nvim_buf_get_name(0)) - load_cache() - end, + callback = callback, }) - vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWinEnter' }, { - callback = function(args) - if vim.bo[args.buf].buftype ~= '' then - return - end - - fileutils.set_file_path(vim.api.nvim_buf_get_name(args.buf)) - load_cache() - end, + vim.api.nvim_create_autocmd('BufEnter', { + group = augroup, + callback = callback, }) vim.api.nvim_create_autocmd('BufLeave', { diff --git a/lua/lsp-toggle/fileutils.lua b/lua/lsp-toggle/fileutils.lua index dad6076..22ab0b5 100644 --- a/lua/lsp-toggle/fileutils.lua +++ b/lua/lsp-toggle/fileutils.lua @@ -1,3 +1,4 @@ +---@class LspToggleFileUtils local M = {} M.root_dir = vim.fn.stdpath('cache') .. '/lsp-toggle' @@ -8,6 +9,12 @@ M.file_path = '' ---@param str string ---@return string hash local function djb2(str) + if vim.fn.has('nvim-0.11') == 1 then + vim.validate('str', str, 'string', false) + else + vim.validate({ str = { str, 'string' } }) + end + local hash = 5381 for i = 1, str:len() do local c = str:byte(i) @@ -17,47 +24,53 @@ local function djb2(str) return tostring(hash) end ----@param path string +---@param path? string function M.set_file_path(path) - M.file_path = path + if vim.fn.has('nvim-0.11') == 1 then + vim.validate('path', path, 'string', true) + else + vim.validate({ path = { path, { 'string', 'nil' } } }) + end + + M.file_path = path or M.file_path end ---@return string function M.produce_path() - if vim.fn.mkdir(M.root_dir, 'p') ~= 1 then - error('[File] Failed to create directory!', vim.log.levels.ERROR) + if not vim.fn.isdirectory(M.root_dir) then + local dir_fd = vim.uv.fs_mkdir(M.root_dir, tonumber('755', 8)) + if not dir_fd then + error('[FILE] Failed to create directory!', vim.log.levels.ERROR) + end end return string.format('%s/%s.json', M.root_dir, djb2(M.file_path)) end ----@param data table +---@param data table ---@return boolean|nil function M.save(data) - local path = M.produce_path() - - if not path then - return nil + if vim.fn.has('nvim-0.11') == 1 then + vim.validate('data', data, 'table', false, 'table') + else + vim.validate({ data = { data, 'table' } }) end + local path = M.produce_path() local fd = vim.uv.fs_open(path, 'w', tonumber('644', 8)) if not fd then return nil end - vim.uv.fs_write(fd, vim.fn.json_encode(data)) + vim.uv.fs_write(fd, vim.fn.json_encode(data), -1) vim.uv.fs_close(fd) return true end ----@return table|nil +---@return table|nil function M.load() -- returns lspClients local path = M.produce_path() - if not path then - return nil - end - local stat = vim.uv.fs_stat(path) if not stat then return nil @@ -69,7 +82,7 @@ function M.load() return nil end - local content = vim.uv.fs_read(fd, stat.size) + local content = vim.uv.fs_read(fd, stat.size, -1) vim.uv.fs_close(fd) if not content then return nil @@ -79,19 +92,31 @@ function M.load() end ---@param path? string +---@return boolean? result function M.clear_cache(path) + if vim.fn.has('nvim-0.11') == 1 then + vim.validate('path', path, 'string', true) + else + vim.validate({ path = { path, { 'string', 'nil' } } }) + end path = path or M.root_dir local stat = vim.uv.fs_stat(path) if not stat or stat.type ~= 'directory' then - vim.notify('No cache to clear!', vim.log.levels.WARN) + vim.notify('[FILE] No cache to clear!', vim.log.levels.WARN) return nil end local dir = vim.uv.fs_scandir(path) + if not dir then + vim.notify('[FILE] Unable to scan directory!', vim.log.levels.ERROR) + return nil + end + + local success = true - while true do + while success do ---@type string?, 'directory'|'file'? local item, item_type = vim.uv.fs_scandir_next(dir) @@ -102,13 +127,12 @@ function M.clear_cache(path) item = path .. '/' .. item if item_type == 'file' then - vim.uv.fs_unlink(item) - elseif item_type == 'directory' then - M.clear_cache(item) + success = vim.uv.fs_unlink(item) end end - return vim.uv.fs_rmdir(path) + success = vim.uv.fs_rmdir(path) + return success end return M diff --git a/lua/lsp-toggle/toggle.lua b/lua/lsp-toggle/toggle.lua index fae4a8e..635da19 100644 --- a/lua/lsp-toggle/toggle.lua +++ b/lua/lsp-toggle/toggle.lua @@ -3,14 +3,16 @@ local file = require('lsp-toggle.fileutils') local window = require('lsp-toggle.window') local utils = require('lsp-toggle.utils') +---@class LspToggle.Toggle local M = {} function M.handle_toggle() local opts = require('lsp-toggle.config').options + local win = window.window_id + local bufnr = window.window_buf - local cursor_pos = vim.api.nvim_win_get_cursor(0) - local cursor_line = cursor_pos[1] - local line_text = vim.api.nvim_buf_get_lines(0, cursor_line - 1, cursor_line, false)[1] + local cursor_line = vim.api.nvim_win_get_cursor(win)[1] + local line_text = vim.api.nvim_buf_get_lines(bufnr, cursor_line - 1, cursor_line, false)[1] local server_name = line_text:sub(5) for name, tb_server in pairs(utils.clients) do diff --git a/lua/lsp-toggle/utils.lua b/lua/lsp-toggle/utils.lua index 63af8b3..eb45161 100644 --- a/lua/lsp-toggle/utils.lua +++ b/lua/lsp-toggle/utils.lua @@ -1,8 +1,13 @@ local fileutils = require('lsp-toggle.fileutils') +---@class LspToggleUtils.Client +---@field enabled boolean +---@field server_name string + +---@class LspToggleUtils local M = {} ----@type table +---@type table M.clients = {} function M.load_all_clients() @@ -15,7 +20,7 @@ function M.load_all_clients() enabled = vim.lsp.is_enabled(client.name), server_name = client.name, } - else + elseif vim.list_contains(vim.tbl_keys(M.clients), client.name) then M.clients[client.name] = nil end end @@ -25,13 +30,13 @@ function M.merge_table_pf() local opts = require('lsp-toggle.config').options M.load_all_clients() - local file_clients = opts.cache and fileutils.load() or {} + local file_clients = opts.cache and (fileutils.load() or {}) or {} local excluded = require('lsp-toggle.config').options.exclude_lsp -- merge tables with priority to file for name, client in pairs(M.clients) do local added = false - if not vim.tbl_contains(excluded, name) then + if not vim.list_contains(excluded, name) then for fname, fclient in pairs(file_clients) do if fname == name then M.clients[fname] = fclient diff --git a/lua/lsp-toggle/window.lua b/lua/lsp-toggle/window.lua index eaee717..bc47a2b 100644 --- a/lua/lsp-toggle/window.lua +++ b/lua/lsp-toggle/window.lua @@ -1,9 +1,12 @@ local utils = require('lsp-toggle.utils') +---@class LspToggle.Window local M = {} + +---@type string[] M.out_buf_table = {} ----@param clients table +---@param clients table function M.print_display(clients) M.out_buf_table = {} for _, tb_server in pairs(clients) do @@ -71,10 +74,12 @@ function M.open_window() end function M.close_window() - if M.window_id then - vim.api.nvim_win_close(M.window_id, true) - M.window_id = nil + if not M.window_id then + return end + + vim.api.nvim_win_close(M.window_id, true) + M.window_id = nil end return M diff --git a/plugin/lsp-toggle.lua b/plugin/lsp-toggle.lua index 94cccd1..b5f65c0 100644 --- a/plugin/lsp-toggle.lua +++ b/plugin/lsp-toggle.lua @@ -16,8 +16,10 @@ end, { }) vim.api.nvim_create_user_command('ToggleLSPClearCache', function() - fileutils.clear_cache() - vim.notify('Cleared cache, you should probably restart nvim', vim.log.levels.WARN) + local notify = fileutils.clear_cache() + if notify then + vim.notify('Cleared cache, you should probably restart nvim', vim.log.levels.WARN) + end end, { desc = 'Clear the local cache for lsp-toggle' }) -- vim:ts=4:sts=4:sw=0:noet:ai:si:sta: