From 63f54d13aa7233986f784ef857faef259a889ed6 Mon Sep 17 00:00:00 2001 From: pommicket Date: Thu, 23 Mar 2023 13:22:16 -0400 Subject: go-to-build-error now also detects rust ::: references --- buffer.c | 3 +++ build.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- main.c | 2 -- ted.h | 8 +++++++- 4 files changed, 58 insertions(+), 7 deletions(-) diff --git a/buffer.c b/buffer.c index 3f25142..c440ed4 100644 --- a/buffer.c +++ b/buffer.c @@ -308,6 +308,9 @@ bool buffer_indent_with_spaces(TextBuffer *buffer) { } String32 buffer_get_line(TextBuffer *buffer, u32 line_number) { + if (line_number >= buffer->nlines) { + return str32(NULL, 0); + } Line *line = &buffer->lines[line_number]; return (String32) { .str = line->str, .len = line->len diff --git a/build.c b/build.c index 0311b09..9d7e3ad 100644 --- a/build.c +++ b/build.c @@ -118,8 +118,35 @@ static void build_go_to_error(Ted *ted) { if (ted_open_file(ted, error.path)) { TextBuffer *buffer = ted->active_buffer; assert(buffer); + + u32 index = error.column; + + if (error.columns_per_tab > 1) { + // get correct index + String32 line = buffer_get_line(buffer, error.line); + u32 column = 0; + index = 0; + while (column < error.column) { + if (index >= line.len) + break; + if (line.str[index] == '\t') { + column += error.columns_per_tab; + } else { + column += 1; + } + ++index; + } + } + + + BufferPos pos = { + .line = error.line, + .index = index, + }; + + // move cursor to error - buffer_cursor_move_to_pos(buffer, error.pos); + buffer_cursor_move_to_pos(buffer, pos); buffer->center_cursor_next_frame = true; // move cursor to error in build output @@ -180,16 +207,30 @@ void build_check_for_errors(Ted *ted) { continue; } bool is_error = true; + // well, for a bit of time i thought rust was weird + // and treated tabs as 4 columns + // apparently its just a bug, which ive filed here + // https://github.com/rust-lang/rust/issues/109537 + // we could treat ::: references as 4-columns-per-tab, + // but then that would be wrong if the bug gets fixed. + // all this is to say that columns_per_tab is currently always 1, + // but might be useful at some point. + u8 columns_per_tab = 1; char32_t *p = line->str, *end = p + line->len; { // rust errors look like: // " --> file:line:column" + // and can also include stuff like + // " ::: file:line:column" while (p != end && *p == ' ') { ++p; } - if (end - p >= 4 && p[0] == '-' && p[1] == '-' && p[2] == '>' && p[3] == ' ') { - p += 4; + if (end - p >= 4) { + String32 first4 = str32(p, 4); + if (str32_cmp_ascii(first4, "::: ") == 0 || str32_cmp_ascii(first4, "--> ") == 0) { + p += 4; + } } } @@ -243,9 +284,12 @@ void build_check_for_errors(Ted *ted) { pfilename += 3; path_full(ted->build_dir, pfilename, full_path, sizeof full_path); } + BuildError error = { .path = str_dup(full_path), - .pos = {.line = (u32)line_number, .index = (u32)column_number}, + .line = (u32)line_number, + .column = (u32)column_number, + .columns_per_tab = columns_per_tab, .build_output_line = line_idx }; arr_add(ted->build_errors, error); diff --git a/main.c b/main.c index 4f17e77..d3cdbed 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,4 @@ /* -@TODO: -- some rust error locations arent detected? FUTURE FEATURES: - better undo chaining (dechain on backspace?) - font setting & support for multiple fonts to cover more characters diff --git a/ted.h b/ted.h index 79bab2f..2e935ff 100644 --- a/ted.h +++ b/ted.h @@ -531,7 +531,12 @@ typedef struct { typedef struct { char *path; - BufferPos pos; + u32 line; + u32 column; + /// if this is 1, then column == UTF-32 index. + /// if this is 4, for example, then column 4 in a line starting with a tab would + /// be the character right after the tab. + u8 columns_per_tab; /// which line in the build output corresponds to this error u32 build_output_line; } BuildError; @@ -914,6 +919,7 @@ u8 buffer_tab_width(TextBuffer *buffer); bool buffer_indent_with_spaces(TextBuffer *buffer); /// NOTE: this string will be invalidated when the line is edited!!! /// only use it briefly!! +/// returns an empty string if `line_number` is out of range. String32 buffer_get_line(TextBuffer *buffer, u32 line_number); /// get at most `nchars` characters starting from position `pos`. /// returns the number of characters actually available. -- cgit v1.2.3