2 * Copyright Neil Brown ©2015-2023 <neil@brown.name>
3 * May be distributed under terms of GPLv2 - see file:COPYING
7 * 16 bytes are rendered as hex, and then chars
8 * Well... currently we do chars, not bytes, because I cannot control
19 #define PANE_DATA_TYPE struct he_data
27 #include "core-pane.h"
29 static struct map *he_map;
30 static struct pane *do_render_hex_attach(struct pane *parent safe);
32 DEF_LOOKUP_CMD(render_hex_handle, he_map);
34 DEF_CMD_CLOSED(render_hex_close)
36 struct pane *p = ci->home;
37 struct he_data *he = p->data;
43 DEF_CMD(render_hex_clone)
45 struct pane *parent = ci->focus;
47 do_render_hex_attach(parent);
48 pane_clone_children(ci->home, parent->focus);
52 DEF_CMD(render_hex_notify_replace)
55 /* If change happens only after the view port, we don't
57 * If before, we might need to update addresses.
58 * However we cannot currently access the view port, so
59 * always signal damage. FIXME.
61 call("view:changed", pane_focus(ci->home));
65 DEF_CMD(render_hex_eol)
68 int rpt = RPT_NUM(ci);
69 bool one_more = ci->num2 > 0;
74 call("CountLines", ci->focus, 0, ci->mark);
76 pos = attr_find_int(*mark_attr(ci->mark), "char") - 1;
77 while (rpt > 0 && ch != WEOF) {
78 while ((pos & 15) != 15 &&
79 (ch = doc_next(ci->focus, ci->mark)) != WEOF)
82 if (rpt || one_more) {
83 ch = doc_next(ci->focus, ci->mark);
87 while (rpt < 0 && ch != WEOF) {
88 while ((pos & 15) != 0 &&
89 (ch = doc_prev(ci->focus, ci->mark)) != WEOF)
92 if (rpt || one_more) {
93 ch = doc_prev(ci->focus, ci->mark);
103 struct mark *m = NULL;
104 struct mark *pm = ci->mark2;
114 call("CountLines", ci->focus, 0, ci->mark);
115 pos = attr_find_int(*mark_attr(ci->mark), "char") - 1;
118 if (doc_following(ci->focus, ci->mark) == WEOF)
120 snprintf(buf, sizeof(buf), "<bold>%08x:</> ", pos);
121 buf_concat(&ret, buf);
122 m = mark_dup_view(ci->mark);
123 for (i = 0; i < 16; i++) {
125 struct mark *m2 = ci->mark;
127 if (pm && mark_same(m2, pm) && pm_offset < 0)
129 if (ci->num >= 0 && ci->num <= ret.len)
132 ch = doc_next(ci->focus, m2);
136 sprintf(buf, "%02x ", ch & 0xff);
137 buf_concat(&ret, buf);
139 buf_append(&ret, ' ');
142 buf_concat(&ret, " <fg:red>");
143 for (i = 0; i < 16; i++) {
146 ch = doc_next(ci->focus, m);
151 buf_append(&ret, ch);
153 /* '<<' to quote the '<' */
154 buf_append(&ret, ch);
155 buf_append(&ret, ' ');
157 buf_append(&ret, ' ');
159 buf_concat(&ret, "</>\n");
163 rv = comm_call(ci->comm2, "callback:render", ci->focus, pm_offset, NULL,
169 DEF_CMD(render_line_prev)
171 /* If ->num is 0, round down to multiple of 16.
172 * if it is 1, subtract a further 16.
178 call("CountLines", ci->focus, 0, ci->mark);
180 from = attr_find_int(*mark_attr(ci->mark), "char") - 1;
189 doc_prev(ci->focus, ci->mark);
197 struct he_data *he = ci->home->data;
200 return home_call(ci->home->parent, "doc:byte", ci->focus,
201 ci->num, ci->mark, ci->str,
202 ci->num2, ci->mark2, ci->str2);
204 return home_call(ci->home->parent, "doc:char", ci->focus,
205 ci->num, ci->mark, ci->str,
206 ci->num2, ci->mark2, ci->str2);
209 static void render_hex_register_map(void)
211 he_map = key_alloc();
213 key_add(he_map, "doc:EOL", &render_hex_eol);
214 key_add(he_map, "doc:char", &hex_char);
216 key_add(he_map, "doc:render-line-prev", &render_line_prev);
217 key_add(he_map, "doc:render-line", &render_line);
219 key_add(he_map, "Close", &render_hex_close);
220 key_add(he_map, "Clone", &render_hex_clone);
221 key_add(he_map, "doc:replaced", &render_hex_notify_replace);
224 static struct pane *do_render_hex_attach(struct pane *parent safe)
228 char *charset = pane_attr_get(parent, "doc:charset");
231 render_hex_register_map();
233 p = pane_register(parent, 0, &render_hex_handle.c);
237 call("doc:request:doc:replaced", p);
238 attr_set_str(&p->attrs, "render-wrap", "no");
239 attr_set_str(&p->attrs, "heading", "<bold> 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 0 1 2 3 4 5 6 7 8 9 a b c d e f</>");
241 he->bytes = (charset && strcmp(charset, "8bit") != 0);
242 return call_ret(pane, "attach-render-lines", p);
245 DEF_CMD(render_hex_attach)
247 struct pane *p = do_render_hex_attach(ci->focus);
251 return comm_call(ci->comm2, "callback:attach", p);
254 DEF_CMD(hex_appeared)
256 char *t = pane_attr_get(ci->focus, "doc-type");
257 if (t && strcmp(t, "text") == 0)
258 attr_set_str(&ci->focus->attrs, "render-cmd-H", "hex");
262 void edlib_init(struct pane *ed safe)
264 call_comm("global-set-command", ed, &render_hex_attach, 0, NULL, "attach-render-hex");
265 call_comm("global-set-command", ed, &hex_appeared, 0, NULL, "doc:appeared-hex");