#Tests for autocompletion
108 messages · Page 1 of 1 (latest)
Hey there 🙂
I've summed it up here https://github.com/typst/typst/pull/2912
But the main part of it is, are we okay with this kind of metadata // Autocomplete: explicit, with_label, contains "int","integer", excludes "bool" and there's also a few other questions
Should I copy them here?
Also things are cleanly separated so if you want multiple smaller PRs it's no problem
The PR size is okay as-is
What is the purpose of // Autocomplete: true |Â false?
Like // Ref: true|false but the main reason why I introduced it is that it would be convenient to have a way to ignore errors when validate_autocomplete is true, because often, when you work on autocompletion the errors and hints don't matter, it would make for clearer test but would be a bit more complex
Hmm, disabling tests might make sense
But Ref: true|false is different because it affects the test result. Whereas autocomplete only has an effect if you actually specify expected autocompletions.
If you want to split it, we could merge the other improvements more quickly. Otherwise, it can stay as one PR.
It's okay for me if it's a bit slower and I don't split it
Hints and errors should be handled the same. Either we have some way to ignore them (or maybe just ignore errors in the autocomplete line by default) or we just don't.
I think generally autocompletion tests should be separate from non-autocompeltion ones
So maybe they should be mutually exclusive
And autocomplete tests ignore errors
I think so too
Does it make sense to have access, in autocompletion tests, to explicit (in typst_ide::autocomplete(....., explicit : bool) ?
as well as label?
it is okay to always set explicit: true I think
explicit is mostly used to show a few default suggestions in case nothing more specific exists
nothing that would come up often in tests
Should we always test against Completion::apply? cause I think it makes more sense than label some time but other times it has a weird value {variable}/{other_variable}
I think always label is okay for now
Design problem !
Currently the second annotation works
// test.typ
// Autocomplete: true
// Ref: false
// Hints: false
---
// Autocomplete contains: `-1` "int", "if conditional"
// #i
---
// Autocomplete contains: `-1` "len", "first", "last", "at", "push", "pop", "insert", "remove", "slice", "contains", "find", "position", "range", "filter", "map", "enumerate", "zip", "fold", "sum", "product", "any", "all", "flatten", "rev", "split", "join", "intersperse", "sorted", "dedup", "first", "last", "at", "pop", "push", "insert", "remove", "foozerzer"
#().
but if you uncomment // #i it stops working because the parsing gets messed up with probably?
this workaround works
#let i = 0
#{
// Autocomplete contains: `-1` "int", "if conditional"
i
}
but it is a bit painful to require of autocomplete test writers
plus.. that's not exactly what you want to test
I pushed a working version on the PR, I'm maybe a bit verbose in my reporting/error printing warning but we have a verbose option so if some things are too much I can just put them behind that flag!
overall it's working pretty good already, it'll be really simple to add a Autocomplete exclude and to print a bit more when verbose
Uncommenting #i fails the second annotation? That's strange since the individual tests should be unrelated.
Or do you mean Autocomplete contains: -1 "int", "if conditional" with second annotation?
Even then, I don't understand why it would happen
Seems more like a bug than a design problem
Are they parsed separately?
No, I mean autocomplete doesn't work correctly for the second annotation if we have #i (errors ) before (parsing problem?)
They are parsed separately
It might be a parsing bug or an autocomplete bug but it's reasonable that autocomplete wouldn't work perfectly when there's an error in the file
Ah, that's super weird then
why would you expect int and if conditional after #i though?
it's not valid syntax there
Makes it seem like they are parsed together but I'll take a look
If you write #i you will get if and int in the completions suggestions
Ah, right
plus that test is actually passing by itself :p
why is -1 in backticks?
felt more meaningful that way, also eases the range parsing part, it's a "special" range value
I'm not married to it though
seems like extra typing pain tbh
that's fair but I think it's more readable, you want it removed?
the collision of the two usages of - is the problem?
but autocomplete never has a range right?
can I also use it in normal tests, e.g. 1--1?
or maybe in your case 1 - backtick - 1 backtick?
okay, I checked and I was wrong, it doesn't error the second annotation anymore, it must have been a weird bug on my part
I don't understand what 1--1 means
from 1 to -1
I'm not advocating for it, just asking whether it naturally arose from your implementation
No I only modified the range parsing, you can use -1 in any test but it is translated as the range -1..-1
since autocomplete doesn't' need a range
so it only works in isolation, not in a range?
I mean, it is a range, but it only works if you need an index
right now if someone passes a range with len != 0, i throw a warning in autocomplete
what we had before + -1
but are -1-2 probably not right?
1 is not a range tho
Okay for getting rid of the backticks
should we accept -1 as a position instead of a range then?
then -1--1 would be accepted but I don't love it
I don't mind either way
People are probably gonna complain about the confusing range syntax
thats fair, that's why I liked -1 as a shorthand, can we have that without the backticks?
I don't see why not
but then, let's keep the rest of the logic, no -1--1, not -1 as a position
okay
Well, ready for review!
@scarlet bobcat
I updated my PR, In order to refactor the error handling in the metadata parsing phase I moved a number of things around to simplify the code.
It had the nice properties of being able to error on invalid metadata keys which is really useful instead of just ignoring it.
The parsing of it gets ... bad though
currently it still ignores invalid keys cause these would be parsed as keys:
// See also: https://github.com/mTvare6/hello-world.rs
// Should output Name: Typst. Age: 2..
Plus the parsing is a bit messy not a big big deal but still
let metadata = |s: &mut Scanner<'a>| -> Option<(String, &'a str)> {
if !s.eat_if("//") {
return None;
}
s.eat_whitespace();
let key1 = s.eat_while(|c: char| !c.is_whitespace() && c != ':');
if key1.is_empty() {
return None;
}
s.eat_whitespace();
let key2 = s.eat_while(|c: char| !c.is_whitespace() && c != ':');
let key =
if key2.is_empty() { key1.to_string() } else { format!("{} {}", key1, key2) };
s.eat_whitespace();
if !s.eat_if(':') {
return None;
}
let value = s.eat_until('\n');
Some((key, value))
};
I would like to replace this all mess with s.eat_until(':')
a possible solution for this would be to force metadata to start with /// (or even \\\\ or \\! for forward compatibility) instead of //
It would allow to error on invalid metadata keys as well.
It requires changing 19 lines (17 tests)
I feel like that's not too big a change (I can do it obviously), Should I go forward with it?
what does /// give us over //? I don't yet understand.
current parsing consumes // then tries to find two words then consumes :
The problem is some comments starts the same way but are not metadata
examples: ```typ
// https://github.com/typst/typst/issues/2162
// Test whether relative: "parent" works correctly on conic gradients.
// Make sure they don't work when relative: "self".
/// would disambiguate it
It requires changing 19 lines (17 tests)
That's stupid; we need to change all tests ^^'
Or We need to say that // {key} {key}: is reserved and you should use /// which would only require only changing 19 lines, it seems sensible imo
@scarlet bobcat
can't we still hardcode which keys can occur?
it must start with "Error" or "Autocomplete" or sth like that after all
We can but then if the person writes error or Errors it doesn't work but looks like its working which is too easy to miss
We also want to think about it review wise
I guess it's not that much to ask to have /// for either annotations or comments looking like annotations
@tidal cloak I think we still had a bit of a misunderstanding. I think the setup now is confusing because most of the things that require triple slash disambiguation don't look like an annotation at all to a human. They just happen to have a colon somewhere. I think failing on error: or error : (as opposed to Error:) is reasonable, but failing on correct: is gonna be annoying really quickly.
the problem is how to differentiate between error and correct
there's no super easy way to check that something is a typo
to_lowercase is easy and would catch error
I could create a score that measures how like one of the annotation a string is and then we'd arbitrarily choose a max score but that seems brittle
I think it's okay to require some comments to have /// It's not that big of a deal imo
if you really think we need to catch other stuff, there is also hamming distance
that's true
I was thinking of something like that