mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
internal: Allow OnTypeFormatting to send SnippetTextEdit
But continue to send TextEdit only.
This commit is contained in:
parent
3de03d4c61
commit
636d4880c4
5 changed files with 38 additions and 15 deletions
|
@ -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!(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue