vis: move text object definitions to separate file
[vis.git] / text.h
blob90da900ab1fefa7243c5b9f20c7fee0872e69682
1 #ifndef TEXT_H
2 #define TEXT_H
4 #include <stdbool.h>
5 #include <time.h>
6 #include <unistd.h>
7 #include <stdarg.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
11 #define EPOS ((size_t)-1) /* invalid position */
13 typedef size_t Filepos;
15 typedef struct {
16 size_t start, end; /* range in bytes from start of the file */
17 } Filerange;
19 typedef struct Text Text;
20 typedef struct Piece Piece;
22 typedef struct {
23 const char *start; /* begin of piece's data */
24 const char *end; /* pointer to the first byte after valid data i.e. [start, end) */
25 const char *text; /* current position within piece: start <= text < end */
26 const Piece *piece; /* internal state do not touch! */
27 size_t pos; /* global position in bytes from start of file */
28 } Iterator;
30 #define text_iterate(txt, it, pos) \
31 for (Iterator it = text_iterator_get((txt), (pos)); \
32 text_iterator_valid(&it); \
33 text_iterator_next(&it))
35 /* create a text instance populated with the given file content, if `filename'
36 * is NULL the text starts out empty */
37 Text *text_load(const char *filename);
38 /* file information at time of load or last save */
39 struct stat text_stat(Text*);
40 bool text_appendf(Text*, const char *format, ...);
41 bool text_printf(Text*, size_t pos, const char *format, ...);
42 bool text_vprintf(Text*, size_t pos, const char *format, va_list ap);
43 /* inserts a line ending character (depending on file type) */
44 bool text_insert_newline(Text*, size_t pos);
45 /* insert `len' bytes starting from `data' at `pos' which has to be
46 * in the interval [0, text_size(txt)] */
47 bool text_insert(Text*, size_t pos, const char *data, size_t len);
48 /* delete `len' bytes starting from `pos' */
49 bool text_delete(Text*, size_t pos, size_t len);
50 bool text_delete_range(Text*, Filerange*);
51 /* mark the current text state, such that it can be {un,re}done */
52 void text_snapshot(Text*);
53 /* undo/redo to the last snapshotted state. returns the position where
54 * the change occured or EPOS if nothing could be {un,re}done. */
55 size_t text_undo(Text*);
56 size_t text_redo(Text*);
57 /* move chronlogically to the `count' earlier/later revision */
58 size_t text_earlier(Text*, int count);
59 size_t text_later(Text*, int count);
60 /* restore the text to the state closest to the time given */
61 size_t text_restore(Text*, time_t);
62 /* get creation time of current state */
63 time_t text_state(Text*);
65 size_t text_pos_by_lineno(Text*, size_t lineno);
66 size_t text_lineno_by_pos(Text*, size_t pos);
68 /* set `buf' to the byte found at `pos' and return true, if `pos' is invalid
69 * false is returned and `buf' is left unmodified */
70 bool text_byte_get(Text*, size_t pos, char *buf);
71 /* store at most `len' bytes starting from `pos' into `buf', the return value
72 * indicates how many bytes were copied into `buf'. WARNING buf will not be
73 * NUL terminated. */
74 size_t text_bytes_get(Text*, size_t pos, size_t len, char *buf);
75 /* allocate a NUL terminated buffer and fill at most `len' bytes
76 * starting at `pos'. Freeing is the caller's responsibility! */
77 char *text_bytes_alloc0(Text*, size_t pos, size_t len);
79 Iterator text_iterator_get(Text*, size_t pos);
80 bool text_iterator_valid(const Iterator*);
81 bool text_iterator_next(Iterator*);
82 bool text_iterator_prev(Iterator*);
84 /* get byte at current iterator position, if this is at EOF a NUL
85 * byte (which is not actually part of the file) is read. */
86 bool text_iterator_byte_get(Iterator*, char *b);
87 /* advance iterator by one byte and get byte at new position. */
88 bool text_iterator_byte_prev(Iterator*, char *b);
89 /* if the new position is at EOF a NUL byte (which is not actually
90 * part of the file) is read. */
91 bool text_iterator_byte_next(Iterator*, char *b);
92 /* move to the next/previous UTF-8 encoded Unicode codepoint
93 * and set c (if it is non NULL) to the first byte */
94 bool text_iterator_codepoint_next(Iterator *it, char *c);
95 bool text_iterator_codepoint_prev(Iterator *it, char *c);
96 /* move to next/previous grapheme i.e. might skip over multiple
97 * Unicode codepoints (e.g. for combining characters) */
98 bool text_iterator_char_next(Iterator*, char *c);
99 bool text_iterator_char_prev(Iterator*, char *c);
101 typedef const char* Mark;
102 /* mark position `pos', the returned mark can be used to later retrieve
103 * the same text segment */
104 Mark text_mark_set(Text*, size_t pos);
105 /* get position of mark in bytes from start of the file or EPOS if
106 * the mark is not/no longer valid e.g. if the corresponding text was
107 * deleted. If the change is later restored the mark will once again be
108 * valid. */
109 size_t text_mark_get(Text*, Mark);
111 /* get position of change denoted by index, where 0 indicates the most recent */
112 size_t text_history_get(Text*, size_t index);
113 /* return the size in bytes of the whole text */
114 size_t text_size(Text*);
115 /* query whether the text contains any unsaved modifications */
116 bool text_modified(Text*);
117 /* query whether `addr` is part of a memory mapped region associated with
118 * this text instance */
119 bool text_sigbus(Text*, const char *addr);
121 /* which type of new lines does the text use? */
122 enum TextNewLine {
123 TEXT_NEWLINE_NL = 1,
124 TEXT_NEWLINE_CRNL,
127 enum TextNewLine text_newline_type(Text*);
129 /* save the whole text to the given `filename'. Return true if succesful.
130 * In which case an implicit snapshot is taken. The save might associate a
131 * new inode to file. */
132 bool text_save(Text*, const char *filename);
133 bool text_save_range(Text*, Filerange*, const char *file);
134 /* write the text content to the given file descriptor `fd'. Return the
135 * number of bytes written or -1 in case there was an error. */
136 ssize_t text_write(Text*, int fd);
137 ssize_t text_write_range(Text*, Filerange*, int fd);
138 /* release all ressources associated with this text instance */
139 void text_free(Text*);
141 #endif