Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lua/lsp-toggle.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
68 changes: 36 additions & 32 deletions lua/lsp-toggle/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -18,68 +20,70 @@ 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
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', {
Expand Down
68 changes: 46 additions & 22 deletions lua/lsp-toggle/fileutils.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
---@class LspToggleFileUtils
local M = {}

M.root_dir = vim.fn.stdpath('cache') .. '/lsp-toggle'
Expand All @@ -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)
Expand All @@ -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<string, { enabled: boolean, server_name: string }>
---@param data table<string, LspToggleUtils.Client>
---@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<string, LspToggleUtils.Client>')
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<string, { enabled: boolean, server_name: string }>|nil
---@return table<string, LspToggleUtils.Client>|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
Expand All @@ -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
Expand All @@ -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)

Expand All @@ -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
Expand Down
8 changes: 5 additions & 3 deletions lua/lsp-toggle/toggle.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 9 additions & 4 deletions lua/lsp-toggle/utils.lua
Original file line number Diff line number Diff line change
@@ -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<string, { enabled: boolean, server_name: string }>
---@type table<string, LspToggleUtils.Client>
M.clients = {}

function M.load_all_clients()
Expand All @@ -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
Expand All @@ -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
Expand Down
13 changes: 9 additions & 4 deletions lua/lsp-toggle/window.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
local utils = require('lsp-toggle.utils')

---@class LspToggle.Window
local M = {}

---@type string[]
M.out_buf_table = {}

---@param clients table<string, { enabled: boolean, server_name: string }>
---@param clients table<string, LspToggleUtils.Client>
function M.print_display(clients)
M.out_buf_table = {}
for _, tb_server in pairs(clients) do
Expand Down Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions plugin/lsp-toggle.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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: