| 115 | } |
| 116 | |
| 117 | fn suggest_types(&self, input: &str) { |
| 118 | let type_name = input.split(|c: char| c == ':' || c.is_whitespace()).next().unwrap_or(input); |
| 119 | if type_name == "*" || type_name.is_empty() { |
| 120 | return; |
| 121 | } |
| 122 | |
| 123 | let suggestions: Vec<_> = NodeId::all_variants() |
| 124 | .map(|id| id.tag_name()) |
| 125 | .map(|name| (name, levenshtein(name, type_name))) |
| 126 | .sorted_by(|(_, a), (_, b)| a.cmp(b)) |
| 127 | .enumerate() |
| 128 | .take_while_inclusive(|(i, (_, score))| *i < 4 && *score < 4) |
| 129 | .collect(); |
| 130 | |
| 131 | if !suggestions.is_empty() { |
| 132 | eprintln!("\nDid you mean:"); |
| 133 | for (_, (s, _)) in suggestions { |
| 134 | eprintln!(" {s}"); |
| 135 | } |
| 136 | } |
| 137 | eprintln!("\nRun 'csskit tree' to see all node types."); |
| 138 | } |
| 139 | |
| 140 | fn parsed_selectors<'b>(&'b self, bump: &'b Bump) -> Option<QuerySelectorList<'b>> { |
| 141 | let lexer = Lexer::new(&CsskitAtomSet::ATOMS, &self.selector); |