Add auto-completion support for snippet files (#23698)
Release Notes: - Added auto-completion support for snippet files. 
This commit is contained in:
parent
6e9ea47849
commit
6293b20fd0
7 changed files with 64 additions and 5 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -6956,6 +6956,7 @@ dependencies = [
|
|||
"serde_json",
|
||||
"settings",
|
||||
"smol",
|
||||
"snippet_provider",
|
||||
"task",
|
||||
"text",
|
||||
"theme",
|
||||
|
@ -12059,6 +12060,7 @@ dependencies = [
|
|||
"gpui",
|
||||
"parking_lot",
|
||||
"paths",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"snippet",
|
||||
|
|
|
@ -60,6 +60,7 @@ serde.workspace = true
|
|||
serde_json.workspace = true
|
||||
settings.workspace = true
|
||||
smol.workspace = true
|
||||
snippet_provider.workspace = true
|
||||
task.workspace = true
|
||||
toml.workspace = true
|
||||
tree-sitter = { workspace = true, optional = true }
|
||||
|
|
|
@ -85,6 +85,7 @@ impl JsonLspAdapter {
|
|||
cx,
|
||||
);
|
||||
let tasks_schema = task::TaskTemplates::generate_json_schema();
|
||||
let snippets_schema = snippet_provider::format::VSSnippetsFile::generate_json_schema();
|
||||
let tsconfig_schema = serde_json::Value::from_str(TSCONFIG_SCHEMA).unwrap();
|
||||
let package_json_schema = serde_json::Value::from_str(PACKAGE_JSON_SCHEMA).unwrap();
|
||||
|
||||
|
@ -125,8 +126,17 @@ impl JsonLspAdapter {
|
|||
paths::local_tasks_file_relative_path()
|
||||
],
|
||||
"schema": tasks_schema,
|
||||
},
|
||||
{
|
||||
"fileMatch": [
|
||||
schema_file_match(
|
||||
paths::snippets_dir()
|
||||
.join("*.json")
|
||||
.as_path()
|
||||
)
|
||||
],
|
||||
"schema": snippets_schema,
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
})
|
||||
|
|
|
@ -189,6 +189,12 @@ pub fn themes_dir() -> &'static PathBuf {
|
|||
THEMES_DIR.get_or_init(|| config_dir().join("themes"))
|
||||
}
|
||||
|
||||
/// Returns the path to the snippets directory.
|
||||
pub fn snippets_dir() -> &'static PathBuf {
|
||||
static SNIPPETS_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
SNIPPETS_DIR.get_or_init(|| config_dir().join("snippets"))
|
||||
}
|
||||
|
||||
/// Returns the path to the contexts directory.
|
||||
///
|
||||
/// This is where the saved contexts from the Assistant are stored.
|
||||
|
|
|
@ -21,3 +21,4 @@ serde.workspace = true
|
|||
serde_json.workspace = true
|
||||
snippet.workspace = true
|
||||
util.workspace = true
|
||||
schemars.workspace = true
|
||||
|
|
|
@ -1,13 +1,47 @@
|
|||
use collections::HashMap;
|
||||
use schemars::{
|
||||
gen::SchemaSettings,
|
||||
schema::{ObjectValidation, Schema, SchemaObject},
|
||||
JsonSchema,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_json::Value;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub(crate) struct VSSnippetsFile {
|
||||
pub struct VSSnippetsFile {
|
||||
#[serde(flatten)]
|
||||
pub(crate) snippets: HashMap<String, VSCodeSnippet>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
impl VSSnippetsFile {
|
||||
pub fn generate_json_schema() -> Value {
|
||||
let schema = SchemaSettings::draft07()
|
||||
.with(|settings| settings.option_add_null_type = false)
|
||||
.into_generator()
|
||||
.into_root_schema_for::<Self>();
|
||||
|
||||
serde_json::to_value(schema).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl JsonSchema for VSSnippetsFile {
|
||||
fn schema_name() -> String {
|
||||
"VSSnippetsFile".into()
|
||||
}
|
||||
|
||||
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> Schema {
|
||||
SchemaObject {
|
||||
object: Some(Box::new(ObjectValidation {
|
||||
additional_properties: Some(Box::new(gen.subschema_for::<VSCodeSnippet>())),
|
||||
..Default::default()
|
||||
})),
|
||||
..Default::default()
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
#[serde(untagged)]
|
||||
pub(crate) enum ListOrDirect {
|
||||
Single(String),
|
||||
|
@ -36,9 +70,14 @@ impl std::fmt::Display for ListOrDirect {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub(crate) struct VSCodeSnippet {
|
||||
/// The snippet prefix used to decide whether a completion menu should be shown.
|
||||
pub(crate) prefix: Option<ListOrDirect>,
|
||||
|
||||
/// The snippet content. Use `$1` and `${1:defaultText}` to define cursor positions and `$0` for final cursor position.
|
||||
pub(crate) body: ListOrDirect,
|
||||
|
||||
/// The snippet description displayed inside the completion menu.
|
||||
pub(crate) description: Option<ListOrDirect>,
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
mod extension_snippet;
|
||||
mod format;
|
||||
pub mod format;
|
||||
mod registry;
|
||||
|
||||
use std::{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue