Line | Branch | Exec | Source |
---|---|---|---|
1 | #include <stdlib.h> | ||
2 | #include <string.h> | ||
3 | #include <unistd.h> | ||
4 | #include "msg.h" | ||
5 | #include "command/error.h" | ||
6 | #include "editor.h" | ||
7 | #include "util/debug.h" | ||
8 | #include "util/numtostr.h" | ||
9 | #include "util/path.h" | ||
10 | #include "util/xmalloc.h" | ||
11 | |||
12 | 1 | static void free_message(Message *m) | |
13 | { | ||
14 |
1/2✓ Branch 0 (2→3) taken 1 times.
✗ Branch 1 (2→4) not taken.
|
1 | if (m->loc) { |
15 | 1 | file_location_free(m->loc); | |
16 | } | ||
17 | 1 | free(m); | |
18 | 1 | } | |
19 | |||
20 | ✗ | Message *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 | |||
31 | 1 | void add_message(MessageArray *msgs, Message *m) | |
32 | { | ||
33 | 1 | ptr_array_append(&msgs->array, m); | |
34 | 1 | } | |
35 | |||
36 | 1 | bool activate_current_message(const MessageArray *msgs, Window *window) | |
37 | { | ||
38 | 1 | size_t count = msgs->array.count; | |
39 |
1/2✓ Branch 0 (2→3) taken 1 times.
✗ Branch 1 (2→12) not taken.
|
1 | if (count == 0) { |
40 | return false; | ||
41 | } | ||
42 | |||
43 | 1 | size_t pos = msgs->pos; | |
44 | 1 | BUG_ON(pos >= count); | |
45 | 1 | const Message *m = msgs->array.ptrs[pos]; | |
46 | 1 | const FileLocation *loc = m->loc; | |
47 |
3/6✓ Branch 0 (5→6) taken 1 times.
✗ Branch 1 (5→9) not taken.
✓ Branch 2 (6→7) taken 1 times.
✗ Branch 3 (6→9) not taken.
✓ Branch 4 (8→9) taken 1 times.
✗ Branch 5 (8→12) not taken.
|
1 | if (loc && loc->filename && !file_location_go(window, loc)) { |
48 | // Failed to jump to location; error message is visible | ||
49 | return false; | ||
50 | } | ||
51 | |||
52 | 1 | ErrorBuffer *ebuf = &window->editor->err; | |
53 |
1/2✓ Branch 0 (9→10) taken 1 times.
✗ Branch 1 (9→11) not taken.
|
1 | if (count == 1) { |
54 | 1 | return info_msg(ebuf, "%s", m->msg); | |
55 | } | ||
56 | |||
57 | ✗ | return info_msg(ebuf, "[%zu/%zu] %s", pos + 1, count, m->msg); | |
58 | } | ||
59 | |||
60 | 1 | void activate_current_message_save ( | |
61 | const MessageArray *msgs, | ||
62 | PointerArray *bookmarks, | ||
63 | const View *view | ||
64 | ) { | ||
65 | 1 | size_t nmsgs = msgs->array.count; | |
66 |
1/2✓ Branch 0 (2→3) taken 1 times.
✗ Branch 1 (2→12) not taken.
|
1 | if (nmsgs == 0) { |
67 | ✗ | return; | |
68 | } | ||
69 | |||
70 | 1 | const BlockIter save = view->cursor; | |
71 | 1 | const unsigned long line = view->cy + 1; | |
72 | 1 | const unsigned long col = view->cx_char + 1; | |
73 | 1 | activate_current_message(msgs, view->window); | |
74 | |||
75 | 1 | const BlockIter *cursor = &view->window->editor->view->cursor; | |
76 |
2/6✓ Branch 0 (4→5) taken 1 times.
✗ Branch 1 (4→7) not taken.
✗ Branch 2 (5→6) not taken.
✓ Branch 3 (5→7) taken 1 times.
✗ Branch 4 (6→7) not taken.
✗ Branch 5 (6→12) not taken.
|
1 | if (nmsgs == 1 && cursor->blk == save.blk && cursor->offset == save.offset) { |
77 | // TODO: Make this condition configurable (some people may prefer | ||
78 | // to *always* push a bookmark) | ||
79 | return; | ||
80 | } | ||
81 | |||
82 | // Active view or cursor position changed, or MAY change due to | ||
83 | // there being multiple Messages to navigate with `msg -n|-p`; | ||
84 | // bookmark the previous location | ||
85 | 1 | const Buffer *b = view->buffer; | |
86 |
1/2✗ Branch 0 (7→8) not taken.
✓ Branch 1 (7→9) taken 1 times.
|
1 | char *filename = b->abs_filename ? xstrdup(b->abs_filename) : NULL; |
87 | 1 | bookmark_push(bookmarks, new_file_location(filename, b->id, line, col)); | |
88 | } | ||
89 | |||
90 | 9 | void clear_messages(MessageArray *msgs) | |
91 | { | ||
92 | 9 | msgs->pos = 0; | |
93 | 9 | ptr_array_free_cb(&msgs->array, FREE_FUNC(free_message)); | |
94 | 9 | } | |
95 | |||
96 | ✗ | String dump_messages(const MessageArray *messages) | |
97 | { | ||
98 | ✗ | String buf = string_new(4096); | |
99 | ✗ | char cwd[8192]; | |
100 | ✗ | if (unlikely(!getcwd(cwd, sizeof cwd))) { | |
101 | ✗ | return buf; | |
102 | } | ||
103 | |||
104 | ✗ | for (size_t i = 0, n = messages->array.count; i < n; i++) { | |
105 | ✗ | char *ptr = string_reserve_space(&buf, DECIMAL_STR_MAX(i)); | |
106 | ✗ | buf.len += buf_umax_to_str(i + 1, ptr); | |
107 | ✗ | string_append_literal(&buf, ": "); | |
108 | |||
109 | ✗ | const Message *m = messages->array.ptrs[i]; | |
110 | ✗ | const FileLocation *loc = m->loc; | |
111 | ✗ | if (!loc || !loc->filename) { | |
112 | ✗ | goto append_msg; | |
113 | } | ||
114 | |||
115 | ✗ | if (path_is_absolute(loc->filename)) { | |
116 | ✗ | char *rel = path_relative(loc->filename, cwd); | |
117 | ✗ | string_append_cstring(&buf, rel); | |
118 | ✗ | free(rel); | |
119 | } else { | ||
120 | ✗ | string_append_cstring(&buf, loc->filename); | |
121 | } | ||
122 | |||
123 | ✗ | string_append_byte(&buf, ':'); | |
124 | |||
125 | ✗ | if (loc->pattern) { | |
126 | ✗ | string_append_literal(&buf, " /"); | |
127 | ✗ | string_append_cstring(&buf, loc->pattern); | |
128 | ✗ | string_append_literal(&buf, "/\n"); | |
129 | ✗ | continue; | |
130 | } | ||
131 | |||
132 | ✗ | if (loc->line != 0) { | |
133 | ✗ | string_append_cstring(&buf, ulong_to_str(loc->line)); | |
134 | ✗ | string_append_byte(&buf, ':'); | |
135 | ✗ | if (loc->column != 0) { | |
136 | ✗ | string_append_cstring(&buf, ulong_to_str(loc->column)); | |
137 | ✗ | string_append_byte(&buf, ':'); | |
138 | } | ||
139 | } | ||
140 | |||
141 | ✗ | string_append_literal(&buf, " "); | |
142 | |||
143 | ✗ | append_msg: | |
144 | ✗ | string_append_cstring(&buf, m->msg); | |
145 | ✗ | string_append_byte(&buf, '\n'); | |
146 | } | ||
147 | |||
148 | ✗ | return buf; | |
149 | } | ||
150 |