Refactor indentation for consistent style across codebase.
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
Release / Build Linux amd64 (push) Has been cancelled
Release / Build Linux arm64 (push) Has been cancelled
Release / Build macOS arm64 (.app) (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
Release / Build Linux amd64 (push) Has been cancelled
Release / Build Linux arm64 (push) Has been cancelled
Release / Build macOS arm64 (.app) (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
This commit is contained in:
@@ -542,4 +542,4 @@ const UndoSystem *
|
|||||||
Buffer::Undo() const
|
Buffer::Undo() const
|
||||||
{
|
{
|
||||||
return undo_sys_.get();
|
return undo_sys_.get();
|
||||||
}
|
}
|
||||||
|
|||||||
2
Buffer.h
2
Buffer.h
@@ -468,4 +468,4 @@ private:
|
|||||||
std::unique_ptr<kte::HighlighterEngine> highlighter_;
|
std::unique_ptr<kte::HighlighterEngine> highlighter_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KTE_BUFFER_H
|
#endif // KTE_BUFFER_H
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ project(kte)
|
|||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(KTE_VERSION "1.2.0")
|
set(KTE_VERSION "1.2.1")
|
||||||
|
|
||||||
# Default to terminal-only build to avoid SDL/OpenGL dependency by default.
|
# Default to terminal-only build to avoid SDL/OpenGL dependency by default.
|
||||||
# Enable with -DBUILD_GUI=ON when SDL2/OpenGL/Freetype are available.
|
# Enable with -DBUILD_GUI=ON when SDL2/OpenGL/Freetype are available.
|
||||||
|
|||||||
@@ -3800,4 +3800,4 @@ Execute(Editor &ed, const std::string &name, const std::string &arg, int count)
|
|||||||
return false;
|
return false;
|
||||||
CommandContext ctx{ed, arg, count};
|
CommandContext ctx{ed, arg, count};
|
||||||
return cmd->handler ? cmd->handler(ctx) : false;
|
return cmd->handler ? cmd->handler(ctx) : false;
|
||||||
}
|
}
|
||||||
|
|||||||
10
Command.h
10
Command.h
@@ -94,10 +94,10 @@ enum class CommandId {
|
|||||||
// Theme by name
|
// Theme by name
|
||||||
ThemeSetByName,
|
ThemeSetByName,
|
||||||
// Background mode (GUI)
|
// Background mode (GUI)
|
||||||
BackgroundSet,
|
BackgroundSet,
|
||||||
// Syntax highlighting
|
// Syntax highlighting
|
||||||
Syntax, // ":syntax on|off|reload"
|
Syntax, // ":syntax on|off|reload"
|
||||||
SetOption, // generic ":set key=value" (v1: filetype=<lang>)
|
SetOption, // generic ":set key=value" (v1: filetype=<lang>)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -151,4 +151,4 @@ bool Execute(Editor &ed, CommandId id, const std::string &arg = std::string(), i
|
|||||||
|
|
||||||
bool Execute(Editor &ed, const std::string &name, const std::string &arg = std::string(), int count = 0);
|
bool Execute(Editor &ed, const std::string &name, const std::string &arg = std::string(), int count = 0);
|
||||||
|
|
||||||
#endif // KTE_COMMAND_H
|
#endif // KTE_COMMAND_H
|
||||||
@@ -282,4 +282,4 @@ Editor::Reset()
|
|||||||
quit_confirm_pending_ = false;
|
quit_confirm_pending_ = false;
|
||||||
buffers_.clear();
|
buffers_.clear();
|
||||||
curbuf_ = 0;
|
curbuf_ = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
46
GUIConfig.cc
46
GUIConfig.cc
@@ -102,27 +102,27 @@ GUIConfig::LoadFromFile(const std::string &path)
|
|||||||
if (v > 0.0f) {
|
if (v > 0.0f) {
|
||||||
font_size = v;
|
font_size = v;
|
||||||
}
|
}
|
||||||
} else if (key == "theme") {
|
} else if (key == "theme") {
|
||||||
theme = val;
|
theme = val;
|
||||||
} else if (key == "background" || key == "bg") {
|
} else if (key == "background" || key == "bg") {
|
||||||
std::string v = val;
|
std::string v = val;
|
||||||
std::transform(v.begin(), v.end(), v.begin(), [](unsigned char c) {
|
std::transform(v.begin(), v.end(), v.begin(), [](unsigned char c) {
|
||||||
return (char) std::tolower(c);
|
return (char) std::tolower(c);
|
||||||
});
|
});
|
||||||
if (v == "light" || v == "dark")
|
if (v == "light" || v == "dark")
|
||||||
background = v;
|
background = v;
|
||||||
} else if (key == "syntax") {
|
} else if (key == "syntax") {
|
||||||
std::string v = val;
|
std::string v = val;
|
||||||
std::transform(v.begin(), v.end(), v.begin(), [](unsigned char c) {
|
std::transform(v.begin(), v.end(), v.begin(), [](unsigned char c) {
|
||||||
return (char) std::tolower(c);
|
return (char) std::tolower(c);
|
||||||
});
|
});
|
||||||
if (v == "1" || v == "on" || v == "true" || v == "yes") {
|
if (v == "1" || v == "on" || v == "true" || v == "yes") {
|
||||||
syntax = true;
|
syntax = true;
|
||||||
} else if (v == "0" || v == "off" || v == "false" || v == "no") {
|
} else if (v == "0" || v == "off" || v == "false" || v == "no") {
|
||||||
syntax = false;
|
syntax = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
24
GUIConfig.h
24
GUIConfig.h
@@ -12,18 +12,18 @@
|
|||||||
|
|
||||||
class GUIConfig {
|
class GUIConfig {
|
||||||
public:
|
public:
|
||||||
bool fullscreen = false;
|
bool fullscreen = false;
|
||||||
int columns = 80;
|
int columns = 80;
|
||||||
int rows = 42;
|
int rows = 42;
|
||||||
float font_size = (float) KTE_FONT_SIZE;
|
float font_size = (float) KTE_FONT_SIZE;
|
||||||
std::string theme = "nord";
|
std::string theme = "nord";
|
||||||
// Background mode for themes that support light/dark variants
|
// Background mode for themes that support light/dark variants
|
||||||
// Values: "dark" (default), "light"
|
// Values: "dark" (default), "light"
|
||||||
std::string background = "dark";
|
std::string background = "dark";
|
||||||
|
|
||||||
// Default syntax highlighting state for GUI (kge): on/off
|
// Default syntax highlighting state for GUI (kge): on/off
|
||||||
// Accepts: on/off/true/false/yes/no/1/0 in the ini file.
|
// Accepts: on/off/true/false/yes/no/1/0 in the ini file.
|
||||||
bool syntax = true; // default: enabled
|
bool syntax = true; // default: enabled
|
||||||
|
|
||||||
// Load from default path: $HOME/.config/kte/kge.ini
|
// Load from default path: $HOME/.config/kte/kge.ini
|
||||||
static GUIConfig Load();
|
static GUIConfig Load();
|
||||||
@@ -32,4 +32,4 @@ public:
|
|||||||
bool LoadFromFile(const std::string &path);
|
bool LoadFromFile(const std::string &path);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KTE_GUI_CONFIG_H
|
#endif // KTE_GUI_CONFIG_H
|
||||||
@@ -318,4 +318,4 @@ GUIFrontend::LoadGuiFont_(const char * /*path*/, float size_px)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// No runtime font reload or system font resolution in this simplified build.
|
// No runtime font reload or system font resolution in this simplified build.
|
||||||
|
|||||||
140
GUIRenderer.cc
140
GUIRenderer.cc
@@ -139,29 +139,29 @@ GUIRenderer::Draw(Editor &ed)
|
|||||||
vis_rows = 1;
|
vis_rows = 1;
|
||||||
long last_row = first_row + vis_rows - 1;
|
long last_row = first_row + vis_rows - 1;
|
||||||
|
|
||||||
if (!forced_scroll) {
|
if (!forced_scroll) {
|
||||||
long cyr = static_cast<long>(cy);
|
long cyr = static_cast<long>(cy);
|
||||||
if (cyr < first_row || cyr > last_row) {
|
if (cyr < first_row || cyr > last_row) {
|
||||||
float target = (static_cast<float>(cyr) - std::max(0L, vis_rows / 2)) * row_h;
|
float target = (static_cast<float>(cyr) - std::max(0L, vis_rows / 2)) * row_h;
|
||||||
float max_y = ImGui::GetScrollMaxY();
|
float max_y = ImGui::GetScrollMaxY();
|
||||||
if (target < 0.f)
|
if (target < 0.f)
|
||||||
target = 0.f;
|
target = 0.f;
|
||||||
if (max_y >= 0.f && target > max_y)
|
if (max_y >= 0.f && target > max_y)
|
||||||
target = max_y;
|
target = max_y;
|
||||||
ImGui::SetScrollY(target);
|
ImGui::SetScrollY(target);
|
||||||
// refresh local variables
|
// refresh local variables
|
||||||
scroll_y = ImGui::GetScrollY();
|
scroll_y = ImGui::GetScrollY();
|
||||||
first_row = static_cast<long>(scroll_y / row_h);
|
first_row = static_cast<long>(scroll_y / row_h);
|
||||||
last_row = first_row + vis_rows - 1;
|
last_row = first_row + vis_rows - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Phase 3: prefetch visible viewport highlights and warm around in background
|
// Phase 3: prefetch visible viewport highlights and warm around in background
|
||||||
if (buf->SyntaxEnabled() && buf->Highlighter() && buf->Highlighter()->HasHighlighter()) {
|
if (buf->SyntaxEnabled() && buf->Highlighter() && buf->Highlighter()->HasHighlighter()) {
|
||||||
int fr = static_cast<int>(std::max(0L, first_row));
|
int fr = static_cast<int>(std::max(0L, first_row));
|
||||||
int rc = static_cast<int>(std::max(1L, vis_rows));
|
int rc = static_cast<int>(std::max(1L, vis_rows));
|
||||||
buf->Highlighter()->PrefetchViewport(*buf, fr, rc, buf->Version());
|
buf->Highlighter()->PrefetchViewport(*buf, fr, rc, buf->Version());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Handle mouse click before rendering to avoid dependent on drawn items
|
// Handle mouse click before rendering to avoid dependent on drawn items
|
||||||
if (ImGui::IsWindowHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
if (ImGui::IsWindowHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
||||||
ImVec2 mp = ImGui::GetIO().MousePos;
|
ImVec2 mp = ImGui::GetIO().MousePos;
|
||||||
@@ -329,50 +329,56 @@ GUIRenderer::Draw(Editor &ed)
|
|||||||
ImGui::GetWindowDrawList()->AddRectFilled(p0, p1, col);
|
ImGui::GetWindowDrawList()->AddRectFilled(p0, p1, col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Emit entire line to an expanded buffer (tabs -> spaces)
|
// Emit entire line to an expanded buffer (tabs -> spaces)
|
||||||
for (std::size_t src = 0; src < line.size(); ++src) {
|
for (std::size_t src = 0; src < line.size(); ++src) {
|
||||||
char c = line[src];
|
char c = line[src];
|
||||||
if (c == '\t') {
|
if (c == '\t') {
|
||||||
std::size_t adv = (tabw - (rx_abs_draw % tabw));
|
std::size_t adv = (tabw - (rx_abs_draw % tabw));
|
||||||
expanded.append(adv, ' ');
|
expanded.append(adv, ' ');
|
||||||
rx_abs_draw += adv;
|
rx_abs_draw += adv;
|
||||||
} else {
|
} else {
|
||||||
expanded.push_back(c);
|
expanded.push_back(c);
|
||||||
rx_abs_draw += 1;
|
rx_abs_draw += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw syntax-colored runs (text above background highlights)
|
// Draw syntax-colored runs (text above background highlights)
|
||||||
if (buf->SyntaxEnabled() && buf->Highlighter() && buf->Highlighter()->HasHighlighter()) {
|
if (buf->SyntaxEnabled() && buf->Highlighter() && buf->Highlighter()->HasHighlighter()) {
|
||||||
const kte::LineHighlight &lh = buf->Highlighter()->GetLine(*buf, static_cast<int>(i), buf->Version());
|
const kte::LineHighlight &lh = buf->Highlighter()->GetLine(
|
||||||
// Helper to convert a src column to expanded rx position
|
*buf, static_cast<int>(i), buf->Version());
|
||||||
auto src_to_rx_full = [&](std::size_t sidx) -> std::size_t {
|
// Helper to convert a src column to expanded rx position
|
||||||
std::size_t rx = 0;
|
auto src_to_rx_full = [&](std::size_t sidx) -> std::size_t {
|
||||||
for (std::size_t k = 0; k < sidx && k < line.size(); ++k) {
|
std::size_t rx = 0;
|
||||||
rx += (line[k] == '\t') ? (tabw - (rx % tabw)) : 1;
|
for (std::size_t k = 0; k < sidx && k < line.size(); ++k) {
|
||||||
}
|
rx += (line[k] == '\t') ? (tabw - (rx % tabw)) : 1;
|
||||||
return rx;
|
}
|
||||||
};
|
return rx;
|
||||||
for (const auto &sp: lh.spans) {
|
};
|
||||||
std::size_t rx_s = src_to_rx_full(static_cast<std::size_t>(std::max(0, sp.col_start)));
|
for (const auto &sp: lh.spans) {
|
||||||
std::size_t rx_e = src_to_rx_full(static_cast<std::size_t>(std::max(sp.col_start, sp.col_end)));
|
std::size_t rx_s = src_to_rx_full(
|
||||||
if (rx_e <= coloffs_now)
|
static_cast<std::size_t>(std::max(0, sp.col_start)));
|
||||||
continue;
|
std::size_t rx_e = src_to_rx_full(
|
||||||
std::size_t vx0 = (rx_s > coloffs_now) ? (rx_s - coloffs_now) : 0;
|
static_cast<std::size_t>(std::max(sp.col_start, sp.col_end)));
|
||||||
std::size_t vx1 = (rx_e > coloffs_now) ? (rx_e - coloffs_now) : 0;
|
if (rx_e <= coloffs_now)
|
||||||
if (vx0 >= expanded.size()) continue;
|
continue;
|
||||||
vx1 = std::min<std::size_t>(vx1, expanded.size());
|
std::size_t vx0 = (rx_s > coloffs_now) ? (rx_s - coloffs_now) : 0;
|
||||||
if (vx1 <= vx0) continue;
|
std::size_t vx1 = (rx_e > coloffs_now) ? (rx_e - coloffs_now) : 0;
|
||||||
ImU32 col = ImGui::GetColorU32(kte::SyntaxInk(sp.kind));
|
if (vx0 >= expanded.size())
|
||||||
ImVec2 p = ImVec2(line_pos.x + static_cast<float>(vx0) * space_w, line_pos.y);
|
continue;
|
||||||
ImGui::GetWindowDrawList()->AddText(p, col, expanded.c_str() + vx0, expanded.c_str() + vx1);
|
vx1 = std::min<std::size_t>(vx1, expanded.size());
|
||||||
}
|
if (vx1 <= vx0)
|
||||||
// We drew text via draw list (no layout advance). Manually advance the cursor to the next line.
|
continue;
|
||||||
ImGui::SetCursorScreenPos(ImVec2(line_pos.x, line_pos.y + line_h));
|
ImU32 col = ImGui::GetColorU32(kte::SyntaxInk(sp.kind));
|
||||||
} else {
|
ImVec2 p = ImVec2(line_pos.x + static_cast<float>(vx0) * space_w, line_pos.y);
|
||||||
// No syntax: draw as one run
|
ImGui::GetWindowDrawList()->AddText(
|
||||||
ImGui::TextUnformatted(expanded.c_str());
|
p, col, expanded.c_str() + vx0, expanded.c_str() + vx1);
|
||||||
}
|
}
|
||||||
|
// We drew text via draw list (no layout advance). Manually advance the cursor to the next line.
|
||||||
|
ImGui::SetCursorScreenPos(ImVec2(line_pos.x, line_pos.y + line_h));
|
||||||
|
} else {
|
||||||
|
// No syntax: draw as one run
|
||||||
|
ImGui::TextUnformatted(expanded.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
// Draw a visible cursor indicator on the current line
|
// Draw a visible cursor indicator on the current line
|
||||||
if (i == cy) {
|
if (i == cy) {
|
||||||
@@ -761,4 +767,4 @@ GUIRenderer::Draw(Editor &ed)
|
|||||||
ed.SetFilePickerVisible(false);
|
ed.SetFilePickerVisible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -412,4 +412,4 @@ SyntaxInk(const TokenKind k)
|
|||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace kte
|
} // namespace kte
|
||||||
|
|||||||
44
Highlight.h
44
Highlight.h
@@ -5,35 +5,33 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace kte {
|
namespace kte {
|
||||||
|
|
||||||
// Token kinds shared between renderers and highlighters
|
// Token kinds shared between renderers and highlighters
|
||||||
enum class TokenKind {
|
enum class TokenKind {
|
||||||
Default,
|
Default,
|
||||||
Keyword,
|
Keyword,
|
||||||
Type,
|
Type,
|
||||||
String,
|
String,
|
||||||
Char,
|
Char,
|
||||||
Comment,
|
Comment,
|
||||||
Number,
|
Number,
|
||||||
Preproc,
|
Preproc,
|
||||||
Constant,
|
Constant,
|
||||||
Function,
|
Function,
|
||||||
Operator,
|
Operator,
|
||||||
Punctuation,
|
Punctuation,
|
||||||
Identifier,
|
Identifier,
|
||||||
Whitespace,
|
Whitespace,
|
||||||
Error
|
Error
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HighlightSpan {
|
struct HighlightSpan {
|
||||||
int col_start{0}; // inclusive, 0-based columns in buffer indices
|
int col_start{0}; // inclusive, 0-based columns in buffer indices
|
||||||
int col_end{0}; // exclusive
|
int col_end{0}; // exclusive
|
||||||
TokenKind kind{TokenKind::Default};
|
TokenKind kind{TokenKind::Default};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LineHighlight {
|
struct LineHighlight {
|
||||||
std::vector<HighlightSpan> spans;
|
std::vector<HighlightSpan> spans;
|
||||||
std::uint64_t version{0}; // buffer version used for this line
|
std::uint64_t version{0}; // buffer version used for this line
|
||||||
};
|
};
|
||||||
|
} // namespace kte
|
||||||
} // namespace kte
|
|
||||||
@@ -2,9 +2,11 @@ ROADMAP / TODO:
|
|||||||
|
|
||||||
- [x] Search + Replace
|
- [x] Search + Replace
|
||||||
- [x] Regex search + replace
|
- [x] Regex search + replace
|
||||||
- [ ] The undo system should actually work
|
|
||||||
- [x] Able to mark buffers as read-only
|
- [x] Able to mark buffers as read-only
|
||||||
- [x] Built-in help text
|
- [x] Built-in help text
|
||||||
- [x] Shorten paths in the homedir with ~
|
- [x] Shorten paths in the homedir with ~
|
||||||
- [x] When the filename is longer than the message window, scoot left to
|
- [x] When the filename is longer than the message window, scoot left to
|
||||||
keep it in view
|
keep it in view
|
||||||
|
- [x] Syntax highlighting
|
||||||
|
- [ ] The undo system should actually work
|
||||||
|
- [ ] LSP integration
|
||||||
|
|||||||
@@ -42,18 +42,18 @@ TerminalRenderer::Draw(Editor &ed)
|
|||||||
std::size_t coloffs = buf->Coloffs();
|
std::size_t coloffs = buf->Coloffs();
|
||||||
|
|
||||||
const int tabw = 8;
|
const int tabw = 8;
|
||||||
// Phase 3: prefetch visible viewport highlights (current terminal area)
|
// Phase 3: prefetch visible viewport highlights (current terminal area)
|
||||||
if (buf->SyntaxEnabled() && buf->Highlighter() && buf->Highlighter()->HasHighlighter()) {
|
if (buf->SyntaxEnabled() && buf->Highlighter() && buf->Highlighter()->HasHighlighter()) {
|
||||||
int fr = static_cast<int>(rowoffs);
|
int fr = static_cast<int>(rowoffs);
|
||||||
int rc = std::max(0, content_rows);
|
int rc = std::max(0, content_rows);
|
||||||
buf->Highlighter()->PrefetchViewport(*buf, fr, rc, buf->Version());
|
buf->Highlighter()->PrefetchViewport(*buf, fr, rc, buf->Version());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int r = 0; r < content_rows; ++r) {
|
for (int r = 0; r < content_rows; ++r) {
|
||||||
move(r, 0);
|
move(r, 0);
|
||||||
std::size_t li = rowoffs + static_cast<std::size_t>(r);
|
std::size_t li = rowoffs + static_cast<std::size_t>(r);
|
||||||
std::size_t render_col = 0;
|
std::size_t render_col = 0;
|
||||||
std::size_t src_i = 0;
|
std::size_t src_i = 0;
|
||||||
// Compute matches for this line if search highlighting is active
|
// Compute matches for this line if search highlighting is active
|
||||||
bool search_mode = ed.SearchActive() && !ed.SearchQuery().empty();
|
bool search_mode = ed.SearchActive() && !ed.SearchQuery().empty();
|
||||||
std::vector<std::pair<std::size_t, std::size_t> > ranges; // [start, end)
|
std::vector<std::pair<std::size_t, std::size_t> > ranges; // [start, end)
|
||||||
@@ -105,49 +105,53 @@ TerminalRenderer::Draw(Editor &ed)
|
|||||||
bool hl_on = false;
|
bool hl_on = false;
|
||||||
bool cur_on = false;
|
bool cur_on = false;
|
||||||
int written = 0;
|
int written = 0;
|
||||||
if (li < lines.size()) {
|
if (li < lines.size()) {
|
||||||
std::string line = static_cast<std::string>(lines[li]);
|
std::string line = static_cast<std::string>(lines[li]);
|
||||||
src_i = 0;
|
src_i = 0;
|
||||||
render_col = 0;
|
render_col = 0;
|
||||||
// Syntax highlighting: fetch per-line spans
|
// Syntax highlighting: fetch per-line spans
|
||||||
const kte::LineHighlight *lh_ptr = nullptr;
|
const kte::LineHighlight *lh_ptr = nullptr;
|
||||||
if (buf->SyntaxEnabled() && buf->Highlighter() && buf->Highlighter()->HasHighlighter()) {
|
if (buf->SyntaxEnabled() && buf->Highlighter() && buf->Highlighter()->
|
||||||
lh_ptr = &buf->Highlighter()->GetLine(*buf, static_cast<int>(li), buf->Version());
|
HasHighlighter()) {
|
||||||
}
|
lh_ptr = &buf->Highlighter()->GetLine(
|
||||||
auto token_at = [&](std::size_t src_index) -> kte::TokenKind {
|
*buf, static_cast<int>(li), buf->Version());
|
||||||
if (!lh_ptr) return kte::TokenKind::Default;
|
}
|
||||||
for (const auto &sp: lh_ptr->spans) {
|
auto token_at = [&](std::size_t src_index) -> kte::TokenKind {
|
||||||
if (static_cast<int>(src_index) >= sp.col_start && static_cast<int>(src_index) < sp.col_end)
|
if (!lh_ptr)
|
||||||
return sp.kind;
|
return kte::TokenKind::Default;
|
||||||
}
|
for (const auto &sp: lh_ptr->spans) {
|
||||||
return kte::TokenKind::Default;
|
if (static_cast<int>(src_index) >= sp.col_start && static_cast<int>(
|
||||||
};
|
src_index) < sp.col_end)
|
||||||
auto apply_token_attr = [&](kte::TokenKind k) {
|
return sp.kind;
|
||||||
// Map to simple attributes; search highlight uses A_STANDOUT which takes precedence below
|
}
|
||||||
attrset(A_NORMAL);
|
return kte::TokenKind::Default;
|
||||||
switch (k) {
|
};
|
||||||
case kte::TokenKind::Keyword:
|
auto apply_token_attr = [&](kte::TokenKind k) {
|
||||||
case kte::TokenKind::Type:
|
// Map to simple attributes; search highlight uses A_STANDOUT which takes precedence below
|
||||||
case kte::TokenKind::Constant:
|
attrset(A_NORMAL);
|
||||||
case kte::TokenKind::Function:
|
switch (k) {
|
||||||
attron(A_BOLD);
|
case kte::TokenKind::Keyword:
|
||||||
break;
|
case kte::TokenKind::Type:
|
||||||
case kte::TokenKind::Comment:
|
case kte::TokenKind::Constant:
|
||||||
attron(A_DIM);
|
case kte::TokenKind::Function:
|
||||||
break;
|
attron(A_BOLD);
|
||||||
case kte::TokenKind::String:
|
break;
|
||||||
case kte::TokenKind::Char:
|
case kte::TokenKind::Comment:
|
||||||
case kte::TokenKind::Number:
|
attron(A_DIM);
|
||||||
// standout a bit using A_UNDERLINE if available
|
break;
|
||||||
attron(A_UNDERLINE);
|
case kte::TokenKind::String:
|
||||||
break;
|
case kte::TokenKind::Char:
|
||||||
default:
|
case kte::TokenKind::Number:
|
||||||
break;
|
// standout a bit using A_UNDERLINE if available
|
||||||
}
|
attron(A_UNDERLINE);
|
||||||
};
|
break;
|
||||||
while (written < cols) {
|
default:
|
||||||
char ch = ' ';
|
break;
|
||||||
bool from_src = false;
|
}
|
||||||
|
};
|
||||||
|
while (written < cols) {
|
||||||
|
char ch = ' ';
|
||||||
|
bool from_src = false;
|
||||||
if (src_i < line.size()) {
|
if (src_i < line.size()) {
|
||||||
unsigned char c = static_cast<unsigned char>(line[src_i]);
|
unsigned char c = static_cast<unsigned char>(line[src_i]);
|
||||||
if (c == '\t') {
|
if (c == '\t') {
|
||||||
@@ -166,45 +170,45 @@ TerminalRenderer::Draw(Editor &ed)
|
|||||||
next_tab -= to_skip;
|
next_tab -= to_skip;
|
||||||
}
|
}
|
||||||
// Now render visible spaces
|
// Now render visible spaces
|
||||||
while (next_tab > 0 && written < cols) {
|
while (next_tab > 0 && written < cols) {
|
||||||
bool in_hl = search_mode && is_src_in_hl(src_i);
|
bool in_hl = search_mode && is_src_in_hl(src_i);
|
||||||
bool in_cur =
|
bool in_cur =
|
||||||
has_current && li == cur_my && src_i >= cur_mx
|
has_current && li == cur_my && src_i >= cur_mx
|
||||||
&& src_i < cur_mend;
|
&& src_i < cur_mend;
|
||||||
// Toggle highlight attributes
|
// Toggle highlight attributes
|
||||||
int attr = 0;
|
int attr = 0;
|
||||||
if (in_hl)
|
if (in_hl)
|
||||||
attr |= A_STANDOUT;
|
attr |= A_STANDOUT;
|
||||||
if (in_cur)
|
if (in_cur)
|
||||||
attr |= A_BOLD;
|
attr |= A_BOLD;
|
||||||
if ((attr & A_STANDOUT) && !hl_on) {
|
if ((attr & A_STANDOUT) && !hl_on) {
|
||||||
attron(A_STANDOUT);
|
attron(A_STANDOUT);
|
||||||
hl_on = true;
|
hl_on = true;
|
||||||
}
|
}
|
||||||
if (!(attr & A_STANDOUT) && hl_on) {
|
if (!(attr & A_STANDOUT) && hl_on) {
|
||||||
attroff(A_STANDOUT);
|
attroff(A_STANDOUT);
|
||||||
hl_on = false;
|
hl_on = false;
|
||||||
}
|
}
|
||||||
if ((attr & A_BOLD) && !cur_on) {
|
if ((attr & A_BOLD) && !cur_on) {
|
||||||
attron(A_BOLD);
|
attron(A_BOLD);
|
||||||
cur_on = true;
|
cur_on = true;
|
||||||
}
|
}
|
||||||
if (!(attr & A_BOLD) && cur_on) {
|
if (!(attr & A_BOLD) && cur_on) {
|
||||||
attroff(A_BOLD);
|
attroff(A_BOLD);
|
||||||
cur_on = false;
|
cur_on = false;
|
||||||
}
|
}
|
||||||
// Apply syntax attribute only if not in search highlight
|
// Apply syntax attribute only if not in search highlight
|
||||||
if (!in_hl) {
|
if (!in_hl) {
|
||||||
apply_token_attr(token_at(src_i));
|
apply_token_attr(token_at(src_i));
|
||||||
}
|
}
|
||||||
addch(' ');
|
addch(' ');
|
||||||
++written;
|
++written;
|
||||||
++render_col;
|
++render_col;
|
||||||
--next_tab;
|
--next_tab;
|
||||||
}
|
}
|
||||||
++src_i;
|
++src_i;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// normal char
|
// normal char
|
||||||
if (render_col < coloffs) {
|
if (render_col < coloffs) {
|
||||||
++render_col;
|
++render_col;
|
||||||
@@ -219,49 +223,49 @@ TerminalRenderer::Draw(Editor &ed)
|
|||||||
ch = ' ';
|
ch = ' ';
|
||||||
from_src = false;
|
from_src = false;
|
||||||
}
|
}
|
||||||
bool in_hl = search_mode && from_src && is_src_in_hl(src_i);
|
bool in_hl = search_mode && from_src && is_src_in_hl(src_i);
|
||||||
bool in_cur =
|
bool in_cur =
|
||||||
has_current && li == cur_my && from_src && src_i >= cur_mx && src_i <
|
has_current && li == cur_my && from_src && src_i >= cur_mx && src_i <
|
||||||
cur_mend;
|
cur_mend;
|
||||||
if (in_hl && !hl_on) {
|
if (in_hl && !hl_on) {
|
||||||
attron(A_STANDOUT);
|
attron(A_STANDOUT);
|
||||||
hl_on = true;
|
hl_on = true;
|
||||||
}
|
}
|
||||||
if (!in_hl && hl_on) {
|
if (!in_hl && hl_on) {
|
||||||
attroff(A_STANDOUT);
|
attroff(A_STANDOUT);
|
||||||
hl_on = false;
|
hl_on = false;
|
||||||
}
|
}
|
||||||
if (in_cur && !cur_on) {
|
if (in_cur && !cur_on) {
|
||||||
attron(A_BOLD);
|
attron(A_BOLD);
|
||||||
cur_on = true;
|
cur_on = true;
|
||||||
}
|
}
|
||||||
if (!in_cur && cur_on) {
|
if (!in_cur && cur_on) {
|
||||||
attroff(A_BOLD);
|
attroff(A_BOLD);
|
||||||
cur_on = false;
|
cur_on = false;
|
||||||
}
|
}
|
||||||
if (!in_hl && from_src) {
|
if (!in_hl && from_src) {
|
||||||
apply_token_attr(token_at(src_i));
|
apply_token_attr(token_at(src_i));
|
||||||
}
|
}
|
||||||
addch(static_cast<unsigned char>(ch));
|
addch(static_cast<unsigned char>(ch));
|
||||||
++written;
|
++written;
|
||||||
++render_col;
|
++render_col;
|
||||||
if (from_src)
|
if (from_src)
|
||||||
++src_i;
|
++src_i;
|
||||||
if (src_i >= line.size() && written >= cols)
|
if (src_i >= line.size() && written >= cols)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hl_on) {
|
if (hl_on) {
|
||||||
attroff(A_STANDOUT);
|
attroff(A_STANDOUT);
|
||||||
hl_on = false;
|
hl_on = false;
|
||||||
}
|
}
|
||||||
if (cur_on) {
|
if (cur_on) {
|
||||||
attroff(A_BOLD);
|
attroff(A_BOLD);
|
||||||
cur_on = false;
|
cur_on = false;
|
||||||
}
|
}
|
||||||
attrset(A_NORMAL);
|
attrset(A_NORMAL);
|
||||||
clrtoeol();
|
clrtoeol();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Place terminal cursor at logical position accounting for tabs and coloffs
|
// Place terminal cursor at logical position accounting for tabs and coloffs
|
||||||
std::size_t cy = buf->Cury();
|
std::size_t cy = buf->Cury();
|
||||||
@@ -464,4 +468,4 @@ TerminalRenderer::Draw(Editor &ed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user