From ea8980a28cc0503880efd64dfa76b613e999a209 Mon Sep 17 00:00:00 2001 From: Elias Aebi Date: Sat, 7 Oct 2023 18:46:01 +0200 Subject: [PATCH] SyntaxScopeMap improvements --- atom/src/syntax-scope-map.cc | 53 +++++++++++++++------- language-html/grammars/tree-sitter-html.cc | 4 +- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/atom/src/syntax-scope-map.cc b/atom/src/syntax-scope-map.cc index c41f9e2..6a23189 100644 --- a/atom/src/syntax-scope-map.cc +++ b/atom/src/syntax-scope-map.cc @@ -16,53 +16,59 @@ struct Node { double indexValue; }; -static bool isNameChar(char c) { +bool isNameChar(char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' || c == '-'; } -template static void process(F f, const std::string &selector) { +template void process(F f, const std::string &selector) { std::vector nodes; - for (size_t i = 0; i < selector.size();) { + const size_t length = selector.size(); + for (size_t i = 0; i < length;) { const char c = selector[i]; - if (isNameChar(selector[i])) { + if (isNameChar(c)) { const size_t start = i; while (i < selector.size() && isNameChar(selector[i])) { i++; } nodes.push_back({NodeType::tag, selector.substr(start, i - start)}); - } else if (selector[i] == '"') { + } else if (c == '"' || c == '\'') { + const char quote = c; const size_t start = i; i++; - while (i < selector.size() && selector[i] != '"') { - i++; + while (i < length && selector[i] != quote) { + if (selector[i] == '\\' && i + 1 < length) { + i += 2; + } else { + i++; + } } - if (i < selector.size() && selector[i] == '"') { + if (i < length && selector[i] == quote) { i++; } nodes.push_back({NodeType::string, selector.substr(start, i - start)}); - } else if (selector[i] == '*') { + } else if (c == '*') { const size_t start = i; i++; nodes.push_back({NodeType::universal, selector.substr(start, i - start)}); - } else if (selector[i] == '>') { + } else if (c == '>') { const size_t start = i; i++; nodes.push_back({NodeType::combinator, selector.substr(start, i - start)}); - } else if (selector[i] == ':') { + } else if (c == ':') { const size_t start = i; i++; - while (i < selector.size() && isNameChar(selector[i])) { + while (i < length && isNameChar(selector[i])) { i++; } const size_t end = i; double index = 0; - if (i < selector.size() && selector[i] == '(') { + if (i < length && selector[i] == '(') { i++; - while (i < selector.size() && selector[i] >= '0' && selector[i] <= '9') { + while (i < length && selector[i] >= '0' && selector[i] <= '9') { index = index * 10 + (selector[i] - '0'); i++; } - if (i < selector.size() && selector[i] == ')') { + if (i < length && selector[i] == ')') { i++; } } @@ -74,6 +80,21 @@ template static void process(F f, const std::string &selector) { f(nodes); } +std::string unescape(const std::string &s) { + std::string result; + const size_t length = s.size(); + for (size_t i = 0; i < length;) { + if (s[i] == '\\' && i + 1 < length) { + result.push_back(s[i + 1]); + i += 2; + } else { + result.push_back(s[i]); + i++; + } + } + return result; +} + } static void setTableDefaults(std::unordered_map> &, bool); @@ -123,7 +144,7 @@ void SyntaxScopeMap::addSelector(const std::string &selector, std::shared_ptranonymousScopeTable; - const std::string value = termNode.value.substr(1, termNode.value.size() - 2); //.replace(/\\"/g, '"'); + const std::string value = unescape(termNode.value.substr(1, termNode.value.size() - 2)); if (!(*currentMap)[value]) (*currentMap)[value] = std::unique_ptr(new Table()); currentTable = (*currentMap)[value].get(); } diff --git a/language-html/grammars/tree-sitter-html.cc b/language-html/grammars/tree-sitter-html.cc index 2b1b98f..da4574b 100644 --- a/language-html/grammars/tree-sitter-html.cc +++ b/language-html/grammars/tree-sitter-html.cc @@ -69,9 +69,9 @@ extern "C" TreeSitterGrammar *atom_language_html() { // Target the first and last. // Single quotes and double quotes are targeted in separate selectors because // of quote-escaping difficulties. - scope("quoted_attribute_value > \"\"\":nth-child(0)", "punctuation.definition.string.begin"), + scope("quoted_attribute_value > '\"':nth-child(0)", "punctuation.definition.string.begin"), scope("quoted_attribute_value > \"'\":nth-child(0)", "punctuation.definition.string.begin"), - scope("quoted_attribute_value > \"\"\":nth-child(2)", "punctuation.definition.string.end"), + scope("quoted_attribute_value > '\"':nth-child(2)", "punctuation.definition.string.end"), scope("quoted_attribute_value > \"'\":nth-child(2)", "punctuation.definition.string.end") );