2 * Copyright Neil Brown <neil@brown.name> 2015
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
28 static struct map *he_map;
29 static struct pane *do_render_hex_attach(struct pane *parent);
31 DEF_CMD(render_hex_handle)
33 struct pane *p = ci->home;
34 struct he_data *he = p->data;
37 ret = key_lookup(he_map, ci);
41 if (strcmp(ci->key, "Close") == 0) {
42 struct pane *p = he->pane;
45 doc_del_view(p, &he->type);
51 if (strcmp(ci->key, "Clone") == 0) {
52 struct pane *parent = ci->focus;
55 do_render_hex_attach(parent);
58 return pane_clone(c, parent->focus);
64 DEF_CMD(render_hex_notify)
66 struct he_data *he = container_of(ci->comm, struct he_data, type);
68 if (strcmp(ci->key, "Notify:Replace") == 0) {
69 pane_damaged(pane_child(he->pane), DAMAGED_CONTENT);
72 if (strcmp(ci->key, "Release") == 0) {
81 DEF_CMD(render_hex_eol)
83 struct doc *d = doc_from_pane(ci->home);
84 struct editor *ed = pane2ed(ci->home);
86 int rpt = RPT_NUM(ci);
88 struct cmd_info ci2 = {0};
90 ci2.key = "CountLines";
91 ci2.home = ci2.focus = ci->home;
93 key_lookup(ed->commands, &ci2);
94 pos = attr_find_int(*mark_attr(ci->mark), "chars");
96 pos = attr_find_int(*mark_attr(ci->mark), "chars");
97 while (rpt > 0 && ch != WEOF) {
98 while ((pos & 15) != 15 &&
99 (ch = mark_next(d, ci->mark)) != WEOF)
103 ch = mark_next(d, ci->mark);
107 while (rpt < 0 && ch != WEOF) {
108 while ((pos & 15) != 0 &&
109 (ch = mark_prev(d, ci->mark)) != WEOF)
113 ch = mark_prev(d, ci->mark);
123 struct cmd_info ci2 = {0};
124 struct mark *m = NULL;
125 struct doc *d = doc_from_pane(ci->home);
126 struct mark *pm = ci->mark2;
134 ci2.key = "CountLines";
135 ci2.home = ci2.focus = ci->home;
137 key_lookup(d->ed->commands, &ci2);
138 pos = attr_find_int(*mark_attr(ci->mark), "chars");
141 if (doc_following(d, ci->mark) == WEOF)
143 sprintf(buf, "<bold>%08x:</> ", pos);
144 buf_concat(&ret, buf);
145 m = mark_dup(ci->mark, 0);
146 for (i = 0; i < 16; i++) {
148 struct mark *m2 = ci->mark;
150 if (pm && mark_same(d, m2, pm))
152 if (ci->numeric >= 0 && ci->numeric != NO_NUMERIC &&
153 ci->numeric <= ret.len)
156 ch = mark_next(d, m2);
160 sprintf(buf, "%02x ", ch & 0xff);
161 buf_concat(&ret, buf);
163 buf_append(&ret, ' ');
166 buf_concat(&ret, " <fg:red>");
167 for (i = 0; i < 16; i++) {
170 ch = mark_next(d, m);
175 buf_append(&ret, ch);
176 buf_append(&ret, ' ');
178 buf_append(&ret, ' ');
180 buf_concat(&ret, "</>\n");
184 ci->str = buf_final(&ret);
188 DEF_CMD(render_line_prev)
190 /* If ->numeric is 0, round down to multiple of 16.
191 * if it is 1, subtract a further 16.
193 struct doc *d = doc_from_pane(ci->home);
194 struct cmd_info ci2 = {0};
197 ci2.key = "CountLines";
198 ci2.home = ci2.focus = ci->home;
200 key_lookup(d->ed->commands, &ci2);
202 from = attr_find_int(*mark_attr(ci->mark), "chars");
204 if (ci->numeric && to >= 16)
207 mark_prev(d, ci->mark);
213 static void render_hex_register_map(void)
215 he_map = key_alloc();
217 key_add(he_map, "Move-EOL", &render_hex_eol);
219 key_add(he_map, "render-line-prev", &render_line_prev);
220 key_add(he_map, "render-line", &render_line);
223 static struct pane *do_render_hex_attach(struct pane *parent)
225 struct he_data *he = malloc(sizeof(*he));
229 render_hex_register_map();
231 he->type = render_hex_notify;
232 he->typenum = doc_add_view(parent, &he->type, 0);
233 p = pane_register(parent, 0, &render_hex_handle, he, NULL);
234 attr_set_str(&p->attrs, "render-wrap", "no", -1);
235 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</>", -1);
237 render_attach("lines", p);
242 DEF_CMD(render_hex_attach)
244 ci->focus = do_render_hex_attach(ci->focus);
248 void edlib_init(struct editor *ed)
250 key_add(ed->commands, "render-hex-attach", &render_hex_attach);