aboutsummaryrefslogtreecommitdiff
path: root/examples/dte/msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/dte/msg.c')
-rw-r--r--examples/dte/msg.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/examples/dte/msg.c b/examples/dte/msg.c
new file mode 100644
index 0000000..203347f
--- /dev/null
+++ b/examples/dte/msg.c
@@ -0,0 +1,139 @@
1#include <stdlib.h>
2#include <string.h>
3#include <unistd.h>
4#include "msg.h"
5#include "editor.h"
6#include "error.h"
7#include "util/debug.h"
8#include "util/numtostr.h"
9#include "util/path.h"
10#include "util/xmalloc.h"
11
12static void free_message(Message *m)
13{
14 if (m->loc) {
15 file_location_free(m->loc);
16 }
17 free(m);
18}
19
20Message *new_message(const char *msg, size_t len)
21{
22 Message *m = xmalloc(sizeof(*m) + len + 1);
23 m->loc = NULL;
24 if (len) {
25 memcpy(m->msg, msg, len);
26 }
27 m->msg[len] = '\0';
28 return m;
29}
30
31void add_message(MessageArray *msgs, Message *m)
32{
33 ptr_array_append(&msgs->array, m);
34}
35
36bool activate_current_message(EditorState *e)
37{
38 const MessageArray *msgs = &e->messages;
39 size_t count = msgs->array.count;
40 if (count == 0) {
41 return true;
42 }
43
44 size_t pos = msgs->pos;
45 BUG_ON(pos >= count);
46 const Message *m = msgs->array.ptrs[pos];
47 const FileLocation *loc = m->loc;
48 if (loc && loc->filename && !file_location_go(e->window, loc)) {
49 // Failed to jump to location; error message is visible
50 return false;
51 }
52
53 if (count == 1) {
54 info_msg("%s", m->msg);
55 } else {
56 info_msg("[%zu/%zu] %s", pos + 1, count, m->msg);
57 }
58
59 return true;
60}
61
62bool activate_current_message_save(EditorState *e)
63{
64 const View *view = e->view;
65 const BlockIter save = view->cursor;
66 FileLocation *loc = get_current_file_location(view);
67 bool ok = activate_current_message(e);
68
69 // Save position if file changed or cursor moved
70 view = e->view;
71 if (view->cursor.blk != save.blk || view->cursor.offset != save.offset) {
72 bookmark_push(&e->bookmarks, loc);
73 } else {
74 file_location_free(loc);
75 }
76
77 return ok;
78}
79
80void clear_messages(MessageArray *msgs)
81{
82 msgs->pos = 0;
83 ptr_array_free_cb(&msgs->array, FREE_FUNC(free_message));
84}
85
86String dump_messages(const MessageArray *messages)
87{
88 String buf = string_new(4096);
89 char cwd[8192];
90 if (unlikely(!getcwd(cwd, sizeof cwd))) {
91 return buf;
92 }
93
94 for (size_t i = 0, n = messages->array.count; i < n; i++) {
95 char *ptr = string_reserve_space(&buf, DECIMAL_STR_MAX(i));
96 buf.len += buf_umax_to_str(i + 1, ptr);
97 string_append_literal(&buf, ": ");
98
99 const Message *m = messages->array.ptrs[i];
100 const FileLocation *loc = m->loc;
101 if (!loc || !loc->filename) {
102 goto append_msg;
103 }
104
105 if (path_is_absolute(loc->filename)) {
106 char *rel = path_relative(loc->filename, cwd);
107 string_append_cstring(&buf, rel);
108 free(rel);
109 } else {
110 string_append_cstring(&buf, loc->filename);
111 }
112
113 string_append_byte(&buf, ':');
114
115 if (loc->pattern) {
116 string_append_literal(&buf, " /");
117 string_append_cstring(&buf, loc->pattern);
118 string_append_literal(&buf, "/\n");
119 continue;
120 }
121
122 if (loc->line != 0) {
123 string_append_cstring(&buf, ulong_to_str(loc->line));
124 string_append_byte(&buf, ':');
125 if (loc->column != 0) {
126 string_append_cstring(&buf, ulong_to_str(loc->column));
127 string_append_byte(&buf, ':');
128 }
129 }
130
131 string_append_literal(&buf, " ");
132
133 append_msg:
134 string_append_cstring(&buf, m->msg);
135 string_append_byte(&buf, '\n');
136 }
137
138 return buf;
139}