diff --git a/.clangd b/.clangd old mode 100644 new mode 100755 diff --git a/.gitattributes b/.gitattributes old mode 100644 new mode 100755 diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.gitmodules b/.gitmodules old mode 100644 new mode 100755 diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/TODO.md b/TODO.md old mode 100644 new mode 100755 index ef18d8d..0cccdc0 --- a/TODO.md +++ b/TODO.md @@ -2,35 +2,45 @@ Copyright 2025 Syed Daanish # TODO -## Next few super long boring things to do:: -* redo lsp threads such that no mutex needed for any rope stuff (done) - - Also make the classes own the methods in lsp (done) - - This will mean that parsers/renderers and keystrokes will not need to be individually locked (done) - - And so it will be much faster (done) - - At which point the main thread can also be blocked on user input or lsp responses and still be faster -* Add a superclass for editor called Window (which can be popup or tiled) (done) -* Add a recursive tiling class for windows (done) -* Handled by a single renderer that calls and renders each window (done) -* Make editor's functions into its own methods (classify it) (done) - - While at it - - Seperate system functions into a class that branches to support local / ssh / server modes. - - Even lsp shouldnt be directly controlled because it can branch on local and server modes - - check wolfSSH stuff for remote editing - - Thick and thin mode - - thin mode only shares screen diffing over the network - uses server settings / themes - - thick only shared fileio and lsp data with local used for all else - uses local settings / themes - - Redo hooks as a engine of its own. - - And factorize renderer into its own class (and make it just return an array of the render without knowing teh x,y) - - which is just managed by the renderer - - which is reused by scrollers/ensurers too - - this will then allow inlay hints to be possible - - and also make VAI easier to implement +- And factorize renderer into its own class + - which is just managed by the renderer + - and adjusment.cc will call it +- which is reused by scrollers/ensurers too (for knowing screen wrapped end) +- this will then allow inlay hints to be possible +- and also make VAI easier to implement * Allow keybinds to be set in ruby -* then the fun part: +* ruby file for project specific runs alongside any system wide ones + +- Seperate system functions into a class that branches to support local / ssh / server modes. +- Even lsp shouldnt be directly controlled because it can branch on local and server modes + - check libssh2 or child process stuff for remote editing (remote mode) + - Thick and thin mode (server mode) (through ssh or port) (for website only port + webhook) + - thin mode only shares screen diffing over the network - uses server settings / themes / shell + - only one user connects at a time + - provides data as a websocket with tui or gui/online modes where tui shares diffing as is (can be connected to by gui or website) + - and gui/online modes try to (if not then render onto a canvas) forward window.render_gui() and dedicated windowing system (i.e windowing is html divs) + - and window.render_gui() returns a markup code (custom markup) + - and for events i could either leave tui as-is and for markup have special event handling or i + - implement the widget system in both and have the same event handling then + - actually for true cross platform i need to make a ui lib with widgets etc. so it is workable on all platforms (so they all need only a single ui lib) + - thick only shared fileio and lsp data with local used for all else - uses local settings / themes + - multiple users connect at once but maybe either make them not be allowed to open same file or make vscode like multiediting (unsure how exactly) + - they all share same lsp instances + - they all have the same shell access + - allow having an instance that forwards thick mode to thin mode (to connect online mode to a thick server for code collaboration) * Then allow ruby code to create and handle windows as extentions * Then 3 inbuilt extentions being file manager, theme picker, tab selector +* make another tile type called tile tabbed that has a tab switcher and shows only one of its children at once +* it takes focus and takes some keybinds for switching and forwards the rest (it also forwards the info and adds one for itself - the selected/total tabs) +* also implement info strings for all the stuff that take focus + +* Mode is a feild on a editor and there is no global "mode system" except in editors (enxtentions do their own thing) + * make mode normal and not atomic if it is truly unused across threads + * this means keybinds can be set to use the editor as insert mode only and so behave like vscode + +* split lsp stuff into multiple files (not a monolithic class as it is now) * Extentions can also be used as file openers (for like databases . diffing . images . audio etc) * Local cache for state management (like undo history, cursor positions etc) (location can be set in config) * make sure to write inbuilt extentions in cpp and not ruby @@ -110,8 +120,6 @@ Copyright 2025 Syed Daanish * [ ] **Auto brace selection:** Add support for auto brace selection. -* [ ] **Tree-sitter Indent:** Attempt to allow Tree-sitter to handle indentation if possible. - ### UX * [ ] **Completion Filtering:** @@ -120,7 +128,7 @@ Copyright 2025 Syed Daanish * [ ] **Basic Autocomplete:** Keep a list of words in the current buffer for non-LSP fallback. -### Major Features +### Features * [ ] **Search & Replace:** * [ ] Add Search/Replace UI. @@ -154,3 +162,14 @@ Copyright 2025 Syed Daanish * [ ] Switch JSON parser to `RapidJSON` (or similar high-performance lib). * [ ] Decrease usage of `std::string` in UI, LSP, warnings etc. * [ ] Also for vectors into managed memory especially for completions/lsp-stuff. + + + + + + + + + + + diff --git a/config/main.rb b/config/main.rb old mode 100644 new mode 100755 diff --git a/config/theme.rb b/config/theme.rb old mode 100644 new mode 100755 diff --git a/include/editor/completions.h b/include/editor/completions.h old mode 100644 new mode 100755 diff --git a/include/editor/decl.h b/include/editor/decl.h old mode 100644 new mode 100755 diff --git a/include/editor/editor.h b/include/editor/editor.h old mode 100644 new mode 100755 index 52f8965..be19088 --- a/include/editor/editor.h +++ b/include/editor/editor.h @@ -1,7 +1,9 @@ #ifndef EDITOR_H #define EDITOR_H +#include "editor/hooks.h" #include "editor/indents.h" +#include "editor/visual.h" #include "extentions/diagnostics.h" #include "extentions/hover.h" #include "io/knot.h" @@ -31,7 +33,6 @@ struct Editor : Window { Coord size = {0, 0}; Coord scroll = {0, 0}; Language lang = {}; - uint32_t hooks[94] = {0}; bool jumper_set = false; std::vector warnings = {}; bool warnings_dirty = false; @@ -42,6 +43,7 @@ struct Editor : Window { DiagnosticBox *diagnostic_popup = init_diagnostic(); std::atomic lsp_version = 1; IndentationEngine indents = {}; + HookEngine hooks = {}; Parser *parser = nullptr; ExtraHighlighter extra_hl = {}; bool is_css_color = false; @@ -84,7 +86,6 @@ struct Editor : Window { void backspace_edit(); void delete_prev_word(); void delete_next_word(); - void clear_hooks_at_line(uint32_t line); void cursor_prev_word(); void cursor_next_word(); void select_all(); @@ -158,19 +159,6 @@ struct Editor : Window { free(it->buffer); free(it); } - - inline void apply_hook_insertion(uint32_t line, uint32_t rows) { - for (auto &hook : this->hooks) - if (hook > line) - hook += rows; - } - - inline void apply_hook_deletion(uint32_t removal_start, - uint32_t removal_end) { - for (auto &hook : this->hooks) - if (hook > removal_start) - hook -= removal_end - removal_start + 1; - } }; #endif diff --git a/include/editor/helpers.h b/include/editor/helpers.h old mode 100644 new mode 100755 diff --git a/include/editor/hooks.h b/include/editor/hooks.h new file mode 100755 index 0000000..47516f7 --- /dev/null +++ b/include/editor/hooks.h @@ -0,0 +1,91 @@ +#ifndef EDITOR_HOOKS_H +#define EDITOR_HOOKS_H + +#include "utils/utils.h" + +struct HookEngine { + uint32_t hooks[94]; + std::vector> v; + std::vector>::iterator it; + + HookEngine() { + for (int i = 0; i < 94; i++) + hooks[i] = UINT32_MAX; + v.reserve(94); + } + + inline void edit(uint32_t line, uint32_t removed_rows, + uint32_t inserted_rows) { + + int64_t delta = (int64_t)inserted_rows - (int64_t)removed_rows; + for (int i = 0; i < 94; i++) { + uint32_t &h = hooks[i]; + if (h == UINT32_MAX) + continue; + if (h < line) + continue; + if (removed_rows > 0 && h < line + removed_rows) { + h = UINT32_MAX; + continue; + } + h = (uint32_t)((int64_t)h + delta); + } + } + + inline void set(char c, uint32_t line) { + if (c < '!' || c > '~') + return; + int idx = c - '!'; + for (int i = 0; i < 94; i++) { + if (hooks[i] == line) { + hooks[i] = UINT32_MAX; + break; + } + } + hooks[idx] = line; + } + + inline bool get(char c, uint32_t *out_line) const { + if (c < '!' || c > '~') + return false; + uint32_t h = hooks[c - '!']; + if (h == UINT32_MAX) + return false; + *out_line = h; + return true; + } + + inline void clear_line(uint32_t line) { + for (int i = 0; i < 94; i++) + if (hooks[i] == line) + hooks[i] = UINT32_MAX; + } + + inline void clear(char c) { + if (c < '!' || c > '~') + return; + hooks[c - '!'] = UINT32_MAX; + } + + void start_iter(uint32_t scroll_line) { + for (int i = 0; i < 94; i++) + if (hooks[i] != UINT32_MAX) + v.push_back({hooks[i], (char)('!' + i)}); + std::sort(v.begin(), v.end(), + [](const auto &a, const auto &b) { return a.first < b.first; }); + it = std::lower_bound( + v.begin(), v.end(), scroll_line, + [](const auto &p, uint32_t line) { return p.first < line; }); + } + + char next(uint32_t line_index) { + if (it != v.end() && it->first == line_index) { + char c = it->second; + it++; + return c; + } + return '\0'; + } +}; + +#endif diff --git a/include/editor/indents.h b/include/editor/indents.h old mode 100644 new mode 100755 diff --git a/include/editor/visual.h b/include/editor/visual.h new file mode 100755 index 0000000..6dd8df8 --- /dev/null +++ b/include/editor/visual.h @@ -0,0 +1,113 @@ +#include "editor/decl.h" +#include "io/knot.h" +#include "io/sysio.h" +#include "utils/utils.h" + +struct GraphemeIterator { + char *line{nullptr}; + uint32_t len{0}; + + GraphemeIterator(char *line, uint32_t len) : line(line), len(len) {} + + char *next(uint32_t *o_len, uint32_t *o_width) { + if (!line || len == 0) + return nullptr; + char *cur = line; + uint32_t g = grapheme_next_character_break_utf8(cur, len); + if (o_width) + *o_width = display_width(cur, g); + if (o_len) + *o_len = g; + line += g; + len -= g; + return cur; + } +}; + +struct VisualIterator { + LineIterator *it{nullptr}; + uint32_t line_index{UINT32_MAX}; + uint32_t offset{0}; + uint32_t len{0}; + bool first{true}; + char *line{nullptr}; + uint32_t render_width{io::cols}; + std::stack> prev_stack; + + VisualIterator(Knot *root, Coord pos, uint32_t width) + : it(begin_l_iter(root, pos.row)), offset(pos.col), + line_index(pos.row - 1), render_width(width) {} + + std::pair prev() { + if (!it) + return {{UINT32_MAX, UINT32_MAX}, {UINT32_MAX, UINT32_MAX}}; + if (prev_stack.empty()) + return _prev(); + auto ret = prev_stack.top(); + offset = ret.first.col; + prev_stack.pop(); + return ret; + } + + std::pair _prev() { + if (!it) + return {{UINT32_MAX, UINT32_MAX}, {UINT32_MAX, UINT32_MAX}}; + line_index--; + line = prev_line(it, &len); + if (!line) + return {{UINT32_MAX, UINT32_MAX}, {UINT32_MAX, UINT32_MAX}}; + if (len > 0 && line[len - 1] == '\n') + len--; + offset = first ? offset : 0; + first = false; + GraphemeIterator g(line + offset, len - offset); + uint32_t o_len, o_width, rendered = 0, advance = 0; + while (g.next(&o_len, &o_width)) { + if (rendered + o_width > render_width) { + prev_stack.push({{line_index, offset}, {line_index, offset + advance}}); + offset += advance; + rendered = 0; + advance = 0; + } + advance += o_len; + rendered += o_width; + } + return {{line_index, offset}, {line_index, offset + advance}}; + } + + std::pair next() { + if (!it) + return {{UINT32_MAX, UINT32_MAX}, {UINT32_MAX, UINT32_MAX}}; + if (!line) { + line_index++; + line = next_line(it, &len); + if (!line) + return {{UINT32_MAX, UINT32_MAX}, {UINT32_MAX, UINT32_MAX}}; + if (len > 0 && line[len - 1] == '\n') + len--; + offset = first ? offset : 0; + first = false; + } + GraphemeIterator g(line + offset, len - offset); + uint32_t o_len, o_width, rendered = 0, advance = 0; + while (g.next(&o_len, &o_width)) { + if (rendered + o_width > render_width) { + offset += advance; + return {{line_index, offset - advance}, {line_index, offset}}; + } + advance += o_len; + rendered += o_width; + } + offset += advance; + if (offset >= len) + line = nullptr; + return {{line_index, offset}, {line_index, offset + advance}}; + } + + ~VisualIterator() { + if (!it) + return; + free(it->buffer); + free(it); + } +}; diff --git a/include/extentions/diagnostics.h b/include/extentions/diagnostics.h old mode 100644 new mode 100755 diff --git a/include/extentions/hover.h b/include/extentions/hover.h old mode 100644 new mode 100755 diff --git a/include/io/knot.h b/include/io/knot.h old mode 100644 new mode 100755 diff --git a/include/io/sysio.h b/include/io/sysio.h old mode 100644 new mode 100755 diff --git a/include/lsp/lsp.h b/include/lsp/lsp.h old mode 100644 new mode 100755 diff --git a/include/main.h b/include/main.h old mode 100644 new mode 100755 diff --git a/include/pch.h b/include/pch.h old mode 100644 new mode 100755 index 096ba85..1e5eb3c --- a/include/pch.h +++ b/include/pch.h @@ -31,6 +31,7 @@ extern "C" { #include #include #include +#include #include #include #include diff --git a/include/ruby/decl.h b/include/ruby/decl.h old mode 100644 new mode 100755 diff --git a/include/ruby/libcrib.rb b/include/ruby/libcrib.rb old mode 100644 new mode 100755 diff --git a/include/ruby/ruby_compiled.h b/include/ruby/ruby_compiled.h old mode 100644 new mode 100755 diff --git a/include/syntax/decl.h b/include/syntax/decl.h old mode 100644 new mode 100755 diff --git a/include/syntax/extras.h b/include/syntax/extras.h old mode 100644 new mode 100755 diff --git a/include/syntax/langs.h b/include/syntax/langs.h old mode 100644 new mode 100755 diff --git a/include/syntax/line_map.h b/include/syntax/line_map.h old mode 100644 new mode 100755 diff --git a/include/syntax/parser.h b/include/syntax/parser.h old mode 100644 new mode 100755 diff --git a/include/syntax/tokens.def b/include/syntax/tokens.def old mode 100644 new mode 100755 diff --git a/include/syntax/trie.h b/include/syntax/trie.h old mode 100644 new mode 100755 diff --git a/include/ui/bar.h b/include/ui/bar.h old mode 100644 new mode 100755 diff --git a/include/ui/completionbox.h b/include/ui/completionbox.h old mode 100644 new mode 100755 diff --git a/include/utils/utils.h b/include/utils/utils.h old mode 100644 new mode 100755 diff --git a/include/windows/decl.h b/include/windows/decl.h old mode 100644 new mode 100755 diff --git a/installer.sh b/installer.sh old mode 100644 new mode 100755 diff --git a/libs/unicode_width/unicode_width.c b/libs/unicode_width/unicode_width.c old mode 100644 new mode 100755 diff --git a/libs/unicode_width/unicode_width.h b/libs/unicode_width/unicode_width.h old mode 100644 new mode 100755 diff --git a/samples/Makefile b/samples/Makefile old mode 100644 new mode 100755 diff --git a/samples/bash.sh b/samples/bash.sh old mode 100644 new mode 100755 diff --git a/samples/css.css b/samples/css.css old mode 100644 new mode 100755 diff --git a/samples/diff.patch b/samples/diff.patch old mode 100644 new mode 100755 diff --git a/samples/embedded_template.erb b/samples/embedded_template.erb old mode 100644 new mode 100755 diff --git a/samples/fish.fish b/samples/fish.fish old mode 100644 new mode 100755 diff --git a/samples/gdscript.gd b/samples/gdscript.gd old mode 100644 new mode 100755 diff --git a/samples/go.go b/samples/go.go old mode 100644 new mode 100755 diff --git a/samples/go.mod b/samples/go.mod old mode 100644 new mode 100755 diff --git a/samples/haskell.hs b/samples/haskell.hs old mode 100644 new mode 100755 diff --git a/samples/html.html b/samples/html.html old mode 100644 new mode 100755 diff --git a/samples/ini.ini b/samples/ini.ini old mode 100644 new mode 100755 diff --git a/samples/javascript.js b/samples/javascript.js old mode 100644 new mode 100755 diff --git a/samples/json.jsonc b/samples/json.jsonc old mode 100644 new mode 100755 diff --git a/samples/lua.lua b/samples/lua.lua old mode 100644 new mode 100755 diff --git a/samples/markdown.md b/samples/markdown.md old mode 100644 new mode 100755 diff --git a/samples/nginx.conf b/samples/nginx.conf old mode 100644 new mode 100755 diff --git a/samples/php.php b/samples/php.php old mode 100644 new mode 100755 diff --git a/samples/python.py b/samples/python.py old mode 100644 new mode 100755 diff --git a/samples/regex.regex b/samples/regex.regex old mode 100644 new mode 100755 diff --git a/samples/ruby.rb b/samples/ruby.rb old mode 100644 new mode 100755 diff --git a/samples/rust.rs b/samples/rust.rs old mode 100644 new mode 100755 diff --git a/samples/sample.gitattributes b/samples/sample.gitattributes old mode 100644 new mode 100755 diff --git a/samples/sample.gitignore b/samples/sample.gitignore old mode 100644 new mode 100755 diff --git a/samples/sql.sql b/samples/sql.sql old mode 100644 new mode 100755 diff --git a/samples/toml.toml b/samples/toml.toml old mode 100644 new mode 100755 diff --git a/samples/yaml.yaml b/samples/yaml.yaml old mode 100644 new mode 100755 diff --git a/src/editor/adjustment.cc b/src/editor/adjustment.cc old mode 100644 new mode 100755 index 5304af1..95e24f2 --- a/src/editor/adjustment.cc +++ b/src/editor/adjustment.cc @@ -2,72 +2,27 @@ void Editor::ensure_cursor() { if (this->cursor < this->scroll) { - this->cursor.row = this->scroll.row; - this->cursor.col = this->scroll.col; + this->cursor = this->scroll; this->cursor_preffered = UINT32_MAX; return; } uint32_t numlen = EXTRA_META + static_cast(std::log10(this->root->line_count + 1)); uint32_t render_width = this->size.col - numlen; - uint32_t visual_rows = 0; - uint32_t line_index = this->scroll.row; - bool first_visual_line = true; - LineIterator *it = begin_l_iter(this->root, line_index); - if (!it) - return; - Coord last_visible = this->scroll; - while (true) { - if (visual_rows >= this->size.row) - break; - uint32_t line_len; - char *line = next_line(it, &line_len); - if (!line) - break; - if (line_len > 0 && line[line_len - 1] == '\n') - line_len--; - uint32_t offset = first_visual_line ? this->scroll.col : 0; - first_visual_line = false; - while (offset < line_len || (line_len == 0 && offset == 0)) { - Coord current = {line_index, offset}; - last_visible = current; - visual_rows++; - if (visual_rows >= this->size.row) - break; - uint32_t col = 0; - uint32_t advance = 0; - uint32_t left = line_len - offset; - while (left > 0 && col < render_width) { - uint32_t g = - grapheme_next_character_break_utf8(line + offset + advance, left); - int w = display_width(line + offset + advance, g); - if (col + w > render_width) - break; - advance += g; - left -= g; - col += w; - } - if (line_index == this->cursor.row) { - if (this->cursor.col >= offset && - this->cursor.col <= offset + advance) { - free(it->buffer); - free(it); - return; - } - } - if (advance == 0) - break; - offset += advance; - if (line_len == 0) - break; - } - line_index++; + uint32_t render_height = 0; + VisualIterator vis(root, scroll, render_width); + std::pair vline; + Coord last_visible = scroll; + while ((vline = vis.next()).first.row != UINT32_MAX && + render_height < this->size.row) { + render_height++; + last_visible = vline.first; + if (cursor >= vline.first && cursor < vline.second) + return; } - this->cursor.row = last_visible.row; - this->cursor.col = last_visible.col; + cursor = last_visible; + cursor_preffered = UINT32_MAX; this->cursor_preffered = UINT32_MAX; - free(it->buffer); - free(it); } void Editor::ensure_scroll() { diff --git a/src/editor/boundaries.cc b/src/editor/boundaries.cc old mode 100644 new mode 100755 diff --git a/src/editor/click.cc b/src/editor/click.cc old mode 100644 new mode 100755 diff --git a/src/editor/commands.cc b/src/editor/commands.cc old mode 100644 new mode 100755 diff --git a/src/editor/completions.cc b/src/editor/completions.cc old mode 100644 new mode 100755 diff --git a/src/editor/cursor.cc b/src/editor/cursor.cc old mode 100644 new mode 100755 diff --git a/src/editor/edit.cc b/src/editor/edit.cc old mode 100644 new mode 100755 index f079f8f..0ece19a --- a/src/editor/edit.cc +++ b/src/editor/edit.cc @@ -44,10 +44,10 @@ void Editor::edit_erase(Coord pos, int64_t len) { } uint32_t start_row = point.row; uint32_t end_row = pos.row; - this->apply_hook_deletion(start_row + 1, end_row); this->root = erase(this->root, start, byte_pos - start); if (this->parser) this->parser->edit(start_row, end_row - start_row, 0); + this->hooks.edit(start_row, end_row - start_row, 0); if (do_lsp) { auto lsp = this->lsp.load(); if (lsp->incremental_sync) { @@ -113,10 +113,10 @@ void Editor::edit_erase(Coord pos, int64_t len) { } uint32_t start_row = pos.row; uint32_t end_row = point.row; - this->apply_hook_deletion(start_row + 1, end_row); this->root = erase(this->root, byte_pos, end - byte_pos); if (this->parser) this->parser->edit(start_row, end_row - start_row, 0); + this->hooks.edit(start_row, end_row - start_row, 0); if (do_lsp) { auto lsp = this->lsp.load(); if (lsp->incremental_sync) { @@ -169,9 +169,9 @@ void Editor::edit_insert(Coord pos, char *data, uint32_t len) { for (uint32_t i = 0; i < len; i++) if (data[i] == '\n') rows++; - this->apply_hook_insertion(pos.row, rows); if (this->parser) this->parser->edit(pos.row, 0, rows); + this->hooks.edit(pos.row, 0, rows); auto lsp = this->lsp.load(); if (lsp) { if (lsp->incremental_sync) { @@ -234,6 +234,7 @@ void Editor::edit_replace(Coord start, Coord end, const char *text, rows++; if (this->parser) this->parser->edit(start.row, end.row - start.row, rows); + this->hooks.edit(start.row, end.row - start.row, rows); auto lsp = this->lsp.load(); if (lsp) { if (lsp->incremental_sync) { diff --git a/src/editor/editor.cc b/src/editor/editor.cc old mode 100644 new mode 100755 diff --git a/src/editor/events.cc b/src/editor/events.cc old mode 100644 new mode 100755 index e7c0bc1..256803a --- a/src/editor/events.cc +++ b/src/editor/events.cc @@ -96,7 +96,7 @@ void Editor::handle_event(KeyEvent event) { this->jumper_set = false; break; case 'N': - this->clear_hooks_at_line(this->cursor.row); + this->hooks.clear_line(this->cursor.row); break; case 's': case 'v': @@ -218,18 +218,11 @@ void Editor::handle_event(KeyEvent event) { if (event.key_type == KEY_CHAR && event.len == 1 && (event.c[0] >= '!' && event.c[0] <= '~')) { if (this->jumper_set) { - for (uint8_t i = 0; i < 94; i++) - if (this->hooks[i] == this->cursor.row + 1) { - this->hooks[i] = 0; - break; - } - this->hooks[event.c[0] - '!'] = this->cursor.row + 1; + this->hooks.set(event.c[0], this->cursor.row); } else { - uint32_t line = this->hooks[event.c[0] - '!'] - 1; - if (line > 0) { + uint32_t line; + if (this->hooks.get(event.c[0], &line)) this->cursor = {line, 0}; - this->cursor_preffered = UINT32_MAX; - } } } mode = NORMAL; diff --git a/src/editor/fluff.cc b/src/editor/fluff.cc new file mode 100755 index 0000000..e69de29 diff --git a/src/editor/helpers.cc b/src/editor/helpers.cc old mode 100644 new mode 100755 index 9398170..ed66b2a --- a/src/editor/helpers.cc +++ b/src/editor/helpers.cc @@ -312,14 +312,6 @@ void Editor::delete_next_word() { this->edit_erase(this->cursor, next_col_cluster); } -void Editor::clear_hooks_at_line(uint32_t line) { - for (uint8_t i = 0; i < 94; i++) - if (this->hooks[i] == line + 1) { - this->hooks[i] = 0; - break; - } -} - void Editor::cursor_prev_word() { uint32_t prev_col; word_boundaries(this->cursor, &prev_col, nullptr, nullptr, nullptr); diff --git a/src/editor/indents.cc b/src/editor/indents.cc old mode 100644 new mode 100755 diff --git a/src/editor/lsp.cc b/src/editor/lsp.cc old mode 100644 new mode 100755 diff --git a/src/editor/move_line.cc b/src/editor/move_line.cc old mode 100644 new mode 100755 diff --git a/src/editor/renderer.cc b/src/editor/renderer.cc old mode 100644 new mode 100755 index 8a6ed3f..4e51289 --- a/src/editor/renderer.cc +++ b/src/editor/renderer.cc @@ -11,14 +11,7 @@ void Editor::render(std::vector &buffer, Coord size, Coord pos) { EXTRA_META + static_cast(std::log10(this->root->line_count + 1)); uint32_t render_width = size.col - numlen; uint32_t render_x = pos.col + numlen + 1; - std::vector> v; - for (size_t i = 0; i < 94; ++i) - if (this->hooks[i] != 0) - v.push_back({this->hooks[i], '!' + i}); - std::sort(v.begin(), v.end()); - auto hook_it = v.begin(); - while (hook_it != v.end() && hook_it->first <= this->scroll.row) - ++hook_it; + this->hooks.start_iter(this->scroll.row); auto warn_it = this->warnings.begin(); while (warn_it != this->warnings.end() && warn_it->line < this->scroll.row) ++warn_it; @@ -140,14 +133,9 @@ void Editor::render(std::vector &buffer, Coord size, Coord pos) { while (current_byte_offset < line_len && rendered_rows < this->size.row) { uint32_t color = this->cursor.row == line_index ? 0x222222 : 0; if (current_byte_offset == 0 || rendered_rows == 0) { - const char *hook = ""; - char h[2] = {0, 0}; - if (hook_it != v.end() && hook_it->first == line_index + 1) { - h[0] = hook_it->second; - hook = h; - hook_it++; - } - update(pos.row + rendered_rows, pos.col, hook, 0xAAAAAA, 0, 0, 0, 1); + char hook = this->hooks.next(line_index); + update(pos.row + rendered_rows, pos.col, {hook, 0}, 0xAAAAAA, 0, 0, 0, + 1); char buf[16]; int len = snprintf(buf, sizeof(buf), "%*u ", numlen, line_index + 1); uint32_t num_color = @@ -337,14 +325,8 @@ void Editor::render(std::vector &buffer, Coord size, Coord pos) { if (line_len == 0 || (current_byte_offset >= line_len && rendered_rows == 0)) { uint32_t color = this->cursor.row == line_index ? 0x222222 : 0; - const char *hook = ""; - char h[2] = {0, 0}; - if (hook_it != v.end() && hook_it->first == line_index + 1) { - h[0] = hook_it->second; - hook = h; - hook_it++; - } - update(pos.row + rendered_rows, pos.col, hook, 0xAAAAAA, 0, 0, 0, 1); + char hook = this->hooks.next(line_index); + update(pos.row + rendered_rows, pos.col, {hook, 0}, 0xAAAAAA, 0, 0, 0, 1); char buf[16]; int len = snprintf(buf, sizeof(buf), "%*u ", numlen, line_index + 1); uint32_t num_color = this->cursor.row == line_index ? 0xFFFFFF : 0x555555; diff --git a/src/editor/scroll.cc b/src/editor/scroll.cc old mode 100644 new mode 100755 diff --git a/src/editor/selection.cc b/src/editor/selection.cc old mode 100644 new mode 100755 diff --git a/src/editor/worker.cc b/src/editor/worker.cc old mode 100644 new mode 100755 diff --git a/src/extentions/completion.cc b/src/extentions/completion.cc old mode 100644 new mode 100755 diff --git a/src/extentions/diagnostics.cc b/src/extentions/diagnostics.cc old mode 100644 new mode 100755 diff --git a/src/extentions/hover.cc b/src/extentions/hover.cc old mode 100644 new mode 100755 diff --git a/src/io/input.cc b/src/io/input.cc old mode 100644 new mode 100755 diff --git a/src/io/knot.cc b/src/io/knot.cc old mode 100644 new mode 100755 diff --git a/src/io/renderer.cc b/src/io/renderer.cc old mode 100644 new mode 100755 diff --git a/src/lsp/handlers.cc b/src/lsp/handlers.cc old mode 100644 new mode 100755 diff --git a/src/lsp/process.cc b/src/lsp/process.cc old mode 100644 new mode 100755 diff --git a/src/lsp/worker.cc b/src/lsp/worker.cc old mode 100644 new mode 100755 diff --git a/src/main.cc b/src/main.cc old mode 100644 new mode 100755 index 9b0bbb3..cc54df2 --- a/src/main.cc +++ b/src/main.cc @@ -8,9 +8,8 @@ #include "windows/decl.h" std::atomic running{true}; -Queue event_queue; -fs::path pwd; std::atomic mode = NORMAL; +fs::path pwd; namespace ui { Bar bar; @@ -18,7 +17,7 @@ Bar bar; void background_lsp() { while (running) - throttle(8ms, lsp_worker); + throttle(16ms, lsp_worker); } int main(int argc, char *argv[]) { @@ -44,9 +43,15 @@ int main(int argc, char *argv[]) { std::thread lsp_thread(background_lsp); while (running) { - uint8_t consumed = 0; + layout::focused_window->work(); + render(); + throttle(16ms, io_render); KeyEvent event; - while (++consumed < 32 && (event = read_key()).key_type != KEY_NONE) { + while (running && lsp::response_queue.empty() && + (event = read_key()).key_type == KEY_NONE) + std::this_thread::sleep_for(1ms); + uint8_t consumed = 0; + do { if (event.key_type != KEY_NONE) { if (event.key_type == KEY_CHAR && event.len == 1 && event.c[0] == CTRL('q')) { @@ -67,14 +72,11 @@ int main(int argc, char *argv[]) { event.c) free(event.c); } - } + } while (++consumed < 32 && (event = read_key()).key_type != KEY_NONE); std::unique_ptr msg; while (lsp::response_queue.pop(msg)) { msg->callback(*msg); }; - layout::focused_window->work(); - render(); - throttle(8ms, io_render); } quit: diff --git a/src/ruby/bindings.cc b/src/ruby/bindings.cc old mode 100644 new mode 100755 diff --git a/src/ruby/process.cc b/src/ruby/process.cc old mode 100644 new mode 100755 diff --git a/src/syntax/bash.cc b/src/syntax/bash.cc old mode 100644 new mode 100755 diff --git a/src/syntax/parser.cc b/src/syntax/parser.cc old mode 100644 new mode 100755 diff --git a/src/syntax/ruby.cc b/src/syntax/ruby.cc old mode 100644 new mode 100755 diff --git a/src/ui/bar.cc b/src/ui/bar.cc old mode 100644 new mode 100755 diff --git a/src/ui/completionbox.cc b/src/ui/completionbox.cc old mode 100644 new mode 100755 diff --git a/src/utils/system.cc b/src/utils/system.cc old mode 100644 new mode 100755 diff --git a/src/utils/text.cc b/src/utils/text.cc old mode 100644 new mode 100755 diff --git a/src/utils/unicode.cc b/src/utils/unicode.cc old mode 100644 new mode 100755 diff --git a/src/windows/renderer.cc b/src/windows/renderer.cc old mode 100644 new mode 100755