Skip to content

Instantly share code, notes, and snippets.

@doole
Forked from alexpls/appearance.lua
Created August 14, 2024 08:01
Show Gist options
  • Save doole/d64156f4f4a86a428bf2c8e3e8e39126 to your computer and use it in GitHub Desktop.
Save doole/d64156f4f4a86a428bf2c8e3e8e39126 to your computer and use it in GitHub Desktop.
-- vim: tabstop=2 shiftwidth=2 expandtab
-- We almost always start by importing the wezterm module
local wezterm = require 'wezterm'
-- Define a lua table to hold _our_ module's functions
local module = {}
-- Returns a bool based on whether the host operating system's
-- appearance is light or dark.
function module.is_dark()
-- wezterm.gui is not always available, depending on what
-- environment wezterm is operating in. Just return true
-- if it's not defined.
if wezterm.gui then
-- Some systems report appearance like "Dark High Contrast"
-- so let's just look for the string "Dark" and if we find
-- it assume appearance is dark.
return wezterm.gui.get_appearance():find("Dark")
end
return true
end
return module
-- vim: tabstop=2 shiftwidth=2 expandtab
local wezterm = require 'wezterm'
local module = {}
local project_dir = wezterm.home_dir .. "/Projects"
local function project_dirs()
-- Start with your home directory as a project, 'cause you might want
-- to jump straight to it sometimes.
local projects = { wezterm.home_dir }
-- WezTerm comes with a glob function! Let's use it to get a lua table
-- containing all subdirectories of your project folder.
for _, dir in ipairs(wezterm.glob(project_dir .. '/*')) do
-- ... and add them to the projects table.
table.insert(projects, dir)
end
return projects
end
function module.choose_project()
local choices = {}
for _, value in ipairs(project_dirs()) do
table.insert(choices, { label = value })
end
return wezterm.action.InputSelector {
title = "Projects",
choices = choices,
fuzzy = true,
action = wezterm.action_callback(function(child_window, child_pane, id, label)
-- "label" may be empty if nothing was selected. Don't bother doing anything
-- when that happens.
if not label then return end
-- The SwitchToWorkspace action will switch us to a workspace if it already exists,
-- otherwise it will create it for us.
child_window:perform_action(wezterm.action.SwitchToWorkspace {
-- We'll give our new workspace a nice name, like the last path segment
-- of the directory we're opening up.
name = label:match("([^/]+)$"),
-- Here's the meat. We'll spawn a new terminal with the current working
-- directory set to the directory that was picked.
spawn = { cwd = label },
}, child_pane)
end),
}
end
return module
-- vim: tabstop=2 shiftwidth=2 expandtab
local wezterm = require 'wezterm'
local config = wezterm.config_builder()
local appearance = require 'appearance'
local projects = require 'projects'
config.set_environment_variables = {
PATH = '/opt/homebrew/bin:' .. os.getenv('PATH')
}
if appearance.is_dark() then
config.color_scheme = 'Tokyo Night'
else
config.color_scheme = 'Tokyo Night Day'
end
-- Slightly transparent and blurred background
config.window_background_opacity = 0.9
config.macos_window_background_blur = 30
-- Removes the title bar, leaving only the tab bar. Keeps
-- the ability to resize by dragging the window's edges.
-- On macOS, 'RESIZE|INTEGRATED_BUTTONS' also looks nice if
-- you want to keep the window controls visible and integrate
-- them into the tab bar.
config.window_decorations = 'RESIZE'
-- Sets the font for the window frame (tab bar)
config.window_frame = {
-- Berkeley Mono for me again, though an idea could be to try a
-- serif font here instead of monospace for a nicer look?
font = wezterm.font({ family = 'Berkeley Mono', weight = 'Bold' }),
font_size = 11,
}
local function segments_for_right_status(window)
return {
window:active_workspace(),
wezterm.strftime('%a %b %-d %H:%M'),
wezterm.hostname(),
}
end
wezterm.on('update-status', function(window, _)
local SOLID_LEFT_ARROW = utf8.char(0xe0b2)
local segments = segments_for_right_status(window)
local color_scheme = window:effective_config().resolved_palette
-- Note the use of wezterm.color.parse here, this returns
-- a Color object, which comes with functionality for lightening
-- or darkening the colour (amongst other things).
local bg = wezterm.color.parse(color_scheme.background)
local fg = color_scheme.foreground
-- Each powerline segment is going to be coloured progressively
-- darker/lighter depending on whether we're on a dark/light colour
-- scheme. Let's establish the "from" and "to" bounds of our gradient.
local gradient_to, gradient_from = bg
if appearance.is_dark() then
gradient_from = gradient_to:lighten(0.2)
else
gradient_from = gradient_to:darken(0.2)
end
-- Yes, WezTerm supports creating gradients, because why not?! Although
-- they'd usually be used for setting high fidelity gradients on your terminal's
-- background, we'll use them here to give us a sample of the powerline segment
-- colours we need.
local gradient = wezterm.color.gradient(
{
orientation = 'Horizontal',
colors = { gradient_from, gradient_to },
},
#segments -- only gives us as many colours as we have segments.
)
-- We'll build up the elements to send to wezterm.format in this table.
local elements = {}
for i, seg in ipairs(segments) do
local is_first = i == 1
if is_first then
table.insert(elements, { Background = { Color = 'none' } })
end
table.insert(elements, { Foreground = { Color = gradient[i] } })
table.insert(elements, { Text = SOLID_LEFT_ARROW })
table.insert(elements, { Foreground = { Color = fg } })
table.insert(elements, { Background = { Color = gradient[i] } })
table.insert(elements, { Text = ' ' .. seg .. ' ' })
end
window:set_right_status(wezterm.format(elements))
end)
local function move_pane(key, direction)
return {
key = key,
mods = 'LEADER',
action = wezterm.action.ActivatePaneDirection(direction),
}
end
local function resize_pane(key, direction)
return {
key = key,
action = wezterm.action.AdjustPaneSize { direction, 3 }
}
end
-- If you're using emacs you probably wanna choose a different leader here,
-- since we're gonna be making it a bit harder to CTRL + A for jumping to
-- the start of a line
config.leader = { key = 'a', mods = 'CTRL', timeout_milliseconds = 1000 }
-- Table mapping keypresses to actions
config.keys = {
-- Sends ESC + b and ESC + f sequence, which is used
-- for telling your shell to jump back/forward.
{
-- When the left arrow is pressed
key = 'LeftArrow',
-- With the "Option" key modifier held down
mods = 'OPT',
-- Perform this action, in this case - sending ESC + B
-- to the terminal
action = wezterm.action.SendString '\x1bb',
},
{
key = 'RightArrow',
mods = 'OPT',
action = wezterm.action.SendString '\x1bf',
},
{
key = ',',
mods = 'SUPER',
action = wezterm.action.SpawnCommandInNewTab {
cwd = wezterm.home_dir,
args = { 'nvim', wezterm.config_file },
},
},
{
-- I'm used to tmux bindings, so am using the quotes (") key to
-- split horizontally, and the percent (%) key to split vertically.
key = '"',
-- Note that instead of a key modifier mapped to a key on your keyboard
-- like CTRL or ALT, we can use the LEADER modifier instead.
-- This means that this binding will be invoked when you press the leader
-- (CTRL + A), quickly followed by quotes (").
mods = 'LEADER',
action = wezterm.action.SplitHorizontal { domain = 'CurrentPaneDomain' },
},
{
key = '%',
mods = 'LEADER',
action = wezterm.action.SplitVertical { domain = 'CurrentPaneDomain' },
},
{
key = 'a',
-- When we're in leader mode _and_ CTRL + A is pressed...
mods = 'LEADER|CTRL',
-- Actually send CTRL + A key to the terminal
action = wezterm.action.SendKey { key = 'a', mods = 'CTRL' },
},
move_pane('j', 'Down'),
move_pane('k', 'Up'),
move_pane('h', 'Left'),
move_pane('l', 'Right'),
{
-- When we push LEADER + R...
key = 'r',
mods = 'LEADER',
-- Activate the `resize_panes` keytable
action = wezterm.action.ActivateKeyTable {
name = 'resize_panes',
-- Ensures the keytable stays active after it handles its
-- first keypress.
one_shot = false,
-- Deactivate the keytable after a timeout.
timeout_milliseconds = 1000,
}
},
{
key = 'p',
mods = 'LEADER',
-- Present in to our project picker
action = projects.choose_project(),
},
{
key = 'f',
mods = 'LEADER',
-- Present a list of existing workspaces
action = wezterm.action.ShowLauncherArgs { flags = 'FUZZY|WORKSPACES' },
},
}
config.key_tables = {
resize_panes = {
resize_pane('j', 'Down'),
resize_pane('k', 'Up'),
resize_pane('h', 'Left'),
resize_pane('l', 'Right'),
},
}
return config
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment