From bffdc55d63449ca1a80e649df6f8b35f20937b91 Mon Sep 17 00:00:00 2001
From: tims <0xtimsb@gmail.com>
Date: Fri, 6 Dec 2024 22:56:47 +0530
Subject: [PATCH] linux: Make prompt detail selectable (#21405)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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:
When detail is `None` or empty string:
Release Notes:
- N/A
---
Cargo.lock | 1 +
crates/zed/Cargo.toml | 1 +
crates/zed/src/zed/linux_prompts.rs | 43 ++++++++++++++++++++---------
3 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index e421917d8f2b7d31fa4109212f7bc8912120d30d..b93ebce571a3548eb34d66074587d9e0173da860 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -16083,6 +16083,7 @@ dependencies = [
"languages",
"libc",
"log",
+ "markdown",
"markdown_preview",
"menu",
"mimalloc",
diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml
index 6b26a01f271df74827a14bac4a0e391d5c5082ac..9a672757a6870ccf67d12ad465494fa894aecb11 100644
--- a/crates/zed/Cargo.toml
+++ b/crates/zed/Cargo.toml
@@ -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 }
diff --git a/crates/zed/src/zed/linux_prompts.rs b/crates/zed/src/zed/linux_prompts.rs
index 1961a5f9cd60fb9175f220e8adaf4611a459c526..aa262a11b94303d4d8d69c60008bb10f92e0c050 100644
--- a/crates/zed/src/zed/linux_prompts.rs
+++ b/crates/zed/src/zed/linux_prompts.rs
@@ -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;
@@ -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)
+ })
+ }),
}
});
@@ -42,10 +61,10 @@ pub fn fallback_prompt_renderer(
pub struct FallbackPromptRenderer {
_level: PromptLevel,
message: String,
- detail: Option,
actions: Vec,
focus: FocusHandle,
active_action_id: usize,
+ detail: Option>,
}
impl FallbackPromptRenderer {
@@ -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())