Two plugins for the Terminator terminal emulator (GTK3 / VTE 2.91 / Python 3):
scrollback_tools.py— select, copy, save, and sanitize retained VTE scrollback.pane_color_menu.py— temporary per-pane background + header colouring, with presets.
git clone https://github.com/cheddarsunrae/terminator_toolkit.git
cd terminator_toolkit
./install.shThis copies both plugins into ~/.config/terminator/plugins, backing up any
existing files of the same name first. For a system-wide install (all users):
./install.sh --systemThen:
- Restart Terminator (fully quit and relaunch).
- Right-click a pane → Preferences → Plugins.
- Enable:
SelectAllScrollback,CopyAllScrollback,SaveScrollback,CopySanitized,PaneColorMenu.
To remove:
./uninstall.sh # or --system, matching how you installedEach of these four actions is a separate plugin (its own checkbox in Preferences → Plugins), appearing in the pane right-click menu:
| Menu item | What it does |
|---|---|
| Select All Scrollback | Selects everything VTE has retained in the active pane. |
| Copy All Scrollback | Copies the whole retained buffer (history + screen) to the desktop clipboard. |
| Save Scrollback… | Saves the buffer as a timestamped UTF-8 file (terminator-scrollback-YYYYMMDD-HHMMSS.txt) via a save dialog. |
| Copy All, Sanitized | Copies a cleaned copy: strips ANSI escapes, normalizes newlines to \n, trims trailing whitespace, collapses blank-line runs, and redacts obvious secrets. |
How the buffer is read. The primary path is Vte.Terminal.write_contents_sync()
— a purpose-built VTE call that dumps the terminal's current contents
(including scrollback) directly to a stream, with no row/column
coordinates involved at all. An earlier version of this plugin computed a
row range from the vertical scroll adjustment and called
get_text_range_format() directly; on some VTE builds that adjustment
reports pixels rather than rows (the scroll-unit-is-pixels property,
changed in VTE 0.76), which could silently produce a technically-valid but
empty range — pasting as the right number of blank lines with none of the
actual content. write_contents_sync sidesteps that whole class of bug by
letting VTE itself decide what "the whole buffer" means.
get_text_range_format / get_text_range remain only as a fallback for VTE
builds that predate write_contents_sync, with the visible screen as the
last resort if nothing else is available.
If extraction ever comes back empty, Copy/Sanitize now shows an error dialog rather than silently putting nothing on the clipboard.
How much is retained is governed by your profile's Scrollback lines setting (Preferences → Profiles → Scrolling). These plugins can only see what VTE still holds.
Copy All, Sanitized redacts:
- PEM private-key blocks (
-----BEGIN … PRIVATE KEY----- … -----END … PRIVATE KEY-----). - Secret-looking assignments:
KEY=value/KEY: valuewhere the key contains words likepassword,passwd,secret,token,api_key,access_key,secret_key,private_key,client_secret,passphrase,auth_token,credential(case-insensitive,exportprefix allowed). The key name is kept; only the value becomes***REDACTED***. Bearer <token>values.- AWS access-key IDs (
AKIA…).
This is a best-effort convenience filter, not a security guarantee. It only catches these common shapes — always eyeball the result before sharing. To add patterns, edit the regexes near the top of
plugins/scrollback_tools.py(_SECRET_ASSIGN_RE, plus the_BEARER_RE/_AWS_AKIA_REextras).
Enable PaneColorMenu, then right-click inside a pane and choose
Set Pane Colour.
| Preset | Suggested use | Background | Text | Contrast |
|---|---|---|---|---|
| Red | Production / Root | #592222 |
#EEDDDD |
9.6:1 |
| Amber | Staging | #594222 |
#EEE7DD |
7.7:1 |
| Green | Development | #22593D |
#DDEEE6 |
6.8:1 |
| Blue | Local | #223D59 |
#DDE6EE |
8.9:1 |
| Purple | Monitoring | #462259 |
#E8DDEE |
9.8:1 |
| Slate | Neutral | #35383B |
#E5E6E6 |
9.4:1 |
Each built-in is a curated (background, text) pair, not a background with
auto black/white text. A saturated background against pure #000000 /
#FFFFFF is exactly the harsh, eye-straining combo this started with; these
use desaturated, moderately dark backgrounds with soft tinted near-white text
(closer to Nord/Gruvbox/Solarized-style terminal themes) and all clear WCAG
AA body-text contrast (≥ 4.5:1) with real margin.
- Custom… opens a dialog with two colour pickers — background and text — side by side, so you can freely mix and match. There's also an "Auto-pick a readable text colour" checkbox for when you just want a background and don't want to think about contrast (it uses a soft near-black/near-white, not harsh pure black/white, based on a luminance check on the background).
- Save Current as Preset… stores the background and text colour you last applied as a named preset, written into the Terminator config under the plugin's own section. It appears in the menu the next time you open it.
- Reset to Profile restores the pane's titlebar config and calls
Terminator's own
reconfigure()to reapply the active profile's colours, palette, and background.
Pane colours are deliberately temporary and per-pane: they do not modify the shared Terminator profile and do not survive closing or recreating the pane.
Terminator owns the VTE colours. It stores them as attributes on each pane
(bgcolor, fgcolor_active, fgcolor_inactive, bgcolor_inactive,
palette_active/palette_inactive) and re-applies them with
vte.set_colors() on every focus change — that's the unfocused-dimming
feature. Its focus handlers are, essentially:
def on_vte_focus_in(self, ...):
self.vte.set_colors(self.fgcolor_active, self.bgcolor, self.palette_active)
def on_vte_focus_out(self, ...):
self.vte.set_colors(self.fgcolor_inactive, self.bgcolor_inactive, self.palette_inactive)A naive vte.set_color_background(...) call is wiped the instant the
right-click menu closes and focus returns to the pane. PaneColorMenu
instead writes those same attributes and calls set_colors() the way
Terminator does, so the colour survives focus changes.
For the header, Titlebar.update() only runs its colouring code when called
with a terminal argument (update(other)); calling update() with no
argument only refreshes the label text and font. So the plugin overrides the
titlebar's title_*_color config keys (per-pane, via a proxy that never
mutates the shared profile) and calls titlebar.update(terminal) — the same
path Terminator uses to paint its own red/blue/grey titlebars.
If a colour operation ever fails, the plugin shows a dialog with the Python traceback rather than doing nothing silently.
Saved presets live in ~/.config/terminator/config under
[plugins] → [[PaneColorMenu]], one nested block per preset:
[plugins]
[[PaneColorMenu]]
[[[preset_ops]]]
name = Ops
bg = #123456
fg = #DCE6F0Edit or delete those blocks to rename/recolour/remove a saved preset, or edit
the BUILTIN_PRESETS list at the top of plugins/pane_color_menu.py to
change the built-in defaults (each entry is (key, label, bg_hex, fg_hex)).
Restart Terminator to pick up changes.
Presets saved by an earlier version of this plugin (with only a color key
and no fg) still load fine — they fall back to auto-picked text colour.
Set Pane Colourchanges the default fg/bg only; the 16-colour ANSI palette stays from your profile, so coloured program output still renders normally.
Targets Terminator 2.x on GTK3 with VTE 2.91. The scrollback-extraction path
degrades gracefully across VTE 0.68 → 0.80+. If the right-click menu ever
fails to appear after installing, launch terminator -d from another
terminal to see the Python traceback — the fastest way to spot a
version-specific API difference.
terminator_toolkit/
├── install.sh # installer (user or --system)
├── uninstall.sh # uninstaller (user or --system)
├── plugins/
│ ├── scrollback_tools.py
│ └── pane_color_menu.py
├── LICENSE
└── README.md
MIT — see LICENSE.