mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-23 12:45:04 +00:00
feat: don't trigger trivial completion when the trigger char is an ascii punctuation (#748)
This commit is contained in:
parent
e8f5f6185a
commit
493f8a8695
13 changed files with 162 additions and 6 deletions
|
@ -46,6 +46,8 @@ pub struct CompletionRequest {
|
||||||
pub position: LspPosition,
|
pub position: LspPosition,
|
||||||
/// Whether the completion is triggered explicitly.
|
/// Whether the completion is triggered explicitly.
|
||||||
pub explicit: bool,
|
pub explicit: bool,
|
||||||
|
/// The character that triggered the completion, if any.
|
||||||
|
pub trigger_character: Option<char>,
|
||||||
/// Whether to trigger suggest completion, a.k.a. auto-completion.
|
/// Whether to trigger suggest completion, a.k.a. auto-completion.
|
||||||
pub trigger_suggest: bool,
|
pub trigger_suggest: bool,
|
||||||
/// Whether to trigger named parameter completion.
|
/// Whether to trigger named parameter completion.
|
||||||
|
@ -145,6 +147,7 @@ impl StatefulRequest for CompletionRequest {
|
||||||
&source,
|
&source,
|
||||||
cursor,
|
cursor,
|
||||||
explicit,
|
explicit,
|
||||||
|
self.trigger_character,
|
||||||
self.trigger_suggest,
|
self.trigger_suggest,
|
||||||
self.trigger_parameter_hints,
|
self.trigger_parameter_hints,
|
||||||
self.trigger_named_completion,
|
self.trigger_named_completion,
|
||||||
|
@ -336,6 +339,11 @@ mod tests {
|
||||||
|
|
||||||
let docs = find_module_level_docs(&source).unwrap_or_default();
|
let docs = find_module_level_docs(&source).unwrap_or_default();
|
||||||
let properties = get_test_properties(&docs);
|
let properties = get_test_properties(&docs);
|
||||||
|
|
||||||
|
let trigger_character = properties
|
||||||
|
.get("trigger_character")
|
||||||
|
.map(|v| v.chars().next().unwrap());
|
||||||
|
|
||||||
let mut includes = HashSet::new();
|
let mut includes = HashSet::new();
|
||||||
let mut excludes = HashSet::new();
|
let mut excludes = HashSet::new();
|
||||||
|
|
||||||
|
@ -389,6 +397,7 @@ mod tests {
|
||||||
path: ctx.path_for_id(id).unwrap(),
|
path: ctx.path_for_id(id).unwrap(),
|
||||||
position: ctx.to_lsp_pos(s, &source),
|
position: ctx.to_lsp_pos(s, &source),
|
||||||
explicit: false,
|
explicit: false,
|
||||||
|
trigger_character,
|
||||||
trigger_suggest: true,
|
trigger_suggest: true,
|
||||||
trigger_parameter_hints: true,
|
trigger_parameter_hints: true,
|
||||||
trigger_named_completion: true,
|
trigger_named_completion: true,
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
// contains: attach
|
||||||
|
$: /* range -1..0 */$
|
|
@ -0,0 +1,3 @@
|
||||||
|
// contains: attach
|
||||||
|
// trigger_character: :
|
||||||
|
$: /* range -1..0 */$
|
|
@ -0,0 +1,2 @@
|
||||||
|
// contains: attach
|
||||||
|
$: /* range -1..0 */$
|
|
@ -0,0 +1,3 @@
|
||||||
|
// contains: attach
|
||||||
|
// trigger_character: :
|
||||||
|
$: /* range -1..0 */$
|
|
@ -0,0 +1,3 @@
|
||||||
|
// contains: length
|
||||||
|
// trigger_character: :
|
||||||
|
#set text(baseline: /* range -1..0 */)
|
|
@ -0,0 +1,33 @@
|
||||||
|
---
|
||||||
|
source: crates/tinymist-query/src/completion.rs
|
||||||
|
description: Completion on (22..23)
|
||||||
|
expression: "JsonRepr::new_pure(results)"
|
||||||
|
input_file: crates/tinymist-query/src/fixtures/completion/colon_markup.typ
|
||||||
|
---
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"isIncomplete": false,
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"kind": 3,
|
||||||
|
"label": "attach",
|
||||||
|
"labelDetails": {
|
||||||
|
"description": "(content, b: content | none, bl: content | none, br: content | none, t: content | none, tl: content | none, tr: content | none) => attach"
|
||||||
|
},
|
||||||
|
"textEdit": {
|
||||||
|
"newText": "attach(${1:})",
|
||||||
|
"range": {
|
||||||
|
"end": {
|
||||||
|
"character": 2,
|
||||||
|
"line": 1
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"character": 1,
|
||||||
|
"line": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
source: crates/tinymist-query/src/completion.rs
|
||||||
|
description: Completion on (46..47)
|
||||||
|
expression: "JsonRepr::new_pure(results)"
|
||||||
|
input_file: crates/tinymist-query/src/fixtures/completion/colon_markup2.typ
|
||||||
|
---
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"isIncomplete": false,
|
||||||
|
"items": []
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,33 @@
|
||||||
|
---
|
||||||
|
source: crates/tinymist-query/src/completion.rs
|
||||||
|
description: Completion on (22..23)
|
||||||
|
expression: "JsonRepr::new_pure(results)"
|
||||||
|
input_file: crates/tinymist-query/src/fixtures/completion/colon_math.typ
|
||||||
|
---
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"isIncomplete": false,
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"kind": 3,
|
||||||
|
"label": "attach",
|
||||||
|
"labelDetails": {
|
||||||
|
"description": "(content, b: content | none, bl: content | none, br: content | none, t: content | none, tl: content | none, tr: content | none) => attach"
|
||||||
|
},
|
||||||
|
"textEdit": {
|
||||||
|
"newText": "attach(${1:})",
|
||||||
|
"range": {
|
||||||
|
"end": {
|
||||||
|
"character": 2,
|
||||||
|
"line": 1
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"character": 1,
|
||||||
|
"line": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
source: crates/tinymist-query/src/completion.rs
|
||||||
|
description: Completion on (46..47)
|
||||||
|
expression: "JsonRepr::new_pure(results)"
|
||||||
|
input_file: crates/tinymist-query/src/fixtures/completion/colon_math2.typ
|
||||||
|
---
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"isIncomplete": false,
|
||||||
|
"items": []
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,31 @@
|
||||||
|
---
|
||||||
|
source: crates/tinymist-query/src/completion.rs
|
||||||
|
description: Completion on (63..64)
|
||||||
|
expression: "JsonRepr::new_pure(results)"
|
||||||
|
input_file: crates/tinymist-query/src/fixtures/completion/colon_param.typ
|
||||||
|
---
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"isIncomplete": false,
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"kind": 15,
|
||||||
|
"label": "length",
|
||||||
|
"sortText": "000",
|
||||||
|
"textEdit": {
|
||||||
|
"newText": " ${1:length}",
|
||||||
|
"range": {
|
||||||
|
"end": {
|
||||||
|
"character": 19,
|
||||||
|
"line": 2
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"character": 19,
|
||||||
|
"line": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
|
@ -187,7 +187,7 @@ fn complete_markup(ctx: &mut CompletionContext) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Anywhere: "|".
|
// Anywhere: "|".
|
||||||
if ctx.explicit {
|
if !is_triggerred_by_punc(ctx.trigger_character) && ctx.explicit {
|
||||||
ctx.from = ctx.cursor;
|
ctx.from = ctx.cursor;
|
||||||
markup_completions(ctx);
|
markup_completions(ctx);
|
||||||
return true;
|
return true;
|
||||||
|
@ -316,14 +316,16 @@ fn complete_math(ctx: &mut CompletionContext) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Behind existing atom or identifier: "$a|$" or "$abc|$".
|
// Behind existing atom or identifier: "$a|$" or "$abc|$".
|
||||||
if matches!(ctx.leaf.kind(), SyntaxKind::Text | SyntaxKind::MathIdent) {
|
if !is_triggerred_by_punc(ctx.trigger_character)
|
||||||
|
&& matches!(ctx.leaf.kind(), SyntaxKind::Text | SyntaxKind::MathIdent)
|
||||||
|
{
|
||||||
ctx.from = ctx.leaf.offset();
|
ctx.from = ctx.leaf.offset();
|
||||||
math_completions(ctx);
|
math_completions(ctx);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Anywhere: "$|$".
|
// Anywhere: "$|$".
|
||||||
if ctx.explicit {
|
if !is_triggerred_by_punc(ctx.trigger_character) && ctx.explicit {
|
||||||
ctx.from = ctx.cursor;
|
ctx.from = ctx.cursor;
|
||||||
math_completions(ctx);
|
math_completions(ctx);
|
||||||
return true;
|
return true;
|
||||||
|
@ -959,6 +961,7 @@ pub struct CompletionContext<'a, 'b> {
|
||||||
pub leaf: LinkedNode<'a>,
|
pub leaf: LinkedNode<'a>,
|
||||||
pub cursor: usize,
|
pub cursor: usize,
|
||||||
pub explicit: bool,
|
pub explicit: bool,
|
||||||
|
pub trigger_character: Option<char>,
|
||||||
pub trigger_suggest: bool,
|
pub trigger_suggest: bool,
|
||||||
pub trigger_parameter_hints: bool,
|
pub trigger_parameter_hints: bool,
|
||||||
pub trigger_named_completion: bool,
|
pub trigger_named_completion: bool,
|
||||||
|
@ -980,6 +983,7 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
|
||||||
source: &'a Source,
|
source: &'a Source,
|
||||||
cursor: usize,
|
cursor: usize,
|
||||||
explicit: bool,
|
explicit: bool,
|
||||||
|
trigger_character: Option<char>,
|
||||||
trigger_suggest: bool,
|
trigger_suggest: bool,
|
||||||
trigger_parameter_hints: bool,
|
trigger_parameter_hints: bool,
|
||||||
trigger_named_completion: bool,
|
trigger_named_completion: bool,
|
||||||
|
@ -996,6 +1000,7 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
|
||||||
root,
|
root,
|
||||||
leaf,
|
leaf,
|
||||||
cursor,
|
cursor,
|
||||||
|
trigger_character,
|
||||||
trigger_suggest,
|
trigger_suggest,
|
||||||
trigger_parameter_hints,
|
trigger_parameter_hints,
|
||||||
trigger_named_completion,
|
trigger_named_completion,
|
||||||
|
@ -1298,3 +1303,7 @@ fn slice_at(s: &str, mut rng: Range<usize>) -> &str {
|
||||||
|
|
||||||
&s[rng]
|
&s[rng]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_triggerred_by_punc(trigger_character: Option<char>) -> bool {
|
||||||
|
trigger_character.is_some_and(|c| c.is_ascii_punctuation())
|
||||||
|
}
|
||||||
|
|
|
@ -746,10 +746,13 @@ impl LanguageState {
|
||||||
|
|
||||||
fn completion(&mut self, req_id: RequestId, params: CompletionParams) -> ScheduledResult {
|
fn completion(&mut self, req_id: RequestId, params: CompletionParams) -> ScheduledResult {
|
||||||
let (path, position) = as_path_pos(params.text_document_position);
|
let (path, position) = as_path_pos(params.text_document_position);
|
||||||
let explicit = params
|
let explicit = params.context.as_ref().map_or(false, |context| {
|
||||||
|
context.trigger_kind == CompletionTriggerKind::INVOKED
|
||||||
|
});
|
||||||
|
let trigger_character = params
|
||||||
.context
|
.context
|
||||||
.map(|context| context.trigger_kind == CompletionTriggerKind::INVOKED)
|
.and_then(|c| c.trigger_character)
|
||||||
.unwrap_or(false);
|
.and_then(|c| c.chars().next());
|
||||||
let trigger_suggest = self.config.trigger_suggest;
|
let trigger_suggest = self.config.trigger_suggest;
|
||||||
let trigger_parameter_hints = self.config.trigger_parameter_hints;
|
let trigger_parameter_hints = self.config.trigger_parameter_hints;
|
||||||
let trigger_named_completion = self.config.trigger_named_completion;
|
let trigger_named_completion = self.config.trigger_named_completion;
|
||||||
|
@ -760,6 +763,7 @@ impl LanguageState {
|
||||||
path,
|
path,
|
||||||
position,
|
position,
|
||||||
explicit,
|
explicit,
|
||||||
|
trigger_character,
|
||||||
trigger_suggest,
|
trigger_suggest,
|
||||||
trigger_parameter_hints,
|
trigger_parameter_hints,
|
||||||
trigger_named_completion
|
trigger_named_completion
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue