Skip to content

Utils.Class.Picker

sravioli edited this page Oct 27, 2024 · 2 revisions

Overview

The Utils.Class.Picker module is a Lua class designed to facilitate the selection of items or actions in Wezterm. It provides a customizable interface for picking from a list of choices, with support for fuzzy matching, custom sorting, and integration with Wezterm's input selector.

Usage

local Picker = require "utils.class.picker"
local picker = Picker:new {
  title = "Select an Option",
  subdir = "my_subdir",
  fuzzy = true,
}

-- Invoking the picker
picker:pick()

Features

  • Customizable Choices: Allows defining a list of choices with custom labels and values.
  • Fuzzy Matching: Supports fuzzy matching for easy selection.
  • Sorting: Provides the ability to sort choices using custom comparator functions.
  • Integration with Wezterm: Integrates seamlessly with Wezterm's input selector and configuration system.
  • Logging: Includes logging capabilities for debugging and error tracking.

Class Structure

The Utils.Class.Picker class provides a structured way to manage and present a list of choices for user selection, leveraging Wezterm's capabilities.

Data Structures

The Utils.Class.Picker class uses several key data structures to manage choices and facilitate the selection process. Understanding these structures is crucial for effectively utilizing the picker.

Choice

A Choice represents an individual selectable item in the picker. Each choice consists of:

  • id [string] - unique identifier for the choice.
  • label [string|table] - display label for the choice, which can be a string or a table for complex labels.

Example:

local choice = { id = "choice1", label = "Choice 1" }

Choice.private

A Choice.private structure extends the basic Choice structure to include additional metadata for internal use:

  • module [PickList] - module associated with this choice.
  • value [Choice] - original Choice structure containing the id and label.

Example:

---how modules get registered
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

PickList

A PickList defines the interface that modules must implement to provide choices for the picker.

PickList.Opts

PickList.Opts is a table of options passed to the PickList.activate() function. It includes:

  • window [wt.Window] - Wezterm window instance.
  • pane [wt.Pane] - Wezterm pane instance.
  • id [string|nil] - identifier of the selected choice.
  • label [string|table|nil] - label of the selected choice.
PickList.getReturn

PickList.getReturn represents the return type of the PickList.get() function in a PickList. It can be either:

  • string - single choice identifier.
  • table - table containing:
    • id [string] - unique identifier for the choice.
    • label [string|table] - display label for the choice, which can be a string or a table for complex labels.
Methods
.get()

Retrieves the available choices.

Returns:

  • list [PickList.getReturn] - single or multiple available choice(s).

Example:

local PickList = {
  get = function()
    local sizes = {}
    for i = 8, 30 do
      sizes[#sizes + 1] = { label = ("%2dpt"):format(i), id = tostring(i) }
    end
    sizes[#sizes + 1] =
      { id = tostring(require("config.font").font_size), label = "Reset" }

    return sizes
  end,
}
.activate(Config, opts)

Parameters:

  • Config [table] - Wezterm's configuration overrides.
  • opts [PickList.Opts] - objects that could be useful for activation.

Example:

local PickList = {
  activate = function(Config, opts)
    Config.font_size = tonumber(opts.id)
  end,
}

Methods

:new(opts)

Creates a new Utils.Class.Picker instance.

Parameters:

  • opts [Utils.Class.Picker] - configuration options for the picker:
    • subdir [string] - name of the picker module subdirectory. The picker searches subdirectories in the ./picker/assets/ directory.
    • title [string] (optional) - title of the picker window. Default: "Pick a value"
    • build [function] (optional) exposes the internal private choices table to allow the user to dynamically modify it.
      • Parameters:
        • __choices [Choices.private] - internal choices table.
        • comp [fun(a, b): boolean] - comparator function to sort the choices table.
        • opts [table] - Wezterm's objects:
          • window [wt.Window] - Wezterm's window object.
          • pane [wt.Pane] - Wezterm's pane object.
      • Returns:
        • choices [Choice[]] - list of choices.
    • comp [function] - comparator function to sort choices:
      • Parameters:
        • a [Choice] - first choice
        • b [Choice] - second choice
      • Returns:
        • result [boolean] - result of the comparison between the two elements.
    • fuzzy [boolean] (optional) - whether to enable or disable fuzzy matching. Default: false.
    • alphabet [string] (optional) - Custom alphabet for input selection. Useful when fuzzy = false Default: "1234567890abcdefghilmnopqrstuvwxyz".
    • description [string] (optional) - description. Default: "Select an item.".
    • fuzzy_description [string] (optional) - description when fuzzy matching is enabled. Default: "Fuzzy matching: ".

Returns:

  • instance [Utils.Class.Picker] - new class instance.

Example:

local picker = Picker:new({
  subdir = "my_subdir",
  title = "Select an Option",
  fuzzy = true,
})

:register(name)

Registers a module by requiring it and filling the __choices table. This function is private.

Parameters:

  • name [string] - Lua require() path to the module.

:select(overrides, opts)

Activates the selected module. Acts as a wrapper to PickList.activate(). This function is private.

Parameters:

  • Overrides [table] - Wezterm's configuration overrides.
  • opts [PickList.Opts] - objects that could be useful for activation.

:pick()

Invokes the picker.

Example:

picker:pick()