buffer.h - ledit - Text editor (WIP) | |
git clone git://lumidify.org/ledit.git (fast, but not encrypted) | |
git clone https://lumidify.org/ledit.git (encrypted, but very slow) | |
git clone git://4kcetb7mo7hj6grozzybxtotsub5bempzo4lirzc3437amof2c2impyd.onion/… | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
buffer.h (11292B) | |
--- | |
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, … | |
38 ledit_clipboard *clipboard; /* this also doesn't really bel… | |
39 /* FIXME: add some sort of manager that holds shared stuff like … | |
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… | |
49 size_t lines_num; /* number of lines */ | |
50 int modified; /* whether buffer was modified … | |
51 int hard_line_based; /* whether operations should wo… | |
52 Note that this doesn't actua… | |
53 the buffer functions, it is … | |
54 views can be updated to disp… | |
55 }; | |
56 | |
57 /* | |
58 * Create a new buffer with one empty line | |
59 */ | |
60 ledit_buffer *buffer_create(ledit_common *common, ledit_clipboard *clipb… | |
61 | |
62 /* | |
63 * Lock all views except the given view. | |
64 */ | |
65 void buffer_lock_all_views_except(ledit_buffer *buffer, ledit_view *view… | |
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… | |
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 … | |
103 * with an error message which must be copied as soon as possible becaus… | |
104 * be overwritten by subsequent function calls. | |
105 */ | |
106 int buffer_load_file(ledit_buffer *buffer, char *filename, size_t line, … | |
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 … | |
111 * with an error message which must be copied as soon as possible becaus… | |
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 … | |
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 * The macro is used in order to give better debug | |
146 * information when there is an error since so many | |
147 * functions call this one. | |
148 */ | |
149 ledit_line *buffer_get_line_impl(ledit_buffer *buffer, size_t index, con… | |
150 #define buffer_get_line(buffer, index) (buffer_get_line_impl((buffer), (… | |
151 | |
152 /* | |
153 * Tell views to recalculate the height of line 'line' and | |
154 * update the pixel offsets of the following lines. | |
155 */ | |
156 void buffer_recalc_line(ledit_buffer *buffer, size_t line); | |
157 | |
158 /* | |
159 * Tell views to recalculate the height for all lines starting at 'line' | |
160 * where the text_dirty attribute is set and update the pixel offsets of | |
161 * all lines after 'line'. | |
162 * Also clear the text_dirty attribute for all lines starting at 'line'. | |
163 */ | |
164 void buffer_recalc_from_line(ledit_buffer *buffer, size_t line); | |
165 | |
166 /* | |
167 * Tell views to recalculate all lines. | |
168 * Also clear the text_dirty attribute for all lines. | |
169 */ | |
170 void buffer_recalc_all_lines(ledit_buffer *buffer); | |
171 | |
172 /* | |
173 * Get needed length of text range, including newlines. | |
174 * - NUL is not included | |
175 * - if the last range ends at the end of a line, the newline is *not* i… | |
176 * - the range must be sorted already | |
177 */ | |
178 size_t buffer_textlen(ledit_buffer *buffer, size_t line1, size_t byte1, … | |
179 | |
180 /* | |
181 * Copy text range into given buffer and resize it if necessary. | |
182 * - the range must be sorted already | |
183 */ | |
184 void buffer_copy_text_to_txtbuf( | |
185 ledit_buffer *buffer, | |
186 txtbuf *buf, /* oh, isn't that a very non-confusing name? */ | |
187 size_t line1, size_t byte1, | |
188 size_t line2, size_t byte2 | |
189 ); | |
190 | |
191 /* | |
192 * Get the byte index of the previous utf8 character starting at byte in… | |
193 */ | |
194 size_t line_next_utf8(ledit_line *line, size_t index); | |
195 | |
196 /* | |
197 * Get the byte index of the previous utf8 character starting at byte in… | |
198 */ | |
199 size_t line_prev_utf8(ledit_line *line, size_t index); | |
200 | |
201 /* | |
202 * Get the unicode character index of a byte position. | |
203 * Note that the time complexity of this is linear. | |
204 */ | |
205 size_t line_byte_to_char(ledit_line *line, size_t byte); | |
206 | |
207 /* | |
208 * Get the line and byte position of the unicode character position 'num' | |
209 * positions after the position at line 'line' and byte position 'byte'. | |
210 * The new position is returned in 'line_ret' and 'byte_ret'. | |
211 * If multiline is non-zero, the new position may be on a different line. | |
212 * Otherwise, it is at most the length of the given line. | |
213 * A newline counts as one position. | |
214 */ | |
215 void buffer_next_char_pos( | |
216 ledit_buffer *buffer, | |
217 size_t line, size_t byte, | |
218 int num, int multiline, | |
219 size_t *line_ret, size_t *byte_ret | |
220 ); | |
221 | |
222 /* | |
223 * Get the line and byte position of the unicode character position 'num' | |
224 * positions before the position at line 'line' and byte position 'byte'. | |
225 * The new position is returned in 'line_ret' and 'byte_ret'. | |
226 * If multiline is non-zero, the new position may be on a different line. | |
227 * Otherwise, it is never earlier than position 0 on the given line. | |
228 * A newline counts as one position. | |
229 */ | |
230 void buffer_prev_char_pos( | |
231 ledit_buffer *buffer, | |
232 size_t line, size_t byte, | |
233 int num, int multiline, | |
234 size_t *line_ret, size_t *byte_ret | |
235 ); | |
236 | |
237 /* | |
238 * Insert a mark with key 'mark' (which has byte length 'len') at line '… | |
239 */ | |
240 void buffer_insert_mark(ledit_buffer *buffer, char *mark, size_t len, si… | |
241 | |
242 /* | |
243 * Retrieve mark 'mark' (with byte length 'len'). | |
244 * The line and byte of the mark are written to 'line_ret' and 'byte_ret… | |
245 * These returned positions are always valid positions in the buffer, ev… | |
246 * if the buffer has been modified and the mark points to an invalid loc… | |
247 * Returns 0 if the mark was found, 1 otherwise. | |
248 */ | |
249 int buffer_get_mark(ledit_buffer *buffer, char *mark, size_t len, size_t… | |
250 | |
251 /* | |
252 * Perform one undo step. | |
253 * 'mode' should be the current mode of the calling view. | |
254 * 'cur_line' and 'cur_byte' are filled with the new line and cursor | |
255 * position after the undo. | |
256 */ | |
257 undo_status buffer_undo(ledit_buffer *buffer, ledit_mode mode, size_t *c… | |
258 | |
259 /* | |
260 * Same as 'buffer_undo', but for redo. | |
261 */ | |
262 undo_status buffer_redo(ledit_buffer *buffer, ledit_mode mode, size_t *c… | |
263 | |
264 /* | |
265 * Delete the given range (which does not need to be sorted yet) and | |
266 * add the operation to the undo stack. | |
267 * 'cur_range' is the cursor range to be added to the undo stack. | |
268 * 'start_undo_group' and 'mode' are also used for the undo stack. | |
269 * If 'text_ret' is not NULL, the deleted text is written to it. | |
270 * This function does not tell the views to update their line heights | |
271 * and offsets. | |
272 */ | |
273 void buffer_delete_with_undo_base( | |
274 ledit_buffer *buffer, ledit_range cur_range, | |
275 int start_undo_group, ledit_mode mode, /* for undo */ | |
276 size_t line_index1, size_t byte_index1, | |
277 size_t line_index2, size_t byte_index2, | |
278 txtbuf *text_ret | |
279 ); | |
280 | |
281 /* | |
282 * Same as 'buffer_delete_with_undo_base', but the views are told to | |
283 * update their line heights and offsets afterwards. | |
284 */ | |
285 void buffer_delete_with_undo( | |
286 ledit_buffer *buffer, ledit_range cur_range, | |
287 int start_undo_group, ledit_mode mode, /* for undo */ | |
288 size_t line_index1, size_t byte_index1, | |
289 size_t line_index2, size_t byte_index2, | |
290 txtbuf *text_ret | |
291 ); | |
292 | |
293 /* | |
294 * Insert the given 'text' with length 'len' at line 'line' and | |
295 * byte index 'byte and add the operation to the undo stack. | |
296 * 'cur_range', 'start_undo_group', and 'mode' are used for the | |
297 * undo stack. If 'set_range_end' is set, the end position of | |
298 * 'cur_range' is set to the end position of the insertion before | |
299 * adding the operation to the undo stack. | |
300 * If 'line_ret' and 'byte_ret' are not NULL, they are filled with | |
301 * the end position of the insertion. | |
302 * This function does not tell the views to update their line heights | |
303 * and offsets. | |
304 */ | |
305 void buffer_insert_with_undo_base( | |
306 ledit_buffer *buffer, | |
307 ledit_range cur_range, int set_range_end, | |
308 int start_undo_group, ledit_mode mode, | |
309 size_t line, size_t byte, | |
310 char *text, size_t len, | |
311 size_t *line_ret, size_t *byte_ret | |
312 ); | |
313 | |
314 /* | |
315 * Same as 'buffer_insert_with_undo_base', but the views are told to | |
316 * update their line heights and offsets afterwards. | |
317 */ | |
318 void buffer_insert_with_undo( | |
319 ledit_buffer *buffer, | |
320 ledit_range cur_range, int set_range_end, | |
321 int start_undo_group, ledit_mode mode, | |
322 size_t line, size_t byte, | |
323 char *text, size_t len, | |
324 size_t *line_ret, size_t *byte_ret | |
325 ); | |
326 | |
327 #endif |