Skip to content

Embedded Terminal tool window (JetBrains-style), rooted at the workspace folder #5

Description

@dG9hc3Q

Summary

Add an embedded Terminal tool window, like JetBrains' terminal: a
bottom-docked panel running a real interactive shell rooted at the current
workspace folder, so the writer can run git, scripts, file ops etc.
without leaving Rhymr.

Motivation

Rhymr is aiming to be a "JetBrains-capable IDE" for lyrics; an integrated
terminal is table stakes for that workflow. It also complements the VCS
work (gutter, branch status, Git Log #3) — quick git / shell access in the
project context.

Behaviour (target)

  • Bottom-docked tool window, same mechanism as Rhyme Search / Git Log —
    registers as a ToolWindow in the dock manager (Rearrangeable tool-window layout: dock/move/resize/float like a JetBrains IDE #4) so it can be
    toggled, resized, moved and (eventually) floated.
  • Toggled from the bottom stripe + an app.terminal gio action/accel
    (JetBrains uses Alt+F12) + a menu entry.
  • CWD = workspace root. Uses the shared root path from
    WorkspaceController; when there's no open project, falls back to the
    user's home dir. Opening / switching projects starts (or offers to
    restart) the shell in the new root — mirror how the status-bar branch
    segment and file tree react to a root change.
  • Real interactive PTY: full-screen curses apps (vim, htop, git log
    pager), colour, resize/SIGWINCH, Ctrl-C etc. all work.
  • Multiple terminal tabs within the panel, each independently
    rooted at the workspace; a "+" to open another, close on tab close or
    shell exit.
  • Shell selection: Settings override, else $SHELL on macOS / %ComSpec%
    (or PowerShell) on Windows.
  • Copy/paste, select, scrollback, clear; font = the editor monospace
    (--app-font-* from Settings); 16-colour + default fg/bg from the
    src/css.rs PALETTE (dark/light), matched to the editor scheme.
  • PTY read/write loop runs off the GTK main thread; output marshalled
    to the widget on the main loop (CLAUDE.md non-negotiable).

Key design question — terminal widget / cross-platform parity

CLAUDE.md requires macOS + Windows parity and a shared platform trait,
not copy-paste. The terminal core is the crux:

  • Option A — VTE4 (vte4 crate / libvte-2.91-gtk4): drop-in GTK4
    terminal widget, least code. But VTE is GNOME/Linux-first — awkward to
    ship on macOS (Homebrew libvte) and not available on Windows. Fails
    the parity requirement on its own.
  • Option B — portable PTY + emulator core + custom render (recommended
    for parity): portable-pty (wezterm) for the cross-platform PTY
    (ConPTY on Windows, openpty on Unix), an emulation core
    (alacritty_terminal, or the vte parser crate feeding our own grid),
    rendered into a gtk::DrawingArea with the Settings monospace font and
    palette colours. More work, but one code path on both OSes with only the
    PTY spawn behind the platform trait.
  • Option C — hybrid: VTE4 where present, Option B elsewhere. Two
    renderers to maintain — least attractive.

Recommend Option B. Confirm approach before starting (this touches the
platform trait — per CLAUDE.md "when unsure, ask").

Proposed structure

  • app/terminal.rs — the panel widget: tab bar + terminal view(s),
    ToolWindow registration, toggle plumbing.
  • terminal/ module — OS-agnostic: PTY session lifecycle, the emulator
    grid/parser, input encoding, resize.
  • platform/* — only the PTY spawn (shell path, env, ConPTY vs openpty)
    behind the existing platform trait; no duplicated session logic.
  • Constants (default shell fallbacks, scrollback limit, read-buffer size)
    in the one constants/config module, not scattered.
  • SCSS stem for the panel/tab-bar chrome, registered in CSS_FILES in
    src/css.rs and build.rs; boxy, --radius-* = 0. Icons via
    crate::app::icons::img.
  • Persist open/closed (and tab count / cwd if cheap) via the layout.*
    settings area from Rearrangeable tool-window layout: dock/move/resize/float like a JetBrains IDE #4.

Phasing

  • P1 — single terminal, PTY rooted at workspace root, basic
    colour/resize/scrollback, copy-paste, off-thread IO. Depends on the
    widget decision above.
  • P2 — multiple tabs; shell selection setting; restart-on-root-change;
    clear action.
  • P3 — theming polish (palette-matched colours, cursor styles), search
    in scrollback, "open terminal here" from a file-tree folder context
    menu.

Out of scope

  • A full multiplexer / split panes inside one terminal tab.
  • Remote / SSH sessions.
  • Running Rhymr build tasks through a task-runner UI (separate concern).

Acceptance criteria

  • Bottom-docked "Terminal" tool window via the dock manager (Rearrangeable tool-window layout: dock/move/resize/float like a JetBrains IDE #4),
    toggled from the stripe + app.terminal action/accel + menu entry.
  • Interactive shell starts in the workspace root (home dir when no
    project); full-screen TUI apps, colour and resize work.
  • PTY spawn is the only OS-specific piece, behind the platform trait;
    session/emulation logic is shared, not duplicated.
  • All PTY IO off the GTK main thread.
  • Multiple terminal tabs; shell honours the Settings override then the
    OS default.
  • Font from the editor monospace setting; colours from the src/css.rs
    palette in both themes.
  • Open/closed state persisted with the rest of the layout.
  • SCSS stem registered in css.rs + build.rs; icons via
    icons::img.
  • cargo fmt + cargo clippy clean; syllable regression suite
    unaffected.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions