summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2021-02-16 15:38:59 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2021-02-16 15:38:59 -0500
commit4b8db533619ee8eef64ded0793f413faaa7609c2 (patch)
tree8b3f158897ae2ff2f3e8f78ad0712bc4b40b328f
parent824c4ff4be5a0bf55b6644fed06fcfe2248c4301 (diff)
detecting errors in build output
-rw-r--r--buffer.c33
-rw-r--r--build.c60
-rw-r--r--find.c12
-rw-r--r--main.c33
-rw-r--r--ted.c29
-rw-r--r--ted.h11
6 files changed, 137 insertions, 41 deletions
diff --git a/buffer.c b/buffer.c
index eeadff0..6d5b211 100644
--- a/buffer.c
+++ b/buffer.c
@@ -2085,6 +2085,38 @@ void buffer_render(TextBuffer *buffer, Rect r) {
buffer->x1 = x1; buffer->y1 = y1; buffer->x2 = x2; buffer->y2 = y2;
+ // handle mouse clicks
+ for (u32 i = 0; i < ted->nmouse_clicks[SDL_BUTTON_LEFT]; ++i) {
+ v2 point = ted->mouse_clicks[SDL_BUTTON_LEFT][i];
+ u8 times = ted->mouse_click_times[SDL_BUTTON_LEFT][i];
+ BufferPos pos;
+ if (buffer_pixels_to_pos(buffer, point, &pos)) {
+ // user clicked on buffer
+ if (!ted->menu)
+ ted->active_buffer = buffer;
+ if (buffer == ted->active_buffer) {
+ buffer_cursor_move_to_pos(buffer, pos);
+
+ switch ((times - 1) % 3) {
+ case 0: break; // single-click
+ case 1: // double-click: select word
+ buffer_select_word(buffer);
+ break;
+ case 2: // triple-click: select line
+ buffer_select_line(buffer);
+ break;
+ }
+ ted->drag_buffer = buffer;
+ }
+ }
+ }
+
+ if (rect_contains_point(rect4(x1, y1, x2, y2), ted->mouse_pos)) {
+ // scroll with mouse wheel
+ double scroll_speed = 2.5;
+ buffer_scroll(buffer, ted->scroll_total_x * scroll_speed, ted->scroll_total_y * scroll_speed);
+ }
+
// get screen coordinates of cursor
v2 cursor_display_pos = buffer_pos_to_pixels(buffer, buffer->cursor_pos);
// the rectangle that the cursor is rendered as
@@ -2283,6 +2315,7 @@ void buffer_render(TextBuffer *buffer, Rect r) {
}
gl_geometry_draw();
}
+
}
// if you do:
diff --git a/build.c b/build.c
index 0afee56..6b439e2 100644
--- a/build.c
+++ b/build.c
@@ -1,4 +1,5 @@
static void build_start(Ted *ted) {
+ chdir(ted->cwd);
#if __unix__
char *program = "/bin/sh";
char *argv[] = {
@@ -19,6 +20,9 @@ static void build_start(Ted *ted) {
static void build_stop(Ted *ted) {
if (ted->building)
process_kill(&ted->build_process);
+ arr_foreach_ptr(ted->build_errors, BuildError, err) {
+ free(err->filename);
+ }
ted->building = false;
ted->build_shown = false;
}
@@ -89,6 +93,62 @@ static void build_frame(Ted *ted, float x1, float y1, float x2, float y2) {
} else {
buffer_insert_utf8_at_cursor(buffer, message);
ted->building = false;
+
+ // check for errors
+ for (u32 line_idx = 0; line_idx < buffer->nlines; ++line_idx) {
+ Line *line = &buffer->lines[line_idx];
+ if (line->len < 3) {
+ continue;
+ }
+ bool is_error = true;
+ u32 i = 0;
+ char32_t *str = line->str; u32 len = line->len;
+
+ // we have something like main.c:5
+
+ // get file name
+ while (i < len) {
+ if (str[i] == ':') break;
+ if (!is32_alnum(str[i]) && str[i] != '/' && str[i] != '.' && str[i] != '\\') {
+ is_error = false;
+ break;
+ }
+ ++i;
+ }
+ if (i >= len) is_error = false;
+
+ if (is_error) {
+ u32 filename_len = i;
+ u32 line_number_len = 0;
+ ++i;
+ while (i < len) {
+ if (str[i] == ':') break;
+ if (str[i] < '0' || str[i] > '9') {
+ is_error = false;
+ break;
+ }
+ ++i;
+ ++line_number_len;
+ }
+ if (i >= len) is_error = false;
+ if (line_number_len == 0) is_error = false;
+
+ if (is_error) {
+ char *line_number_str = str32_to_utf8_cstr(str32(str + filename_len + 1, line_number_len));
+ if (line_number_str) {
+ int line_number = atoi(line_number_str);
+ free(line_number_str);
+
+ char *filename = str32_to_utf8_cstr(str32(str, filename_len));
+ if (filename) {
+ char full_path[TED_PATH_MAX];
+ ted_full_path(ted, filename, full_path, sizeof full_path);
+ printf("File %s line %d\n",full_path,line_number);
+ }
+ }
+ }
+ }
+ }
}
buffer->view_only = true;
}
diff --git a/find.c b/find.c
index 2612577..12455bd 100644
--- a/find.c
+++ b/find.c
@@ -413,18 +413,6 @@ static void find_menu_frame(Ted *ted, float x1, float y1, float x2, float y2) {
x += checkbox_frame(ted, &ted->find_case_sensitive, "Case sensitive", V2(x, y1)).x + 2*padding;
x += checkbox_frame(ted, &ted->find_regex, "Regular expression", V2(x, y1)).x + 2*padding;
- if (replace) {
- // check if the find or replace line buffer was clicked on
- for (u32 i = 0; i < ted->nmouse_clicks[SDL_BUTTON_LEFT]; ++i) {
- v2 point = ted->mouse_clicks[SDL_BUTTON_LEFT][i];
- if (rect_contains_point(find_buffer_bounds, point))
- ted->active_buffer = find_buffer;
- else if (rect_contains_point(replace_buffer_bounds, point))
- ted->active_buffer = replace_buffer;
-
- }
- }
-
buffer_render(find_buffer, find_buffer_bounds);
if (replace) buffer_render(replace_buffer, replace_buffer_bounds);
diff --git a/main.c b/main.c
index f2f5ec7..09009f5 100644
--- a/main.c
+++ b/main.c
@@ -412,9 +412,6 @@ int main(int argc, char **argv) {
Sint32 dx = event.wheel.x, dy = -event.wheel.y;
ted->scroll_total_x += dx;
ted->scroll_total_y += dy;
- double scroll_speed = 2.5;
- if (ted->active_buffer)
- buffer_scroll(ted->active_buffer, dx * scroll_speed, dy * scroll_speed);
} break;
case SDL_MOUSEBUTTONDOWN: {
Uint32 button = event.button.button;
@@ -435,33 +432,11 @@ int main(int argc, char **argv) {
add = false;
}
}
- if (add)
- ted->mouse_clicks[button][ted->nmouse_clicks[button]++] = pos;
- }
- switch (button) {
- case SDL_BUTTON_LEFT: {
- if (buffer) {
- BufferPos pos = {0};
- if (buffer_pixels_to_pos(buffer, V2(x, y), &pos)) {
- if (key_modifier == KEY_MODIFIER_SHIFT) {
- buffer_select_to_pos(buffer, pos);
- } else if (key_modifier == 0) {
- buffer_cursor_move_to_pos(buffer, pos);
- switch ((event.button.clicks - 1) % 3) {
- case 0: break; // single-click
- case 1: // double-click: select word
- buffer_select_word(buffer);
- break;
- case 2: // triple-click: select line
- buffer_select_line(buffer);
- break;
- }
- }
- ted->drag_buffer = buffer;
-
- }
+ if (add) {
+ ted->mouse_clicks[button][ted->nmouse_clicks[button]] = pos;
+ ted->mouse_click_times[button][ted->nmouse_clicks[button]] = event.button.clicks;
+ ++ted->nmouse_clicks[button];
}
- } break;
}
} break;
case SDL_MOUSEMOTION: {
diff --git a/ted.c b/ted.c
index a1cbed5..94505df 100644
--- a/ted.c
+++ b/ted.c
@@ -262,3 +262,32 @@ static bool ted_save_all(Ted *ted) {
}
return success;
}
+
+static void ted_full_path(Ted *ted, char const *relpath, char *abspath, size_t abspath_size) {
+ str_cpy(abspath, abspath_size, ted->cwd);
+
+ while (1) {
+ size_t component_len = strcspn(relpath, ALL_PATH_SEPARATORS);
+ char const *component_end = relpath + component_len;
+
+ size_t len = strlen(abspath);
+ if (abspath[len - 1] != PATH_SEPARATOR)
+ str_cat(abspath, abspath_size, PATH_SEPARATOR_STR);
+ if (component_len == 1 && relpath[0] == '.') {
+ // ., do nothing
+ } else if (component_len == 2 && relpath[0] == '.' && relpath[1] == '.') {
+ // ..
+ char *lastsep = strrchr(abspath, PATH_SEPARATOR);
+ if (lastsep == abspath)
+ lastsep[1] = '\0';
+ else
+ lastsep[0] = '\0';
+ } else {
+ strn_cat(abspath, abspath_size, relpath, component_len);
+ }
+ if (*component_end == 0)
+ break;
+ else
+ relpath = component_end + 1;
+ }
+}
diff --git a/ted.h b/ted.h
index 32a41c1..3278e73 100644
--- a/ted.h
+++ b/ted.h
@@ -202,6 +202,12 @@ typedef struct {
BufferPos end;
} FindResult;
+typedef struct {
+ char *filename;
+ u32 line;
+ u32 build_output_line; // which line in the build output corresponds to this error
+} BuildError;
+
typedef struct Ted {
SDL_Window *window;
Font *font_bold;
@@ -219,6 +225,8 @@ typedef struct Ted {
v2 mouse_pos;
u8 nmouse_clicks[4]; // nmouse_clicks[i] = length of mouse_clicks[i]
v2 mouse_clicks[4][32]; // mouse_clicks[SDL_BUTTON_RIGHT], for example, is all the right mouse-clicks that have happened this frame
+ // number of times mouse was clicked at each position
+ u8 mouse_click_times[4][32];
int scroll_total_x, scroll_total_y; // total amount scrolled in the x and y direction this frame
Menu menu;
FileSelector file_selector;
@@ -241,6 +249,9 @@ typedef struct Ted {
Command warn_unsaved; // if non-zero, the user is trying to execute this command, but there are unsaved changes
bool build_shown; // are we showing the build output?
bool building; // is the build process running?
+
+ BuildError *build_errors; // dynamic array of build errors
+
Process build_process;
// When we read the stdout from the build process, the tail end of the read could be an
// incomplete UTF-8 code point. This is where we store that "tail end" until more