diff --git a/lua/hover/actions.lua b/lua/hover/actions.lua index 05b8ee4..5be9719 100644 --- a/lua/hover/actions.lua +++ b/lua/hover/actions.lua @@ -14,15 +14,21 @@ local initialised = false --- @param provider Hover.Provider --- @param bufnr integer +--- @param opts? Hover.Options --- @return boolean -local function is_enabled(provider, bufnr) - return provider.enabled == nil or provider.enabled(bufnr) +local function is_enabled(provider, bufnr, opts) + opts = opts or {} + opts.bufnr = opts.bufnr or bufnr + opts.pos = opts.pos or api.nvim_win_get_cursor(0) + + return provider.enabled == nil or provider.enabled(opts.bufnr, opts) end --- @param bufnr integer --- @param winnr integer --- @param active_provider_id integer -local function add_title(bufnr, winnr, active_provider_id) +--- @param opts Hover.Options +local function add_title(bufnr, winnr, active_provider_id, opts) if not has_winbar then vim.notify_once('hover.nvim: `config.title` requires neovim >= 0.8.0', vim.log.levels.WARN) return @@ -33,7 +39,7 @@ local function add_title(bufnr, winnr, active_provider_id) local winbar_length = 0 for _, p in ipairs(providers) do - if is_enabled(p, bufnr) then + if is_enabled(p, bufnr, opts) then local hl = p.id == active_provider_id and 'TabLineSel' or 'TabLineFill' title[#title + 1] = string.format('%%#%s# %s ', hl, p.name) title[#title + 1] = '%#Normal# ' @@ -156,7 +162,7 @@ local function show_hover(bufnr, provider_id, config, result, opts) local winid = util.open_floating_preview(result.lines, result.bufnr, result.filetype, opts) if config.title then - add_title(bufnr, winid, provider_id) + add_title(bufnr, winid, provider_id, opts) end vim.w[winid].hover_provider = provider_id @@ -233,7 +239,7 @@ M.hover = async.void(function(opts) for _, provider in ipairs(providers) do if not opts or not opts.providers or vim.tbl_contains(opts.providers, provider.name) then async.scheduler() - if use_provider and is_enabled(provider, bufnr) and run_provider(provider, opts) then + if use_provider and is_enabled(provider, bufnr, opts) and run_provider(provider, opts) then return end if provider.id == current_provider then @@ -245,7 +251,7 @@ M.hover = async.void(function(opts) for _, provider in ipairs(providers) do if not opts or not opts.providers or vim.tbl_contains(opts.providers, provider.name) then async.scheduler() - if is_enabled(provider, bufnr) and run_provider(provider, opts) then + if is_enabled(provider, bufnr, opts) and run_provider(provider, opts) then return end end @@ -269,7 +275,7 @@ function M.hover_switch(direction, opts) if p.id == current_provider then provider_idx = provider_count end - if is_enabled(p, bufnr) then + if is_enabled(p, bufnr, opts) then active_providers[provider_count] = n provider_count = provider_count + 1 end @@ -299,7 +305,7 @@ function M.hover_select(opts) --- @param provider Hover.Provider --- @return boolean vim.tbl_filter(function(provider) - return is_enabled(provider, bufnr) + return is_enabled(provider, bufnr, opts) end, providers), { prompt = 'Select hover:', diff --git a/lua/hover/providers.lua b/lua/hover/providers.lua index 00ff55a..34a959c 100644 --- a/lua/hover/providers.lua +++ b/lua/hover/providers.lua @@ -12,7 +12,7 @@ local M = {} --- @field priority integer --- @field name string --- @field execute fun(opts?: Hover.Options, done: fun(result?: Hover.Result)) ---- @field enabled fun(bufnr: integer): boolean +--- @field enabled fun(bufnr: integer, opts?: Hover.Options): boolean --- @class Hover.Provider : Hover.RegisterProvider --- @field id integer diff --git a/lua/hover/providers/diagnostic.lua b/lua/hover/providers/diagnostic.lua index 720913f..5778082 100644 --- a/lua/hover/providers/diagnostic.lua +++ b/lua/hover/providers/diagnostic.lua @@ -39,15 +39,14 @@ local function count_sources(diagnostics) end --- @param diagnostics vim.Diagnostic[] +--- @param lnum integer +--- @param col integer --- @param bufnr integer --- @return vim.Diagnostic[] -local function filter_diagnostics(diagnostics, bufnr) +local function filter_diagnostics(diagnostics, lnum, col, bufnr) local float_opts = get_float_opts() local scope = float_opts.scope or 'line' - local pos = api.nvim_win_get_cursor(0) - local lnum = pos[1] - 1 - local col = pos[2] if scope == 'line' then --- @param d vim.Diagnostic --- @return boolean @@ -72,10 +71,13 @@ local function filter_diagnostics(diagnostics, bufnr) end --- @param bufnr integer +--- @param opts? Hover.Options --- @return boolean -local function enabled(bufnr) +local function enabled(bufnr, opts) local buffer_diagnostics = vim.diagnostic.get(bufnr) - local diagnostics = filter_diagnostics(buffer_diagnostics, bufnr) + local pos = opts and opts.pos or api.nvim_win_get_cursor(0) + local lnum, col = pos[1] - 1, pos[2] + local diagnostics = filter_diagnostics(buffer_diagnostics, lnum, col, bufnr) return #diagnostics ~= 0 end @@ -83,7 +85,8 @@ end --- @param done fun(result?: Hover.Result) local function execute(opts, done) local buffer_diagnostics = vim.diagnostic.get(opts.bufnr) - local diagnostics = filter_diagnostics(buffer_diagnostics, opts.bufnr) + local lnum, col = opts.pos[1] - 1, opts.pos[2] + local diagnostics = filter_diagnostics(buffer_diagnostics, lnum, col, opts.bufnr) local float_opts = get_float_opts() diff --git a/lua/hover/providers/fold_preview.lua b/lua/hover/providers/fold_preview.lua index 385f781..47a550f 100644 --- a/lua/hover/providers/fold_preview.lua +++ b/lua/hover/providers/fold_preview.lua @@ -28,16 +28,27 @@ set_border_shift(config.preview_opts.border) hover.register({ name = 'Fold Preview', - enabled = function() - return fn.foldclosed(fn.line('.')) ~= -1 + enabled = function(bufnr, opts) + local pos = opts and opts.pos or api.nvim_win_get_cursor(0) + local lnum = pos[1] + + return vim.api.nvim_buf_call(bufnr, function() + return fn.foldclosed(lnum) ~= -1 + end) end, - execute = function(_opts, done) - local cur_line = fn.line('.') - local fold_start = fn.foldclosed(cur_line) - local fold_end = fn.foldclosedend(cur_line) + execute = function(opts, done) + local cur_bufnr = opts and opts.bufnr or api.nvim_get_current_buf() + local cur_pos = opts and opts.pos or api.nvim_win_get_cursor(0) + local cur_line = cur_pos[1] + + local fold_bounds = vim.api.nvim_buf_call(cur_bufnr, function() + return { fn.foldclosed(cur_line), fn.foldclosedend(cur_line) } + end) + + --- @cast fold_bounds {[1]: integer, [2]: integer} - local cur_win = api.nvim_get_current_win() - local cur_bufnr = api.nvim_win_get_buf(cur_win) + local fold_start = fold_bounds[1] + local fold_end = fold_bounds[2] local folded_lines = api.nvim_buf_get_lines(cur_bufnr, fold_start - 1, fold_end, true)