Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

wezterm/bugabinga/status.lua

Raw
local wez = require 'wezterm'
local bat = require 'bugabinga.battery'
local agent = require 'bugabinga.agent'

---@diagnostic disable-next-line: different-requires
local nugu_dark = require 'bugabinga.nugu.palette_dark'.palette
---@diagnostic disable-next-line: different-requires
local nugu_light = require 'bugabinga.nugu.palette_light'.palette
local palette = nugu_dark

local program_icons = {
  aerc = wez.nerdfonts.md_email,
  bat = wez.nerdfonts.md_file_document,
  btm = wez.nerdfonts.md_monitor_dashboard,
  cargo = wez.nerdfonts.dev_rust,
  chawan = wez.nerdfonts.md_web,
  claude = wez.nerdfonts.md_robot_outline,
  cmus = wez.nerdfonts.md_music,
  code = wez.nerdfonts.custom_neovim,
  codex = '',
  edit = wez.nerdfonts.custom_neovim,
  fd = wez.nerdfonts.md_folder_search_outline,
  fin = wez.nerdfonts.md_magnify,
  firefox = wez.nerdfonts.fa_firefox,
  fzf = wez.nerdfonts.md_magnify,
  g = wez.nerdfonts.dev_git,
  gh = wez.nerdfonts.dev_github_badge,
  git = wez.nerdfonts.dev_git,
  gitu = wez.nerdfonts.dev_git,
  glow = wez.nerdfonts.md_language_markdown,
  java = wez.nerdfonts.dev_java,
  jj = wez.nerdfonts.md_source_branch,
  lazygit = wez.nerdfonts.dev_git,
  list = wez.nerdfonts.md_folder_multiple,
  mise = wez.nerdfonts.md_hammer_wrench,
  mpv = wez.nerdfonts.fa_film,
  mvn = wez.nerdfonts.dev_maven,
  neovide = wez.nerdfonts.custom_neovim,
  node = wez.nerdfonts.dev_nodejs_small,
  npm = wez.nerdfonts.dev_npm,
  npx = wez.nerdfonts.dev_npm,
  nu = wez.nerdfonts.oct_terminal,
  nvim = wez.nerdfonts.custom_neovim,
  package = wez.nerdfonts.md_hammer_wrench,
  podman = wez.nerdfonts.linux_docker,
  python = wez.nerdfonts.dev_python,
  rbw = wez.nerdfonts.md_shield_key,
  rg = wez.nerdfonts.md_file_search,
  rustc = wez.nerdfonts.dev_rust,
  show = wez.nerdfonts.md_file_document,
  ssh = wez.nerdfonts.md_shield_key,
  topgrade = wez.nerdfonts.md_update,
  tree = wez.nerdfonts.md_file_tree,
  tre = wez.nerdfonts.md_file_tree,
  unpackage = wez.nerdfonts.md_hammer_wrench,
  uv = wez.nerdfonts.dev_python,
  vi = wez.nerdfonts.custom_neovim,
  video = wez.nerdfonts.fa_film,
  vim = wez.nerdfonts.custom_neovim,
  web = wez.nerdfonts.fa_firefox,
  wezterm = wez.nerdfonts.oct_terminal,
  yazi = wez.nerdfonts.md_folder_open,
  yy = wez.nerdfonts.md_folder_open,
  zed = wez.nerdfonts.md_code_braces,
  zeditor = wez.nerdfonts.md_code_braces,
  zig = wez.nerdfonts.dev_zig,
}

local clean = function ( value )
  if not value or value == '' then return nil end
  value = value:gsub( '^%s+', '' ):gsub( '%s+$', '' )
  if value == '' then return nil end
  return value
end

local basename = function ( value )
  if not value or value == '' then return nil end
  value = value:gsub( '\\', '/' ):gsub( '/+$', '' )
  return value:match '([^/]+)$' or value
end

local use_palette_for_scheme = function ( scheme )
  palette = scheme == 'nugu-light' and nugu_light or nugu_dark
end

local use_palette_for_window = function ( window )
  local ok, config = pcall( function () return window:effective_config() end )
  if ok and config then use_palette_for_scheme( config.color_scheme ) end
end

local short_workspace = function ( name, max_width )
  name = clean( name ) or 'default'
  local home = wez.home_dir
  if home and name:sub( 1, #home ) == home then
    name = '~' .. name:sub( #home + 1 )
  end
  if name:find( '/', 1, true ) or name:find( '\\', 1, true ) then
    name = basename( name ) or name
  end
  return wez.truncate_right( name, max_width or 18 )
end

local workspace_slug = function ( name )
  local slug = short_workspace( name ):gsub( '[^%w]', '' ):sub( 1, 3 ):lower()
  return slug ~= '' and slug or '?'
end

local workspace_chips = function ( active )
  active = clean( active ) or 'default'

  local ok, names = pcall( wez.mux.get_workspace_names )
  if not ok or type( names ) ~= 'table' or #names <= 1 then
    return short_workspace( active )
  end

  table.sort( names, function ( a, b )
    return tostring( a ):lower() < tostring( b ):lower()
  end )

  local parts = {}
  for _, name in ipairs( names ) do
    local label = workspace_slug( name )
    if name == active then label = '[' .. short_workspace( name, 42 ) .. ']' end
    table.insert( parts, label )
  end

  return table.concat( parts, ' ' )
end

local function starts_with_name( title, name )
  if not title or not name then return false end
  local lower = title:lower()
  name = name:lower()
  if lower:sub( 1, #name ) ~= name then return false end
  local boundary = lower:sub( #name + 1, #name + 1 )
  return boundary == '' or boundary:match '%W' ~= nil
end

local function pane_project( pane )
  local cwd = pane and pane.current_working_dir
  local ok, path = pcall( function () return cwd and cwd.file_path end )
  return ok and path and short_workspace( path, 24 ) or nil
end

local tab_text = function ( tab )
  local explicit = clean( tab.tab_title )
  if explicit then return explicit end

  local pane = tab.active_pane
  local user_vars = pane and pane.user_vars
  local title = clean( pane and pane.title )
  local identity = agent.identity( user_vars )
  if identity == 'Pi' then
    local parts = { (wez.nerdfonts.md_pirate or '\u{f0a08}') .. ' Pi', }
    local session = clean( user_vars and user_vars.agent_session )
    local project = clean( user_vars and user_vars.agent_project ) or pane_project( pane )
    if session then table.insert( parts, session ) end
    if project and project ~= session then table.insert( parts, project ) end
    return table.concat( parts, ' · ' )
  end

  local program = agent.program( user_vars )
  local label = identity or program
  if not label then return title or 'tab' end
  if starts_with_name( title, label ) or starts_with_name( title, program ) then
    label = title
  else
    local project = pane_project( pane )
    if project then label = label .. ' · ' .. project end
  end
  local icon = program_icons[program]
  return icon and (icon .. ' ' .. label) or label
end

local zoomed = function ( pane )
  local tab = pane:tab()
  if not tab then return nil end

  for _, info in ipairs( tab:panes_with_info() ) do
    if info.is_zoomed then return 'zoom' end
  end

  return nil
end

local host_domain = function ()
  local triple = wez.target_triple or ''
  if triple:find( 'windows', 1, true ) then return 'WIN', wez.nerdfonts.dev_windows or '', palette.warning end
  if triple:find( 'darwin', 1, true ) then return 'MAC', wez.nerdfonts.dev_apple or '', palette.ui.important_local end
  if triple:find( 'linux', 1, true ) then return 'LIN', wez.nerdfonts.dev_linux or '', palette.ui.important_local end
  if triple:find( 'bsd', 1, true ) then return 'BSD', wez.nerdfonts.md_freebsd or '󰣠 ', palette.ui.important_local end
  return 'LOC', wez.nerdfonts.cod_terminal or '', palette.ui.important_local
end

local domain_label = function ( domain )
  if domain == 'unix' then return 'MUX', wez.nerdfonts.cod_server or wez.nerdfonts.cod_terminal or '', palette.info end
  if not domain or domain == 'local' or domain == 'Local' then return host_domain() end
  if domain:find( '^WSL:', 1, false ) then return 'WSL', wez.nerdfonts.dev_linux or '', palette.ui.important_local end
  if domain:find( '^scope:', 1, false ) then return 'EXE', wez.nerdfonts.cod_gear or '', palette.warning end
  return (domain:upper():gsub( '[^%w]', '' ):sub( 1, 3 ) .. 'LOC'):sub( 1, 3 ), wez.nerdfonts.cod_terminal or '',
    palette.ui.important_local
end

wez.on( 'format-tab-title', function ( tab, tabs, panes, config, hover, max_width )
  if config then use_palette_for_scheme( config.color_scheme ) end

  local bg = palette.content.backdrop
  local fg = palette.content.minor
  if tab.is_active then
    bg = palette.ui.focus
    fg = palette.content.backdrop
  elseif hover then
    bg = palette.ui.accent
    fg = palette.content.backdrop
  end

  local marker = tab.is_active and '●' or '○'
  local progress, progress_state = agent.badge( tab.active_pane.progress )
  if not tab.is_active and progress_state == 'working' then fg = palette.info end
  if not tab.is_active and progress_state == 'error' then fg = palette.error end

  local title = tab_text( tab )
  local suffix = progress and (' ' .. progress) or ''
  local label = string.format( ' %s %d %s%s ', marker, tab.tab_index + 1, title, suffix )
  label = wez.truncate_right( label, math.max( 1, max_width or 32 ) )

  return {
    { Background = { Color = bg, }, },
    { Foreground = { Color = fg, }, },
    { Attribute = { Intensity = tab.is_active and 'Bold' or 'Normal', }, },
    { Text = label, },
    'ResetAttributes',
  }
end )

wez.on( 'format-window-title', function ( tab )
  local ok, workspace = pcall( wez.mux.get_active_workspace )
  workspace = ok and workspace or 'default'
  local title = tab and tab_text( tab ) or 'WezTerm'
  return '[' .. workspace .. '] ' .. title
end )

wez.on( 'update-status', function ( window, pane )
  local ok_status, status_error = pcall( function ()
    agent.write_snapshot()
    use_palette_for_window( window )

    local right = {}
    local key_table = window:active_key_table()
    if window:leader_is_active() then key_table = 'LEADER' end
    if key_table then
      right = {
        { Background = { Color = palette.error, }, },
        { Foreground = { Color = palette.ui.backdrop, }, },
        { Attribute = { Intensity = 'Bold', }, },
        { Text = ' ' .. key_table .. ' ', },
        'ResetAttributes',
        { Text = ' ', },
      }
    end

    local ok_zoom, zoomed_state = pcall( zoomed, pane )
    if ok_zoom and zoomed_state then
      table.insert( right, { Foreground = { Color = palette.ui.minor, }, } )
      table.insert( right, { Text = zoomed_state .. ' ', } )
    end
    window:set_right_status( wez.format( right ) )

    local battery = bat.get_battery_icons( palette )
    if battery ~= '' then battery = ' ' .. battery .. ' ' end

    local ok_domain, domain = pcall( pane.get_domain_name, pane )
    local domain_text, domain_icon, domain_color = domain_label( ok_domain and domain or nil )
    local workspace = workspace_chips( window:active_workspace() )

    window:set_left_status( wez.format {
      { Text = battery, },
      { Foreground = { Color = palette.ui.important_local, }, },
      ---@diagnostic disable-next-line: missing-fields
      { Attribute = { Intensity = 'Bold', }, },
      { Text = '● ' .. workspace .. '  ', },
      { Foreground = { Color = domain_color, }, },
      { Text = domain_icon .. ' ' .. domain_text .. '  ', },
      'ResetAttributes',
    } )
  end )

  if not ok_status then
    wez.log_error( 'status render failed: ' .. tostring( status_error ) )
    window:set_right_status( wez.format {
      { Foreground = { Color = palette.error, }, },
      { Text = ' status error ', },
    } )
  end
end )

return function ( cfg )
  ---@cast cfg Config
  cfg.enable_tab_bar = true
  cfg.hide_tab_bar_if_only_one_tab = false
  cfg.use_fancy_tab_bar = false
  cfg.tab_max_width = 128
  cfg.show_tabs_in_tab_bar = true
  cfg.show_new_tab_button_in_tab_bar = false
  cfg.tab_bar_at_bottom = true
end