1use std::{path::Path, sync::Arc};
2
3use anyhow::Result;
4use collections::HashMap;
5use gpui::{App, Global, ReadGlobal, UpdateGlobal};
6use parking_lot::RwLock;
7
8use crate::{Snippet, SnippetKind, file_stem_to_key};
9
10struct GlobalSnippetRegistry(Arc<SnippetRegistry>);
11
12impl Global for GlobalSnippetRegistry {}
13
14#[derive(Default)]
15pub struct SnippetRegistry {
16 snippets: RwLock<HashMap<SnippetKind, Vec<Arc<Snippet>>>>,
17}
18
19impl SnippetRegistry {
20 pub fn global(cx: &App) -> Arc<Self> {
21 GlobalSnippetRegistry::global(cx).0.clone()
22 }
23
24 pub fn try_global(cx: &App) -> Option<Arc<Self>> {
25 cx.try_global::<GlobalSnippetRegistry>()
26 .map(|registry| registry.0.clone())
27 }
28
29 pub fn init_global(cx: &mut App) {
30 GlobalSnippetRegistry::set_global(cx, GlobalSnippetRegistry(Arc::new(Self::new())))
31 }
32
33 pub fn new() -> Self {
34 Self {
35 snippets: RwLock::new(HashMap::default()),
36 }
37 }
38
39 pub fn register_snippets(&self, file_path: &Path, contents: &str) -> Result<()> {
40 let snippets_in_file: crate::format::VsSnippetsFile =
41 serde_json_lenient::from_str(contents)?;
42 let kind = file_path
43 .file_stem()
44 .and_then(|stem| stem.to_str().and_then(file_stem_to_key));
45 let snippets = crate::file_to_snippets(snippets_in_file);
46 self.snippets.write().insert(kind, snippets);
47
48 Ok(())
49 }
50
51 pub fn get_snippets(&self, kind: &SnippetKind) -> Vec<Arc<Snippet>> {
52 self.snippets.read().get(kind).cloned().unwrap_or_default()
53 }
54}