summaryrefslogtreecommitdiff
path: root/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'buffer.c')
-rw-r--r--buffer.c114
1 files changed, 110 insertions, 4 deletions
diff --git a/buffer.c b/buffer.c
index f1e8047..3f94cf1 100644
--- a/buffer.c
+++ b/buffer.c
@@ -8,6 +8,12 @@
#define BUFFER_UNTITLED "Untitled" // what to call untitled buffers
+/// A single line in a buffer
+typedef struct Line Line;
+
+/// A single undoable edit to a buffer
+typedef struct BufferEdit BufferEdit;
+
struct Line {
SyntaxState syntax;
u32 len;
@@ -24,6 +30,87 @@ struct BufferEdit {
double time; // time at start of edit (i.e. the time just before the edit), in seconds since epoch
};
+struct TextBuffer {
+ /// NULL if this buffer is untitled or doesn't correspond to a file (e.g. line buffers)
+ char *path;
+ /// we keep a back-pointer to the ted instance so we don't have to pass it in to every buffer function
+ Ted *ted;
+ /// number of characters scrolled in the x direction (multiply by space width to get pixels)
+ double scroll_x;
+ /// number of characters scrolled in the y direction
+ double scroll_y;
+ /// last write time to \ref path
+ double last_write_time;
+ /// the language the buffer has been manually set to, or \ref LANG_NONE if it hasn't been set to anything
+ i64 manual_language;
+ /// position of cursor
+ BufferPos cursor_pos;
+ /// if \ref selection is true, the text between \ref selection_pos and \ref cursor_pos is selected.
+ BufferPos selection_pos;
+ /// "previous" position of cursor, for \ref CMD_PREVIOUS_POSITION
+ BufferPos prev_cursor_pos;
+ /// "line buffers" are buffers which can only have one line of text (used for inputs)
+ bool is_line_buffer;
+ /// is anything selected?
+ bool selection;
+ /// set to false to disable undo events
+ bool store_undo_events;
+ /// will the next undo event be chained with the ones after?
+ bool will_chain_edits;
+ /// will the next undo event be chained with the previous one?
+ bool chaining_edits;
+ /// view-only mode
+ bool view_only;
+ /// (line buffers only) set to true when submitted. you have to reset it to false.
+ bool line_buffer_submitted;
+ /// If set to true, buffer will be scrolled to the cursor position next frame.
+ /// This is to fix the problem that \ref x1, \ref y1, \ref x2, \ref y2 are not updated until the buffer is rendered.
+ bool center_cursor_next_frame;
+ /// x coordinate of left side of buffer
+ float x1;
+ /// y coordinate of top side of buffer
+ float y1;
+ /// x coordinate of right side of buffer
+ float x2;
+ /// y coordinate of bottom side of buffer
+ float y2;
+ /// number of lines in buffer
+ u32 nlines;
+ /// capacity of \ref lines
+ u32 lines_capacity;
+
+ /// cached settings index (into ted->all_settings), or -1 if has not been computed yet
+ i32 settings_idx;
+
+ /// which LSP this document is open in
+ LSPID lsp_opened_in;
+ /// determining which LSP to use for a buffer takes some work,
+ /// so we don't want to do it every single frame.
+ /// this keeps track of the last time we actually checked what the correct LSP is.
+ double last_lsp_check;
+
+ /// where in the undo history was the last write? used by \ref buffer_unsaved_changes
+ u32 undo_history_write_pos;
+ /// which lines are on screen? updated when \ref buffer_render is called.
+ u32 first_line_on_screen, last_line_on_screen;
+
+ /// to cache syntax highlighting properly, it is important to keep track of the
+ /// first and last line modified since last frame.
+ u32 frame_earliest_line_modified;
+ /// see \ref frame_earliest_line_modified.
+ u32 frame_latest_line_modified;
+
+ /// lines
+ Line *lines;
+ /// last error
+ char error[256];
+ /// dynamic array of undo history
+ BufferEdit *undo_history;
+ /// dynamic array of redo history
+ BufferEdit *redo_history;
+};
+
+
// this is a macro so we get -Wformat warnings
#define buffer_error(buffer, ...) \
snprintf(buffer->error, sizeof buffer->error - 1, __VA_ARGS__)
@@ -82,6 +169,17 @@ bool buffer_is_named_file(TextBuffer *buffer) {
return buffer->path != NULL;
}
+bool buffer_is_line_buffer(TextBuffer *buffer) {
+ return buffer->is_line_buffer;
+}
+
+bool line_buffer_is_submitted(TextBuffer *buffer) {
+ return buffer->is_line_buffer && buffer->line_buffer_submitted;
+}
+
+void line_buffer_clear_submitted(TextBuffer *buffer) {
+ buffer->line_buffer_submitted = false;
+}
bool buffer_is_view_only(TextBuffer *buffer) {
return buffer->view_only;
@@ -107,6 +205,10 @@ BufferPos buffer_cursor_pos(TextBuffer *buffer) {
return buffer->cursor_pos;
}
+bool buffer_has_selection(TextBuffer *buffer) {
+ return buffer->selection;
+}
+
bool buffer_selection_pos(TextBuffer *buffer, BufferPos *pos) {
if (buffer->selection) {
if (pos) *pos = buffer->selection_pos;
@@ -1107,7 +1209,10 @@ void buffer_scroll_to_cursor(TextBuffer *buffer) {
buffer_scroll_to_pos(buffer, buffer->cursor_pos);
}
-// scroll so that the cursor is in the center of the screen
+void buffer_set_manual_language(TextBuffer *buffer, u32 language) {
+ buffer->manual_language = language;
+}
+
void buffer_center_cursor(TextBuffer *buffer) {
double cursor_line = buffer->cursor_pos.line;
double cursor_col = buffer_index_to_xoff(buffer, (u32)cursor_line, buffer->cursor_pos.index)
@@ -1121,6 +1226,10 @@ void buffer_center_cursor(TextBuffer *buffer) {
buffer_correct_scroll(buffer);
}
+void buffer_center_cursor_next_frame(TextBuffer *buffer) {
+ buffer->center_cursor_next_frame = true;
+}
+
// move left (if `by` is negative) or right (if `by` is positive) by the specified amount.
// returns the signed number of characters successfully moved (it could be less in magnitude than `by` if the beginning of the file is reached)
static i64 buffer_pos_move_horizontally(TextBuffer *buffer, BufferPos *p, i64 by) {
@@ -1549,7 +1658,6 @@ void buffer_cursor_move_to_end_of_file(TextBuffer *buffer) {
static void buffer_lines_modified(TextBuffer *buffer, u32 first_line, u32 last_line) {
assert(last_line >= first_line);
- buffer->modified = true;
if (first_line < buffer->frame_earliest_line_modified)
buffer->frame_earliest_line_modified = first_line;
if (last_line > buffer->frame_latest_line_modified)
@@ -2606,8 +2714,6 @@ void buffer_redo(TextBuffer *buffer, i64 ntimes) {
// buffer_end_edit_chain(buffer)
// pressing ctrl+z will undo both the insertion of text1 and text2.
void buffer_start_edit_chain(TextBuffer *buffer) {
- assert(!buffer->chaining_edits);
- assert(!buffer->will_chain_edits);
buffer->will_chain_edits = true;
}