Add hidden prompt_to_focus field to OpenPromptLibrary action (#29062)

Release Notes:

- N/A
This commit is contained in:
Michael Sloan 2025-04-18 14:39:40 -06:00 committed by GitHub
parent 327fee4d22
commit 73a767fc45
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 60 additions and 18 deletions

1
Cargo.lock generated
View file

@ -18322,6 +18322,7 @@ dependencies = [
"gpui",
"schemars",
"serde",
"uuid",
"workspace-hack",
]

View file

@ -2965,6 +2965,11 @@ impl ActiveThread {
))
};
let first_default_user_rules_id = project_context
.default_user_rules
.first()
.map(|user_rules| user_rules.uuid);
let rules_files = project_context
.worktrees
.iter()
@ -3015,8 +3020,13 @@ impl ActiveThread {
.icon_color(Color::Ignored)
// TODO: Figure out a way to pass focus handle here so we can display the `OpenPromptLibrary` keybinding
.tooltip(Tooltip::text("View User Rules"))
.on_click(|_event, window, cx| {
window.dispatch_action(Box::new(OpenPromptLibrary), cx)
.on_click(move |_event, window, cx| {
window.dispatch_action(
Box::new(OpenPromptLibrary {
prompt_to_focus: first_default_user_rules_id,
}),
cx,
)
}),
),
)

View file

@ -25,7 +25,7 @@ use language_model::{LanguageModelProviderTosView, LanguageModelRegistry};
use language_model_selector::ToggleModelSelector;
use project::Project;
use prompt_library::{PromptLibrary, open_prompt_library};
use prompt_store::PromptBuilder;
use prompt_store::{PromptBuilder, PromptId};
use proto::Plan;
use settings::{Settings, update_settings_file};
use time::UtcOffset;
@ -83,7 +83,7 @@ pub fn init(cx: &mut App) {
if let Some(panel) = workspace.panel::<AssistantPanel>(cx) {
workspace.focus_panel::<AssistantPanel>(window, cx);
panel.update(cx, |panel, cx| {
panel.deploy_prompt_library(&OpenPromptLibrary, window, cx)
panel.deploy_prompt_library(&OpenPromptLibrary::default(), window, cx)
});
}
})
@ -488,7 +488,7 @@ impl AssistantPanel {
fn deploy_prompt_library(
&mut self,
_: &OpenPromptLibrary,
action: &OpenPromptLibrary,
_window: &mut Window,
cx: &mut Context<Self>,
) {
@ -502,6 +502,7 @@ impl AssistantPanel {
None,
))
}),
action.prompt_to_focus.map(|uuid| PromptId::User { uuid }),
cx,
)
.detach_and_log_err(cx);
@ -1119,7 +1120,7 @@ impl AssistantPanel {
"New Text Thread",
NewTextThread.boxed_clone(),
)
.action("Prompt Library", Box::new(OpenPromptLibrary))
.action("Prompt Library", Box::new(OpenPromptLibrary::default()))
.action("Settings", Box::new(OpenConfiguration))
.separator()
.action(

View file

@ -24,8 +24,8 @@ use heed::types::SerdeBincode;
use language_model::{LanguageModelToolUseId, Role, TokenUsage};
use project::{Project, Worktree};
use prompt_store::{
DefaultUserRulesContext, ProjectContext, PromptBuilder, PromptStore, PromptsUpdatedEvent,
RulesFileContext, WorktreeContext,
DefaultUserRulesContext, ProjectContext, PromptBuilder, PromptId, PromptStore,
PromptsUpdatedEvent, RulesFileContext, WorktreeContext,
};
use serde::{Deserialize, Serialize};
use settings::{Settings as _, SettingsStore};
@ -246,6 +246,10 @@ impl ThreadStore {
.into_iter()
.flat_map(|(contents, prompt_metadata)| match contents {
Ok(contents) => Some(DefaultUserRulesContext {
uuid: match prompt_metadata.id {
PromptId::User { uuid } => uuid,
PromptId::EditWorkflow => return None,
},
title: prompt_metadata.title.map(|title| title.to_string()),
contents,
}),

View file

@ -27,7 +27,7 @@ use language_model::{
};
use project::Project;
use prompt_library::{PromptLibrary, open_prompt_library};
use prompt_store::PromptBuilder;
use prompt_store::{PromptBuilder, PromptId};
use search::{BufferSearchBar, buffer_search::DivRegistrar};
use settings::{Settings, update_settings_file};
@ -62,7 +62,7 @@ pub fn init(cx: &mut App) {
if let Some(panel) = workspace.panel::<AssistantPanel>(cx) {
workspace.focus_panel::<AssistantPanel>(window, cx);
panel.update(cx, |panel, cx| {
panel.deploy_prompt_library(&OpenPromptLibrary, window, cx)
panel.deploy_prompt_library(&OpenPromptLibrary::default(), window, cx)
});
}
});
@ -272,7 +272,10 @@ impl AssistantPanel {
menu.context(focus_handle.clone())
.action("New Chat", Box::new(NewChat))
.action("History", Box::new(DeployHistory))
.action("Prompt Library", Box::new(OpenPromptLibrary))
.action(
"Prompt Library",
Box::new(OpenPromptLibrary::default()),
)
.action("Configure", Box::new(ShowConfiguration))
.action(zoom_label, Box::new(ToggleZoom))
}))
@ -1043,7 +1046,7 @@ impl AssistantPanel {
fn deploy_prompt_library(
&mut self,
_: &OpenPromptLibrary,
action: &OpenPromptLibrary,
_window: &mut Window,
cx: &mut Context<Self>,
) {
@ -1057,6 +1060,7 @@ impl AssistantPanel {
None,
))
}),
action.prompt_to_focus.map(|uuid| PromptId::User { uuid }),
cx,
)
.detach_and_log_err(cx);

View file

@ -29,6 +29,6 @@ settings.workspace = true
theme.workspace = true
ui.workspace = true
util.workspace = true
workspace-hack.workspace = true
workspace.workspace = true
zed_actions.workspace = true
workspace-hack.workspace = true

View file

@ -75,6 +75,7 @@ pub fn open_prompt_library(
language_registry: Arc<LanguageRegistry>,
inline_assist_delegate: Box<dyn InlineAssistDelegate>,
make_completion_provider: Arc<dyn Fn() -> Box<dyn CompletionProvider>>,
prompt_to_focus: Option<PromptId>,
cx: &mut App,
) -> Task<Result<WindowHandle<PromptLibrary>>> {
let store = PromptStore::global(cx);
@ -88,7 +89,12 @@ pub fn open_prompt_library(
.find_map(|window| window.downcast::<PromptLibrary>());
if let Some(existing_window) = existing_window {
existing_window
.update(cx, |_, window, _| window.activate_window())
.update(cx, |prompt_library, window, cx| {
if let Some(prompt_to_focus) = prompt_to_focus {
prompt_library.load_prompt(prompt_to_focus, true, window, cx);
}
window.activate_window()
})
.ok();
Some(existing_window)
@ -120,14 +126,18 @@ pub fn open_prompt_library(
},
|window, cx| {
cx.new(|cx| {
PromptLibrary::new(
let mut prompt_library = PromptLibrary::new(
store,
language_registry,
inline_assist_delegate,
make_completion_provider,
window,
cx,
)
);
if let Some(prompt_to_focus) = prompt_to_focus {
prompt_library.load_prompt(prompt_to_focus, true, window, cx);
}
prompt_library
})
},
)

View file

@ -15,6 +15,7 @@ use std::{
};
use text::LineEnding;
use util::{ResultExt, get_system_shell};
use uuid::Uuid;
#[derive(Debug, Clone, Serialize)]
pub struct ProjectContext {
@ -51,6 +52,7 @@ impl ProjectContext {
#[derive(Debug, Clone, Serialize)]
pub struct DefaultUserRulesContext {
pub uuid: Uuid,
pub title: Option<String>,
pub contents: String,
}
@ -409,6 +411,7 @@ mod test {
}),
}];
let default_user_rules = vec![DefaultUserRulesContext {
uuid: Uuid::nil(),
title: Some("Rules title".into()),
contents: "Rules contents".into(),
}];

View file

@ -13,3 +13,4 @@ gpui.workspace = true
schemars.workspace = true
serde.workspace = true
workspace-hack.workspace = true
uuid.workspace = true

View file

@ -190,13 +190,21 @@ pub mod agent {
}
pub mod assistant {
use gpui::{action_with_deprecated_aliases, actions, impl_actions};
use gpui::{actions, impl_action_with_deprecated_aliases, impl_actions};
use schemars::JsonSchema;
use serde::Deserialize;
use uuid::Uuid;
actions!(assistant, [ToggleFocus, ShowConfiguration]);
action_with_deprecated_aliases!(
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct OpenPromptLibrary {
#[serde(skip)]
pub prompt_to_focus: Option<Uuid>,
}
impl_action_with_deprecated_aliases!(
assistant,
OpenPromptLibrary,
["assistant::DeployPromptLibrary"]