Switch to OOP style code
This commit is contained in:
@@ -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]))) {
|
||||
|
||||
@@ -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});
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -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);
|
||||
// }
|
||||
|
||||
119
src/ui/hover.cc
119
src/ui/hover.cc
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user