Skip to content

feat: add wrapped-default as render #286

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 22, 2024
Merged
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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ Mostly same as `compact`, but lines are wrapped based on `max_width`, some paddi

![image](https://github.com/rcarriga/nvim-notify/assets/73286100/72237d45-6e3b-4c2a-8010-513a26871682)

5. "wrapped-default"

Similar to `default`, but lines are wrapped based on `max_width`, some padding is added.

Feel free to submit custom rendering functions to share with others!

### Animation Style
Expand Down
1 change: 1 addition & 0 deletions lua/notify/render/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
--- - `"simple"`
--- - `"compact"`
--- - `"wrapped-compact"`
--- - `"wrapped-default"`
---
--- Custom functions should accept a buffer, a notification record and a highlights table
---
Expand Down
86 changes: 86 additions & 0 deletions lua/notify/render/wrapped-default.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
local vim_api = vim.api
local base = require("notify.render.base")

---@param line string
---@param width number
---@return table
local function split_length(line, width)
local text = {}
local next_line
while true do
if #line == 0 then
return text
end
next_line, line = line:sub(1, width), line:sub(width + 1)
text[#text + 1] = next_line
end
end

---@param lines string[]
---@param max_width number
---@return table
local function custom_wrap(lines, max_width)
local wrapped_lines = {}
for _, line in pairs(lines) do
local new_lines = split_length(line, max_width)
for _, nl in ipairs(new_lines) do
nl = nl:gsub("^%s*", " "):gsub("%s*$", " ")
table.insert(wrapped_lines, nl)
end
end
return wrapped_lines
end

---@param bufnr number
---@param notif notify.Record
---@param highlights notify.Highlights
---@param config notify.Config
return function(bufnr, notif, highlights, config)
local namespace = base.namespace()
local icon = notif.icon .. " "
local title = notif.title[1] or "Notify"

local terminal_width = vim.o.columns
local default_max_width = math.floor((terminal_width * 30) / 100)
local max_width = config.max_width and config.max_width() or default_max_width

-- Ensure max_width is within bounds
max_width = math.max(10, math.min(max_width, terminal_width - 1))

local message = custom_wrap(notif.message, max_width)

local prefix = string.format(" %s %s", icon, title)
table.insert(message, 1, prefix)
table.insert(message, 2, string.rep("━", max_width))

vim_api.nvim_buf_set_lines(bufnr, 0, -1, false, message)

local prefix_length = vim.str_utfindex(prefix)
prefix_length = math.min(prefix_length, max_width - 1)

vim_api.nvim_buf_set_extmark(bufnr, namespace, 0, 0, {
virt_text = {
{ " " },
{ icon, highlights.icon },
{ title, highlights.title },
{ " " },
},
virt_text_win_col = 0,
priority = 10,
})

vim_api.nvim_buf_set_extmark(bufnr, namespace, 1, 0, {
virt_text = {
{ string.rep("━", max_width), highlights.border },
},
virt_text_win_col = 0,
priority = 10,
})

vim_api.nvim_buf_set_extmark(bufnr, namespace, 2, prefix_length + 1, {
hl_group = highlights.body,
end_line = #message,
end_col = 0,
priority = 50,
})
end
25 changes: 24 additions & 1 deletion tests/unit/init_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,29 @@ describe("checking public interface", function()
assert.is.True(called)
end)

a.it("validates max width and prefix length", function()
local terminal_width = vim.o.columns
notify.setup({
background_colour = "#000000",
max_width = function()
return math.min(terminal_width, 50)
end,
})

local win = notify.async("test", "info").events.open()

assert.is.True(vim.api.nvim_win_get_width(win) <= terminal_width)

local notif = notify.notify("Test Notification", "info", {
title = "Long Title That Should Be Cut Off",
})

local prefix_title = notif.title and notif.title[1] or "Default Title"

local prefix_length = vim.str_utfindex(prefix_title)
assert.is.True(prefix_length <= terminal_width)
end)

a.it("uses custom render in call", function()
local called = false
notify
Expand Down Expand Up @@ -87,7 +110,7 @@ describe("checking public interface", function()
end)
end)

a.it("uses the confgured minimum width", function()
a.it("uses the configured minimum width", function()
notify.setup({
background_colour = "#000000",
minimum_width = 20,
Expand Down