2 * Copyright Neil Brown ©2015-2019 <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
27 static struct map *he_map;
28 static struct pane *do_render_hex_attach(struct pane *parent safe);
30 DEF_LOOKUP_CMD(render_hex_handle, he_map);
32 DEF_CMD(render_hex_close)
34 struct pane *p = ci->home;
35 struct he_data *he = p->data;
38 p->data = safe_cast NULL;
44 DEF_CMD(render_hex_clone)
46 struct pane *parent = ci->focus;
48 do_render_hex_attach(parent);
49 pane_clone_children(ci->home, parent->focus);
53 DEF_CMD(render_hex_notify_replace)
56 /* If change happens only after the view port, we don't
58 * If before, we might need to update addresses.
59 * However we cannot currently access the view port, so
60 * always signal damage.
62 pane_damaged(ci->home, DAMAGED_CONTENT);
66 DEF_CMD(render_hex_eol)
69 int rpt = RPT_NUM(ci);
74 call("CountLines", ci->home, 0, ci->mark);
76 pos = attr_find_int(*mark_attr(ci->mark), "chars");
77 while (rpt > 0 && ch != WEOF) {
78 while ((pos & 15) != 15 &&
79 (ch = mark_next_pane(ci->focus, ci->mark)) != WEOF)
83 ch = mark_next_pane(ci->focus, ci->mark);
87 while (rpt < 0 && ch != WEOF) {
88 while ((pos & 15) != 0 &&
89 (ch = mark_prev_pane(ci->focus, ci->mark)) != WEOF)
93 ch = mark_prev_pane(ci->focus, ci->mark);
103 struct mark *m = NULL;
104 struct mark *pm = ci->mark2;
113 call("CountLines", ci->home, 0, ci->mark);
114 pos = attr_find_int(*mark_attr(ci->mark), "chars");
117 if (doc_following_pane(ci->focus, ci->mark) == WEOF)
119 snprintf(buf, sizeof(buf), "<bold>%08x:</> ", pos);
120 buf_concat(&ret, buf);
121 m = mark_dup_view(ci->mark);
122 for (i = 0; i < 16; i++) {
124 struct mark *m2 = ci->mark;
126 if (pm && mark_same(m2, pm))
128 if (ci->num >= 0 && ci->num != NO_NUMERIC &&
132 ch = mark_next_pane(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 = mark_next_pane(ci->focus, m);
151 buf_append(&ret, ch);
152 buf_append(&ret, ' ');
154 buf_append(&ret, ' ');
156 buf_concat(&ret, "</>\n");
160 rv = comm_call(ci->comm2, "callback:render", ci->focus, 0, NULL,
166 DEF_CMD(render_line_prev)
168 /* If ->num is 0, round down to multiple of 16.
169 * if it is 1, subtract a further 16.
175 call("CountLines", ci->home, 0, ci->mark);
177 from = attr_find_int(*mark_attr(ci->mark), "chars");
179 if (ci->num && to >= 16)
182 mark_prev_pane(ci->focus, ci->mark);
190 struct he_data *he = ci->home->data;
192 if (!he->bytes || !ci->home->parent)
194 return home_call(ci->home->parent, "doc:step-bytes", ci->focus,
195 ci->num, ci->mark, ci->str,
196 ci->num2, ci->mark2, ci->str2);
199 static void render_hex_register_map(void)
201 he_map = key_alloc();
203 key_add(he_map, "Move-EOL", &render_hex_eol);
204 key_add(he_map, "doc:step", &hex_step);
206 key_add(he_map, "doc:render-line-prev", &render_line_prev);
207 key_add(he_map, "doc:render-line", &render_line);
209 key_add(he_map, "Close", &render_hex_close);
210 key_add(he_map, "Clone", &render_hex_clone);
211 key_add(he_map, "Notify:doc:Replace", &render_hex_notify_replace);
214 static struct pane *do_render_hex_attach(struct pane *parent safe)
216 struct he_data *he = malloc(sizeof(*he));
218 char *charset = pane_attr_get(parent, "doc:charset");
221 render_hex_register_map();
223 p = pane_register(parent, 0, &render_hex_handle.c, he, NULL);
224 call("doc:Request:Notify:doc:Replace", p);
225 attr_set_str(&p->attrs, "render-wrap", "no");
226 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</>");
228 he->bytes = (charset && strcmp(charset, "8bit") != 0);
229 return call_ret(pane, "attach-render-lines", p);
232 DEF_CMD(render_hex_attach)
234 struct pane *p = do_render_hex_attach(ci->focus);
238 return comm_call(ci->comm2, "callback:attach", p);
241 DEF_CMD(hex_appeared)
243 char *t = pane_attr_get(ci->focus, "doc-type");
244 if (t && strcmp(t, "text") == 0)
245 attr_set_str(&ci->focus->attrs, "render-Chr-H", "hex");
249 void edlib_init(struct pane *ed safe)
251 call_comm("global-set-command", ed, &render_hex_attach, 0, NULL, "attach-render-hex");
252 call_comm("global-set-command", ed, &hex_appeared, 0, NULL, "doc:appeared-hex");