Skip to content

Commit

Permalink
fix(padding)!: validate padding before drawing popup
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Validate padding alongside the window width and
height, before drawing popup.

Closes: GH-62
Signed-off-by: Filip Dutescu <filip.dutescu@gmail.com>
  • Loading branch information
filipdutescu committed Nov 8, 2021
1 parent a4a1bcf commit da75d77
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 17 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,12 @@ require('renamer').setup {
-- The popup title, shown if `border` is true
title = 'Rename',
-- The padding around the popup content
padding = { 0, 0, 0, 0 },
padding = {
top = 0,
left = 0,
bottom = 0,
right = 0,
}
-- Whether or not to shown a border around the popup
border = true,
-- The characters which make up the border
Expand Down
12 changes: 9 additions & 3 deletions doc/renamer.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ renamer.setup({opts})
-- The popup title, shown if `border` is true
title = 'Rename',
-- The padding around the popup content
padding = { 0, 0, 0, 0 },
padding = {
top = 0,
left = 0,
bottom = 0,
right = 0,
}
-- Whether or not to shown a border around the popup
border = true,
-- The characters which make up the border
Expand Down Expand Up @@ -65,10 +70,11 @@ renamer.setup({opts})
Fields: ~
{title} (string) title of the popup, shown on the top border
(default: 'Rename')
{padding} (list) list of integer values that define the
{padding} (table) table of integer values that define the
padding of the popup, as such:
above/right/below/left
(default: { 0, 0, 0, 0 })
(default: { top = 0, left = 0, bottom = 0,
right = 0 })
{border} (boolean) defines whether or not to draw the border
(default: true)
{border_chars} (list) list of characters to use for the border,
Expand Down
9 changes: 7 additions & 2 deletions lua/renamer/defaults.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ local mappings = require 'renamer.mappings'

--- @class Defaults
--- @field public title string
--- @field public padding integer[]
--- @field public padding table
--- @field public border boolean
--- @field public border_chars string[]
--- @field public show_refs boolean
Expand All @@ -11,7 +11,12 @@ local defaults = {
-- The popup title, shown if `border` is true
title = 'Rename',
-- The padding around the popup content
padding = { 0, 0, 0, 0 },
padding = {
top = 0,
left = 0,
bottom = 0,
right = 0,
},
-- Whether or not to shown a border around the popup
border = true,
-- The characters which make up the border
Expand Down
27 changes: 20 additions & 7 deletions lua/renamer/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ local renamer = {}
--- -- The popup title, shown if `border` is true
--- title = 'Rename',
--- -- The padding around the popup content
--- padding = { 0, 0, 0, 0 },
--- padding = {
--- top = 0,
--- left = 0,
--- bottom = 0,
--- right = 0,
--- }
--- -- Whether or not to shown a border around the popup
--- border = true,
--- -- The characters which make up the border
Expand All @@ -53,7 +58,12 @@ function renamer.setup(opts)
local defaults = require 'renamer.defaults'

renamer.title = utils.get_value_or_default(opts, 'title', defaults.title)
renamer.padding = utils.get_value_or_default(opts, 'padding', defaults.padding)
renamer.padding = {
top = utils.get_value_or_default(opts.padding, 'top', defaults.padding.top),
left = utils.get_value_or_default(opts.padding, 'left', defaults.padding.left),
bottom = utils.get_value_or_default(opts.padding, 'bottom', defaults.padding.bottom),
right = utils.get_value_or_default(opts.padding, 'right', defaults.padding.right),
}
renamer.border = utils.get_value_or_default(opts, 'border', defaults.border)
renamer.border_chars = utils.get_value_or_default(opts, 'border_chars', defaults.border_chars)
renamer.show_refs = utils.get_value_or_default(opts, 'show_refs', defaults.show_refs)
Expand Down Expand Up @@ -81,10 +91,12 @@ function renamer.rename()
local win_width = vim.api.nvim_win_get_width(0)
local cword = vim.fn.expand '<cword>'
local popup_opts = renamer._create_default_popup_opts(cword)
local is_height_too_short = renamer.border == true and win_height < 4
or not (renamer.border == true) and win_height < 2
local is_width_too_short = renamer.border == true and win_width < popup_opts.minwidth + 2
or not (renamer.border == true) and win_width < popup_opts.minwidth
local padding_top_bottom = renamer.padding.top + renamer.padding.bottom
local padding_left_right = renamer.padding.left + renamer.padding.right
local is_height_too_short = renamer.border == true and win_height < 4 + padding_top_bottom
or not (renamer.border == true) and win_height < 2 + padding_top_bottom
local is_width_too_short = renamer.border == true and win_width < popup_opts.minwidth + 2 + padding_left_right
or not (renamer.border == true) and win_width < popup_opts.minwidth + padding_left_right

if is_height_too_short or is_width_too_short then
log.error 'Window does not provide enough space for the popup to be drawn.'
Expand Down Expand Up @@ -191,10 +203,11 @@ function renamer.on_close(window_id, should_set_cursor_pos)
end

function renamer._create_default_popup_opts(cword)
local p = renamer.padding
return {
title = renamer.title,
titlehighlight = 'RenamerTitle',
padding = renamer.padding,
padding = { p.top, p.right, p.bottom, p.left },
border = renamer.border,
borderchars = renamer.border_chars,
highlight = 'RenamerNormal',
Expand Down
7 changes: 6 additions & 1 deletion lua/tests/defaults_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ describe('defaults', function()
local mappings = require 'renamer.mappings'
local expected_defaults = {
title = 'Rename',
padding = { 0, 0, 0, 0 },
padding = {
top = 0,
left = 0,
bottom = 0,
right = 0,
},
border = true,
border_chars = { '', '', '', '', '', '', '', '' },
show_refs = true,
Expand Down
64 changes: 63 additions & 1 deletion lua/tests/renamer_rename_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,67 @@ describe('renamer', function()
expand.revert(expand)
end)

it('should fallback to `vim.lsp.buf.rename()` if padding is too large (with border)', function()
renamer.setup {
padding = {
top = 20,
left = 20,
bottom = 20,
right = 20,
},
}
local expected_cword = 'test'
local api_mock = mock(vim.api, true)
api_mock.nvim_win_get_cursor.returns()
api_mock.nvim_win_get_height.returns(15)
api_mock.nvim_win_get_width.returns(10)
api_mock.nvim_get_mode.returns { mode = 'n' }
local expand = stub(vim.fn, 'expand').returns(expected_cword)
local rename = stub(renamer, '_nvim_lsp_rename').returns()
local document_highlight = stub(renamer, '_document_highlight').returns()
stub(popup, 'create').returns(1, {})

renamer.rename()

assert.spy(rename).called_at_least(1)
assert.spy(rename).called_at_most(1)
mock.revert(api_mock)
document_highlight.revert(document_highlight)
rename.revert(rename)
expand.revert(expand)
end)

it('should fallback to `vim.lsp.buf.rename()` if padding is too large (without border)', function()
renamer.setup {
border = false,
padding = {
top = 20,
left = 20,
bottom = 20,
right = 20,
},
}
local expected_cword = 'test'
local api_mock = mock(vim.api, true)
api_mock.nvim_win_get_cursor.returns()
api_mock.nvim_win_get_height.returns(15)
api_mock.nvim_win_get_width.returns(10)
api_mock.nvim_get_mode.returns { mode = 'n' }
local expand = stub(vim.fn, 'expand').returns(expected_cword)
local rename = stub(renamer, '_nvim_lsp_rename').returns()
local document_highlight = stub(renamer, '_document_highlight').returns()
stub(popup, 'create').returns(1, {})

renamer.rename()

assert.spy(rename).called_at_least(1)
assert.spy(rename).called_at_most(1)
mock.revert(api_mock)
document_highlight.revert(document_highlight)
rename.revert(rename)
expand.revert(expand)
end)

it('should call `_get_word_boundaries_in_line`', function()
local expected_cword, expected_line, expected_col = 'test', 1, 2
local api_mock = mock(vim.api, true)
Expand Down Expand Up @@ -237,10 +298,11 @@ describe('renamer', function()
it('should return the buffer ID and the popup options', function()
local expected_col_no, expected_line_no = 2, 2
local word_start = 1
local p = renamer.padding
local expected_opts = {
title = renamer.title,
titlehighlight = 'RenamerTitle',
padding = renamer.padding,
padding = { p.top, p.right, p.bottom, p.left },
border = renamer.border,
borderchars = renamer.border_chars,
highlight = 'RenamerNormal',
Expand Down
14 changes: 12 additions & 2 deletions lua/tests/renamer_setup_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ describe('renamer', function()
it('should use defaults where no options are passed ("padding" passed)', function()
local mappings = require 'renamer.mappings'
local opts = {
padding = { 1, 2, 3, 4 },
padding = {
top = 1,
left = 2,
bottom = 3,
right = 4,
},
}

renamer.setup(opts)
Expand Down Expand Up @@ -127,7 +132,12 @@ describe('renamer', function()
local mappings = require 'renamer.mappings'
local opts = {
title = 'abc',
padding = { 1, 2, 3, 4 },
padding = {
top = 1,
left = 2,
bottom = 3,
right = 4,
},
border = false,
border_chars = { '', '', '', '', '', '', '', '' },
show_refs = false,
Expand Down

0 comments on commit da75d77

Please sign in to comment.