| 291 | type Candidate = String; |
| 292 | |
| 293 | fn complete( |
| 294 | &self, |
| 295 | line: &str, |
| 296 | pos: usize, |
| 297 | _ctx: &Context<'_>, |
| 298 | ) -> Result<(usize, Vec<Self::Candidate>), ReadlineError> { |
| 299 | let (start, word) = extract_word(line, pos, None, |c| c.is_space()); |
| 300 | |
| 301 | // Handle command completion |
| 302 | if word.starts_with('/') { |
| 303 | return Ok(complete_command(self.available_commands.clone(), word, start)); |
| 304 | } |
| 305 | |
| 306 | if line.starts_with('@') { |
| 307 | let search_word = line.strip_prefix('@').unwrap_or(""); |
| 308 | if let Ok(completions) = self.prompt_completer.complete_prompt(search_word) { |
| 309 | if !completions.is_empty() { |
| 310 | return Ok((0, completions)); |
| 311 | } |
| 312 | } |
| 313 | } |
| 314 | |
| 315 | // Handle file path completion as fallback |
| 316 | if let Ok((pos, completions)) = self.path_completer.complete_path(line, pos, _ctx) { |
| 317 | if !completions.is_empty() { |
| 318 | return Ok((pos, completions)); |
| 319 | } |
| 320 | } |
| 321 | |
| 322 | // Default: no completions |
| 323 | Ok((start, Vec::new())) |
| 324 | } |
| 325 | } |
| 326 | |
| 327 | /// Custom hinter that provides shadowtext suggestions |