Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 636d488

Browse files
committed
internal: Allow OnTypeFormatting to send SnippetTextEdit
But continue to send TextEdit only.
1 parent 3de03d4 commit 636d488

File tree

5 files changed

+38
-15
lines changed

5 files changed

+38
-15
lines changed

crates/ide/src/typing.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ pub(crate) use on_enter::on_enter;
3434
// Don't forget to add new trigger characters to `server_capabilities` in `caps.rs`.
3535
pub(crate) const TRIGGER_CHARS: &str = ".=>{";
3636

37+
struct ExtendedTextEdit {
38+
edit: TextEdit,
39+
is_snippet: bool,
40+
}
41+
3742
// Feature: On Typing Assists
3843
//
3944
// Some features trigger on typing certain characters:
@@ -68,22 +73,27 @@ pub(crate) fn on_char_typed(
6873
return None;
6974
}
7075
let edit = on_char_typed_inner(file, position.offset, char_typed)?;
71-
Some(SourceChange::from_text_edit(position.file_id, edit))
76+
let mut sc = SourceChange::from_text_edit(position.file_id, edit.edit);
77+
sc.is_snippet = edit.is_snippet;
78+
Some(sc)
7279
}
7380

7481
fn on_char_typed_inner(
7582
file: &Parse<SourceFile>,
7683
offset: TextSize,
7784
char_typed: char,
78-
) -> Option<TextEdit> {
85+
) -> Option<ExtendedTextEdit> {
86+
fn conv(text_edit: Option<TextEdit>) -> Option<ExtendedTextEdit> {
87+
Some(ExtendedTextEdit { edit: text_edit?, is_snippet: false })
88+
}
7989
if !stdx::always!(TRIGGER_CHARS.contains(char_typed)) {
8090
return None;
8191
}
8292
match char_typed {
83-
'.' => on_dot_typed(&file.tree(), offset),
84-
'=' => on_eq_typed(&file.tree(), offset),
85-
'>' => on_arrow_typed(&file.tree(), offset),
86-
'{' => on_opening_brace_typed(file, offset),
93+
'.' => conv(on_dot_typed(&file.tree(), offset)),
94+
'=' => conv(on_eq_typed(&file.tree(), offset)),
95+
'>' => conv(on_arrow_typed(&file.tree(), offset)),
96+
'{' => conv(on_opening_brace_typed(file, offset)),
8797
_ => unreachable!(),
8898
}
8999
}

crates/rust-analyzer/src/handlers.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ pub(crate) fn handle_on_enter(
276276
pub(crate) fn handle_on_type_formatting(
277277
snap: GlobalStateSnapshot,
278278
params: lsp_types::DocumentOnTypeFormattingParams,
279-
) -> Result<Option<Vec<lsp_types::TextEdit>>> {
279+
) -> Result<Option<Vec<lsp_ext::SnippetTextEdit>>> {
280280
let _p = profile::span("handle_on_type_formatting");
281281
let mut position = from_proto::file_position(&snap, params.text_document_position)?;
282282
let line_index = snap.file_line_index(position.file_id)?;
@@ -306,9 +306,9 @@ pub(crate) fn handle_on_type_formatting(
306306
};
307307

308308
// This should be a single-file edit
309-
let (_, edit) = edit.source_file_edits.into_iter().next().unwrap();
309+
let (_, text_edit) = edit.source_file_edits.into_iter().next().unwrap();
310310

311-
let change = to_proto::text_edit_vec(&line_index, edit);
311+
let change = to_proto::snippet_text_edit_vec(&line_index, edit.is_snippet, text_edit);
312312
Ok(Some(change))
313313
}
314314

crates/rust-analyzer/src/lsp_ext.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use std::{collections::HashMap, path::PathBuf};
44

55
use lsp_types::request::Request;
66
use lsp_types::{
7-
notification::Notification, CodeActionKind, PartialResultParams, Position, Range,
8-
TextDocumentIdentifier, WorkDoneProgressParams,
7+
notification::Notification, CodeActionKind, DocumentOnTypeFormattingParams,
8+
PartialResultParams, Position, Range, TextDocumentIdentifier, WorkDoneProgressParams,
99
};
1010
use serde::{Deserialize, Serialize};
1111

@@ -512,6 +512,19 @@ pub enum WorkspaceSymbolSearchKind {
512512
AllSymbols,
513513
}
514514

515+
/// The document on type formatting request is sent from the client to
516+
/// the server to format parts of the document during typing. This is
517+
/// almost same as lsp_types::request::OnTypeFormatting, but the
518+
/// result has SnippetTextEdit in it instead of TextEdit.
519+
#[derive(Debug)]
520+
pub enum OnTypeFormatting {}
521+
522+
impl Request for OnTypeFormatting {
523+
type Params = DocumentOnTypeFormattingParams;
524+
type Result = Option<Vec<SnippetTextEdit>>;
525+
const METHOD: &'static str = "textDocument/onTypeFormatting";
526+
}
527+
515528
#[derive(Debug, Serialize, Deserialize)]
516529
pub struct CompletionResolveData {
517530
pub position: lsp_types::TextDocumentPositionParams,

crates/rust-analyzer/src/main_loop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ impl GlobalState {
605605
.on::<lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml)
606606
.on::<lsp_ext::MoveItem>(handlers::handle_move_item)
607607
.on::<lsp_ext::WorkspaceSymbol>(handlers::handle_workspace_symbol)
608-
.on::<lsp_types::request::OnTypeFormatting>(handlers::handle_on_type_formatting)
608+
.on::<lsp_ext::OnTypeFormatting>(handlers::handle_on_type_formatting)
609609
.on::<lsp_types::request::DocumentSymbolRequest>(handlers::handle_document_symbol)
610610
.on::<lsp_types::request::GotoDefinition>(handlers::handle_goto_definition)
611611
.on::<lsp_types::request::GotoDeclaration>(handlers::handle_goto_declaration)

docs/dev/lsp-extensions.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!---
2-
lsp_ext.rs hash: 44e8238e4fbd4128
2+
lsp_ext.rs hash: 2a188defec26cc7c
33
44
If you need to change the above hash to make the test pass, please check if you
55
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
4747

4848
**Experimental Client Capability:** `{ "snippetTextEdit": boolean }`
4949

50-
If this capability is set, `WorkspaceEdit`s returned from `codeAction` requests might contain `SnippetTextEdit`s instead of usual `TextEdit`s:
50+
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:
5151

5252
```typescript
5353
interface SnippetTextEdit extends TextEdit {
@@ -63,7 +63,7 @@ export interface TextDocumentEdit {
6363
}
6464
```
6565

66-
When applying such code action, the editor should insert snippet, with tab stops and placeholder.
66+
When applying such code action or text edit, the editor should insert snippet, with tab stops and placeholder.
6767
At the moment, rust-analyzer guarantees that only a single edit will have `InsertTextFormat.Snippet`.
6868

6969
### Example

0 commit comments

Comments
 (0)