Last active
March 4, 2024 08:26
-
-
Save Broderick-Westrope/8030cff3c605924ee249ca780ed091d9 to your computer and use it in GitHub Desktop.
wezterm config
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local wezterm = require("wezterm") | |
local session_manager = {} | |
--- Helper function to safely perform file operations and capture errors. | |
local function safe_file_operation(func, ...) | |
local success, result_or_error = pcall(func, ...) | |
if not success then | |
wezterm.log_info("File operation error: " .. tostring(result_or_error)) | |
return false, result_or_error | |
end | |
return true, result_or_error | |
end | |
--- Helper function to construct the file path for saving and loading session states. | |
local function construct_file_path(workspace_name) | |
return wezterm.home_dir .. "/.config/wezterm/wezterm-session-manager/wezterm_state_" .. workspace_name .. ".json" | |
end | |
--- Retrieves the current workspace data from the active window. | |
local function retrieve_workspace_data(window) | |
local workspace_name = window:active_workspace() | |
local workspace_data = { | |
name = workspace_name, | |
tabs = {} | |
} | |
for _, tab in ipairs(window:mux_window():tabs()) do | |
local tab_data = { | |
tab_id = tostring(tab:tab_id()), | |
panes = {} | |
} | |
for _, pane_info in ipairs(tab:panes_with_info()) do | |
table.insert(tab_data.panes, { | |
pane_id = tostring(pane_info.pane:pane_id()), | |
index = pane_info.index, | |
is_active = pane_info.is_active, | |
is_zoomed = pane_info.is_zoomed, | |
left = pane_info.left, | |
top = pane_info.top, | |
width = pane_info.width, | |
height = pane_info.height, | |
pixel_width = pane_info.pixel_width, | |
pixel_height = pane_info.pixel_height, | |
cwd = tostring(pane_info.pane:get_current_working_dir()), | |
tty = tostring(pane_info.pane:get_foreground_process_name()) | |
}) | |
end | |
table.insert(workspace_data.tabs, tab_data) | |
end | |
return workspace_data | |
end | |
--- Saves data to a JSON file. | |
local function save_to_json_file(data, file_path) | |
-- Attempt to open the file for writing and check for success | |
local success, file_or_error = safe_file_operation(io.open, file_path, "w") | |
if not success then | |
wezterm.log_info("Failed to open file for writing: " .. tostring(file_or_error)) | |
return false | |
end | |
-- If successful, 'file_or_error' will be the file handle | |
local file = file_or_error | |
-- Now attempt to write the data to the file | |
success, file_or_error = safe_file_operation(file.write, file, wezterm.json_encode(data)) | |
if not success then | |
wezterm.log_info("Failed to write to file: " .. tostring(file_or_error)) | |
-- Ensure the file is closed even if writing fails | |
file:close() | |
return false | |
end | |
-- Close the file after writing is successful | |
file:close() | |
return true | |
end | |
--- Loads data from a JSON file. | |
local function load_from_json_file(file_path) | |
local file, err = safe_file_operation(io.open, file_path, "r") | |
if not file then | |
wezterm.log_info("Failed to open file: " .. tostring(err)) | |
return nil | |
end | |
local content, err = safe_file_operation(file.read, file, "*a") | |
if not content then | |
wezterm.log_info("Failed to read file: " .. tostring(err)) | |
return nil | |
end | |
file:close() | |
local data, err = safe_file_operation(wezterm.json_parse, content) | |
if not data then | |
wezterm.log_info("Failed to parse JSON: " .. tostring(err)) | |
return nil | |
end | |
return data | |
end | |
--- Recreates the workspace based on the provided data. | |
local function recreate_workspace(window, workspace_data) | |
-- Detailed implementation as previously discussed... | |
end | |
--- Orchestrator function to save the current workspace state. | |
function session_manager.save_state(window) | |
local data = retrieve_workspace_data(window) | |
local file_path = construct_file_path(data.name) | |
if save_to_json_file(data, file_path) then | |
window:toast_notification('WezTerm Session Manager', 'Workspace state saved successfully', nil, 4000) | |
else | |
window:toast_notification('WezTerm Session Manager', 'Failed to save workspace state', nil, 4000) | |
end | |
end | |
--- Allows selecting which workspace to load. | |
function session_manager.load_state(window) | |
local sessions_dir = wezterm.home_dir .. "/.config/wezterm/wezterm-session-manager/" | |
local entries, err = wezterm.read_dir(sessions_dir) | |
if not entries then | |
wezterm.log_info("Error reading sessions directory: " .. tostring(err)) | |
return | |
end | |
local items = {} | |
for _, entry in ipairs(entries) do | |
if not entry then | |
wezterm.log_error("Encountered an invalid entry in sessions directory") | |
goto continue | |
end | |
-- Extract the filename from the entry path | |
local filename = entry:match("^.+[/\\](.+)$") | |
if not filename then | |
wezterm.log_error("Could not extract filename from entry: " .. entry) | |
goto continue | |
end | |
-- Now use 'filename' for matching and manipulation | |
if filename:match("^wezterm_state_.*%.json$") then | |
table.insert(items, { | |
label = filename:gsub("^wezterm_state_(.*)%.json$", "%1"), | |
file_path = sessions_dir .. filename, | |
}) | |
else | |
-- Log skipping files that do not match the session file pattern | |
wezterm.log_info("Skipping non-session file: " .. filename) | |
end | |
::continue:: | |
end | |
if #items == 0 then | |
window:toast_notification("WezTerm Session Manager", "No saved sessions found.", nil, 4000) | |
return | |
end | |
window:show_overlay(wezterm.gui.overlay.new_selection_window({ | |
items = items, | |
on_select = function(item) | |
if not item then | |
wezterm.log_error("Item is nil in on_select") | |
return | |
end | |
if not item.file_path or not item.label then | |
wezterm.log_error("Item missing expected fields in on_select: " .. wezterm.json_encode(item)) | |
return | |
end | |
local workspace_data = load_from_json_file(item.file_path) | |
if workspace_data then | |
recreate_workspace(window, workspace_data) | |
window:toast_notification("WezTerm Session Manager", "Session " .. item.label .. " loaded successfully.", nil, | |
4000) | |
else | |
window:toast_notification("WezTerm Session Manager", "Failed to load session " .. item.label, nil, 4000) | |
end | |
end, | |
})) | |
end | |
return session_manager |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- This script depends on: | |
-- - WezTerm Session Manager (https://github.com/danielcopper/wezterm-session-manager) | |
local wezterm = require("wezterm") | |
local session_manager = require("wezterm-session-manager") | |
local config = wezterm.config_builder() | |
local bgColor = "#050014" | |
-- Color Scheme | |
local scheme = wezterm.color.get_builtin_schemes()["Tokyo Night Moon"] | |
scheme.background = bgColor | |
config.color_schemes = { | |
["My Custom Scheme"] = scheme | |
} | |
config.color_scheme = "My Custom Scheme" | |
-- Font | |
config.font_size = 18 | |
config.font = wezterm.font("FiraCode Nerd Font Mono") | |
-- Tab Appearance | |
config.use_fancy_tab_bar = false | |
config.hide_tab_bar_if_only_one_tab = true | |
config.colors = { | |
tab_bar = { | |
background = bgColor, | |
active_tab = { | |
bg_color = bgColor, | |
fg_color = scheme.ansi[6] | |
}, | |
inactive_tab = { | |
bg_color = bgColor, | |
fg_color = scheme.brights[8] | |
}, | |
inactive_tab_hover = { | |
bg_color = bgColor, | |
fg_color = scheme.ansi[6] | |
}, | |
new_tab = { | |
bg_color = bgColor, | |
fg_color = scheme.ansi[8] | |
}, | |
new_tab_hover = { | |
bg_color = bgColor, | |
fg_color = scheme.ansi[6] | |
} | |
} | |
} | |
config.window_decorations = "RESIZE" | |
local process_icons = { | |
['docker'] = wezterm.nerdfonts.linux_docker, | |
['docker-compose'] = wezterm.nerdfonts.linux_docker, | |
['psql'] = '', | |
['usql'] = '', | |
['kuberlr'] = wezterm.nerdfonts.linux_docker, | |
['ssh'] = wezterm.nerdfonts.fa_exchange, | |
['ssh-add'] = wezterm.nerdfonts.fa_exchange, | |
['kubectl'] = wezterm.nerdfonts.linux_docker, | |
['stern'] = wezterm.nerdfonts.linux_docker, | |
['nvim'] = wezterm.nerdfonts.custom_vim, | |
['make'] = wezterm.nerdfonts.seti_makefile, | |
['vim'] = wezterm.nerdfonts.dev_vim, | |
['node'] = wezterm.nerdfonts.mdi_hexagon, | |
['go'] = wezterm.nerdfonts.seti_go, | |
['zsh'] = wezterm.nerdfonts.dev_terminal, | |
['bash'] = wezterm.nerdfonts.cod_terminal_bash, | |
['btm'] = wezterm.nerdfonts.mdi_chart_donut_variant, | |
['htop'] = wezterm.nerdfonts.mdi_chart_donut_variant, | |
['cargo'] = wezterm.nerdfonts.dev_rust, | |
['sudo'] = wezterm.nerdfonts.fa_hashtag, | |
['lazydocker'] = wezterm.nerdfonts.linux_docker, | |
['lazygit'] = wezterm.nerdfonts.dev_git, | |
['git'] = wezterm.nerdfonts.dev_git, | |
['lua'] = wezterm.nerdfonts.seti_lua, | |
['wget'] = wezterm.nerdfonts.mdi_arrow_down_box, | |
['curl'] = wezterm.nerdfonts.mdi_flattr, | |
['gh'] = wezterm.nerdfonts.dev_github_badge, | |
['ruby'] = wezterm.nerdfonts.cod_ruby, | |
} | |
local function get_current_working_dir(tab) | |
local current_dir = tab.active_pane and tab.active_pane.current_working_dir or { | |
file_path = '' | |
} | |
local HOME_DIR = string.format('file://%s', os.getenv('HOME')) | |
return current_dir == HOME_DIR and '.' or string.gsub(current_dir.file_path, '(.*[/\\])(.*)', '%2') | |
end | |
local function get_process(tab) | |
if not tab.active_pane or tab.active_pane.foreground_process_name == '' then | |
return '[?]' | |
end | |
local process_name = string.gsub(tab.active_pane.foreground_process_name, '(.*[/\\])(.*)', '%2') | |
if string.find(process_name, 'kubectl') then | |
process_name = 'kubectl' | |
end | |
return process_icons[process_name] or string.format('[%s]', process_name) | |
end | |
wezterm.on('format-tab-title', function(tab, tabs, panes, config, hover, max_width) | |
local has_unseen_output = false | |
if not tab.is_active then | |
for _, pane in ipairs(tab.panes) do | |
if pane.has_unseen_output then | |
has_unseen_output = true | |
break | |
end | |
end | |
end | |
local cwd = wezterm.format({ { | |
Attribute = { | |
Intensity = 'Bold' | |
} | |
}, { | |
Text = get_current_working_dir(tab) | |
} }) | |
local title = string.format(' %s ~ %s ', get_process(tab), cwd) | |
if has_unseen_output then | |
return { | |
{ | |
Foreground = { | |
Color = scheme.ansi[5] | |
} | |
}, | |
{ | |
Text = title | |
} } | |
end | |
return { { | |
Text = title | |
} } | |
end) | |
config.tab_max_width = 60 | |
config.default_cursor_style = 'SteadyUnderline' | |
config.command_palette_font_size = 18 | |
config.command_palette_bg_color = bgColor | |
wezterm.on("save_session", function(window) session_manager.save_state(window) end) | |
wezterm.on("load_session", function(window) session_manager.load_state(window) end) | |
wezterm.on("restore_session", function(window) session_manager.restore_state(window) end) | |
config.leader = { key = 'a', mods = 'CTRL', timeout_milliseconds = 3000 } | |
config.keys = { | |
-- Send "CTRL-A" to the terminal when pressing CTRL-A, CTRL-A | |
{ | |
key = 'a', | |
mods = 'LEADER|CTRL', | |
action = wezterm.action.SendKey { key = 'a', mods = 'CTRL' }, | |
}, | |
{ key = "S", mods = "LEADER", action = wezterm.action { EmitEvent = "save_session" } }, | |
{ key = "L", mods = "LEADER", action = wezterm.action { EmitEvent = "load_session" } }, | |
{ key = "R", mods = "LEADER", action = wezterm.action { EmitEvent = "restore_session" } }, | |
-- Make Option-Left equivalent to Alt-b which many line editors interpret as backward-word | |
{ key = "LeftArrow", mods = "OPT", action = wezterm.action { SendString = "\x1bb" } }, | |
-- Make Option-Right equivalent to Alt-f; forward-word | |
{ key = "RightArrow", mods = "OPT", action = wezterm.action { SendString = "\x1bf" } } | |
} | |
-- and finally, return the configuration to wezterm | |
return config |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment