Skip to content

Commit

Permalink
feat: add type annotations for plenary.window
Browse files Browse the repository at this point in the history
  • Loading branch information
delphinus committed Apr 28, 2024
1 parent 832a7d6 commit 07e5613
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 1 deletion.
1 change: 1 addition & 0 deletions lua/plenary/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
---@field scandir PlenaryScandir
---@field strings PlenaryStrings
---@field tbl PlenaryTbl
---@field window PlenaryWindow
local plenary = setmetatable({}, {
__index = function(t, k)
local ok, val = pcall(require, string.format("plenary.%s", k))
Expand Down
71 changes: 70 additions & 1 deletion lua/plenary/window/border.lua
Original file line number Diff line number Diff line change
@@ -1,16 +1,53 @@
local strings = require "plenary.strings"

---@class PlenaryWindowBorder
---@field bufnr integer
---@field content_win_id integer
---@field content_win_options vim.api.keyset.win_config
---@field contents string[]
---@field win_id integer
---@field private _border_win_options PlenaryWindowBorderBorderOptions
local Border = {}

---@class PlenaryWindowBorderBorderOptions
---@field border_thickness PlenaryWindowBorderBorderThickness
---@field topleft string
---@field topright string
---@field top string
---@field left string
---@field right string
---@field botleft string
---@field botright string
---@field bot string
---@field focusable? boolean
---@field highlight? string
---@field title? string|PlenaryWindowBorderTitles
---@field titlehighlight? string

---@class PlenaryWindowBorderBorderThickness
---@field top integer
---@field right integer
---@field bot integer
---@field left integer

---@alias PlenaryWindowBorderPos "NW"|"N"|"NE"|"SW"|"S"|"SE"
---@alias PlenaryWindowBorderRanges { [1]: integer, [2]: integer, [3]: integer? }[]
---@alias PlenaryWindowBorderTitles { text: string, pos: PlenaryWindowBorderPos }[]

Border.__index = Border

---@type PlenaryWindowBorderBorderThickness
Border._default_thickness = {
top = 1,
right = 1,
bot = 1,
left = 1,
}

---@param title_pos string
---@param title_len integer
---@param total_width integer
---@return integer
local calc_left_start = function(title_pos, title_len, total_width)
if string.find(title_pos, "W") then
return 0
Expand All @@ -21,6 +58,15 @@ local calc_left_start = function(title_pos, title_len, total_width)
end
end

---comment
---@param title string
---@param pos PlenaryWindowBorderPos
---@param width integer
---@param left_char string
---@param mid_char string
---@param right_char string
---@return string horizontal_line
---@return PlenaryWindowBorderRanges ranges
local create_horizontal_line = function(title, pos, width, left_char, mid_char, right_char)
local title_len
if title == "" then
Expand All @@ -46,6 +92,7 @@ local create_horizontal_line = function(title, pos, width, left_char, mid_char,
string.rep(mid_char, width - title_len - left_start),
right_char
)
---@type PlenaryWindowBorderRanges
local ranges = {}
if title_len ~= 0 then
-- Need to calculate again due to multi-byte characters
Expand All @@ -55,6 +102,11 @@ local create_horizontal_line = function(title, pos, width, left_char, mid_char,
return horizontal_line, ranges
end

---@param content_win_id integer
---@param content_win_options vim.api.keyset.win_config
---@param border_win_options PlenaryWindowBorderBorderOptions
---@return string[] border_lines
---@return PlenaryWindowBorderRanges ranges
function Border._create_lines(content_win_id, content_win_options, border_win_options)
local content_pos = vim.api.nvim_win_get_position(content_win_id)
local content_height = vim.api.nvim_win_get_height(content_win_id)
Expand All @@ -71,15 +123,17 @@ function Border._create_lines(content_win_id, content_win_options, border_win_op
border_win_options.border_thickness.left = left_enabled and 1 or 0
border_win_options.border_thickness.right = right_enabled and 1 or 0

---@type string[]
local border_lines = {}
---@type PlenaryWindowBorderRanges
local ranges = {}

-- border_win_options.title should have be a list with entries of the
-- form: { pos = foo, text = bar }.
-- pos can take values in { "NW", "N", "NE", "SW", "S", "SE" }
local titles = type(border_win_options.title) == "string" and { { pos = "N", text = border_win_options.title } }
or border_win_options.title
or {}
or {} --[[@as PlenaryWindowBorderTitles]]

local topline = nil
local topleft = (left_enabled and border_win_options.topleft) or ""
Expand Down Expand Up @@ -164,6 +218,9 @@ function Border._create_lines(content_win_id, content_win_options, border_win_op
return border_lines, ranges
end

---@param bufnr integer
---@param ranges? PlenaryWindowBorderRanges
---@param hl? string
local set_title_highlights = function(bufnr, ranges, hl)
-- Check if both `hl` and `ranges` are provided, and `ranges` is not the empty table.
if hl and ranges and next(ranges) then
Expand All @@ -173,6 +230,8 @@ local set_title_highlights = function(bufnr, ranges, hl)
end
end

---@param new_title string
---@param pos string
function Border:change_title(new_title, pos)
if self._border_win_options.title == new_title then
return
Expand All @@ -195,6 +254,9 @@ end

-- Updates characters for border lines, and returns nvim_win_config
-- (generally used in conjunction with `move` or `new`)
---@param content_win_options vim.api.keyset.win_config
---@param border_win_options PlenaryWindowBorderBorderOptions
---@return vim.api.keyset.win_config
function Border:__align_calc_config(content_win_options, border_win_options)
border_win_options = vim.tbl_deep_extend("keep", border_win_options, {
border_thickness = Border._default_thickness,
Expand Down Expand Up @@ -239,6 +301,8 @@ end
-- Sets the size and position of the given Border.
-- Can be used to create a new window (with `create_window = true`)
-- or change an existing one
---@param content_win_options vim.api.keyset.win_config
---@param border_win_options PlenaryWindowBorderBorderOptions
function Border:move(content_win_options, border_win_options)
-- Update lines in border buffer, and get config for border window
local nvim_win_config = self:__align_calc_config(content_win_options, border_win_options)
Expand All @@ -249,6 +313,11 @@ function Border:move(content_win_options, border_win_options)
set_title_highlights(self.bufnr, self.title_ranges, self._border_win_options.titlehighlight)
end

---@param content_bufnr integer
---@param content_win_id integer
---@param content_win_options vim.api.keyset.win_config
---@param border_win_options PlenaryWindowBorderBorderOptions
---@return PlenaryWindowBorder
function Border:new(content_bufnr, content_win_id, content_win_options, border_win_options)
assert(type(content_win_id) == "number", "Must supply a valid win_id. It's possible you forgot to call with ':'")

Expand Down
21 changes: 21 additions & 0 deletions lua/plenary/window/float.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local tbl = require "plenary.tbl"

_AssociatedBufs = {}

---@param bufnr integer
local clear_buf_on_leave = function(bufnr)
vim.cmd(
string.format(
Expand All @@ -13,13 +14,22 @@ local clear_buf_on_leave = function(bufnr)
)
end

---@class PlenaryWindowFloat
---@field default_options PlenaryWindowFloatOptions
local win_float = {}

---@class PlenaryWindowFloatOptions
---@field bufnr? integer
---@field percentage float
---@field winblend float

win_float.default_options = {
winblend = 15,
percentage = 0.9,
}

---@param options? PlenaryWindowFloatOptions
---@return vim.api.keyset.win_config
function win_float.default_opts(options)
options = tbl.apply_defaults(options, win_float.default_options)

Expand All @@ -41,6 +51,8 @@ function win_float.default_opts(options)
return opts
end

---@param options? PlenaryWindowFloatOptions
---@return { bufnr: integer, win_id: integer }
function win_float.centered(options)
options = tbl.apply_defaults(options, win_float.default_options)

Expand All @@ -60,6 +72,9 @@ function win_float.centered(options)
}
end

---@param top_text string[]
---@param options? PlenaryWindowFloatOptions
---@return { bufnr: integer, win_id: integer, minor_bufnr: integer, minor_win_id: integer }
function win_float.centered_with_top_win(top_text, options)
options = tbl.apply_defaults(options, win_float.default_options)

Expand Down Expand Up @@ -135,6 +150,11 @@ end
-- If table, first index should be start, second_index should be end
--@param win_opts Table
--@param border_opts Table
---@param col_range integer
---@param row_range integer
---@param win_opts? PlenaryWindowFloatOptions
---@param border_opts? PlenaryWindowBorderBorderOptions
---@return table
function win_float.percentage_range_window(col_range, row_range, win_opts, border_opts)
win_opts = tbl.apply_defaults(win_opts, win_float.default_options)

Expand Down Expand Up @@ -195,6 +215,7 @@ function win_float.percentage_range_window(col_range, row_range, win_opts, borde
}
end

---@param bufnr integer
function win_float.clear(bufnr)
if _AssociatedBufs[bufnr] == nil then
return
Expand Down
5 changes: 5 additions & 0 deletions lua/plenary/window/init.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
---@class PlenaryWindow
local window = {}

---@param win_id integer
---@param force? boolean
window.try_close = function(win_id, force)
if force == nil then
force = true
Expand All @@ -8,6 +11,8 @@ window.try_close = function(win_id, force)
pcall(vim.api.nvim_win_close, win_id, force)
end

---@param parent_win_id integer
---@param child_win_id integer
window.close_related_win = function(parent_win_id, child_win_id)
window.try_close(parent_win_id, true)
window.try_close(child_win_id, true)
Expand Down

0 comments on commit 07e5613

Please sign in to comment.