diff --git a/README.md b/README.md index 47b1da9..70994ea 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ With Lazy: ```lua ---@module "neominimap.config.meta" { - "Isrothy/neominimap.nvim", + "Isrothy/neominimap.nvim", version = "v3.x.x", lazy = false, -- NOTE: NO NEED to Lazy load -- Optional. You can alse set your own keybindings @@ -275,7 +275,7 @@ vim.g.neominimap = { --- Border style of the floating window. --- Accepts all usual border style options (e.g., "single", "double") --- @type string | string[] | [string, string][] - window_border = "single", + window_border = vim.fn.has("nvim-0.11") == 1 and vim.opt.winborder:get() or "single", -- When true, the floating window will be recreated when you close it. -- When false, the minimap will be disabled for the current tab when you close the minimap window. @@ -298,7 +298,24 @@ vim.g.neominimap = { diagnostic = { enabled = true, ---@type boolean - severity = vim.diagnostic.severity.WARN, ---@type vim.diagnostic.SeverityInt + + -- When enabled, diagnostics will be sourced directly from the DiagnosticChanged event, + -- meaning they will follow the settings from vim.diagnostic.config. + -- In this mode, the `severity` filter is ignored. + use_event_diagnostics = false, ---@type boolean + + -- The `severity` option specifies which diagnostics to include based on their severity. + -- Note: This option is ignored when `use_event_diagnostics` is enabled. + -- + -- Allowed formats for the `severity` filter: + -- 1. A single severity level: + -- eg: severity = vim.diagnostic.severity.WARN + -- 2. A table with a "min" and/or "max" key: + -- eg: severity = { min = vim.diagnostic.severity.WARN, max = vim.diagnostic.severity.ERROR } + -- 3. A list-like table of severity values: + -- eg: severity = { vim.diagnostic.severity.WARN, vim.diagnostic.severity.ERROR } + ---@see vim.diagnostic.severity + severity = nil, ---@type vim.diagnostic.SeverityFilter? mode = "line", ---@type Neominimap.Handler.Annotation.Mode priority = { ERROR = 100, ---@type integer @@ -504,27 +521,27 @@ To refresh the minimap for windows 3 and 4: - Global API - - `require('neominimap').on()` + - `require('neominimap.api').enable()` - **Description:** Enable the minimap globally across all buffers and windows. - **Arguments:** None - - `require('neominimap').off()` + - `require('neominimap.api').disable()` - **Description:** Disable the minimap globally. - **Arguments:** None - - `require('neominimap').toggle()` + - `require('neominimap.api').toggle()` - **Description:** Toggle the minimap on or off globally. - **Arguments:** None - - `require('neominimap').refresh()` + - `require('neominimap.api').refresh()` - **Description:** Refresh the minimap globally. - **Arguments:** None - - `require('neominimap').enabled()` + - `require('neominimap.api').enabled()` - **Description:** Check if the minimap is enabled globally. - **Arguments:** None @@ -532,56 +549,56 @@ To refresh the minimap for windows 3 and 4: - Buffer API - - `require('neominimap').bufOn()` + - `require('neominimap.api').buf.enable()` - **Description:** Enable the minimap for specified buffers. - - **Arguments:** List of buffer numbers (defaults to current buffer if list is empty) + - **Arguments:** None (defaults to current buffer), or an integer or a list of buffer numbers - - `require('neominimap').bufOff()` + - `require('neominimap.api').buf.disable()` - **Description:** Disable the minimap for specified buffers. - - **Arguments:** List of buffer numbers (defaults to current buffer if list is empty) + - **Arguments:** None (defaults to current buffer), or an integer or a list of buffer numbers - - `require('neominimap').bufToggle()` + - `require('neominimap.api').buf.toggle()` - **Description:** Toggle the minimap for specified buffers. - - **Arguments:** List of buffer numbers (defaults to current buffer if list is empty) + - **Arguments:** None (defaults to current buffer), or an integer or a list of buffer numbers - - `require('neominimap').bufRefresh()` + - `require('neominimap.api').buf.refresh()` - **Description:** Refresh the minimap buffers for specified buffers. - - **Arguments:** List of buffer numbers (defaults to current buffer if list is empty) + - **Arguments:** None (defaults to current buffer), or an integer or a list of buffer numbers - - `require('neominimap').bufEnabled(bufnr)` + - `require('neominimap').buf.enabled(bufnr)` - **Description:** Check if the minimap is enabled for specified buffers. - **Arguments:** A buffer number. If no buffer is specified, check for the current buffer. - **Returns:** `true` if the minimap is enabled, `false` otherwise -- Tabpage API +- Tab API - - `require('neominimap').tabOn()`\* + - `require('neominimap.api').tab.enable()` - **Description:** Enable the minimap for specified tabpages. - - **Arguments:** List of tabpage IDs (defaults to current tabpage if list is empty) + - **Arguments:** None (defaults to current tabage), or an integer or a list of tabpage IDs - - `require('neominimap').tabOff()` + - `require('neominimap.api').tab.disable()` - **Description:** Disable the minimap for specified tabpages. - - **Arguments:** List of tabpage IDs (defaults to current tabpage if list is empty) + - **Arguments:** None (defaults to current tabage), or an integer or a list of tabpage IDs - - `require('neominimap').tabToggle()` + - `require('neominimap.api').tab.toggle()` - **Description:** Toggle the minimap for specified tabpages. - - **Arguments:** List of tabpage IDs (defaults to current tabpage if list is empty) + - **Arguments:** None (defaults to current tabage), or an integer or a list of tabpage IDs - - `require('neominimap').tabRefresh(tabid)` + - `require('neominimap.api').tab.refresh()` - **Description:** Refresh the minimap tabs for specified tabpages. - - **Arguments:** List of tabpage IDs (defaults to current tabpage if list is empty) + - **Arguments:** None (defaults to current tabage), or an integer or a list of tabpage IDs - - `require('neominimap').tabEnabled(tabid)` + - `require('neominimap').tab.enabled(tabid)` - **Description:** Check if the minimap is enabled for specified tabpages. - **Arguments:** A tabpage ID. If no tabpage is specified, check for the @@ -590,27 +607,27 @@ To refresh the minimap for windows 3 and 4: - Window API - - `require('neominimap').winOn()` + - `require('neominimap.api').win.enable()` - **Description:** Enable the minimap for specified windows. - - **Arguments:** List of window IDs (defaults to current window if list is empty) + - **Arguments:** None (defaults to current window), or an integer or a list of window IDs - - `require('neominimap').winOff()` + - `require('neominimap.api').win.disable()` - **Description:** Disable the minimap for specified windows. - - **Arguments:** List of window IDs (defaults to current window if list is empty) + - **Arguments:** None (defaults to current window), or an integer or a list of window IDs - - `require('neominimap').winToggle()` + - `require('neominimap.api').win.toggle()` - **Description:** Toggle the minimap for specified windows. - - **Arguments:** List of window IDs (defaults to current window if list is empty) + - **Arguments:** None (defaults to current window), or an integer or a list of window IDs - - `require('neominimap').winRefresh()` + - `require('neominimap.api').win.refresh()` - **Description:** Refresh the minimap windows for specified windows. - - **Arguments:** List of window IDs (defaults to current window if list is empty) + - **Arguments:** None (defaults to current window), or an integer or a list of window IDs - - `require('neominimap').winEnabled(winid)` + - `require('neominimap').win.enable(winid)` - **Description:** Check if the minimap is enabled for specified windows. - **Arguments:** A window ID. If no window is specified, check for the @@ -619,20 +636,80 @@ To refresh the minimap for windows 3 and 4: - Focus Control - - `require('neominimap').focus()` + - `require('neominimap.api').focus.enable()` - **Description:** Focus the minimap window, allowing interaction with it. - **Arguments:** None - - `require('neominimap').unfocus()` + - `require('neominimap.api').focus.disable()` - **Description:** Unfocus the minimap window, returning focus to the editor. - **Arguments:** None - - `require('neominimap').toggleFocus()` + - `require('neominimap.api').focus.toggle()` - **Description:** Toggle focus between the minimap and the main editor window. - **Arguments:** None - + +### Migration Guide + +
+ Click to expand + +The neominimap API has been updated to provide a more intuitive and flexible interface. +The old API is now deprecated and will eventually be removed. +This guide will help you transition to the new neominimap.api. + +| Old Function | New Function | +| ----------------------------------- | ----------------------------------------- | +| `require('neominimap').on` | `require('neominimap.api').enable` | +| `require('neominimap').off` | `require('neominimap.api').disable` | +| `require('neominimap').toggle` | `require('neominimap.api').toggle` | +| `require('neominimap').refresh` | `require('neominimap.api').refresh` | +| `require('neominimap').enabled` | `require('neominimap.api').enabled` | +| `require('neominimap').bufOn` | `require('neominimap.api').buf.enable` | +| `require('neominimap').bufOff` | `require('neominimap.api').buf.disable` | +| `require('neominimap').bufToggle` | `require('neominimap.api').buf.toggle` | +| `require('neominimap').bufRefresh` | `require('neominimap.api').buf.refresh` | +| `require('neominimap').bufEnabled` | `require('neominimap.api').buf.enabled` | +| `require('neominimap').tabOn` | `require('neominimap.api').tab.disable` | +| `require('neominimap').tabOff` | `require('neominimap.api').tab.disable` | +| `require('neominimap').tabToggle` | `require('neominimap.api').tab.toggle` | +| `require('neominimap').tabRefresh` | `require('neominimap.api').tab.refresh` | +| `require('neominimap').tabEnabled` | `require('neominimap.api').tab.enabled` | +| `require('neominimap').winOn` | `require('neominimap.api').win.enable` | +| `require('neominimap').winOff` | `require('neominimap.api').win.disable` | +| `require('neominimap').winToggle` | `require('neominimap.api').win.toggle` | +| `require('neominimap').winEnabled` | `require('neominimap.api').win.enabled` | +| `require('neominimap').winRefresh` | `require('neominimap.api').win.refresh` | +| `require('neominimap').focus` | `require('neominimap.api').focus.enable` | +| `require('neominimap').unfocus` | `require('neominimap.api').focus.disable` | +| `require('neominimap').toggleFocus` | `require('neominimap.api').focus.toggle` | + +#### Key Differences Between the Old and New API + +| Aspect | Old API (`neominimap`).doSomeThing | New API (`neominimap.api`).do_some_thing() | +| ----------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | +| Input Type | Expects a list of integers. | Accepts `nil`, a single integer, or a list of integers. An empty list does nothing. | +| Default Behavior | Automatically defaults to the current buffer/tab/window if the input list is empty. | Explicitly requires omitted input to default to the current buffer/tab/window. | +| Design Philosophy | A wrapper for Vim commands, with implicit behaviors. | Independent of Vim commands. | + +#### Handle Input Changes + +- **Old Behavior:** Passing an empty list (`{}`) defaulted to the current buffer, tab, or window. +- **New Behavior:** Passing an empty list does nothing. + To default to the current context, pass `nil` or omit the argument. + +Here is an example: + +```lua +-- Old API +require('neominimap').bufOn({}) -- Defaults to current buffer +-- New API +require('neominimap.api').buf.enable() -- Explicitly defaults to current buffer +require('neominimap.api').buf.enable({}) -- Does nothing +``` + +
## Customized Handlers diff --git a/lua/neominimap.lua b/lua/neominimap.lua index be94737..5ba61c6 100644 --- a/lua/neominimap.lua +++ b/lua/neominimap.lua @@ -1,130 +1,185 @@ local M = {} +---@deprecated ---@type Neominimap.Command.Impl M.refresh = function(args, opts) + vim.deprecate("require('neominimap').refresh", "require('neominimap.api').refresh", "v4", "neominimap.nvim") require("neominimap.command.global").subcommand_tbl.refresh.impl(args, opts) end +---@deprecated ---@type Neominimap.Command.Impl M.on = function(args, opts) + vim.deprecate("require('neominimap').on", "require('neominimap.api').enable", "v4", "neominimap.nvim") require("neominimap.command.global").subcommand_tbl.on.impl(args, opts) end +---@deprecated ---@type Neominimap.Command.Impl M.off = function(args, opts) + vim.deprecate("require('neominimap').off", "require('neominimap.api').disable", "v4", "neominimap.nvim") require("neominimap.command.global").subcommand_tbl.off.impl(args, opts) end +---@deprecated ---@type Neominimap.Command.Impl M.toggle = function(args, opts) + vim.deprecate("require('neominimap').toggle", "require('neominimap.api').toggle", "v4", "neominimap.nvim") require("neominimap.command.global").subcommand_tbl.toggle.impl(args, opts) end +---@deprecated +--- Minimap is enabled globally +---@return boolean +M.enabled = function() + vim.deprecate("require('neominimap').enabled", "require('neominimap.api').enabled", "v4", "neominimap.nvim") + return require("neominimap.variables").g.enabled +end + +---@deprecated ---@type Neominimap.Command.Impl M.bufOn = function(args, opts) + vim.deprecate("require('neominimap').bufOn", "require('neominimap.api').buf.enable", "v4", "neominimap.nvim") require("neominimap.command.buf").subcommand_tbl.bufOn.impl(args, opts) end +---@deprecated ---@type Neominimap.Command.Impl M.bufOff = function(args, opts) + vim.deprecate("require('neominimap').bufOff", "require('neominimap.api').buf.disable", "v4", "neominimap.nvim") require("neominimap.command.buf").subcommand_tbl.bufOff.impl(args, opts) end +---@deprecated ---@type Neominimap.Command.Impl M.bufToggle = function(args, opts) + vim.deprecate("require('neominimap').bufToggle", "require('neominimap.api').buf.toggle", "v4", "neominimap.nvim") require("neominimap.command.buf").subcommand_tbl.bufToggle.impl(args, opts) end +---@deprecated ---@type Neominimap.Command.Impl M.bufRefresh = function(args, opts) + vim.deprecate("require('neominimap').bufRefresh", "require('neominimap.api').buf.refresh", "v4", "neominimap.nvim") require("neominimap.command.buf").subcommand_tbl.bufRefresh.impl(args, opts) end +---@deprecated +--- Minimap is enabled for the given buffer +---@param bufnr integer? If nil, check for the current buffer +---@return boolean +M.bufEnabled = function(bufnr) + vim.deprecate("require('neominimap').bufEnabled", "require('neominimap.api').buf.enabled", "v4", "neominimap.nvim") + if bufnr == nil then + bufnr = 0 + end + return require("neominimap.variables").b[bufnr].enabled +end + +---@deprecated ---@type Neominimap.Command.Impl M.winOn = function(args, opts) + vim.deprecate("require('neominimap').winOn", "require('neominimap.api').win.enable", "v4", "neominimap.nvim") require("neominimap.command.win").subcommand_tbl.winOn.impl(args, opts) end +---@deprecated ---@type Neominimap.Command.Impl M.winOff = function(args, opts) + vim.deprecate("require('neominimap').winOff", "require('neominimap.api').win.disable", "v4", "neominimap.nvim") require("neominimap.command.win").subcommand_tbl.winOff.impl(args, opts) end +---@deprecated ---@type Neominimap.Command.Impl M.winToggle = function(args, opts) + vim.deprecate("require('neominimap').winToggle", "require('neominimap.api').win.toggle", "v4", "neominimap.nvim") require("neominimap.command.win").subcommand_tbl.winToggle.impl(args, opts) end +---@deprecated ---@type Neominimap.Command.Impl M.winRefresh = function(args, opts) + vim.deprecate("require('neominimap').winRefresh", "require('neominimap.api').win.refresh", "v4", "neominimap.nvim") require("neominimap.command.win").subcommand_tbl.winRefresh.impl(args, opts) end +---@deprecated ---@type Neominimap.Command.Impl M.tabOn = function(args, opts) + vim.deprecate("require('neominimap').tabOn", "require('neominimap.api').tab.enable", "v4", "neominimap.nvim") require("neominimap.command.tab").subcommand_tbl.tabOn.impl(args, opts) end +---@deprecated ---@type Neominimap.Command.Impl M.tabOff = function(args, opts) + vim.deprecate("require('neominimap').tabOff", "require('neominimap.api').tab.disable", "v4", "neominimap.nvim") require("neominimap.command.tab").subcommand_tbl.tabOff.impl(args, opts) end +---@deprecated +--- Minimap is enabled for the given window +---@param winid integer? If nil, check for the current window +---@return boolean +M.winEnabled = function(winid) + vim.deprecate("require('neominimap').winEnabled", "require('neominimap.api').win.wnabled", "v4", "neominimap.nvim") + if winid == nil then + winid = 0 + end + return require("neominimap.variables").w[winid].enabled +end + +---@deprecated ---@type Neominimap.Command.Impl M.tabToggle = function(args, opts) + vim.deprecate("require('neominimap').tabToggle", "require('neominimap.api').tab.toggle", "v4", "neominimap.nvim") require("neominimap.command.tab").subcommand_tbl.tabToggle.impl(args, opts) end +---@deprecated ---@type Neominimap.Command.Impl M.tabRefresh = function(args, opts) + vim.deprecate("require('neominimap').tabRefresh", "require('neominimap.api').tab.refresh", "v4", "neominimap.nvim") require("neominimap.command.tab").subcommand_tbl.tabRefresh.impl(args, opts) end +---@deprecated +--- Minimap is enabled for the given tab page +---@param tabid integer? If nil, check for the current tab page +---@return boolean +M.tabEnabled = function(tabid) + vim.deprecate("require('neominimap').tabEnabled", "require('neominimap.api').tab.enabled", "v4", "neominimap.nvim") + if tabid == nil then + tabid = 0 + end + return require("neominimap.variables").t[tabid].enabled +end + +---@deprecated ---@type Neominimap.Command.Impl M.focus = function(args, opts) + vim.deprecate("require('neominimap').focus", "require('neominimap.api').focus.on", "v4", "neominimap.nvim") require("neominimap.command.focus").subcommand_tbl.focus.impl(args, opts) end +---@deprecated ---@type Neominimap.Command.Impl M.unfocus = function(args, opts) + vim.deprecate("require('neominimap').unfocus", "require('neominimap.api').focus.off", "v4", "neominimap.nvim") require("neominimap.command.focus").subcommand_tbl.unfocus.impl(args, opts) end +---@deprecated ---@type Neominimap.Command.Impl M.toggleFocus = function(args, opts) + vim.deprecate( + "require('neominimap').toggleFocus", + "require('neominimap.api').focus.toggle", + "v4", + "neominimap.nvim" + ) require("neominimap.command.focus").subcommand_tbl.toggleFocus.impl(args, opts) end ---- Minimap is enabled globally -M.enabled = function() - return require("neominimap.variables").g.enabled -end - ---- Minimap is enabled for the given buffer ----@param bufnr integer? If nil, check for the current buffer -M.bufEnabled = function(bufnr) - if bufnr == nil then - bufnr = 0 - end - return require("neominimap.variables").b[bufnr].enabled -end - ---- Minimap is enabled for the given window ----@param winid integer? If nil, check for the current window -M.winEnabled = function(winid) - if winid == nil then - winid = 0 - end - return require("neominimap.variables").w[winid].enabled -end - ---- Minimap is enabled for the given tab page ----@param tabid integer? If nil, check for the current tab page -M.tabEnabled = function(tabid) - if tabid == nil then - tabid = 0 - end - return require("neominimap.variables").t[tabid].enabled -end - return M diff --git a/lua/neominimap/api/init.lua b/lua/neominimap/api/init.lua new file mode 100644 index 0000000..2b39610 --- /dev/null +++ b/lua/neominimap/api/init.lua @@ -0,0 +1,116 @@ +return { + --- Turns on Neominimap globally + enable = function() + require("neominimap.api.internal.global").enable() + end, + + --- Turns off Neominimap globally + disable = function() + require("neominimap.api.internal.global").disable() + end, + + --- Toggles Neominimap globally + toggle = function() + require("neominimap.api.internal.global").toggle() + end, + + --- Refreshes Neominimap globally + refresh = function() + require("neominimap.api.internal.global").refresh() + end, + + buf = { + ---Turns on Neominimap for the given buffers. If no buffers are provided, it will be applied to the current buffer. + ---@param buf_list integer|integer[]|nil + enable = function(buf_list) + require("neominimap.api.internal.buf").enable(buf_list) + end, + + ---Turns off Neominimap for the given buffers. If no buffers are provided, it will be applied to the current buffer. + ---@param buf_list integer|integer[]|nil + disable = function(buf_list) + require("neominimap.api.internal.buf").disable(buf_list) + end, + + ---Toggles Neominimap for the given buffers. If no buffers are provided, it will be applied to the current buffer. + ---@param buf_list integer|integer[]|nil + toggle = function(buf_list) + require("neominimap.api.internal.buf").toggle(buf_list) + end, + + ---Refreshes Neominimap for the given buffers. If no buffers are provided, it will be applied to the current buffer. + ---@param buf_list integer|integer[]|nil + refresh = function(buf_list) + require("neominimap.api.internal.buf").refresh(buf_list) + end, + }, + + win = { + --- Turns on Neominimap for the given windows. If no windows are provided, it will be applied to the current window. + ---@param win_list integer|integer[]|nil + enable = function(win_list) + require("neominimap.api.internal.win").enable(win_list) + end, + + --- Turns off Neominimap for the given windows. If no windows are provided, it will be applied to the current window. + ---@param win_list integer|integer[]|nil + disable = function(win_list) + require("neominimap.api.internal.win").disable(win_list) + end, + + --- Toggles Neominimap for the given windows. If no windows are provided, it will be applied to the current window. + ---@param win_list integer|integer[]|nil + toggle = function(win_list) + require("neominimap.api.internal.win").toggle(win_list) + end, + + --- Refreshes Neominimap for the given windows. If no windows are provided, it will be applied to the current window. + ---@param win_list integer|integer[]|nil + refresh = function(win_list) + require("neominimap.api.internal.win").refresh(win_list) + end, + }, + + tab = { + --- Turns on Neominimap for the given tabs. If no tabs are provided, it will be applied to the current tab. + ---@param tab_list integer|integer[]|nil + enable = function(tab_list) + require("neominimap.api.internal.tab").enable(tab_list) + end, + + --- Turns off Neominimap for the given tabs. If no tabs are provided, it will be applied to the current tab. + ---@param tab_list integer|integer[]|nil + disable = function(tab_list) + require("neominimap.api.internal.tab").disable(tab_list) + end, + + --- Toggles Neominimap for the given tabs. If no tabs are provided, it will be applied to the current tab. + ---@param tab_list integer|integer[]|nil + toggle = function(tab_list) + require("neominimap.api.internal.tab").toggle(tab_list) + end, + + --- Refreshes Neominimap for the given tabs. If no tabs are provided, it will be applied to the current tab. + ---@param tab_list integer|integer[]|nil + refresh = function(tab_list) + require("neominimap.api.internal.tab").refresh(tab_list) + end, + }, + + focus = { + --- Focuses on the Neominimap window + enable = function() + require("neominimap.api.internal.focus").enable() + end, + + --- Unfocuses the Neominimap window + disable = function() + require("neominimap.api.internal.focus").disable() + end, + + --- Toggles focus on the Neominimap window + toggle = function() + require("neominimap.api.internal.focus").toggle() + end, + }, +} diff --git a/lua/neominimap/api/internal/buf.lua b/lua/neominimap/api/internal/buf.lua new file mode 100644 index 0000000..73b40e2 --- /dev/null +++ b/lua/neominimap/api/internal/buf.lua @@ -0,0 +1,73 @@ +---@class Neominimap.Api.Buf.Handler +---@field refresh fun(bufnr:integer) +---@field enable fun(bufnr:integer) +---@field disable fun(bufnr:integer) + +---@param bufnr integer +local enable = function(bufnr) + local var = require("neominimap.variables") + var.b[bufnr].enabled = true + require("neominimap.buffer").get_buf_apis().enable(bufnr) +end + +---@param bufnr integer +local disable = function(bufnr) + local var = require("neominimap.variables") + var.b[bufnr].enabled = false + require("neominimap.buffer").get_buf_apis().disable(bufnr) +end + +---@param bufnr integer +local toggle = function(bufnr) + local var = require("neominimap.variables") + if var.b[bufnr].enabled then + disable(bufnr) + else + enable(bufnr) + end +end + +---@param bufnr integer +local refresh = function(bufnr) + require("neominimap.buffer").get_buf_apis().refresh(bufnr) +end + +---@param buf_list table +---@return boolean +---@return string? +local validate_buf_list = function(buf_list) + local is_valid, err = require("neominimap.api.util").validate_list_of_integers(buf_list) + if not is_valid then + return false, err + end + for _, bufno in ipairs(buf_list) do + if not vim.api.nvim_buf_is_valid(bufno) then + return false, string.format("Buffer %d is not valid.", bufno) + end + end + return true +end + +---@param func fun(bufnr:integer) +---@return fun(buf_list:integer|integer[]|nil) +local wrap_buf_function = function(func) + return function(buf_list) + if buf_list == nil then + buf_list = { vim.api.nvim_get_current_buf() } + elseif type(buf_list) ~= "table" then + buf_list = { buf_list } + end + local is_valid, err = validate_buf_list(buf_list) + if not is_valid then + error(err) + end + vim.tbl_map(func, buf_list) + end +end + +return { + enable = wrap_buf_function(enable), + disable = wrap_buf_function(disable), + toggle = wrap_buf_function(toggle), + refresh = wrap_buf_function(refresh), +} diff --git a/lua/neominimap/api/internal/focus.lua b/lua/neominimap/api/internal/focus.lua new file mode 100644 index 0000000..3d46a7c --- /dev/null +++ b/lua/neominimap/api/internal/focus.lua @@ -0,0 +1,25 @@ +local api = vim.api + +---@class Neominimap.Api.Focus.Handler +---@field focus fun(winid:integer) +---@field unfocus fun(mwinid:integer) +---@field toggle_focus fun(winid:integer) + +local M = {} + +M.enable = function() + local winid = api.nvim_get_current_win() + require("neominimap.window").get_focus_apis().focus(winid) +end + +M.disable = function() + local winid = api.nvim_get_current_win() + require("neominimap.window").get_focus_apis().unfocus(winid) +end + +M.toggle = function() + local winid = api.nvim_get_current_win() + require("neominimap.window").get_focus_apis().toggle_focus(winid) +end + +return M diff --git a/lua/neominimap/api/internal/global.lua b/lua/neominimap/api/internal/global.lua new file mode 100644 index 0000000..0990fe2 --- /dev/null +++ b/lua/neominimap/api/internal/global.lua @@ -0,0 +1,55 @@ +---@class Neominimap.Api.Global.Handler +---@field enable fun() +---@field disable fun() +---@field refresh fun() + +local function enable() + local var = require("neominimap.variables") + local logger = require("neominimap.logger") + if var.g.enabled then + return + end + var.g.enabled = true + require("neominimap.autocmds").create_autocmds() + + logger.log("Minimap is being opened. Initializing buffers and windows.", vim.log.levels.INFO) + require("neominimap.buffer").get_global_apis().enable() + require("neominimap.window").get_global_apis().enable() + logger.log("Minimap has been successfully opened.", vim.log.levels.INFO) +end + +local function disable() + local var = require("neominimap.variables") + if not var.g.enabled then + return + end + var.g.enabled = false + require("neominimap.autocmds").clear_autocmds() + + local logger = require("neominimap.logger") + logger.log("Minimap is being closed. Cleaning up buffers and windows.", vim.log.levels.INFO) + require("neominimap.buffer").get_global_apis().disable() + require("neominimap.window").get_global_apis().disable() + logger.log("Minimap has been successfully closed.", vim.log.levels.INFO) +end + +local function toggle() + local var = require("neominimap.variables") + if var.g.enabled then + disable() + else + enable() + end +end + +local function refresh() + require("neominimap.window").get_global_apis().refresh() + require("neominimap.buffer").get_global_apis().refresh() +end + +return { + enable = enable, + disable = disable, + toggle = toggle, + refresh = refresh, +} diff --git a/lua/neominimap/api/internal/tab.lua b/lua/neominimap/api/internal/tab.lua new file mode 100644 index 0000000..796df92 --- /dev/null +++ b/lua/neominimap/api/internal/tab.lua @@ -0,0 +1,75 @@ +local api = vim.api + +---@class Neominimap.Api.Tab.Handler +---@field refresh fun(tabid:integer) +---@field enable fun(tabid:integer) +---@field disable fun(tabid:integer) + +---@param tabid integer +local function enable(tabid) + local var = require("neominimap.variables") + var.t[tabid].enabled = true + require("neominimap.window").get_tab_apis().enable(tabid) +end + +---@param tabid integer +local function disalbe(tabid) + local var = require("neominimap.variables") + var.t[tabid].enabled = false + require("neominimap.window").get_tab_apis().disable(tabid) +end + +---@param tabid integer +local function toggle(tabid) + local var = require("neominimap.variables") + if var.t[tabid].enabled then + disalbe(tabid) + else + enable(tabid) + end +end + +---@param tabid integer +local function refresh(tabid) + require("neominimap.window").get_tab_apis().refresh(tabid) +end + +---@param tab_list table +---@return boolean +---@return string? +local valid_tab_list = function(tab_list) + local is_valid, err = require("neominimap.api.util").validate_list_of_integers(tab_list) + if not is_valid then + return false, err + end + for _, tabid in ipairs(tab_list) do + if not api.nvim_tabpage_is_valid(tabid) then + return false, string.format("Tab %d is not valid.", tabid) + end + end + return true +end + +---@param func fun(tabid:integer) +---@return fun(tab_list:integer|integer[]|nil) +local wrap_tab_function = function(func) + return function(tab_list) + if tab_list == nil then + tab_list = { api.nvim_get_current_tabpage() } + elseif type(tab_list) ~= "table" then + tab_list = { tab_list } + end + local is_valid, err = valid_tab_list(tab_list) + if not is_valid then + error(err) + end + vim.tbl_map(func, tab_list) + end +end + +return { + enable = wrap_tab_function(enable), + disable = wrap_tab_function(disalbe), + toggle = wrap_tab_function(toggle), + refresh = wrap_tab_function(refresh), +} diff --git a/lua/neominimap/api/internal/win.lua b/lua/neominimap/api/internal/win.lua new file mode 100644 index 0000000..3b345d6 --- /dev/null +++ b/lua/neominimap/api/internal/win.lua @@ -0,0 +1,73 @@ +---@class Neominimap.Api.Win.Handler +---@field refresh fun(winid:integer) +---@field enable fun(winid:integer) +---@field disable fun(winid:integer) + +---@param winid integer +local enable = function(winid) + local var = require("neominimap.variables") + var.w[winid].enabled = true + require("neominimap.window").get_win_apis().enable(winid) +end + +---@param winid integer +local disable = function(winid) + local var = require("neominimap.variables") + var.w[winid].enabled = false + require("neominimap.window").get_win_apis().disable(winid) +end + +---@param winid integer +local toggle = function(winid) + local var = require("neominimap.variables") + if var.w[winid].enabled then + disable(winid) + else + enable(winid) + end +end + +---@param winid integer +local function refresh(winid) + require("neominimap.window").get_win_apis().refresh(winid) +end + +---@param win_list table +---@return boolean +---@return string? +local validate_win_list = function(win_list) + local is_valid, err = require("neominimap.api.util").validate_list_of_integers(win_list) + if not is_valid then + return false, err + end + for _, winid in ipairs(win_list) do + if not vim.api.nvim_win_is_valid(winid) then + return false, string.format("Window %d is not valid.", winid) + end + end + return true +end + +---@param func fun(winid:integer) +---@return fun(win_list:integer|integer[]|nil) +local wrap_win_function = function(func) + return function(win_list) + if win_list == nil then + win_list = { vim.api.nvim_get_current_win() } + elseif type(win_list) ~= "table" then + win_list = { win_list } + end + local is_valid, err = validate_win_list(win_list) + if not is_valid then + error(err) + end + vim.tbl_map(func, win_list) + end +end + +return { + enable = wrap_win_function(enable), + disable = wrap_win_function(disable), + toggle = wrap_win_function(toggle), + refresh = wrap_win_function(refresh), +} diff --git a/lua/neominimap/api/util.lua b/lua/neominimap/api/util.lua new file mode 100644 index 0000000..09ae8b5 --- /dev/null +++ b/lua/neominimap/api/util.lua @@ -0,0 +1,23 @@ +local M = {} + +---Validate that tbl is a list of integers +---@param input any +---@return boolean is_valid +---@return string | nil error_message +M.validate_list_of_integers = function(input) + if type(input) ~= "table" then + return false, "Input is not a table" + end + + for i, value in ipairs(input) do + if type(value) ~= "number" then + return false, string.format("Element at index %d is not a number", i) + end + if value % 1 ~= 0 then + return false, string.format("Element at index %d is not an integer", i) + end + end + return true +end + +return M diff --git a/lua/neominimap/buffer/cmds.lua b/lua/neominimap/buffer/apis.lua similarity index 55% rename from lua/neominimap/buffer/cmds.lua rename to lua/neominimap/buffer/apis.lua index 6c07f7f..8b016ab 100644 --- a/lua/neominimap/buffer/cmds.lua +++ b/lua/neominimap/buffer/apis.lua @@ -8,17 +8,17 @@ local refresh = vim.schedule_wrap(function(bufnr) require("neominimap.buffer.internal").refresh_minimap_buffer(bufnr) end) ----@type Neominimap.Command.Buf.Handler -M.buf_cmds = { - ["bufOn"] = refresh, - ["bufOff"] = refresh, - ["bufRefresh"] = refresh, +---@type Neominimap.Api.Buf.Handler +M.buf_apis = { + ["enable"] = refresh, + ["disable"] = refresh, + ["refresh"] = refresh, } ----@type Neominimap.Command.Global.Handler -M.global_cmds = { - ["on"] = refresh_all, - ["off"] = refresh_all, +---@type Neominimap.Api.Global.Handler +M.global_apis = { + ["enable"] = refresh_all, + ["disable"] = refresh_all, ["refresh"] = refresh_all, } diff --git a/lua/neominimap/buffer/init.lua b/lua/neominimap/buffer/init.lua index 98d4559..4742f57 100644 --- a/lua/neominimap/buffer/init.lua +++ b/lua/neominimap/buffer/init.lua @@ -56,14 +56,14 @@ M.list_buffers = function() return require("neominimap.buffer.buffer_map").list_buffers() end ---- @return Neominimap.Command.Buf.Handler -M.get_buf_cmds = function() - return require("neominimap.buffer.cmds").buf_cmds +--- @return Neominimap.Api.Buf.Handler +M.get_buf_apis = function() + return require("neominimap.buffer.apis").buf_apis end ---- @return Neominimap.Command.Global.Handler -M.get_global_cmds = function() - return require("neominimap.buffer.cmds").global_cmds +--- @return Neominimap.Api.Global.Handler +M.get_global_apis = function() + return require("neominimap.buffer.apis").global_apis end ---@param bufnr integer diff --git a/lua/neominimap/buffer/internal.lua b/lua/neominimap/buffer/internal.lua index 6905b1e..d479b93 100644 --- a/lua/neominimap/buffer/internal.lua +++ b/lua/neominimap/buffer/internal.lua @@ -211,7 +211,6 @@ end M.apply_handler = function(bufnr, handler_name) local var = require("neominimap.variables") if api.nvim_buf_is_valid(bufnr) and var.b[bufnr].enabled then - -- local logger = require("neominimap.logger") local fun = var.b[bufnr].update_handler[handler_name] if fun ~= nil then fun() diff --git a/lua/neominimap/command/buf.lua b/lua/neominimap/command/buf.lua index 0ca3d9f..8962a3e 100644 --- a/lua/neominimap/command/buf.lua +++ b/lua/neominimap/command/buf.lua @@ -1,99 +1,33 @@ -local api = vim.api - ----@class Neominimap.Command.Buf.Handler ----@field bufRefresh fun(bufnr:integer) ----@field bufOn fun(bufnr:integer) ----@field bufOff fun(bufnr:integer) - local M = {} ----@param args string[] ----@return integer[] -local args_to_list = function(args) - if #args == 0 then - return { vim.api.nvim_get_current_buf() } - else - local bufnr = {} - for _, arg in ipairs(args) do - local nr = tonumber(arg) - local logger = require("neominimap.logger") - if not nr then - logger.notify(string.format("Buffer number %s is not a number.", arg), vim.log.levels.ERROR) - elseif not api.nvim_buf_is_valid(nr) then - logger.notify(string.format("Buffer %d is not valid.", nr), vim.log.levels.ERROR) - else - table.insert(bufnr, tonumber(arg)) - end - end - return bufnr - end -end - ----@param bufnr integer -local function bufOn(bufnr) - local var = require("neominimap.variables") - var.b[bufnr].enabled = true - require("neominimap.buffer").get_buf_cmds().bufOn(bufnr) -end - ----@param bufnr integer -local function bufOff(bufnr) - local var = require("neominimap.variables") - var.b[bufnr].enabled = false - require("neominimap.buffer").get_buf_cmds().bufOff(bufnr) -end - ----@param bufnr integer -local function bufToggle(bufnr) - local var = require("neominimap.variables") - if var.b[bufnr].enabled then - bufOff(bufnr) - else - bufOn(bufnr) - end -end - ----@param bufnr integer -local function bufRefresh(bufnr) - require("neominimap.buffer").get_buf_cmds().bufRefresh(bufnr) -end - ---@type table M.subcommand_tbl = { ["bufOn"] = { impl = function(args) local logger = require("neominimap.logger") logger.log.info("Command bufOn triggered.") - - local buf_list = args_to_list(args) - vim.tbl_map(bufOn, buf_list) + require("neominimap.api").buf.enable(#args ~= 0 and vim.tbl_map(tonumber, args) or nil) end, }, ["bufOff"] = { impl = function(args) local logger = require("neominimap.logger") logger.log.info("Command bufOff triggered.") - - local buf_list = args_to_list(args) - vim.tbl_map(bufOff, buf_list) + require("neominimap.api").buf.disable(#args ~= 0 and vim.tbl_map(tonumber, args) or nil) end, }, ["bufToggle"] = { impl = function(args) local logger = require("neominimap.logger") logger.log.info("Command bufToggle triggered.") - - local buf_list = args_to_list(args) - vim.tbl_map(bufToggle, buf_list) + require("neominimap.api").buf.toggle(#args ~= 0 and vim.tbl_map(tonumber, args) or nil) end, }, ["bufRefresh"] = { impl = function(args) local logger = require("neominimap.logger") logger.log.info("Command bufRefresh triggered.") - - local bufnr = args_to_list(args) - vim.tbl_map(bufRefresh, bufnr) + require("neominimap.api").buf.refresh(#args ~= 0 and vim.tbl_map(tonumber, args) or nil) end, }, } diff --git a/lua/neominimap/command/focus.lua b/lua/neominimap/command/focus.lua index 45d9dc9..dfb76e4 100644 --- a/lua/neominimap/command/focus.lua +++ b/lua/neominimap/command/focus.lua @@ -1,10 +1,3 @@ -local api = vim.api - ----@class Neominimap.Command.Focus.Handler ----@field focus fun(winid:integer) ----@field unfocus fun(mwinid:integer) ----@field toggleFocus fun(winid:integer) - local M = {} ---@type table @@ -13,27 +6,21 @@ M.subcommand_tbl = { impl = function() local logger = require("neominimap.logger") logger.log.info("Command focus triggered.") - - local winid = api.nvim_get_current_win() - require("neominimap.window").get_focus_cmds().focus(winid) + require("neominimap.api").focus.enable() end, }, ["unfocus"] = { impl = function() local logger = require("neominimap.logger") logger.log.info("Command unfocus triggered.") - - local winid = api.nvim_get_current_win() - require("neominimap.window").get_focus_cmds().unfocus(winid) + require("neominimap.api").focus.disable() end, }, ["toggleFocus"] = { impl = function() local logger = require("neominimap.logger") logger.log.info("Command toggleFocus triggered.") - - local winid = api.nvim_get_current_win() - require("neominimap.window").get_focus_cmds().toggleFocus(winid) + require("neominimap.api").focus.toggle() end, }, } diff --git a/lua/neominimap/command/global.lua b/lua/neominimap/command/global.lua index d54ff2f..1ddadc3 100644 --- a/lua/neominimap/command/global.lua +++ b/lua/neominimap/command/global.lua @@ -1,82 +1,33 @@ local M = {} ----@class Neominimap.Command.Global.Handler ----@field on fun() ----@field off fun() ----@field refresh fun() - -local function open_minimap() - local var = require("neominimap.variables") - local logger = require("neominimap.logger") - if var.g.enabled then - return - end - var.g.enabled = true - require("neominimap.autocmds").create_autocmds() - - logger.log.info("Minimap is being opened. Initializing buffers and windows.") - require("neominimap.buffer").get_global_cmds().on() - require("neominimap.window").get_global_cmds().on() - logger.log.info("Minimap has been successfully opened.") -end - -local function close_minimap() - local var = require("neominimap.variables") - if not var.g.enabled then - return - end - var.g.enabled = false - require("neominimap.autocmds").clear_autocmds() - - local logger = require("neominimap.logger") - logger.log.info("Minimap is being closed. Cleaning up buffers and windows.") - require("neominimap.buffer").get_global_cmds().off() - require("neominimap.window").get_global_cmds().off() - logger.log.info("Minimap has been successfully closed.") -end - -local function toggle_minimap() - local var = require("neominimap.variables") - if var.g.enabled then - close_minimap() - else - open_minimap() - end -end - -local function refresh_minimap() - require("neominimap.window").get_global_cmds().refresh() - require("neominimap.buffer").get_global_cmds().refresh() -end - ---@type table M.subcommand_tbl = { ["on"] = { impl = function() local logger = require("neominimap.logger") logger.log.info("Command on triggered.") - open_minimap() + require("neominimap.api").enable() end, }, ["off"] = { impl = function() local logger = require("neominimap.logger") logger.log.info("Command off triggered.") - close_minimap() + require("neominimap.api").disable() end, }, ["toggle"] = { impl = function() local logger = require("neominimap.logger") logger.log.info("Command toggle triggered.") - toggle_minimap() + require("neominimap.api").toggle() end, }, ["refresh"] = { impl = function() local logger = require("neominimap.logger") logger.log.info("Command refresh triggered.") - refresh_minimap() + require("neominimap.api").refresh() end, }, } diff --git a/lua/neominimap/command/tab.lua b/lua/neominimap/command/tab.lua index 2f70a6c..e199989 100644 --- a/lua/neominimap/command/tab.lua +++ b/lua/neominimap/command/tab.lua @@ -1,99 +1,33 @@ -local api = vim.api - ----@class Neominimap.Command.Tab.Handler ----@field tabRefresh fun(tabid:integer) ----@field tabOn fun(tabid:integer) ----@field tabOff fun(tabid:integer) - local M = {} ----@param args string[] ----@return integer[] -local args_to_list = function(args) - if #args == 0 then - return { api.nvim_get_current_tabpage() } - else - local tabid = {} - for _, arg in ipairs(args) do - local nr = tonumber(arg) - local logger = require("neominimap.logger") - if not nr then - logger.notify(string.format("Tab ID %s is not a number.", arg), vim.log.levels.ERROR) - elseif not api.nvim_tabpage_is_valid(nr) then - logger.notify(string.format("Tab %d is not valid.", nr), vim.log.levels.ERROR) - else - table.insert(tabid, tonumber(arg)) - end - end - return tabid - end -end - ----@param tabid integer -local function tabOn(tabid) - local var = require("neominimap.variables") - var.t[tabid].enabled = true - require("neominimap.window").get_tab_cmds().tabOn(tabid) -end - ----@param tabid integer -local function tabOff(tabid) - local var = require("neominimap.variables") - var.t[tabid].enabled = false - require("neominimap.window").get_tab_cmds().tabOff(tabid) -end - ----@param tabid integer -local function tabToggle(tabid) - local var = require("neominimap.variables") - if var.t[tabid].enabled then - tabOff(tabid) - else - tabOn(tabid) - end -end - ----@param tabid integer -local function tabRefresh(tabid) - require("neominimap.window").get_tab_cmds().tabRefresh(tabid) -end - ---@type tabletype table M.subcommand_tbl = { ["tabOn"] = { impl = function(args) local logger = require("neominimap.logger") logger.log.info("Command tabOn triggered.") - - local tab_list = args_to_list(args) - vim.tbl_map(tabOn, tab_list) + require("neominimap.api").tab.enable(#args ~= 0 and vim.tbl_map(tonumber, args) or nil) end, }, ["tabOff"] = { impl = function(args) local logger = require("neominimap.logger") logger.log.info("Command tabOff triggered.") - - local tab_list = args_to_list(args) - vim.tbl_map(tabOff, tab_list) + require("neominimap.api").tab.disable(#args ~= 0 and vim.tbl_map(tonumber, args) or nil) end, }, ["tabToggle"] = { impl = function(args) local logger = require("neominimap.logger") logger.log.info("Command tabToggle triggered.") - - local tab_list = args_to_list(args) - vim.tbl_map(tabToggle, tab_list) + require("neominimap.api").tab.toggle(#args ~= 0 and vim.tbl_map(tonumber, args) or nil) end, }, ["tabRefresh"] = { impl = function(args) local logger = require("neominimap.logger") logger.log.info("Command tabRefresh triggered.") - - local tabid = args_to_list(args) - vim.tbl_map(tabRefresh, tabid) + require("neominimap.api").tab.refresh(#args ~= 0 and vim.tbl_map(tonumber, args) or nil) end, }, } diff --git a/lua/neominimap/command/win.lua b/lua/neominimap/command/win.lua index 79877f4..6b4e95a 100644 --- a/lua/neominimap/command/win.lua +++ b/lua/neominimap/command/win.lua @@ -1,99 +1,33 @@ -local api = vim.api - ----@class Neominimap.Command.Win.Handler ----@field winRefresh fun(winid:integer) ----@field winOn fun(winid:integer) ----@field winOff fun(winid:integer) - local M = {} ----@param args string[] ----@return integer[] -local args_to_list = function(args) - if #args == 0 then - return { vim.api.nvim_get_current_win() } - else - local bufnr = {} - for _, arg in ipairs(args) do - local nr = tonumber(arg) - local logger = require("neominimap.logger") - if not nr then - logger.notify(string.format("Window ID %s is not a number.", arg), vim.log.levels.ERROR) - elseif not api.nvim_win_is_valid(nr) then - logger.notify(string.format("Window ID %d is not valid.", nr), vim.log.levels.ERROR) - else - table.insert(bufnr, tonumber(arg)) - end - end - return bufnr - end -end - ----@param winid integer -local winOn = function(winid) - local var = require("neominimap.variables") - var.w[winid].enabled = true - require("neominimap.window").get_win_cmds().winOn(winid) -end - ----@param winid integer -local winOff = function(winid) - local var = require("neominimap.variables") - var.w[winid].enabled = false - require("neominimap.window").get_win_cmds().winOff(winid) -end - ----@param winid integer -local winToggle = function(winid) - local var = require("neominimap.variables") - if var.w[winid].enabled then - winOff(winid) - else - winOn(winid) - end -end - ----@param winid integer -local function winRefresh(winid) - require("neominimap.window").get_win_cmds().winRefresh(winid) -end - ---@type table M.subcommand_tbl = { ["winOn"] = { impl = function(args) local logger = require("neominimap.logger") logger.log.info("Command winOn triggered.") - - local win_list = args_to_list(args) - vim.tbl_map(winOn, win_list) + require("neominimap.api").win.enable(#args ~= 0 and vim.tbl_map(tonumber, args) or nil) end, }, ["winOff"] = { impl = function(args) local logger = require("neominimap.logger") logger.log.info("Command winOff triggered.") - - local win_list = args_to_list(args) - vim.tbl_map(winOff, win_list) + require("neominimap.api").win.disable(#args ~= 0 and vim.tbl_map(tonumber, args) or nil) end, }, ["winToggle"] = { impl = function(args) local logger = require("neominimap.logger") logger.log.info("Command winToggle triggered.") - - local win_list = args_to_list(args) - vim.tbl_map(winToggle, win_list) + require("neominimap.api").win.toggle(#args ~= 0 and vim.tbl_map(tonumber, args) or nil) end, }, ["winRefresh"] = { impl = function(args) local logger = require("neominimap.logger") logger.log.info("Command winRefresh triggered.") - - local win_list = args_to_list(args) - vim.tbl_map(winRefresh, win_list) + require("neominimap.api").win.refresh(#args ~= 0 and vim.tbl_map(tonumber, args) or nil) end, }, } diff --git a/lua/neominimap/config/internal.lua b/lua/neominimap/config/internal.lua index 119614d..5fef305 100644 --- a/lua/neominimap/config/internal.lua +++ b/lua/neominimap/config/internal.lua @@ -102,7 +102,7 @@ local M = { --- Border style of the floating window. --- Accepts all usual border style options (e.g., "single", "double") --- @type string | string[] | [string, string][] - window_border = "single", + window_border = vim.fn.has("nvim-0.11") == 1 and vim.opt.winborder:get() or "single", -- When true, the floating window will be recreated when you close it. -- When false, the minimap will be disabled for the current window when you close the minimap window. @@ -125,7 +125,23 @@ local M = { diagnostic = { enabled = true, ---@type boolean - severity = vim.diagnostic.severity.WARN, ---@type vim.diagnostic.SeverityInt + -- When enabled, diagnostics will be sourced directly from the DiagnosticChanged event, + -- meaning they will follow the settings from vim.diagnostic.config. + -- In this mode, the `severity` filter is ignored. + use_event_diagnostics = false, ---@type boolean + + -- The `severity` option specifies which diagnostics to include based on their severity. + -- Note: This option is ignored when `use_event_diagnostics` is enabled. + -- + -- Allowed formats for the `severity` filter: + -- 1. A single severity level: + -- eg: severity = vim.diagnostic.severity.WARN + -- 2. A table with a "min" and/or "max" key: + -- eg: severity = { min = vim.diagnostic.severity.WARN, max = vim.diagnostic.severity.ERROR } + -- 3. A list-like table of severity values: + -- eg: severity = { vim.diagnostic.severity.WARN, vim.diagnostic.severity.ERROR } + ---@see vim.diagnostic.severity + severity = nil, ---@type vim.diagnostic.SeverityFilter? mode = "line", ---@type Neominimap.Handler.Annotation.Mode priority = { ERROR = 100, ---@type integer diff --git a/lua/neominimap/config/meta.lua b/lua/neominimap/config/meta.lua index c2daabf..10c66bf 100644 --- a/lua/neominimap/config/meta.lua +++ b/lua/neominimap/config/meta.lua @@ -51,7 +51,8 @@ local M = {} ---@class (exact) Neominimap.DiagnosticConfig ---@field enabled? boolean ---@field mode? Neominimap.Handler.Annotation.Mode ----@field severity? vim.diagnostic.SeverityInt +---@field use_event_diagnostics? boolean +---@field severity? vim.diagnostic.SeverityFilter ---@field priority? {ERROR?: integer, WARN?: integer, INFO?: integer, HINT?: integer} ---@field icon? {ERROR?: string, WARN?: string, INFO?: string, HINT?: string} diff --git a/lua/neominimap/config/validator.lua b/lua/neominimap/config/validator.lua index a32a242..f64bc9f 100644 --- a/lua/neominimap/config/validator.lua +++ b/lua/neominimap/config/validator.lua @@ -45,6 +45,38 @@ end) ---@type fun(x:any):boolean local is_array_of_handlers = is_array_of(is_handler) +--- Validates that x is a valid vim.diagnostic.SeverityFilter value. +--- It can be a single number, an array of numbers, or a table with min and max keys. +---@param x any +---@return boolean +local function is_severity_filter(x) + if x == nil then + return true + elseif type(x) == "number" then + return true + elseif type(x) == "table" then + local is_array = true + for k, v in pairs(x) do + if type(k) ~= "number" then + is_array = false + break + end + end + if is_array then + for _, v in ipairs(x) do + if type(v) ~= "number" then + return false + end + end + return true + end + if x.min ~= nil and x.max ~= nil and type(x.min) == "number" and type(x.max) == "number" then + return true + end + end + return false +end + ---@param cfg Neominimap.Internal.Config ---@return boolean is_valid ---@return string|nil error_message @@ -89,7 +121,7 @@ M.validate_config = function(cfg) diagnostic = { cfg.diagnostic, "table" }, ["diagnostic.enabled"] = { cfg.diagnostic.enabled, "boolean" }, - ["diagnostic.severity"] = { cfg.diagnostic.severity, "number" }, + ["diagnostic.severity"] = { cfg.diagnostic.severity, is_severity_filter, "vim.diagnostic.SeverityFilter?" }, ["diagnostic.mode"] = { cfg.diagnostic.mode, "string" }, ["diagnostic.priority.ERROR"] = { cfg.diagnostic.priority.ERROR, "number" }, ["diagnostic.priority.WARN"] = { cfg.diagnostic.priority.WARN, "number" }, diff --git a/lua/neominimap/map/handlers/builtins/diagnostic.lua b/lua/neominimap/map/handlers/builtins/diagnostic.lua index a45064d..29a5f92 100644 --- a/lua/neominimap/map/handlers/builtins/diagnostic.lua +++ b/lua/neominimap/map/handlers/builtins/diagnostic.lua @@ -58,14 +58,41 @@ local icon_list = { config.diagnostic.icon.HINT, } +---@type Neominimap.Map.Handler.Autocmd.Callback +M.on_diagnostic_changed = function(apply, args) + local logger = require("neominimap.logger") + logger.log.trace("DiagnosticChanged event triggered.") + local bufnr = tonumber(args.buf) + if not bufnr or not vim.api.nvim_buf_is_valid(bufnr) then + return + end + local diagnostics = args.data.diagnostics + if config.diagnostic.use_event_diagnostics then + local var = require("neominimap.variables") + var.b[tonumber(bufnr)].diagnostics = diagnostics + end + vim.schedule(function() + logger.log.trace("Updating diagnostics.") + apply(bufnr) + logger.log.trace("Diagnostics updated.") + end) +end + ---@param bufnr integer ---@return Neominimap.Map.Handler.Annotation[] M.get_annotations = function(bufnr) - local diags = diagnostic.get(bufnr, { - severity = { - min = config.diagnostic.severity, - }, - }) + --- @type vim.Diagnostic[] + local diags = (function() + if config.diagnostic.use_event_diagnostics then + local var = require("neominimap.variables") + local ret = var.b[bufnr].diagnostics + var.b[bufnr].diagnostics = nil + return ret + else + return diagnostic.get(bufnr, { severity = config.diagnostic.severity }) + end + end)() + ---@type Neominimap.Map.Handler.Annotation[] local annotation = {} local util = require("neominimap.util") diff --git a/lua/neominimap/map/handlers/builtins/init.lua b/lua/neominimap/map/handlers/builtins/init.lua index 7abecca..ce100fe 100644 --- a/lua/neominimap/map/handlers/builtins/init.lua +++ b/lua/neominimap/map/handlers/builtins/init.lua @@ -14,6 +14,10 @@ return { pattern = "GitSignsUpdate", desc = "Update git annotations when git signs are updated", get_buffers = function(args) + local data = args.data + if not data then + return nil + end ---@type integer return tonumber(args.data.buffer) end, @@ -36,6 +40,10 @@ return { pattern = "MiniDiffUpdated", desc = "Update mini diff annotations when mini diff signs are updated", get_buffers = function(args) + local data = args.data + if not data then + return nil + end ---@type integer return tonumber(args.data.buffer) end, @@ -56,8 +64,8 @@ return { event = "DiagnosticChanged", opts = { desc = "Update diagnostic annotations when diagnostics are changed", - get_buffers = function(_) - return api.nvim_list_bufs() + callback = function(apply, args) + require("neominimap.map.handlers.builtins.diagnostic").on_diagnostic_changed(apply, args) end, }, }, diff --git a/lua/neominimap/map/handlers/init.lua b/lua/neominimap/map/handlers/init.lua index ee591aa..d61c747 100644 --- a/lua/neominimap/map/handlers/init.lua +++ b/lua/neominimap/map/handlers/init.lua @@ -25,7 +25,7 @@ local config = require("neominimap.config") ---@field desc? string ---If callback is set, then get_buffers is ignored ---@field callback? Neominimap.Map.Handler.Autocmd.Callback ----@field get_buffers? fun(data:vim.api.keyset.create_autocmd.callback_args): integer[] | integer +---@field get_buffers? fun(data:vim.api.keyset.create_autocmd.callback_args): integer[] | integer | nil ---@class Neominimap.Map.Handler.Autocmd ---@field event string|string[] @@ -75,7 +75,7 @@ M.create_autocmds = function(group) vim.tbl_map(function(bufnr) apply(bufnr, handler.name) end, target) - else + elseif target then apply(target, handler.name) end end diff --git a/lua/neominimap/variables.lua b/lua/neominimap/variables.lua index 822ffbc..c092668 100644 --- a/lua/neominimap/variables.lua +++ b/lua/neominimap/variables.lua @@ -84,6 +84,7 @@ local buffer_default = { render = function() end, ---@type fun() Render minimap for this buffer. Generate text and TreeSitter highlights. update_handler = {}, ---@type table cached_folds = {}, ---@type Neominimap.Fold[] + diagnostics = {}, ---@type vim.Diagnostic[] } ---@class Neominimap.Variables.Window diff --git a/lua/neominimap/window/float/cmds.lua b/lua/neominimap/window/float/apis.lua similarity index 68% rename from lua/neominimap/window/float/cmds.lua rename to lua/neominimap/window/float/apis.lua index eefa7fb..1e26af7 100644 --- a/lua/neominimap/window/float/cmds.lua +++ b/lua/neominimap/window/float/apis.lua @@ -12,29 +12,29 @@ local refresh_all_in_tab = vim.schedule_wrap(function(tabid) require("neominimap.window.float.internal").refresh_minimaps_in_tab(tabid) end) ----@type Neominimap.Command.Global.Handler -M.global_cmds = { - ["on"] = refresh_all, - ["off"] = refresh_all, +---@type Neominimap.Api.Global.Handler +M.global_apis = { + ["enable"] = refresh_all, + ["disable"] = refresh_all, ["refresh"] = refresh_all, } ----@type Neominimap.Command.Tab.Handler -M.tab_cmds = { - ["tabRefresh"] = refresh_all_in_tab, - ["tabOn"] = refresh_all_in_tab, - ["tabOff"] = refresh_all_in_tab, +---@type Neominimap.Api.Tab.Handler +M.tab_apis = { + ["enable"] = refresh_all_in_tab, + ["disable"] = refresh_all_in_tab, + ["refresh"] = refresh_all_in_tab, } ----@type Neominimap.Command.Win.Handler -M.win_cmds = { - ["winRefresh"] = refresh, - ["winOn"] = refresh, - ["winOff"] = refresh, +---@type Neominimap.Api.Win.Handler +M.win_apis = { + ["enable"] = refresh, + ["disable"] = refresh, + ["refresh"] = refresh, } ----@type Neominimap.Command.Focus.Handler -M.focus_cmds = { +---@type Neominimap.Api.Focus.Handler +M.focus_apis = { ["focus"] = vim.schedule_wrap(function(winid) local ok = require("neominimap.window.float.internal").focus(winid) if not ok then @@ -49,12 +49,12 @@ M.focus_cmds = { logger.notify("Minimap can not be unfocused for current window", vim.log.levels.ERROR) end end), - ["toggleFocus"] = function(winid) + ["toggle_focus"] = function(winid) local window_map = require("neominimap.window.float.window_map") if window_map.is_minimap_window(winid) then - M.focus_cmds.unfocus(winid) + M.focus_apis.unfocus(winid) else - M.focus_cmds.focus(winid) + M.focus_apis.focus(winid) end end, } diff --git a/lua/neominimap/window/float/init.lua b/lua/neominimap/window/float/init.lua index cfff05a..e7dbacd 100644 --- a/lua/neominimap/window/float/init.lua +++ b/lua/neominimap/window/float/init.lua @@ -70,20 +70,20 @@ return { end, }) end, - get_global_cmds = function() - local cmds = require("neominimap.window.float.cmds") - return cmds.global_cmds + get_global_apis = function() + local cmds = require("neominimap.window.float.apis") + return cmds.global_apis end, - get_win_cmds = function() - local cmds = require("neominimap.window.float.cmds") - return cmds.win_cmds + get_win_apis = function() + local cmds = require("neominimap.window.float.apis") + return cmds.win_apis end, - get_tab_cmds = function() - local cmds = require("neominimap.window.float.cmds") - return cmds.tab_cmds + get_tab_apis = function() + local cmds = require("neominimap.window.float.apis") + return cmds.tab_apis end, - get_focus_cmds = function() - local cmds = require("neominimap.window.float.cmds") - return cmds.focus_cmds + get_focus_apis = function() + local cmds = require("neominimap.window.float.apis") + return cmds.focus_apis end, } diff --git a/lua/neominimap/window/init.lua b/lua/neominimap/window/init.lua index a6ff635..3d1c2a6 100644 --- a/lua/neominimap/window/init.lua +++ b/lua/neominimap/window/init.lua @@ -11,10 +11,10 @@ api.nvim_set_hl(0, "NeominimapCursorLineFold", { link = "CursorLineSign", defaul ---@class Neominimap.Window ---@field create_autocmds fun(group: string | integer) ----@field get_global_cmds fun():Neominimap.Command.Global.Handler ----@field get_win_cmds fun():Neominimap.Command.Win.Handler ----@field get_tab_cmds fun():Neominimap.Command.Tab.Handler ----@field get_focus_cmds fun():Neominimap.Command.Focus.Handler +---@field get_global_apis fun():Neominimap.Api.Global.Handler +---@field get_win_apis fun():Neominimap.Api.Win.Handler +---@field get_tab_apis fun():Neominimap.Api.Tab.Handler +---@field get_focus_apis fun():Neominimap.Api.Focus.Handler ---@type table local tbl = { diff --git a/lua/neominimap/window/split/cmds.lua b/lua/neominimap/window/split/apis.lua similarity index 70% rename from lua/neominimap/window/split/cmds.lua rename to lua/neominimap/window/split/apis.lua index 4e96fc6..e8ce976 100644 --- a/lua/neominimap/window/split/cmds.lua +++ b/lua/neominimap/window/split/apis.lua @@ -10,33 +10,33 @@ local refresh_tab = vim.schedule_wrap(function() require("neominimap.window.split.internal").refresh_current_tab() end) ----@type Neominimap.Command.Global.Handler -M.global_cmds = { - ["on"] = vim.schedule_wrap(function() +---@type Neominimap.Api.Global.Handler +M.global_apis = { + ["enable"] = vim.schedule_wrap(function() require("neominimap.window.split.internal").create_minimap_window_in_current_tab() end), - ["off"] = vim.schedule_wrap(function() + ["disable"] = vim.schedule_wrap(function() require("neominimap.window.split.internal").close_minimap_window_for_all_tabs() end), ["refresh"] = refresh, } ----@type Neominimap.Command.Tab.Handler -M.tab_cmds = { - ["tabRefresh"] = refresh_tab, - ["tabOn"] = refresh_tab, - ["tabOff"] = refresh_tab, +---@type Neominimap.Api.Tab.Handler +M.tab_apis = { + ["enable"] = refresh_tab, + ["disable"] = refresh_tab, + ["refresh"] = refresh_tab, } ----@type Neominimap.Command.Win.Handler -M.win_cmds = { - ["winRefresh"] = refresh, - ["winOn"] = refresh, - ["winOff"] = refresh, +---@type Neominimap.Api.Win.Handler +M.win_apis = { + ["enable"] = refresh, + ["disable"] = refresh, + ["refresh"] = refresh, } ----@type Neominimap.Command.Focus.Handler -M.focus_cmds = { +---@type Neominimap.Api.Focus.Handler +M.focus_apis = { ["focus"] = vim.schedule_wrap(function() local ok = require("neominimap.window.split.internal").focus() if not ok then @@ -51,14 +51,14 @@ M.focus_cmds = { logger.notify("Minimap can not be unfocused for current window", vim.log.levels.ERROR) end end), - ["toggleFocus"] = function() + ["toggle_focus"] = function() local tabid = api.nvim_get_current_tabpage() local winid = api.nvim_get_current_win() local window_map = require("neominimap.window.split.window_map") if window_map.is_minimap_window(tabid, winid) then - M.focus_cmds.unfocus(0) + M.focus_apis.unfocus(0) else - M.focus_cmds.focus(0) + M.focus_apis.focus(0) end end, } diff --git a/lua/neominimap/window/split/init.lua b/lua/neominimap/window/split/init.lua index 28e4952..fa03af0 100644 --- a/lua/neominimap/window/split/init.lua +++ b/lua/neominimap/window/split/init.lua @@ -67,20 +67,20 @@ return { end, }) end, - get_global_cmds = function() - local cmds = require("neominimap.window.split.cmds") - return cmds.global_cmds + get_global_apis = function() + local apis = require("neominimap.window.split.apis") + return apis.global_apis end, - get_win_cmds = function() - local cmds = require("neominimap.window.split.cmds") - return cmds.win_cmds + get_win_apis = function() + local apis = require("neominimap.window.split.apis") + return apis.win_apis end, - get_tab_cmds = function() - local cmds = require("neominimap.window.split.cmds") - return cmds.tab_cmds + get_tab_apis = function() + local apis = require("neominimap.window.split.apis") + return apis.tab_apis end, - get_focus_cmds = function() - local cmds = require("neominimap.window.split.cmds") - return cmds.focus_cmds + get_focus_apis = function() + local apis = require("neominimap.window.split.apis") + return apis.focus_apis end, }