ass_editor/extensions/builtin/auto_complete/
extension.rs1use super::types::{AutoCompleteConfig, CompletionItem};
8use crate::core::{EditorDocument, Position, Result};
9use crate::extensions::{ExtensionCapability, ExtensionInfo, ExtensionState};
10use ass_core::parser::{Script, Section};
11
12#[cfg(not(feature = "std"))]
13use alloc::{
14 string::{String, ToString},
15 vec::Vec,
16};
17
18pub struct AutoCompleteExtension {
20 pub(super) info: ExtensionInfo,
21 pub(super) state: ExtensionState,
22 pub(super) style_names: Vec<String>,
24 pub(super) config: AutoCompleteConfig,
26}
27
28impl AutoCompleteExtension {
29 pub fn new() -> Self {
31 let info = ExtensionInfo::new(
32 "auto-complete".to_string(),
33 "1.0.0".to_string(),
34 "ASS-RS Team".to_string(),
35 "Built-in auto-completion for ASS/SSA files".to_string(),
36 )
37 .with_capability(ExtensionCapability::CodeCompletion)
38 .with_license("MIT".to_string());
39
40 Self {
41 info,
42 state: ExtensionState::Uninitialized,
43 style_names: Vec::new(),
44 config: AutoCompleteConfig::default(),
45 }
46 }
47
48 pub fn get_completions(
50 &mut self,
51 document: &EditorDocument,
52 position: Position,
53 ) -> Result<Vec<CompletionItem>> {
54 self.update_style_names(document)?;
56
57 let context = self.get_completion_context(document, position)?;
59
60 let mut completions = Vec::new();
62
63 if context.line.is_empty() || context.line.starts_with('[') {
65 completions.extend(self.get_section_completions(&context));
66 }
67
68 if let Some(ref section) = context.section {
70 if !context.in_override_tag && self.config.complete_fields {
71 completions.extend(self.get_field_completions(section, &context));
72 }
73 }
74
75 if context.in_override_tag && self.config.complete_tags {
77 completions.extend(self.get_tag_completions(&context));
78 }
79
80 if self.should_complete_style(&context) && self.config.complete_styles {
82 completions.extend(self.get_style_completions(&context));
83 }
84
85 completions.sort_by_key(|c| c.sort_order);
87 completions.truncate(self.config.max_suggestions);
88
89 Ok(completions)
90 }
91
92 pub(super) fn update_style_names(&mut self, document: &EditorDocument) -> Result<()> {
94 self.style_names.clear();
95
96 if let Ok(script) = Script::parse(&document.text()) {
97 for section in script.sections() {
98 if let Section::Styles(styles) = section {
99 for style in styles {
100 self.style_names.push(style.name.to_string());
101 }
102 }
103 }
104 }
105
106 Ok(())
107 }
108}
109
110impl Default for AutoCompleteExtension {
111 fn default() -> Self {
112 Self::new()
113 }
114}