├── .gitignore ├── plugin ├── sessionizer │ ├── generators │ │ ├── default_workspace.lua │ │ ├── all_active_workspaces.lua │ │ └── fd_search.lua │ ├── input_selector.lua │ ├── helpers.lua │ └── schema_processor.lua └── init.lua ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | test.lua 2 | issue_*.lua 3 | .direnv 4 | .envrc 5 | 6 | -------------------------------------------------------------------------------- /plugin/sessionizer/generators/default_workspace.lua: -------------------------------------------------------------------------------- 1 | local helpers = require "sessionizer.helpers" 2 | 3 | local generator = {} 4 | 5 | local function find(opts) 6 | local default_options = { 7 | id_overwrite = "default", 8 | label_overwrite = "Default", 9 | } 10 | 11 | helpers.merge_tables(default_options, opts) 12 | opts = default_options 13 | 14 | return { { label = opts.label_overwrite, id = opts.id_overwrite } } 15 | end 16 | 17 | generator.DefaultWorkspace = function(opts) 18 | return function() 19 | return find(opts) 20 | end 21 | end 22 | 23 | return generator 24 | -------------------------------------------------------------------------------- /plugin/sessionizer/input_selector.lua: -------------------------------------------------------------------------------- 1 | local wezterm = require "wezterm" 2 | 3 | local input_selector = {} 4 | 5 | ---@param options SchemaOptions 6 | ---@param choices Entry[] 7 | ---@return unknown 8 | input_selector.get_input_selector = function(options, choices) 9 | return wezterm.action.InputSelector { 10 | title = options.title, 11 | description = options.prompt, 12 | fuzzy_description = options.prompt, 13 | fuzzy = options.always_fuzzy, 14 | choices = choices, 15 | action = wezterm.action_callback(options.callback), 16 | } 17 | end 18 | 19 | return input_selector 20 | -------------------------------------------------------------------------------- /plugin/sessionizer/helpers.lua: -------------------------------------------------------------------------------- 1 | local helpers = {} 2 | 3 | helpers.append_each = function(source, destination) 4 | for _, value in ipairs(source) do 5 | table.insert(destination, value) 6 | end 7 | end 8 | 9 | helpers.merge_tables = function(t1, t2) 10 | if (not t2) then return end 11 | for k, v in pairs(t2) do 12 | if type(v) == "table" and type(t1[k]) == "table" then 13 | helpers.merge_tables(t1[k], t2[k]) 14 | else 15 | t1[k] = v 16 | end 17 | end 18 | end 19 | 20 | helpers.for_each_entry = function(f) 21 | return function(entries) 22 | for _, entry in ipairs(entries) do 23 | f(entry) 24 | end 25 | end 26 | end 27 | 28 | return helpers 29 | -------------------------------------------------------------------------------- /plugin/sessionizer/generators/all_active_workspaces.lua: -------------------------------------------------------------------------------- 1 | local wezterm = require "wezterm" 2 | local helpers = require "sessionizer.helpers" 3 | 4 | local generator = {} 5 | 6 | local function find(opts) 7 | local default_options = { 8 | filter_default = true, 9 | filter_current = true, 10 | } 11 | 12 | helpers.merge_tables(default_options, opts) 13 | opts = default_options 14 | 15 | local entries = {} 16 | 17 | local current = nil 18 | if opts.filter_current then 19 | current = wezterm.mux.get_active_workspace() 20 | end 21 | 22 | local all_workspaces = wezterm.mux.get_workspace_names() 23 | for _, v in ipairs(all_workspaces) do 24 | if opts.filter_current and v == current then goto continue end 25 | if opts.filter_default and v == "default" then goto continue end 26 | 27 | table.insert(entries, { label = v, id = v }) 28 | ::continue:: 29 | end 30 | return entries 31 | end 32 | 33 | generator.AllActiveWorkspaces = function(opts) 34 | return function() 35 | return find(opts) 36 | end 37 | end 38 | 39 | return generator 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Mikka Sendke 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /plugin/init.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path .. ";" .. ({ ... })[2]:gsub("init.lua$", "?.lua") 2 | 3 | local wezterm = require "wezterm" 4 | local schema_processor = require "sessionizer.schema_processor" 5 | local input_selector = require "sessionizer.input_selector" 6 | local uniqueEventCount = 0 7 | 8 | return { 9 | apply_to_config = function(config) end, 10 | show = function(schema) 11 | local uniqueEventId = "sessionizer-show-" .. uniqueEventCount 12 | uniqueEventCount = uniqueEventCount + 1 13 | 14 | wezterm.on(uniqueEventId, function(window, pane) 15 | local entries = schema_processor.evaluate_schema(schema) 16 | local options = schema_processor.complete_schema(schema).options 17 | window:perform_action(input_selector.get_input_selector(options, entries), pane) 18 | end) 19 | return wezterm.action.EmitEvent(uniqueEventId) 20 | end, 21 | DefaultWorkspace = require "sessionizer.generators.default_workspace".DefaultWorkspace, 22 | AllActiveWorkspaces = require "sessionizer.generators.all_active_workspaces".AllActiveWorkspaces, 23 | FdSearch = require "sessionizer.generators.fd_search".FdSearch, 24 | 25 | for_each_entry = require "sessionizer.helpers".for_each_entry, 26 | DefaultCallback = require "sessionizer.schema_processor".DefaultCallback, -- NOTE: maybe relocate this 27 | } 28 | 29 | ---@alias Schema SchemaScope|(PrimitiveElement)[] 30 | 31 | ---@class SchemaScope 32 | ---@field options SchemaOptions 33 | ---@field processing (fun(schema: Entry[]): Entry[])[] 34 | ---@field [integer] Schema 35 | 36 | ---@class SchemaOptions 37 | ---@field title string 38 | ---@field prompt string 39 | ---@field always_fuzzy boolean 40 | ---@field callback fun(window, pane, id, label) 41 | 42 | ---@alias PrimitiveElement Entry|string 43 | 44 | ---@class Entry 45 | ---@field id string 46 | ---@field label string 47 | -------------------------------------------------------------------------------- /plugin/sessionizer/schema_processor.lua: -------------------------------------------------------------------------------- 1 | local helpers = require "sessionizer.helpers" 2 | 3 | local schema_processor = {} 4 | 5 | ---@param schema Schema 6 | ---@return Entry[] 7 | schema_processor.evaluate_schema = function(schema) 8 | schema = schema_processor.complete_schema(schema) -- PERF: this wastes a lot of resources filling in options for each schema 9 | local result = {} -- eventhough we only care about top level options 10 | 11 | for key, value in pairs(schema) do 12 | if key == "processing" or key == "options" then goto continue end 13 | 14 | if type(value) == "string" then -- string i.e. shorthand for entry 15 | helpers.append_each({ { label = value, id = value } }, result) 16 | elseif type(value) == "table" then 17 | if value.label and value.id then -- raw entry 18 | helpers.append_each({ value }, result) 19 | else -- has to be another schema 20 | helpers.append_each(schema_processor.evaluate_schema(value), result) 21 | end 22 | elseif type(value) == "function" then -- so it is a generator 23 | helpers.append_each(schema_processor.evaluate_schema(value()), result) 24 | end 25 | 26 | ::continue:: 27 | end 28 | 29 | for _, processor in ipairs(schema.processing) do 30 | processor(result) 31 | end 32 | 33 | return result 34 | end 35 | 36 | ---@param schema Schema 37 | ---@return Schema 38 | schema_processor.complete_schema = function(schema) 39 | if type(schema.processing) == "function" then schema.processing = { schema.processing } end 40 | 41 | local defaults = { 42 | options = { 43 | title = "Sessionizer", 44 | prompt = "Select entry: ", 45 | always_fuzzy = true, 46 | callback = schema_processor.DefaultCallback, 47 | }, 48 | 49 | processing = {}, 50 | } 51 | helpers.merge_tables(defaults, schema) 52 | schema = defaults 53 | return schema 54 | end 55 | 56 | schema_processor.DefaultCallback = function(window, pane, id, label) 57 | if not id then return end 58 | window:perform_action(require "wezterm".action.SwitchToWorkspace({ name = id, spawn = { cwd = id } }), pane) 59 | end 60 | 61 | return schema_processor 62 | -------------------------------------------------------------------------------- /plugin/sessionizer/generators/fd_search.lua: -------------------------------------------------------------------------------- 1 | local wezterm = require "wezterm" 2 | local helpers = require "sessionizer.helpers" 3 | 4 | local generator = {} 5 | 6 | local fd_path = nil 7 | local is_windows = wezterm.target_triple == "x86_64-pc-windows-msvc" 8 | 9 | ---@return string|nil 10 | local function get_fd_path_auto() 11 | local command = {} 12 | if is_windows then 13 | command[#command + 1] = "where.exe" 14 | else 15 | command[#command + 1] = "which" 16 | end 17 | command[#command + 1] = "fd" 18 | 19 | -- TODO: make error handling better (honestly for all run_child_process, I think they can panic) 20 | local success, stdout, stderr = wezterm.run_child_process(command) 21 | if not success then 22 | wezterm.log_error("sessionizer.wezterm: failed to run command to find fd binary; command: ", command) 23 | return 24 | end 25 | 26 | local cleansed = stdout:gsub("\n$", "") 27 | if is_windows then 28 | cleansed = cleansed:gsub("\r$", "") 29 | end 30 | return cleansed 31 | end 32 | 33 | local function normalize_options(opts) 34 | local default_options = { 35 | "no_path_specified", 36 | fd_path = fd_path, 37 | include_submodules = false, 38 | max_depth = 16, 39 | format = "{//}", 40 | exclude = { "node_modules" }, 41 | extra_args = {}, 42 | } 43 | 44 | if not opts.fd_path then 45 | default_options.fd_path = get_fd_path_auto() or "fd_not_found" 46 | end 47 | 48 | helpers.merge_tables(default_options, opts) 49 | return default_options 50 | end 51 | 52 | local function get_command(opts) 53 | local command = { 54 | opts.fd_path, 55 | "-Hs", 56 | "^.git$", 57 | "-td", 58 | "--max-depth=" .. opts.max_depth, 59 | "--prune", 60 | "--format", 61 | opts.format, 62 | } 63 | if opts.include_submodules then 64 | command[#command + 1] = "-tf" 65 | end 66 | for _, v in ipairs(opts.exclude) do 67 | command[#command + 1] = "-E" 68 | command[#command + 1] = v 69 | end 70 | 71 | command[#command + 1] = opts[1] 72 | 73 | for _, v in ipairs(opts.extra_args) do 74 | command[#command + 1] = v 75 | end 76 | 77 | return command 78 | end 79 | 80 | local function get_results(command) 81 | local result = {} 82 | 83 | ---@type boolean, string?, string? 84 | local success, stdout, stderr = wezterm.run_child_process(command) 85 | if not success then 86 | wezterm.log_error("Command failed: ", command) 87 | wezterm.log_error("stderr: ", stderr) 88 | return {} 89 | end 90 | 91 | if not stdout then 92 | wezterm.log_warn("stdout was nil in command: ", command) 93 | return {} 94 | end 95 | 96 | for line in stdout:gmatch "[^\n]+" do 97 | local entry = { label = line, id = line } 98 | table.insert(result, entry) 99 | end 100 | 101 | return result 102 | end 103 | 104 | 105 | local function find(opts) 106 | if type(opts) == "string" then 107 | opts = { opts } 108 | end 109 | 110 | local normalized_options = normalize_options(opts) 111 | local command = get_command(normalized_options) 112 | 113 | return get_results(command) 114 | end 115 | 116 | generator.FdSearch = function(opts) 117 | return function() 118 | local entries = find(opts) 119 | return entries 120 | end 121 | end 122 | 123 | 124 | return generator 125 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sessionizer.wezterm 2 | 3 | A flexible sessionizer for WezTerm allowing you to define custom menus to switch workspaces, open projects, or trigger other actions. It was originally inspired by [ThePrimeagen's tmux-sessionizer](https://github.com/theprimeagen/tmux-sessionizer). 4 | 5 | > [!NOTE] 6 | > If you're using the old version of this plugin you might want to read the sections below and/or have a look at the migration example down below under [Advanced Examples](#advanced-examples). If you need the old version now it is available under https://github.com/mikkasendke/sessionizer-legacy and replace the url of `wezterm.plugin.require`. 7 | 8 | https://github.com/user-attachments/assets/e99b29ec-39f4-4066-8aca-b89fdae3994c 9 | 10 | ## Installation 11 | 12 | #### 1. Install Dependencies (Optional but recommended) 13 | Install [`fd`](https://github.com/sharkdp/fd): Only needed if you want to use the `FdSearch` _generator_ (This is usually used to get the paths to git repositories). 14 | 15 | #### 2. Add to WezTerm Config 16 | Add the following to your `wezterm.lua` file: 17 | 18 | ```lua 19 | local sessionizer = wezterm.plugin.require "https://github.com/mikkasendke/sessionizer.wezterm" 20 | ``` 21 | 22 | #### 3. Define a _Schema_ 23 | Create a table (called a Schema) defining the menu you want to see: 24 | 25 | ```lua 26 | local my_schema = { 27 | { label = "Some project", id = "~/dev/project" }, -- Custom entry, label is what you see. By default id is used as the path for a workspace. 28 | "Workspace 1", -- Simple string entry, expands to { label = "Workspace 1", id = "Workspace 1" } 29 | sessionizer.DefaultWorkspace {}, 30 | sessionizer.AllActiveWorkspaces {}, 31 | sessionizer.FdSearch "~/my_projects", -- Searches for git repos in ~/my_projects 32 | } 33 | ``` 34 | 35 | #### 4. Add a Keybinding 36 | Insert something like this into your config.keys table: 37 | ```lua 38 | config.keys = { 39 | { key = "S", mods = "ALT", action = sessionizer.show(my_schema) }, 40 | -- ... other keybindings ... 41 | } 42 | ``` 43 | 44 | See [Advanced Examples](#advanced-examples) for more complex use cases. 45 | 46 | ## Understanding Schemas 47 | 48 | A schema is a Lua table that defines what appears in your sessionizer menu and how it behaves. It tells the plugin what to display and what to do when an entry was selected. 49 | 50 | A schema can contain the following elements: 51 | 52 | 1. **`options` (Table, Optional):** Controls the appearance and behavior of the menu. These are its fields: 53 | 54 | | Name | Type | Default | Description | 55 | | -------------- | --------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | 56 | | `title` | `string` | `"Sessionizer"` | The **window** title when the sessionizer is open. | 57 | | `prompt` | `string` | `"Select entry: "` | The prompt text shown in the input area. | 58 | | `always_fuzzy` | `boolean` | `true` | Whether to enable fuzzy finding always or only after typing /. | 59 | | `callback` | `function`| `sessionizer.DefaultCallback` | Function called when an entry is selected. Signature: `function(window, pane, id, label)`. Default switches to workspace `id` and creates one in the directory `id` if it does not already exist. | 60 | 61 | 2. **Entries (Array Elements):** Define the items that appear in the menu. These can be a mix of: 62 | * **String:** Shorthand for `{ label = value, id = value }`. 63 | ```lua 64 | "My Workspace" 65 | ``` 66 | * **Table (Entry):** A table with `label` and `id` fields. 67 | ```lua 68 | { label = "WezTerm Config", id = "~/.config/wezterm" } 69 | ``` 70 | * **Table (Schema):** Another schema table can be nested inside and its entries will be included (its `options` will be ignored though). 71 | * **Function (Generator):** A function that returns a Schema. For example: 72 | ```lua 73 | function exampleGenerator() 74 | local schema = {} 75 | for i=1,10 do 76 | table.insert(schema, { label = "Workspace " .. i, id = "this is workspace " .. i }) 77 | end 78 | return schema 79 | end 80 | -- or this: 81 | -- sessionizer.AllActiveWorkspaces is a function that returns a generator, 82 | -- it's useful to provide some options. 83 | sessionizer.AllActiveWorkspaces { filter_default = true } 84 | ``` 85 | See [Built-in Generators](#built-in-generators) for some built-in generators and see [List of plugins that provide features 86 | ](#list-of-plugins-that-provide-features) for other plugins that provide generators or integrate in another way. 87 | 88 | 3. **`processing` (Table | Function, Optional):** Function(s) to modify entries before they are used/displayed. 89 | * Can be a function or table of functions. 90 | * Each function modifies the `entries` array in-place. 91 | * Useful for styling, filtering, or formatting entries. 92 | * Example using the helper: 93 | ```lua 94 | -- prepends 📁 to each entry 95 | processing = sessionizer.for_each_entry(function(entry) 96 | entry.label = "📁 " .. entry.label 97 | end) 98 | 99 | -- or: 100 | processing = { 101 | sessionizer.for_each_entry(function(entry) -- recolors labels and replaces the absolute path to the home directory with ~ 102 | entry.label = wezterm.format { 103 | { Foreground = { Color = "#cc99ff" } }, 104 | { Text = entry.label:gsub(wezterm.home_dir, "~") }, 105 | } 106 | end), 107 | sessionizer.for_each_entry(function(entry) -- same as above 108 | entry.label = "📁 " .. entry.label 109 | end) 110 | } 111 | ``` 112 | See [Processing Entries](#processing-entries) for more info. 113 | ## Built-in Generators 114 | 115 | Generators create entries dynamically each time you open the sessionizer. They provide up-to-date lists of choices like current workspaces or project folders. 116 | Some commonly used ones are already built-in via functions that return a generator when passed options, we can call them generator factories. 117 | 118 | ### `sessionizer.DefaultWorkspace(opts)` 119 | Creates an entry for your default or home workspace. 120 | 121 | - **Options:** `{ label_overwrite, id_overwrite }` 122 | - `label_overwrite` (string): Custom label for the entry (default: `"Default"`). 123 | - `id_overwrite` (string): Custom id for the entry (default: `"default"`). 124 | 125 | _Example usage:_ 126 | ```lua 127 | sessionizer.DefaultWorkspace { label_overwrite = "🏠 Home", id_overwrite = "home_ws" } 128 | -- The id typically matches config.default_workspace in your wezterm config 129 | ``` 130 | 131 | ### `sessionizer.AllActiveWorkspaces(opts)` 132 | Lists all currently active WezTerm workspaces. 133 | 134 | - **Options:** `{ filter_default, filter_current }` 135 | - `filter_default` (boolean): Exclude the "default" workspace (default: `true`). 136 | - `filter_current` (boolean): Exclude the currently active workspace (default: `true`). 137 | 138 | _Example usage:_ 139 | ```lua 140 | sessionizer.AllActiveWorkspaces {} -- Use defaults 141 | sessionizer.AllActiveWorkspaces { filter_default = false } -- Include "default" 142 | ``` 143 | 144 | ### `sessionizer.FdSearch(opts | path_string)` 145 | Searches for directories (like projects) using `fd`. Requires the `fd` binary to be installed. 146 | 147 | - **Options:** Either a string (the path to search) or a table for advanced options. 148 | - As a string: The search path. 149 | - As a table: 150 | - `[1]` (string, required): The base path to search within. 151 | - `fd_path` (string): Path to the `fd` binary (auto-detected if omitted, use it for troubleshooting). 152 | - `include_submodules` (boolean): Search git submodules too (default: `false`). 153 | - `max_depth` (number): Maximum search depth (default: `16`). 154 | - `format` (string): fd output format (default: `{//}`). 155 | - `exclude` (table): List of patterns to exclude (default: `{ "node_modules" }`). 156 | - `extra_args` (table): Additional raw arguments for `fd`. 157 | 158 | _Example usage:_ 159 | ```lua 160 | sessionizer.FdSearch(wezterm.home_dir .. "/dev") -- Simple path string 161 | sessionizer.FdSearch { -- Advanced options 162 | wezterm.home_dir .. "/projects", 163 | max_depth = 32, 164 | include_submodules = true, 165 | exclude = { "target" }, 166 | } 167 | ``` 168 | 169 | ## Processing Entries 170 | 171 | Use the `processing` key to modify entries after generation but before display. This is useful for formatting, filtering, or sorting entries. 172 | 173 | Example of shortening home directory paths: 174 | 175 | ```lua 176 | local my_schema = { 177 | sessionizer.FdSearch(wezterm.home_dir .. "/dev"), 178 | 179 | -- Make paths more readable by replacing home directory with ~ 180 | processing = sessionizer.for_each_entry(function(entry) 181 | entry.label = entry.label:gsub(wezterm.home_dir, "~") 182 | end) 183 | } 184 | ``` 185 | 186 | You can also use multiple processing functions: 187 | 188 | ```lua 189 | processing = { 190 | -- First processor: Shorten paths 191 | sessionizer.for_each_entry(function(entry) 192 | entry.label = entry.label:gsub(wezterm.home_dir, "~") 193 | end), 194 | 195 | -- Second processor: Add icons to entries 196 | sessionizer.for_each_entry(function(entry) 197 | entry.label = "📁 " .. entry.label 198 | end) 199 | } 200 | ``` 201 | 202 | ## Advanced Examples 203 | 204 | 1. How I use it: 205 | ```lua 206 | local sessionizer = wezterm.plugin.require "https://github.com/mikkasendke/sessionizer.wezterm" 207 | local history = wezterm.plugin.require "https://github.com/mikkasendke/sessionizer-history" 208 | 209 | local schema = { 210 | options = { callback = history.Wrapper(sessionizer.DefaultCallback) }, 211 | sessionizer.DefaultWorkspace {}, 212 | history.MostRecentWorkspace {}, 213 | 214 | wezterm.home_dir .. "/dev", 215 | wezterm.home_dir .. "/.nixos-config", 216 | wezterm.home_dir .. "/.config/wezterm", 217 | wezterm.home_dir .. "/.config/nvim", 218 | wezterm.home_dir .. "/.config/sway", 219 | wezterm.home_dir .. "/.config/waybar", 220 | wezterm.home_dir .. "/.config/ags", 221 | wezterm.home_dir .. "/Uni", 222 | 223 | sessionizer.FdSearch(wezterm.home_dir .. "/dev"), 224 | sessionizer.FdSearch(wezterm.home_dir .. "/Uni"), 225 | 226 | processing = sessionizer.for_each_entry(function(entry) 227 | entry.label = entry.label:gsub(wezterm.home_dir, "~") 228 | end) 229 | } 230 | 231 | table.insert(config.keys, { 232 | key = "s", 233 | mods = "ALT", 234 | action = sessionizer.show(schema) 235 | }) 236 | table.insert(config.keys, { 237 | key = "m", 238 | mods = "ALT", 239 | action = history.switch_to_most_recent_workspace 240 | }) 241 | ``` 242 | 2. A replica of [smart_workspace_switcher.wezterm](https://github.com/MLFlexer/smart_workspace_switcher.wezterm): 243 | ```lua 244 | local history = wezterm.plugin.require "https://github.com/mikkasendke/sessionizer-history.git" 245 | 246 | local smart_workspace_switcher_replica = { 247 | options = { 248 | prompt = "Workspace to switch: ", 249 | callback = history.Wrapper(sessionizer.DefaultCallback) 250 | }, 251 | { 252 | sessionizer.AllActiveWorkspaces { filter_current = false, filter_default = false }, 253 | processing = sessionizer.for_each_entry(function(entry) 254 | entry.label = wezterm.format { 255 | { Text = "󱂬 : " .. entry.label }, 256 | } 257 | end) 258 | }, 259 | wezterm.plugin.require "https://github.com/mikkasendke/sessionizer-zoxide.git".Zoxide {}, 260 | processing = sessionizer.for_each_entry(function(entry) 261 | entry.label = entry.label:gsub(wezterm.home_dir, "~") 262 | end), 263 | } 264 | 265 | table.insert(config.keys, { 266 | key = "e", 267 | mods = "ALT", 268 | action = sessionizer.show(smart_workspace_switcher_replica) 269 | }) 270 | table.insert(config.keys, { 271 | key = "m", 272 | mods = "ALT", 273 | action = history.switch_to_most_recent_workspace 274 | }) 275 | ``` 276 | 3. Migrating a legacy config: 277 | Here is an example of a config in the old style and what it turns into: 278 | Old: 279 | ```lua 280 | local sessionizer = wezterm.plugin.require "https://github.com/mikkasendke/sessionizer.wezterm" 281 | sessionizer.apply_to_config(config) -- this is not needed anymore (no default binds) 282 | local home_dir = wezterm.home_dir 283 | local config_path = home_dir .. ("/.config") 284 | sessionizer.config.paths = { -- for these you will want a sessionizer.FdSearch for each of the paths 285 | home_dir .. "/dev", 286 | home_dir .. "/other" 287 | } 288 | sessionizer.config.title = "My title" -- this moves to the options field 289 | sessionizer.config.fuzzy = false -- in options field now renamed to always_fuzzy 290 | sessionizer.config.show_additional_before_paths = true -- not needed as order matters in a schema table 291 | command_options = { include_submodules = true } -- these options can now be passed to sessionizer.FdSearch individually 292 | sessionizer.config.additional_directories = { -- these can be put in the schema by themselves 293 | config_path .. "/wezterm", 294 | config_path .. "/nvim", 295 | config_path, 296 | home_dir .. "/.nixos-config", 297 | home_dir .. "/dev", 298 | } 299 | ``` 300 | Migrated version: 301 | ```lua 302 | local sessionizer = wezterm.plugin.require "https://github.com/mikkasendke/sessionizer.wezterm" 303 | local history = wezterm.plugin.require "https://github.com/mikkasendke/sessionizer-history.git" -- the most recent functionality moved to another plugin 304 | 305 | local home_dir = wezterm.home_dir 306 | local config_path = home_dir .. ("/.config") 307 | 308 | local schema = { 309 | options = { 310 | title = "My title", 311 | always_fuzzy = false, 312 | callback = history.Wrapper(sessionizer.DefaultCallback), -- tell history that we changed to another workspace 313 | }, 314 | config_path .. "/wezterm", 315 | config_path .. "/nvim", 316 | config_path, 317 | home_dir .. "/.nixos-config", 318 | home_dir .. "/dev", 319 | sessionizer.FdSearch { home_dir .. "/dev", include_submodules = true }, 320 | sessionizer.FdSearch { home_dir .. "/other", include_submodules = true }, 321 | } 322 | -- Now you need to call sessionizer.show with this schema on a keypress yourself. 323 | -- you could for example do: 324 | config.keys = { 325 | { key = "s", mods = "ALT", action = sessionizer.show(schema) }, 326 | { key = "m", mods = "ALT", action = history.switch_to_most_recent_workspace }, 327 | } 328 | ``` 329 | 330 | ## List of plugins that provide features 331 | 332 | * [sessionizer-history](https://github.com/mikkasendke/sessionizer-history): provides a generator and callback wrapper for getting the most recent workspace 333 | * [sessionizer-zoxide](https://github.com/mikkasendke/sessionizer-zoxide): provides a generator for results from zoxide 334 | 335 | _Feel free to make a pr if you have another plugin that integrates with sessionizer.wezterm._ 336 | 337 | ## Contributing 338 | 339 | Contributions, issues, and pull requests are welcome! 340 | Especially now with the new version released any issue reports are very welcome :) 341 | --------------------------------------------------------------------------------