Skip to content

Commit

Permalink
feat: add wrapped-default as render (#286)
Browse files Browse the repository at this point in the history
* feat: add wrapped-default as render

* test(notify): add validation tests for max_width and prefix_length

- Added unit tests to validate `max_width` and ensure it does not exceed the terminal width.
- Ensured `prefix_length` is within the valid range to prevent 'col out of range' errors.
- Improved test coverage for rendering and notification layout in `nvim-notify`.

These changes address issues related to invalid column rendering and out-of-bounds errors.

---------

Co-authored-by: rvjs <renato.valentim@tempest.com.br>
  • Loading branch information
RenatoValentim and rvjs authored Sep 22, 2024
1 parent d333b6f commit fbef5d3
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 1 deletion.
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

0 comments on commit fbef5d3

Please sign in to comment.