From f9cc5c2268f2facd81ca5b47abfdb11958bb627e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3n=C3=A1n=20Carrigan?= Date: Wed, 1 Sep 2021 09:50:00 +0100 Subject: [PATCH] feat: expose notications --- README.md | 9 ++++++ lua/notify/config/init.lua | 20 ++++++------ lua/notify/init.lua | 40 ++++++++++++++++++------ lua/notify/service/buffer/highlights.lua | 2 +- lua/notify/service/buffer/init.lua | 8 +++-- lua/notify/service/init.lua | 9 +----- lua/notify/service/notification.lua | 3 +- tests/unit/init_spec.lua | 12 +++++++ 8 files changed, 72 insertions(+), 31 deletions(-) create mode 100644 tests/unit/init_spec.lua diff --git a/README.md b/README.md index 04ffa78..acdcc87 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,15 @@ vim.notify("This is an error message.\nSomething went wrong!", "error", { }) ``` +You can get a list of past notifications with the history function +```lua +require("notify").history() +``` +which returns a list of tables with the following keys: +- `message: string[]` Lines of the message +- `level: string` Log level +- `time: number` Time of message, as returned by `vim.fn.localtime()` + ## Configuration ### Setup diff --git a/lua/notify/config/init.lua b/lua/notify/config/init.lua index 849440c..6ef9a69 100644 --- a/lua/notify/config/init.lua +++ b/lua/notify/config/init.lua @@ -31,15 +31,17 @@ local function validate_highlight(colour_or_group, needs_opacity) local group_bg = vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID(colour_or_group)), "bg") if group_bg == "" then if needs_opacity then - vim.notify( - "Highlight group '" - .. colour_or_group - .. "' has no background highlight.\n\n" - .. "Please provide an RGB hex value or highlight group with a background value for 'background_colour' option\n\n" - .. "Defaulting to #000000", - "warn", - { title = "nvim-notify" } - ) + vim.schedule(function() + vim.notify( + "Highlight group '" + .. colour_or_group + .. "' has no background highlight.\n\n" + .. "Please provide an RGB hex value or highlight group with a background value for 'background_colour' option\n\n" + .. "Defaulting to #000000", + "warn", + { title = "nvim-notify" } + ) + end) end return "#000000" end diff --git a/lua/notify/init.lua b/lua/notify/init.lua index ec6a962..95c9c61 100644 --- a/lua/notify/init.lua +++ b/lua/notify/init.lua @@ -2,14 +2,20 @@ local util = require("notify.util") local config = util.lazy_require("notify.config") local stages = util.lazy_require("notify.stages") +---@type fun(message: string | string[], level: string | number, opts: NotifyOptions): Notification +local Notification = util.lazy_require("notify.service.notification") ---@type fun(stages: function[]): WindowAnimator local WindowAnimator = util.lazy_require("notify.windows") ---@type fun(receiver: fun(pending: FIFOQueue, time: number): table | nil): NotificationService local NotificationService = util.lazy_require("notify.service") local service +---@type Notification[] +local notifications = {} -local function setup(user_config) +local M = {} + +function M.setup(user_config) config.setup(user_config) local animator_stages = config.stages() animator_stages = type(animator_stages) == "string" and stages[animator_stages] or animator_stages @@ -22,17 +28,31 @@ end ---@param message string | string[] ---@param level string | number ---@param opts NotifyOptions -local function notify(_, message, level, opts) - vim.schedule(function() - if not service then - setup() - end - service:push(message, level, opts) - end) +local function notify(message, level, opts) + if not service then + M.setup() + end + local notification = Notification(message, level, opts or {}) + table.insert(notifications, notification) + service:push(notification) end -local M = { setup = setup } +function M.history() + return vim.tbl_map(function(notif) + return { message = notif.message, level = notif.level, time = notif.time } + end, notifications) +end -setmetatable(M, { __call = notify }) +setmetatable(M, { + __call = function(_, m, l, o) + if vim.in_fast_event() then + vim.schedule(function() + notify(m, l, o) + end) + else + notify(m, l, o) + end + end, +}) return M diff --git a/lua/notify/service/buffer/highlights.lua b/lua/notify/service/buffer/highlights.lua index 0ff0479..04d3b62 100644 --- a/lua/notify/service/buffer/highlights.lua +++ b/lua/notify/service/buffer/highlights.lua @@ -24,7 +24,7 @@ function NotifyBufHighlights:new(level, buffer) orig = "NotifyINFO" .. section end local new = orig .. buffer - vim.cmd("hi link " .. new .. " " .. orig) + vim.cmd("silent! hi link " .. new .. " " .. orig) return new end local title = linked_group("Title") diff --git a/lua/notify/service/buffer/init.lua b/lua/notify/service/buffer/init.lua index 0efdd30..9d96321 100644 --- a/lua/notify/service/buffer/init.lua +++ b/lua/notify/service/buffer/init.lua @@ -37,7 +37,9 @@ function NotificationBuf:open(win) end self._state = BufState.OPEN if self._notif.on_open then - self._notif.on_open(win) + vim.schedule(function() + self._notif.on_open(win) + end) end end @@ -47,7 +49,9 @@ function NotificationBuf:close(win) end self._state = BufState.CLOSED if self._notif.on_close then - self._notif.on_close(win) + vim.schedule(function() + self._notif.on_close(win) + end) end end diff --git a/lua/notify/service/init.lua b/lua/notify/service/init.lua index b7d51fb..114e7d4 100644 --- a/lua/notify/service/init.lua +++ b/lua/notify/service/init.lua @@ -1,12 +1,10 @@ local util = require("notify.util") local NotificationBuf = require("notify.service.buffer") -local Notification = require("notify.service.notification") ---@class NotificationService ---@field private _running boolean ---@field private _pending FIFOQueue ---@field private _receiver fun(pending: FIFOQueue, time: number): boolean ----@field private _notifications Notification[] local NotificationService = {} function NotificationService:new(receiver) @@ -14,7 +12,6 @@ function NotificationService:new(receiver) _receiver = receiver, _pending = util.FIFOQueue(), _running = false, - _notifications = {}, } self.__index = self setmetatable(service, self) @@ -38,11 +35,7 @@ function NotificationService:_run() end, 30) end ----@param message string | string[] ----@param level string | number ----@param opts NotifyOptions -function NotificationService:push(message, level, opts) - local notif = Notification(message, level, opts or {}) +function NotificationService:push(notif) local buf = vim.api.nvim_create_buf(false, true) local notif_buf = NotificationBuf(buf, notif) notif_buf:render() diff --git a/lua/notify/service/notification.lua b/lua/notify/service/notification.lua index 5f0881f..695b561 100644 --- a/lua/notify/service/notification.lua +++ b/lua/notify/service/notification.lua @@ -2,7 +2,7 @@ local config = require("notify.config") ---@class Notification ---@field level string ----@field message string +---@field message string[] ---@field timeout number | nil ---@field title string[] ---@field icon string @@ -14,6 +14,7 @@ local config = require("notify.config") local Notification = {} function Notification:new(message, level, opts) + opts = opts or {} if type(level) == "number" then level = vim.lsp.log_levels[level] end diff --git a/tests/unit/init_spec.lua b/tests/unit/init_spec.lua new file mode 100644 index 0000000..e6bd767 --- /dev/null +++ b/tests/unit/init_spec.lua @@ -0,0 +1,12 @@ +describe("checking public interface", function() + local notify = require("notify") + require("notify").setup({ background_colour = "#000000" }) + + describe("notifications", function() + it("returns all previous notifications", function() + notify("test", "error") + local notifs = notify.history() + assert.are.same({ { message = { "test" }, level = "ERROR", time = notifs[1].time } }, notifs) + end) + end) +end)