{"id":50982658,"url":"https://github.com/annie444/sync-panes.wez","last_synced_at":"2026-07-07T14:00:31.820Z","repository":{"id":362546133,"uuid":"1259637515","full_name":"annie444/sync-panes.wez","owner":"annie444","description":"A WezTerm plugin that mirrors your keystrokes to every pane in the active tab — the equivalent of tmux's synchronize-panes.","archived":false,"fork":false,"pushed_at":"2026-06-23T06:16:05.000Z","size":46,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-23T08:13:38.513Z","etag":null,"topics":["keybindings","multiplexing","wezterm","wezterm-plugin"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/annie444.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-04T17:53:31.000Z","updated_at":"2026-06-23T06:15:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/annie444/sync-panes.wez","commit_stats":null,"previous_names":["annie444/sync-panes.wez"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/annie444/sync-panes.wez","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/annie444%2Fsync-panes.wez","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/annie444%2Fsync-panes.wez/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/annie444%2Fsync-panes.wez/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/annie444%2Fsync-panes.wez/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/annie444","download_url":"https://codeload.github.com/annie444/sync-panes.wez/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/annie444%2Fsync-panes.wez/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35230519,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-07T02:00:07.222Z","response_time":90,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["keybindings","multiplexing","wezterm","wezterm-plugin"],"created_at":"2026-06-19T16:00:28.624Z","updated_at":"2026-07-07T14:00:31.752Z","avatar_url":"https://github.com/annie444.png","language":"Lua","funding_links":[],"categories":["Keybinding"],"sub_categories":[],"readme":"# sync-panes.wez\n\nA [WezTerm](https://wezterm.org/) plugin that mirrors your keystrokes to **every\npane in the active tab** — the equivalent of tmux's `synchronize-panes`. Toggle\nit on, type once, and the same input lands in all panes at the same time.\n\n## Features\n\n- **One-key toggle** — turn synchronization on/off per GUI window (default\n  `CTRL+SHIFT+E`).\n- **Status indicator** — an optional `⟳ SYNC` badge in the right status bar\n  while sync is active.\n- **Border highlight** — optionally recolor the window border _and_ pane split\n  lines while sync is active for a second, hard-to-miss visual cue.\n- **Broadcasts everything you'd expect** — printable characters, `Ctrl`/`Alt`\n  combinations, `Enter`/`Tab`/`Backspace`/`Escape`, arrow \u0026 navigation keys, and\n  `F1`–`F12`.\n- **Survives config reloads** — enabled state is stored in `wezterm.GLOBAL`, so\n  reloading your config won't drop you out of sync mode.\n- **Configurable** — change the toggle key, key-table name, indicator text and\n  color, the border highlight color, and the Backspace byte.\n\n## Requirements\n\nA recent version of WezTerm — any build that includes the `wezterm.plugin` API.\n\n## Installation\n\nWezTerm plugins are loaded straight from a git URL. Add this to your\n`wezterm.lua`:\n\n```lua\nlocal sync = wezterm.plugin.require(\"https://github.com/annie444/sync-panes.wez\")\n```\n\nWezTerm clones and caches the plugin automatically on next launch.\n\n## Quick start\n\n```lua\nlocal wezterm = require(\"wezterm\")\nlocal config = wezterm.config_builder()\n\nlocal sync = wezterm.plugin.require(\"https://github.com/annie444/sync-panes.wez\")\nsync.apply_to_config(config)\n\nreturn config\n```\n\nThat's it. Press **`CTRL+SHIFT+E`** to toggle synchronization for the current\nwindow. While it's on, the `⟳ SYNC` indicator appears at the right of the status\nbar and every key you type is sent to all panes in the tab.\n\n## Configuration\n\nPass an options table as the second argument to `apply_to_config`. Every field\nis optional and falls back to the default below.\n\n| Option            | Default         | Description                                                                                   |\n| ----------------- | --------------- | --------------------------------------------------------------------------------------------- |\n| `key_table_name`  | `\"sync_mode\"`   | Name of the key table the plugin generates.                                                   |\n| `toggle_key`      | `\"E\"`           | Key that toggles synchronization.                                                             |\n| `toggle_mods`     | `\"CTRL\\|SHIFT\"` | Modifiers for the toggle key. Must not collide with a mirrored key (see [Caveats](#caveats)). |\n| `indicator`       | `false`         | Show the right-status indicator while sync is active. Set `false` to manage it yourself.      |\n| `status_text`     | `\"⟳ SYNC\"`      | Text shown in the indicator.                                                                  |\n| `indicator_color` | `\"Red\"`         | Color for the indicator text (ANSI color name or `#rrggbb` hex).                              |\n| `border`          | `false`         | Recolor the window border and pane splits while sync is active. Set `true` to enable.         |\n| `border_color`    | `\"Red\"`         | Color for the border and pane splits while sync is active (used when `border = true`).        |\n| `backspace`       | `\"\\127\"`        | Byte(s) sent for Backspace. `0x7f` (DEL) is the common default; use `\"\\8\"` for `^H`.          |\n\n### Example\n\n```lua\nsync.apply_to_config(config, {\n  toggle_key = \"S\",\n  toggle_mods = \"CTRL|SHIFT\",\n  status_text = \"BROADCAST\",\n  indicator = true,\n  indicator_color = \"Yellow\",\n  border = true,\n  border_color = \"Yellow\",\n})\n```\n\n## Usage\n\n- Press the toggle key (default `CTRL+SHIFT+E`) to start or stop synchronizing.\n- Synchronization is **per GUI window** — toggling one window doesn't affect\n  another.\n- While active, anything you type is sent to every pane in the active tab,\n  including the pane you're typing in (so there's no double input).\n- Control sequences are broadcast too: pressing **`Ctrl+C`** while synced sends\n  an interrupt to _all_ panes at once.\n\n## Integrating with tabline\n\nIf you use [`tabline.wez`](https://github.com/michaelbrusegard/tabline.wez), you\ncan show the sync state in tabline's status bar instead of the plugin's own\nright-status indicator — no extra wiring required. tabline's built-in `mode`\ncomponent reads the active WezTerm key table, and this plugin's table is named\n`sync_mode`, so while sync is active the `mode` cell automatically displays\n**`SYNC`**.\n\n1. **Turn off the built-in indicator** so the two don't double up:\n\n   ```lua\n   sync.apply_to_config(config, { indicator = false })\n   ```\n\n2. **Add `'mode'` to a tabline section** (skip if it's already there):\n\n   ```lua\n   tabline.setup({\n     sections = { tabline_a = { 'mode' } },\n   })\n   ```\n\n3. **Color it** with tabline `theme_overrides`, keyed by the table name:\n\n   ```lua\n   tabline.setup({\n     options = {\n       theme_overrides = {\n         sync_mode = {\n           a = { fg = '#1e1e2e', bg = '#f38ba8' },\n           b = { fg = '#f38ba8', bg = '#313244' },\n           c = { fg = '#cdd6f4', bg = '#1e1e2e' },\n         },\n       },\n     },\n     sections = { tabline_a = { 'mode' } },\n   })\n   ```\n\n### Notes\n\n- **The table name must end in `_mode`.** tabline only treats a key table as a\n  \"mode\" when its name ends in `_mode`; otherwise the cell shows `NORMAL`. The\n  default `sync_mode` → `SYNC`. To change the label, rename the table while\n  keeping the suffix (e.g. `key_table_name = \"broadcast_mode\"` → `BROADCAST`) and\n  match the `theme_overrides` key to it.\n- **`status_text` and `indicator_color` don't apply here.** Those style the\n  plugin's own right-status indicator only — the tabline label comes from the key\n  table name and tabline's theme.\n\n## API\n\n`apply_to_config` is all most setups need, but the plugin also exposes helpers\nfor custom integrations.\n\n### `sync.apply_to_config(config, opts?)`\n\nRegisters the key table and binds the toggle key. Returns the modified `config`.\n\n### `sync.is_synced(window)`\n\nReturns `true` if synchronization is currently enabled for the given GUI window.\nUseful for composing your own status bar when you set `indicator = false`:\n\n```lua\nsync.apply_to_config(config, { indicator = false })\n\nwezterm.on(\"update-status\", function(window, _)\n  if sync.is_synced(window) then\n    window:set_right_status(\" SYNC \")\n  else\n    window:set_right_status(\"\")\n  end\nend)\n```\n\n### `sync.toggle`\n\nThe toggle action itself. Bind it to an additional key if you'd like more than\none way to switch sync on and off:\n\n```lua\ntable.insert(config.keys, {\n  key = \"F5\",\n  action = sync.toggle,\n})\n```\n\n## Caveats\n\n- **Toggle key must not be a mirrored key.** The key that toggles sync has to\n  fall _through_ the active key table rather than being broadcast. `CTRL|SHIFT`\n  combinations are never mirrored, which is why the default `CTRL+SHIFT+E` works.\n  If you pick a different combination, make sure it isn't one of the broadcast\n  keys.\n- **Arrow keys use normal cursor mode.** Navigation keys are sent as\n  _normal_-mode (not application-mode) cursor sequences. Full-screen TUIs that\n  switch the terminal into application cursor mode may receive different bytes\n  than they expect for the arrow keys.\n- **Backspace defaults to DEL (`0x7f`).** This matches the behavior of the latest\n  WezTerm release. If you're running an older version, set `backspace = \"\\8\"`.\n\n## License\n\n[MIT](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fannie444%2Fsync-panes.wez","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fannie444%2Fsync-panes.wez","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fannie444%2Fsync-panes.wez/lists"}