diff --git a/grammar/bash.scm b/grammar/bash.scm index eb7aa41..4554282 100644 --- a/grammar/bash.scm +++ b/grammar/bash.scm @@ -281,7 +281,7 @@ (extglob_pattern) ] @string.regexp -;; #fbb152 #000000 0 0 0 3 +;; #51eeba #000000 0 0 0 3 ((program . (comment) @keyword.directive @nospell) diff --git a/grammar/ruby.scm b/grammar/ruby.scm index a2e78a1..7c70da7 100644 --- a/grammar/ruby.scm +++ b/grammar/ruby.scm @@ -245,23 +245,11 @@ ;; #AAAAAA #000000 0 1 0 1 (comment) @comment -(program - (comment)+ @comment.documentation - (class)) - -(module - (comment)+ @comment.documentation - (body_statement - (class))) - -(class - (comment)+ @comment.documentation - (body_statement - (method))) - -(body_statement - (comment)+ @comment.documentation - (method)) +;; #51eeba #000000 0 0 0 3 +((program + . + (comment) @shebang @nospell) + (#match? @shebang "^#!/")) ;; #ffffff #000000 0 0 0 1 [ diff --git a/include/ts.h b/include/ts.h index 96ff6f2..5c39ef0 100644 --- a/include/ts.h +++ b/include/ts.h @@ -2,10 +2,14 @@ #define TS_H #include "./editor.h" +#include #define HEX(s) (static_cast(std::stoul(s, nullptr, 16))) +extern std::unordered_map regex_cache; + TSQuery *load_query(const char *query_path, Editor *editor); void ts_collect_spans(Editor *editor); +void clear_regex_cache(); #endif diff --git a/src/editor.cc b/src/editor.cc index 5730686..6da8afd 100644 --- a/src/editor.cc +++ b/src/editor.cc @@ -12,8 +12,11 @@ Editor *new_editor(const char *filename, Coord position, Coord size) { return nullptr; uint32_t len = 0; char *str = load_file(filename, &len); - if (!str) + if (!str) { + free_editor(editor); + log("me?"); return nullptr; + } editor->filename = filename; editor->position = position; editor->size = size; diff --git a/src/main.cc b/src/main.cc index ad9dc2c..dce00ef 100644 --- a/src/main.cc +++ b/src/main.cc @@ -5,22 +5,14 @@ #include #include #include -#include #include #include std::atomic running{true}; Queue event_queue; -std::atomic render_frames{0}; -std::atomic worker_frames{0}; - -auto start_time = std::chrono::high_resolution_clock::now(); - void background_worker(Editor *editor) { while (running) { - worker_frames++; - ts_collect_spans(editor); std::this_thread::sleep_for(std::chrono::milliseconds(16)); @@ -164,7 +156,7 @@ void handle_editor_event(Editor *editor, KeyEvent event) { int main(int argc, char *argv[]) { Coord screen = start_screen(); - const char *filename = (argc > 1) ? argv[1] : "ts.cpp"; + const char *filename = (argc > 1) ? argv[1] : ""; Editor *editor = new_editor(filename, {0, 0}, {screen.row, screen.col}); if (!editor) { @@ -173,14 +165,10 @@ int main(int argc, char *argv[]) { return 1; } - start_time = std::chrono::high_resolution_clock::now(); - std::thread input_thread(input_listener); std::thread work_thread(background_worker, editor); while (running) { - render_frames++; - KeyEvent event; while (event_queue.pop(event)) handle_editor_event(editor, event); @@ -196,20 +184,9 @@ int main(int argc, char *argv[]) { if (work_thread.joinable()) work_thread.join(); - auto end_time = std::chrono::high_resolution_clock::now(); - double seconds = std::chrono::duration(end_time - start_time).count(); - - double render_fps = render_frames / seconds; - double worker_fps = worker_frames / seconds; - end_screen(); - std::cout << "\n======= Performance Summary =======\n"; - std::cout << "Runtime: " << seconds << "s\n"; - std::cout << "Render loop FPS: " << render_fps << "Hz\n"; - std::cout << "Worker loop FPS: " << worker_fps << "Hz\n"; - std::cout << "===================================\n"; - free_editor(editor); + clear_regex_cache(); return 0; } diff --git a/src/ts.cc b/src/ts.cc index b09a2cd..1c41b67 100644 --- a/src/ts.cc +++ b/src/ts.cc @@ -8,7 +8,27 @@ #include #include -static std::unordered_map regex_cache; +std::unordered_map regex_cache; + +void clear_regex_cache() { + for (auto &kv : regex_cache) { + pcre2_code_free(kv.second); + } + regex_cache.clear(); +} + +pcre2_code *get_re(const std::string &pattern) { + auto it = regex_cache.find(pattern); + if (it != regex_cache.end()) + return it->second; + int errornum; + PCRE2_SIZE erroffset; + pcre2_code *re = + pcre2_compile((PCRE2_SPTR)pattern.c_str(), PCRE2_ZERO_TERMINATED, 0, + &errornum, &erroffset, nullptr); + regex_cache[pattern] = re; + return re; +} static const std::regex scm_regex( R"((@[A-Za-z0-9_.]+)|(;; \#[0-9a-fA-F]{6} \#[0-9a-fA-F]{6} [01] [01] [01] \d+))"); @@ -94,8 +114,6 @@ static inline bool ts_predicate(TSQuery *query, const TSQueryMatch &match, ts_query_predicates_for_pattern(query, match.pattern_index, &step_count); if (!steps || step_count != 4) return true; - if (source->char_count >= (16 * 1024)) - return false; std::string command; std::string regex_txt; uint32_t subject_id = 0; @@ -124,15 +142,13 @@ static inline bool ts_predicate(TSQuery *query, const TSQueryMatch &match, } const TSNode *node = find_capture_node(match, subject_id); std::string subject = node_text(*node, source); - auto it = regex_cache.find(regex_txt); - if (it == regex_cache.end()) - it = regex_cache.emplace(regex_txt, std::regex(regex_txt)).first; - const std::regex &re = it->second; - if (command == "match?") - return std::regex_match(subject, re); - else if (command == "not-match?") - return !std::regex_match(subject, re); - return false; + pcre2_code *re = get_re(regex_txt); + pcre2_match_data *md = pcre2_match_data_create_from_pattern(re, nullptr); + int rc = pcre2_match(re, (PCRE2_SPTR)subject.c_str(), subject.size(), 0, 0, + md, nullptr); + pcre2_match_data_free(md); + bool ok = (rc >= 0); + return (command == "match?" ? ok : !ok); } const char *read_ts(void *payload, uint32_t byte_index, TSPoint,