Skip to content

Commit 2c93e29

Browse files
committed
feat: use width of extmarks for window width
Takes rendered virtual text into account when calculating window width. Allows long titles to determine width See #68
1 parent 8e0ccb0 commit 2c93e29

File tree

5 files changed

+70
-17
lines changed

5 files changed

+70
-17
lines changed

lua/notify/render/base.lua

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
local M = {}
2+
3+
local namespace = vim.api.nvim_create_namespace("nvim-notify")
4+
5+
function M.namespace()
6+
return namespace
7+
end
8+
9+
return M

lua/notify/render/default.lua

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,48 @@
11
local api = vim.api
22
local config = require("notify.config")
3-
local namespace = api.nvim_create_namespace("nvim-notify")
3+
local base = require("notify.render.base")
44

55
return function(bufnr, notif, highlights)
66
local left_icon = notif.icon .. " "
7-
local max_width = math.max(
8-
math.max(unpack(vim.tbl_map(function(line)
9-
return vim.fn.strchars(line)
10-
end, notif.message))),
11-
config.minimum_width()
12-
)
13-
local left_title = notif.title[1] .. string.rep(" ", max_width)
7+
local max_message_width = math.max(math.max(unpack(vim.tbl_map(function(line)
8+
return vim.fn.strchars(line)
9+
end, notif.message))))
1410
local right_title = notif.title[2]
11+
local left_title = notif.title[1]
12+
local title_accum = vim.str_utfindex(left_icon)
13+
+ vim.str_utfindex(right_title)
14+
+ vim.str_utfindex(left_title)
15+
16+
local left_buffer = string.rep(" ", math.max(0, max_message_width - title_accum))
17+
18+
local namespace = base.namespace()
1519
api.nvim_buf_set_lines(bufnr, 0, 1, false, { "", "" })
1620
api.nvim_buf_set_extmark(bufnr, namespace, 0, 0, {
1721
virt_text = {
1822
{ " " },
1923
{ left_icon, highlights.icon },
20-
{ left_title, highlights.title },
24+
{ left_title .. left_buffer, highlights.title },
2125
},
2226
virt_text_win_col = 0,
23-
priority = max_width,
27+
priority = 10,
2428
})
2529
api.nvim_buf_set_extmark(bufnr, namespace, 0, 0, {
26-
virt_text = { { right_title, highlights.title }, { " " } },
30+
virt_text = { { " " }, { right_title, highlights.title }, { " " } },
2731
virt_text_pos = "right_align",
28-
priority = max_width,
32+
priority = 10,
2933
})
3034
api.nvim_buf_set_extmark(bufnr, namespace, 1, 0, {
31-
virt_text = { { string.rep("", max_width), highlights.border } },
35+
virt_text = {
36+
{
37+
string.rep(
38+
"",
39+
math.max(vim.str_utfindex(left_buffer) + title_accum + 2, config.minimum_width())
40+
),
41+
highlights.border,
42+
},
43+
},
3244
virt_text_win_col = 0,
33-
priority = max_width,
45+
priority = 10,
3446
})
3547
api.nvim_buf_set_lines(bufnr, 2, -1, false, notif.message)
3648

lua/notify/render/minimal.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
local api = vim.api
2-
local namespace = api.nvim_create_namespace("nvim-notify")
2+
local base = require("notify.render.base")
33

44
return function(bufnr, notif, highlights)
5+
local namespace = base.namespace()
56
api.nvim_buf_set_lines(bufnr, 0, -1, false, notif.message)
67

78
api.nvim_buf_set_extmark(bufnr, namespace, 0, 0, {

lua/notify/service/buffer/init.lua

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,28 @@ function NotificationBuf:render()
106106
for _, line in pairs(lines) do
107107
width = math.max(width, vim.str_utfindex(line))
108108
end
109+
local render_namespace = require("notify.render.base").namespace()
110+
local success, extmarks = pcall(
111+
api.nvim_buf_get_extmarks,
112+
buf,
113+
render_namespace,
114+
0,
115+
#lines,
116+
{ details = true }
117+
)
118+
if not success then
119+
extmarks = {}
120+
end
121+
local virt_texts = {}
122+
for _, mark in ipairs(extmarks) do
123+
local details = mark[4]
124+
for _, virt_text in ipairs(details.virt_text or {}) do
125+
virt_texts[mark[2]] = (virt_texts[mark[2]] or "") .. virt_text[1]
126+
end
127+
end
128+
for _, text in pairs(virt_texts) do
129+
width = math.max(width, vim.str_utfindex(text))
130+
end
109131

110132
self._width = width
111133
self._height = #lines

tests/unit/init_spec.lua

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ describe("checking public interface", function()
8282
a.it("uses the confgured minimum width", function()
8383
notify.setup({
8484
background_colour = "#000000",
85-
minimum_width = 10,
85+
minimum_width = 20,
8686
})
8787
local win = notify.async("test").events.open()
88-
assert.equal(vim.api.nvim_win_get_width(win), 10)
88+
assert.equal(vim.api.nvim_win_get_width(win), 20)
8989
end)
9090

9191
a.it("uses the configured max width", function()
@@ -109,4 +109,13 @@ describe("checking public interface", function()
109109
local win = notify.async("test").events.open()
110110
assert.equal(vim.api.nvim_win_get_height(win), 3)
111111
end)
112+
113+
a.it("renders title as longest line", function()
114+
notify.setup({
115+
background_colour = "#000000",
116+
minimum_width = 10,
117+
})
118+
local win = notify.async("test", nil, { title = { string.rep("a", 16), "" } }).events.open()
119+
assert.equal(21, vim.api.nvim_win_get_width(win))
120+
end)
112121
end)

0 commit comments

Comments
 (0)