mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
Fix duplicate completions (#4563)
This commit is contained in:
parent
f3863f14af
commit
09e0464e87
@ -5,8 +5,8 @@ use ecow::{eco_format, EcoString};
|
||||
use if_chain::if_chain;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typst::foundations::{
|
||||
fields_on, format_str, mutable_methods_on, repr, AutoValue, CastInfo, Func, Label,
|
||||
NoneValue, Repr, Scope, StyleChain, Styles, Type, Value,
|
||||
fields_on, format_str, repr, AutoValue, CastInfo, Func, Label, NoneValue, Repr,
|
||||
Scope, StyleChain, Styles, Type, Value,
|
||||
};
|
||||
use typst::model::Document;
|
||||
use typst::syntax::{
|
||||
@ -396,19 +396,6 @@ fn field_access_completions(
|
||||
}
|
||||
}
|
||||
|
||||
for &(method, args) in mutable_methods_on(value.ty()) {
|
||||
ctx.completions.push(Completion {
|
||||
kind: CompletionKind::Func,
|
||||
label: method.into(),
|
||||
apply: Some(if args {
|
||||
eco_format!("{method}(${{}})")
|
||||
} else {
|
||||
eco_format!("{method}()${{}}")
|
||||
}),
|
||||
detail: None,
|
||||
})
|
||||
}
|
||||
|
||||
for &field in fields_on(value.ty()) {
|
||||
// Complete the field name along with its value. Notes:
|
||||
// 1. No parentheses since function fields cannot currently be called
|
||||
@ -1394,7 +1381,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_whitespace_in_autocomplete() {
|
||||
fn test_autocomplete_whitespace() {
|
||||
//Check that extra space before '.' is handled correctly.
|
||||
test("#() .", 5, &[], &["insert", "remove", "len", "all"]);
|
||||
test("#{() .}", 6, &["insert", "remove", "len", "all"], &["foo"]);
|
||||
@ -1404,10 +1391,16 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_before_window_char_boundary() {
|
||||
fn test_autocomplete_before_window_char_boundary() {
|
||||
// Check that the `before_window` doesn't slice into invalid byte
|
||||
// boundaries.
|
||||
let s = "😀😀 #text(font: \"\")";
|
||||
test(s, s.len() - 2, &[], &[]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_autocomplete_mutable_method() {
|
||||
let s = "#{ let x = (1, 2, 3); x. }";
|
||||
test(s, s.len() - 2, &["at", "push", "pop"], &[]);
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,9 @@
|
||||
//! Handles special built-in methods on values.
|
||||
|
||||
use crate::diag::{At, SourceResult};
|
||||
use crate::foundations::{Args, Array, Dict, Str, Type, Value};
|
||||
use crate::foundations::{Args, Str, Type, Value};
|
||||
use crate::syntax::Span;
|
||||
|
||||
/// List the available methods for a type and whether they take arguments.
|
||||
pub fn mutable_methods_on(ty: Type) -> &'static [(&'static str, bool)] {
|
||||
if ty == Type::of::<Array>() {
|
||||
&[
|
||||
("first", false),
|
||||
("last", false),
|
||||
("at", true),
|
||||
("pop", false),
|
||||
("push", true),
|
||||
("insert", true),
|
||||
("remove", true),
|
||||
]
|
||||
} else if ty == Type::of::<Dict>() {
|
||||
&[("at", true), ("insert", true), ("remove", true)]
|
||||
} else {
|
||||
&[]
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether a specific method is mutating.
|
||||
pub(crate) fn is_mutating_method(method: &str) -> bool {
|
||||
matches!(method, "push" | "pop" | "insert" | "remove")
|
||||
|
@ -49,7 +49,7 @@ pub use self::float::*;
|
||||
pub use self::func::*;
|
||||
pub use self::int::*;
|
||||
pub use self::label::*;
|
||||
pub use self::methods::*;
|
||||
pub(crate) use self::methods::*;
|
||||
pub use self::module::*;
|
||||
pub use self::none::*;
|
||||
pub use self::plugin::*;
|
||||
|
Loading…
x
Reference in New Issue
Block a user