Skip to content

Commit

Permalink
linux: Make prompt detail selectable (#21405)
Browse files Browse the repository at this point in the history
Closes #21305

As Linux doesn’t have native prompts, Zed uses a custom GPU-based
prompt, like the "About Zed" prompt. Currently, the detail in the prompt
isn’t selectable.

This PR fixes that by using the editor's multi-line selectable
functionality to make the detail selectable (and thus copyable). It
achieves this by disabling editing and setting the cursor to
transparent. The editor also does all the heavy lifting, like
double-clicking to select a word or triple-clicking to select a line,
like what user expects from selectable.

Before/After:

<img
src="https://github.com/user-attachments/assets/2012a6cc-a1ed-4efe-8bfb-440a9259f07a"
alt="before" width="360px" />

<img
src="https://github.com/user-attachments/assets/31922ef5-cb2d-4e90-a1a1-00843e767432"
alt="after" width="360px" />

When detail is `None` or empty string:

<img
src="https://github.com/user-attachments/assets/2be5c921-bda1-4db3-85cd-b4b0e2df86d2"
alt="none" width="360px" />

Release Notes:

- N/A
  • Loading branch information
smitbarmase authored Dec 6, 2024
1 parent 9ca0d99 commit bffdc55
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 13 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/zed/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ language_tools.workspace = true
languages = { workspace = true, features = ["load-grammars"] }
libc.workspace = true
log.workspace = true
markdown.workspace = true
markdown_preview.workspace = true
menu.workspace = true
mimalloc = { version = "0.1", optional = true }
Expand Down
43 changes: 30 additions & 13 deletions crates/zed/src/zed/linux_prompts.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use gpui::{
div, AppContext, EventEmitter, FocusHandle, FocusableView, FontWeight, InteractiveElement,
IntoElement, ParentElement, PromptHandle, PromptLevel, PromptResponse, Render,
RenderablePromptHandle, Styled, ViewContext, VisualContext, WindowContext,
IntoElement, ParentElement, PromptHandle, PromptLevel, PromptResponse, Refineable, Render,
RenderablePromptHandle, Styled, TextStyleRefinement, View, ViewContext, VisualContext,
WindowContext,
};
use markdown::{Markdown, MarkdownStyle};
use settings::Settings;
use theme::ThemeSettings;
use ui::{
h_flex, v_flex, ButtonCommon, ButtonStyle, Clickable, ElevationIndex, FluentBuilder, LabelSize,
TintColor,
h_flex, v_flex, ActiveTheme, ButtonCommon, ButtonStyle, Clickable, ElevationIndex,
FluentBuilder, LabelSize, TintColor,
};
use workspace::ui::StyledExt;

Expand All @@ -28,10 +30,27 @@ pub fn fallback_prompt_renderer(
|cx| FallbackPromptRenderer {
_level: level,
message: message.to_string(),
detail: detail.map(ToString::to_string),
actions: actions.iter().map(ToString::to_string).collect(),
focus: cx.focus_handle(),
active_action_id: 0,
detail: detail.filter(|text| !text.is_empty()).map(|text| {
cx.new_view(|cx| {
let settings = ThemeSettings::get_global(cx);
let mut base_text_style = cx.text_style();
base_text_style.refine(&TextStyleRefinement {
font_family: Some(settings.ui_font.family.clone()),
font_size: Some(settings.ui_font_size.into()),
color: Some(ui::Color::Muted.color(cx)),
..Default::default()
});
let markdown_style = MarkdownStyle {
base_text_style,
selection_background_color: { cx.theme().players().local().selection },
..Default::default()
};
Markdown::new(text.to_string(), markdown_style, None, None, cx)
})
}),
}
});

Expand All @@ -42,10 +61,10 @@ pub fn fallback_prompt_renderer(
pub struct FallbackPromptRenderer {
_level: PromptLevel,
message: String,
detail: Option<String>,
actions: Vec<String>,
focus: FocusHandle,
active_action_id: usize,
detail: Option<View<Markdown>>,
}

impl FallbackPromptRenderer {
Expand Down Expand Up @@ -111,13 +130,11 @@ impl Render for FallbackPromptRenderer {
.child(self.message.clone())
.text_color(ui::Color::Default.color(cx)),
)
.children(self.detail.clone().map(|detail| {
div()
.w_full()
.text_xs()
.text_color(ui::Color::Muted.color(cx))
.child(detail)
}))
.children(
self.detail
.clone()
.map(|detail| div().w_full().text_xs().child(detail)),
)
.child(h_flex().justify_end().gap_2().children(
self.actions.iter().enumerate().rev().map(|(ix, action)| {
ui::Button::new(ix, action.clone())
Expand Down

0 comments on commit bffdc55

Please sign in to comment.