Add find-in-scrollback, unicode11, and keyboard pane navigation
Three xterm.js features, implemented together because they share the XtermPane mount + the single attachCustomKeyEventHandler: - Unicode 11: load @xterm/addon-unicode11, set activeVersion='11' after the canvas renderer so emoji/CJK/box-drawing widths stop drifting. - Find in scrollback: @xterm/addon-search + a new per-pane SearchBar overlay (Ctrl+Shift+F to open, Enter/Shift+Enter next/prev, regex + case toggles, Esc to close & refocus). Overlay is an absolutely- positioned sibling in a position:relative wrapper so fit() is unaffected. - Pane navigation: Ctrl+Alt+Arrow / Ctrl+Alt+HJKL (spatial neighbour via findNeighborInDirection) and Alt+1..9 (Nth leaf in walkLeaves order). XtermPane emits a NavigateIntent; App resolves the target leaf and sets it active, reusing the existing isActive->focusTrigger refocus chain. All chords live in one attachCustomKeyEventHandler (xterm replaces the handler on each call). Shortcuts added to shortcuts.ts (SoT for README + Help), including the Alt+digit shell-conflict caveat. tsc clean apart from the three not-yet-installed addon modules. Needs pnpm install on the Windows host + runtime verification. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8bb080345e
commit
baa00dfc5c
8 changed files with 526 additions and 29 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import { createContext, useContext, type ReactNode } from "react";
|
||||
import type { Orientation, NodeId, LeafShellSpec } from "./tree";
|
||||
import type { Orientation, NodeId, LeafShellSpec, Direction } from "./tree";
|
||||
import type { PaneId, SshHost } from "../../ipc";
|
||||
|
||||
/**
|
||||
|
|
@ -62,6 +62,16 @@ export interface Orchestration {
|
|||
* The PTY stays alive across the move (the new window's XtermPane
|
||||
* adopts the existing PaneId; scrollback ring is replayed). */
|
||||
moveToNewWindow: (leafId: NodeId) => void;
|
||||
/**
|
||||
* Navigate focus from within a pane's key-handler. XtermPane emits the
|
||||
* intent; LeafPane/App resolve the target leaf and set it active.
|
||||
*
|
||||
* `{ kind: "direction", dir }` — move to the spatial neighbour in that
|
||||
* direction using the same flattenLayout geometry as Ctrl+Shift+Arrow.
|
||||
* `{ kind: "index", n }` — focus the Nth leaf in DFS (walkLeaves) order,
|
||||
* 1-indexed, clamped to the leaf count (so Alt+9 with 3 panes picks pane 3).
|
||||
*/
|
||||
navigateTo: (intent: NavigateIntent) => void;
|
||||
/** Returns a PaneId only for leaves that just arrived via a window
|
||||
* transfer (so LeafPane can pass `existingPaneId` to XtermPane to skip
|
||||
* the spawn). One-shot — App clears the entry once the pane has
|
||||
|
|
@ -69,6 +79,13 @@ export interface Orchestration {
|
|||
getInitialPaneIdFor: (leafId: NodeId) => PaneId | undefined;
|
||||
}
|
||||
|
||||
/** Discriminated intent emitted by XtermPane's key handler. App resolves
|
||||
* the actual target leaf from the current tree without XtermPane needing
|
||||
* to know anything about layout geometry or leaf ordering. */
|
||||
export type NavigateIntent =
|
||||
| { kind: "direction"; dir: Direction }
|
||||
| { kind: "index"; n: number };
|
||||
|
||||
const OrchestrationContext = createContext<Orchestration | null>(null);
|
||||
|
||||
export function OrchestrationProvider({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue