buffer.h (10999B)
1 #ifndef _LEDIT_BUFFER_H_ 2 #define _LEDIT_BUFFER_H_ 3 4 #include <time.h> 5 #include <stdio.h> 6 #include <stddef.h> 7 8 #include "common.h" 9 #include "txtbuf.h" 10 #include "undo.h" 11 12 typedef struct ledit_buffer ledit_buffer; 13 14 #include "view.h" 15 16 typedef struct { 17 ledit_buffer *parent_buffer; 18 char *text; /* text, stored as gap buffer */ 19 size_t gap; /* position of gap for gap buffer */ 20 size_t cap; /* allocated space for text */ 21 size_t len; /* actual length of text */ 22 } ledit_line; 23 24 typedef struct { 25 char *text; 26 size_t line; 27 size_t byte; 28 } ledit_buffer_mark; 29 30 typedef struct { 31 size_t len, alloc; 32 ledit_buffer_mark *marks; 33 } ledit_buffer_marklist; 34 35 /* TODO: advisory lock on file */ 36 struct ledit_buffer { 37 ledit_common *common; /* common stuff, e.g. display, etc. - this doesn't really belong here */ 38 ledit_clipboard *clipboard; /* this also doesn't really belong here */ 39 /* FIXME: add some sort of manager that holds shared stuff like clipboard and manages the buffer and views */ 40 char *filename; /* last opened filename */ 41 struct timespec file_mtime; /* last modified time of file */ 42 undo_stack *undo; /* undo manager */ 43 ledit_buffer_marklist *marklist; /* list of mark positions set */ 44 ledit_line *lines; /* array of lines */ 45 ledit_view **views; /* array of registered views */ 46 size_t views_num; /* number of views in array */ 47 size_t lines_cap; /* size of lines array */ 48 size_t lines_gap; /* position of gap for line gap buffer */ 49 size_t lines_num; /* number of lines */ 50 int modified; /* whether buffer was modified since loading a file */ 51 int hard_line_based; /* whether operations should work on soft- or hardlines 52 Note that this doesn't actually change any behavior of 53 the buffer functions, it is just stored here so all 54 views can be updated to display it in their status. */ 55 }; 56 57 /* 58 * Create a new buffer with one empty line 59 */ 60 ledit_buffer *buffer_create(ledit_common *common, ledit_clipboard *clipboard); 61 62 /* 63 * Lock all views except the given view. 64 */ 65 void buffer_lock_all_views_except(ledit_buffer *buffer, ledit_view *view, char *lock_text); 66 67 /* 68 * Unlock all views. 69 */ 70 void buffer_unlock_all_views(ledit_buffer *buffer); 71 72 /* 73 * Set the hard line mode of the buffer and update the 74 * displayed mode in all views. 75 */ 76 void buffer_set_hard_line_based(ledit_buffer *buffer, int hl); 77 78 /* 79 * Add a new view to the buffer. 80 * 'line' and 'pos' are the initial line and byte position of the cursor. 81 * 'scroll_offset' is the initial pixel scroll offset. 82 */ 83 void buffer_add_view( 84 ledit_buffer *buffer, ledit_mode mode, size_t line, size_t pos, long scroll_offset 85 ); 86 87 /* 88 * Remove the given view from the buffer. 89 * Nothing is done if the view does not belong to the buffer. 90 */ 91 void buffer_remove_view(ledit_buffer *buffer, ledit_view *view); 92 93 /* 94 * Call 'view_recalc_from_line' for all views. 95 */ 96 void buffer_recalc_all_views_from_line(ledit_buffer *buffer, size_t line); 97 98 /* 99 * Load a file into the buffer at line 'line'. 100 * If the line is empty, the text is inserted directly. 101 * Otherwise it is appended after the line. 102 * Returns 0 on success and 1 on error. In case of an error, *errstr is filled 103 * with an error message which must be copied as soon as possible because it may 104 * be overwritten by subsequent function calls. 105 */ 106 int buffer_load_file(ledit_buffer *buffer, char *filename, size_t line, char **errstr); 107 108 /* 109 * Write the buffer to a FILE pointer. 110 * Returns 0 on success and 1 on error. In case of an error, *errstr is filled 111 * with an error message which must be copied as soon as possible because it may 112 * be overwritten by subsequent function calls. 113 * In all cases, 'file' is closed. 114 */ 115 int buffer_write_to_file(ledit_buffer *buffer, FILE *file, char **errstr); 116 117 /* 118 * Write the buffer to a filename. 119 * Behaves the same as 'buffer_write_to_file'. 120 */ 121 int buffer_write_to_filename(ledit_buffer *buffer, char *filename, char **errstr); 122 123 /* 124 * Write the buffer to a file descriptor. 125 * Behaves the same as 'buffer_write_to_file', but if the 126 * file descriptor cannot be fdopen'd, it is closed before returning. 127 */ 128 int buffer_write_to_fd(ledit_buffer *buffer, int fd, char **errstr); 129 130 /* 131 * Destroy a buffer. 132 */ 133 void buffer_destroy(ledit_buffer *buffer); 134 135 /* 136 * Normalize a line, i.e. move the gap to the end and add '\0' 137 * so the text can be used as a normal string 138 */ 139 void buffer_normalize_line(ledit_line *line); 140 141 /* 142 * Get the line at logical index 'index'. 143 * The returned line is only valid until the next 144 * action that appends or deletes line entries. 145 */ 146 ledit_line *buffer_get_line(ledit_buffer *buffer, size_t index); 147 148 /* 149 * Tell views to recalculate the height of line 'line' and 150 * update the pixel offsets of the following lines. 151 */ 152 void buffer_recalc_line(ledit_buffer *buffer, size_t line); 153 154 /* 155 * Tell views to recalculate the height for all lines starting at 'line' 156 * where the text_dirty attribute is set and update the pixel offsets of 157 * all lines after 'line'. 158 * Also clear the text_dirty attribute for all lines starting at 'line'. 159 */ 160 void buffer_recalc_from_line(ledit_buffer *buffer, size_t line); 161 162 /* 163 * Tell views to recalculate all lines. 164 * Also clear the text_dirty attribute for all lines. 165 */ 166 void buffer_recalc_all_lines(ledit_buffer *buffer); 167 168 /* 169 * Get needed length of text range, including newlines. 170 * - NUL is not included 171 * - if the last range ends at the end of a line, the newline is *not* included 172 * - the range must be sorted already 173 */ 174 size_t buffer_textlen(ledit_buffer *buffer, size_t line1, size_t byte1, size_t line2, size_t byte2); 175 176 /* 177 * Copy text range into given buffer and resize it if necessary. 178 * - the range must be sorted already 179 */ 180 void buffer_copy_text_to_txtbuf( 181 ledit_buffer *buffer, 182 txtbuf *buf, /* oh, isn't that a very non-confusing name? */ 183 size_t line1, size_t byte1, 184 size_t line2, size_t byte2 185 ); 186 187 /* 188 * Get the byte index of the previous utf8 character starting at byte index 'index'. 189 */ 190 size_t line_next_utf8(ledit_line *line, size_t index); 191 192 /* 193 * Get the byte index of the previous utf8 character starting at byte index 'index'. 194 */ 195 size_t line_prev_utf8(ledit_line *line, size_t index); 196 197 /* 198 * Get the unicode character index of a byte position. 199 * Note that the time complexity of this is linear. 200 */ 201 size_t line_byte_to_char(ledit_line *line, size_t byte); 202 203 /* 204 * Get the line and byte position of the unicode character position 'num' 205 * positions after the position at line 'line' and byte position 'byte'. 206 * The new position is returned in 'line_ret' and 'byte_ret'. 207 * If multiline is non-zero, the new position may be on a different line. 208 * Otherwise, it is at most the length of the given line. 209 * A newline counts as one position. 210 */ 211 void buffer_next_char_pos( 212 ledit_buffer *buffer, 213 size_t line, size_t byte, 214 int num, int multiline, 215 size_t *line_ret, size_t *byte_ret 216 ); 217 218 /* 219 * Get the line and byte position of the unicode character position 'num' 220 * positions before the position at line 'line' and byte position 'byte'. 221 * The new position is returned in 'line_ret' and 'byte_ret'. 222 * If multiline is non-zero, the new position may be on a different line. 223 * Otherwise, it is never earlier than position 0 on the given line. 224 * A newline counts as one position. 225 */ 226 void buffer_prev_char_pos( 227 ledit_buffer *buffer, 228 size_t line, size_t byte, 229 int num, int multiline, 230 size_t *line_ret, size_t *byte_ret 231 ); 232 233 /* 234 * Insert a mark with key 'mark' (which has byte length 'len') at line 'line' and byte 'byte'. 235 */ 236 void buffer_insert_mark(ledit_buffer *buffer, char *mark, size_t len, size_t line, size_t byte); 237 238 /* 239 * Retrieve mark 'mark' (with byte length 'len'). 240 * The line and byte of the mark are written to 'line_ret' and 'byte_ret'. 241 * These returned positions are always valid positions in the buffer, even 242 * if the buffer has been modified and the mark points to an invalid location. 243 * Returns 0 if the mark was found, 1 otherwise. 244 */ 245 int buffer_get_mark(ledit_buffer *buffer, char *mark, size_t len, size_t *line_ret, size_t *byte_ret); 246 247 /* 248 * Perform one undo step. 249 * 'mode' should be the current mode of the calling view. 250 * 'cur_line' and 'cur_byte' are filled with the new line and cursor 251 * position after the undo. 252 */ 253 undo_status buffer_undo(ledit_buffer *buffer, ledit_mode mode, size_t *cur_line, size_t *cur_byte); 254 255 /* 256 * Same as 'buffer_undo', but for redo. 257 */ 258 undo_status buffer_redo(ledit_buffer *buffer, ledit_mode mode, size_t *cur_line, size_t *cur_byte); 259 260 /* 261 * Delete the given range (which does not need to be sorted yet) and 262 * add the operation to the undo stack. 263 * 'cur_range' is the cursor range to be added to the undo stack. 264 * 'start_undo_group' and 'mode' are also used for the undo stack. 265 * If 'text_ret' is not NULL, the deleted text is written to it. 266 * This function does not tell the views to update their line heights 267 * and offsets. 268 */ 269 void buffer_delete_with_undo_base( 270 ledit_buffer *buffer, ledit_range cur_range, 271 int start_undo_group, ledit_mode mode, /* for undo */ 272 size_t line_index1, size_t byte_index1, 273 size_t line_index2, size_t byte_index2, 274 txtbuf *text_ret 275 ); 276 277 /* 278 * Same as 'buffer_delete_with_undo_base', but the views are told to 279 * update their line heights and offsets afterwards. 280 */ 281 void buffer_delete_with_undo( 282 ledit_buffer *buffer, ledit_range cur_range, 283 int start_undo_group, ledit_mode mode, /* for undo */ 284 size_t line_index1, size_t byte_index1, 285 size_t line_index2, size_t byte_index2, 286 txtbuf *text_ret 287 ); 288 289 /* 290 * Insert the given 'text' with length 'len' at line 'line' and 291 * byte index 'byte and add the operation to the undo stack. 292 * 'cur_range', 'start_undo_group', and 'mode' are used for the 293 * undo stack. If 'set_range_end' is set, the end position of 294 * 'cur_range' is set to the end position of the insertion before 295 * adding the operation to the undo stack. 296 * If 'line_ret' and 'byte_ret' are not NULL, they are filled with 297 * the end position of the insertion. 298 * This function does not tell the views to update their line heights 299 * and offsets. 300 */ 301 void buffer_insert_with_undo_base( 302 ledit_buffer *buffer, 303 ledit_range cur_range, int set_range_end, 304 int start_undo_group, ledit_mode mode, 305 size_t line, size_t byte, 306 char *text, size_t len, 307 size_t *line_ret, size_t *byte_ret 308 ); 309 310 /* 311 * Same as 'buffer_insert_with_undo_base', but the views are told to 312 * update their line heights and offsets afterwards. 313 */ 314 void buffer_insert_with_undo( 315 ledit_buffer *buffer, 316 ledit_range cur_range, int set_range_end, 317 int start_undo_group, ledit_mode mode, 318 size_t line, size_t byte, 319 char *text, size_t len, 320 size_t *line_ret, size_t *byte_ret 321 ); 322 323 #endif