ass_editor/extensions/builtin/auto_complete/
editor_ext.rs1use super::extension::AutoCompleteExtension;
7use crate::core::{Position, Result};
8use crate::extensions::{
9 EditorExtension, ExtensionCommand, ExtensionContext, ExtensionInfo, ExtensionResult,
10 ExtensionState, MessageLevel,
11};
12
13#[cfg(not(feature = "std"))]
14use alloc::{
15 collections::BTreeMap as HashMap,
16 format,
17 string::{String, ToString},
18 vec,
19 vec::Vec,
20};
21#[cfg(feature = "std")]
22use std::collections::HashMap;
23
24impl EditorExtension for AutoCompleteExtension {
25 fn info(&self) -> &ExtensionInfo {
26 &self.info
27 }
28
29 fn initialize(&mut self, context: &mut dyn ExtensionContext) -> Result<()> {
30 self.state = ExtensionState::Active;
31
32 if let Some(fields) = context.get_config("autocomplete.complete_fields") {
34 self.config.complete_fields = fields == "true";
35 }
36 if let Some(styles) = context.get_config("autocomplete.complete_styles") {
37 self.config.complete_styles = styles == "true";
38 }
39 if let Some(tags) = context.get_config("autocomplete.complete_tags") {
40 self.config.complete_tags = tags == "true";
41 }
42 if let Some(values) = context.get_config("autocomplete.complete_values") {
43 self.config.complete_values = values == "true";
44 }
45 if let Some(max) = context.get_config("autocomplete.max_suggestions") {
46 if let Ok(max_val) = max.parse() {
47 self.config.max_suggestions = max_val;
48 }
49 }
50
51 context.show_message("Auto-completion initialized", MessageLevel::Info)?;
52 Ok(())
53 }
54
55 fn shutdown(&mut self, _context: &mut dyn ExtensionContext) -> Result<()> {
56 self.state = ExtensionState::Shutdown;
57 self.style_names.clear();
58 Ok(())
59 }
60
61 fn state(&self) -> ExtensionState {
62 self.state
63 }
64
65 fn execute_command(
66 &mut self,
67 command_id: &str,
68 args: &HashMap<String, String>,
69 context: &mut dyn ExtensionContext,
70 ) -> Result<ExtensionResult> {
71 match command_id {
72 "autocomplete.trigger" => {
73 if let Some(doc) = context.current_document() {
74 let position = if let Some(offset_str) = args.get("position") {
76 if let Ok(offset) = offset_str.parse() {
77 Position::new(offset)
78 } else {
79 Position::new(doc.len_bytes())
80 }
81 } else {
82 Position::new(doc.len_bytes())
83 };
84
85 let completions = self.get_completions(doc, position)?;
86 let mut result = ExtensionResult::success_with_message(format!(
87 "Found {} completions",
88 completions.len()
89 ));
90
91 for (i, completion) in completions.iter().take(10).enumerate() {
93 result
94 .data
95 .insert(format!("completion_{i}"), completion.insert_text.clone());
96 }
97
98 Ok(result)
99 } else {
100 Ok(ExtensionResult::failure("No active document".to_string()))
101 }
102 }
103 "autocomplete.update_styles" => {
104 if let Some(doc) = context.current_document() {
105 self.update_style_names(doc)?;
106 Ok(ExtensionResult::success_with_message(format!(
107 "Updated {} style names",
108 self.style_names.len()
109 )))
110 } else {
111 Ok(ExtensionResult::failure("No active document".to_string()))
112 }
113 }
114 _ => Ok(ExtensionResult::failure(format!(
115 "Unknown command: {command_id}"
116 ))),
117 }
118 }
119
120 fn commands(&self) -> Vec<ExtensionCommand> {
121 vec![
122 ExtensionCommand::new(
123 "autocomplete.trigger".to_string(),
124 "Trigger Completion".to_string(),
125 "Get completion suggestions at cursor position".to_string(),
126 )
127 .with_category("Completion".to_string()),
128 ExtensionCommand::new(
129 "autocomplete.update_styles".to_string(),
130 "Update Style Names".to_string(),
131 "Update known style names from document".to_string(),
132 )
133 .with_category("Completion".to_string()),
134 ]
135 }
136
137 fn config_schema(&self) -> HashMap<String, String> {
138 let mut schema = HashMap::new();
139 schema.insert(
140 "autocomplete.complete_fields".to_string(),
141 "boolean".to_string(),
142 );
143 schema.insert(
144 "autocomplete.complete_styles".to_string(),
145 "boolean".to_string(),
146 );
147 schema.insert(
148 "autocomplete.complete_tags".to_string(),
149 "boolean".to_string(),
150 );
151 schema.insert(
152 "autocomplete.complete_values".to_string(),
153 "boolean".to_string(),
154 );
155 schema.insert(
156 "autocomplete.max_suggestions".to_string(),
157 "number".to_string(),
158 );
159 schema.insert("autocomplete.min_chars".to_string(), "number".to_string());
160 schema
161 }
162}