summaryrefslogtreecommitdiff
path: root/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'buffer.c')
-rw-r--r--buffer.c93
1 files changed, 27 insertions, 66 deletions
diff --git a/buffer.c b/buffer.c
index 56afffc..cfebcac 100644
--- a/buffer.c
+++ b/buffer.c
@@ -7,25 +7,25 @@
// this is a macro so we get -Wformat warnings
-#define buffer_seterr(buffer, ...) \
+#define buffer_error(buffer, ...) \
snprintf(buffer->error, sizeof buffer->error - 1, __VA_ARGS__)
-bool buffer_haserr(TextBuffer *buffer) {
+bool buffer_has_error(TextBuffer *buffer) {
return buffer->error[0] != '\0';
}
// returns the buffer's last error
-const char *buffer_geterr(TextBuffer *buffer) {
+const char *buffer_get_error(TextBuffer *buffer) {
return buffer->error;
}
-void buffer_clearerr(TextBuffer *buffer) {
+void buffer_clear_error(TextBuffer *buffer) {
*buffer->error = '\0';
}
// set the buffer's error to indicate that we're out of memory
static void buffer_out_of_mem(TextBuffer *buffer) {
- buffer_seterr(buffer, "Out of memory.");
+ buffer_error(buffer, "Out of memory.");
}
@@ -60,10 +60,6 @@ bool buffer_empty(TextBuffer *buffer) {
return buffer->nlines == 1 && buffer->lines[0].len == 0;
}
-const char *buffer_get_filename(TextBuffer *buffer) {
- return buffer->filename;
-}
-
bool buffer_is_untitled(TextBuffer *buffer) {
if (buffer->filename)
return streq(buffer->filename, TED_UNTITLED);
@@ -179,31 +175,20 @@ bool buffer_unsaved_changes(TextBuffer *buffer) {
return arr_len(buffer->undo_history) != buffer->undo_history_write_pos;
}
-// code point at position.
-// returns 0 if the position is invalid. note that it can also return 0 for a valid position, if there's a null character there
-char32_t buffer_char_at_pos(TextBuffer *buffer, BufferPos p) {
- if (p.line >= buffer->nlines)
- return 0; // invalid (line too large)
-
- Line *line = &buffer->lines[p.line];
- if (p.index < line->len) {
- return line->str[p.index];
- } else if (p.index > line->len) {
- // invalid (col too large)
+char32_t buffer_char_at_pos(TextBuffer *buffer, BufferPos pos) {
+ if (!buffer_pos_valid(buffer, pos))
return 0;
- } else {
- return '\n';
- }
+
+ Line *line = &buffer->lines[pos.line];
+ return line->str[pos.index];
}
-// 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];
@@ -211,12 +196,10 @@ char32_t buffer_char_after_pos(TextBuffer *buffer, BufferPos pos) {
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);
}
@@ -345,10 +328,6 @@ static u64 buffer_checksum(TextBuffer *buffer) {
return sum;
}
-// Get some number of characters of text from the given position in the buffer.
-// Returns the number of characters gotten.
-// You can pass NULL for text if you just want to know how many characters *could* be accessed before the
-// end of the file.
size_t buffer_get_text_at_pos(TextBuffer *buffer, BufferPos pos, char32_t *text, size_t nchars) {
if (!buffer_pos_valid(buffer, pos)) {
return 0; // invalid position. no chars for you!
@@ -381,8 +360,6 @@ size_t buffer_get_text_at_pos(TextBuffer *buffer, BufferPos pos, char32_t *text,
return nchars - chars_left;
}
-// returns a UTF-32 string of at most `nchars` code points from `buffer` starting at `pos`
-// the string should be str32_free'd.
String32 buffer_get_str32_text_at_pos(TextBuffer *buffer, BufferPos pos, size_t nchars) {
String32 s32 = {0};
size_t len = buffer_get_text_at_pos(buffer, pos, NULL, nchars);
@@ -397,8 +374,6 @@ String32 buffer_get_str32_text_at_pos(TextBuffer *buffer, BufferPos pos, size_t
return s32;
}
-// see buffer_get_str32_text_at_pos. returns NULL on failure (out of memory)
-// the returned string should be free'd
char *buffer_get_utf8_text_at_pos(TextBuffer *buffer, BufferPos pos, size_t nchars) {
String32 s32 = buffer_get_str32_text_at_pos(buffer, pos, nchars);
char *ret = str32_to_utf8_cstr(s32);
@@ -407,9 +382,6 @@ char *buffer_get_utf8_text_at_pos(TextBuffer *buffer, BufferPos pos, size_t ncha
return ret;
}
-// Puts a UTF-8 string containing the contents of the buffer into out.
-// Returns the number of bytes, including a null terminator.
-// To use, first pass NULL for out to get the number of bytes you need to allocate.
size_t buffer_contents_utf8(TextBuffer *buffer, char *out) {
char *p = out, x[4];
size_t size = 0;
@@ -431,8 +403,6 @@ size_t buffer_contents_utf8(TextBuffer *buffer, char *out) {
return size;
}
-// Returns a UTF-8 string containing the contents of `buffer`.
-// free the return value.
char *buffer_contents_utf8_alloc(TextBuffer *buffer) {
size_t size = buffer_contents_utf8(buffer, NULL);
char *s = calloc(1, size);
@@ -537,7 +507,6 @@ static bool buffer_line_valid(Line *line) {
return true;
}
-// perform a series of checks to make sure the buffer doesn't have any invalid values
void buffer_check_valid(TextBuffer *buffer) {
assert(buffer->nlines);
buffer_pos_check_valid(buffer, buffer->cursor_pos);
@@ -847,8 +816,6 @@ static u32 buffer_column_to_index(TextBuffer *buffer, u32 line, u32 column) {
return len;
}
-// returns the number of lines of text in the buffer into *lines (if not NULL),
-// and the number of columns of text, i.e. the number of columns in the longest line displayed, into *cols (if not NULL)
void buffer_text_dimensions(TextBuffer *buffer, u32 *lines, u32 *columns) {
if (lines) {
*lines = buffer->nlines;
@@ -865,12 +832,10 @@ void buffer_text_dimensions(TextBuffer *buffer, u32 *lines, u32 *columns) {
}
-// returns the number of rows of text that can fit in the buffer
float buffer_display_lines(TextBuffer *buffer) {
return (buffer->y2 - buffer->y1) / text_font_char_height(buffer_font(buffer));
}
-// returns the number of columns of text that can fit in the buffer
float buffer_display_cols(TextBuffer *buffer) {
return (buffer->x2 - buffer->x1) / text_font_char_width(buffer_font(buffer));
}
@@ -905,7 +870,6 @@ void buffer_scroll(TextBuffer *buffer, double dx, double dy) {
buffer_correct_scroll(buffer);
}
-// returns the position of the character at the given position in the buffer.
vec2 buffer_pos_to_pixels(TextBuffer *buffer, BufferPos pos) {
buffer_pos_validate(buffer, &pos);
u32 line = pos.line, index = pos.index;
@@ -917,8 +881,6 @@ vec2 buffer_pos_to_pixels(TextBuffer *buffer, BufferPos pos) {
return Vec2(x, y);
}
-// convert pixel coordinates to a position in the buffer, selecting the closest character.
-// returns false if the position is not inside the buffer, but still sets *pos to the closest character.
bool buffer_pixels_to_pos(TextBuffer *buffer, vec2 pixel_coords, BufferPos *pos) {
bool ret = true;
float x = pixel_coords.x, y = pixel_coords.y;
@@ -1005,7 +967,6 @@ void buffer_scroll_to_pos(TextBuffer *buffer, BufferPos pos) {
buffer_correct_scroll(buffer); // it's possible that min/max_scroll_x/y go too far
}
-// scroll in such a way that this position is in the center of the screen
void buffer_scroll_center_pos(TextBuffer *buffer, BufferPos pos) {
double line = pos.line;
double col = buffer_index_to_column(buffer, pos.line, pos.index);
@@ -1551,7 +1512,7 @@ BufferPos buffer_insert_text_at_pos(TextBuffer *buffer, BufferPos pos, String32
if (buffer->view_only)
return pos;
if (str.len > U32_MAX) {
- buffer_seterr(buffer, "Inserting too much text (length: %zu).", str.len);
+ buffer_error(buffer, "Inserting too much text (length: %zu).", str.len);
BufferPos ret = {0,0};
return ret;
}
@@ -1840,7 +1801,7 @@ static void buffer_delete_lines(TextBuffer *buffer, u32 first_line_idx, u32 nlin
void buffer_delete_chars_at_pos(TextBuffer *buffer, BufferPos pos, i64 nchars_) {
if (buffer->view_only) return;
if (nchars_ < 0) {
- buffer_seterr(buffer, "Deleting negative characters (specifically, " I64_FMT ").", nchars_);
+ buffer_error(buffer, "Deleting negative characters (specifically, " I64_FMT ").", nchars_);
return;
}
if (nchars_ <= 0) return;
@@ -2247,7 +2208,7 @@ void buffer_copy_or_cut(TextBuffer *buffer, bool cut) {
int err = SDL_SetClipboardText(text);
free(text);
if (err < 0) {
- buffer_seterr(buffer, "Couldn't set clipboard contents: %s", SDL_GetError());
+ buffer_error(buffer, "Couldn't set clipboard contents: %s", SDL_GetError());
} else {
// text copied successfully
if (cut) {
@@ -2302,10 +2263,10 @@ Status buffer_load_file(TextBuffer *buffer, const char *filename) {
u32 max_file_size_view_only = default_settings->max_file_size_view_only;
if (file_pos == -1 || file_pos == LONG_MAX) {
- buffer_seterr(buffer, "Couldn't get file position. There is something wrong with the file '%s'.", filename);
+ buffer_error(buffer, "Couldn't get file position. There is something wrong with the file '%s'.", filename);
success = false;
} else if (file_size > max_file_size_editable && file_size > max_file_size_view_only) {
- buffer_seterr(buffer, "File too big (size: %zu).", file_size);
+ buffer_error(buffer, "File too big (size: %zu).", file_size);
success = false;
} else {
u8 *file_contents = buffer_calloc(buffer, 1, file_size + 2);
@@ -2335,7 +2296,7 @@ Status buffer_load_file(TextBuffer *buffer, const char *filename) {
} else if (n >= (size_t)(-2)) {
// invalid UTF-8
success = false;
- buffer_seterr(buffer, "Invalid UTF-8 (position: %td).", p - file_contents);
+ buffer_error(buffer, "Invalid UTF-8 (position: %td).", p - file_contents);
break;
} else {
p += n;
@@ -2351,7 +2312,7 @@ Status buffer_load_file(TextBuffer *buffer, const char *filename) {
}
}
} else {
- buffer_seterr(buffer, "Error reading from file.");
+ buffer_error(buffer, "Error reading from file.");
success = false;
}
if (!success) {
@@ -2394,7 +2355,7 @@ Status buffer_load_file(TextBuffer *buffer, const char *filename) {
}
fclose(fp);
} else {
- buffer_seterr(buffer, "Couldn't open file %s: %s.", filename, strerror(errno));
+ buffer_error(buffer, "Couldn't open file %s: %s.", filename, strerror(errno));
success = false;
}
return success;
@@ -2422,7 +2383,7 @@ void buffer_reload(TextBuffer *buffer) {
// has this buffer been changed by another program since last save?
bool buffer_externally_changed(TextBuffer *buffer) {
- if (!buffer->filename || buffer_is_untitled(buffer))
+ if (!buffer_is_named_file(buffer))
return false;
return buffer->last_write_time != timespec_to_seconds(time_last_modified(buffer->filename));
}
@@ -2444,7 +2405,7 @@ bool buffer_save(TextBuffer *buffer) {
if (!buffer->is_line_buffer && buffer->filename) {
if (buffer->view_only) {
- buffer_seterr(buffer, "Can't save view-only file.");
+ buffer_error(buffer, "Can't save view-only file.");
return false;
}
@@ -2467,7 +2428,7 @@ bool buffer_save(TextBuffer *buffer) {
size_t bytes = unicode_utf32_to_utf8(utf8, *p);
if (bytes != (size_t)-1) {
if (fwrite(utf8, 1, bytes, out) != bytes) {
- buffer_seterr(buffer, "Couldn't write to %s.", buffer->filename);
+ buffer_error(buffer, "Couldn't write to %s.", buffer->filename);
}
}
}
@@ -2477,15 +2438,15 @@ bool buffer_save(TextBuffer *buffer) {
}
}
if (ferror(out)) {
- if (!buffer_haserr(buffer))
- buffer_seterr(buffer, "Couldn't write to %s.", buffer->filename);
+ if (!buffer_has_error(buffer))
+ buffer_error(buffer, "Couldn't write to %s.", buffer->filename);
}
if (fclose(out) != 0) {
- if (!buffer_haserr(buffer))
- buffer_seterr(buffer, "Couldn't close file %s.", buffer->filename);
+ if (!buffer_has_error(buffer))
+ buffer_error(buffer, "Couldn't close file %s.", buffer->filename);
}
buffer->last_write_time = timespec_to_seconds(time_last_modified(buffer->filename));
- bool success = !buffer_haserr(buffer);
+ bool success = !buffer_has_error(buffer);
if (success) {
buffer->undo_history_write_pos = arr_len(buffer->undo_history);
const char *name = buffer->filename ? path_filename(buffer->filename) : TED_UNTITLED;
@@ -2495,7 +2456,7 @@ bool buffer_save(TextBuffer *buffer) {
}
return success;
} else {
- buffer_seterr(buffer, "Couldn't open file %s for writing: %s.", buffer->filename, strerror(errno));
+ buffer_error(buffer, "Couldn't open file %s for writing: %s.", buffer->filename, strerror(errno));
return false;
}
} else {