Skip to content

Add setting to disable '#' trigger for AI Command Search - #15340

Open
warp-agent-staging[bot] wants to merge 6 commits into
masterfrom
factory/ai-command-search-hash-trigger-setting
Open

Add setting to disable '#' trigger for AI Command Search#15340
warp-agent-staging[bot] wants to merge 6 commits into
masterfrom
factory/ai-command-search-hash-trigger-setting

Conversation

@warp-agent-staging

@warp-agent-staging warp-agent-staging Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a setting to disable the # character trigger for AI Command Search, so typing # at the start of terminal input (e.g. to write a shell comment like # some note) no longer opens AI Command Search. The keybinding (input:toggle_natural_language_command_search, default `ctrl-``) continues to open AI Command Search regardless of this setting.

Fixes #2227.

Linked Issue

  • The linked issue is labeled enhancement, triaged, area:agent.
  • Where appropriate, screenshots or a short video of the implementation are included below (especially for user-visible or UI changes).

Changes

  • app/src/settings/input.rs: new InputSettings.enable_ai_command_search_hash_trigger bool setting (terminal.input.enable_ai_command_search_hash_trigger), default true (preserves current behavior).
  • app/src/terminal/input.rs: gate the open-on-type path (typing # at buffer start) on the new setting; gate the AI_COMMAND_SEARCH_HINT_TEXT hint (Type '#' for AI command suggestions) so it isn't shown when the trigger is disabled; refresh hint text when the setting changes.
  • app/src/settings_view/warp_agent_page.rs: the toggle ("Enable '#' trigger for AI Command Search") is its own AiCommandSearchHashTriggerWidget, under Settings > Agents > Warp Agent > Input, right after "Show input hint text" — plus a matching Command Palette entry. It shares the "Input" section header with AIInputWidget via a Category, so settings search isolates it without dropping the shared header. WarpAgentPageView::build_page was promoted from PageType::Uncategorized to PageType::Categorized for this (mirroring the pattern the Appearance page already uses for its own "Input" section); one other widget (CloudHandoffWidget) needed a trailing-margin fix to keep its section boundary consistent with its siblings after that refactor.
  • app/src/settings_view/mod.rs, app/src/workspace/view.rs: keymap context flag wired for the Command Palette toggle.
  • app/src/terminal/input_tests.rs, app/src/settings_view/mod_tests.rs: behavior and settings-search-filter test coverage (see Testing).

Testing

  • cargo check --bin warp and cargo clippy -p warp --all-targets --tests -- -D warnings pass; ./script/format --check is clean.

  • Added deterministic App::test coverage:

    • app/src/terminal/input_tests.rs (subscribing to Event::ShowCommandSearch): hash_trigger_disabled_keeps_hash_literal_and_does_not_open_ai_command_search, hash_trigger_enabled_by_default_opens_ai_command_search, hotkey_opens_ai_command_search_even_when_hash_trigger_disabled.
    • app/src/settings_view/mod_tests.rs (stub Category/PageType::Categorized pages): a query unique to one widget isolates it within a shared category without pulling in its sibling or unrelated categories, the shared header survives regardless of which sibling widget matches, and an empty query restores everything. A follow-up compound-query test (input hash) confirms the isolated widget still carries the shared "Input" context alongside its own row-specific terms, so combined queries someone would actually type still find it.
  • Full settings_view test suite (244 tests) passes.

  • Manually/visually verified in the running app, both toggle states:

    • The toggle is under Settings > Agents > Warp Agent > Input (right after "Show input hint text"), and no longer present on the Features page.
    • Settings search for "hash" or "AI Command Search" isolates exactly this row while the "Input" header stays visible; a reverse-direction check (searching "denylist", unique to the neighboring widget) isolates that row instead and excludes this one; clearing search restores the full section.
    • Setting ON (default): typing # on an empty line still opens AI Command Search.
    • Setting OFF: typing # this is a test comment stays as plain literal text (no interception), and pressing Enter submits it as a normal shell comment — the user is not trapped, which was the original complaint in the issue.
    • Setting OFF: the ctrl-`` hotkey still opens AI Command Search.
    • Toggling the setting back ON restores the original typed-# behavior.
    • Full-page regression scan of the Warp Agent settings page confirmed correct separators/headers throughout, including a follow-up fix for one boundary (Cloud Handoff → Custom Inference) that lost its divider in the refactor.
  • I have manually tested my changes locally with ./script/run

Screenshots / Videos

Agent Mode

  • Warp Agent Mode - This PR was created via Warp's AI Agent Mode

Computer-use video recordings

View video recording - Full verification flow at the current location (Settings > Agents > Warp Agent > Input): the toggle and settings search, typing '#' with the setting ON/OFF, submitting a literal # comment, and the ctrl-` hotkey still opening AI Command Search with the trigger disabled.

Adds InputSettings.enable_ai_command_search_hash_trigger (default true,
preserving current behavior). When disabled, typing '#' at the start of
terminal input no longer opens AI Command Search, leaving it as plain
text (e.g. for shell comments); the hotkey
(input:toggle_natural_language_command_search) still opens it. Also
gates the hint text that advertises the '#' shorthand, and surfaces the
setting on the Features settings page and Command Palette, mirroring
the existing '@' context menu / slash command toggles.

Fixes #2227.
@warp-agent-staging

Copy link
Copy Markdown
Contributor Author

This PR was generated with Warp.

Comment @warp-factory on this PR to send it follow-up work.

View run View conversation View on Slack

@warp-agent-staging
warp-agent-staging Bot marked this pull request as ready for review August 20, 2026 03:38
Covers APP-5557's acceptance criteria with deterministic App::test
coverage, subscribing to Event::ShowCommandSearch on the terminal
Input view:
- with the setting disabled, typing '#' (and text after it) stays as
  literal input and does not open AI Command Search
- with the setting left at its default (enabled), typing '#' still
  opens AI Command Search
- the input:toggle_natural_language_command_search hotkey action
  still opens AI Command Search even when the '#' trigger is
  disabled
Per requester feedback, the toggle belongs next to the other AI input
behavior settings rather than on the general Features page.

- Remove AiCommandSearchHashTriggerWidget, its FeaturesPageAction
  variant, telemetry arm, handle_action arm, and command-palette
  registration from features_page.rs.
- Fold the toggle into AIInputWidget in warp_agent_page.rs, right
  after "Show input hint text", using the widget's own
  render_ai_setting_toggle convention. Extend AIInputWidget's
  search_terms so settings search still finds it by its new home.
- Add a WarpAgentPageAction::ToggleAiCommandSearchHashTrigger variant
  and register its own command-palette entry (gated on
  IS_ANY_AI_ENABLED) in warp_agent_page.rs's init_actions_from_parent_view,
  fully replacing the Features-page registration rather than leaving
  a split/duplicated one behind.

The setting key, its default, the gate in app/src/terminal/input.rs,
the hint-text suppression, and the existing behavior tests are
unchanged.
Folding the toggle's terms into AIInputWidget made a query like 'hash'
or 'AI Command Search' retain the entire Input mega-widget instead of
isolating just this row, since the widget is the search unit.

- Split it into a new AiCommandSearchHashTriggerWidget carrying only
  its own search terms; AIInputWidget's terms and content revert to
  what they were before this feature.
- Promote WarpAgentPageView::build_page from PageType::Uncategorized
  to PageType::Categorized so the two Input widgets can share one
  "Input" subheader at the Category level. The subheader now survives
  search as long as either widget matches, instead of disappearing
  whenever AIInputWidget itself doesn't match. Every other section
  becomes a single-widget category with an empty title, preserving
  its existing self-drawn header; each widget's now-redundant leading
  separator is removed in favor of Category's own between-category
  separator (this is the same PageType::Categorized pattern already
  used by the Appearance page's own "Input" section).
- Add App::test coverage in mod_tests.rs against stub Categorized
  pages: a query unique to one widget isolates it within the shared
  category without pulling in its sibling or unrelated categories,
  the shared header survives regardless of which sibling widget
  matches, and an empty query restores everything.

Re-verified with cargo check/clippy/fmt and the full settings_view
and terminal::input::tests::hash_trigger_* test suites (all pass);
confirmed the one unrelated failure in
terminal::input::decorations::tests::test_decorations_with_multibyte_chars
pre-exists on the prior commit, unaffected by this change.
CloudHandoffWidget was the only section widget that didn't wrap its
content in a trailing-margin Container the way AwsBedrockWidget,
GeminiEnterpriseWidget, and CustomModelRoutersWidget already do to
keep the following section's title from crowding their last row.
That asymmetry was previously masked because every widget rendered
its own leading separator with its own spacing; now that separators
are inserted generically between categories, the missing trailing
margin left the boundary between Cloud Handoff and Custom Inference
visually crowded enough that the separator line was easy to miss.

Found via a follow-up computer-use pass across the whole Warp Agent
page after the Categorized refactor.
Category titles don't participate in PageType::update_filter — only
each widget's own terms are matched — so a compound query like
'input hash' or 'terminal hash' (exactly what someone hunting for
this setting would type) matched nothing: the row-specific terms had
no 'input'/'terminal', and AIInputWidget has no 'hash'.

Add 'terminal input' to AiCommandSearchHashTriggerWidget's own terms
alongside its row-specific ones (not to AIInputWidget's terms, which
would reintroduce the earlier mega-widget isolation problem).

Extend the stub Categorized test in mod_tests.rs with a matching
compound-query assertion so this can't regress.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add the ability to customize or turn off AI Command Search on typing # in the terminal

0 participants