mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-29 12:38:02 +00:00
Run slash commands both on enter and on argument completion that requires it (#16283)
Release Notes: - N/A
This commit is contained in:
parent
5a30e29848
commit
c45adce2e3
9 changed files with 61 additions and 34 deletions
|
@ -2081,7 +2081,7 @@ impl ContextEditor {
|
|||
}
|
||||
|
||||
editor.insert(&format!("/{name}"), cx);
|
||||
if command.requires_argument() {
|
||||
if command.accepts_arguments() {
|
||||
editor.insert(" ", cx);
|
||||
editor.show_completions(&ShowCompletions::default(), cx);
|
||||
}
|
||||
|
@ -2094,6 +2094,10 @@ impl ContextEditor {
|
|||
}
|
||||
|
||||
pub fn confirm_command(&mut self, _: &ConfirmCommand, cx: &mut ViewContext<Self>) {
|
||||
if self.editor.read(cx).has_active_completions_menu() {
|
||||
return;
|
||||
}
|
||||
|
||||
let selections = self.editor.read(cx).selections.disjoint_anchors();
|
||||
let mut commands_by_range = HashMap::default();
|
||||
let workspace = self.workspace.clone();
|
||||
|
|
|
@ -97,20 +97,25 @@ impl SlashCommandCompletionProvider {
|
|||
let command = commands.command(&mat.string)?;
|
||||
let mut new_text = mat.string.clone();
|
||||
let requires_argument = command.requires_argument();
|
||||
if requires_argument {
|
||||
let accepts_arguments = command.accepts_arguments();
|
||||
if requires_argument || accepts_arguments {
|
||||
new_text.push(' ');
|
||||
}
|
||||
|
||||
let confirm = editor.clone().zip(workspace.clone()).and_then(
|
||||
|(editor, workspace)| {
|
||||
(!requires_argument).then(|| {
|
||||
let confirm =
|
||||
editor
|
||||
.clone()
|
||||
.zip(workspace.clone())
|
||||
.map(|(editor, workspace)| {
|
||||
let command_name = mat.string.clone();
|
||||
let command_range = command_range.clone();
|
||||
let editor = editor.clone();
|
||||
let workspace = workspace.clone();
|
||||
Arc::new(
|
||||
move |intent: CompletionIntent, cx: &mut WindowContext| {
|
||||
if intent.is_complete() {
|
||||
if !requires_argument
|
||||
&& (!accepts_arguments || intent.is_complete())
|
||||
{
|
||||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
editor.run_command(
|
||||
|
@ -123,12 +128,13 @@ impl SlashCommandCompletionProvider {
|
|||
);
|
||||
})
|
||||
.ok();
|
||||
false
|
||||
} else {
|
||||
requires_argument || accepts_arguments
|
||||
}
|
||||
},
|
||||
) as Arc<_>
|
||||
})
|
||||
},
|
||||
);
|
||||
});
|
||||
Some(project::Completion {
|
||||
old_range: name_range.clone(),
|
||||
documentation: Some(Documentation::SingleLine(command.description())),
|
||||
|
@ -136,7 +142,6 @@ impl SlashCommandCompletionProvider {
|
|||
label: command.label(cx),
|
||||
server_id: LanguageServerId(0),
|
||||
lsp_completion: Default::default(),
|
||||
show_new_completions_on_confirm: requires_argument,
|
||||
confirm,
|
||||
})
|
||||
})
|
||||
|
@ -175,7 +180,7 @@ impl SlashCommandCompletionProvider {
|
|||
.await?
|
||||
.into_iter()
|
||||
.map(|new_argument| {
|
||||
let confirm = if new_argument.run_command {
|
||||
let confirm =
|
||||
editor
|
||||
.clone()
|
||||
.zip(workspace.clone())
|
||||
|
@ -192,7 +197,7 @@ impl SlashCommandCompletionProvider {
|
|||
let command_range = command_range.clone();
|
||||
let command_name = command_name.clone();
|
||||
move |intent: CompletionIntent, cx: &mut WindowContext| {
|
||||
if intent.is_complete() {
|
||||
if new_argument.run_command || intent.is_complete() {
|
||||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
editor.run_command(
|
||||
|
@ -205,13 +210,13 @@ impl SlashCommandCompletionProvider {
|
|||
);
|
||||
})
|
||||
.ok();
|
||||
false
|
||||
} else {
|
||||
!new_argument.run_command
|
||||
}
|
||||
}
|
||||
}) as Arc<_>
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
});
|
||||
|
||||
let mut new_text = new_argument.new_text.clone();
|
||||
if !new_argument.run_command {
|
||||
|
@ -229,7 +234,6 @@ impl SlashCommandCompletionProvider {
|
|||
documentation: None,
|
||||
server_id: LanguageServerId(0),
|
||||
lsp_completion: Default::default(),
|
||||
show_new_completions_on_confirm: !new_argument.run_command,
|
||||
confirm,
|
||||
}
|
||||
})
|
||||
|
|
|
@ -103,6 +103,10 @@ impl SlashCommand for DiagnosticsSlashCommand {
|
|||
false
|
||||
}
|
||||
|
||||
fn accepts_arguments(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn complete_argument(
|
||||
self: Arc<Self>,
|
||||
arguments: &[String],
|
||||
|
|
|
@ -39,6 +39,10 @@ impl SlashCommand for TabSlashCommand {
|
|||
false
|
||||
}
|
||||
|
||||
fn accepts_arguments(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn complete_argument(
|
||||
self: Arc<Self>,
|
||||
arguments: &[String],
|
||||
|
@ -94,15 +98,16 @@ impl SlashCommand for TabSlashCommand {
|
|||
})
|
||||
});
|
||||
|
||||
let active_item_completion = active_item_path.as_deref().map(|active_item_path| {
|
||||
let path_string = active_item_path.to_string_lossy().to_string();
|
||||
ArgumentCompletion {
|
||||
let active_item_completion = active_item_path
|
||||
.as_deref()
|
||||
.map(|active_item_path| active_item_path.to_string_lossy().to_string())
|
||||
.filter(|path_string| !argument_set.contains(path_string))
|
||||
.map(|path_string| ArgumentCompletion {
|
||||
label: path_string.clone().into(),
|
||||
new_text: path_string,
|
||||
replace_previous_arguments: false,
|
||||
run_command,
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Ok(active_item_completion
|
||||
.into_iter()
|
||||
|
|
|
@ -40,6 +40,10 @@ impl SlashCommand for TerminalSlashCommand {
|
|||
false
|
||||
}
|
||||
|
||||
fn accepts_arguments(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn complete_argument(
|
||||
self: Arc<Self>,
|
||||
_arguments: &[String],
|
||||
|
|
|
@ -42,6 +42,9 @@ pub trait SlashCommand: 'static + Send + Sync {
|
|||
cx: &mut WindowContext,
|
||||
) -> Task<Result<Vec<ArgumentCompletion>>>;
|
||||
fn requires_argument(&self) -> bool;
|
||||
fn accepts_arguments(&self) -> bool {
|
||||
self.requires_argument()
|
||||
}
|
||||
fn run(
|
||||
self: Arc<Self>,
|
||||
arguments: &[String],
|
||||
|
|
|
@ -314,7 +314,6 @@ impl MessageEditor {
|
|||
server_id: LanguageServerId(0), // TODO: Make this optional or something?
|
||||
lsp_completion: Default::default(), // TODO: Make this optional or something?
|
||||
confirm: None,
|
||||
show_new_completions_on_confirm: false,
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
|
|
|
@ -4379,11 +4379,11 @@ impl Editor {
|
|||
this.refresh_inline_completion(true, cx);
|
||||
});
|
||||
|
||||
if let Some(confirm) = completion.confirm.as_ref() {
|
||||
(confirm)(intent, cx);
|
||||
}
|
||||
|
||||
if completion.show_new_completions_on_confirm {
|
||||
let show_new_completions_on_confirm = completion
|
||||
.confirm
|
||||
.as_ref()
|
||||
.map_or(false, |confirm| confirm(intent, cx));
|
||||
if show_new_completions_on_confirm {
|
||||
self.show_completions(&ShowCompletions { trigger: None }, cx);
|
||||
}
|
||||
|
||||
|
@ -11926,6 +11926,12 @@ impl Editor {
|
|||
let bounds = self.last_bounds?;
|
||||
Some(element::gutter_bounds(bounds, self.gutter_dimensions))
|
||||
}
|
||||
|
||||
pub fn has_active_completions_menu(&self) -> bool {
|
||||
self.context_menu.read().as_ref().map_or(false, |menu| {
|
||||
menu.visible() && matches!(menu, ContextMenu::Completions(_))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn hunks_for_selections(
|
||||
|
@ -12141,7 +12147,6 @@ fn snippet_completions(
|
|||
..Default::default()
|
||||
},
|
||||
confirm: None,
|
||||
show_new_completions_on_confirm: false,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
|
|
|
@ -450,9 +450,10 @@ pub struct Completion {
|
|||
/// The raw completion provided by the language server.
|
||||
pub lsp_completion: lsp::CompletionItem,
|
||||
/// An optional callback to invoke when this completion is confirmed.
|
||||
pub confirm: Option<Arc<dyn Send + Sync + Fn(CompletionIntent, &mut WindowContext)>>,
|
||||
/// If true, the editor will show a new completion menu after this completion is confirmed.
|
||||
pub show_new_completions_on_confirm: bool,
|
||||
/// Returns, whether new completions should be retriggered after the current one.
|
||||
/// If `true` is returned, the editor will show a new completion menu after this completion is confirmed.
|
||||
/// if no confirmation is provided or `false` is returned, the completion will be committed.
|
||||
pub confirm: Option<Arc<dyn Send + Sync + Fn(CompletionIntent, &mut WindowContext) -> bool>>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Completion {
|
||||
|
@ -9128,7 +9129,6 @@ impl Project {
|
|||
filter_range: Default::default(),
|
||||
},
|
||||
confirm: None,
|
||||
show_new_completions_on_confirm: false,
|
||||
},
|
||||
false,
|
||||
cx,
|
||||
|
@ -10765,7 +10765,6 @@ async fn populate_labels_for_completions(
|
|||
documentation,
|
||||
lsp_completion,
|
||||
confirm: None,
|
||||
show_new_completions_on_confirm: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue