Skip to content

feat(terminal): click the live prompt's directory to jump elsewhere - #474

Open
linjunsu wants to merge 2 commits into
Kuddev:mainfrom
linjunsu:feat/prompt-directory-jump
Open

linjunsu wants to merge 2 commits into
Kuddev:mainfrom
linjunsu:feat/prompt-directory-jump

Conversation

@linjunsu

@linjunsu linjunsu commented Oct 4, 2026 •

Copy link
Copy Markdown

Result / 用户结果

A plain click on the working directory shown in the prompt the shell is currently waiting at opens a searchable directory picker (parent, subfolders, frequent directories). Choosing an entry runs cd in the same pane, using the pane shell's own syntax. Quick Jump's folder rows keep opening a new tab; this covers the "move this shell somewhere else" case without typing the path.

单击当前提示符上的工作目录,弹出可搜索的目录选择器(上一级、子文件夹、常用目录)。选中后在同一个 pane 里按该 shell 的语法执行 cd。Quick Jump 的文件夹行仍是新开标签,本 PR 补的是"让当前 shell 换个目录"且不必手打路径的场景。

The click is only taken over when it is safe to type a command; otherwise the existing click behaviour (selection, hover preview, Ctrl+click to open) is unchanged:

  • only the prompt the shell is waiting at — older prompts and command output keep their normal selection/double-click behaviour;
  • only an empty prompt: half-typed input, running commands, full-screen programs and mouse-reporting apps are left alone;
  • only local PowerShell, cmd and POSIX shells; SSH, WSL and unrecognised shells are left alone.

Design / 设计边界

  • Responsibility and affected modules:
    • terminal/view/directory_jump.rs (new): decides whether a click lands on the live prompt's directory and builds the cd line (cd -LiteralPath '…', cd /d "…", POSIX single quotes). Submission reuses the existing run_command path, which waits for a ready prompt instead of typing into a running program.
    • terminal/view/pointer.rs: one branch on mouse-up after the existing link/selection handling; emits TerminalViewEvent::DirectoryJumpRequested.
    • workspace/directory_jump.rs (new): projects the picker rows and runs the chosen entry. The overlay, filtering and keyboard handling are the existing command palette (palette_override), with a new WorkspacePaletteAction::ChangeDirectory.
    • nebula_terminal term/prompt.rs: adds a read-only nebula_live_prompt_line() accessor over the existing OSC 133;A marks.
  • Why this belongs here; interfaces that remain unchanged: prompt/cwd state stays owned by the terminal; the workspace only renders and dispatches. No existing palette action or setting changes meaning.
  • How the directory is recognised: the shell-reported cwd is matched in its displayed form (absolute, or ~-relative) on the prompt row first, because the path hint regex stops at the first space and does not cover CJK names; custom prompts that abbreviate the path fall back to the existing path hint, accepting only existing local directories.
  • Edge cases found while testing on Windows:
    • Tabs launched from the shell picker store a full program path (e.g. …\WindowsApps\pwsh.exe), which shell_short_tag does not map; the shell is identified from the program's file name first.
    • A resize clears prompt marks (reflow shifts absolute lines) while the shell keeps waiting at the same prompt. Tabs restored in the background print their prompt before their first real layout, so the live prompt was unknown there. When marks are gone but the prompt is still active, the rows just above the cursor (at most 3) are used.
    • A real click can drift across half a cell and leave a one-cell selection; a selection that never left one cell still counts as a click and is cleared.
  • Necessary extraction: the palette's keyboard path (run_selected_palette_action in workspace.rs) and click path (palette.rs) carried identical copies of the action match. They now share run_workspace_palette_action in palette.rs, so the new action is wired once and workspace.rs shrinks (3253 → 3222 lines) instead of exceeding its ratcheted budget. Behaviour of the existing actions is unchanged.
  • Dependency, data-format, threading, or lifetime changes: none.
  • Compatibility and migration/fallback behavior: nothing persisted; i18n adds directory_jump.* to en-US, zh-CN and zh-TW; other catalogs fall back to English.

Evidence / 验证依据

  • Commands and actual results (Windows 11, rebased on e537d52):
    • python scripts/check_architecture.py --base origin/main — passes (only pre-existing "tighten exception" notices). An earlier revision failed here because workspace.rs grew past its ratcheted 3253 lines; see the extraction below.
    • python -m unittest scripts.tests.test_architecture_budgets scripts.tests.test_architecture_dependencies scripts.tests.test_architecture_governance — 54 tests OK.
    • cargo test --manifest-path tools/i18n-contract/Cargo.toml --locked — 23 passed, 1 ignored.
    • cargo test --release --locked -p nebula --test i18n_contract — 23 passed, 1 ignored.
    • cargo test --release --locked -p nebula --bin pebrel --features gpui-test-support -- directory_jump i18n:: pointer tab_identity terminal_activity — 36 passed, 1 ignored; after the extraction, -- directory_jump palette command_palette quick_jump — 57 passed.
    • cargo test --release --locked -p nebula_terminal --lib — 280 passed.
    • cargo test --release --locked -p nebula --test file_line_budget — 2 passed.
    • cargo fmt --all -- --check — no content differences (--config newline_style=Auto; on this Windows checkout the plain command only reports CRLF newline style for every file in the repository, including untouched ones).
    • cargo test --release --locked -p nebula --bin pebrel --features gpui-test-support (full suite) — 2239 passed, 1 failed: platform::environment::tests::inherited_environment_reaches_a_real_child_with_pane_overrides, which fails on this machine because a non-ASCII directory on PATH is mangled by the legacy code page; unrelated to this change.
    • Not run locally: Linux/macOS native suites.
  • Regression tests:
    • cd_commands_quote_for_each_shell, full_program_paths_are_recognised_by_file_name, shell_tags_pick_a_cd_syntax, displayed_path_span_maps_wide_characters_to_columns (terminal side);
    • picker_lists_parent_then_sorted_children_and_skips_the_current_directory, a_clicked_directory_other_than_cwd_is_offered_first (workspace side);
    • live_prompt_line_follows_marks_and_resize_keeps_the_prompt_active (core: marks, resize, command start).
  • UI changes: checked on Windows 11 at 150% scale in an isolated instance (separate config dir) with PowerShell 7 — picker opens from the live prompt (including the part after a space and CJK characters), entries cd into folders with spaces/CJK names, Enter picks the highlighted row, Esc closes; no picker for older prompts (5 rows tried), half-typed input or a running command; restored background tabs work after the resize fallback. Re-checked on a release build of this exact branch: picker shows the zh-CN catalog strings, Enter and mouse selection both cd through the shared dispatch. No screenshots attached; I can add them if useful.
  • Hot-path changes: none. Work happens only on a qualifying mouse-up (one row scan, one read_dir when the picker opens).

Required Review / 必须确认

  • I followed CONTRIBUTING.md, docs/architecture.md, and docs/project-constraints.md.
  • I split responsibilities, not arbitrary line ranges; no duplicate behavior authority was added.
  • python3 scripts/check_architecture.py --base <PR-base-commit> passes; budgets were not inflated to fit the change.
  • Tests cover success and failure; platform/feature coverage limitations are stated.
  • New messages use typed i18n IDs and matching placeholders; untranslated content has an explicit fallback.
  • Governance changes include a counterexample, corrected contract, tests, and a maintainer-reviewed decision. (Not applicable.)

A plain click on the working directory shown by the prompt the shell is
waiting at opens a searchable picker: the parent, the subfolders and the
frequent directories. The chosen entry is submitted as a shell-specific
cd in that same pane (PowerShell, cmd or POSIX quoting), unlike Quick
Jump's folders, which open a new tab.

The click only counts while the shell sits at an empty prompt; older
prompts, half-typed input, running commands, full-screen programs, SSH
and WSL panes keep the existing click behaviour. The cwd is matched in
its displayed form first, so paths with spaces or CJK characters work
even where the path hint stops at the first space.

The shell is identified from the launch program's file name, so tabs
started from a full path such as ...\WindowsApps\pwsh.exe qualify. A
resize drops prompt marks while the shell keeps waiting at the prompt
(tabs restored in the background hit this on first layout); the live
prompt then falls back to the rows just above the cursor. A click that
drifts within one cell still counts.

The palette's keyboard and click paths carried identical copies of the
action dispatch; they now share run_workspace_palette_action in
palette.rs, so the new action is wired once and workspace.rs stays within
its ratcheted line budget.
@linjunsu
linjunsu requested a review from Kuddev as a code owner October 4, 2026 13:23
The hint fallback built its "link modifier held" state with cfg! checks,
which pushed the platform cfg count outside platform/ over its budget.
osc_links already owns the link modifier choice through
Platform::current(); expose it as link_modifiers() and use that.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant