mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-08-03 01:42:14 +00:00
feat: issue import changes request during willRenameFiles
(#648)
* feat: issue import changes request during `willRenameFiles` * test: update snapshot * fix: snapshot
This commit is contained in:
parent
c9846b1d0d
commit
7b0fb6036d
10 changed files with 193 additions and 63 deletions
|
@ -5,11 +5,6 @@ input_file: crates/tinymist-query/src/fixtures/rename/module_path.typ
|
||||||
---
|
---
|
||||||
{
|
{
|
||||||
"documentChanges": [
|
"documentChanges": [
|
||||||
{
|
|
||||||
"kind": "rename",
|
|
||||||
"newUri": "new_name.typ",
|
|
||||||
"oldUri": "variable.typ"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"edits": [
|
"edits": [
|
||||||
{
|
{
|
||||||
|
@ -21,6 +16,11 @@ input_file: crates/tinymist-query/src/fixtures/rename/module_path.typ
|
||||||
"uri": "s1.typ",
|
"uri": "s1.typ",
|
||||||
"version": null
|
"version": null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "rename",
|
||||||
|
"newUri": "new_name.typ",
|
||||||
|
"oldUri": "variable.typ"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,6 @@ input_file: crates/tinymist-query/src/fixtures/rename/module_path_alias.typ
|
||||||
---
|
---
|
||||||
{
|
{
|
||||||
"documentChanges": [
|
"documentChanges": [
|
||||||
{
|
|
||||||
"kind": "rename",
|
|
||||||
"newUri": "new_name.typ",
|
|
||||||
"oldUri": "variable.typ"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"edits": [
|
"edits": [
|
||||||
{
|
{
|
||||||
|
@ -21,6 +16,11 @@ input_file: crates/tinymist-query/src/fixtures/rename/module_path_alias.typ
|
||||||
"uri": "s1.typ",
|
"uri": "s1.typ",
|
||||||
"version": null
|
"version": null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "rename",
|
||||||
|
"newUri": "new_name.typ",
|
||||||
|
"oldUri": "variable.typ"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,6 @@ input_file: crates/tinymist-query/src/fixtures/rename/module_path_non_cano.typ
|
||||||
---
|
---
|
||||||
{
|
{
|
||||||
"documentChanges": [
|
"documentChanges": [
|
||||||
{
|
|
||||||
"kind": "rename",
|
|
||||||
"newUri": "new_name.typ",
|
|
||||||
"oldUri": "variable.typ"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"edits": [
|
"edits": [
|
||||||
{
|
{
|
||||||
|
@ -21,6 +16,11 @@ input_file: crates/tinymist-query/src/fixtures/rename/module_path_non_cano.typ
|
||||||
"uri": "s1.typ",
|
"uri": "s1.typ",
|
||||||
"version": null
|
"version": null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "rename",
|
||||||
|
"newUri": "new_name.typ",
|
||||||
|
"oldUri": "variable.typ"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,6 @@ input_file: crates/tinymist-query/src/fixtures/rename/module_path_star.typ
|
||||||
---
|
---
|
||||||
{
|
{
|
||||||
"documentChanges": [
|
"documentChanges": [
|
||||||
{
|
|
||||||
"kind": "rename",
|
|
||||||
"newUri": "new_name.typ",
|
|
||||||
"oldUri": "variable.typ"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"edits": [
|
"edits": [
|
||||||
{
|
{
|
||||||
|
@ -21,6 +16,11 @@ input_file: crates/tinymist-query/src/fixtures/rename/module_path_star.typ
|
||||||
"uri": "s1.typ",
|
"uri": "s1.typ",
|
||||||
"version": null
|
"version": null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "rename",
|
||||||
|
"newUri": "new_name.typ",
|
||||||
|
"oldUri": "variable.typ"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,8 @@ mod inlay_hint;
|
||||||
pub use inlay_hint::*;
|
pub use inlay_hint::*;
|
||||||
mod jump;
|
mod jump;
|
||||||
pub use jump::*;
|
pub use jump::*;
|
||||||
|
mod will_rename_files;
|
||||||
|
pub use will_rename_files::*;
|
||||||
mod rename;
|
mod rename;
|
||||||
pub use rename::*;
|
pub use rename::*;
|
||||||
mod selection_range;
|
mod selection_range;
|
||||||
|
@ -251,6 +253,7 @@ mod polymorphic {
|
||||||
Completion(CompletionRequest),
|
Completion(CompletionRequest),
|
||||||
SignatureHelp(SignatureHelpRequest),
|
SignatureHelp(SignatureHelpRequest),
|
||||||
Rename(RenameRequest),
|
Rename(RenameRequest),
|
||||||
|
WillRenameFiles(WillRenameFilesRequest),
|
||||||
PrepareRename(PrepareRenameRequest),
|
PrepareRename(PrepareRenameRequest),
|
||||||
DocumentSymbol(DocumentSymbolRequest),
|
DocumentSymbol(DocumentSymbolRequest),
|
||||||
Symbol(SymbolRequest),
|
Symbol(SymbolRequest),
|
||||||
|
@ -286,6 +289,7 @@ mod polymorphic {
|
||||||
Self::Completion(..) => Mergeable,
|
Self::Completion(..) => Mergeable,
|
||||||
Self::SignatureHelp(..) => PinnedFirst,
|
Self::SignatureHelp(..) => PinnedFirst,
|
||||||
Self::Rename(..) => Mergeable,
|
Self::Rename(..) => Mergeable,
|
||||||
|
Self::WillRenameFiles(..) => Mergeable,
|
||||||
Self::PrepareRename(..) => Mergeable,
|
Self::PrepareRename(..) => Mergeable,
|
||||||
Self::DocumentSymbol(..) => ContextFreeUnique,
|
Self::DocumentSymbol(..) => ContextFreeUnique,
|
||||||
Self::WorkspaceLabel(..) => Mergeable,
|
Self::WorkspaceLabel(..) => Mergeable,
|
||||||
|
@ -320,6 +324,7 @@ mod polymorphic {
|
||||||
Self::Completion(req) => &req.path,
|
Self::Completion(req) => &req.path,
|
||||||
Self::SignatureHelp(req) => &req.path,
|
Self::SignatureHelp(req) => &req.path,
|
||||||
Self::Rename(req) => &req.path,
|
Self::Rename(req) => &req.path,
|
||||||
|
Self::WillRenameFiles(..) => return None,
|
||||||
Self::PrepareRename(req) => &req.path,
|
Self::PrepareRename(req) => &req.path,
|
||||||
Self::DocumentSymbol(req) => &req.path,
|
Self::DocumentSymbol(req) => &req.path,
|
||||||
Self::Symbol(..) => return None,
|
Self::Symbol(..) => return None,
|
||||||
|
@ -356,6 +361,7 @@ mod polymorphic {
|
||||||
SignatureHelp(Option<SignatureHelp>),
|
SignatureHelp(Option<SignatureHelp>),
|
||||||
PrepareRename(Option<PrepareRenameResponse>),
|
PrepareRename(Option<PrepareRenameResponse>),
|
||||||
Rename(Option<WorkspaceEdit>),
|
Rename(Option<WorkspaceEdit>),
|
||||||
|
WillRenameFiles(Option<WorkspaceEdit>),
|
||||||
DocumentSymbol(Option<DocumentSymbolResponse>),
|
DocumentSymbol(Option<DocumentSymbolResponse>),
|
||||||
Symbol(Option<Vec<SymbolInformation>>),
|
Symbol(Option<Vec<SymbolInformation>>),
|
||||||
WorkspaceLabel(Option<Vec<SymbolInformation>>),
|
WorkspaceLabel(Option<Vec<SymbolInformation>>),
|
||||||
|
@ -390,6 +396,7 @@ mod polymorphic {
|
||||||
Self::SignatureHelp(res) => serde_json::to_value(res),
|
Self::SignatureHelp(res) => serde_json::to_value(res),
|
||||||
Self::PrepareRename(res) => serde_json::to_value(res),
|
Self::PrepareRename(res) => serde_json::to_value(res),
|
||||||
Self::Rename(res) => serde_json::to_value(res),
|
Self::Rename(res) => serde_json::to_value(res),
|
||||||
|
Self::WillRenameFiles(res) => serde_json::to_value(res),
|
||||||
Self::DocumentSymbol(res) => serde_json::to_value(res),
|
Self::DocumentSymbol(res) => serde_json::to_value(res),
|
||||||
Self::Symbol(res) => serde_json::to_value(res),
|
Self::Symbol(res) => serde_json::to_value(res),
|
||||||
Self::WorkspaceLabel(res) => serde_json::to_value(res),
|
Self::WorkspaceLabel(res) => serde_json::to_value(res),
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use lsp_types::{
|
use lsp_types::{
|
||||||
DocumentChanges, OneOf, OptionalVersionedTextDocumentIdentifier, RenameFile, TextDocumentEdit,
|
DocumentChangeOperation, DocumentChanges, OneOf, OptionalVersionedTextDocumentIdentifier,
|
||||||
|
RenameFile, TextDocumentEdit,
|
||||||
};
|
};
|
||||||
use reflexo::path::{unix_slash, PathClean};
|
use reflexo::path::{unix_slash, PathClean};
|
||||||
use typst::foundations::{Repr, Str};
|
use typst::foundations::{Repr, Str};
|
||||||
|
@ -56,9 +57,6 @@ impl StatefulRequest for RenameRequest {
|
||||||
self.new_name
|
self.new_name
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut editions: HashMap<Url, Vec<TextEdit>> = HashMap::new();
|
|
||||||
let mut document_changes = vec![];
|
|
||||||
|
|
||||||
let def_fid = lnk.def_at?.0;
|
let def_fid = lnk.def_at?.0;
|
||||||
let old_path = ctx.path_for_id(def_fid).ok()?;
|
let old_path = ctx.path_for_id(def_fid).ok()?;
|
||||||
|
|
||||||
|
@ -74,6 +72,11 @@ impl StatefulRequest for RenameRequest {
|
||||||
let old_uri = path_to_url(&old_path).ok()?;
|
let old_uri = path_to_url(&old_path).ok()?;
|
||||||
let new_uri = path_to_url(&new_path).ok()?;
|
let new_uri = path_to_url(&new_path).ok()?;
|
||||||
|
|
||||||
|
let mut edits: HashMap<Url, Vec<TextEdit>> = HashMap::new();
|
||||||
|
do_rename_file(ctx, def_fid, diff, &mut edits)?;
|
||||||
|
|
||||||
|
let mut document_changes = edits_to_document_changes(edits);
|
||||||
|
|
||||||
document_changes.push(lsp_types::DocumentChangeOperation::Op(
|
document_changes.push(lsp_types::DocumentChangeOperation::Op(
|
||||||
lsp_types::ResourceOp::Rename(RenameFile {
|
lsp_types::ResourceOp::Rename(RenameFile {
|
||||||
old_uri,
|
old_uri,
|
||||||
|
@ -83,40 +86,7 @@ impl StatefulRequest for RenameRequest {
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
|
|
||||||
let dep = ctx.module_dependencies().get(&def_fid)?.clone();
|
|
||||||
|
|
||||||
for ref_fid in dep.dependents.iter() {
|
|
||||||
let ref_src = ctx.source_by_id(*ref_fid).ok()?;
|
|
||||||
let uri = ctx.uri_for_id(*ref_fid).ok()?;
|
|
||||||
|
|
||||||
let Some(import_info) = ctx.import_info(ref_src.clone()) else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
let edits = editions.entry(uri).or_default();
|
|
||||||
for (rng, importing_src) in &import_info.imports {
|
|
||||||
let importing = importing_src.as_ref().map(|s| s.id());
|
|
||||||
if importing.map_or(true, |i| i != def_fid) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
log::debug!("import: {rng:?} -> {importing:?} v.s. {def_fid:?}");
|
|
||||||
rename_importer(ctx, &ref_src, rng.clone(), &diff, edits);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: validate: workspace.workspaceEdit.resourceOperations
|
// todo: validate: workspace.workspaceEdit.resourceOperations
|
||||||
for edition in editions.into_iter() {
|
|
||||||
document_changes.push(lsp_types::DocumentChangeOperation::Edit(
|
|
||||||
TextDocumentEdit {
|
|
||||||
text_document: OptionalVersionedTextDocumentIdentifier {
|
|
||||||
uri: edition.0,
|
|
||||||
version: None,
|
|
||||||
},
|
|
||||||
edits: edition.1.into_iter().map(OneOf::Left).collect(),
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(WorkspaceEdit {
|
Some(WorkspaceEdit {
|
||||||
document_changes: Some(DocumentChanges::Operations(document_changes)),
|
document_changes: Some(DocumentChanges::Operations(document_changes)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -125,7 +95,7 @@ impl StatefulRequest for RenameRequest {
|
||||||
_ => {
|
_ => {
|
||||||
let references = find_references(ctx, source.clone(), doc.as_ref(), deref_target)?;
|
let references = find_references(ctx, source.clone(), doc.as_ref(), deref_target)?;
|
||||||
|
|
||||||
let mut editions = HashMap::new();
|
let mut edits = HashMap::new();
|
||||||
|
|
||||||
let (def_fid, _def_range) = lnk.def_at?;
|
let (def_fid, _def_range) = lnk.def_at?;
|
||||||
let def_loc = {
|
let def_loc = {
|
||||||
|
@ -147,17 +117,17 @@ impl StatefulRequest for RenameRequest {
|
||||||
for i in (Some(def_loc).into_iter()).chain(references) {
|
for i in (Some(def_loc).into_iter()).chain(references) {
|
||||||
let uri = i.uri;
|
let uri = i.uri;
|
||||||
let range = i.range;
|
let range = i.range;
|
||||||
let edits = editions.entry(uri).or_insert_with(Vec::new);
|
let edits = edits.entry(uri).or_insert_with(Vec::new);
|
||||||
edits.push(TextEdit {
|
edits.push(TextEdit {
|
||||||
range,
|
range,
|
||||||
new_text: self.new_name.clone(),
|
new_text: self.new_name.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
log::info!("rename editions: {editions:?}");
|
log::info!("rename edits: {edits:?}");
|
||||||
|
|
||||||
Some(WorkspaceEdit {
|
Some(WorkspaceEdit {
|
||||||
changes: Some(editions),
|
changes: Some(edits),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -165,6 +135,51 @@ impl StatefulRequest for RenameRequest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn do_rename_file(
|
||||||
|
ctx: &mut AnalysisContext,
|
||||||
|
def_fid: TypstFileId,
|
||||||
|
diff: PathBuf,
|
||||||
|
edits: &mut HashMap<Url, Vec<TextEdit>>,
|
||||||
|
) -> Option<()> {
|
||||||
|
let dep = ctx.module_dependencies().get(&def_fid)?.clone();
|
||||||
|
|
||||||
|
for ref_fid in dep.dependents.iter() {
|
||||||
|
let ref_src = ctx.source_by_id(*ref_fid).ok()?;
|
||||||
|
let uri = ctx.uri_for_id(*ref_fid).ok()?;
|
||||||
|
|
||||||
|
let Some(import_info) = ctx.import_info(ref_src.clone()) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let edits = edits.entry(uri).or_default();
|
||||||
|
for (rng, importing_src) in &import_info.imports {
|
||||||
|
let importing = importing_src.as_ref().map(|s| s.id());
|
||||||
|
if importing.map_or(true, |i| i != def_fid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
log::debug!("import: {rng:?} -> {importing:?} v.s. {def_fid:?}");
|
||||||
|
rename_importer(ctx, &ref_src, rng.clone(), &diff, edits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn edits_to_document_changes(
|
||||||
|
edits: HashMap<Url, Vec<TextEdit>>,
|
||||||
|
) -> Vec<DocumentChangeOperation> {
|
||||||
|
let mut document_changes = vec![];
|
||||||
|
|
||||||
|
for (uri, edits) in edits {
|
||||||
|
document_changes.push(lsp_types::DocumentChangeOperation::Edit(TextDocumentEdit {
|
||||||
|
text_document: OptionalVersionedTextDocumentIdentifier { uri, version: None },
|
||||||
|
edits: edits.into_iter().map(OneOf::Left).collect(),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
document_changes
|
||||||
|
}
|
||||||
|
|
||||||
fn rename_importer(
|
fn rename_importer(
|
||||||
ctx: &AnalysisContext,
|
ctx: &AnalysisContext,
|
||||||
src: &Source,
|
src: &Source,
|
||||||
|
|
65
crates/tinymist-query/src/will_rename_files.rs
Normal file
65
crates/tinymist-query/src/will_rename_files.rs
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
use lsp_types::ChangeAnnotation;
|
||||||
|
|
||||||
|
use crate::{do_rename_file, edits_to_document_changes, prelude::*};
|
||||||
|
|
||||||
|
/// Handle [`workspace/willRenameFiles`] request is sent from the client to the
|
||||||
|
/// server.
|
||||||
|
///
|
||||||
|
/// [`workspace/willRenameFiles`]: https://microsoft.github.io/language-server-protocol/specification#workspace_willRenameFiles
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct WillRenameFilesRequest {
|
||||||
|
/// rename paths from `left` to `right`
|
||||||
|
pub paths: Vec<(PathBuf, PathBuf)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StatefulRequest for WillRenameFilesRequest {
|
||||||
|
type Response = WorkspaceEdit;
|
||||||
|
|
||||||
|
fn request(
|
||||||
|
self,
|
||||||
|
ctx: &mut AnalysisContext,
|
||||||
|
_doc: Option<VersionedDocument>,
|
||||||
|
) -> Option<Self::Response> {
|
||||||
|
let mut edits: HashMap<Url, Vec<TextEdit>> = HashMap::new();
|
||||||
|
|
||||||
|
self.paths
|
||||||
|
.into_iter()
|
||||||
|
.map(|(left, right)| {
|
||||||
|
let diff = pathdiff::diff_paths(&right, &left)?;
|
||||||
|
log::info!("did rename diff: {diff:?}");
|
||||||
|
if diff.is_absolute() {
|
||||||
|
log::info!(
|
||||||
|
"bad rename: absolute path, base: {left:?}, new: {right:?}, diff: {diff:?}"
|
||||||
|
);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let def_fid = ctx.file_id_by_path(&left).ok()?;
|
||||||
|
log::info!("did rename def_fid: {def_fid:?}");
|
||||||
|
|
||||||
|
do_rename_file(ctx, def_fid, diff, &mut edits)
|
||||||
|
})
|
||||||
|
.collect::<Option<Vec<()>>>()?;
|
||||||
|
log::info!("did rename edits: {edits:?}");
|
||||||
|
let document_changes = edits_to_document_changes(edits);
|
||||||
|
if document_changes.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut change_annotations = HashMap::new();
|
||||||
|
change_annotations.insert(
|
||||||
|
"Typst Rename Files".to_string(),
|
||||||
|
ChangeAnnotation {
|
||||||
|
label: "Typst Rename Files".to_string(),
|
||||||
|
needs_confirmation: Some(true),
|
||||||
|
description: Some("Rename files should update imports".to_string()),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Some(WorkspaceEdit {
|
||||||
|
changes: None,
|
||||||
|
document_changes: Some(lsp_types::DocumentChanges::Operations(document_changes)),
|
||||||
|
change_annotations: Some(change_annotations),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -164,6 +164,22 @@ impl Initializer for SuperInit {
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let file_operations = const_config.notify_will_rename_files.then(|| {
|
||||||
|
WorkspaceFileOperationsServerCapabilities {
|
||||||
|
will_rename: Some(FileOperationRegistrationOptions {
|
||||||
|
filters: vec![FileOperationFilter {
|
||||||
|
scheme: Some("file".to_string()),
|
||||||
|
pattern: FileOperationPattern {
|
||||||
|
glob: "**/*.typ".to_string(),
|
||||||
|
matches: Some(FileOperationPatternKind::File),
|
||||||
|
options: None,
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
}),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let res = InitializeResult {
|
let res = InitializeResult {
|
||||||
capabilities: ServerCapabilities {
|
capabilities: ServerCapabilities {
|
||||||
// todo: respect position_encoding
|
// todo: respect position_encoding
|
||||||
|
@ -226,7 +242,7 @@ impl Initializer for SuperInit {
|
||||||
supported: Some(true),
|
supported: Some(true),
|
||||||
change_notifications: Some(OneOf::Left(true)),
|
change_notifications: Some(OneOf::Left(true)),
|
||||||
}),
|
}),
|
||||||
..Default::default()
|
file_operations,
|
||||||
}),
|
}),
|
||||||
document_formatting_provider,
|
document_formatting_provider,
|
||||||
inlay_hint_provider: Some(OneOf::Left(true)),
|
inlay_hint_provider: Some(OneOf::Left(true)),
|
||||||
|
@ -357,6 +373,8 @@ pub struct ConstConfig {
|
||||||
pub position_encoding: PositionEncoding,
|
pub position_encoding: PositionEncoding,
|
||||||
/// Allow dynamic registration of configuration changes.
|
/// Allow dynamic registration of configuration changes.
|
||||||
pub cfg_change_registration: bool,
|
pub cfg_change_registration: bool,
|
||||||
|
/// Allow notifying workspace/didRenameFiles
|
||||||
|
pub notify_will_rename_files: bool,
|
||||||
/// Allow dynamic registration of semantic tokens.
|
/// Allow dynamic registration of semantic tokens.
|
||||||
pub tokens_dynamic_registration: bool,
|
pub tokens_dynamic_registration: bool,
|
||||||
/// Allow overlapping tokens.
|
/// Allow overlapping tokens.
|
||||||
|
@ -392,6 +410,7 @@ impl From<&InitializeParams> for ConstConfig {
|
||||||
};
|
};
|
||||||
|
|
||||||
let workspace = params.capabilities.workspace.as_ref();
|
let workspace = params.capabilities.workspace.as_ref();
|
||||||
|
let file_operations = try_(|| workspace?.file_operations.as_ref());
|
||||||
let doc = params.capabilities.text_document.as_ref();
|
let doc = params.capabilities.text_document.as_ref();
|
||||||
let sema = try_(|| doc?.semantic_tokens.as_ref());
|
let sema = try_(|| doc?.semantic_tokens.as_ref());
|
||||||
let fold = try_(|| doc?.folding_range.as_ref());
|
let fold = try_(|| doc?.folding_range.as_ref());
|
||||||
|
@ -400,6 +419,7 @@ impl From<&InitializeParams> for ConstConfig {
|
||||||
Self {
|
Self {
|
||||||
position_encoding,
|
position_encoding,
|
||||||
cfg_change_registration: try_or(|| workspace?.configuration, false),
|
cfg_change_registration: try_or(|| workspace?.configuration, false),
|
||||||
|
notify_will_rename_files: try_or(|| file_operations?.will_rename, false),
|
||||||
tokens_dynamic_registration: try_or(|| sema?.dynamic_registration, false),
|
tokens_dynamic_registration: try_or(|| sema?.dynamic_registration, false),
|
||||||
tokens_overlapping_token_support: try_or(|| sema?.overlapping_token_support, false),
|
tokens_overlapping_token_support: try_or(|| sema?.overlapping_token_support, false),
|
||||||
tokens_multiline_token_support: try_or(|| sema?.multiline_token_support, false),
|
tokens_multiline_token_support: try_or(|| sema?.multiline_token_support, false),
|
||||||
|
|
|
@ -233,6 +233,7 @@ impl LanguageState {
|
||||||
.with_request_::<References>(State::references)
|
.with_request_::<References>(State::references)
|
||||||
.with_request_::<WorkspaceSymbolRequest>(State::symbol)
|
.with_request_::<WorkspaceSymbolRequest>(State::symbol)
|
||||||
.with_request_::<OnEnter>(State::on_enter)
|
.with_request_::<OnEnter>(State::on_enter)
|
||||||
|
.with_request_::<WillRenameFiles>(State::will_rename_files)
|
||||||
// notifications
|
// notifications
|
||||||
.with_notification::<Initialized>(State::initialized)
|
.with_notification::<Initialized>(State::initialized)
|
||||||
.with_notification::<DidOpenTextDocument>(State::did_open)
|
.with_notification::<DidOpenTextDocument>(State::did_open)
|
||||||
|
@ -790,6 +791,27 @@ impl LanguageState {
|
||||||
let (path, position) = as_path_pos(params);
|
let (path, position) = as_path_pos(params);
|
||||||
run_query!(req_id, self.OnEnter(path, position))
|
run_query!(req_id, self.OnEnter(path, position))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn will_rename_files(
|
||||||
|
&mut self,
|
||||||
|
req_id: RequestId,
|
||||||
|
params: RenameFilesParams,
|
||||||
|
) -> ScheduledResult {
|
||||||
|
log::info!("will rename files {params:?}");
|
||||||
|
let paths = params
|
||||||
|
.files
|
||||||
|
.iter()
|
||||||
|
.map(|f| {
|
||||||
|
Some((
|
||||||
|
as_path_(Url::parse(&f.old_uri).ok()?),
|
||||||
|
as_path_(Url::parse(&f.new_uri).ok()?),
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.collect::<Option<Vec<_>>>()
|
||||||
|
.ok_or_else(|| invalid_params("invalid urls"))?;
|
||||||
|
|
||||||
|
run_query!(req_id, self.WillRenameFiles(paths))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LanguageState {
|
impl LanguageState {
|
||||||
|
@ -1047,6 +1069,7 @@ impl LanguageState {
|
||||||
Completion(req) => handle.run_stateful(snap, req, R::Completion),
|
Completion(req) => handle.run_stateful(snap, req, R::Completion),
|
||||||
SignatureHelp(req) => handle.run_semantic(snap, req, R::SignatureHelp),
|
SignatureHelp(req) => handle.run_semantic(snap, req, R::SignatureHelp),
|
||||||
Rename(req) => handle.run_stateful(snap, req, R::Rename),
|
Rename(req) => handle.run_stateful(snap, req, R::Rename),
|
||||||
|
WillRenameFiles(req) => handle.run_stateful(snap, req, R::WillRenameFiles),
|
||||||
PrepareRename(req) => handle.run_stateful(snap, req, R::PrepareRename),
|
PrepareRename(req) => handle.run_stateful(snap, req, R::PrepareRename),
|
||||||
Symbol(req) => handle.run_semantic(snap, req, R::Symbol),
|
Symbol(req) => handle.run_semantic(snap, req, R::Symbol),
|
||||||
WorkspaceLabel(req) => handle.run_semantic(snap, req, R::WorkspaceLabel),
|
WorkspaceLabel(req) => handle.run_semantic(snap, req, R::WorkspaceLabel),
|
||||||
|
|
|
@ -385,7 +385,7 @@ fn e2e() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let hash = replay_log(&tinymist_binary, &root.join("vscode"));
|
let hash = replay_log(&tinymist_binary, &root.join("vscode"));
|
||||||
insta::assert_snapshot!(hash, @"siphash128_13:427c0fe870e3acd4e53a9e101bc6dc29");
|
insta::assert_snapshot!(hash, @"siphash128_13:5f3b961e94db34a9d7e9f6a405617c0d");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue