summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--buffer.c57
-rw-r--r--colors.h3
-rw-r--r--gl.c1
-rw-r--r--main.c2
-rw-r--r--syntax.c26
-rw-r--r--ted.cfg2
7 files changed, 92 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index f51aa9b..b049cd4 100644
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,8 @@ ALL_CFLAGS=$(CFLAGS) -Wall -Wextra -Wshadow -Wconversion -Wpedantic -pedantic -s
-Wno-unused-function -Wno-fixed-enum-extension -Wimplicit-fallthrough -Wno-format-truncation -Wno-unknown-warning-option
LIBS=-lSDL2 -lGL -ldl -lm libpcre2-32.a -Ipcre2-10.36/build
DEBUG_CFLAGS=$(ALL_CFLAGS) -DDEBUG -O0 -g
-RELEASE_CFLAGS=$(ALL_CFLAGS) -O3
-PROFILE_CFLAGS=$(ALL_CFLAGS) -O3 -DPROFILE=1
+RELEASE_CFLAGS=$(ALL_CFLAGS) -O3 -g
+PROFILE_CFLAGS=$(ALL_CFLAGS) -O3 -g -DPROFILE=1
GLOBAL_DATA_DIR=/usr/share/ted
LOCAL_DATA_DIR=/home/`logname`/.local/share/ted
INSTALL_BIN_DIR=/usr/bin
diff --git a/buffer.c b/buffer.c
index 78d5191..3f7e521 100644
--- a/buffer.c
+++ b/buffer.c
@@ -160,6 +160,31 @@ char32_t buffer_char_at_pos(TextBuffer *buffer, BufferPos p) {
}
}
+// returns 0 if pos is at the start of a line
+char32_t buffer_char_before_pos(TextBuffer *buffer, BufferPos pos) {
+ assert(buffer_pos_valid(buffer, pos));
+ if (pos.index == 0) return 0;
+ return buffer->lines[pos.line].str[pos.index - 1];
+}
+
+// returns 0 if pos is at the end of a line (unlike buffer_char_at_pos)
+char32_t buffer_char_after_pos(TextBuffer *buffer, BufferPos pos) {
+ assert(buffer_pos_valid(buffer, pos));
+ Line *line = &buffer->lines[pos.line];
+ if (pos.index >= line->len) return 0;
+ return line->str[pos.index];
+}
+
+// returns the character to the left of the cursor, or 0 if the cursor at the start of the line.
+char32_t buffer_char_before_cursor(TextBuffer *buffer) {
+ return buffer_char_before_pos(buffer, buffer->cursor_pos);
+}
+
+// returns 0 if cursor is at end of line
+char32_t buffer_char_after_cursor(TextBuffer *buffer) {
+ return buffer_char_after_pos(buffer, buffer->cursor_pos);
+}
+
BufferPos buffer_start_of_file(TextBuffer *buffer) {
(void)buffer;
return (BufferPos){.line = 0, .index = 0};
@@ -2184,12 +2209,42 @@ void buffer_render(TextBuffer *buffer, Rect r) {
double t = fmod(absolute_time, period);
is_on = t < time_on; // are we in the "on" part of the period?
}
+
+ // highlight matching brackets
+ char32_t cursor_bracket = buffer_char_before_cursor(buffer);
+ char32_t matching_bracket = syntax_matching_bracket(language, cursor_bracket);
+ if (cursor_bracket && matching_bracket) {
+ int direction = syntax_is_opening_bracket(language, cursor_bracket) ? +1 : -1;
+ int depth = 1;
+ BufferPos pos = buffer->cursor_pos;
+ buffer_pos_move_left(buffer, &pos, 1);
+ while (pos.line >= start_line) {
+ if (buffer_pos_move_right(buffer, &pos, direction)) {
+ char32_t c = buffer_char_after_pos(buffer, pos);
+ if (c == cursor_bracket) depth += 1;
+ else if (c == matching_bracket) depth -= 1;
+ if (depth == 0) break;
+ } else {
+ break;
+ }
+ }
+ if (depth == 0) {
+ // highlight it
+ v2 gl_pos = buffer_pos_to_pixels(buffer, pos);
+ Rect hl_rect = rect(gl_pos, V2(char_width, char_height));
+ if (buffer_clip_rect(buffer, &hl_rect)) {
+ gl_geometry_rect(hl_rect, colors[COLOR_MATCHING_BRACKET_HL]);
+ }
+ }
+ }
+
+
if (is_on) {
if (buffer_clip_rect(buffer, &cursor_rect)) {
gl_geometry_rect(cursor_rect, colors[COLOR_CURSOR]);
- gl_geometry_draw();
}
}
+ gl_geometry_draw();
}
}
diff --git a/colors.h b/colors.h
index 1512aef..43becf1 100644
--- a/colors.h
+++ b/colors.h
@@ -7,6 +7,7 @@ ENUM_U16 {
COLOR_HL,
COLOR_CURSOR,
COLOR_CURSOR_LINE_BG,
+ COLOR_MATCHING_BRACKET_HL,
COLOR_BORDER,
COLOR_TEXT_FOLDER,
COLOR_TEXT_OTHER,
@@ -35,6 +36,7 @@ ENUM_U16 {
COLOR_LINE_NUMBERS,
COLOR_CURSOR_LINE_NUMBER,
COLOR_LINE_NUMBERS_SEPARATOR,
+
COLOR_COUNT
} ENUM_U16_END(ColorSetting);
@@ -52,6 +54,7 @@ static ColorName const color_names[COLOR_COUNT] = {
{COLOR_HL, "hl"},
{COLOR_CURSOR, "cursor"},
{COLOR_CURSOR_LINE_BG, "cursor-line-bg"},
+ {COLOR_MATCHING_BRACKET_HL, "matching-bracket-hl"},
{COLOR_BORDER, "border"},
{COLOR_TEXT_FOLDER, "text-folder"},
{COLOR_TEXT_OTHER, "text-other"},
diff --git a/gl.c b/gl.c
index a9850cd..9a35a1f 100644
--- a/gl.c
+++ b/gl.c
@@ -222,6 +222,7 @@ static void gl_geometry_rect_border(Rect r, float border_thickness, u32 color) {
static void gl_geometry_draw(void) {
size_t ntriangles = arr_len(gl_geometry_triangles);
+ if (ntriangles == 0) return;
// convert coordinates to NDC
for (size_t i = 0; i < ntriangles; ++i) {
diff --git a/main.c b/main.c
index 3af8a89..ef3b9dd 100644
--- a/main.c
+++ b/main.c
@@ -4,6 +4,8 @@
// - completion
// - view-only
// - Windows installation
+// - restore previously opened files (setting: restore-session)
+// - on crash, output backtrace to log, save buffers to temp directory
#include "base.h"
no_warn_start
diff --git a/syntax.c b/syntax.c
index 01e6b7d..26ce234 100644
--- a/syntax.c
+++ b/syntax.c
@@ -45,6 +45,32 @@ static inline bool syntax_keyword_matches(char32_t *text, size_t len, char const
}
}
+// returns ')' for '(', etc., or 0 if c is not an opening bracket
+char32_t syntax_matching_bracket(Language lang, char32_t c) {
+ (void)lang; // not needed yet
+ switch (c) {
+ case '(': return ')';
+ case ')': return '(';
+ case '[': return ']';
+ case ']': return '[';
+ case '{': return '}';
+ case '}': return '{';
+ }
+ return 0;
+}
+
+// returns true for opening brackets, false for closing brackets/non-brackets
+bool syntax_is_opening_bracket(Language lang, char32_t c) {
+ (void)lang;
+ switch (c) {
+ case '(':
+ case '[':
+ case '{':
+ return true;
+ }
+ return false;
+}
+
// lookup the given string in the keywords table
static Keyword const *syntax_keyword_lookup(Keyword const *const *all_keywords, size_t n_all_keywords, char32_t *str, size_t len) {
if (!len) return NULL;
diff --git a/ted.cfg b/ted.cfg
index 60b9929..69b2aa4 100644
--- a/ted.cfg
+++ b/ted.cfg
@@ -116,6 +116,8 @@ border = #a77
active-tab-hl = #a77a
cursor-line-bg = #222
cursor = #3ff
+# color to highlight matching brackets with
+matching-bracket-hl = #fda8
selection-bg = #36aa
hl = #ccc
text = #fff