2 * Copyright (c) 2021, 2024 Omar Polo <op@omarpolo.com>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 TAILQ_HEAD(mhist, hist_item) head;
29 struct hist_item *cur;
36 TAILQ_ENTRY(hist_item) entries;
44 if ((hist = calloc(1, sizeof(*hist))) == NULL)
47 TAILQ_INIT(&hist->head);
54 hist_free(struct hist *hist)
64 hist_erase_from(struct hist *hist, struct hist_item *h)
66 struct hist_item *next;
69 next = TAILQ_NEXT(h, entries);
72 TAILQ_REMOVE(&hist->head, h, entries);
80 hist_erase(struct hist *hist)
82 hist_erase_from(hist, TAILQ_FIRST(&hist->head));
90 hist_size(struct hist *hist)
96 hist_off(struct hist *hist)
104 hist_cur(struct hist *hist)
106 if (hist->cur == NULL)
108 return (hist->cur->str);
112 hist_cur_offs(struct hist *hist, size_t *line, size_t *curr)
117 if (hist->cur == NULL)
120 *line = hist->cur->line_off;
121 *curr = hist->cur->current_off;
126 hist_set_cur(struct hist *hist, const char *str)
130 if (hist->cur == NULL)
133 if ((d = strdup(str)) == NULL)
136 free(hist->cur->str);
142 hist_set_offs(struct hist *hist, size_t line, size_t curr)
144 if (hist->cur == NULL)
147 hist->cur->line_off = line;
148 hist->cur->current_off = line;
153 hist_nth(struct hist *hist, size_t n)
159 TAILQ_FOREACH(h, &hist->head, entries) {
167 hist_prev(struct hist *hist)
170 int wrap = hist->flags & HIST_WRAP;
172 if (hist->cur == NULL && !wrap)
175 if (hist->cur == NULL ||
176 (h = TAILQ_PREV(hist->cur, mhist, entries)) == NULL) {
177 if (!wrap || (h = TAILQ_LAST(&hist->head, mhist)) == NULL)
179 hist->off = hist->size - 1;
188 hist_next(struct hist *hist)
191 int wrap = hist->flags & HIST_WRAP;
193 if (hist->cur == NULL && !wrap)
196 if (hist->cur == NULL ||
197 (h = TAILQ_NEXT(hist->cur, entries)) == NULL) {
198 if (!wrap || (h = TAILQ_FIRST(&hist->head)) == NULL)
209 hist_seek_start(struct hist *hist)
216 hist_push(struct hist *hist, const char *str)
220 if ((h = calloc(1, sizeof(*h))) == NULL)
223 if ((h->str = strdup(str)) == NULL) {
228 if (hist->cur != NULL)
229 hist_erase_from(hist, TAILQ_NEXT(hist->cur, entries));
233 TAILQ_INSERT_TAIL(&hist->head, h, entries);
238 hist_prepend(struct hist *hist, const char *str)
242 if (hist->cur == NULL)
245 if ((h = calloc(1, sizeof(*h))) == NULL)
248 if ((h->str = strdup(str)) == NULL) {
255 TAILQ_INSERT_BEFORE(hist->cur, h, entries);
260 hist_append(struct hist *hist, const char *str)
265 * Not sure. The minibuffer needs to append even when there
268 if (hist->cur == NULL && !(hist->flags & HIST_WRAP))
271 if ((h = calloc(1, sizeof(*h))) == NULL)
274 if ((h->str = strdup(str)) == NULL) {
280 TAILQ_INSERT_TAIL(&hist->head, h, entries);