mark. When you start with a pointer you can immediately find a nearby
mark of any group. Pointers cannot store extra arbitrary data.
-The first time a mark is moved to a different location in the document a
-"mark:moving" message is sent to the pane which owns the mark (usually a
-document). Subsequent movement will not cause any notification until
-"mark_ack(mark)" is called. This clears a flag on the mark so that the
-next movement will again cause a message to be sent. This is useful for
-various tasks including ensuring that any drawing of the cursor is
-updated properly.
+Calling "mark_watch(mark)" on a mark causes it to have a flag set so
+that certain movements of marks cause a notification to be sent to the
+pane which owns the mark - usually a document. When a notification is
+sent, the "watched" flag is cleared on the mark that was moved (if it
+was already set), so the notification handler will need to call
+mark_watch(mark) again if it needs to see the next movement.
+
+Whenever a watch mark is moved, whether by a movement command
+("doc:char", "doc:set-ref" etc) or by moving it to the location of
+another mark with mark_to_mark(), a "mark:moving" notification is sent
+to the owner of the mark. The primary mark in the notification is the
+mark that was moved. The focus is the mark owner.
+
+Whenever a mark is moved with mark_to_mark() to a mark which is watched,
+a "mark:arrived" notification is sent to the mark owner. In this case
+the destination mark is passed to the notification as the secondary mark
+(mark2). If mark_to_mark() is called with both marks being watch, both
+notifications are sent.
### working with marks
- mark_dup(mark)
- mark_dup_view(mark)
- mark_free(mark)
-- mark_ack(mark)
+- mark_watch(mark)
- mark_next(mark)
- mark_prev(mark)
- mark_reset(pane, mark, int)
- [ ] commands to resolve a conflict
- [ ] command to apply a patch hunk
- [ ] whitespace: don't show errors unless doc has been changed.???
+- [ ] mailto: links should be sent to nm (if active)
+- [ ] press K:Enter on a link should do something
- [ ] split notmuch into two databases, last 6 months and the rest.
- [ ] script to move messages every week - but not deleted messages
Bugs to be fixed
----------------
-- [ ] I cannot dup a mark in a mark:moving handler. That is too
+- [ ] multipart must handle Notify:Close better. It should NULL out the
+ pointer to the pane, and always check it isn't NULL.
+- [X] I cannot dup a mark in a mark:moving handler. That is too
restrictive. I need a different way to decide that incoming marks
get notified.
+ Maybe generate "mark:arrived" when a mark is moved to an
+ interesting mark, and flag new marks as "moved" so they don't
+ initially send a mark:moved notification.
- [X] doc:text passes an unterminated string to "content" for
doc:content. num2 is the length. python doesn't know this
and so tries to convert it all to utf8. This is wasteful as
double them
- [X] when w3m text is copied we get the markup. I find this useful,
but is it *right*??
-- [ ] notmuch: don't mark up links in text created by w3m - they are
- already marked if needed.
+- [X] notmuch: don't mark up links in text created by w3m - they are
+ already marked if needed. This was fixed by making conversion
+ async so:
+- [ ] async email part converts need to do their own URL marking.
+ PDF particularly, and html2md. Maybe others.
- [X] notmuch: "reply" should clear unread/new flags.
- [X] transparent images appear in email with horiz lines
- [X] Replying to w3m/html mail results in unsightly markup in reply
isn't an md-mode yet!
- [X] config.py should load from $HOME/.config/edlib/config.py
exec(read())
-- [ ] lang-python should put each mode in a separate module
+- [ ] lang-python should put each module in a separate module
Maybe PyImport_ExecCodeModuleEx() after reading and compile()ing
the source file. Or set up path to find edlib modules.
- [X] redefining doc:char but not doc:content in mail-compose causes
- [ ] email: urls should not be followed unless they are visible.
Maybe display in the message window, which might be made larger
just for this purpose.
+ Maybe "Message-button"
- [ ] renderline *knows* about scaling and when it places the cursor
in an image, it gets it wrong for ncurses. It should ask about
scaling.
dd->old_point = mark_dup(dd->point);
else
mark_to_mark(dd->old_point, dd->point);
- mark_ack(dd->point);
+ mark_watch(dd->point);
return 1;
}
pane_add_notify(p, doc, "doc:notify-viewers");
pane_add_notify(p, doc, "mark:moving");
call("doc:notify:doc:revisit", doc, 0);
- mark_ack(m);
+ mark_watch(m);
}
static struct pane *doc_attach(struct pane *parent)
static void notify_mark_moving(struct mark *m safe, struct mark *m2)
{
- if (m2 && !(m2->flags & MARK_FLAG_MOVED))
- /* Any mark moved here is notified */;
- else if (m->flags & MARK_FLAG_MOVED)
- return;
- m->flags |= MARK_FLAG_MOVED;
+ if (m->flags & MARK_FLAG_WATCHED) {
+ m->flags &= ~MARK_FLAG_WATCHED;
+ pane_notify("mark:moving", m->owner, 0, m);
+ }
- pane_notify("mark:moving", m->owner, 0, m, NULL, 0, m2);
+ if (m2 && (m2->flags & MARK_FLAG_WATCHED))
+ pane_notify("mark:arrived", m->owner, 0, m, NULL, 0, m2);
}
-void mark_ack(struct mark *m)
+void mark_watch(struct mark *m)
{
if (m)
- m->flags &= ~MARK_FLAG_MOVED;
+ m->flags |= MARK_FLAG_WATCHED;
}
static void mark_ref_copy(struct mark *to safe, struct mark *from safe)
INIT_TLIST_HEAD(&ret->view, GRP_MARK);
ret->viewnum = view;
hlist_add_head(&ret->all, &d->marks);
- ret->flags = MARK_FLAG_MOVED;
if (view == MARK_POINT) {
struct point_links *lnk = alloc_buf(sizeof(*lnk) +
* understands .ref
*/
};
-#define MARK_FLAG_MOVED 1
+#define MARK_FLAG_WATCHED 1
static inline bool mark_valid(struct mark *m)
{
struct mark *safe mark_dup(struct mark *m safe);
struct mark *safe mark_dup_view(struct mark *m safe);
void mark_free(struct mark *m);
-void mark_ack(struct mark *m);
+void mark_watch(struct mark *m);
struct mark *mark_first(struct doc *d safe);
struct mark *mark_next(struct mark *m safe);
return Py_None;
}
-static PyObject *Mark_ack(Mark *self safe, PyObject *args)
+static PyObject *Mark_watch(Mark *self safe, PyObject *args)
{
struct mark *m = self->mark;
PyErr_SetString(PyExc_TypeError, "Mark has been freed");
return NULL;
}
- mark_ack(m);
+ mark_watch(m);
Py_INCREF(Py_None);
return Py_None;
}
"If this mark is in range, move to end"},
{"release", (PyCFunction)Mark_release, METH_NOARGS,
"release a vmark so it can disappear"},
- {"ack", (PyCFunction)Mark_ack, METH_NOARGS,
+ {"watch", (PyCFunction)Mark_watch, METH_NOARGS,
"acknowledge movement of a point - allow further notifications"},
{"step", (PyCFunction)Mark_step, METH_VARARGS,
"Move mark over any adjacent marks with same reference"},
* stacking b64 impossible - but who would want to?
* This can have a value "0", "1", "2". A mark is never on the
* 4th char of a QUAD.
- * doc:set-ref initialises this as does a mark:moving notification
+ * doc:set-ref initialises this as does a mark:arrived notification
* which references another mark. doc:char and doc:byte will use
* the pos to know how to interpret, and will update it after any
* movement as will doc:content.
pos -= 4;
ps[0] += pos;
attr_set_str(&m->attrs, "b64-pos", ps);
- mark_ack(m);
+ mark_watch(m);
}
static int get_pos(struct mark *m safe)
return Efallthrough;
}
-DEF_CMD(base64_moving)
+DEF_CMD(base64_arrived)
{
struct mark *m = ci->mark;
struct mark *ref = ci->mark2;
if (get_pos(m) >= 0)
/* Interesting mark, keep tracking it */
- mark_ack(m);
+ mark_watch(m);
if (!ref)
return 1;
pos = get_pos(ref);
p = pane_register(ci->focus, 0, &b64_handle.c);
if (!p)
return Efail;
- call("doc:request:mark:moving", p);
+ call("doc:request:mark:arrived", p);
return comm_call(ci->comm2, "callback:attach", p);
}
key_add(b64_map, "doc:content", &base64_content);
key_add(b64_map, "doc:content-bytes", &base64_content);
key_add(b64_map, "doc:set-ref", &base64_setref);
- key_add(b64_map, "mark:moving", &base64_moving);
+ key_add(b64_map, "mark:arrived", &base64_arrived);
key_add(b64_map, "Free", &edlib_do_free);
call_comm("global-set-command", ed, &b64_attach, 0, NULL, "attach-base64");
title = default_title;
title = format_status(title, ci->focus, pm);
- mark_ack(pm);
+ mark_watch(pm);
if (vd->border & BORDER_LEFT) {
/* Left border is (currently) always a scroll bar */
def handle_refresh(self, key, focus, **a):
"handle:Refresh:view"
point = focus.call("doc:point", ret = 'mark')
- point.ack()
+ point.watch()
skip_pre = False
skip_post = False
if self.pre_paren: