copied profile

This commit is contained in:
Peter Wood
2025-04-08 15:31:34 -04:00
parent 59ea35edc7
commit 6c72ecbd48
106 changed files with 9515 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
---@module "utils.class.config"
---@author sravioli
---@license GNU-GPLv3
---locals are faster
-- local type, pcall, pairs, setmetatable = type, pcall, pairs, setmetatable
local wt = require "wezterm"
---@class Utils.Class.Config
local M = {}
---@package
---
---Class logger
M.log = require("utils.class.logger"):new "Config"
---Initializes a new Config object.
---Creates a new Wezterm configuration object. If `wezterm.config_builder()` is available,
---it will use the config builder and set the configuration to strict mode.
---
---@return Utils.Class.Config self new instance of the Wezterm configuration.
function M:new()
self.config = {}
if wt.config_builder then ---@diagnostic disable-line: undefined-field
self.config = wt.config_builder() ---@diagnostic disable-line: undefined-field
self.config:set_strict_mode(true)
M.log:debug "Wezterm's config builder is available"
else
M.log:warn "Wezterm's config builder is unavailable"
end
self = setmetatable(self.config, { __index = M })
return self
end
---Adds a module to the Wezterm configuration.
---This function allows you to extend the Wezterm configuration by adding new options
---from a specified module. If a string is provided, it requires the module and merges
---its options. If a table is provided, it merges the table directly into the configuration.
---
---**Example usage**
---
---~~~lua
---local Config = require "config"
---return Config:new():add(require "<module.name>")
---~~~
---
---@param spec string|table lua `require()` path to config table or config table
---@return Utils.Class.Config # Modified Config object with the new options.
function M:add(spec)
if type(spec) == "string" then
if not (pcall(require, spec)) then
M.log:error("Unable to require module %s", spec)
return self
end
spec = require(spec)
end
for key, value in pairs(spec) do
if self.config[key] == spec[key] then
M.log:warn("found duplicate! old: %s, new: %s", self.config[key], spec[key])
end
self.config[key] = value
end
return self.config
end
return M

View File

@@ -0,0 +1,258 @@
---@module "utils.class.icon"
---@author sravioli
---@license GNU-GPLv3
---@diagnostic disable-next-line: undefined-field
local nf = require("wezterm").nerdfonts
-- {{{1 META
--~ {{{2 Icons.Sep
---Tabs bar separators
---@class Utils.Class.Icons.Sep.tb
---@field leftmost string `▐`
---@field left string ``
---@field right string ``
---
---Status-bar separators
---@class Utils.Class.Icons.Sep.sb
---@field left string ``
---@field right string ``
---@field modal string ``
---
---Separators
---@class Utils.Class.Icons.Sep
---@field sb Utils.Class.Icons.Sep.sb
---@field tb Utils.Class.Icons.Sep.tb
---@field block string `█`
--~ }}}
--~ {{{2 Icons.Bat
---Icons for a full battery
---@class Utils.Class.Icons.Bat.Full
---@field ["100"] string `󰁹`
---
---Icons for a charging battery
---@class Utils.Class.Icons.Bat.Charging
---@field ["00"] string `󰂃`
---@field ["10"] string `󰢜
---@field ["20"] string `󰂆
---@field ["30"] string `󰂇
---@field ["40"] string `󰂈
---@field ["50"] string `󰢝
---@field ["60"] string `󰂉
---@field ["70"] string `󰢞
---@field ["80"] string `󰂊
---@field ["90"] string `󰂋
---@field ["100"] string `󰂅`
---
---Icons for a discharging battery
---@class Utils.Class.Icons.Bat.Discharging
---@field ["00"] string `󰂎`
---@field ["10"] string `󰁺`
---@field ["20"] string `󰁻`
---@field ["30"] string `󰁼`
---@field ["40"] string `󰁽`
---@field ["50"] string `󰁾`
---@field ["60"] string `󰁿`
---@field ["70"] string `󰂀`
---@field ["80"] string `󰂁`
---@field ["90"] string `󰂂`
---@field ["100"] string `󰁹`
---
---Collection of battery icons
---@class Utils.Class.Icons.Bat
---@field Full Utils.Class.Icons.Bat.Full
---@field Charging Utils.Class.Icons.Bat.Charging
---@field Discharging Utils.Class.Icons.Bat.Discharging
--~ }}}
--~ {{{2 Icons.Nums
---{ 󰬺, 󰬻, 󰬼, 󰬽, 󰬾, 󰬿, 󰭀, 󰭁, 󰭂, 󰿩 }
---@class Utils.Class.Icons.Nums: string[]
--~ }}}
--~ {{{2 Icons.Progs
---Indexed list of programs names and their respective icons
---@class Utils.Class.Icons.Progs: table<string: string>
--~ }}}
--~ {{{2 Icons.Clock
---Indexed list of clock icons
---@class Utils.Class.Icons.Clock: table<string: string>
---@field ["00"] string `󱑊`
---@field ["01"] string `󱐿`
---@field ["02"] string `󱑀`
---@field ["03"] string `󱑁`
---@field ["04"] string `󱑂`
---@field ["05"] string `󱑃`
---@field ["06"] string `󱑄`
---@field ["07"] string `󱑅`
---@field ["08"] string `󱑆`
---@field ["09"] string `󱑇`
---@field ["10"] string `󱑈`
---@field ["11"] string `󱑉`
---@field ["12"] string `󱑊`
--~ }}}
--~ {{{2 Utils.Class.Icons
---@class Utils.Class.Icons
---@field Sep Utils.Class.Icons.Sep
---@field Bat Utils.Class.Icons.Bat
---@field Nums Utils.Class.Icons.Nums
---@field Progs Utils.Class.Icons.Progs
---@field Clock Utils.Class.Icons.Clock
---@field Folder string `󰉋`
---@field Workspace string `󰒘`
---@field Hostname string `󱄄`
---@field Notification string ``
--~ }}}
-- }}}
---@class Utils.Class.Icons
local M = {}
M.Notification = nf.cod_circle_small_filled
M.Workspace = nf.md_shield
M.Folder = nf.md_folder
M.Hostname = nf.md_monitor_shimmer
M.Sep = {
block = "",
sb = {
left = nf.pl_left_hard_divider,
right = nf.pl_right_hard_divider,
modal = nf.ple_forwardslash_separator,
},
ws = {
right = nf.ple_right_half_circle_thick,
left = nf.ple_left_half_circle_thick,
},
tb = {
leftmost = "",
left = nf.ple_upper_right_triangle,
right = nf.ple_lower_left_triangle,
},
}
M.Bat = {
Full = {
["100"] = nf.md_battery,
},
Charging = {
["00"] = nf.md_battery_alert,
["10"] = nf.md_battery_charging_10,
["20"] = nf.md_battery_charging_20,
["30"] = nf.md_battery_charging_30,
["40"] = nf.md_battery_charging_40,
["50"] = nf.md_battery_charging_50,
["60"] = nf.md_battery_charging_60,
["70"] = nf.md_battery_charging_70,
["80"] = nf.md_battery_charging_80,
["90"] = nf.md_battery_charging_90,
["100"] = nf.md_battery_charging_100,
},
Discharging = {
["00"] = nf.md_battery_outline,
["10"] = nf.md_battery_10,
["20"] = nf.md_battery_20,
["30"] = nf.md_battery_30,
["40"] = nf.md_battery_40,
["50"] = nf.md_battery_50,
["60"] = nf.md_battery_60,
["70"] = nf.md_battery_70,
["80"] = nf.md_battery_80,
["90"] = nf.md_battery_90,
["100"] = nf.md_battery,
},
}
M.Nums = {
nf.md_numeric_1,
nf.md_numeric_2,
nf.md_numeric_3,
nf.md_numeric_4,
nf.md_numeric_5,
nf.md_numeric_6,
nf.md_numeric_7,
nf.md_numeric_8,
nf.md_numeric_9,
nf.md_numeric_10,
}
M.Clock = {
["00"] = nf.md_clock_time_twelve,
["01"] = nf.md_clock_time_one,
["02"] = nf.md_clock_time_two,
["03"] = nf.md_clock_time_three,
["04"] = nf.md_clock_time_four,
["05"] = nf.md_clock_time_five,
["06"] = nf.md_clock_time_six,
["07"] = nf.md_clock_time_seven,
["08"] = nf.md_clock_time_eight,
["09"] = nf.md_clock_time_nine,
["10"] = nf.md_clock_time_ten,
["11"] = nf.md_clock_time_eleven,
["12"] = nf.md_clock_time_twelve,
}
M.Progs = {
["bash"] = nf.cod_terminal_bash,
["btm"] = nf.md_chart_donut_variant,
["btop"] = nf.md_chart_areaspline,
["C:\\WINDOWS\\system32\\cmd.exe"] = nf.md_console_line,
["cargo"] = nf.dev_rust,
["curl"] = nf.mdi_flattr,
["docker-compose"] = nf.linux_docker,
["docker"] = nf.linux_docker,
["fish"] = nf.md_fish,
["gh"] = nf.dev_github_badge,
["git"] = nf.dev_git,
["go"] = nf.seti_go,
["htop"] = nf.md_chart_areaspline,
["kubectl"] = nf.linux_docker,
["kuberlr"] = nf.linux_docker,
["lazydocker"] = nf.linux_docker,
["lazygit"] = nf.cod_github,
["lua"] = nf.seti_lua,
["make"] = nf.seti_makefile,
["node"] = nf.md_nodejs,
["nvim"] = nf.custom_neovim,
["pacman"] = "󰮯 ",
["paru"] = "󰮯 ",
["perl"] = nf.seti_perl,
["psql"] = nf.dev_postgresql,
["pwsh"] = nf.md_console,
["pwsh.exe"] = nf.md_console,
["python"] = nf.seti_python,
["ruby"] = nf.cod_ruby,
["sudo"] = nf.fa_hashtag,
["Topgrade"] = nf.md_rocket_launch,
["vim"] = nf.dev_vim,
["wget"] = nf.mdi_arrow_down_box,
["zsh"] = nf.dev_terminal,
["Yazi"] = nf.md_duck,
}
return M
-- vim: fdm=marker fdl=1

View File

@@ -0,0 +1,17 @@
---@class Utils.Class
---@field config Utils.Class.Config
---@field icon Utils.Class.Icons
---@field layout Utils.Class.Layout
---@field logger Utils.Class.Logger
---@field picker Utils.Class.Picker
local M = {}
local mod = ...
setmetatable(M, {
__index = function(t, k)
t[k] = require(mod .. "." .. k)
return t[k]
end,
})
return M

View File

@@ -0,0 +1,144 @@
---@module "utils.class.layout"
---@author sravioli
---@license GNU-GPLv3.0
local Logger = require "utils.class.logger"
local wt = require "wezterm"
-- selene: allow(incorrect_standard_library_use)
local tinsert, tunpack = table.insert, unpack or table.unpack
local attribute_mappings = {
None = "ResetAttributes",
NoUnderline = { Underline = "None" },
Single = { Underline = "Single" },
Double = { Underline = "Double" },
Curly = { Underline = "Curly" },
Dotted = { Underline = "Dotted" },
Dashed = { Underline = "Dashed" },
Normal = { Intensity = "Normal" },
Bold = { Intensity = "Bold" },
Half = { Intensity = "Half" },
Italic = { Italic = true },
NoItalic = { Italic = false },
}
-- stylua: ignore
local ansi_colors = {
Black = true, Maroon = true, Green = true, Olive = true, Navy = true, Purple = true,
Teal = true, Silver = true, Grey = true, Red = true, Lime = true, Yellow = true,
Blue = true, Fuchsia = true, Aqua = true, White = true,
}
---The `Layout` class was created to address the need for a more straightforward and organized
---way to build formatted text layouts in Wezterm. Wezterm's
---[`FormatItem`](https://wezfurlong.org/wezterm/config/lua/wezterm/format.html) objects
---can be cumbersome to handle directly, especially when dealing with multiple attributes
---and text segments. The `Layout` class encapsulates this complexity, providing a clear
---and concise API to manage these objects.
---
---@class Utils.Class.Layout
---@field private layout table
---@field private log table
---@field private name string
local M = {}
---Creates a new class instance.
---
---@param name? string name of the layout. Used for logging purposes.
---@return Utils.Class.Layout layout newly created class instance.
function M:new(name)
name = "Layout" .. (name and " > " .. name or "")
return setmetatable(
{ layout = {}, log = Logger:new(name), name = name },
{ __index = self }
)
end
---Inserts the given element in the Layout.
---
---Inserts the text element with the specified background and foreground colors, as well as
---optional attributes such as: underline style, text intensity, etc.
---
---Supports all the attributes that Wezterm's
---[`FormatItem`](https://wezfurlong.org/wezterm/config/lua/wezterm/format.html) object
---defines, and supports color definitions similarly.
---
---@param action "append"|"prepend" action type
---@param background string background color of the element.
---@param foreground string foreground color of the element.
---@param text string text to be added.
---@param attributes? table attributes to style the text.
---@return Utils.Class.Layout self updated layout instance.
function M:insert(action, background, foreground, text, attributes)
if not action or action == "" then
return self.log:error "Cannot operate with empty action"
end
local idx = function()
return action == "prepend" and 1 or #self + 1
end
local colors_pair = { { "Background", background }, { "Foreground", foreground } }
for i = 1, #colors_pair do
local attr, color = tunpack(colors_pair[i])
local color_entry = ansi_colors[color] and { [attr] = { AnsiColor = color } }
or { [attr] = { Color = color } }
tinsert(self, idx(), color_entry)
end
if attributes then
for i = 1, #attributes do
local attribute = attributes[i]
if not attribute_mappings[attribute] then
return self.log:error("attribute '%s' is not defined!", attribute)
end
tinsert(self, idx(), { Attribute = attribute_mappings[attribute] })
end
end
tinsert(self, idx(), { Text = text })
return self
end
---Append the given element in the Layout.
---@see Utils.Class.Layout.insert
function M:append(background, foreground, text, attributes)
return M.insert(self, "append", background, foreground, text, attributes)
end
---Prepend the given element in the Layout.
---@see Utils.Class.Layout.insert
function M:prepend(background, foreground, text, attributes)
return M.insert(self, "prepend", foreground, background, text, attributes)
end
---Clears all elements from the layout.
---
---@return Utils.Class.Layout self The cleared layout instance.
function M:clear()
self.log:debug("clearing layout %s", self.name)
self.layout = {}
return self
end
---Formats the Layout object
---
---@return string format The resulting string formatted by `wezterm.format()`
function M:format()
self.log:debug("formatting layout %s", self.name)
---@diagnostic disable-next-line: undefined-field
return wt.format(self)
end
---Logs the unformatted layout to wezterm's debug console
---@param formatted boolean whether to log the formatted layout or not
function M:debug(formatted)
self.log:info(formatted and self:format() or self)
end
return M

View File

@@ -0,0 +1,147 @@
---@module "utils.class.logger"
---@author sravioli
---@license GNU-GPLv3
local wt = require "wezterm"
---@diagnostic disable-next-line: undefined-field
local G, log_info, log_warn, log_error = wt.GLOBAL, wt.log_info, wt.log_warn, wt.log_error
-- selene: allow(incorrect_standard_library_use)
local unpack = unpack or table.unpack
local inspect = require("utils.external.inspect").inspect
local levels = { DEBUG = 0, INFO = 1, WARN = 2, ERROR = 3 }
-- {{{1 Helpers
local h = {}
---Converts each given vararg to a string
---@param ... any
---@return ... string
h.stringify = function(...)
local args = { ... }
for i = 1, #args do
if type(args[i]) == "userdata" then
args[i] = tostring(args[i])
else
args[i] = inspect(args[i])
end
end
return unpack(args)
end
---Returns the appropriate log level
---@param level string|integer
---@return integer level log level converted to integer
h.get_level = function(level)
if type(level) == "string" then
level = levels[level:upper()]
end
return level
end
-- }}}
---@class Utils.Class.Logger
---@field identifier string
---@field enabled boolean
---@field log_level integer
local M = {}
M.__index = M
---Creates a new class instance
---
---Whether logging is enabled is globally controlled by the `wezterm.GLOBAL.enable_logging`
---variable. Setting it to `false` (either from the Debug overlay or from the configuration),
---will disable logging; the opposite happens when it is set to `true`.
---
---@param identifier? string indentifier that will be printed in brackets before the msg
---@param enabled? boolean whether to enable logging or not. defaults to true at warn lvl
---@return Utils.Class.Logger
function M:new(identifier, enabled)
return setmetatable({
identifier = identifier or "Logger",
enabled = G.enable_logging or enabled or true,
log_level = h.get_level(G.log_level or levels.WARN),
}, self)
end
---Logs a message with the specified log level
---
---Logs the given string to the Wezterm's debug overlay. The message can be either a
---simple string or a format string. The latter must only use `%s` placeholders since the
---function already takes care of stringifing any non-string value.
---
---@param level integer|string log level
---@param message string log message or format string
---@param ... any additional arguments to format into the message
function M:log(level, message, ...)
if not (G.enable_logging and self.enabled) then
return
end
if h.get_level(level) < self.log_level then
return
end
local msg = ("[%s] %s"):format(self.identifier, message:format(h.stringify(...)))
if (level == levels.DEBUG) or (level == levels.INFO) then
log_info(msg)
elseif level == levels.WARN then
log_warn(msg)
elseif level == levels.ERROR then
log_error(msg)
else
self:error("invalid log level: %s", level)
end
end
---Logs a debug level message to the Wezterm's debug overlay.
---
---Logs the given string to the Wezterm's debug overlay. The message can be either a
---simple string or a format string. The latter must only use `%s` placeholders since the
---function already takes care of stringifing any non-string value.
---
---@param message string log message or format string
---@param ... any additional arguments to format into the message
function M:debug(message, ...)
self:log(levels.DEBUG, "DEBUG: " .. message, ...)
end
---Logs a info level message to the Wezterm's debug overlay.
---
---Logs the given string to the Wezterm's debug overlay. The message can be either a
---simple string or a format string. The latter must only use `%s` placeholders since the
---function already takes care of stringifing any non-string value.
---
---@param message string log message or format string
---@param ... any additional arguments to format into the message
function M:info(message, ...)
self:log(levels.INFO, message, ...)
end
---Logs a warn level message to the Wezterm's debug overlay.
---
---Logs the given string to the Wezterm's debug overlay. The message can be either a
---simple string or a format string. The latter must only use `%s` placeholders since the
---function already takes care of stringifing any non-string value.
---
---@param message string log message or format string
---@param ... any additional arguments to format into the message
function M:warn(message, ...)
self:log(levels.WARN, message, ...)
end
---Logs an error level message to the Wezterm's debug overlay.
---
---Logs the given string to the Wezterm's debug overlay. The message can be either a
---simple string or a format string. The latter must only use `%s` placeholders since the
---function already takes care of stringifing any non-string value.
---
---@param message string log message or format string
---@param ... any additional arguments to format into the message
function M:error(message, ...)
self:log(levels.ERROR, message, ...)
end
return M

View File

@@ -0,0 +1,266 @@
---@module "utils.class.picker"
---@author sravioli
---@license GNU-GPLv3
---@diagnostic disable: undefined-field
local Utils = require "utils"
local fs, Logger = Utils.fn.fs, Utils.class.logger
local wt = require "wezterm"
local config_dir = wt.config_dir
-- {{{1 Meta
--~ {{{2 wt.Window
---@class wt.Window
---@field active_key_table function
---@field active_pane function
---@field active_tab function
---@field active_workspace function
---@field composition_status function
---@field copy_to_clipboard function
---@field current_event function
---@field effective_config function
---@field focus function
---@field get_appearance function
---@field get_config_overrides function
---@field get_dimensions function
---@field get_selection_escapes_for_pane function
---@field get_selection_text_for_pane function
---@field is_focused function
---@field keyboard_modifiers function
---@field leader_is_active function
---@field maximize function
---@field mux_window function
---@field perform_action function
---@field restore function
---@field set_config_overrides function
---@field set_inner_size function
---@field set_left_status function
---@field set_position function
---@field set_right_status function
---@field toast_notification function
---@field toggle_fullscreen function
---@field window_id function
--~ }}}
--~ {{{2 wt.Pane
---@class wt.Pane
---@field activate function
---@field get_current_working_dir function
---@field get_cursor_position function
---@field get_dimensions function
---@field get_domain_name function
---@field get_foreground_process_info function
---@field get_foreground_process_name function
---@field get_lines_as_escapes function
---@field get_lines_as_text function
---@field get_logical_lines_as_text function
---@field get_metadata function
---@field get_semantic_zone_at function
---@field get_semantic_zones function
---@field get_text_from_region function
---@field get_text_from_semantic_zone function
---@field get_title function
---@field get_tty_name function
---@field get_user_vars function
---@field has_unseen_output function
---@field inject_output function
---@field is_alt_screen_active function
---@field move_to_new_tab function
---@field move_to_new_window function
---@field mux_pane function
---@field pane_id function
---@field paste function
---@field send_paste function
---@field send_text function
---@field split function
---@field tab function
---@field window function
--~ }}}
--~ {{{2 Utils.Class.Picker
---@alias Module PickList
---@alias Choice { id: string, label: string|table }
---@alias Choice.private { module: Module, value: Choice }
---@class Utils.Class.Picker
---@field subdir string name of the picker module
---@field title string defaults to `"Pick a value"`
---@field choices? Choice[] defaults to `{}`
---@field __choices? Choice.private[] defaults to `{}`
---@field fuzzy? boolean defaults to `false`
---@field alphabet? string defaults to `"1234567890abcdefghilmnopqrstuvwxyz"`
---@field description? string defaults to `"Select an item."`
---@field fuzzy_description? string defaults to `"Fuzzy matching: "`
---@field comp? fun(a, b): boolean function to sort choices
---@field build? fun(__choices: Choice.private[], comp: function, opts: { window: wt.Window, pane: wt.Pane }): Choice[]
---@field new? fun(opts: Utils.Class.Picker): Utils.Class.Picker
---@field private log? Utils.Class.Logger
--~ }}}
--~ {{{2 PickList.Opts
---@alias PickList.Opts { window: wt.Window, pane: wt.Pane, id: string|nil, label: string|nil }
---@alias PickList.getReturn string|{ id: string|nil, label: string|table|nil }
---@class PickList
---@field get fun(): PickList.getReturn
---@field activate fun(Config: table, opts: PickList.Opts): nil
--~ }}}
-- }}}
-- {{{1 Helper functions
local h = {}
---Normalize an item to the `choices` format
---@param item string|number
---@return table normalized_item
function h.normalize(item)
return type(item) == "table" and item or { id = item }
end
---Determines whether the given item is an array or not.
---@param item PickList.getReturn
---@return boolean result whether or not the item is an array
function h.is_array(item)
return type(item) == "table" and item[1] ~= nil
end
---Build the choices table
---@param items table
---@param comp? fun(a, b): boolean
---@return Choice[] choices
function h.build(items, comp)
local choices = {}
for _, item in pairs(items) do
choices[#choices + 1] = { id = item.value.id, label = item.value.label }
end
table.sort(choices, comp or function(a, b)
return a.id < b.id
end)
return choices
end
---Converts a file path to a lua require path
---@param path string
---@return string require_path
function h.path_to_module(path)
return (path:sub(#config_dir + 2):gsub("%.lua$", ""):gsub(fs.path_separator, "."))
end
-- }}}
---@class Utils.Class.Picker
local M = {}
---Creates a new picker object
---@param opts Utils.Class.Picker
---@return Utils.Class.Picker Picker
function M.new(opts)
local self = setmetatable({}, { __index = M })
self.title = opts.title or "Pick a value"
self.choices = {}
self.__choices = {}
self.log = Logger:new("Picker > " .. self.title)
self.comp = opts.comp
self.build = opts.build or h.build
self.fuzzy = opts.fuzzy or false
self.alphabet = opts.alphabet or "1234567890abcdefghilmnopqrstuvwxyz"
self.description = opts.description or "Select an item."
self.fuzzy_description = opts.fuzzy_description or "Fuzzy matching: "
local dir = fs.pathconcat(config_dir, "picker", "assets", opts.subdir)
local paths = fs.ls_dir(dir)
if not paths then
self.log:error("Cannot read files from %s", dir)
return {}
end
for i = 1, #paths do
self:register(h.path_to_module(paths[i]))
end
return self
end
---Registers the module by requiring it and filling the `__choices` table
---@param name string the lua require path to the module
function M:register(name)
---@class PickList
local module = require(name)
local result = module.get()
if h.is_array(result) then
for i = 1, #result do
local item = h.normalize(result[i])
self.__choices[item.id] =
{ module = module, value = { id = item.id, label = item.label } }
self.log:debug("registered item: %s", self.__choices[item.id])
end
else
---@cast result string
result = h.normalize(result)
self.__choices[result.id] =
{ module = module, value = { id = result.id, label = result.label } }
self.log:debug("registered item: %s", self.__choices[result.id])
end
end
---Activates the selected module
---@param Overrides table config overrides
---@param opts PickList.Opts
---@return nil
function M:select(Overrides, opts)
local choice = self.__choices[opts.id]
if not choice then
return self.log:error("%s is not defined for %s", opts.id, self.title)
end
choice.module.activate(Overrides, opts)
end
---Invoke the picker.
---@return nil
function M:pick()
return wt.action_callback(function(window, pane)
local opts = { window = window, pane = pane }
window:perform_action(
wt.action.InputSelector {
action = wt.action_callback(function(inner_window, _, id, label)
if not id and not label then
self.log:error "cancelled by user"
else
local callback_opts = { window = window, pane = pane, id = id, label = label }
self.log:info("applying %s", id)
local Overrides = inner_window:get_config_overrides() or {}
self:select(Overrides, callback_opts)
window:set_config_overrides(Overrides)
end
end),
title = self.title,
choices = self.build(self.__choices, self.comp, opts),
fuzzy = self.fuzzy,
description = self.description,
fuzzy_description = self.fuzzy_description,
alphabet = self.alphabet,
},
pane
)
end)
end
return M

View File

@@ -0,0 +1,24 @@
local a;if(tonumber(_VERSION or(""):match"[%d.]*$")or 0)<5.3 then local b,c=pcall(require,"compat53.module")if b then a=c end end;local math=a and a.math or math;local string=a and a.string or string;local table=a and a.table or table;local inspect={Options={}}inspect._VERSION="inspect.lua 3.1.0"inspect._URL="http://github.com/kikito/inspect.lua"inspect._DESCRIPTION="human-readable representations of tables"inspect._LICENSE=[[
MIT LICENSE
Copyright (c) 2022 Enrique García Cota
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]inspect.KEY=setmetatable({},{__tostring=function()return"inspect.KEY"end})inspect.METATABLE=setmetatable({},{__tostring=function()return"inspect.METATABLE"end})local tostring=tostring;local e=string.rep;local f=string.match;local g=string.char;local h=string.gsub;local i=string.format;local j;if rawget then j=rawget else j=function(k,l)return k[l]end end;local function m(k)return next,k,nil end;local function n(o)if f(o,'"')and not f(o,"'")then return"'"..o.."'"end;return'"'..h(o,'"','\\"')..'"'end;local p={["\a"]="\\a",["\b"]="\\b",["\f"]="\\f",["\n"]="\\n",["\r"]="\\r",["\t"]="\\t",["\v"]="\\v",["\127"]="\\127"}local q={["\127"]="\127"}for r=0,31 do local s=g(r)if not p[s]then p[s]="\\"..r;q[s]=i("\\%03d",r)end end;local function t(o)return h(h(h(o,"\\","\\\\"),"(%c)%f[0-9]",q),"%c",p)end;local u={["and"]=true,["break"]=true,["do"]=true,["else"]=true,["elseif"]=true,["end"]=true,["false"]=true,["for"]=true,["function"]=true,["goto"]=true,["if"]=true,["in"]=true,["local"]=true,["nil"]=true,["not"]=true,["or"]=true,["repeat"]=true,["return"]=true,["then"]=true,["true"]=true,["until"]=true,["while"]=true}local function v(o)return type(o)=="string"and not not o:match"^[_%a][_%a%d]*$"and not u[o]end;local w=math.floor;local function x(l,y)return type(l)=="number"and w(l)==l and 1<=l and l<=y end;local z={["number"]=1,["boolean"]=2,["string"]=3,["table"]=4,["function"]=5,["userdata"]=6,["thread"]=7}local function A(B,C)local D,E=type(B),type(C)if D==E and(D=="string"or D=="number")then return B<C end;local F=z[D]or 100;local G=z[E]or 100;return F==G and D<E or F<G end;local function H(k)local I=1;while j(k,I)~=nil do I=I+1 end;I=I-1;local J,K={},0;for l in m(k)do if not x(l,I)then K=K+1;J[K]=l end end;table.sort(J,A)return J,K,I end;local function L(M,N)if type(M)=="table"then if N[M]then N[M]=N[M]+1 else N[M]=1;for l,O in m(M)do L(l,N)L(O,N)end;L(getmetatable(M),N)end end end;local function P(Q,B,C)local R={}local S=#Q;for r=1,S do R[r]=Q[r]end;R[S+1]=B;R[S+2]=C;return R end;local function T(U,V,Q,W)if V==nil then return nil end;if W[V]then return W[V]end;local X=U(V,Q)if type(X)=="table"then local Y={}W[V]=Y;local Z;for l,O in m(X)do Z=T(U,l,P(Q,l,inspect.KEY),W)if Z~=nil then Y[Z]=T(U,O,P(Q,Z),W)end end;local _=T(U,getmetatable(X),P(Q,inspect.METATABLE),W)if type(_)~="table"then _=nil end;setmetatable(Y,_)X=Y end;return X end;local function a0(a1,o)a1.n=a1.n+1;a1[a1.n]=o end;local a2={}local a3={__index=a2}local function a4(a5)a0(a5.buf,a5.newline..e(a5.indent,a5.level))end;function a2:getId(O)local a6=self.ids[O]local a7=self.ids;if not a6 then local a8=type(O)a6=(a7[a8]or 0)+1;a7[O],a7[a8]=a6,a6 end;return tostring(a6)end;function a2:putValue(O)local a1=self.buf;local a8=type(O)if a8=="string"then a0(a1,n(t(O)))elseif a8=="number"or a8=="boolean"or a8=="nil"or a8=="cdata"or a8=="ctype"then a0(a1,tostring(O))elseif a8=="table"and not self.ids[O]then local k=O;if k==inspect.KEY or k==inspect.METATABLE then a0(a1,tostring(k))elseif self.level>=self.depth then a0(a1,"{...}")else if self.cycles[k]>1 then a0(a1,i("<%d>",self:getId(k)))end;local J,K,I=H(k)a0(a1,"{")self.level=self.level+1;for r=1,I+K do if r>1 then a0(a1,",")end;if r<=I then a0(a1," ")self:putValue(k[r])else local l=J[r-I]a4(self)if v(l)then a0(a1,l)else a0(a1,"[")self:putValue(l)a0(a1,"]")end;a0(a1," = ")self:putValue(k[l])end end;local _=getmetatable(k)if type(_)=="table"then if I+K>0 then a0(a1,",")end;a4(self)a0(a1,"<metatable> = ")self:putValue(_)end;self.level=self.level-1;if K>0 or type(_)=="table"then a4(self)elseif I>0 then a0(a1," ")end;a0(a1,"}")end else a0(a1,i("<%s %d>",a8,self:getId(O)))end end;function inspect.inspect(a9,aa)aa=aa or{}local ab=aa.depth or math.huge;local ac=aa.newline or"\n"local ad=aa.indent or" "local U=aa.process;if U then a9=T(U,a9,{},{})end;local N={}L(a9,N)local a5=setmetatable({buf={n=0},ids={},cycles=N,depth=ab,level=0,newline=ac,indent=ad},a3)a5:putValue(a9)return table.concat(a5.buf)end;setmetatable(inspect,{__call=function(ae,a9,aa)return inspect.inspect(a9,aa)end})return inspect

1184
wezterm/.config/utils/fn.lua Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,142 @@
---@module "utils.gpu"
---@author sravioli
---@license GNU-GPLv3
local wt = require "wezterm"
local platform = require("utils.fn").fs.platform() --[[@class Utils.Fn.FileSystem.Platform]]
---see: https://github.com/KevinSilvester/wezterm-config
---@alias WeztermGPUBackend 'Vulkan'|'Metal'|'Gl'|'Dx12'
---@alias WeztermGPUDeviceType 'DiscreteGpu'|'IntegratedGpu'|'Cpu'|'Other'
---@class WeztermGPUAdapter
---@field name string
---@field backend WeztermGPUBackend
---@field device number
---@field device_type WeztermGPUDeviceType
---@field driver? string
---@field driver_info? string
---@field vendor string
---@alias AdapterMap { [WeztermGPUBackend]: WeztermGPUAdapter|nil }|nil
---@class GpuAdapters
---@field __backends WeztermGPUBackend[]
---@field __preferred_backend WeztermGPUBackend
---@field __preferred_device_type WeztermGPUDeviceType
---@field DiscreteGpu AdapterMap
---@field IntegratedGpu AdapterMap
---@field Cpu AdapterMap
---@field Other AdapterMap
local GpuAdapters = {}
GpuAdapters.__index = GpuAdapters
---See `https://github.com/gfx-rs/wgpu#supported-platforms` for more info on available backends
GpuAdapters.AVAILABLE_BACKENDS = {
windows = { "Dx12", "Vulkan", "Gl" },
linux = { "Vulkan", "Gl" },
mac = { "Metal" },
}
---@type WeztermGPUAdapter[]
GpuAdapters.ENUMERATED_GPUS = wt.gui.enumerate_gpus()
---@return GpuAdapters
---@private
function GpuAdapters:init()
local initial = {
__backends = self.AVAILABLE_BACKENDS[platform.os],
__preferred_backend = self.AVAILABLE_BACKENDS[platform.os][1],
DiscreteGpu = nil,
IntegratedGpu = nil,
Cpu = nil,
Other = nil,
}
-- iterate over the enumerated GPUs and create a lookup table (`AdapterMap`)
for _, adapter in ipairs(self.ENUMERATED_GPUS) do
if not initial[adapter.device_type] then
initial[adapter.device_type] = {}
end
initial[adapter.device_type][adapter.backend] = adapter
end
local gpu_adapters = setmetatable(initial, self)
return gpu_adapters
end
---Will pick the best adapter based on the following criteria:
--- 1. Best GPU available (Discrete > Integrated > Other (for wgpu's OpenGl
--- implementation on Discrete GPU) > Cpu)
--- 2. Best graphics API available
---
---Graphics API choices are based on the platform:
--- - Windows: Dx12 > Vulkan > OpenGl
--- - Linux: Vulkan > OpenGl
--- - Mac: Metal
---@see GpuAdapters.AVAILABLE_BACKENDS
---
---If the best adapter combo is not found, it will return `nil` and lets Wezterm decide
---the best adapter.
---
---Please note these are my own personal preferences and may not be the best for your system.
---If you want to manually choose the adapter, use `GpuAdapters:pick_manual(backend, device_type)`
---Or feel free to re-arrange `GpuAdapters.AVAILABLE_BACKENDS` to you liking
---@return WeztermGPUAdapter|nil
function GpuAdapters:pick_best()
local adapters_options = self.DiscreteGpu
if not adapters_options then
adapters_options = self.IntegratedGpu
end
if not adapters_options then
adapters_options = self.Other
end
if not adapters_options then
adapters_options = self.Cpu
end
if not adapters_options then
wt.log_error "No GPU adapters found. Using Default Adapter."
return nil
end
local adapter_choice = adapters_options[self.__preferred_backend]
if not adapter_choice then
wt.log_error "Preferred backend not available. Using Default Adapter."
return nil
end
return adapter_choice
end
---Manually pick the adapter based on the backend and device type.
---If the adapter is not found, it will return nil and lets Wezterm decide the best adapter.
---@param backend WeztermGPUBackend
---@param device_type WeztermGPUDeviceType
---@return WeztermGPUAdapter|nil
function GpuAdapters:pick_manual(backend, device_type)
local adapters_options = self[device_type]
if not adapters_options then
wt.log_error "No GPU adapters found. Using Default Adapter."
return nil
end
local adapter_choice = adapters_options[backend]
if not adapter_choice then
wt.log_error "Preferred backend not available. Using Default Adapter."
return nil
end
return adapter_choice
end
return GpuAdapters:init()

View File

@@ -0,0 +1,15 @@
---@class Utils
---@field class Utils.Class
---@field fn Utils.Fn
---@field gpu GpuAdapters
local M = {}
local mod = ...
setmetatable(M, {
__index = function(t, k)
t[k] = require(mod .. "." .. k)
return t[k]
end,
})
return M