Switch to OOP style code

This commit is contained in:
2026-02-04 00:38:11 +00:00
parent e3fc5323df
commit a62d4a18a8
50 changed files with 3011 additions and 3078 deletions

View File

@@ -3,17 +3,24 @@
#include "lsp/lsp.h"
#include "main.h"
#include "syntax/decl.h"
#include "windows/decl.h"
void Bar::log(std::string message) { log_line = message; }
void Bar::render() {
void Bar::render(std::vector<ScreenCell> &buffer) {
USING(LSPInstance);
Editor *editor = editors[current_editor];
BarLine bar_line =
bar_contents(mode, editor->lang.name, editor->warnings.size(),
editor->lsp ? editor->lsp->lsp->command : "",
editor->filename, editor->filename, editor->cursor.row + 1,
editor->root->line_count + 1, screen.col);
BarLine bar_line;
bar_line = bar_contents(mode, screen.col, pwd.string(), focused_window);
auto update = [&](uint32_t row, uint32_t col, std::string text, uint32_t fg,
uint32_t bg, uint8_t flags, uint32_t width) {
ScreenCell &c = buffer[row * screen.col + col];
c.utf8 = text;
c.width = width;
c.fg = fg;
c.bg = bg;
c.flags = flags;
c.ul_color = 0;
};
uint32_t row = screen.row - 2;
uint32_t width = screen.col;
std::string &line = bar_line.line;
@@ -26,43 +33,46 @@ void Bar::render() {
int width = display_width(cluster.c_str(), cluster_len);
Highlight highlight = bar_line.get_highlight(col);
update(row, col, cluster.c_str(), highlight.fg, highlight.bg,
highlight.flags);
highlight.flags, width);
col += width;
i += cluster_len;
for (int w = 1; w < width; w++)
update(row, col - w, "\x1b", highlight.fg, highlight.bg, highlight.flags);
update(row, col - w, "\x1b", highlight.fg, highlight.bg, highlight.flags,
0);
}
while (col < width)
update(row, col++, " ", 0, 0, 0);
update(row, col++, " ", 0, 0, 0, 1);
col = 0;
row++;
if (mode == RUNNER) {
update(row, col++, ":", 0xFFFFFF, 0, 0);
update(row, col++, ":", 0xFFFFFF, 0, 0, 1);
for (char c : command)
update(row, col++, (char[2]){c, 0}, 0xFFFFFF, 0, 0);
update(row, col++, (char[2]){c, 0}, 0xFFFFFF, 0, 0, 1);
} else {
for (char c : log_line)
update(row, col++, (char[2]){c, 0}, 0xFFFFFF, 0, 0);
update(row, col++, (char[2]){c, 0}, 0xFFFFFF, 0, 0, 1);
}
while (col < width)
update(row, col++, " ", 0, 0, 0);
update(row, col++, " ", 0, 0, 0, 1);
}
void Bar::handle(KeyEvent event) {
void Bar::handle_command(std::string &command) {
if (command == "q") {
running = false;
return;
}
if (focused_window)
focused_window->handle_command(command);
}
void Bar::handle_event(KeyEvent event) {
if (event.key_type == KEY_CHAR && event.len == 1) {
if (event.c[0] == 0x1B) {
command = "";
mode = NORMAL;
} else if (event.c[0] == '\n' || event.c[0] == '\r') {
command = trim(command);
if (command == "w") {
save_file(editors[current_editor]);
} else if (command == "q") {
running = false;
} else if (command == "wq") {
save_file(editors[current_editor]);
running = false;
}
handle_command(command);
mode = NORMAL;
command = "";
} else if (isprint((unsigned char)(event.c[0]))) {

View File

@@ -1,187 +1,187 @@
#include "ui/completionbox.h"
#include "editor/completions.h"
#include "io/sysio.h"
#include "utils/utils.h"
std::string item_kind_name(uint8_t kind) {
switch (kind) {
case 1:
return "Text";
case 2:
return "Method";
case 3:
return "Function";
case 4:
return "Constructor";
case 5:
return "Field";
case 6:
return "Variable";
case 7:
return "Class";
case 8:
return "Interface";
case 9:
return "Module";
case 10:
return "Property";
case 11:
return "Unit";
case 12:
return "Value";
case 13:
return "Enum";
case 14:
return "Keyword";
case 15:
return "Snippet";
case 16:
return "Color";
case 17:
return "File";
case 18:
return "Reference";
case 19:
return "Folder";
case 20:
return "EnumMember";
case 21:
return "Constant";
case 22:
return "Struct";
case 23:
return "Event";
case 24:
return "Operator";
case 25:
return "TypeParameter";
default:
return "Unknown";
}
}
const char *item_symbol(uint8_t kind) { return ""; }
uint32_t kind_color(uint8_t kind) { return 0x82AAFF; }
void CompletionBox::render_update() {
if (hidden || session->visible.empty())
return;
std::unique_lock lock(mtx);
uint32_t max_label_len = 0;
uint32_t max_detail_len = 0;
uint32_t max_kind_len = 0;
for (uint32_t x = session->scroll;
x < session->scroll + 8 && x < session->visible.size(); x++) {
uint32_t i = session->visible[x];
if (i >= session->items.size())
continue;
auto &item = session->items[i];
max_label_len = MAX(max_label_len, (uint32_t)item.label.size());
if (item.detail)
max_detail_len = MAX(max_detail_len, (uint32_t)item.detail->size());
max_kind_len =
MAX(max_kind_len, (uint32_t)item_kind_name(item.kind).size());
}
uint32_t total = session->visible.size();
uint32_t rows = MIN(total, 8);
size.row = rows + 2;
size.col = 2 + 2 + max_label_len + 1 + max_detail_len + 2 + max_kind_len + 1;
cells.assign(size.row * size.col, {" ", 0, 0, 0, 0, 0});
auto set = [&](uint32_t r, uint32_t c, const char *text, uint32_t fg,
uint32_t bg, uint8_t flags) {
if (r < size.row && c < size.col)
cells[r * size.col + c] = {std::string(text), 0, fg, bg, flags, 0};
};
uint32_t border_fg = 0x82AAFF;
uint32_t sel_bg = 0x174225;
set(0, 0, "", border_fg, 0, 0);
for (uint32_t c = 1; c < size.col - 1; c++)
set(0, c, "", border_fg, 0, 0);
set(0, size.col - 1, "", border_fg, 0, 0);
uint32_t start = session->scroll;
uint32_t end = MIN(start + 8, session->visible.size());
for (uint32_t row_idx = start; row_idx < end; row_idx++) {
uint32_t r = (row_idx - start) + 1;
auto &item = session->items[session->visible[row_idx]];
uint32_t bg = (session->visible[row_idx] == session->select) ? sel_bg : 1;
uint32_t fg = 0xFFFFFF;
set(r, 0, "", border_fg, 0, 0);
uint32_t c = 1;
const char *sym = item_symbol(item.kind);
set(r, c++, sym, kind_color(item.kind), bg, 0);
set(r, c++, " ", fg, bg, 0);
for (size_t i = 0; i < item.label.size(); i++)
set(r, c + i, (char[2]){item.label[i], 0}, fg, bg,
item.deprecated ? CF_STRIKETHROUGH : 0);
c += item.label.size();
set(r, c++, " ", fg, bg, 0);
uint32_t detail_fg = 0xAAAAAA;
if (item.detail) {
for (size_t i = 0; i < item.detail->size(); i++)
set(r, c + i, (char[2]){(*item.detail)[i], 0}, detail_fg, bg, 0);
c += item.detail->size();
}
uint32_t pad = size.col - 1 - c - max_kind_len;
for (uint32_t i = 0; i < pad; i++)
set(r, c + i, " ", fg, bg, 0);
c += pad;
std::string kind_name = item_kind_name(item.kind);
for (size_t i = 0; i < kind_name.size(); i++)
set(r, c + i, (char[2]){kind_name[i], 0}, kind_color(item.kind), bg, 0);
set(r, size.col - 1, "", border_fg, 0, 0);
}
uint32_t bottom = size.row - 1;
set(bottom, 0, "", border_fg, 0, 0);
for (uint32_t c = 1; c < size.col - 1; c++)
set(bottom, c, "", border_fg, 0, 0);
set(bottom, size.col - 1, "", border_fg, 0, 0);
if (session->visible.size() > 8) {
std::string info = std::to_string(start + 1) + "-" + std::to_string(end) +
"/" + std::to_string(session->visible.size());
for (size_t i = 0; i < info.size() && i < size.col - 2; i++)
set(bottom, 1 + i, (char[2]){info[i], 0}, border_fg, 0, 0);
}
}
void CompletionBox::render(Coord pos) {
if (hidden || session->visible.empty())
return;
std::shared_lock lock(mtx);
int32_t start_row = (int32_t)pos.row - (int32_t)size.row;
if (start_row < 0)
start_row = pos.row + 1;
int32_t start_col = pos.col;
Coord screen_size = get_size();
if (start_col + size.col > screen_size.col) {
start_col = screen_size.col - size.col;
if (start_col < 0)
start_col = 0;
}
position = {(uint32_t)start_row, (uint32_t)start_col};
for (uint32_t r = 0; r < size.row; r++)
for (uint32_t c = 0; c < size.col; c++)
update(start_row + r, start_col + c, cells[r * size.col + c].utf8,
cells[r * size.col + c].fg, cells[r * size.col + c].bg,
cells[r * size.col + c].flags);
if (session->items.size() > session->select &&
session->items[session->select].documentation &&
*session->items[session->select].documentation != "" &&
!session->hover_dirty) {
if (session->doc != session->select) {
session->doc = session->select;
session->hover.clear();
session->hover.text = *session->items[session->select].documentation;
session->hover.is_markup = true;
session->hover_dirty = true;
} else {
if ((int32_t)position.col - (int32_t)session->hover.size.col > 0) {
session->hover.render({position.row + session->hover.size.row,
position.col - session->hover.size.col});
} else {
session->hover.render(
{position.row + session->hover.size.row, position.col + size.col});
}
}
}
}
// #include "ui/completionbox.h"
// #include "editor/completions.h"
// #include "io/sysio.h"
// #include "utils/utils.h"
//
// std::string item_kind_name(uint8_t kind) {
// switch (kind) {
// case 1:
// return "Text";
// case 2:
// return "Method";
// case 3:
// return "Function";
// case 4:
// return "Constructor";
// case 5:
// return "Field";
// case 6:
// return "Variable";
// case 7:
// return "Class";
// case 8:
// return "Interface";
// case 9:
// return "Module";
// case 10:
// return "Property";
// case 11:
// return "Unit";
// case 12:
// return "Value";
// case 13:
// return "Enum";
// case 14:
// return "Keyword";
// case 15:
// return "Snippet";
// case 16:
// return "Color";
// case 17:
// return "File";
// case 18:
// return "Reference";
// case 19:
// return "Folder";
// case 20:
// return "EnumMember";
// case 21:
// return "Constant";
// case 22:
// return "Struct";
// case 23:
// return "Event";
// case 24:
// return "Operator";
// case 25:
// return "TypeParameter";
// default:
// return "Unknown";
// }
// }
//
// const char *item_symbol(uint8_t kind) { return "●"; }
//
// uint32_t kind_color(uint8_t kind) { return 0x82AAFF; }
//
// void CompletionBox::render_update() {
// if (hidden || session->visible.empty())
// return;
// std::unique_lock lock(mtx);
// uint32_t max_label_len = 0;
// uint32_t max_detail_len = 0;
// uint32_t max_kind_len = 0;
// for (uint32_t x = session->scroll;
// x < session->scroll + 8 && x < session->visible.size(); x++) {
// uint32_t i = session->visible[x];
// if (i >= session->items.size())
// continue;
// auto &item = session->items[i];
// max_label_len = MAX(max_label_len, (uint32_t)item.label.size());
// if (item.detail)
// max_detail_len = MAX(max_detail_len, (uint32_t)item.detail->size());
// max_kind_len =
// MAX(max_kind_len, (uint32_t)item_kind_name(item.kind).size());
// }
// uint32_t total = session->visible.size();
// uint32_t rows = MIN(total, 8);
// size.row = rows + 2;
// size.col = 2 + 2 + max_label_len + 1 + max_detail_len + 2 + max_kind_len +
// 1; cells.assign(size.row * size.col, {" ", 0, 0, 0, 0, 0}); auto set =
// [&](uint32_t r, uint32_t c, const char *text, uint32_t fg,
// uint32_t bg, uint8_t flags) {
// if (r < size.row && c < size.col)
// cells[r * size.col + c] = {std::string(text), 0, fg, bg, flags, 0};
// };
// uint32_t border_fg = 0x82AAFF;
// uint32_t sel_bg = 0x174225;
// set(0, 0, "┌", border_fg, 0, 0);
// for (uint32_t c = 1; c < size.col - 1; c++)
// set(0, c, "─", border_fg, 0, 0);
// set(0, size.col - 1, "┐", border_fg, 0, 0);
// uint32_t start = session->scroll;
// uint32_t end = MIN(start + 8, session->visible.size());
// for (uint32_t row_idx = start; row_idx < end; row_idx++) {
// uint32_t r = (row_idx - start) + 1;
// auto &item = session->items[session->visible[row_idx]];
// uint32_t bg = (session->visible[row_idx] == session->select) ? sel_bg :
// 1; uint32_t fg = 0xFFFFFF; set(r, 0, "│", border_fg, 0, 0); uint32_t c =
// 1; const char *sym = item_symbol(item.kind); set(r, c++, sym,
// kind_color(item.kind), bg, 0); set(r, c++, " ", fg, bg, 0); for (size_t i
// = 0; i < item.label.size(); i++)
// set(r, c + i, (char[2]){item.label[i], 0}, fg, bg,
// item.deprecated ? CF_STRIKETHROUGH : 0);
// c += item.label.size();
// set(r, c++, " ", fg, bg, 0);
// uint32_t detail_fg = 0xAAAAAA;
// if (item.detail) {
// for (size_t i = 0; i < item.detail->size(); i++)
// set(r, c + i, (char[2]){(*item.detail)[i], 0}, detail_fg, bg, 0);
// c += item.detail->size();
// }
// uint32_t pad = size.col - 1 - c - max_kind_len;
// for (uint32_t i = 0; i < pad; i++)
// set(r, c + i, " ", fg, bg, 0);
// c += pad;
// std::string kind_name = item_kind_name(item.kind);
// for (size_t i = 0; i < kind_name.size(); i++)
// set(r, c + i, (char[2]){kind_name[i], 0}, kind_color(item.kind), bg,
// 0);
// set(r, size.col - 1, "│", border_fg, 0, 0);
// }
// uint32_t bottom = size.row - 1;
// set(bottom, 0, "└", border_fg, 0, 0);
// for (uint32_t c = 1; c < size.col - 1; c++)
// set(bottom, c, "─", border_fg, 0, 0);
// set(bottom, size.col - 1, "┘", border_fg, 0, 0);
// if (session->visible.size() > 8) {
// std::string info = std::to_string(start + 1) + "-" + std::to_string(end)
// +
// "/" + std::to_string(session->visible.size());
// for (size_t i = 0; i < info.size() && i < size.col - 2; i++)
// set(bottom, 1 + i, (char[2]){info[i], 0}, border_fg, 0, 0);
// }
// }
//
// void CompletionBox::render(Coord pos) {
// if (hidden || session->visible.empty())
// return;
// std::shared_lock lock(mtx);
// int32_t start_row = (int32_t)pos.row - (int32_t)size.row;
// if (start_row < 0)
// start_row = pos.row + 1;
// int32_t start_col = pos.col;
// Coord screen_size = get_size();
// if (start_col + size.col > screen_size.col) {
// start_col = screen_size.col - size.col;
// if (start_col < 0)
// start_col = 0;
// }
// position = {(uint32_t)start_row, (uint32_t)start_col};
// for (uint32_t r = 0; r < size.row; r++)
// for (uint32_t c = 0; c < size.col; c++)
// update(start_row + r, start_col + c, cells[r * size.col + c].utf8,
// cells[r * size.col + c].fg, cells[r * size.col + c].bg,
// cells[r * size.col + c].flags);
// if (session->items.size() > session->select &&
// session->items[session->select].documentation &&
// *session->items[session->select].documentation != "" &&
// !session->hover_dirty) {
// if (session->doc != session->select) {
// session->doc = session->select;
// session->hover.clear();
// session->hover.text = *session->items[session->select].documentation;
// session->hover.is_markup = true;
// session->hover_dirty = true;
// } else {
// if ((int32_t)position.col - (int32_t)session->hover.size.col > 0) {
// session->hover.render({position.row + session->hover.size.row,
// position.col - session->hover.size.col});
// } else {
// session->hover.render(
// {position.row + session->hover.size.row, position.col +
// size.col});
// }
// }
// }
// }

View File

@@ -1,162 +1,164 @@
#include "ui/diagnostics.h"
void DiagnosticBox::clear() {
warnings.clear();
cells.clear();
size = {0, 0};
};
void DiagnosticBox::render_first() {
if (warnings.empty())
return;
uint32_t longest_line = 8 + warnings[0].source.length();
for (auto &warn : warnings) {
uint32_t longest = 0;
uint32_t cur = 0;
for (char ch : warn.text_full)
if (ch == '\n') {
longest = MAX(longest, cur);
cur = 0;
} else {
if (ch == '\t')
cur += 3;
++cur;
}
longest = MAX(longest, cur);
longest_line = MAX(longest_line, longest + 7);
longest_line = MAX(longest_line, (uint32_t)warn.code.length() + 4);
for (auto &see_also : warn.see_also)
longest_line = MAX(longest_line, (uint32_t)see_also.length() + 4);
}
uint32_t content_width = MIN(longest_line, 150u);
size.col = content_width + 2;
cells.assign(size.col * 25, {" ", 0, 0, 0, 0, 0});
auto set = [&](uint32_t r, uint32_t c, const char *text, uint32_t fg,
uint32_t bg, uint8_t flags) {
cells[r * size.col + c] = {std::string(text), 0, fg, bg, flags, 0};
};
uint32_t base_bg = 0;
uint32_t border_fg = 0x82AAFF;
uint32_t r = 0;
if (warnings[0].source != "") {
std::string src_txt = "Source: ";
for (uint32_t i = 0; i < src_txt.length() && i < content_width; i++)
set(1, i + 1, (char[2]){src_txt[i], 0}, 0x3EAAFF, base_bg, 0);
for (uint32_t i = 0; i < warnings[0].source.length() && i < content_width;
i++)
set(1, i + 1 + src_txt.length(), (char[2]){warnings[0].source[i], 0},
0xffffff, base_bg, 0);
r++;
}
int idx = 1;
for (auto &warn : warnings) {
char buf[4];
std::snprintf(buf, sizeof(buf), "%2d", idx % 100);
std::string line_txt = std::string(buf) + ". ";
for (uint32_t i = 0; i < line_txt.length(); i++)
set(r + 1, i + 1, (char[2]){line_txt[i], 0}, 0xffffff, base_bg, 0);
if (r >= 23)
break;
const char *err_sym = "";
uint32_t c_sym = 0xAAAAAA;
switch (warn.type) {
case 1:
err_sym = "";
c_sym = 0xFF0000;
break;
case 2:
err_sym = "";
c_sym = 0xFFFF00;
break;
case 3:
err_sym = "";
c_sym = 0xFF00FF;
break;
case 4:
err_sym = "";
c_sym = 0xAAAAAA;
break;
}
std::string text = warn.text_full + " " + err_sym;
uint32_t i = 0;
while (i < text.length() && r < 23) {
uint32_t c = 4;
while (c < content_width && i < text.length()) {
if (text[i] == '\n') {
while (i < text.length() && text[i] == '\n')
i++;
break;
}
uint32_t cluster_len = grapheme_next_character_break_utf8(
text.c_str() + i, text.length() - i);
std::string cluster = text.substr(i, cluster_len);
int width = display_width(cluster.c_str(), cluster_len);
if (c + width > content_width)
break;
set(r + 1, c + 1, cluster.c_str(), c_sym, base_bg, 0);
c += width;
i += cluster_len;
for (int w = 1; w < width; w++)
set(r + 1, c - w + 1, "\x1b", c_sym, base_bg, 0);
}
r++;
}
if (r >= 23)
break;
if (warn.code != "") {
for (uint32_t i = 0; i < warn.code.length() && i + 5 < content_width; i++)
set(r + 1, i + 5, (char[2]){warn.code[i], 0}, 0x81cdc6, base_bg, 0);
r++;
}
if (r >= 23)
break;
for (std::string &see_also : warn.see_also) {
uint32_t fg = 0xB55EFF;
uint8_t colon_count = 0;
for (uint32_t i = 0; i < see_also.length() && i + 5 < content_width;
i++) {
set(r + 1, i + 5, (char[2]){see_also[i], 0}, fg, base_bg, 0);
if (see_also[i] == ':')
colon_count++;
if (colon_count == 2)
fg = 0xFFFFFF;
}
r++;
if (r >= 23)
break;
};
idx++;
}
size.row = 2 + r;
set(0, 0, "", border_fg, base_bg, 0);
for (uint32_t i = 1; i < size.col - 1; i++)
set(0, i, "", border_fg, base_bg, 0);
set(0, size.col - 1, "", border_fg, base_bg, 0);
for (uint32_t r = 1; r < size.row - 1; r++) {
set(r, 0, "", border_fg, base_bg, 0);
set(r, size.col - 1, "", border_fg, base_bg, 0);
}
set(size.row - 1, 0, "", border_fg, base_bg, 0);
for (uint32_t i = 1; i < size.col - 1; i++)
set(size.row - 1, i, "", border_fg, base_bg, 0);
set(size.row - 1, size.col - 1, "", border_fg, base_bg, 0);
cells.resize(size.col * size.row);
}
void DiagnosticBox::render(Coord pos) {
int32_t start_row = (int32_t)pos.row - (int32_t)size.row;
if (start_row < 0)
start_row = pos.row + 1;
int32_t start_col = pos.col;
Coord screen_size = get_size();
if (start_col + size.col > screen_size.col) {
start_col = screen_size.col - size.col;
if (start_col < 0)
start_col = 0;
}
for (uint32_t r = 0; r < size.row; r++)
for (uint32_t c = 0; c < size.col; c++)
update(start_row + r, start_col + c, cells[r * size.col + c].utf8,
cells[r * size.col + c].fg, cells[r * size.col + c].bg,
cells[r * size.col + c].flags);
}
// #include "ui/diagnostics.h"
//
// void DiagnosticBox::clear() {
// warnings.clear();
// cells.clear();
// size = {0, 0};
// };
//
// void DiagnosticBox::render_first() {
// if (warnings.empty())
// return;
// uint32_t longest_line = 8 + warnings[0].source.length();
// for (auto &warn : warnings) {
// uint32_t longest = 0;
// uint32_t cur = 0;
// for (char ch : warn.text_full)
// if (ch == '\n') {
// longest = MAX(longest, cur);
// cur = 0;
// } else {
// if (ch == '\t')
// cur += 3;
// ++cur;
// }
// longest = MAX(longest, cur);
// longest_line = MAX(longest_line, longest + 7);
// longest_line = MAX(longest_line, (uint32_t)warn.code.length() + 4);
// for (auto &see_also : warn.see_also)
// longest_line = MAX(longest_line, (uint32_t)see_also.length() + 4);
// }
// uint32_t content_width = MIN(longest_line, 150u);
// size.col = content_width + 2;
// cells.assign(size.col * 25, {" ", 0, 0, 0, 0, 0});
// auto set = [&](uint32_t r, uint32_t c, const char *text, uint32_t fg,
// uint32_t bg, uint8_t flags) {
// cells[r * size.col + c] = {std::string(text), 0, fg, bg, flags, 0};
// };
// uint32_t base_bg = 0;
// uint32_t border_fg = 0x82AAFF;
// uint32_t r = 0;
// if (warnings[0].source != "") {
// std::string src_txt = "Source: ";
// for (uint32_t i = 0; i < src_txt.length() && i < content_width; i++)
// set(1, i + 1, (char[2]){src_txt[i], 0}, 0x3EAAFF, base_bg, 0);
// for (uint32_t i = 0; i < warnings[0].source.length() && i <
// content_width;
// i++)
// set(1, i + 1 + src_txt.length(), (char[2]){warnings[0].source[i], 0},
// 0xffffff, base_bg, 0);
// r++;
// }
// int idx = 1;
// for (auto &warn : warnings) {
// char buf[4];
// std::snprintf(buf, sizeof(buf), "%2d", idx % 100);
// std::string line_txt = std::string(buf) + ". ";
// for (uint32_t i = 0; i < line_txt.length(); i++)
// set(r + 1, i + 1, (char[2]){line_txt[i], 0}, 0xffffff, base_bg, 0);
// if (r >= 23)
// break;
// const char *err_sym = "";
// uint32_t c_sym = 0xAAAAAA;
// switch (warn.type) {
// case 1:
// err_sym = "";
// c_sym = 0xFF0000;
// break;
// case 2:
// err_sym = "";
// c_sym = 0xFFFF00;
// break;
// case 3:
// err_sym = "";
// c_sym = 0xFF00FF;
// break;
// case 4:
// err_sym = "";
// c_sym = 0xAAAAAA;
// break;
// }
// std::string text = warn.text_full + " " + err_sym;
// uint32_t i = 0;
// while (i < text.length() && r < 23) {
// uint32_t c = 4;
// while (c < content_width && i < text.length()) {
// if (text[i] == '\n') {
// while (i < text.length() && text[i] == '\n')
// i++;
// break;
// }
// uint32_t cluster_len = grapheme_next_character_break_utf8(
// text.c_str() + i, text.length() - i);
// std::string cluster = text.substr(i, cluster_len);
// int width = display_width(cluster.c_str(), cluster_len);
// if (c + width > content_width)
// break;
// set(r + 1, c + 1, cluster.c_str(), c_sym, base_bg, 0);
// c += width;
// i += cluster_len;
// for (int w = 1; w < width; w++)
// set(r + 1, c - w + 1, "\x1b", c_sym, base_bg, 0);
// }
// r++;
// }
// if (r >= 23)
// break;
// if (warn.code != "") {
// for (uint32_t i = 0; i < warn.code.length() && i + 5 < content_width;
// i++)
// set(r + 1, i + 5, (char[2]){warn.code[i], 0}, 0x81cdc6, base_bg, 0);
// r++;
// }
// if (r >= 23)
// break;
// for (std::string &see_also : warn.see_also) {
// uint32_t fg = 0xB55EFF;
// uint8_t colon_count = 0;
// for (uint32_t i = 0; i < see_also.length() && i + 5 < content_width;
// i++) {
// set(r + 1, i + 5, (char[2]){see_also[i], 0}, fg, base_bg, 0);
// if (see_also[i] == ':')
// colon_count++;
// if (colon_count == 2)
// fg = 0xFFFFFF;
// }
// r++;
// if (r >= 23)
// break;
// };
// idx++;
// }
// size.row = 2 + r;
// set(0, 0, "┌", border_fg, base_bg, 0);
// for (uint32_t i = 1; i < size.col - 1; i++)
// set(0, i, "─", border_fg, base_bg, 0);
// set(0, size.col - 1, "┐", border_fg, base_bg, 0);
// for (uint32_t r = 1; r < size.row - 1; r++) {
// set(r, 0, "│", border_fg, base_bg, 0);
// set(r, size.col - 1, "│", border_fg, base_bg, 0);
// }
// set(size.row - 1, 0, "└", border_fg, base_bg, 0);
// for (uint32_t i = 1; i < size.col - 1; i++)
// set(size.row - 1, i, "─", border_fg, base_bg, 0);
// set(size.row - 1, size.col - 1, "┘", border_fg, base_bg, 0);
// cells.resize(size.col * size.row);
// }
//
// void DiagnosticBox::render(Coord pos) {
// int32_t start_row = (int32_t)pos.row - (int32_t)size.row;
// if (start_row < 0)
// start_row = pos.row + 1;
// int32_t start_col = pos.col;
// Coord screen_size = get_size();
// if (start_col + size.col > screen_size.col) {
// start_col = screen_size.col - size.col;
// if (start_col < 0)
// start_col = 0;
// }
// for (uint32_t r = 0; r < size.row; r++)
// for (uint32_t c = 0; c < size.col; c++)
// update(start_row + r, start_col + c, cells[r * size.col + c].utf8,
// cells[r * size.col + c].fg, cells[r * size.col + c].bg,
// cells[r * size.col + c].flags);
// }

View File

@@ -1,119 +0,0 @@
#include "ui/hover.h"
#include "syntax/decl.h"
void HoverBox::clear() {
text = "";
scroll_ = 0;
is_markup = false;
size = {0, 0};
cells.clear();
}
void HoverBox::scroll(int32_t number) {
if (text.empty() || number == 0)
return;
uint32_t line_count = 0;
for (uint32_t i = 0; i < text.length(); i++)
if (text[i] == '\n')
line_count++;
scroll_ = MAX((int32_t)scroll_ + number, 0);
if (scroll_ > line_count)
scroll_ = line_count;
render_first(true);
}
void HoverBox::render_first(bool scroll) {
if (!scroll) {
// TODO: call syntax highlighter here
}
uint32_t longest_line = 0;
uint32_t current_width = 0;
for (size_t j = 0; j < text.length(); j++) {
if (text[j] == '\n') {
longest_line = std::max(longest_line, current_width);
current_width = 0;
} else {
current_width += 1;
}
}
// HACK: the 1 is added so the longest line doesnt wrap which should be fixed
// in the loop instead as it was never meant to wrap in the first place
longest_line = MAX(longest_line, current_width) + 1;
uint32_t content_width = MIN(longest_line, 130u);
size.col = content_width + 2;
size_t i = 0;
size_t lines_skipped = 0;
while (i < text.length() && lines_skipped < scroll_) {
if (text[i] == '\n')
lines_skipped++;
i++;
}
uint32_t border_fg = 0x82AAFF;
uint32_t base_bg = 0;
cells.assign(size.col * 26, ScreenCell{" ", 0, 0, 0, 0, 0});
auto set = [&](uint32_t r, uint32_t c, const char *text, uint32_t fg,
uint32_t bg, uint8_t flags) {
cells[r * size.col + c] = {std::string(text), 0, fg, bg, flags, 0};
};
uint32_t r = 0;
while (i < text.length() && r < 24) {
uint32_t c = 0;
while (c < content_width && i < text.length()) {
if (text[i] == '\n') {
while (i < text.length() && text[i] == '\n')
i++;
break;
}
uint32_t cluster_len = grapheme_next_character_break_utf8(
text.c_str() + i, text.length() - i);
std::string cluster = text.substr(i, cluster_len);
int width = display_width(cluster.c_str(), cluster_len);
if (c + width > content_width)
break;
// TODO: Use new highlights
Highlight *hl = nullptr;
uint32_t fg = hl ? hl->fg : 0xFFFFFF;
uint32_t bg = hl ? hl->bg : 0;
uint32_t flags = hl ? hl->flags : 0;
set(r + 1, c + 1, cluster.c_str(), fg, bg | base_bg, flags);
c += width;
i += cluster_len;
for (int w = 1; w < width; w++)
set(r + 1, c - w + 1, "\x1b", 0xFFFFFF, base_bg, 0);
}
r++;
}
if (!scroll)
size.row = r + 2;
set(0, 0, "", border_fg, base_bg, 0);
for (uint32_t i = 1; i < size.col - 1; i++)
set(0, i, "", border_fg, base_bg, 0);
set(0, size.col - 1, "", border_fg, base_bg, 0);
for (uint32_t r = 1; r < size.row - 1; r++) {
set(r, 0, "", border_fg, base_bg, 0);
set(r, size.col - 1, "", border_fg, base_bg, 0);
}
set(size.row - 1, 0, "", border_fg, base_bg, 0);
for (uint32_t i = 1; i < size.col - 1; i++)
set(size.row - 1, i, "", border_fg, base_bg, 0);
set(size.row - 1, size.col - 1, "", border_fg, base_bg, 0);
cells.resize(size.col * size.row);
}
void HoverBox::render(Coord pos) {
int32_t start_row = (int32_t)pos.row - (int32_t)size.row;
if (start_row < 0)
start_row = pos.row + 1;
int32_t start_col = pos.col;
Coord screen_size = get_size();
if (start_col + size.col > screen_size.col) {
start_col = screen_size.col - size.col;
if (start_col < 0)
start_col = 0;
}
for (uint32_t r = 0; r < size.row; r++)
for (uint32_t c = 0; c < size.col; c++)
update(start_row + r, start_col + c, cells[r * size.col + c].utf8,
cells[r * size.col + c].fg, cells[r * size.col + c].bg,
cells[r * size.col + c].flags);
}