Skip to content

input: Allow configuring the completion popover max width#2369

Open
narma wants to merge 2 commits into
longbridge:mainfrom
narma:input/configurable-completion-menu-width
Open

input: Allow configuring the completion popover max width#2369
narma wants to merge 2 commits into
longbridge:mainfrom
narma:input/configurable-completion-menu-width

Conversation

@narma

@narma narma commented May 13, 2026

Copy link
Copy Markdown

Summary

The LSP completion popover width is currently capped at a hardcoded MAX_MENU_WIDTH of 320 px, and there's no public API to override it from outside the crate. That's fine for most identifiers, but it truncates longer LSP labels — e.g. database table identifiers like tbl_verification_tracking that show up in completions for editors hosting SQL/MongoDB/etc. clients.

This PR keeps the default at 320 px (no visual change for existing callers) and adds a way to widen the popover per editor:

  • Renames the hardcoded MAX_MENU_WIDTH to DEFAULT_MAX_MENU_WIDTH (still pub(crate)).
  • Stores max_width: Pixels on CompletionMenu and threads it through CompletionMenu::new, the items column, the documentation panel, and the side-by-side vs vertical layout overflow check.
  • Adds two public methods on InputState:
    • completion_menu_max_width(width: Pixels) -> Self — builder.
    • set_completion_menu_max_width(width, window, cx) — runtime setter that also forwards into an already-open popover.

Usage:

InputState::new(window, cx)
    .code_editor("sql")
    .completion_menu_max_width(px(480.))

AI Assistance

🤖 The patch was drafted by Claude and reviewed/tested by a human; it follows the existing builder-method pattern used for placeholder, searchable, folding, etc.

Test plan

  • cargo check -p gpui-component
  • cargo clippy -p gpui-component -- -D warnings
  • rustfmt on the three touched files
  • Manual: open an editor with long completion labels, verify the popover caps at the configured width and still shrinks to fit when near the right viewport edge.
  • Manual: confirm default behavior (no builder call) is unchanged at 320 px.

The `MAX_MENU_WIDTH` constant in the LSP completion popover was
hardcoded at 320 px and there was no public way to override it from
outside the crate. That caps the popover at a width that comfortably
fits English identifiers but truncates longer LSP labels (e.g. database
table identifiers such as `tbl_verification_tracking`).

This change:

- Renames `MAX_MENU_WIDTH` to `DEFAULT_MAX_MENU_WIDTH` (still
  `pub(crate)`) and keeps the same 320 px default — no behavior change
  for existing callers.
- Stores `max_width: Pixels` on `CompletionMenu` and threads it through
  `CompletionMenu::new`, the items column, the documentation panel, and
  the side-by-side vs vertical layout overflow check.
- Adds `InputState::completion_menu_max_width(width)` (builder) and
  `InputState::set_completion_menu_max_width(width, window, cx)`
  (runtime setter) so embedders can widen the popover. The runtime
  setter also forwards into an already-open popover.

🤖 Generated by AI (Claude), reviewed and tested by a human.
@huacnlee

huacnlee commented May 14, 2026

Copy link
Copy Markdown
Member

This is not a good API, but I don't know is there have a better choice.

@narma

narma commented May 14, 2026

Copy link
Copy Markdown
Author

@huacnlee good point — agreed the two InputState::*completion_menu_max_width* methods felt off. I pushed ca0e6450 that tries a different shape, would this work better?

Instead of a dedicated builder + runtime setter on InputState, the option lives as a public field on Lsp, next to the other LSP-related config (completion_provider, code_action_providers, …):

pub struct CompletionMenuOptions {
    pub max_width: Pixels, // default 320 px
}

pub struct Lsp {
    pub completion_provider: ...,
    pub code_action_providers: ...,
    pub completion_menu: CompletionMenuOptions,
    ...
}

Usage from the embedder side:

let mut state = InputState::new(window, cx).code_editor("sql");
state.lsp.completion_menu.max_width = px(480.);

What this buys us:

  • One discoverable place for completion-popover knobs, matching the existing public-field pattern on Lsp — no new methods on InputState.
  • No duplicated state: CompletionMenu doesn't carry its own max_width copy anymore; on render it just reads self.editor.read(cx).lsp.completion_menu.max_width. Runtime changes propagate through the normal entity update flow, so the dedicated runtime setter is gone too.
  • Future per-popover options (height, padding, doc-panel toggles) can be added as fields on CompletionMenuOptions without growing the InputState API surface.

Net diff vs the previous revision: +31 / −60 lines. Happy to iterate further if you'd prefer a different shape (e.g. keeping it on InputState but as a single completion_menu_options field/builder, or making it a pub(crate) getter on the popover entity instead).

Replace the standalone `InputState::completion_menu_max_width` builder
and `set_completion_menu_max_width` runtime setter with a single
`CompletionMenuOptions` struct exposed as a public field on `Lsp`, in
line with the existing `Lsp::completion_provider` / `code_action_providers`
pattern.

- Add `pub struct CompletionMenuOptions { pub max_width: Pixels }` in
  `lsp/completions.rs` (default 320 px), re-exported via `pub use lsp::*`.
- Add `pub completion_menu: CompletionMenuOptions` to `Lsp`.
- Drop the dedicated field, builder and runtime setter on `InputState`,
  and drop the duplicated `max_width` storage + `set_max_width` method on
  `CompletionMenu`. The popover reads the value from
  `self.editor.read(cx).lsp.completion_menu.max_width` on render, so
  runtime updates work through normal entity update flow.

Usage:

    let mut state = InputState::new(window, cx).code_editor("sql");
    state.lsp.completion_menu.max_width = px(480.);

Future per-popover options (height, padding, doc panel toggles) can be
added as fields on `CompletionMenuOptions` without growing the
`InputState` API surface.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@narma narma force-pushed the input/configurable-completion-menu-width branch from ca0e645 to 34a11ba Compare May 14, 2026 07:50
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.

2 participants