This allows us to store other stuff than just the document.
Signed-off-by: NeilBrown <neil@brown.name>
DEF_CMD(doc_char)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
int rpt = RPT_NUM(ci);
while (rpt > 0) {
- if (mark_next(d, ci->mark) == WEOF)
+ if (mark_next(dd->doc, ci->mark) == WEOF)
break;
rpt -= 1;
}
while (rpt < 0) {
- if (mark_prev(d, ci->mark) == WEOF)
+ if (mark_prev(dd->doc, ci->mark) == WEOF)
break;
rpt += 1;
}
DEF_CMD(doc_word)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
+ struct doc *d = dd->doc;
int rpt = RPT_NUM(ci);
/* We skip spaces, then either alphanum or non-space/alphanum */
DEF_CMD(doc_WORD)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
+ struct doc *d = dd->doc;
int rpt = RPT_NUM(ci);
/* We skip spaces, then non-spaces */
DEF_CMD(doc_eol)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
+ struct doc *d = dd->doc;
wint_t ch = 1;
int rpt = RPT_NUM(ci);
DEF_CMD(doc_file)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
+ struct doc *d = dd->doc;
wint_t ch = 1;
int rpt = RPT_NUM(ci);
DEF_CMD(doc_line)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
+ struct doc *d = dd->doc;
wint_t ch = 1;
int rpt = RPT_NUM(ci);
DEF_CMD(doc_page)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
+ struct doc *d = dd->doc;
wint_t ch = 1;
int rpt = RPT_NUM(ci);
DEF_CMD(doc_handle)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
int ret;
/* This is a hack - I should use a watcher, but I don't have
return 0;
}
if (strcmp(ci->key, "Clone") == 0) {
- struct pane *p = doc_attach(ci->focus, d);
+ struct pane *p = doc_attach(ci->focus, dd->doc);
struct pane *c = pane_child(ci->home);
p->point = point_dup(ci->home->point);
else if (ci->extra == MARK_UNGROUPED)
ci->mark = mark_dup(pt, 1);
else
- ci->mark = do_mark_at_point(d, pt,
+ ci->mark = do_mark_at_point(dd->doc, pt,
ci->extra);
}
return 1;
}
if (strcmp(ci->key, "doc:set-name") == 0) {
- doc_set_name(d, ci->str);
+ doc_set_name(dd->doc, ci->str);
return 1;
}
if (strcmp(ci->key, "doc:add-view") == 0) {
if (!ci->comm2)
return -1;
- ci->extra = do_doc_add_view(d, ci->comm2, ci->extra);
+ ci->extra = do_doc_add_view(dd->doc, ci->comm2, ci->extra);
return 1;
}
if (strcmp(ci->key, "doc:del-view") == 0) {
if (!ci->comm2)
return -1;
- do_doc_del_view(d, ci->comm2);
+ do_doc_del_view(dd->doc, ci->comm2);
return 1;
}
if (strcmp(ci->key, "doc:find-view") == 0) {
if (!ci->comm2)
return -1;
- ci->extra = do_doc_find_view(d, ci->comm2);
+ ci->extra = do_doc_find_view(dd->doc, ci->comm2);
return 1;
}
if (strcmp(ci->key, "doc:find") == 0) {
- ci->misc = d;
+ ci->misc = dd->doc;
return 1;
}
if (strcmp(ci->key, "doc:vmark-get") == 0) {
- ci->mark = do_vmark_first(d, ci->numeric);
- ci->mark2 = do_vmark_last(d, ci->numeric);
+ ci->mark = do_vmark_first(dd->doc, ci->numeric);
+ ci->mark2 = do_vmark_last(dd->doc, ci->numeric);
if (ci->extra && ci->home->point)
- ci->mark2 = do_vmark_at_point(d, ci->home->point,
+ ci->mark2 = do_vmark_at_point(dd->doc, ci->home->point,
ci->numeric);
return 1;
}
- ret = key_lookup(d->map, ci);
+ ret = key_lookup(dd->doc->map, ci);
ret = ret ?: key_lookup(doc_default_cmd, ci);
return ret;
}
struct pane *doc_attach(struct pane *parent, struct doc *d)
{
struct pane *p;
+ struct doc_data *dd = malloc(sizeof(*dd));
- p = pane_register(parent, 0, &doc_handle, d, NULL);
+ dd->doc = d;
+
+ p = pane_register(parent, 0, &doc_handle, dd, NULL);
if (!d->home)
d->home = p;
d->ed = pane2ed(parent);
{
char buf[100];
struct cmd_info ci = {0};
- struct doc *d;
+ struct doc_data *dd;
if (!doc_default_cmd)
init_doc_defaults();
if (!key_lookup(ed->commands, &ci))
return NULL;
}
- d = ci.focus->data;
- return d;
+ dd = ci.focus->data;
+ return dd->doc;
}
struct pane *doc_open(struct editor *ed, int fd, char *name)
struct pane *doc_attach_view(struct pane *parent, struct pane *doc, char *render)
{
struct pane *p;
- p = doc_attach(parent, doc->data);
+ struct doc_data *dd = doc->data;
+ p = doc_attach(parent, dd->doc);
if (p) {
- p->point = point_new(doc->data);
+ p->point = point_new(dd->doc);
p = pane_attach(p, "view", doc, NULL);
}
if (p)
else
strcpy(nname, name);
list_for_each_entry(p, &d->ed->root.focus->children, siblings) {
- struct doc *d2 = p->data;
- if (d != d2 && strcmp(nname, d2->name) == 0) {
+ struct doc_data *d2 = p->data;
+ if (d != d2->doc && strcmp(nname, d2->doc->name) == 0) {
conflict = 1;
unique += 1;
break;
struct pane *p;
list_for_each_entry(p, &ed->root.focus->children, siblings) {
- struct doc *d = p->data;
- if (strcmp(name, d->name) == 0)
+ struct doc_data *dd = p->data;
+ if (strcmp(name, dd->doc->name) == 0)
return p;
}
return NULL;
DEF_CMD(docs_step)
{
- struct doc *doc = ci->home->data;
+ struct doc_data *dd = ci->home->data;
+ struct doc *doc = dd->doc;
struct mark *m = ci->mark;
bool forward = ci->numeric;
bool move = ci->extra;
static char *__docs_get_attr(struct doc *doc, struct mark *m,
bool forward, char *attr)
{
- struct doc *d;
+ struct doc_data *dd;
struct pane *p;
if (!m) {
}
if (!p)
return NULL;
- d = p->data;
+ dd = p->data;
if (strcmp(attr, "name") == 0)
- return d->name;
+ return dd->doc->name;
return doc_attr(p, NULL, 0, attr);
}
DEF_CMD(docs_get_attr)
{
- struct doc *doc = ci->home->data;
+ struct doc_data *dd = ci->home->data;
struct mark *m = ci->mark;
bool forward = ci->numeric != 0;
char *attr = ci->str;
- ci->str2 = __docs_get_attr(doc, m, forward, attr);
+ ci->str2 = __docs_get_attr(dd->doc, m, forward, attr);
return 1;
}
list_for_each_entry(p, &ed->root.focus->children, siblings) {
int i;
- d = p->data;
+ struct doc_data *dd = p->data;
+ d = dd->doc;
if (d->deleting == 2)
docs = d;
if (d->deleting)
struct attrset *attrs;
};
+/* this is ->data for a document pane. Only core-doc and
+ * individual document handlers can know about this.
+ */
+struct doc_data {
+ struct doc *doc;
+};
+
struct display {
char *mode, *next_mode;
int numeric, extra;
DEF_CMD(dir_load_file)
{
- struct doc *d;
+ struct doc_data *dd;
int fd = ci->extra;
char *name = ci->str;
if (ci->home)
- d = ci->home->data;
+ dd = ci->home->data;
else
return -1;
- struct directory *dr = container_of(d, struct directory, doc);
+ struct directory *dr = container_of(dd->doc, struct directory, doc);
struct list_head new;
struct dir_ent *de1, *de2;
struct mark *m, *prev;
if (!de1)
/* Nothing already in dir, so only notify at the end */
donotify = 1;
- prev = m = doc_first_mark_all(d);
+ prev = m = doc_first_mark_all(&dr->doc);
/* 'm' is always at-or-after the earliest of de1 */
while (de1 || de2) {
if (de1 &&
list_del(&de->lst);
free(de);
if (m && donotify) {
- doc_notify_change(d, prev);
- doc_notify_change(d, m);
+ doc_notify_change(&dr->doc, prev);
+ doc_notify_change(&dr->doc, m);
}
} else if (de2 &&
(de1 == NULL || strcmp(de2->name, de1->name) < 0)) {
else
list_add_tail(&de2->lst, &dr->ents);
if (m && donotify) {
- doc_notify_change(d, prev);
- doc_notify_change(d, m);
+ doc_notify_change(&dr->doc, prev);
+ doc_notify_change(&dr->doc, m);
}
} else {
/* de1 and de2 are the same. Just step over de1 and
}
}
if (!donotify) {
- m = doc_first_mark_all(d);
+ m = doc_first_mark_all(&dr->doc);
if (m)
- doc_notify_change(d, m);
+ doc_notify_change(&dr->doc, m);
}
if (name) {
dname += 1;
else
dname = name;
- doc_set_name(d, dname);
+ doc_set_name(&dr->doc, dname);
if (l > 1)
strcat(dr->fname, "/");
}
DEF_CMD(dir_same_file)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
int fd = ci->extra;
struct stat *stb = ci->misc;
- struct directory *dr = container_of(d, struct directory, doc);
+ struct directory *dr = container_of(dd->doc, struct directory, doc);
if (!dr->fname)
return 0;
DEF_CMD(dir_step)
{
- struct doc *doc = ci->home->data;
+ struct doc_data *dd = ci->home->data;
struct mark *m = ci->mark;
bool forward = ci->numeric;
bool move = ci->extra;
- struct directory *dr = container_of(doc, struct directory, doc);
+ struct directory *dr = container_of(dd->doc, struct directory, doc);
struct dir_ent *d = m->ref.d;
wint_t ret;
DEF_CMD(dir_set_ref)
{
- struct doc *d = ci->home->data;
- struct directory *dr = container_of(d, struct directory, doc);
+ struct doc_data *dd = ci->home->data;
+ struct directory *dr = container_of(dd->doc, struct directory, doc);
struct mark *m = ci->mark;
if (list_empty(&dr->ents) || ci->numeric != 1)
DEF_CMD(dir_get_attr)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
struct mark *m = ci->mark;
bool forward = ci->numeric != 0;
char *attr = ci->str;
- ci->str2 = __dir_get_attr(d, m, forward, attr);
+ ci->str2 = __dir_get_attr(dd->doc, m, forward, attr);
return 1;
}
DEF_CMD(dir_destroy)
{
- struct doc *d = ci->home->data;
- struct directory *dr = container_of(d, struct directory, doc);
+ struct doc_data *dd = ci->home->data;
+ struct directory *dr = container_of(dd->doc, struct directory, doc);
while (!list_empty(&dr->ents)) {
struct dir_ent *de = list_entry(dr->ents.next, struct dir_ent, lst);
DEF_CMD(dir_open)
{
struct pane *p = ci->home;
- struct doc *d = p->data;
- struct directory *dr = container_of(d, struct directory, doc);
+ struct doc_data *dd = p->data;
+ struct directory *dr = container_of(dd->doc, struct directory, doc);
struct dir_ent *de = ci->mark->ref.d;
struct pane *par = p->parent;
int fd;
if (p)
pane_close(p);
if (fd >= 0) {
- p = doc_open(d->ed, fd, fname);
+ p = doc_open(dd->doc->ed, fd, fname);
if (p)
p = doc_attach_view(par, p, renderer);
close(fd);
DEF_CMD(text_load_file)
{
- struct doc *d;
+ struct doc_data *dd;
int fd = ci->extra;
char *name = ci->str;
off_t size = lseek(fd, 0, SEEK_END);
struct text *t;
if (ci->home)
- d = ci->home->data;
+ dd = ci->home->data;
else
return -1;
- t = container_of(d, struct text, doc);
+ t = container_of(dd->doc, struct text, doc);
if (size < 0)
goto err;
dname += 1;
else
dname = name;
- doc_set_name(d, dname);
+ doc_set_name(dd->doc, dname);
}
return 1;
err:
DEF_CMD(text_save_file)
{
- struct doc *d = ci->home->data;
- struct text *t = container_of(d, struct text, doc);
+ struct doc_data *dd = ci->home->data;
+ struct text *t = container_of(dd->doc, struct text, doc);
if (!t->fname)
return -1;
DEF_CMD(text_same_file)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
struct stat *stb = ci->misc;
- struct text *t = container_of(d, struct text, doc);
+ struct text *t = container_of(dd->doc, struct text, doc);
if (t->fname == NULL)
return 0;
DEF_CMD(text_reundo)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
struct mark *m = ci->home->point;
bool redo = ci->numeric != 0;
struct doc_ref start, end;
int did_do = 2;
bool first = 1;
- struct text *t = container_of(d, struct text, doc);
+ struct text *t = container_of(dd->doc, struct text, doc);
while (did_do != 1) {
struct mark *m2;
if (first) {
/* Not nearby, look from the start */
- mark_reset(d, m);
+ mark_reset(&t->doc, m);
where = 1;
first = 0;
} else
i = text_retreat_towards(t, &m->ref, &end);
if (i == 0)
break;
- while ((m2 = doc_prev_mark_all_safe(d, m)) != NULL &&
+ while ((m2 = doc_prev_mark_all_safe(&t->doc, m)) != NULL &&
m2->ref.c == m->ref.c &&
m2->ref.o >= m->ref.o)
mark_backward_over(m, m2);
&start, &end) == 0)
break;
- early = doc_prev_mark_all_safe(d, m);
+ early = doc_prev_mark_all_safe(&t->doc, m);
if (early && !text_ref_same(t, &early->ref, &start))
early = NULL;
- point_notify_change(d, ci->home->point, early);
+ point_notify_change(&t->doc, ci->home->point, early);
text_check_consistent(t);
}
DEF_CMD(text_step)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
struct mark *m = ci->mark;
bool forward = ci->numeric;
bool move = ci->extra;
- struct text *t = container_of(d, struct text, doc);
+ struct text *t = container_of(dd->doc, struct text, doc);
struct doc_ref r;
wint_t ret;
DEF_CMD(text_mark_same)
{
- struct doc *d = ci->home->data;
- struct text *t = container_of(d, struct text, doc);
+ struct doc_data *dd = ci->home->data;
+ struct text *t = container_of(dd->doc, struct text, doc);
ci->extra = text_ref_same(t, &ci->mark->ref, &ci->mark2->ref);
return 1;
DEF_CMD(text_get_str)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
struct mark *from = NULL, *to = NULL;
- struct text *t = container_of(d, struct text, doc);
+ struct text *t = container_of(dd->doc, struct text, doc);
struct text_chunk *c, *first, *last;
char *ret;
int l = 0, head, tail;
DEF_CMD(text_set_ref)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
struct mark *m = ci->mark;
- struct text *t = container_of(d, struct text, doc);
+ struct text *t = container_of(dd->doc, struct text, doc);
if (list_empty(&t->text) || ci->numeric != 1) {
m->ref.c = NULL;
*/
struct text_chunk *c;
struct mark *m, *prev;
- struct doc *d = &t->doc;
+ struct doc *d = &t->doc;
list_for_each_entry(c, &t->text, lst) {
check_allocated(t, c->txt, c->end);
DEF_CMD(text_replace)
{
- struct doc *d = ci->home->data;
- struct text *t = container_of(d, struct text, doc);
+ struct doc_data *dd = ci->home->data;
+ struct text *t = container_of(dd->doc, struct text, doc);
struct mark *pm = ci->home->point;
struct mark *end = ci->mark;
char *str = ci->str;
mark_free(myend);
text_del(t, &pm->ref, l, &first);
- for (m = doc_prev_mark_all_safe(d, pm);
+ for (m = doc_prev_mark_all_safe(&t->doc, pm);
m && text_update_prior_after_change(t, &m->ref, &pm->ref, &pm->ref);
- m = doc_prev_mark_all_safe(d, m))
+ m = doc_prev_mark_all_safe(&t->doc, m))
;
for (m = doc_next_mark_all(pm);
m && text_update_following_after_change(t, &m->ref, &pm->ref, &pm->ref);
;
text_check_consistent(t);
}
- early = doc_prev_mark_all_safe(d, pm);
- if (early && !mark_same(d, early, pm))
+ early = doc_prev_mark_all_safe(&t->doc, pm);
+ if (early && !mark_same(&t->doc, early, pm))
early = NULL;
if (str) {
struct mark *m;
text_add_str(t, &pm->ref, str, &start, &first);
- for (m = doc_prev_mark_all_safe(d, pm);
+ for (m = doc_prev_mark_all_safe(&t->doc, pm);
m && text_update_prior_after_change(t, &m->ref, &start, &pm->ref);
- m = doc_prev_mark_all_safe(d, m))
+ m = doc_prev_mark_all_safe(&t->doc, m))
;
for (m = doc_next_mark_all(pm);
m && text_update_following_after_change(t, &m->ref, &start, &pm->ref);
text_check_consistent(t);
}
- point_notify_change(d, pm, early);
+ point_notify_change(&t->doc, pm, early);
ci->numeric = first;
return 1;
}
DEF_CMD(text_get_attr)
{
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
struct mark *m = ci->mark;
bool forward = ci->numeric != 0;
char *attr = ci->str;
- ci->str2 = __text_get_attr(d, m, forward, attr);
+ ci->str2 = __text_get_attr(dd->doc, m, forward, attr);
return 1;
}
char *attr = ci->str;
char *val = ci->str2;
struct text_chunk *c = ci->mark->ref.c;
- struct doc *d = ci->home->data;
- struct text *t = container_of(d, struct text, doc);
+ struct doc_data *dd = ci->home->data;
+ struct text *t = container_of(dd->doc, struct text, doc);
int o = ci->mark->ref.o;
if (!c)
c = list_next_entry(c, lst);
o = c->start;
}
- doc_notify_change(d, ci->mark);
+ doc_notify_change(&t->doc, ci->mark);
return attr_set_str(&c->attrs, attr, val, o);
}
DEF_CMD(text_destroy)
{
- struct doc *d = ci->focus->data;
- struct text *t = container_of(d, struct text, doc);
+ struct doc_data *dd = ci->focus->data;
+ struct text *t = container_of(dd->doc, struct text, doc);
while (!list_empty(&t->text)) {
struct text_chunk *c = list_entry(t->text.next, struct text_chunk, lst);
* If we hit start-of-file without finding newline, return -1;
*/
struct mark *m = ci->mark;
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
+ struct doc *d = dd->doc;
struct mark *boundary = NULL;
int since_boundary;
int rpt = RPT_NUM(ci);
* include that between '<>'.
*/
struct buf b;
- struct doc *d = ci->home->data;
+ struct doc_data *dd = ci->home->data;
+ struct doc *d = dd->doc;
struct mark *m = ci->mark;
struct mark *pm = ci->mark2; /* The location to render as focus */
int o = ci->numeric;
DEF_CMD(format_close)
{
- struct rl_data *rl = ci->home->data;
+ struct rf_data *rl = ci->home->data;
free(rl);
return 1;
}