From 12df9a0012277d49c011854c4eee062f80228832 Mon Sep 17 00:00:00 2001 From: Luke Kershaw <35707277+l-kershaw@users.noreply.github.com> Date: Sat, 4 Sep 2021 22:22:16 +0100 Subject: [PATCH 1/7] feat: allow `pos="center"`, `row=0`, `line=0` --- lua/plenary/popup/init.lua | 72 +++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/lua/plenary/popup/init.lua b/lua/plenary/popup/init.lua index 83d727c0..f2161c24 100644 --- a/lua/plenary/popup/init.lua +++ b/lua/plenary/popup/init.lua @@ -98,6 +98,38 @@ function popup.create(what, vim_options) local win_opts = {} win_opts.relative = "editor" + -- Feels like maxheight, minheight, maxwidth, minwidth will all be related + -- + -- maxheight Maximum height of the contents, excluding border and padding. + -- minheight Minimum height of the contents, excluding border and padding. + -- maxwidth Maximum width of the contents, excluding border, padding and scrollbar. + -- minwidth Minimum width of the contents, excluding border, padding and scrollbar. + local width = vim_options.width or 1 + local height + if type(what) == "number" then + height = vim.api.nvim_buf_line_count(what) + else + for _, v in ipairs(what) do + width = math.max(width, #v) + end + height = #what + end + win_opts.width = utils.bounded(width, vim_options.minwidth, vim_options.maxwidth) + win_opts.height = utils.bounded(height, vim_options.minheight, vim_options.maxheight) + + -- + if vim_options.pos then + if vim_options.pos == "center" then + vim_options.line = 0 + vim_options.col = 0 + win_opts.anchor = "NW" + else + win_opts.anchor = popup._pos_map[vim_options.pos] + end + else + win_opts.anchor = "NW" -- This is the default, but makes `posinvert` easier to implement + end + local cursor_relative_pos = function(pos_str, dim) assert(string.find(pos_str, "^cursor"), "Invalid value for " .. dim) win_opts.relative = "cursor" @@ -110,37 +142,24 @@ function popup.create(what, vim_options) return line end - if vim_options.line then + if vim_options.line and vim_options.line ~= 0 then if type(vim_options.line) == "string" then win_opts.row = cursor_relative_pos(vim_options.line, "row") else win_opts.row = vim_options.line end else - -- TODO: It says it needs to be "vertically cenetered"?... - -- wut is that. - win_opts.row = 0 + win_opts.row = math.floor((vim.o.lines - win_opts.height)/2) end - if vim_options.col then + if vim_options.col and vim_options.col ~= 0 then if type(vim_options.col) == "string" then win_opts.col = cursor_relative_pos(vim_options.col, "col") else win_opts.col = vim_options.col end else - -- TODO: It says it needs to be "horizontally cenetered"?... - win_opts.col = 0 - end - - if vim_options.pos then - if vim_options.pos == "center" then - -- TODO: Do centering.. - else - win_opts.anchor = popup._pos_map[vim_options.pos] - end - else - win_opts.anchor = "NW" -- This is the default, but makes `posinvert` easier to implement + win_opts.col = math.floor((vim.o.columns - win_opts.width)/2) end -- , fixed When FALSE (the default), and: @@ -153,25 +172,6 @@ function popup.create(what, vim_options) win_opts.style = "minimal" - -- Feels like maxheight, minheight, maxwidth, minwidth will all be related - -- - -- maxheight Maximum height of the contents, excluding border and padding. - -- minheight Minimum height of the contents, excluding border and padding. - -- maxwidth Maximum width of the contents, excluding border, padding and scrollbar. - -- minwidth Minimum width of the contents, excluding border, padding and scrollbar. - local width = vim_options.width or 1 - local height - if type(what) == "number" then - height = vim.api.nvim_buf_line_count(what) - else - for _, v in ipairs(what) do - width = math.max(width, #v) - end - height = #what - end - win_opts.width = utils.bounded(width, vim_options.minwidth, vim_options.maxwidth) - win_opts.height = utils.bounded(height, vim_options.minheight, vim_options.maxheight) - -- posinvert, When FALSE the value of "pos" is always used. When -- , TRUE (the default) and the popup does not fit -- , vertically and there is more space on the other side From 14dd33e644589c15cd756435573f6df809f9a14e Mon Sep 17 00:00:00 2001 From: Luke Kershaw <35707277+l-kershaw@users.noreply.github.com> Date: Sat, 4 Sep 2021 22:26:07 +0100 Subject: [PATCH 2/7] fix: shift indices to match vim implementation --- lua/plenary/popup/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/plenary/popup/init.lua b/lua/plenary/popup/init.lua index f2161c24..71d5a4b6 100644 --- a/lua/plenary/popup/init.lua +++ b/lua/plenary/popup/init.lua @@ -146,7 +146,7 @@ function popup.create(what, vim_options) if type(vim_options.line) == "string" then win_opts.row = cursor_relative_pos(vim_options.line, "row") else - win_opts.row = vim_options.line + win_opts.row = vim_options.line - 1 end else win_opts.row = math.floor((vim.o.lines - win_opts.height)/2) @@ -156,7 +156,7 @@ function popup.create(what, vim_options) if type(vim_options.col) == "string" then win_opts.col = cursor_relative_pos(vim_options.col, "col") else - win_opts.col = vim_options.col + win_opts.col = vim_options.col - 1 end else win_opts.col = math.floor((vim.o.columns - win_opts.width)/2) From 55f9fd49d45b6d91685e163a923c7b244f0bb0af Mon Sep 17 00:00:00 2001 From: Luke Kershaw <35707277+l-kershaw@users.noreply.github.com> Date: Sat, 4 Sep 2021 22:34:41 +0100 Subject: [PATCH 3/7] chore: docs and stylua --- lua/plenary/popup/init.lua | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lua/plenary/popup/init.lua b/lua/plenary/popup/init.lua index 71d5a4b6..268b2703 100644 --- a/lua/plenary/popup/init.lua +++ b/lua/plenary/popup/init.lua @@ -117,7 +117,12 @@ function popup.create(what, vim_options) win_opts.width = utils.bounded(width, vim_options.minwidth, vim_options.maxwidth) win_opts.height = utils.bounded(height, vim_options.minheight, vim_options.maxheight) - -- + -- pos + -- + -- Using "topleft", "topright", "botleft", "botright" defines what corner of the popup "line" + -- and "col" are used for. When not set "topleft" behaviour is used. + -- Alternatively "center" can be used to position the popup in the center of the Neovim window, + -- in which case "line" and "col" are ignored. if vim_options.pos then if vim_options.pos == "center" then vim_options.line = 0 @@ -149,7 +154,7 @@ function popup.create(what, vim_options) win_opts.row = vim_options.line - 1 end else - win_opts.row = math.floor((vim.o.lines - win_opts.height)/2) + win_opts.row = math.floor((vim.o.lines - win_opts.height) / 2) end if vim_options.col and vim_options.col ~= 0 then @@ -159,7 +164,7 @@ function popup.create(what, vim_options) win_opts.col = vim_options.col - 1 end else - win_opts.col = math.floor((vim.o.columns - win_opts.width)/2) + win_opts.col = math.floor((vim.o.columns - win_opts.width) / 2) end -- , fixed When FALSE (the default), and: From 944f3587adca3bcdaa981b0e23b3e2b3db639ff5 Mon Sep 17 00:00:00 2001 From: Luke Kershaw <35707277+l-kershaw@users.noreply.github.com> Date: Sun, 5 Sep 2021 12:18:56 +0100 Subject: [PATCH 4/7] docs: add notice to POPUP.md --- POPUP.md | 1 + 1 file changed, 1 insertion(+) diff --git a/POPUP.md b/POPUP.md index 0721f1af..8ac32779 100644 --- a/POPUP.md +++ b/POPUP.md @@ -10,6 +10,7 @@ stablization and any required features are merged into Neovim, we can upstream this and expose the API in vimL to create better compatibility. ## Notices +- **2021-09-05:** we now follow Vim's convention of the first line/column of the screen being indexed 1, so that 0 can be used for centering. - **2021-08-19:** we now follow Vim's default to `noautocmd` on popup creation. This can be overriden with `vim_options.noautocmd=false` ## List of Neovim Features Required: From 5877951c1778ea41cdef6dba7abcfd369ba17d51 Mon Sep 17 00:00:00 2001 From: Luke Kershaw <35707277+l-kershaw@users.noreply.github.com> Date: Sun, 19 Sep 2021 16:43:11 +0100 Subject: [PATCH 5/7] chore: update notice date --- POPUP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/POPUP.md b/POPUP.md index 8ac32779..c56df43d 100644 --- a/POPUP.md +++ b/POPUP.md @@ -10,7 +10,7 @@ stablization and any required features are merged into Neovim, we can upstream this and expose the API in vimL to create better compatibility. ## Notices -- **2021-09-05:** we now follow Vim's convention of the first line/column of the screen being indexed 1, so that 0 can be used for centering. +- **2021-09-19:** we now follow Vim's convention of the first line/column of the screen being indexed 1, so that 0 can be used for centering. - **2021-08-19:** we now follow Vim's default to `noautocmd` on popup creation. This can be overriden with `vim_options.noautocmd=false` ## List of Neovim Features Required: From 6553359c0e71e59c8e7689217adccbdcba18fe28 Mon Sep 17 00:00:00 2001 From: Luke Kershaw <35707277+l-kershaw@users.noreply.github.com> Date: Sun, 19 Sep 2021 17:12:13 +0100 Subject: [PATCH 6/7] fix: stylua complaining for some reason --- tests/plenary/strings_spec.lua | 53 +++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/tests/plenary/strings_spec.lua b/tests/plenary/strings_spec.lua index 0085d3eb..97b335b4 100644 --- a/tests/plenary/strings_spec.lua +++ b/tests/plenary/strings_spec.lua @@ -46,19 +46,46 @@ describe("strings", function() describe("truncate", function() for _, case in ipairs { - { args = { "abcde", 6 }, expected = { single = "abcde", double = "abcde" } }, - { args = { "abcde", 5 }, expected = { single = "abcde", double = "abcde" } }, - { args = { "abcde", 4 }, expected = { single = "abc…", double = "ab…" } }, - { args = { "アイウエオ", 11 }, expected = { single = "アイウエオ", double = "アイウエオ" } }, - { args = { "アイウエオ", 10 }, expected = { single = "アイウエオ", double = "アイウエオ" } }, - { args = { "アイウエオ", 9 }, expected = { single = "アイウエ…", double = "アイウ…" } }, - { args = { "アイウエオ", 8 }, expected = { single = "アイウ…", double = "アイウ…" } }, - { args = { "├─┤", 7 }, expected = { single = "├─┤", double = "├─┤" } }, - { args = { "├─┤", 6 }, expected = { single = "├─┤", double = "├─┤" } }, - { args = { "├─┤", 5 }, expected = { single = "├─┤", double = "├…" } }, - { args = { "├─┤", 4 }, expected = { single = "├─┤", double = "├…" } }, - { args = { "├─┤", 3 }, expected = { single = "├─┤", double = "…" } }, - { args = { "├─┤", 2 }, expected = { single = "├…", double = "…" } }, + -- truncations from the right + { args = { "abcde", 6, nil, 1 }, expected = { single = "abcde", double = "abcde" } }, + { args = { "abcde", 5, nil, 1 }, expected = { single = "abcde", double = "abcde" } }, + { args = { "abcde", 4, nil, 1 }, expected = { single = "abc…", double = "ab…" } }, + { + args = { "アイウエオ", 11, nil, 1 }, + expected = { single = "アイウエオ", double = "アイウエオ" } + }, + { + args = { "アイウエオ", 10, nil, 1 }, + expected = { single = "アイウエオ", double = "アイウエオ" } + }, + { args = { "アイウエオ", 9, nil, 1 }, expected = { single = "アイウエ…", double = "アイウ…" } }, + { args = { "アイウエオ", 8, nil, 1 }, expected = { single = "アイウ…", double = "アイウ…" } }, + { args = { "├─┤", 7, nil, 1 }, expected = { single = "├─┤", double = "├─┤" } }, + { args = { "├─┤", 6, nil, 1 }, expected = { single = "├─┤", double = "├─┤" } }, + { args = { "├─┤", 5, nil, 1 }, expected = { single = "├─┤", double = "├…" } }, + { args = { "├─┤", 4, nil, 1 }, expected = { single = "├─┤", double = "├…" } }, + { args = { "├─┤", 3, nil, 1 }, expected = { single = "├─┤", double = "…" } }, + { args = { "├─┤", 2, nil, 1 }, expected = { single = "├…", double = "…" } }, + -- truncations from the left + { args = { "abcde", 6, nil, -1 }, expected = { single = "abcde", double = "abcde" } }, + { args = { "abcde", 5, nil, -1 }, expected = { single = "abcde", double = "abcde" } }, + { args = { "abcde", 4, nil, -1 }, expected = { single = "…cde", double = "…de" } }, + { + args = { "アイウエオ", 11, nil, 1 }, + expected = { single = "アイウエオ", double = "アイウエオ" } + }, + { + args = { "アイウエオ", 10, nil, 1 }, + expected = { single = "アイウエオ", double = "アイウエオ" } + }, + { args = { "アイウエオ", 9, nil, -1 }, expected = { single = "…イウエオ", double = "…ウエオ" } }, + { args = { "アイウエオ", 8, nil, -1 }, expected = { single = "…ウエオ", double = "…ウエオ" } }, + { args = { "├─┤", 7, nil, -1 }, expected = { single = "├─┤", double = "├─┤" } }, + { args = { "├─┤", 6, nil, -1 }, expected = { single = "├─┤", double = "├─┤" } }, + { args = { "├─┤", 5, nil, -1 }, expected = { single = "├─┤", double = "…┤" } }, + { args = { "├─┤", 4, nil, -1 }, expected = { single = "├─┤", double = "…┤" } }, + { args = { "├─┤", 3, nil, -1 }, expected = { single = "├─┤", double = "…" } }, + { args = { "├─┤", 2, nil, -1 }, expected = { single = "…┤", double = "…" } }, } do for _, ambiwidth in ipairs { "single", "double" } do local msg = ("ambiwidth = %s, [%s, %d] -> %s"):format( From 90dd04f10f88f8299e590d0a704e9a59e9b2ae7e Mon Sep 17 00:00:00 2001 From: Luke Kershaw <35707277+l-kershaw@users.noreply.github.com> Date: Sun, 19 Sep 2021 17:16:14 +0100 Subject: [PATCH 7/7] stylua --- tests/plenary/strings_spec.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/plenary/strings_spec.lua b/tests/plenary/strings_spec.lua index c7ee40e8..cbab7896 100644 --- a/tests/plenary/strings_spec.lua +++ b/tests/plenary/strings_spec.lua @@ -52,11 +52,11 @@ describe("strings", function() { args = { "abcde", 4, nil, 1 }, expected = { single = "abc…", double = "ab…" } }, { args = { "アイウエオ", 11, nil, 1 }, - expected = { single = "アイウエオ", double = "アイウエオ" } + expected = { single = "アイウエオ", double = "アイウエオ" }, }, { args = { "アイウエオ", 10, nil, 1 }, - expected = { single = "アイウエオ", double = "アイウエオ" } + expected = { single = "アイウエオ", double = "アイウエオ" }, }, { args = { "アイウエオ", 9, nil, 1 }, expected = { single = "アイウエ…", double = "アイウ…" } }, { args = { "アイウエオ", 8, nil, 1 }, expected = { single = "アイウ…", double = "アイウ…" } }, @@ -72,11 +72,11 @@ describe("strings", function() { args = { "abcde", 4, nil, -1 }, expected = { single = "…cde", double = "…de" } }, { args = { "アイウエオ", 11, nil, 1 }, - expected = { single = "アイウエオ", double = "アイウエオ" } + expected = { single = "アイウエオ", double = "アイウエオ" }, }, { args = { "アイウエオ", 10, nil, 1 }, - expected = { single = "アイウエオ", double = "アイウエオ" } + expected = { single = "アイウエオ", double = "アイウエオ" }, }, { args = { "アイウエオ", 9, nil, -1 }, expected = { single = "…イウエオ", double = "…ウエオ" } }, { args = { "アイウエオ", 8, nil, -1 }, expected = { single = "…ウエオ", double = "…ウエオ" } },