/*
- * Copyright Neil Brown ©2015 <neil@brown.name>
+ * Copyright Neil Brown ©2015-2023 <neil@brown.name>
* May be distributed under terms of GPLv2 - see file:COPYING
*
* hexedit renderer
#include <string.h>
#include <stdio.h>
+#define PANE_DATA_TYPE struct he_data
#include "core.h"
#include "misc.h"
struct pane *pane;
bool bytes;
};
+#include "core-pane.h"
static struct map *he_map;
static struct pane *do_render_hex_attach(struct pane *parent safe);
DEF_LOOKUP_CMD(render_hex_handle, he_map);
-DEF_CMD(render_hex_close)
+DEF_CMD_CLOSED(render_hex_close)
{
struct pane *p = ci->home;
struct he_data *he = p->data;
he->pane = NULL;
- p->data = safe_cast NULL;
- p->handle = NULL;
- free(he);
return 1;
}
* need damage.
* If before, we might need to update addresses.
* However we cannot currently access the view port, so
- * always signal damage.
+ * always signal damage. FIXME.
*/
- pane_damaged(ci->home, DAMAGED_CONTENT);
+ call("view:changed", pane_focus(ci->home));
return 1;
}
{
wint_t ch = 1;
int rpt = RPT_NUM(ci);
+ bool one_more = ci->num2 > 0;
int pos;
if (!ci->mark)
return Enoarg;
- call("CountLines", ci->home, 0, ci->mark);
+ call("CountLines", ci->focus, 0, ci->mark);
- pos = attr_find_int(*mark_attr(ci->mark), "chars");
+ pos = attr_find_int(*mark_attr(ci->mark), "char") - 1;
while (rpt > 0 && ch != WEOF) {
while ((pos & 15) != 15 &&
- (ch = mark_next_pane(ci->focus, ci->mark)) != WEOF)
+ (ch = doc_next(ci->focus, ci->mark)) != WEOF)
pos += 1;
rpt -= 1;
- if (rpt) {
- ch = mark_next_pane(ci->focus, ci->mark);
+ if (rpt || one_more) {
+ ch = doc_next(ci->focus, ci->mark);
pos += 1;
}
}
while (rpt < 0 && ch != WEOF) {
while ((pos & 15) != 0 &&
- (ch = mark_prev_pane(ci->focus, ci->mark)) != WEOF)
+ (ch = doc_prev(ci->focus, ci->mark)) != WEOF)
pos -= 1;
rpt += 1;
- if (rpt) {
- ch = mark_prev_pane(ci->focus, ci->mark);
+ if (rpt || one_more) {
+ ch = doc_prev(ci->focus, ci->mark);
pos -= 1;
}
}
struct mark *m = NULL;
struct mark *pm = ci->mark2;
int pos;
+ int pm_offset = -1;
int i;
char buf[30];
int rv;
if (!ci->mark)
return Enoarg;
- call("CountLines", ci->home, 0, ci->mark);
- pos = attr_find_int(*mark_attr(ci->mark), "chars");
+ call("CountLines", ci->focus, 0, ci->mark);
+ pos = attr_find_int(*mark_attr(ci->mark), "char") - 1;
buf_init(&ret);
- if (doc_following_pane(ci->focus, ci->mark) == WEOF)
- goto done;
+ if (doc_following(ci->focus, ci->mark) == WEOF)
+ return Efail;
snprintf(buf, sizeof(buf), "<bold>%08x:</> ", pos);
buf_concat(&ret, buf);
m = mark_dup_view(ci->mark);
wint_t ch;
struct mark *m2 = ci->mark;
- if (pm && mark_same(m2, pm))
- goto done;
- if (ci->num >= 0 && ci->num != NO_NUMERIC &&
- ci->num <= ret.len)
+ if (pm && mark_same(m2, pm) && pm_offset < 0)
+ pm_offset = ret.len;
+ if (ci->num >= 0 && ci->num <= ret.len)
goto done;
- ch = mark_next_pane(ci->focus, m2);
+ ch = doc_next(ci->focus, m2);
if (ch == WEOF)
strcpy(buf, " ");
else
for (i = 0; i < 16; i++) {
wint_t ch;
- ch = mark_next_pane(ci->focus, m);
+ ch = doc_next(ci->focus, m);
if (ch == WEOF)
ch = ' ';
if (ch < ' ')
ch = '?';
buf_append(&ret, ch);
+ if (ch == '<')
+ /* '<<' to quote the '<' */
+ buf_append(&ret, ch);
buf_append(&ret, ' ');
if (i == 7)
buf_append(&ret, ' ');
done:
if (m)
mark_free(m);
- rv = comm_call(ci->comm2, "callback:render", ci->focus, 0, NULL,
+ rv = comm_call(ci->comm2, "callback:render", ci->focus, pm_offset, NULL,
buf_final(&ret));
free(ret.b);
- return rv;
+ return rv ?: 1;
}
DEF_CMD(render_line_prev)
if (!ci->mark)
return Enoarg;
- call("CountLines", ci->home, 0, ci->mark);
+ call("CountLines", ci->focus, 0, ci->mark);
- from = attr_find_int(*mark_attr(ci->mark), "chars");
+ from = attr_find_int(*mark_attr(ci->mark), "char") - 1;
to = from & ~0xF;
- if (ci->num && to >= 16)
- to -= 16;
+ if (ci->num) {
+ if (to >= 16)
+ to -= 16;
+ else
+ return Efail;
+ }
while (to < from) {
- mark_prev_pane(ci->focus, ci->mark);
+ doc_prev(ci->focus, ci->mark);
from -= 1;
}
return 1;
}
-DEF_CMD(hex_step)
+DEF_CMD(hex_char)
{
struct he_data *he = ci->home->data;
- if (!he->bytes || !ci->home->parent)
- return 0;
- return home_call(ci->home->parent, "doc:step-bytes", ci->focus,
- ci->num, ci->mark, ci->str,
- ci->num2, ci->mark2, ci->str2);
+ if (he->bytes)
+ return home_call(ci->home->parent, "doc:byte", ci->focus,
+ ci->num, ci->mark, ci->str,
+ ci->num2, ci->mark2, ci->str2);
+ else
+ return home_call(ci->home->parent, "doc:char", ci->focus,
+ ci->num, ci->mark, ci->str,
+ ci->num2, ci->mark2, ci->str2);
}
static void render_hex_register_map(void)
{
he_map = key_alloc();
- key_add(he_map, "Move-EOL", &render_hex_eol);
- key_add(he_map, "doc:step", &hex_step);
+ key_add(he_map, "doc:EOL", &render_hex_eol);
+ key_add(he_map, "doc:char", &hex_char);
- key_add(he_map, "render-line-prev", &render_line_prev);
- key_add(he_map, "render-line", &render_line);
+ key_add(he_map, "doc:render-line-prev", &render_line_prev);
+ key_add(he_map, "doc:render-line", &render_line);
key_add(he_map, "Close", &render_hex_close);
key_add(he_map, "Clone", &render_hex_clone);
- key_add(he_map, "Notify:doc:Replace", &render_hex_notify_replace);
+ key_add(he_map, "doc:replaced", &render_hex_notify_replace);
}
static struct pane *do_render_hex_attach(struct pane *parent safe)
{
- struct he_data *he = malloc(sizeof(*he));
+ struct he_data *he;
struct pane *p;
char *charset = pane_attr_get(parent, "doc:charset");
if (!he_map)
render_hex_register_map();
- p = pane_register(parent, 0, &render_hex_handle.c, he, NULL);
- call("Request:Notify:doc:Replace", p);
+ p = pane_register(parent, 0, &render_hex_handle.c);
+ if (!p)
+ return NULL;
+ he = p->data;
+ call("doc:request:doc:replaced", p);
attr_set_str(&p->attrs, "render-wrap", "no");
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</>");
he->pane = p;
he->bytes = (charset && strcmp(charset, "8bit") != 0);
- return render_attach("lines", p);
+ return call_ret(pane, "attach-render-lines", p);
}
DEF_CMD(render_hex_attach)
struct pane *p = do_render_hex_attach(ci->focus);
if (!p)
- return Esys;
+ return Efail;
return comm_call(ci->comm2, "callback:attach", p);
}
{
char *t = pane_attr_get(ci->focus, "doc-type");
if (t && strcmp(t, "text") == 0)
- attr_set_str(&ci->focus->attrs, "render-Chr-H", "hex");
- return 0;
+ attr_set_str(&ci->focus->attrs, "render-cmd-H", "hex");
+ return Efallthrough;
}
void edlib_init(struct pane *ed safe)