Detailed changes
@@ -112,6 +112,7 @@ impl ContextPickerCompletionProvider {
icon_path: Some(mode.icon().path().into()),
documentation: None,
source: project::CompletionSource::Custom,
+ insert_text_mode: None,
// This ensures that when a user accepts this completion, the
// completion menu will still be shown after "@category " is
// inserted
@@ -163,6 +164,7 @@ impl ContextPickerCompletionProvider {
new_text,
label: CodeLabel::plain(thread_entry.summary.to_string(), None),
documentation: None,
+ insert_text_mode: None,
source: project::CompletionSource::Custom,
icon_path: Some(icon_for_completion.path().into()),
confirm: Some(confirm_completion_callback(
@@ -209,6 +211,7 @@ impl ContextPickerCompletionProvider {
documentation: None,
source: project::CompletionSource::Custom,
icon_path: Some(IconName::Globe.path().into()),
+ insert_text_mode: None,
confirm: Some(confirm_completion_callback(
IconName::Globe.path().into(),
url_to_fetch.clone(),
@@ -290,6 +293,7 @@ impl ContextPickerCompletionProvider {
documentation: None,
source: project::CompletionSource::Custom,
icon_path: Some(completion_icon_path),
+ insert_text_mode: None,
confirm: Some(confirm_completion_callback(
crease_icon_path,
file_name,
@@ -352,6 +356,7 @@ impl ContextPickerCompletionProvider {
documentation: None,
source: project::CompletionSource::Custom,
icon_path: Some(IconName::Code.path().into()),
+ insert_text_mode: None,
confirm: Some(confirm_completion_callback(
IconName::Code.path().into(),
symbol.name.clone().into(),
@@ -127,6 +127,7 @@ impl SlashCommandCompletionProvider {
new_text,
label: command.label(cx),
icon_path: None,
+ insert_text_mode: None,
confirm,
source: CompletionSource::Custom,
})
@@ -228,6 +229,7 @@ impl SlashCommandCompletionProvider {
new_text,
documentation: None,
confirm,
+ insert_text_mode: None,
source: CompletionSource::Custom,
}
})
@@ -315,6 +315,7 @@ impl MessageEditor {
icon_path: None,
confirm: None,
documentation: None,
+ insert_text_mode: None,
source: CompletionSource::Custom,
}
})
@@ -367,6 +367,7 @@ impl ConsoleQueryBarCompletionProvider {
documentation: None,
confirm: None,
source: project::CompletionSource::Custom,
+ insert_text_mode: None,
})
})
.collect(),
@@ -409,6 +410,7 @@ impl ConsoleQueryBarCompletionProvider {
documentation: None,
confirm: None,
source: project::CompletionSource::Custom,
+ insert_text_mode: None,
})
.collect(),
))
@@ -240,6 +240,7 @@ impl CompletionsMenu {
icon_path: None,
documentation: None,
confirm: None,
+ insert_text_mode: None,
source: CompletionSource::Custom,
})
.collect();
@@ -136,7 +136,7 @@ use task::{ResolvedTask, TaskTemplate, TaskVariables};
pub use lsp::CompletionContext;
use lsp::{
CodeActionKind, CompletionItemKind, CompletionTriggerKind, DiagnosticSeverity,
- InsertTextFormat, LanguageServerId, LanguageServerName,
+ InsertTextFormat, InsertTextMode, LanguageServerId, LanguageServerName,
};
use language::BufferSnapshot;
@@ -4442,6 +4442,7 @@ impl Editor {
word_range,
resolved: false,
},
+ insert_text_mode: Some(InsertTextMode::AS_IS),
confirm: None,
}));
@@ -4687,7 +4688,13 @@ impl Editor {
} else {
this.buffer.update(cx, |buffer, cx| {
let edits = ranges.iter().map(|range| (range.clone(), text));
- buffer.edit(edits, this.autoindent_mode.clone(), cx);
+ let auto_indent = if completion.insert_text_mode == Some(InsertTextMode::AS_IS)
+ {
+ None
+ } else {
+ this.autoindent_mode.clone()
+ };
+ buffer.edit(edits, auto_indent, cx);
});
}
for (buffer, edits) in linked_edits {
@@ -18637,6 +18644,7 @@ fn snippet_completions(
.description
.clone()
.map(|description| CompletionDocumentation::SingleLine(description.into())),
+ insert_text_mode: None,
confirm: None,
})
})
@@ -10235,6 +10235,62 @@ async fn test_completion_sort(cx: &mut TestAppContext) {
});
}
+#[gpui::test]
+async fn test_as_is_completions(cx: &mut TestAppContext) {
+ init_test(cx, |_| {});
+ let mut cx = EditorLspTestContext::new_rust(
+ lsp::ServerCapabilities {
+ completion_provider: Some(lsp::CompletionOptions {
+ ..Default::default()
+ }),
+ ..Default::default()
+ },
+ cx,
+ )
+ .await;
+ cx.lsp
+ .set_request_handler::<lsp::request::Completion, _, _>(move |_, _| async move {
+ Ok(Some(lsp::CompletionResponse::Array(vec![
+ lsp::CompletionItem {
+ label: "unsafe".into(),
+ text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
+ range: lsp::Range {
+ start: lsp::Position {
+ line: 1,
+ character: 2,
+ },
+ end: lsp::Position {
+ line: 1,
+ character: 3,
+ },
+ },
+ new_text: "unsafe".to_string(),
+ })),
+ insert_text_mode: Some(lsp::InsertTextMode::AS_IS),
+ ..Default::default()
+ },
+ ])))
+ });
+ cx.set_state("fn a() {}\n nˇ");
+ cx.executor().run_until_parked();
+ cx.update_editor(|editor, window, cx| {
+ editor.show_completions(
+ &ShowCompletions {
+ trigger: Some("\n".into()),
+ },
+ window,
+ cx,
+ );
+ });
+ cx.executor().run_until_parked();
+
+ cx.update_editor(|editor, window, cx| {
+ editor.confirm_completion(&Default::default(), window, cx)
+ });
+ cx.executor().run_until_parked();
+ cx.assert_editor_state("fn a() {}\n unsafeˇ");
+}
+
#[gpui::test]
async fn test_no_duplicated_completion_requests(cx: &mut TestAppContext) {
init_test(cx, |_| {});
@@ -704,8 +704,15 @@ impl LanguageServer {
}),
insert_replace_support: Some(true),
label_details_support: Some(true),
+ insert_text_mode_support: Some(InsertTextModeSupport {
+ value_set: vec![
+ InsertTextMode::AS_IS,
+ InsertTextMode::ADJUST_INDENTATION,
+ ],
+ }),
..Default::default()
}),
+ insert_text_mode: Some(InsertTextMode::ADJUST_INDENTATION),
completion_list: Some(CompletionListCapability {
item_defaults: Some(vec![
"commitCharacters".to_owned(),
@@ -8053,6 +8053,7 @@ impl LspStore {
runs: Default::default(),
filter_range: Default::default(),
},
+ insert_text_mode: None,
icon_path: None,
confirm: None,
}]))),
@@ -9342,6 +9343,7 @@ async fn populate_labels_for_completions(
documentation,
old_range: completion.old_range,
new_text: completion.new_text,
+ insert_text_mode: lsp_completion.insert_text_mode,
source: completion.source,
icon_path: None,
confirm: None,
@@ -9356,6 +9358,7 @@ async fn populate_labels_for_completions(
old_range: completion.old_range,
new_text: completion.new_text,
source: completion.source,
+ insert_text_mode: None,
icon_path: None,
confirm: None,
});
@@ -68,8 +68,8 @@ use language::{
language_settings::InlayHintKind, proto::split_operations,
};
use lsp::{
- CodeActionKind, CompletionContext, CompletionItemKind, DocumentHighlightKind, LanguageServerId,
- LanguageServerName, MessageActionItem,
+ CodeActionKind, CompletionContext, CompletionItemKind, DocumentHighlightKind, InsertTextMode,
+ LanguageServerId, LanguageServerName, MessageActionItem,
};
use lsp_command::*;
use lsp_store::{CompletionDocumentation, LspFormatTarget, OpenLspBufferHandle};
@@ -392,6 +392,8 @@ pub struct Completion {
pub source: CompletionSource,
/// A path to an icon for this completion that is shown in the menu.
pub icon_path: Option<SharedString>,
+ /// Whether to adjust indentation (the default) or not.
+ pub insert_text_mode: Option<InsertTextMode>,
/// An optional callback to invoke when this completion is confirmed.
/// 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.