Make `StatusView:add_item` accept a table

This commit is contained in:
Guldoman 2022-07-13 06:31:17 +02:00
parent 693bd11b22
commit 9cfa3ecd56
No known key found for this signature in database
GPG Key ID: EA928C8BDA1A8825
2 changed files with 121 additions and 104 deletions

View File

@ -168,17 +168,17 @@
```lua ```lua
------@return StatusView.Item ------@return StatusView.Item
function StatusView:add_item( function StatusView:add_item(
predicate, name, alignment, getitem, command, pos, tooltip { predicate, name, alignment, get_item, command, position, tooltip, separator }
) end ) end
``` ```
**Example:** **Example:**
```lua ```lua
core.status_view:add_item( core.status_view:add_item({
nil, predicate = nil,
"status:memory-usage", name = "status:memory-usage",
StatusView.Item.RIGHT, alignment = StatusView.Item.RIGHT,
function() get_item = function()
return { return {
style.text, style.text,
string.format( string.format(
@ -187,10 +187,11 @@
) )
} }
end, end,
nil, command = nil,
1, position = 1,
"lua memory usage" tooltip = "lua memory usage",
).separator = core.status_view.separator2 separator = core.status_view.separator2
})
``` ```
* [CommandView:enter](https://github.com/lite-xl/lite-xl/pull/1004) now accepts * [CommandView:enter](https://github.com/lite-xl/lite-xl/pull/1004) now accepts

View File

@ -47,7 +47,7 @@ StatusView.separator2 = " | "
---@alias core.statusview.item.predicate fun():boolean ---@alias core.statusview.item.predicate fun():boolean
---@alias core.statusview.item.onclick fun(button: string, x: number, y: number) ---@alias core.statusview.item.onclick fun(button: string, x: number, y: number)
---@alias core.statusview.item.getitem fun():core.statusview.styledtext,core.statusview.styledtext ---@alias core.statusview.item.get_item fun():core.statusview.styledtext,core.statusview.styledtext
---@alias core.statusview.item.ondraw fun(x, y, h, hovered: boolean, calc_only?: boolean):number ---@alias core.statusview.item.ondraw fun(x, y, h, hovered: boolean, calc_only?: boolean):number
---@class core.statusview.item : core.object ---@class core.statusview.item : core.object
@ -68,6 +68,44 @@ StatusView.separator2 = " | "
---@field private cached_item core.statusview.styledtext ---@field private cached_item core.statusview.styledtext
local StatusViewItem = Object:extend() local StatusViewItem = Object:extend()
---Available StatusViewItem options.
---@class core.statusview.item.options : table
---@field predicate string | table | core.statusview.item.predicate
---@field name string
---@field alignment core.statusview.item.alignment
---@field get_item core.statusview.item.get_item
---@field command? string | core.statusview.item.onclick
---@field position? integer
---@field tooltip? string
---@field separator? core.statusview.item.separator
local StatusViewItemOptions = {
---A condition to evaluate if the item should be displayed. If a string
---is given it is treated as a require import that should return a valid object
---which is checked against the current active view, the sames applies if a
---table is given. A function that returns a boolean can be used instead to
---perform a custom evaluation, setting to nil means always evaluates to true.
predicate = nil,
---A unique name to identify the item on the status bar.
name = nil,
alignment = nil,
---A function that should return a core.statusview.styledtext element,
---returning empty table is allowed.
get_item = nil,
---The name of a valid registered command or a callback function to execute
---when the item is clicked.
command = nil,
---The position in which to insert the given item on the internal table,
---a value of -1 inserts the item at the end which is the default. A value
---of 1 will insert the item at the beggining.
position = nil,
---Displayed when mouse hovers the item
tooltip = nil,
separator = nil,
}
StatusViewItem.options = StatusViewItemOptions
---Flag to tell the item should me aligned on left side of status bar. ---Flag to tell the item should me aligned on left side of status bar.
---@type number ---@type number
StatusViewItem.LEFT = 1 StatusViewItem.LEFT = 1
@ -81,26 +119,23 @@ StatusViewItem.RIGHT = 2
---| 'core.statusview.item.RIGHT' ---| 'core.statusview.item.RIGHT'
---Constructor ---Constructor
---@param predicate string | table | core.statusview.item.predicate ---@param options core.statusview.item.options
---@param name string function StatusViewItem:new(options)
---@param alignment core.statusview.item.alignment self:set_predicate(options.predicate)
---@param command string | core.statusview.item.onclick self.name = options.name
---@param tooltip? string | nil self.alignment = options.alignment or StatusView.Item.LEFT
function StatusViewItem:new(predicate, name, alignment, command, tooltip) self.command = type(options.command) == "string" and options.command or nil
self:set_predicate(predicate) self.tooltip = options.tooltip or ""
self.name = name self.on_click = type(options.command) == "function" and options.command or nil
self.alignment = alignment or StatusView.Item.LEFT
self.command = type(command) == "string" and command or nil
self.tooltip = tooltip or ""
self.on_click = type(command) == "function" and command or nil
self.on_draw = nil self.on_draw = nil
self.background_color = nil self.background_color = nil
self.background_color_hover = nil self.background_color_hover = nil
self.visible = true self.visible = options.visible == nil and true or options.visible
self.active = false self.active = false
self.x = 0 self.x = 0
self.w = 0 self.w = 0
self.separator = StatusView.separator self.separator = options.separator or StatusView.separator
self.get_item = options.get_item
end end
---Called by the status bar each time that the item needs to be rendered, ---Called by the status bar each time that the item needs to be rendered,
@ -166,11 +201,11 @@ end
function StatusView:register_docview_items() function StatusView:register_docview_items()
if self:get_item("doc:file") then return end if self:get_item("doc:file") then return end
self:add_item( self:add_item({
predicate_docview, predicate = predicate_docview,
"doc:file", name = "doc:file",
StatusView.Item.LEFT, alignment = StatusView.Item.LEFT,
function() get_item = function()
local dv = core.active_view local dv = core.active_view
return { return {
dv.doc:is_dirty() and style.accent or style.text, style.icon_font, "f", dv.doc:is_dirty() and style.accent or style.text, style.icon_font, "f",
@ -178,13 +213,13 @@ function StatusView:register_docview_items()
dv.doc.filename and style.text or style.dim, dv.doc:get_name() dv.doc.filename and style.text or style.dim, dv.doc:get_name()
} }
end end
) })
self:add_item( self:add_item({
predicate_docview, predicate = predicate_docview,
"doc:position", name = "doc:position",
StatusView.Item.LEFT, alignment = StatusView.Item.LEFT,
function() get_item = function()
local dv = core.active_view local dv = core.active_view
local line, col = dv.doc:get_selection() local line, col = dv.doc:get_selection()
return { return {
@ -195,14 +230,15 @@ function StatusView:register_docview_items()
string.format("%.f%%", line / #dv.doc.lines * 100) string.format("%.f%%", line / #dv.doc.lines * 100)
} }
end, end,
"doc:go-to-line" command = "doc:go-to-line",
).tooltip = "line : column" tooltip = "line : column"
})
self:add_item( self:add_item({
predicate_docview, predicate = predicate_docview,
"doc:indentation", name = "doc:indentation",
StatusView.Item.RIGHT, alignment = StatusView.Item.RIGHT,
function() get_item = function()
local dv = core.active_view local dv = core.active_view
local indent_type, indent_size, indent_confirmed = dv.doc:get_indent_info() local indent_type, indent_size, indent_confirmed = dv.doc:get_indent_info()
local indent_label = (indent_type == "hard") and "tabs: " or "spaces: " local indent_label = (indent_type == "hard") and "tabs: " or "spaces: "
@ -211,20 +247,21 @@ function StatusView:register_docview_items()
indent_confirmed and "" or "*" indent_confirmed and "" or "*"
} }
end, end,
function(button, x, y) command = function(button, x, y)
if button == "left" then if button == "left" then
command.perform "indent:set-file-indent-size" command.perform "indent:set-file-indent-size"
elseif button == "right" then elseif button == "right" then
command.perform "indent:set-file-indent-type" command.perform "indent:set-file-indent-type"
end end
end end,
).separator = self.separator2 separator = self.separator2
})
self:add_item( self:add_item({
predicate_docview, predicate = predicate_docview,
"doc:lines", name = "doc:lines",
StatusView.Item.RIGHT, alignment = StatusView.Item.RIGHT,
function() get_item = function()
local dv = core.active_view local dv = core.active_view
return { return {
style.text, style.text,
@ -232,21 +269,22 @@ function StatusView:register_docview_items()
style.font, style.dim, self.separator2, style.font, style.dim, self.separator2,
style.text, #dv.doc.lines, " lines", style.text, #dv.doc.lines, " lines",
} }
end end,
).separator = self.separator2 separator = self.separator2
})
self:add_item( self:add_item({
predicate_docview, predicate = predicate_docview,
"doc:line-ending", name = "doc:line-ending",
StatusView.Item.RIGHT, alignment = StatusView.Item.RIGHT,
function() get_item = function()
local dv = core.active_view local dv = core.active_view
return { return {
style.text, dv.doc.crlf and "CRLF" or "LF" style.text, dv.doc.crlf and "CRLF" or "LF"
} }
end, end,
"doc:toggle-line-ending" command = "doc:toggle-line-ending"
) })
end end
@ -254,11 +292,11 @@ end
function StatusView:register_command_items() function StatusView:register_command_items()
if self:get_item("command:files") then return end if self:get_item("command:files") then return end
self:add_item( self:add_item({
"core.commandview", predicate = "core.commandview",
"command:files", name = "command:files",
StatusView.Item.RIGHT, alignment = StatusView.Item.RIGHT,
function() get_item = function()
return { return {
style.icon_font, "g", style.icon_font, "g",
style.font, style.dim, self.separator2, style.font, style.dim, self.separator2,
@ -266,7 +304,7 @@ function StatusView:register_command_items()
#core.project_files, " files" #core.project_files, " files"
} }
end end
) })
end end
@ -303,33 +341,13 @@ end
---Adds an item to be rendered in the status bar. ---Adds an item to be rendered in the status bar.
---@param predicate string | table | core.statusview.item.predicate : ---@param options core.statusview.item.options
---A condition to evaluate if the item should be displayed. If a string
---is given it is treated as a require import that should return a valid object
---which is checked against the current active view, the sames applies if a
---table is given. A function that returns a boolean can be used instead to
---perform a custom evaluation, setting to nil means always evaluates to true.
---@param name string A unique name to identify the item on the status bar.
---@param alignment core.statusview.item.alignment
---@param getitem core.statusview.item.getitem :
---A function that should return a core.statusview.styledtext element,
---returning empty table is allowed.
---@param command? string | core.statusview.item.onclick :
---The name of a valid registered command or a callback function to execute
---when the item is clicked.
---@param pos? integer :
---The position in which to insert the given item on the internal table,
---a value of -1 inserts the item at the end which is the default. A value
---of 1 will insert the item at the beggining.
---@param tooltip? string Displayed when mouse hovers the item
---@return core.statusview.item ---@return core.statusview.item
function StatusView:add_item(predicate, name, alignment, getitem, command, pos, tooltip) function StatusView:add_item(options)
assert(self:get_item(name) == nil, "status item already exists: " .. name) assert(self:get_item(options.name) == nil, "status item already exists: " .. options.name)
---@type core.statusview.item ---@type core.statusview.item
local item = StatusView.Item(predicate, name, alignment, command, tooltip) local item = StatusView.Item(options)
item.get_item = getitem table.insert(self.items, normalize_position(self, options.position or -1, options.alignment), item)
pos = type(pos) == "nil" and -1 or tonumber(pos)
table.insert(self.items, normalize_position(self, pos, alignment), item)
return item return item
end end
@ -647,19 +665,17 @@ local function merge_deprecated_items(destination, items, alignment)
local position = alignment == StatusView.Item.LEFT and "left" or "right" local position = alignment == StatusView.Item.LEFT and "left" or "right"
local item_start = StatusView.Item( local item_start = StatusView.Item({
nil, name = "deprecated:"..position.."-start",
"deprecated:"..position.."-start", alignment = alignment,
alignment get_item = items_start
) })
item_start.get_item = items_start
local item_end = StatusView.Item( local item_end = StatusView.Item({
nil, name = "deprecated:"..position.."-end",
"deprecated:"..position.."-end", alignment = alignment,
alignment get_item = items_end
) })
item_end.get_item = items_end
table.insert(destination, 1, item_start) table.insert(destination, 1, item_start)
table.insert(destination, item_end) table.insert(destination, item_end)
@ -674,7 +690,7 @@ end
---@return core.statusview.item ---@return core.statusview.item
local function add_spacing(self, destination, separator, alignment, x) local function add_spacing(self, destination, separator, alignment, x)
---@type core.statusview.item ---@type core.statusview.item
local space = StatusView.Item(nil, "space", alignment) local space = StatusView.Item({name = "space", alignment = alignment})
space.cached_item = separator == self.separator and { space.cached_item = separator == self.separator and {
style.text, separator style.text, separator
} or { } or {