Detailed changes
@@ -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,
})
}
}