feat: explicitly trigger suggest after completed import/include snippets (#984)

* feat: explicitly trigger suggest on completing import/include snippets

* fix: comment

* test: update snapshot
This commit is contained in:
Myriad-Dreamin 2024-12-11 14:40:57 +08:00 committed by GitHub
parent a86f7a494a
commit 5747dd6ba6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 87 additions and 40 deletions

View file

@ -145,13 +145,18 @@ impl Analysis {
AllocStats::report(self)
}
/// Get configured trigger suggest command.
pub fn trigger_suggest(&self, context: bool) -> Option<&'static str> {
(self.completion_feat.trigger_suggest && context).then_some("editor.action.triggerSuggest")
}
/// Get configured trigger parameter hints command.
pub fn trigger_parameter_hints(&self, context: bool) -> Option<&'static str> {
(self.completion_feat.trigger_parameter_hints && context)
.then_some("editor.action.triggerParameterHints")
}
/// Get configured trigger after snippet command.
/// Get configured trigger suggest after snippet command.
///
/// > VS Code doesn't do that... Auto triggering suggestion only happens on
/// > typing (word starts or trigger characters). However, you can use
@ -162,7 +167,7 @@ impl Analysis {
return None;
}
(self.completion_feat.trigger_suggest && context).then_some("editor.action.triggerSuggest")
self.trigger_suggest(context)
}
/// Get configured trigger on positional parameter hints command.

View file

@ -19,6 +19,12 @@ pub enum PostfixSnippetScope {
Content,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "camelCase")]
pub enum CompletionCommand {
TriggerSuggest,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, strum::EnumIter)]
pub enum SurroundingSyntax {
Regular,
@ -163,6 +169,8 @@ pub struct PrefixSnippet {
pub snippet: EcoString,
/// The snippet description.
pub description: EcoString,
/// The command to execute.
pub command: Option<CompletionCommand>,
/// Lazily expanded context.
#[serde(skip)]
pub expanded_context: OnceLock<HashSet<CompletionContextKey>>,
@ -235,6 +243,31 @@ impl From<&ConstPrefixSnippet> for Interned<PrefixSnippet> {
label_detail: None,
snippet: snippet.snippet.into(),
description: snippet.description.into(),
command: None,
expanded_context: OnceLock::new(),
})
}
}
struct ConstPrefixSnippetWithSuggest {
context: InterpretMode,
label: &'static str,
snippet: &'static str,
description: &'static str,
}
impl From<&ConstPrefixSnippetWithSuggest> for Interned<PrefixSnippet> {
fn from(snippet: &ConstPrefixSnippetWithSuggest) -> Self {
Interned::new(PrefixSnippet {
context: eco_vec![CompletionContext {
mode: ContextSelector::Positive(Some(snippet.context)),
syntax: ContextSelector::Positive(None),
}],
label: snippet.label.into(),
label_detail: None,
snippet: snippet.snippet.into(),
description: snippet.description.into(),
command: Some(CompletionCommand::TriggerSuggest),
expanded_context: OnceLock::new(),
})
}
@ -344,36 +377,6 @@ pub static DEFAULT_PREFIX_SNIPPET: LazyLock<Vec<Interned<PrefixSnippet>>> = Lazy
snippet: "return ${output}",
description: "Returns early from a function.",
},
ConstPrefixSnippet {
context: InterpretMode::Code,
label: "import module",
snippet: "import \"${}\"",
description: "Imports module from another file.",
},
ConstPrefixSnippet {
context: InterpretMode::Code,
label: "import module by expression",
snippet: "import ${}",
description: "Imports items by expression.",
},
ConstPrefixSnippet {
context: InterpretMode::Code,
label: "import package",
snippet: "import \"@${}\": ${items}",
description: "Imports variables from another file.",
},
ConstPrefixSnippet {
context: InterpretMode::Code,
label: "include (file)",
snippet: "include \"${file}.typ\"",
description: "Includes content from another file.",
},
ConstPrefixSnippet {
context: InterpretMode::Code,
label: "include (package)",
snippet: "include \"@${}\"",
description: "Includes content from another file.",
},
ConstPrefixSnippet {
context: InterpretMode::Code,
label: "array literal",
@ -502,7 +505,42 @@ pub static DEFAULT_PREFIX_SNIPPET: LazyLock<Vec<Interned<PrefixSnippet>>> = Lazy
},
];
SNIPPETS.iter().map(From::from).collect()
const SNIPPET_SUGGEST: &[ConstPrefixSnippetWithSuggest] = &[
ConstPrefixSnippetWithSuggest {
context: InterpretMode::Code,
label: "import module",
snippet: "import \"${}\"",
description: "Imports module from another file.",
},
ConstPrefixSnippetWithSuggest {
context: InterpretMode::Code,
label: "import module by expression",
snippet: "import ${}",
description: "Imports items by expression.",
},
ConstPrefixSnippetWithSuggest {
context: InterpretMode::Code,
label: "import (package)",
snippet: "import \"@${}\"",
description: "Imports variables from another file.",
},
ConstPrefixSnippetWithSuggest {
context: InterpretMode::Code,
label: "include (file)",
snippet: "include \"${}\"",
description: "Includes content from another file.",
},
ConstPrefixSnippetWithSuggest {
context: InterpretMode::Code,
label: "include (package)",
snippet: "include \"@${}\"",
description: "Includes content from another file.",
},
];
let snippets = SNIPPETS.iter().map(From::from);
let snippets2 = SNIPPET_SUGGEST.iter().map(From::from);
snippets.chain(snippets2).collect()
});
pub static DEFAULT_POSTFIX_SNIPPET: LazyLock<Vec<PostfixSnippet>> = LazyLock::new(|| {

View file

@ -19,7 +19,8 @@ use super::{plain_docs_sentence, summarize_font_family};
use crate::adt::interner::Interned;
use crate::analysis::{analyze_labels, DynLabel, LocalContext, Ty};
use crate::snippet::{
CompletionContextKey, PrefixSnippet, SurroundingSyntax, DEFAULT_PREFIX_SNIPPET,
CompletionCommand, CompletionContextKey, PrefixSnippet, SurroundingSyntax,
DEFAULT_PREFIX_SNIPPET,
};
use crate::syntax::InterpretMode;
@ -670,15 +671,18 @@ impl<'a> CompletionContext<'a> {
continue;
}
let analysis = &self.ctx.analysis;
let command = match snippet.command {
Some(CompletionCommand::TriggerSuggest) => analysis.trigger_suggest(true),
None => analysis.trigger_on_snippet(snippet.snippet.contains("${")),
};
self.completions.push(Completion {
kind: CompletionKind::Syntax,
label: snippet.label.as_ref().into(),
apply: Some(snippet.snippet.as_ref().into()),
detail: Some(snippet.description.as_ref().into()),
command: self
.ctx
.analysis
.trigger_on_snippet(snippet.snippet.contains("${")),
command,
..Completion::default()
});
}

View file

@ -374,7 +374,7 @@ fn e2e() {
});
let hash = replay_log(&tinymist_binary, &root.join("neovim"));
insta::assert_snapshot!(hash, @"siphash128_13:8cebcc89c1cbdaab64ad54fded330afb");
insta::assert_snapshot!(hash, @"siphash128_13:3305840819ce4ac8adbbc73890288188");
}
{
@ -385,7 +385,7 @@ fn e2e() {
});
let hash = replay_log(&tinymist_binary, &root.join("vscode"));
insta::assert_snapshot!(hash, @"siphash128_13:6ee935b352766f1faebe86fac4cb77c1");
insta::assert_snapshot!(hash, @"siphash128_13:68d3c231276b454db893af55139d9cad");
}
}