| 156 | } |
| 157 | |
| 158 | void highlight(const String & query, std::vector<replxx::Replxx::Color> & colors, const Context & context, int cursor_position, bool rainbow_parentheses) |
| 159 | { |
| 160 | using namespace replxx; |
| 161 | |
| 162 | /// The `colors` array maps to a Unicode code point position in a string into a color. |
| 163 | /// A color is set for every position individually (not for a range). |
| 164 | |
| 165 | /// Empty input. |
| 166 | if (colors.empty()) |
| 167 | return; |
| 168 | |
| 169 | /// The colors should be legible (and look gorgeous) in both dark and light themes. |
| 170 | /// When modifying this, check it in both themes. |
| 171 | |
| 172 | static const std::unordered_map<Highlight, Replxx::Color> type_to_color = |
| 173 | { |
| 174 | {Highlight::keyword, replxx::color::bold(Replxx::Color::DEFAULT)}, |
| 175 | {Highlight::identifier, Replxx::Color::CYAN}, |
| 176 | {Highlight::function, Replxx::Color::BROWN}, |
| 177 | {Highlight::alias, replxx::color::rgb666(0, 4, 4)}, |
| 178 | {Highlight::substitution, Replxx::Color::MAGENTA}, |
| 179 | {Highlight::number, replxx::color::rgb666(0, 4, 0)}, |
| 180 | {Highlight::string, Replxx::Color::GREEN}, |
| 181 | {Highlight::string_escape, replxx::color::bold(Replxx::Color::LIGHTGRAY)}, |
| 182 | {Highlight::string_metacharacter, replxx::color::bold(Replxx::Color::BRIGHTMAGENTA)}, |
| 183 | }; |
| 184 | |
| 185 | /// We set reasonably small limits for size/depth, because we don't want the CLI to be slow. |
| 186 | /// While syntax highlighting is unneeded for long queries, which the user couldn't read anyway. |
| 187 | |
| 188 | const char * begin = query.data(); |
| 189 | const char * end = begin + query.size(); |
| 190 | Tokens tokens(begin, end, 10000, true); |
| 191 | IParser::Pos token_iterator( |
| 192 | tokens, |
| 193 | static_cast<uint32_t>(context.getSettingsRef()[Setting::max_parser_depth]), |
| 194 | static_cast<uint32_t>(context.getSettingsRef()[Setting::max_parser_backtracks]) |
| 195 | ); |
| 196 | Expected expected; |
| 197 | expected.enable_highlighting = true; |
| 198 | |
| 199 | /// We don't do highlighting for foreign dialects, such as PRQL and Kusto. |
| 200 | /// Only normal ClickHouse SQL queries are highlighted. |
| 201 | |
| 202 | ParserQuery parser(end, false, context.getSettingsRef()[Setting::implicit_select]); |
| 203 | ASTPtr ast; |
| 204 | bool parse_res = false; |
| 205 | |
| 206 | try |
| 207 | { |
| 208 | while (!token_iterator->isEnd()) |
| 209 | { |
| 210 | parse_res = parser.parse(token_iterator, ast, expected); |
| 211 | if (!parse_res) |
| 212 | break; |
| 213 | |
| 214 | if (!token_iterator->isEnd() && token_iterator->type != TokenType::Semicolon) |
| 215 | { |
no test coverage detected