mirror of
https://github.com/nvim-lua/plenary.nvim
synced 2024-09-16 13:24:05 +02:00
feat: allow pos="center"
, row=0
, line=0
(#227)
This commit is contained in:
parent
ce8f7fa999
commit
edb76cc996
3 changed files with 77 additions and 59 deletions
1
POPUP.md
1
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-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:
|
||||
|
|
|
@ -98,61 +98,6 @@ function popup.create(what, vim_options)
|
|||
local win_opts = {}
|
||||
win_opts.relative = "editor"
|
||||
|
||||
local cursor_relative_pos = function(pos_str, dim)
|
||||
assert(string.find(pos_str, "^cursor"), "Invalid value for " .. dim)
|
||||
win_opts.relative = "cursor"
|
||||
local line = 0
|
||||
if (pos_str):match "cursor%+(%d+)" then
|
||||
line = line + tonumber((pos_str):match "cursor%+(%d+)")
|
||||
elseif (pos_str):match "cursor%-(%d+)" then
|
||||
line = line - tonumber((pos_str):match "cursor%-(%d+)")
|
||||
end
|
||||
return line
|
||||
end
|
||||
|
||||
if vim_options.line 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
|
||||
end
|
||||
|
||||
if vim_options.col 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
|
||||
end
|
||||
|
||||
-- , fixed When FALSE (the default), and:
|
||||
-- , - "pos" is "botleft" or "topleft", and
|
||||
-- , - "wrap" is off, and
|
||||
-- , - the popup would be truncated at the right edge of
|
||||
-- , the screen, then
|
||||
-- , the popup is moved to the left so as to fit the
|
||||
-- , contents on the screen. Set to TRUE to disable this.
|
||||
|
||||
win_opts.style = "minimal"
|
||||
|
||||
-- Feels like maxheight, minheight, maxwidth, minwidth will all be related
|
||||
--
|
||||
-- maxheight Maximum height of the contents, excluding border and padding.
|
||||
|
@ -172,6 +117,66 @@ 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
|
||||
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"
|
||||
local line = 0
|
||||
if (pos_str):match "cursor%+(%d+)" then
|
||||
line = line + tonumber((pos_str):match "cursor%+(%d+)")
|
||||
elseif (pos_str):match "cursor%-(%d+)" then
|
||||
line = line - tonumber((pos_str):match "cursor%-(%d+)")
|
||||
end
|
||||
return line
|
||||
end
|
||||
|
||||
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 - 1
|
||||
end
|
||||
else
|
||||
win_opts.row = math.floor((vim.o.lines - win_opts.height) / 2)
|
||||
end
|
||||
|
||||
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 - 1
|
||||
end
|
||||
else
|
||||
win_opts.col = math.floor((vim.o.columns - win_opts.width) / 2)
|
||||
end
|
||||
|
||||
-- , fixed When FALSE (the default), and:
|
||||
-- , - "pos" is "botleft" or "topleft", and
|
||||
-- , - "wrap" is off, and
|
||||
-- , - the popup would be truncated at the right edge of
|
||||
-- , the screen, then
|
||||
-- , the popup is moved to the left so as to fit the
|
||||
-- , contents on the screen. Set to TRUE to disable this.
|
||||
|
||||
win_opts.style = "minimal"
|
||||
|
||||
-- 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
|
||||
|
|
|
@ -50,8 +50,14 @@ describe("strings", function()
|
|||
{ 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 = { "アイウエオ", 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 = "├─┤" } },
|
||||
|
@ -64,8 +70,14 @@ describe("strings", function()
|
|||
{ 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 = { "アイウエオ", 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 = "├─┤" } },
|
||||
|
|
Loading…
Reference in a new issue