]> git.neil.brown.name Git - edlib.git/commitdiff
Introduce closed_ok flag on commands.
authorNeilBrown <neil@brown.name>
Wed, 13 Sep 2023 22:32:17 +0000 (08:32 +1000)
committerNeilBrown <neil@brown.name>
Fri, 15 Sep 2023 03:03:12 +0000 (13:03 +1000)
If closed_ok is set, then it is safe to call the command even if ->home
is DAMAGED_CLOSED.  This will eventually replace checks on "Close".
For now it allows doc_pass_on to pass commands on to the doc even
when the display stack is shutting down.  notmuch needs this to ask
the query doc to refresh when a view is closed.

Signed-off-by: NeilBrown <neil@brown.name>
core-doc.c
core-keymap.c
core-pane.h
core.h
lang-python.c

index 645d2825f831f2d21d5ace450dc3157489a90b73..1e154290ab8f64a3bcb55fe6ef9aaa41be861d22 100644 (file)
@@ -639,7 +639,7 @@ DEF_CMD(doc_request_notify)
        return 1;
 }
 
-DEF_CMD(doc_notify)
+DEF_CMD_CLOSED(doc_notify)
 {
        /* Key is "doc:notify:..." */
        int ret = pane_notify(ksuffix(ci, "doc:notify:"),
@@ -679,7 +679,8 @@ static int do_del_view(struct doc *d safe, int v,
                                        call("editor:notify:Message:broadcast",
                                             owner, 0, NULL,
                                             "WARNING mark not freed by Close:mark");
-                                       LOG("WARNING Mark not freed by Close:mark");
+                                       LOG("WARNING Mark on %s not freed by Close:mark",
+                                           owner->name);
                                        warned = True;
                                }
                                m->mdata = NULL;
@@ -1165,7 +1166,7 @@ DEF_CMD(doc_clip)
        return 1;
 }
 
-DEF_CMD(doc_pass_on)
+DEF_CMD_CLOSED(doc_pass_on)
 {
        struct doc_data *dd = ci->home->data;
        int ret = home_call(dd->doc, ci->key, ci->focus, ci->num,
index d766953ed122b10960586ae51e9dbc9588a74a76..14a5e520aa4f8129ca83e44545f4c09d7921b5bc 100644 (file)
@@ -558,7 +558,9 @@ int key_handle(const struct cmd_info *ci safe)
 
        while (p) {
                int ret = Efallthrough;
-               if (p->handle && !(p->damaged & DAMAGED_CLOSED)) {
+               if (p->handle &&
+                   (p->handle->closed_ok ||
+                    !(p->damaged & DAMAGED_CLOSED))) {
                        vci->home = p;
                        vci->comm = p->handle;
                        /* Don't add this to the call stack as it
index 6c323c4461f90576baa48cb40140731141a0b1df..ebc27fa0ae474d0860ca7e1da151e15c1c5d5b52 100644 (file)
@@ -132,6 +132,7 @@ static inline int do_call_val(enum target_type type, struct pane *home,
                if (home)
                        ci.home = home;
                if ((home->damaged & DAMAGED_CLOSED) &&
+                   !home->handle->closed_ok &&
                    ci.key[0] != 'C' && /* Compile will often optimise
                                         * the strncmp away
                                         */
@@ -148,7 +149,8 @@ static inline int do_call_val(enum target_type type, struct pane *home,
                        return Efail;
                if (home)
                        ci.home = home;
-               if (ci.home->damaged & DAMAGED_CLOSED)
+               if (ci.home->damaged & DAMAGED_CLOSED &&
+                   !comm2a->closed_ok)
                        return Efallthrough;
                ci.comm = comm2a;
                ci.comm2 = comm2b;
diff --git a/core.h b/core.h
index af62ada03d6cf235fa2f1c654afb3ed49ee307a0..25fcb925344e1c904a8cf690a3dd4cb41c0a27f6 100644 (file)
--- a/core.h
+++ b/core.h
@@ -64,10 +64,11 @@ void LOG_BT(void);
 struct pane ;
 
 struct command {
-       int     (*func)(const struct cmd_info *ci safe);
-       int     refcnt; /* only if 'free' is not NULL */
-       void    (*free)(struct command *c safe);
-       const char *name;
+       int             (*func)(const struct cmd_info *ci safe);
+       unsigned int    refcnt; /* only if 'free' is not NULL */
+       unsigned int    closed_ok:1;
+       void            (*free)(struct command *c safe);
+       const char       *name;
 };
 
 enum edlib_errors {
@@ -92,7 +93,7 @@ static inline struct command *safe command_get(struct command * safe c)
 
 static inline void command_put(struct command *c)
 {
-       if (c && c->free && c->refcnt-- == 1)
+       if (c && c->free && --c->refcnt == 0)
                c->free(c);
 }
 
@@ -300,13 +301,23 @@ struct lookup_cmd {
        struct map      **m safe;
 };
 
-#define CMD(_name) {.func = _name ## _func ,           \
-                   .refcnt = 0,                        \
-                   .free = NULL,                       \
-                   .name = # _name,                    \
+#define CMD(_name) {                                   \
+               .func = _name ## _func ,                \
+               .refcnt = 0,                            \
+               .closed_ok = 0,                         \
+               .free = NULL,                           \
+               .name = # _name,                        \
+       }
+#define CMD_CLOSED(_name) {                            \
+               .func = _name ## _func ,                \
+               .refcnt = 0,                            \
+               .closed_ok = 1,                         \
+               .free = NULL,                           \
+               .name = # _name,                        \
        }
 #define CB(_name) {.func = _name ## _func ,            \
                   .refcnt = 0,                         \
+                  .closed_ok = 0,                      \
                   .free = NULL,                        \
                   .name = # _name,                     \
        }
@@ -315,6 +326,10 @@ struct lookup_cmd {
        static int _name ## _func(const struct cmd_info *ci safe); \
        static struct command _name = CMD(_name);       \
        static int _name ## _func(const struct cmd_info *ci safe)
+#define DEF_CMD_CLOSED(_name) \
+       static int _name ## _func(const struct cmd_info *ci safe); \
+       static struct command _name = CMD_CLOSED(_name);        \
+       static int _name ## _func(const struct cmd_info *ci safe)
 #define REDEF_CMD(_name) \
        static int _name ## _func(const struct cmd_info *ci safe)
 #define DEF_EXTERN_CMD(_name) \
@@ -334,6 +349,7 @@ struct lookup_cmd {
        static struct lookup_cmd _name = {              \
                .c.func = key_lookup_cmd_func,          \
                .c.refcnt = 0,                          \
+               .c.closed_ok = 1,                       \
                .c.free = NULL,                         \
                .c.name = #_name,                       \
                .m = &_map,                             \
@@ -354,6 +370,7 @@ int key_pfx_func(const struct cmd_info *ci safe);
        static struct pfx_cmd _name = {                 \
                .c.func = key_pfx_func,                 \
                .c.refcnt = 0,                          \
+               .c.closed_ok = 1,                       \
                .c.free = NULL,                         \
                .c.name = "prefix" #_pfx,               \
                .pfx = _pfx,                            \
index 2152dcd747cc4669030526976b9ed92b1531cea5..6c8ccd1ceacf31b7c1207fc7504896f2c173c043 100644 (file)
@@ -114,6 +114,7 @@ static struct python_command *export_callable(PyObject *callable safe)
        c->c = python_call;
        c->c.free = python_free_command;
        c->c.refcnt = 0;
+       c->c.closed_ok = 0;
        command_get(&c->c);
        Py_INCREF(callable);
        c->callable = callable;
@@ -722,6 +723,7 @@ static int do_Pane_init(Pane *self safe, PyObject *args, PyObject *kwds,
        self->map = key_alloc();
        key_add(self->map, "Close:mark", &python_close_mark);
        self->cmd = python_pane_call;
+       self->cmd.closed_ok = 1;
        self->cmd.free = python_pane_free;
        if (self->ob_base.ob_type)
                self->cmd.name = self->ob_base.ob_type->tp_name;