/ wezterm / extensions / backdrops.lua
backdrops.lua
  1  local colors = require('colors.custom')
  2  local wezterm = require('wezterm')
  3  
  4  -- Seeding random numbers before generating for use
  5  -- Known issue with lua math library
  6  -- see: https://stackoverflow.com/questions/20154991/generating-uniform-random-numbers-in-lua
  7  math.randomseed(os.time())
  8  math.random()
  9  math.random()
 10  math.random()
 11  
 12  local PATH_SEP = '/'
 13  
 14  ---@class BackDrops
 15  ---@field current_idx number index of current image
 16  ---@field files string[] background images
 17  local BackDrops = {}
 18  BackDrops.__index = BackDrops
 19  
 20  --- Initialise backdrop controller
 21  ---@private
 22  function BackDrops:init()
 23    local initial = {
 24      current_idx = 1,
 25      files = {},
 26    }
 27    local backdrops = setmetatable(initial, self)
 28    wezterm.GLOBAL.background = nil
 29    return backdrops
 30  end
 31  
 32  ---MUST BE RUN BEFORE ALL OTHER `BackDrops` functions
 33  ---Sets the `files` after instantiating `BackDrops`.
 34  ---
 35  --- INFO:
 36  ---   During the initial load of the config, this function can only invoked in `wezterm.lua`.
 37  ---   WezTerm's fs utility `read_dir` (used in this function) works by running on a spawned child process.
 38  ---   This throws a coroutine error if the function is invoked in outside of `wezterm.lua` in the -
 39  ---   initial load of the Terminal config.
 40  function BackDrops:set_files()
 41    self.files = wezterm.read_dir(wezterm.config_dir .. PATH_SEP .. 'backdrops')
 42    wezterm.GLOBAL.background = self.files[1]
 43    return self
 44  end
 45  
 46  ---Override the current window options for background
 47  ---@private
 48  ---@param window any WezTerm Window see: https://wezfurlong.org/wezterm/config/lua/window/index.html
 49  function BackDrops:_set_opt(window)
 50    local opts = {
 51      background = {
 52        {
 53          source = { File = wezterm.GLOBAL.background },
 54          horizontal_align = 'Center',
 55        },
 56        {
 57          source = { Color = colors.background },
 58          height = '100%',
 59          width = '100%',
 60          opacity = 0.96,
 61        },
 62      },
 63    }
 64    window:set_config_overrides(opts)
 65  end
 66  
 67  ---Convert the `files` array to a table of `InputSelector` choices
 68  ---see: https://wezfurlong.org/wezterm/config/lua/keyassignment/InputSelector.html
 69  function BackDrops:choices()
 70    local choices = {}
 71    for idx, file in ipairs(self.files) do
 72      local name = file:match('([^' .. PATH_SEP .. ']+)$')
 73      table.insert(choices, {
 74        id = tostring(idx),
 75        label = name,
 76      })
 77    end
 78    return choices
 79  end
 80  
 81  ---Select a random file and redefine the global `wezterm.GLOBAL.background` variable
 82  ---Pass in `Window` object to override the current window options
 83  ---@param window any? WezTerm `Window` see: https://wezfurlong.org/wezterm/config/lua/window/index.html
 84  function BackDrops:random(window)
 85    self.current_idx = math.random(#self.files)
 86    wezterm.GLOBAL.background = self.files[self.current_idx]
 87  
 88    if window ~= nil then
 89      self:_set_opt(window)
 90    end
 91  end
 92  
 93  ---Cycle the loaded `files` and select the next background
 94  ---@param window any WezTerm `Window` see: https://wezfurlong.org/wezterm/config/lua/window/index.html
 95  function BackDrops:cycle_forward(window)
 96    if self.current_idx == #self.files then
 97      self.current_idx = 1
 98    else
 99      self.current_idx = self.current_idx + 1
100    end
101    wezterm.GLOBAL.background = self.files[self.current_idx]
102    self:_set_opt(window)
103  end
104  
105  ---Cycle the loaded `files` and select the previous background
106  ---@param window any WezTerm `Window` see: https://wezfurlong.org/wezterm/config/lua/window/index.html
107  function BackDrops:cycle_back(window)
108    if self.current_idx == 1 then
109      self.current_idx = #self.files
110    else
111      self.current_idx = self.current_idx - 1
112    end
113    wezterm.GLOBAL.background = self.files[self.current_idx]
114    self:_set_opt(window)
115  end
116  
117  ---Set a specific background from the `files` array
118  ---@param window any WezTerm `Window` see: https://wezfurlong.org/wezterm/config/lua/window/index.html
119  ---@param idx number index of the `files` array
120  function BackDrops:set_img(window, idx)
121    if idx == nil or window == nil then
122      wezterm.log_error('Nil window or index')
123      return
124    end
125    if idx > #self.files or idx < 0 then
126      wezterm.log_error('Index out of range')
127      return
128    end
129  
130    self.current_idx = idx
131    wezterm.GLOBAL.background = self.files[self.current_idx]
132    self:_set_opt(window)
133  end
134  
135  return BackDrops:init()