mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-12-23 08:47:50 +00:00
Merge 422b1099f6 into 0bfe655ada
This commit is contained in:
commit
0741201ecf
23 changed files with 385 additions and 62 deletions
|
|
@ -122,8 +122,10 @@ impl ExprInfoRepr {
|
|||
self.resolves
|
||||
.iter()
|
||||
.filter(move |(_, r)| match (decl.as_ref(), r.decl.as_ref()) {
|
||||
(Decl::Label(..), Decl::Label(..)) => r.decl == decl,
|
||||
(Decl::Label(..), Decl::ContentRef(..)) => r.decl.name() == decl.name(),
|
||||
(Decl::Label(..), Decl::Label(..))
|
||||
| (Decl::Label(..), Decl::ContentRef(..))
|
||||
| (Decl::ContentRef(..), Decl::Label(..))
|
||||
| (Decl::ContentRef(..), Decl::ContentRef(..)) => r.decl.name() == decl.name(),
|
||||
(Decl::Label(..), _) => false,
|
||||
_ => r.decl == decl || r.root == of,
|
||||
})
|
||||
|
|
@ -571,7 +573,15 @@ impl Decl {
|
|||
pub fn ref_(ident: ast::Ref) -> Self {
|
||||
Self::ContentRef(SpannedDecl {
|
||||
name: ident.target().into(),
|
||||
at: ident.span(),
|
||||
at: {
|
||||
let marker_span = ident
|
||||
.to_untyped()
|
||||
.children()
|
||||
.find(|child| child.kind() == SyntaxKind::RefMarker)
|
||||
.map(|child| child.span());
|
||||
|
||||
marker_span.unwrap_or(ident.span())
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -701,6 +701,17 @@ impl<'a> SyntaxClass<'a> {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if the syntax class contains an error node.
|
||||
pub fn contains_error(&self) -> bool {
|
||||
use SyntaxClass::*;
|
||||
match self {
|
||||
Label { is_error, .. } => *is_error,
|
||||
Normal(kind, _) => *kind == SyntaxKind::Error,
|
||||
Callee(..) | VarAccess(..) => self.node().kind() == SyntaxKind::Error,
|
||||
Ref { .. } | ImportPath(..) | IncludePath(..) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Classifies node's syntax (inner syntax) that can be operated on by IDE
|
||||
|
|
|
|||
|
|
@ -681,6 +681,9 @@ impl SharedContext {
|
|||
}
|
||||
}
|
||||
|
||||
// todo: if previous and current are both valid language items. we prefer to
|
||||
// select the previous one. e.g. @a:1|@b:1, we will select the `@a:1`?
|
||||
|
||||
classify_syntax(node, cursor)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ expression: "JsonRepr::new_pure(result)"
|
|||
input_file: crates/tinymist-query/src/fixtures/references/cross_file_ref_label.typ
|
||||
---
|
||||
[
|
||||
"base1.typ@1:10:1:13",
|
||||
"base2.typ@1:10:1:13",
|
||||
"base2.typ@3:10:3:13",
|
||||
"s2.typ@6:31:6:34"
|
||||
"base1.typ@0:11:0:13",
|
||||
"base1.typ@1:11:1:13",
|
||||
"base2.typ@1:11:1:13",
|
||||
"base2.typ@3:11:3:13",
|
||||
"s2.typ@6:32:6:34"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -4,5 +4,6 @@ expression: "JsonRepr::new_pure(result)"
|
|||
input_file: crates/tinymist-query/src/fixtures/references/label.typ
|
||||
---
|
||||
[
|
||||
"s0.typ@5:0:5:12"
|
||||
"s0.typ@3:11:3:22",
|
||||
"s0.typ@5:1:5:12"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ expression: "JsonRepr::new_pure(result)"
|
|||
input_file: crates/tinymist-query/src/fixtures/references/ref_label.typ
|
||||
---
|
||||
[
|
||||
"s0.typ@5:0:5:12",
|
||||
"s0.typ@7:21:7:33",
|
||||
"s0.typ@9:0:9:12"
|
||||
"s0.typ@3:11:3:22",
|
||||
"s0.typ@5:1:5:12",
|
||||
"s0.typ@7:22:7:33",
|
||||
"s0.typ@9:1:9:12"
|
||||
]
|
||||
|
|
|
|||
7
crates/tinymist-query/src/fixtures/rename/label.typ
Normal file
7
crates/tinymist-query/src/fixtures/rename/label.typ
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/// compile: true
|
||||
|
||||
#set heading(numbering: "1.")
|
||||
|
||||
= Labeled <title_label>
|
||||
|
||||
/* position after */ @title_label
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
/// compile: true
|
||||
|
||||
#let test1(body) = figure(body)
|
||||
#test1([Test1]) <fig:test1>
|
||||
/* position after */ @fig:test1[123]
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
/// compile: true
|
||||
|
||||
#let test1(body) = figure(body)
|
||||
#test1([Test1]) <fig:test1>
|
||||
/* position after */ @fig:test1
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/// compile: true
|
||||
|
||||
#let test1(body) = figure(body)
|
||||
#test1([Test1]) <fig:test1>
|
||||
@fig:test1
|
||||
|
||||
#let test2(body) = test1(body)
|
||||
#test2([Test2]) <fig:test2>
|
||||
/* position after */ @fig:test2
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/prepare_rename.rs
|
||||
expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||
input_file: crates/tinymist-query/src/fixtures/rename/label.typ
|
||||
---
|
||||
{
|
||||
"placeholder": "title_label",
|
||||
"range": "6:22:6:33"
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/prepare_rename.rs
|
||||
expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||
input_file: crates/tinymist-query/src/fixtures/rename/label_content.typ
|
||||
---
|
||||
{
|
||||
"placeholder": "fig:test1",
|
||||
"range": "4:22:4:31"
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/prepare_rename.rs
|
||||
expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||
input_file: crates/tinymist-query/src/fixtures/rename/label_indir.typ
|
||||
---
|
||||
{
|
||||
"placeholder": "fig:test1",
|
||||
"range": "4:22:4:31"
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/prepare_rename.rs
|
||||
expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||
input_file: crates/tinymist-query/src/fixtures/rename/label_indir2.typ
|
||||
---
|
||||
{
|
||||
"placeholder": "fig:test2",
|
||||
"range": "8:22:8:31"
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/rename.rs
|
||||
expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||
input_file: crates/tinymist-query/src/fixtures/rename/label.typ
|
||||
---
|
||||
{
|
||||
"changeAnnotations": {
|
||||
"Typst Rename Labels": {
|
||||
"description": "The language server fuzzy searched the labels",
|
||||
"label": "Typst Rename Labels",
|
||||
"needsConfirmation": true
|
||||
}
|
||||
},
|
||||
"documentChanges": [
|
||||
{
|
||||
"edits": [
|
||||
{
|
||||
"annotationId": "Typst Rename Labels",
|
||||
"newText": "new_name",
|
||||
"range": "4:11:4:22"
|
||||
},
|
||||
{
|
||||
"annotationId": "Typst Rename Labels",
|
||||
"newText": "new_name",
|
||||
"range": "6:22:6:33"
|
||||
}
|
||||
],
|
||||
"textDocument": {
|
||||
"uri": "s0.typ",
|
||||
"version": null
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/rename.rs
|
||||
expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||
input_file: crates/tinymist-query/src/fixtures/rename/label_content.typ
|
||||
---
|
||||
{
|
||||
"changeAnnotations": {
|
||||
"Typst Rename Labels": {
|
||||
"description": "The language server fuzzy searched the labels",
|
||||
"label": "Typst Rename Labels",
|
||||
"needsConfirmation": true
|
||||
}
|
||||
},
|
||||
"documentChanges": [
|
||||
{
|
||||
"edits": [
|
||||
{
|
||||
"annotationId": "Typst Rename Labels",
|
||||
"newText": "new_name",
|
||||
"range": "4:22:4:31"
|
||||
},
|
||||
{
|
||||
"annotationId": "Typst Rename Labels",
|
||||
"newText": "new_name",
|
||||
"range": "3:17:3:26"
|
||||
}
|
||||
],
|
||||
"textDocument": {
|
||||
"uri": "s0.typ",
|
||||
"version": null
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/rename.rs
|
||||
expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||
input_file: crates/tinymist-query/src/fixtures/rename/label_indir.typ
|
||||
---
|
||||
{
|
||||
"changeAnnotations": {
|
||||
"Typst Rename Labels": {
|
||||
"description": "The language server fuzzy searched the labels",
|
||||
"label": "Typst Rename Labels",
|
||||
"needsConfirmation": true
|
||||
}
|
||||
},
|
||||
"documentChanges": [
|
||||
{
|
||||
"edits": [
|
||||
{
|
||||
"annotationId": "Typst Rename Labels",
|
||||
"newText": "new_name",
|
||||
"range": "4:22:4:31"
|
||||
},
|
||||
{
|
||||
"annotationId": "Typst Rename Labels",
|
||||
"newText": "new_name",
|
||||
"range": "3:17:3:26"
|
||||
}
|
||||
],
|
||||
"textDocument": {
|
||||
"uri": "s0.typ",
|
||||
"version": null
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/rename.rs
|
||||
expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||
input_file: crates/tinymist-query/src/fixtures/rename/label_indir2.typ
|
||||
---
|
||||
{
|
||||
"changeAnnotations": {
|
||||
"Typst Rename Labels": {
|
||||
"description": "The language server fuzzy searched the labels",
|
||||
"label": "Typst Rename Labels",
|
||||
"needsConfirmation": true
|
||||
}
|
||||
},
|
||||
"documentChanges": [
|
||||
{
|
||||
"edits": [
|
||||
{
|
||||
"annotationId": "Typst Rename Labels",
|
||||
"newText": "new_name",
|
||||
"range": "8:22:8:31"
|
||||
},
|
||||
{
|
||||
"annotationId": "Typst Rename Labels",
|
||||
"newText": "new_name",
|
||||
"range": "7:17:7:26"
|
||||
}
|
||||
],
|
||||
"textDocument": {
|
||||
"uri": "s0.typ",
|
||||
"version": null
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -37,42 +37,66 @@ impl SemanticRequest for PrepareRenameRequest {
|
|||
fn request(self, ctx: &mut LocalContext) -> Option<Self::Response> {
|
||||
let source = ctx.source_by_path(&self.path).ok()?;
|
||||
let syntax = ctx.classify_for_decl(&source, self.position)?;
|
||||
if matches!(syntax.node().kind(), SyntaxKind::FieldAccess) {
|
||||
// todo: rename field access
|
||||
log::info!("prepare_rename: field access is not a definition site");
|
||||
if bad_syntax(&syntax) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let origin_selection_range = ctx.to_lsp_range(syntax.node().range(), &source);
|
||||
// todo: process RefMarker consistently?
|
||||
let mut node = syntax.node().clone();
|
||||
if matches!(node.kind(), SyntaxKind::Ref) {
|
||||
let marker = node
|
||||
.children()
|
||||
.find(|child| child.kind() == SyntaxKind::RefMarker)?;
|
||||
node = marker;
|
||||
}
|
||||
let mut range = node.range();
|
||||
if matches!(node.kind(), SyntaxKind::RefMarker) {
|
||||
range.start += 1;
|
||||
}
|
||||
|
||||
let origin_selection_range = ctx.to_lsp_range(range, &source);
|
||||
let def = ctx.def_of_syntax(&source, syntax.clone())?;
|
||||
|
||||
let (name, range) = prepare_renaming(&syntax, &def)?;
|
||||
let name = prepare_renaming(&syntax, &def)?;
|
||||
|
||||
Some(PrepareRenameResponse::RangeWithPlaceholder {
|
||||
range: range.unwrap_or(origin_selection_range),
|
||||
range: origin_selection_range,
|
||||
placeholder: name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn prepare_renaming(
|
||||
deref_target: &SyntaxClass,
|
||||
def: &Definition,
|
||||
) -> Option<(String, Option<LspRange>)> {
|
||||
let name = def.name().clone();
|
||||
fn bad_syntax(syntax: &SyntaxClass) -> bool {
|
||||
if matches!(syntax.node().kind(), SyntaxKind::FieldAccess) {
|
||||
// todo: rename field access
|
||||
log::info!("prepare_rename: field access is not a definition site");
|
||||
return true;
|
||||
}
|
||||
|
||||
if syntax.contains_error() {
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
pub(crate) fn prepare_renaming(syntax: &SyntaxClass, def: &Definition) -> Option<String> {
|
||||
if bad_syntax(syntax) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let def_fid = def.file_id()?;
|
||||
|
||||
if WorkspaceResolver::is_package_file(def_fid) {
|
||||
crate::log_debug_ct!(
|
||||
"prepare_rename: {name} is in a package {pkg:?}",
|
||||
"prepare_rename: is in a package {pkg:?}, def: {def:?}",
|
||||
pkg = def_fid.package(),
|
||||
);
|
||||
return None;
|
||||
}
|
||||
|
||||
let var_rename = || Some((name.to_string(), None));
|
||||
let decl_name = || def.name().clone().to_string();
|
||||
|
||||
crate::log_debug_ct!("prepare_rename: {name}");
|
||||
use Decl::*;
|
||||
match def.decl.as_ref() {
|
||||
// Cannot rename headings or blocks
|
||||
|
|
@ -81,17 +105,17 @@ pub(crate) fn prepare_renaming(
|
|||
// LexicalKind::Mod(Star) => None,
|
||||
// Cannot rename expression import
|
||||
// LexicalKind::Mod(Module(ModSrc::Expr(..))) => None,
|
||||
Var(..) => var_rename(),
|
||||
Func(..) | Closure(..) => validate_fn_renaming(def).map(|_| (name.to_string(), None)),
|
||||
Var(..) | Label(..) | ContentRef(..) => Some(decl_name()),
|
||||
Func(..) | Closure(..) => validate_fn_renaming(def).map(|_| decl_name()),
|
||||
Module(..) | ModuleAlias(..) | PathStem(..) | ImportPath(..) | IncludePath(..)
|
||||
| ModuleImport(..) => {
|
||||
let node = deref_target.node().get().clone();
|
||||
let node = syntax.node().get().clone();
|
||||
let path = node.cast::<ast::Str>()?;
|
||||
let name = path.get().to_string();
|
||||
Some((name, None))
|
||||
Some(name)
|
||||
}
|
||||
// todo: label renaming, bibkey renaming
|
||||
BibEntry(..) | Label(..) | ContentRef(..) => None,
|
||||
// todo: bibkey renaming
|
||||
BibEntry(..) => None,
|
||||
ImportAlias(..) | Constant(..) | IdentRef(..) | Import(..) | StrName(..) | Spread(..) => {
|
||||
None
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,13 +140,35 @@ impl ReferencesWorker<'_> {
|
|||
url: &Url,
|
||||
idents: impl Iterator<Item = (&'b Span, &'b Interned<RefExpr>)>,
|
||||
) {
|
||||
self.push_ranges(src, url, idents.map(|(span, _)| span));
|
||||
self.push_ranges(
|
||||
src,
|
||||
url,
|
||||
idents.map(|(span, expr)| {
|
||||
let adjust = match expr.decl.as_ref() {
|
||||
Decl::Label(..) => Some((1, -1)),
|
||||
Decl::ContentRef(..) => Some((1, 0)),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
(*span, adjust)
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
fn push_ranges<'b>(&mut self, src: &Source, url: &Url, spans: impl Iterator<Item = &'b Span>) {
|
||||
self.references.extend(spans.filter_map(|span| {
|
||||
fn push_ranges(
|
||||
&mut self,
|
||||
src: &Source,
|
||||
url: &Url,
|
||||
spans: impl Iterator<Item = (Span, Option<(isize, isize)>)>,
|
||||
) {
|
||||
self.references.extend(spans.filter_map(|(span, adjust)| {
|
||||
// todo: this is not necessary a name span
|
||||
let range = self.ctx.ctx.to_lsp_range(src.range(*span)?, src);
|
||||
let mut range = src.range(span)?;
|
||||
if let Some((start, end)) = adjust {
|
||||
range.start = (range.start as isize + start) as usize;
|
||||
range.end = (range.end as isize + end) as usize;
|
||||
}
|
||||
let range = self.ctx.ctx.to_lsp_range(range, src);
|
||||
Some(LspLocation {
|
||||
uri: url.clone(),
|
||||
range,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use lsp_types::{
|
||||
DocumentChangeOperation, DocumentChanges, OneOf, OptionalVersionedTextDocumentIdentifier,
|
||||
RenameFile, TextDocumentEdit,
|
||||
AnnotatedTextEdit, ChangeAnnotation, DocumentChangeOperation, DocumentChanges, OneOf,
|
||||
OptionalVersionedTextDocumentIdentifier, RenameFile, TextDocumentEdit,
|
||||
};
|
||||
use rustc_hash::FxHashSet;
|
||||
use tinymist_std::path::{PathClean, unix_slash};
|
||||
|
|
@ -76,7 +76,7 @@ impl SemanticRequest for RenameRequest {
|
|||
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);
|
||||
let mut document_changes = edits_to_document_changes(edits, None);
|
||||
|
||||
document_changes.push(lsp_types::DocumentChangeOperation::Op(
|
||||
lsp_types::ResourceOp::Rename(RenameFile {
|
||||
|
|
@ -94,6 +94,7 @@ impl SemanticRequest for RenameRequest {
|
|||
})
|
||||
}
|
||||
_ => {
|
||||
let is_label = matches!(def.decl.kind(), DefKind::Reference);
|
||||
let references = find_references(ctx, &source, syntax)?;
|
||||
|
||||
let mut edits = HashMap::new();
|
||||
|
|
@ -108,12 +109,30 @@ impl SemanticRequest for RenameRequest {
|
|||
});
|
||||
}
|
||||
|
||||
log::info!("rename edits: {edits:?}");
|
||||
crate::log_debug_ct!("rename edits: {edits:?}");
|
||||
|
||||
Some(WorkspaceEdit {
|
||||
changes: Some(edits),
|
||||
..Default::default()
|
||||
})
|
||||
if !is_label {
|
||||
Some(WorkspaceEdit {
|
||||
changes: Some(edits),
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
let change_id = "Typst Rename Labels";
|
||||
|
||||
let document_changes = edits_to_document_changes(edits, Some(change_id));
|
||||
|
||||
let change_annotations = Some(create_change_annotation(
|
||||
change_id,
|
||||
true,
|
||||
Some("The language server fuzzy searched the labels".to_string()),
|
||||
));
|
||||
|
||||
Some(WorkspaceEdit {
|
||||
document_changes: Some(DocumentChanges::Operations(document_changes)),
|
||||
change_annotations,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -300,19 +319,47 @@ impl RenameFileWorker<'_> {
|
|||
|
||||
pub(crate) fn edits_to_document_changes(
|
||||
edits: HashMap<Url, Vec<TextEdit>>,
|
||||
change_id: Option<&str>,
|
||||
) -> 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(),
|
||||
edits: edits
|
||||
.into_iter()
|
||||
.map(|edit| match change_id {
|
||||
Some(change_id) => OneOf::Right(AnnotatedTextEdit {
|
||||
text_edit: edit,
|
||||
annotation_id: change_id.to_owned(),
|
||||
}),
|
||||
None => OneOf::Left(edit),
|
||||
})
|
||||
.collect(),
|
||||
}));
|
||||
}
|
||||
|
||||
document_changes
|
||||
}
|
||||
|
||||
pub(crate) fn create_change_annotation(
|
||||
label: &str,
|
||||
needs_confirmation: bool,
|
||||
description: Option<String>,
|
||||
) -> HashMap<String, ChangeAnnotation> {
|
||||
let mut change_annotations = HashMap::new();
|
||||
change_annotations.insert(
|
||||
label.to_owned(),
|
||||
ChangeAnnotation {
|
||||
label: label.to_owned(),
|
||||
needs_confirmation: Some(needs_confirmation),
|
||||
description,
|
||||
},
|
||||
);
|
||||
|
||||
change_annotations
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -399,10 +399,6 @@ impl ExprWorker<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_label(&mut self, label: ast::Label) -> Expr {
|
||||
Expr::Decl(Decl::label(label.get(), label.span()).into())
|
||||
}
|
||||
|
||||
fn check_element<T: NativeElement>(&mut self, content: EcoVec<Expr>) -> Expr {
|
||||
let elem = Element::of::<T>();
|
||||
Expr::Element(ElementExpr { elem, content }.into())
|
||||
|
|
@ -1105,6 +1101,21 @@ impl ExprWorker<'_> {
|
|||
Expr::Block(items.into())
|
||||
}
|
||||
|
||||
fn check_label(&mut self, label: ast::Label) -> Expr {
|
||||
let decl: Interned<Decl> = Decl::label(label.get(), label.span()).into();
|
||||
|
||||
self.resolve_as(
|
||||
RefExpr {
|
||||
decl: decl.clone(),
|
||||
step: None,
|
||||
root: None,
|
||||
term: None,
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
Expr::Decl(decl)
|
||||
}
|
||||
|
||||
fn check_ref(&mut self, ref_node: ast::Ref) -> Expr {
|
||||
let ident = Interned::new(Decl::ref_(ref_node));
|
||||
let body = ref_node
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
use lsp_types::ChangeAnnotation;
|
||||
|
||||
use crate::{do_rename_file, edits_to_document_changes, prelude::*};
|
||||
use crate::{create_change_annotation, do_rename_file, edits_to_document_changes, prelude::*};
|
||||
|
||||
/// Handle [`workspace/willRenameFiles`] request is sent from the client to the
|
||||
/// server.
|
||||
|
|
@ -37,25 +35,21 @@ impl SemanticRequest for WillRenameFilesRequest {
|
|||
})
|
||||
.collect::<Option<Vec<()>>>()?;
|
||||
log::info!("did rename edits: {edits:?}");
|
||||
let document_changes = edits_to_document_changes(edits);
|
||||
let document_changes = edits_to_document_changes(edits, None);
|
||||
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()),
|
||||
},
|
||||
);
|
||||
let change_annotations = Some(create_change_annotation(
|
||||
"Typst Rename Files",
|
||||
true,
|
||||
Some("Renaming files should update imports".to_string()),
|
||||
));
|
||||
|
||||
Some(WorkspaceEdit {
|
||||
changes: None,
|
||||
document_changes: Some(lsp_types::DocumentChanges::Operations(document_changes)),
|
||||
change_annotations: Some(change_annotations),
|
||||
change_annotations,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue