mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
8510: Move cursor position when using item movers r=jonas-schievink a=jonas-schievink This updates the cursor position when moving items around to stay in the same location within the moved node. I changed the `moveItem` response to `SnippetTextEdit[]`, since that made more sense to me (the file was ignored by the client anyways, since the edits always apply to the current document). It also matches `onEnter`, which seems logical to me, but please let me know if this doesn't make sense. There's still a bug in the client-side snippet code that will cause the cursor position to be slightly off when moving parameters in the same line (presumably we don't track the column correctly after deleting `$0`). Not really sure how to fix that immediately, but this PR should already be an improvement despite that bug. 8533: Fix typo in style guide r=jonas-schievink a=jonas-schievink Fixes bold text rendering bors r+ Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
This commit is contained in:
commit
3af303600a
8 changed files with 84 additions and 75 deletions
|
@ -1,4 +1,4 @@
|
||||||
use std::iter::once;
|
use std::{iter::once, mem};
|
||||||
|
|
||||||
use hir::Semantics;
|
use hir::Semantics;
|
||||||
use ide_db::{base_db::FileRange, RootDatabase};
|
use ide_db::{base_db::FileRange, RootDatabase};
|
||||||
|
@ -102,7 +102,7 @@ fn move_in_direction(
|
||||||
ast::GenericArgList(it) => swap_sibling_in_list(node, it.generic_args(), range, direction),
|
ast::GenericArgList(it) => swap_sibling_in_list(node, it.generic_args(), range, direction),
|
||||||
ast::VariantList(it) => swap_sibling_in_list(node, it.variants(), range, direction),
|
ast::VariantList(it) => swap_sibling_in_list(node, it.variants(), range, direction),
|
||||||
ast::TypeBoundList(it) => swap_sibling_in_list(node, it.bounds(), range, direction),
|
ast::TypeBoundList(it) => swap_sibling_in_list(node, it.bounds(), range, direction),
|
||||||
_ => Some(replace_nodes(node, &match direction {
|
_ => Some(replace_nodes(range, node, &match direction {
|
||||||
Direction::Up => node.prev_sibling(),
|
Direction::Up => node.prev_sibling(),
|
||||||
Direction::Down => node.next_sibling(),
|
Direction::Down => node.next_sibling(),
|
||||||
}?))
|
}?))
|
||||||
|
@ -125,7 +125,7 @@ fn swap_sibling_in_list<A: AstNode + Clone, I: Iterator<Item = A>>(
|
||||||
.next();
|
.next();
|
||||||
|
|
||||||
if let Some((l, r)) = list_lookup {
|
if let Some((l, r)) = list_lookup {
|
||||||
Some(replace_nodes(l.syntax(), r.syntax()))
|
Some(replace_nodes(range, l.syntax(), r.syntax()))
|
||||||
} else {
|
} else {
|
||||||
// Cursor is beyond any movable list item (for example, on curly brace in enum).
|
// Cursor is beyond any movable list item (for example, on curly brace in enum).
|
||||||
// It's not necessary, that parent of list is movable (arg list's parent is not, for example),
|
// It's not necessary, that parent of list is movable (arg list's parent is not, for example),
|
||||||
|
@ -134,11 +134,38 @@ fn swap_sibling_in_list<A: AstNode + Clone, I: Iterator<Item = A>>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace_nodes(first: &SyntaxNode, second: &SyntaxNode) -> TextEdit {
|
fn replace_nodes<'a>(
|
||||||
|
range: TextRange,
|
||||||
|
mut first: &'a SyntaxNode,
|
||||||
|
mut second: &'a SyntaxNode,
|
||||||
|
) -> TextEdit {
|
||||||
|
let cursor_offset = if range.is_empty() {
|
||||||
|
// FIXME: `applySnippetTextEdits` does not support non-empty selection ranges
|
||||||
|
if first.text_range().contains_range(range) {
|
||||||
|
Some(range.start() - first.text_range().start())
|
||||||
|
} else if second.text_range().contains_range(range) {
|
||||||
|
mem::swap(&mut first, &mut second);
|
||||||
|
Some(range.start() - first.text_range().start())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let first_with_cursor = match cursor_offset {
|
||||||
|
Some(offset) => {
|
||||||
|
let mut item_text = first.text().to_string();
|
||||||
|
item_text.insert_str(offset.into(), "$0");
|
||||||
|
item_text
|
||||||
|
}
|
||||||
|
None => first.text().to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
let mut edit = TextEditBuilder::default();
|
let mut edit = TextEditBuilder::default();
|
||||||
|
|
||||||
algo::diff(first, second).into_text_edit(&mut edit);
|
algo::diff(first, second).into_text_edit(&mut edit);
|
||||||
algo::diff(second, first).into_text_edit(&mut edit);
|
edit.replace(second.text_range(), first_with_cursor);
|
||||||
|
|
||||||
edit.finish()
|
edit.finish()
|
||||||
}
|
}
|
||||||
|
@ -188,7 +215,7 @@ fn main() {
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
fn main() {
|
fn main() {
|
||||||
match true {
|
match true {
|
||||||
false => {
|
false =>$0 {
|
||||||
println!("Test");
|
println!("Test");
|
||||||
},
|
},
|
||||||
true => {
|
true => {
|
||||||
|
@ -222,7 +249,7 @@ fn main() {
|
||||||
false => {
|
false => {
|
||||||
println!("Test");
|
println!("Test");
|
||||||
},
|
},
|
||||||
true => {
|
true =>$0 {
|
||||||
println!("Hello, world");
|
println!("Hello, world");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -274,7 +301,7 @@ fn main() {
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
fn main() {
|
fn main() {
|
||||||
let test2 = 456;
|
let test2$0 = 456;
|
||||||
let test = 123;
|
let test = 123;
|
||||||
}
|
}
|
||||||
"#]],
|
"#]],
|
||||||
|
@ -293,7 +320,7 @@ fn main() {
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("All I want to say is...");
|
println!("All I want to say is...");$0
|
||||||
println!("Hello, world");
|
println!("Hello, world");
|
||||||
}
|
}
|
||||||
"#]],
|
"#]],
|
||||||
|
@ -313,7 +340,7 @@ fn main() {
|
||||||
fn main() {
|
fn main() {
|
||||||
if true {
|
if true {
|
||||||
println!("Test");
|
println!("Test");
|
||||||
}
|
}$0
|
||||||
|
|
||||||
println!("Hello, world");
|
println!("Hello, world");
|
||||||
}
|
}
|
||||||
|
@ -334,7 +361,7 @@ fn main() {
|
||||||
fn main() {
|
fn main() {
|
||||||
for i in 0..10 {
|
for i in 0..10 {
|
||||||
println!("Test");
|
println!("Test");
|
||||||
}
|
}$0
|
||||||
|
|
||||||
println!("Hello, world");
|
println!("Hello, world");
|
||||||
}
|
}
|
||||||
|
@ -355,7 +382,7 @@ fn main() {
|
||||||
fn main() {
|
fn main() {
|
||||||
loop {
|
loop {
|
||||||
println!("Test");
|
println!("Test");
|
||||||
}
|
}$0
|
||||||
|
|
||||||
println!("Hello, world");
|
println!("Hello, world");
|
||||||
}
|
}
|
||||||
|
@ -376,7 +403,7 @@ fn main() {
|
||||||
fn main() {
|
fn main() {
|
||||||
while true {
|
while true {
|
||||||
println!("Test");
|
println!("Test");
|
||||||
}
|
}$0
|
||||||
|
|
||||||
println!("Hello, world");
|
println!("Hello, world");
|
||||||
}
|
}
|
||||||
|
@ -393,7 +420,7 @@ fn main() {
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
fn main() {
|
fn main() {
|
||||||
return 123;
|
return 123;$0
|
||||||
|
|
||||||
println!("Hello, world");
|
println!("Hello, world");
|
||||||
}
|
}
|
||||||
|
@ -430,7 +457,7 @@ fn main() {}
|
||||||
fn foo() {}$0$0
|
fn foo() {}$0$0
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
fn foo() {}
|
fn foo() {}$0
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
"#]],
|
"#]],
|
||||||
|
@ -451,7 +478,7 @@ impl Wow for Yay $0$0{}
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
struct Yay;
|
struct Yay;
|
||||||
|
|
||||||
impl Wow for Yay {}
|
impl Wow for Yay $0{}
|
||||||
|
|
||||||
trait Wow {}
|
trait Wow {}
|
||||||
"#]],
|
"#]],
|
||||||
|
@ -467,7 +494,7 @@ use std::vec::Vec;
|
||||||
use std::collections::HashMap$0$0;
|
use std::collections::HashMap$0$0;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap$0;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
"#]],
|
"#]],
|
||||||
Direction::Up,
|
Direction::Up,
|
||||||
|
@ -502,7 +529,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_moves_param_up() {
|
fn test_moves_param() {
|
||||||
check(
|
check(
|
||||||
r#"
|
r#"
|
||||||
fn test(one: i32, two$0$0: u32) {}
|
fn test(one: i32, two$0$0: u32) {}
|
||||||
|
@ -512,7 +539,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
fn test(two: u32, one: i32) {}
|
fn test(two$0: u32, one: i32) {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
test(123, 456);
|
test(123, 456);
|
||||||
|
@ -520,6 +547,15 @@ fn main() {
|
||||||
"#]],
|
"#]],
|
||||||
Direction::Up,
|
Direction::Up,
|
||||||
);
|
);
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
fn f($0$0arg: u8, arg2: u16) {}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
fn f(arg2: u16, $0arg: u8) {}
|
||||||
|
"#]],
|
||||||
|
Direction::Down,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -536,7 +572,7 @@ fn main() {
|
||||||
fn test(one: i32, two: u32) {}
|
fn test(one: i32, two: u32) {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
test(456, 123);
|
test(456$0, 123);
|
||||||
}
|
}
|
||||||
"#]],
|
"#]],
|
||||||
Direction::Up,
|
Direction::Up,
|
||||||
|
@ -557,7 +593,7 @@ fn main() {
|
||||||
fn test(one: i32, two: u32) {}
|
fn test(one: i32, two: u32) {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
test(456, 123);
|
test(456, 123$0);
|
||||||
}
|
}
|
||||||
"#]],
|
"#]],
|
||||||
Direction::Down,
|
Direction::Down,
|
||||||
|
@ -594,7 +630,7 @@ struct Test<A, B$0$0>(A, B);
|
||||||
fn main() {}
|
fn main() {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
struct Test<B, A>(A, B);
|
struct Test<B$0, A>(A, B);
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
"#]],
|
"#]],
|
||||||
|
@ -616,7 +652,7 @@ fn main() {
|
||||||
struct Test<A, B>(A, B);
|
struct Test<A, B>(A, B);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let t = Test::<&str, i32>(123, "yay");
|
let t = Test::<&str$0, i32>(123, "yay");
|
||||||
}
|
}
|
||||||
"#]],
|
"#]],
|
||||||
Direction::Up,
|
Direction::Up,
|
||||||
|
@ -636,7 +672,7 @@ fn main() {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
enum Hello {
|
enum Hello {
|
||||||
Two,
|
Two$0,
|
||||||
One
|
One
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,7 +699,7 @@ trait One {}
|
||||||
|
|
||||||
trait Two {}
|
trait Two {}
|
||||||
|
|
||||||
fn test<T: Two + One>(t: T) {}
|
fn test<T: Two$0 + One>(t: T) {}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
"#]],
|
"#]],
|
||||||
|
@ -709,7 +745,7 @@ trait Yay {
|
||||||
impl Yay for Test {
|
impl Yay for Test {
|
||||||
type One = i32;
|
type One = i32;
|
||||||
|
|
||||||
fn inner() {
|
fn inner() {$0
|
||||||
println!("Mmmm");
|
println!("Mmmm");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -736,7 +772,7 @@ fn test() {
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
fn test() {
|
fn test() {
|
||||||
mod hi {
|
mod hi {$0
|
||||||
fn inner() {}
|
fn inner() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,7 +800,7 @@ fn main() {}
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
#[derive(Debug)]
|
$0#[derive(Debug)]
|
||||||
enum FooBar {
|
enum FooBar {
|
||||||
Foo,
|
Foo,
|
||||||
Bar,
|
Bar,
|
||||||
|
@ -784,7 +820,7 @@ fn main() {}
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
enum FooBar {
|
$0enum FooBar {
|
||||||
Foo,
|
Foo,
|
||||||
Bar,
|
Bar,
|
||||||
}
|
}
|
||||||
|
@ -804,7 +840,7 @@ fn main() {}
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
struct Test;
|
struct Test;
|
||||||
|
|
||||||
impl SomeTrait for Test {}
|
$0impl SomeTrait for Test {}
|
||||||
|
|
||||||
trait SomeTrait {}
|
trait SomeTrait {}
|
||||||
|
|
||||||
|
@ -831,7 +867,7 @@ fn main() {}
|
||||||
enum FooBar {
|
enum FooBar {
|
||||||
Foo,
|
Foo,
|
||||||
Bar,
|
Bar,
|
||||||
}
|
}$0
|
||||||
"#]],
|
"#]],
|
||||||
Direction::Down,
|
Direction::Down,
|
||||||
);
|
);
|
||||||
|
@ -848,7 +884,7 @@ fn main() {}
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
struct Test;
|
struct Test;
|
||||||
|
|
||||||
impl SomeTrait for Test {}
|
impl SomeTrait for Test {}$0
|
||||||
|
|
||||||
trait SomeTrait {}
|
trait SomeTrait {}
|
||||||
|
|
||||||
|
|
|
@ -1410,7 +1410,7 @@ pub(crate) fn handle_open_cargo_toml(
|
||||||
pub(crate) fn handle_move_item(
|
pub(crate) fn handle_move_item(
|
||||||
snap: GlobalStateSnapshot,
|
snap: GlobalStateSnapshot,
|
||||||
params: lsp_ext::MoveItemParams,
|
params: lsp_ext::MoveItemParams,
|
||||||
) -> Result<Option<lsp_types::TextDocumentEdit>> {
|
) -> Result<Vec<lsp_ext::SnippetTextEdit>> {
|
||||||
let _p = profile::span("handle_move_item");
|
let _p = profile::span("handle_move_item");
|
||||||
let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?;
|
let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?;
|
||||||
let range = from_proto::file_range(&snap, params.text_document, params.range)?;
|
let range = from_proto::file_range(&snap, params.text_document, params.range)?;
|
||||||
|
@ -1421,8 +1421,11 @@ pub(crate) fn handle_move_item(
|
||||||
};
|
};
|
||||||
|
|
||||||
match snap.analysis.move_item(range, direction)? {
|
match snap.analysis.move_item(range, direction)? {
|
||||||
Some(text_edit) => Ok(Some(to_proto::text_document_edit(&snap, file_id, text_edit)?)),
|
Some(text_edit) => {
|
||||||
None => Ok(None),
|
let line_index = snap.file_line_index(file_id)?;
|
||||||
|
Ok(to_proto::snippet_text_edit_vec(&line_index, true, text_edit))
|
||||||
|
}
|
||||||
|
None => Ok(vec![]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -407,7 +407,7 @@ pub enum MoveItem {}
|
||||||
|
|
||||||
impl Request for MoveItem {
|
impl Request for MoveItem {
|
||||||
type Params = MoveItemParams;
|
type Params = MoveItemParams;
|
||||||
type Result = Option<lsp_types::TextDocumentEdit>;
|
type Result = Vec<SnippetTextEdit>;
|
||||||
const METHOD: &'static str = "experimental/moveItem";
|
const METHOD: &'static str = "experimental/moveItem";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -688,18 +688,6 @@ pub(crate) fn goto_definition_response(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn text_document_edit(
|
|
||||||
snap: &GlobalStateSnapshot,
|
|
||||||
file_id: FileId,
|
|
||||||
edit: TextEdit,
|
|
||||||
) -> Result<lsp_types::TextDocumentEdit> {
|
|
||||||
let text_document = optional_versioned_text_document_identifier(snap, file_id);
|
|
||||||
let line_index = snap.file_line_index(file_id)?;
|
|
||||||
let edits =
|
|
||||||
edit.into_iter().map(|it| lsp_types::OneOf::Left(text_edit(&line_index, it))).collect();
|
|
||||||
Ok(lsp_types::TextDocumentEdit { text_document, edits })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn snippet_text_document_edit(
|
pub(crate) fn snippet_text_document_edit(
|
||||||
snap: &GlobalStateSnapshot,
|
snap: &GlobalStateSnapshot,
|
||||||
is_snippet: bool,
|
is_snippet: bool,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<!---
|
<!---
|
||||||
lsp_ext.rs hash: faae991334a151d0
|
lsp_ext.rs hash: b19ddc3ab8767af9
|
||||||
|
|
||||||
If you need to change the above hash to make the test pass, please check if you
|
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:
|
need to adjust this doc as well and ping this issue:
|
||||||
|
|
||||||
https://github.com/rust-analyzer/rust-analyzer/issues/4604
|
https://github.com/rust-analyzer/rust-analyzer/issues/4604
|
||||||
|
|
||||||
|
@ -620,7 +620,7 @@ This request is sent from client to server to move item under cursor or selectio
|
||||||
|
|
||||||
**Request:** `MoveItemParams`
|
**Request:** `MoveItemParams`
|
||||||
|
|
||||||
**Response:** `TextDocumentEdit | null`
|
**Response:** `SnippetTextEdit[]`
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
export interface MoveItemParams {
|
export interface MoveItemParams {
|
||||||
|
|
|
@ -159,7 +159,7 @@ More than one mark per test / code branch doesn't add significantly to understan
|
||||||
Do not use `#[should_panic]` tests.
|
Do not use `#[should_panic]` tests.
|
||||||
Instead, explicitly check for `None`, `Err`, etc.
|
Instead, explicitly check for `None`, `Err`, etc.
|
||||||
|
|
||||||
**Rationale:**a `#[should_panic]` is a tool for library authors, to makes sure that API does not fail silently, when misused.
|
**Rationale:** `#[should_panic]` is a tool for library authors, to makes sure that API does not fail silently, when misused.
|
||||||
`rust-analyzer` is not a library, we don't need to test for API misuse, and we have to handle any user input without panics.
|
`rust-analyzer` is not a library, we don't need to test for API misuse, and we have to handle any user input without panics.
|
||||||
Panic messages in the logs from the `#[should_panic]` tests are confusing.
|
Panic messages in the logs from the `#[should_panic]` tests are confusing.
|
||||||
|
|
||||||
|
|
|
@ -148,34 +148,16 @@ export function moveItem(ctx: Ctx, direction: ra.Direction): Cmd {
|
||||||
const client = ctx.client;
|
const client = ctx.client;
|
||||||
if (!editor || !client) return;
|
if (!editor || !client) return;
|
||||||
|
|
||||||
const edit = await client.sendRequest(ra.moveItem, {
|
const lcEdits = await client.sendRequest(ra.moveItem, {
|
||||||
range: client.code2ProtocolConverter.asRange(editor.selection),
|
range: client.code2ProtocolConverter.asRange(editor.selection),
|
||||||
textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
|
textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
|
||||||
direction
|
direction
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!edit) return;
|
if (!lcEdits) return;
|
||||||
|
|
||||||
let cursor: vscode.Position | null = null;
|
const edits = client.protocol2CodeConverter.asTextEdits(lcEdits);
|
||||||
|
await applySnippetTextEdits(editor, edits);
|
||||||
await editor.edit((builder) => {
|
|
||||||
client.protocol2CodeConverter.asTextEdits(edit.edits).forEach((edit: any) => {
|
|
||||||
builder.replace(edit.range, edit.newText);
|
|
||||||
|
|
||||||
if (direction === ra.Direction.Up) {
|
|
||||||
if (!cursor || edit.range.end.isBeforeOrEqual(cursor)) {
|
|
||||||
cursor = edit.range.end;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!cursor || edit.range.end.isAfterOrEqual(cursor)) {
|
|
||||||
cursor = edit.range.end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).then(() => {
|
|
||||||
const newPosition = cursor ?? editor.selection.start;
|
|
||||||
editor.selection = new vscode.Selection(newPosition, newPosition);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ export interface OpenCargoTomlParams {
|
||||||
textDocument: lc.TextDocumentIdentifier;
|
textDocument: lc.TextDocumentIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const moveItem = new lc.RequestType<MoveItemParams, lc.TextDocumentEdit | void, void>("experimental/moveItem");
|
export const moveItem = new lc.RequestType<MoveItemParams, lc.TextEdit[], void>("experimental/moveItem");
|
||||||
|
|
||||||
export interface MoveItemParams {
|
export interface MoveItemParams {
|
||||||
textDocument: lc.TextDocumentIdentifier;
|
textDocument: lc.TextDocumentIdentifier;
|
||||||
|
|
Loading…
Reference in a new issue