Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide/src/typing.rs22
-rw-r--r--crates/rust-analyzer/src/handlers.rs6
-rw-r--r--crates/rust-analyzer/src/lsp_ext.rs17
-rw-r--r--crates/rust-analyzer/src/main_loop.rs2
-rw-r--r--docs/dev/lsp-extensions.md6
5 files changed, 38 insertions, 15 deletions
diff --git a/crates/ide/src/typing.rs b/crates/ide/src/typing.rs
index a75e6be8b8..d423d8a054 100644
--- a/crates/ide/src/typing.rs
+++ b/crates/ide/src/typing.rs
@@ -34,6 +34,11 @@ pub(crate) use on_enter::on_enter;
// Don't forget to add new trigger characters to `server_capabilities` in `caps.rs`.
pub(crate) const TRIGGER_CHARS: &str = ".=>{";
+struct ExtendedTextEdit {
+ edit: TextEdit,
+ is_snippet: bool,
+}
+
// Feature: On Typing Assists
//
// Some features trigger on typing certain characters:
@@ -68,22 +73,27 @@ pub(crate) fn on_char_typed(
return None;
}
let edit = on_char_typed_inner(file, position.offset, char_typed)?;
- Some(SourceChange::from_text_edit(position.file_id, edit))
+ let mut sc = SourceChange::from_text_edit(position.file_id, edit.edit);
+ sc.is_snippet = edit.is_snippet;
+ Some(sc)
}
fn on_char_typed_inner(
file: &Parse<SourceFile>,
offset: TextSize,
char_typed: char,
-) -> Option<TextEdit> {
+) -> Option<ExtendedTextEdit> {
+ fn conv(text_edit: Option<TextEdit>) -> Option<ExtendedTextEdit> {
+ Some(ExtendedTextEdit { edit: text_edit?, is_snippet: false })
+ }
if !stdx::always!(TRIGGER_CHARS.contains(char_typed)) {
return None;
}
match char_typed {
- '.' => on_dot_typed(&file.tree(), offset),
- '=' => on_eq_typed(&file.tree(), offset),
- '>' => on_arrow_typed(&file.tree(), offset),
- '{' => on_opening_brace_typed(file, offset),
+ '.' => conv(on_dot_typed(&file.tree(), offset)),
+ '=' => conv(on_eq_typed(&file.tree(), offset)),
+ '>' => conv(on_arrow_typed(&file.tree(), offset)),
+ '{' => conv(on_opening_brace_typed(file, offset)),
_ => unreachable!(),
}
}
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 261c02816d..a16f0d904c 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -276,7 +276,7 @@ pub(crate) fn handle_on_enter(
pub(crate) fn handle_on_type_formatting(
snap: GlobalStateSnapshot,
params: lsp_types::DocumentOnTypeFormattingParams,
-) -> Result<Option<Vec<lsp_types::TextEdit>>> {
+) -> Result<Option<Vec<lsp_ext::SnippetTextEdit>>> {
let _p = profile::span("handle_on_type_formatting");
let mut position = from_proto::file_position(&snap, params.text_document_position)?;
let line_index = snap.file_line_index(position.file_id)?;
@@ -306,9 +306,9 @@ pub(crate) fn handle_on_type_formatting(
};
// This should be a single-file edit
- let (_, edit) = edit.source_file_edits.into_iter().next().unwrap();
+ let (_, text_edit) = edit.source_file_edits.into_iter().next().unwrap();
- let change = to_proto::text_edit_vec(&line_index, edit);
+ let change = to_proto::snippet_text_edit_vec(&line_index, edit.is_snippet, text_edit);
Ok(Some(change))
}
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs
index c1b230bd9d..5f0e108624 100644
--- a/crates/rust-analyzer/src/lsp_ext.rs
+++ b/crates/rust-analyzer/src/lsp_ext.rs
@@ -4,8 +4,8 @@ use std::{collections::HashMap, path::PathBuf};
use lsp_types::request::Request;
use lsp_types::{
- notification::Notification, CodeActionKind, PartialResultParams, Position, Range,
- TextDocumentIdentifier, WorkDoneProgressParams,
+ notification::Notification, CodeActionKind, DocumentOnTypeFormattingParams,
+ PartialResultParams, Position, Range, TextDocumentIdentifier, WorkDoneProgressParams,
};
use serde::{Deserialize, Serialize};
@@ -512,6 +512,19 @@ pub enum WorkspaceSymbolSearchKind {
AllSymbols,
}
+/// The document on type formatting request is sent from the client to
+/// the server to format parts of the document during typing. This is
+/// almost same as lsp_types::request::OnTypeFormatting, but the
+/// result has SnippetTextEdit in it instead of TextEdit.
+#[derive(Debug)]
+pub enum OnTypeFormatting {}
+
+impl Request for OnTypeFormatting {
+ type Params = DocumentOnTypeFormattingParams;
+ type Result = Option<Vec<SnippetTextEdit>>;
+ const METHOD: &'static str = "textDocument/onTypeFormatting";
+}
+
#[derive(Debug, Serialize, Deserialize)]
pub struct CompletionResolveData {
pub position: lsp_types::TextDocumentPositionParams,
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index b5ac55e60d..3c87968743 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -605,7 +605,7 @@ impl GlobalState {
.on::<lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml)
.on::<lsp_ext::MoveItem>(handlers::handle_move_item)
.on::<lsp_ext::WorkspaceSymbol>(handlers::handle_workspace_symbol)
- .on::<lsp_types::request::OnTypeFormatting>(handlers::handle_on_type_formatting)
+ .on::<lsp_ext::OnTypeFormatting>(handlers::handle_on_type_formatting)
.on::<lsp_types::request::DocumentSymbolRequest>(handlers::handle_document_symbol)
.on::<lsp_types::request::GotoDefinition>(handlers::handle_goto_definition)
.on::<lsp_types::request::GotoDeclaration>(handlers::handle_goto_declaration)
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md
index 875561608d..983d8e1ac0 100644
--- a/docs/dev/lsp-extensions.md
+++ b/docs/dev/lsp-extensions.md
@@ -1,5 +1,5 @@
<!---
-lsp_ext.rs hash: 44e8238e4fbd4128
+lsp_ext.rs hash: 2a188defec26cc7c
If you need to change the above hash to make the test pass, please check if you
need to adjust this doc as well and ping this issue:
@@ -47,7 +47,7 @@ If a language client does not know about `rust-analyzer`'s configuration options
**Experimental Client Capability:** `{ "snippetTextEdit": boolean }`
-If this capability is set, `WorkspaceEdit`s returned from `codeAction` requests might contain `SnippetTextEdit`s instead of usual `TextEdit`s:
+If this capability is set, `WorkspaceEdit`s returned from `codeAction` requests and `TextEdit`s returned from `textDocument/onTypeFormatting` requests might contain `SnippetTextEdit`s instead of usual `TextEdit`s:
```typescript
interface SnippetTextEdit extends TextEdit {
@@ -63,7 +63,7 @@ export interface TextDocumentEdit {
}
```
-When applying such code action, the editor should insert snippet, with tab stops and placeholder.
+When applying such code action or text edit, the editor should insert snippet, with tab stops and placeholder.
At the moment, rust-analyzer guarantees that only a single edit will have `InsertTextFormat.Snippet`.
### Example