WezTerm Pinned Tabs Plugin

August 16, 2025 ยท View on GitHub

A WezTerm plugin that lets you assign a key binding to a tab. A pinned tab can be opened in the specific directory or can optionally run a program.

Once pinned, the same key binding will always switch to that tab until you close it.

Install

Install the plugin by adding this to your wezterm.lua

    local pinned_tabs = wezterm.plugin.require "https://github.com/selectnull/pinned-tabs.wezterm"

This will install the plugin, but by itself it does nothing. It needs to be configured to become useful.

Configure

    -- Clean up pinned_tabs stale state files on startup.
    -- This is optional, you don't have to call cleanup
    -- if you don't mind a few small files in local state directory
    wezterm.on("gui-startup", function()
      pinned_tabs.cleanup()
    end)

    local pinned_tabs_config = {
      cleanup = true, -- instead of WezTerm startup, you can do the cleanup on config reload
      debug = false, -- you don't want any debug logs (errors will still be logged)
      keys = {
        {
          key = "h",
          mods = "CMD|ALT",
          tab = { program = "/opt/homebrew/bin/htop" }
        },
        {
          key = "e",
          mods = "CMD",
          tab = { name = "editor", cwd = "~/work/" }
        }
      }
    })

    pinned_tabs.apply_to_config(config, pinned_tabs_config)

A table passed in to a tab field has these keys:

    
    {
        name: string,
        cwd: string
        program: string,
        args: string[]
    }

All fields are optional, except either a program or a name must be defined. name is used as a filename to save a state file and if undefined, program is used instead. args is a table of string arguments to pass to a program.

You may choose to configure the keys in a different way.


    local config = wezterm.config_builder()
    -- you might already have this in you config or your config object is plain old lua table
    -- either way, the rest of the setup is the same

    local keys = {
      -- your other key bindings go here
      -- ,
      {
        key = "h",
        mods = "CMD|ALT",
        action = wezterm.action_callback(function(window, pane)
          pinned_tabs.create { program = "/opt/homebrew/bin/htop" }
        end),
      },
      {
        key = "e",
        mods = "CMD",
        action = wezterm.action_callback(function(window, pane)
          pinned_tabs.create { name = "editor", cwd = "~/work/" }
        end),
      }
    }

    config.keys = keys

By configuring it this way, calling apply_to_config is optional.

These are just examples, configure the key bindings to suit your needs and workflow.

Notes

I've tested this on MacOS only. It should work on Linux as is, but Windows might have some bugs. PRs are welcomed.

License

MIT.