diff --git a/src/shell/config/wezterm/appearance.lua b/src/shell/config/wezterm/appearance.lua new file mode 100644 index 0000000..8ce8f54 --- /dev/null +++ b/src/shell/config/wezterm/appearance.lua @@ -0,0 +1,16 @@ +local wezterm = require 'wezterm' + +local module = {} + +-- Check if the current appearance is dark mode +function module.is_dark() + if wezterm.gui then + -- Return true if the appearance contains "Dark" + return wezterm.gui.get_appearance():find("Dark") + end + + -- Default to true (dark mode) if wezterm.gui is not available + return true +end + +return module diff --git a/src/shell/config/wezterm/panes.lua b/src/shell/config/wezterm/panes.lua new file mode 100644 index 0000000..8e6eb82 --- /dev/null +++ b/src/shell/config/wezterm/panes.lua @@ -0,0 +1,22 @@ +local wezterm = require 'wezterm' + +local module = {} + +-- Define a keybinding to move a pane in a specified direction +function module.move_pane(key, direction) + return { + key = key, + mods = 'LEADER', + action = wezterm.action.ActivatePaneDirection(direction), + } +end + +-- Define a keybinding to resize a pane in a specified direction +function module.resize_pane(key, direction) + return { + key = key, + action = wezterm.action.AdjustPaneSize { direction, 2 } + } +end + +return module diff --git a/src/shell/config/wezterm/projects.lua b/src/shell/config/wezterm/projects.lua new file mode 100644 index 0000000..0002b87 --- /dev/null +++ b/src/shell/config/wezterm/projects.lua @@ -0,0 +1,44 @@ +local wezterm = require 'wezterm' + +local module = {} +local base_dir = wezterm.home_dir .. '/Code/*' + +-- Gather all the directories in the base_dir +local function project_dirs() + local projects = {} + + -- Use wezterm.glob to list all directories in base_dir and add them to the projects table + for _, dir in ipairs(wezterm.glob(base_dir .. '/*')) do + table.insert(projects, dir) + end + + return projects +end + +-- Allow the user to choose a project directory using an input selector +function module.choose_project() + local choices = {} + + -- Populate the choices table with directory labels returned by project_dirs() + for _, value in ipairs(project_dirs()) do + table.insert(choices, { label = value }) + end + + -- Display an input selector with the available projects + return wezterm.action.InputSelector { + title = "Projects", -- Set the title of the selector window + choices = choices, -- Provide the list of available projects + fuzzy = true, -- Enable fuzzy matching for easier searching + action = wezterm.action_callback(function(child_window, child_pane, id, label) + if not label then return end -- Ensure a valid label is selected + + -- Switch to the selected workspace, using the project name as the workspace name + child_window:perform_action(wezterm.action.SwitchToWorkspace { + name = label:match("([^/]+)$"), -- Extract the last part of the path as the workspace name + spawn = { cwd = label }, -- Set the working directory to the selected project + }, child_pane) + end), + } +end + +return module diff --git a/src/shell/config/wezterm/wezterm.lua b/src/shell/config/wezterm/wezterm.lua index 5f5a9a7..62efc85 100644 --- a/src/shell/config/wezterm/wezterm.lua +++ b/src/shell/config/wezterm/wezterm.lua @@ -1,23 +1,152 @@ local wezterm = require 'wezterm' -local act = wezterm.action +local projects = require 'projects' +local appearance = require 'appearance' +local panes = require 'panes' -return { - -- Hide tab bar, since we use tmux - enable_tab_bar = false, +local config = wezterm.config_builder() - -- Remove vertical padding - window_padding = { - top = 0, - bottom = 0, - }, +-- Set the default cursor style to a blinking underline +config.default_cursor_style = 'BlinkingUnderline' + +-- Set the color scheme to 'Halcyon' +config.color_scheme = 'Halcyon' - -- Use a nerd font - font = wezterm.font 'MonoLisa Nerd Font', - font_size = 12.0, +-- Set the font to 'MonoLisa Nerd Font' +config.font = wezterm.font({ family = 'MonoLisa Nerd Font' }) - -- Set color scheme - color_scheme = 'Halcyon', +-- Set the window background opacity and macOS window background blur +config.window_background_opacity = 0.98 +config.macos_window_background_blur = 25 - -- Set cursor style - default_cursor_style = "BlinkingUnderline", +-- Configure the window decorations +config.window_decorations = 'RESIZE|INTEGRATED_BUTTONS' + +-- Configure the window frame font and font size +config.window_frame = { + font = wezterm.font({ family = 'MonoLisa Nerd Font', weight = 'Bold' }), + font_size = 11, } + +-- Set the leader key to 'CTRL+a' with a timeout of 1000 milliseconds +config.leader = { key = 'a', mods = 'CTRL', timeout_milliseconds = 1000 } + +-- Define keybindings for various actions +config.keys = { + -- Split the pane horizontally + { + key = '|', + mods = 'LEADER', + action = wezterm.action.SplitHorizontal { domain = 'CurrentPaneDomain' }, + }, + -- Split the pane vertically + { + key = '-', + mods = 'LEADER', + action = wezterm.action.SplitVertical { domain = 'CurrentPaneDomain' }, + }, + -- Send 'CTRL+a' to the terminal + { + key = 'a', + mods = 'LEADER|CTRL', + action = wezterm.action.SendKey { key = 'a', mods = 'CTRL' }, + }, + -- Activate the resize panes key table + { + key = 'r', + mods = 'LEADER', + action = wezterm.action.ActivateKeyTable { + name = 'resize_panes', + one_shot = false, + timeout_milliseconds = 1000, + } + }, + -- Trigger project selection using the LEADER+p keybinding + { + key = 'p', + mods = 'LEADER', + action = projects.choose_project(), + }, + -- Show the launcher with fuzzy matching and workspaces using LEADER+f + { + key = 'f', + mods = 'LEADER', + action = wezterm.action.ShowLauncherArgs { flags = 'FUZZY|WORKSPACES' }, + }, + + -- Define keybindings for moving the pane + panes.move_pane('j', 'Down'), + panes.move_pane('k', 'Up'), + panes.move_pane('h', 'Left'), + panes.move_pane('l', 'Right'), +} + +-- Define key tables for resizing panes +config.key_tables = { + resize_panes = { + panes.resize_pane('j', 'Down'), + panes.resize_pane('k', 'Up'), + panes.resize_pane('h', 'Left'), + panes.resize_pane('l', 'Right'), + }, +} + +-- Define a function to generate segments for the right status bar +local function segments_for_right_status(window) + return { + window:active_workspace(), + wezterm.strftime('%a %b %-d %H:%M:%S'), + wezterm.hostname(), + } +end + +-- Update the status bar when the 'update-status' event is triggered +wezterm.on('update-status', function(window, _) + local SEPARATOR = wezterm.nerdfonts.ple_lower_right_triangle + local segments = segments_for_right_status(window) + + local color_scheme = window:effective_config().resolved_palette + + local bg = wezterm.color.parse(color_scheme.background) + local fg = wezterm.color.parse(color_scheme.foreground) + + local gradient_to = bg + local gradient_from + + -- Determine the gradient color based on the appearance (dark or light) + if appearance.is_dark() then + gradient_from = gradient_to:lighten(0.2) + else + gradient_from = gradient_to:darken(0.2) + end + + -- Create a horizontal gradient based on the number of segments + local gradient = wezterm.color.gradient( + { + orientation = 'Horizontal', + colors = { gradient_from, gradient_to }, + }, + #segments + ) + + local elements = {} + + -- Build the status bar elements from the segments + 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 = SEPARATOR }) + + table.insert(elements, { Foreground = { Color = fg } }) + table.insert(elements, { Background = { Color = gradient[i] } }) + table.insert(elements, { Text = ' ' .. seg .. ' ' }) + end + + -- Set the right status with the formatted elements + window:set_right_status(wezterm.format(elements)) +end) + +return config