]> git.neil.brown.name Git - edlib.git/commitdiff
Introduce pane_register_root()
authorNeilBrown <neil@brown.name>
Sat, 10 Jun 2023 04:03:34 +0000 (14:03 +1000)
committerNeilBrown <neil@brown.name>
Wed, 28 Jun 2023 07:51:41 +0000 (17:51 +1000)
pane_register_root() is an internal interface, called only by
editor_new(), which creates a root pane, with ->parent pointing to
itself.
pane_register() and doc_register() must now be given a non-NULL parent.

Signed-off-by: NeilBrown <neil@brown.name>
15 files changed:
DOC/TODO.md
core-doc.c
core-editor.c
core-pane.c
core.h
display-ncurses.c
internal.h
lang-python.c
lib-keymap.c
lib-linecount.c
lib-view.c
lib-viewer.c
mode-emacs.c
render-complete.c
render-lines.c

index bd6486ad447108aa6692477889162829063bdc77..a3698224d413ea164a6b5da2376a703b0835dc7b 100644 (file)
@@ -11,7 +11,7 @@ the file.
 
 - [X] give every pane a link to root/editor main and use that
       instead of statics.  Then maybe times_up() can use pane_too_long()
-- [ ] mark DEF_CMD structs as const
+- [X] mark DEF_CMD structs as const- NO, ->refcnt is not constant.
 - [X] rexel: don't abort if something looks wrong, just fail.
 
 ### Small
@@ -26,6 +26,8 @@ the file.
 - [ ] emacs: :C-q to recognise names of Unicode chars: e.g. WASTEBASKET
        Possibly matches a list which continued :C-q cycles through
 - [ ] linecount 'view' mode improvements
+- [ ] allocate pane->data together with pane.  A single allocation so
+      that we can avoid the cost of a dereference.
 
 ### Medium
 
@@ -76,7 +78,9 @@ Core features
 - [ ] LOG_BT() doesn't see TYPE_pane and TYPE_comm calls.
 - [ ] give every pane a link to root/editor main and use that
       instead of statics.  Then maybe times_up() can use pane_too_long()
-- [ ] mark DEF_CMD structs as const
+- [ ] allocate pane->data together with pane.  A single allocation so
+      that we can avoid the cost of a dereference.
+- [X] mark DEF_CMD structs as const - doesn't work due to refcount
 - [ ] teach input to allow a repeat command to be registered so that e.g.
       search/replace and do a bit of work, then ask to be called again.
       input can cancel this on suitable input.
index b060f5ed83ce8e43e50e9bb86d8fec847491b621..77672fd7d9ae31cb47f64100e4c763fab952d4ce 100644 (file)
@@ -60,18 +60,17 @@ static void doc_init(struct doc *d safe)
        d->refcnt = NULL;
 }
 
-struct pane *__doc_register(struct pane *parent,
-                                struct command *handle safe,
-                                struct doc *doc safe,
-                                void *data safe,
-                                short data_size)
+struct pane *__doc_register(struct pane *parent safe,
+                           struct command *handle safe,
+                           struct doc *doc safe,
+                           void *data safe,
+                           short data_size)
 {
        struct pane *p;
 
        ASSERT(data_size == 0 || data == (void*)doc);
        /* Documents are always registered against the root */
-       if (parent)
-               parent = pane_root(parent);
+       parent = pane_root(parent);
        doc_init(doc);
        p = __pane_register(parent, 0, handle, doc, data_size);
        return p;
index c7173531f483e2a2ff6f4a2d799c59790a2d7952..a4fc8b820a426624eedd488294183e84fd364641 100644 (file)
@@ -514,7 +514,7 @@ struct pane *editor_new(void)
        key_add_chain(ei->map, ed_map);
        ei->cmd = ed_handle;
        ei->cmd.m = &ei->map;
-       ed = pane_register(NULL, 0, &ei->cmd.c, ei);
+       ed = pane_register_root(&ei->cmd.c, ei, sizeof(ei));
 
        if (ed) {
                doc_setup(ed);
index aab46946027d957daae71cdb6bbb54e092e39820..d5a5410b75927755770a82f324f4bb07ad64c552 100644 (file)
@@ -144,9 +144,9 @@ void pane_damaged(struct pane *p, int type)
        }
 }
 
-struct pane *__pane_register(struct pane *parent, short z,
-                            struct command *handle safe,
-                            void *data, short data_size)
+static struct pane *__do_pane_register(struct pane *parent, short z,
+                                      struct command *handle safe,
+                                      void *data, short data_size)
 {
        struct pane *p;
 
@@ -180,6 +180,19 @@ struct pane *__pane_register(struct pane *parent, short z,
        return p;
 }
 
+struct pane *__pane_register(struct pane *parent safe, short z,
+                            struct command *handle safe,
+                            void *data, short data_size)
+{
+       return __do_pane_register(parent, z, handle, data, data_size);
+}
+
+struct pane *pane_register_root(struct command *handle safe,
+                               void *data, short data_size)
+{
+       return __do_pane_register(NULL, 0, handle, data, data_size);
+}
+
 /* 'abs_z' is a global z-depth number (->z is relative to parent)
  * 'abs_z' of root is 0, and abs_z of every other pane with z<=0 is 1 more than
  * abs_z or parent, and abs_z of pane with z>0 is 1 more than max abs_z
diff --git a/core.h b/core.h
index c965abbfee706d4a50e5b61a720d9c6872c75433..3631c374bf04ed2bcdcea06b3d63aae6d5086539 100644 (file)
--- a/core.h
+++ b/core.h
@@ -483,14 +483,14 @@ enum {
 #define DAMAGED_NEED_CALL (DAMAGED_SIZE | DAMAGED_REFRESH)
 
 struct xy {short x,y;};
-struct pane * __pane_register(struct pane *parent, short z,
+struct pane * __pane_register(struct pane *parent safe, short z,
                              struct command *handle safe, void *data,
                              short data_size);
 #define pane_register(...) VFUNC(pane_register, __VA_ARGS__)
 #define pane_register4(p,z,h,d) __pane_register(p,z,h,d,sizeof((d)[0]))
 #define pane_register3(p,z,h) __pane_register(p,z,h,NULL, 0)
 
-struct pane *__doc_register(struct pane *parent,
+struct pane *__doc_register(struct pane *parent safe,
                            struct command *handle safe,
                            struct doc *doc safe,
                            void *data safe,
index e960d6f8a43ffaea765575fbc30682987fd0379a..62d3009559514ee9cf7e9c0449a3eb08966d91c3 100644 (file)
@@ -1338,7 +1338,7 @@ static void ncurses_start(struct pane *p safe)
        pane_resize(p, 0, 0, cols, rows);
 }
 
-static struct pane *ncurses_init(struct pane *ed,
+static struct pane *ncurses_init(struct pane *ed safe,
                                 const char *tty, const char *term)
 {
        SCREEN *scr;
index 750ff33cbeaf437392c23a0de8d89c0895424a81..903f773d0464b2dca6f1df2d4f82b821cd2085ad 100644 (file)
@@ -16,6 +16,9 @@ struct mark *do_vmark_at_or_before(struct doc *d safe, struct mark *m safe, int
 struct mark *do_mark_at_point(struct mark *pt safe, int view);
 void __mark_free(struct mark *m);
 
+struct pane *pane_register_root(struct command *handle safe,
+                               void *data, short data_size);
+
 void editor_delayed_free(struct pane *ed safe, struct pane *p safe);
 void editor_delayed_mark_free(struct mark *m safe);
 void doc_setup(struct pane *ed safe);
index 19350e04fa9ad044c2b35c27a8b64ef305f3a33d..424d012a41b54dd4a9071d8de5fef614222310b6 100644 (file)
@@ -700,7 +700,6 @@ static int __Pane_init(Pane *self safe, PyObject *args, PyObject *kwds,
                       Pane **parentp safe,
                       int *zp safe)
 {
-       Pane *parent = NULL;
        int ret;
        static const char *keywords[] = {"parent", "z", NULL};
 
@@ -715,21 +714,11 @@ static int __Pane_init(Pane *self safe, PyObject *args, PyObject *kwds,
                return 0;
 
        /* Pane(parent=None, z=0) */
-       ret = PyArg_ParseTupleAndKeywords(args, kwds, "|Oi", (char**)keywords,
-                                         &parent, zp);
+       ret = PyArg_ParseTupleAndKeywords(args, kwds, "O!|i", (char**)keywords,
+                                         &PaneType, parentp, zp);
        if (ret <= 0)
                return -1;
 
-       if ((PyObject*)parent == Py_None)
-               parent = NULL;
-
-       if (parent && !PyObject_TypeCheck(parent, &PaneType)) {
-               PyErr_SetString(PyExc_TypeError, "First arg must be edlib.Pane or None");
-               return -1;
-       }
-
-       *parentp = parent;
-
        self->map = key_alloc();
        key_add(self->map, "Close:mark", &python_close_mark);
        self->cmd = python_pane_call;
@@ -748,13 +737,14 @@ static int Pane_init(Pane *self safe, PyObject *args, PyObject *kwds)
 
        if (ret <= 0)
                return ret;
+       if (!parent || !parent->pane)
+               return -1;
 
        /* The pane holds a reference to the Pane through the ->handle
         * function
         */
        Py_INCREF(self);
-       self->pane = pane_register(parent ? parent->pane : NULL,
-                                  z, &self->cmd, self);
+       self->pane = pane_register(parent->pane, z, &self->cmd, self);
        if (self->pane)
                pane_get(self->pane);
        return 0;
@@ -766,12 +756,13 @@ static int Doc_init(Doc *self, PyObject *args, PyObject *kwds)
        int z = 0;
        int ret = __Pane_init((Pane*safe)self, args, kwds, &parent, &z);
 
-       if (ret <= 0 || !self)
+       if (ret <= 0)
                return ret;
+       if (!self || !parent || !parent->pane)
+               return -1;
 
        self->cmd.func = python_doc_call_func;
-       self->pane = __doc_register(parent ? parent->pane : NULL,
-                                   &self->cmd, &self->doc, self, 0);
+       self->pane = __doc_register(parent->pane, &self->cmd, &self->doc, self, 0);
        if (self->pane)
                pane_get(self->pane);
        self->doc.refcnt = mark_refcnt;
index 33e1a93921135b8de113e4dd4436f69cd418c004..86f6dd165b91743d10b2cb360223666ecd23b2ec 100644 (file)
@@ -17,7 +17,7 @@ struct key_data {
        struct command  *globalcmd;
 };
 
-static struct pane *safe do_keymap_attach(struct pane *p);
+static struct pane *safe do_keymap_attach(struct pane *p safe);
 
 DEF_CMD(keymap_handle)
 {
@@ -65,7 +65,7 @@ DEF_CMD(keymap_handle)
        return Efallthrough;
 }
 
-static struct pane *safe do_keymap_attach(struct pane *p)
+static struct pane *safe do_keymap_attach(struct pane *p safe)
 {
        struct key_data *kd = malloc(sizeof(*kd));
 
index b30744720314ccef9325ca7c591915402a802286..d01e258490f8a271db6ea20baee3d01a64b80fa7 100644 (file)
@@ -391,7 +391,8 @@ DEF_CMD(count_lines)
                struct pane *p;
 
                alloc(cli, pane);
-               p = pane_register(NULL, 0, &handle_count_lines.c, cli);
+               p = pane_register(pane_root(ci->focus), 0,
+                                 &handle_count_lines.c, cli);
                if (!p)
                        return Efail;
                cli->view_num = home_call(ci->focus, "doc:add-view", p) - 1;
index 51e407b1125df18a9eb02cd256d8025e27dd99fc..7ae09c88bc1a1d8d29134e7d443dda1c68acc9ce 100644 (file)
@@ -41,7 +41,7 @@ enum {
 
 static struct map *view_map safe;
 DEF_LOOKUP_CMD(view_handle, view_map);
-static struct pane *do_view_attach(struct pane *par, int border);
+static struct pane *do_view_attach(struct pane *par safe, int border);
 static int calc_border(struct pane *p safe);
 
 static const char default_status[] =
@@ -392,7 +392,7 @@ DEF_CMD(view_reposition)
        return Efallthrough;
 }
 
-static struct pane *do_view_attach(struct pane *par, int border)
+static struct pane *do_view_attach(struct pane *par safe, int border)
 {
        struct view_data *vd;
        struct pane *p;
index 43ee2890b98cc3f1a35ec363d77c06ae839c6339..aa98fcdb5d7abbe1352347c1ca8b6a9c94a605a6 100644 (file)
@@ -25,7 +25,7 @@ struct viewer_data {
        bool active;
 };
 
-static struct pane *safe do_viewer_attach(struct pane *par)
+static struct pane *safe do_viewer_attach(struct pane *par safe)
 {
        struct viewer_data *vd;
 
index 2f3991e968ad98d9bacb2ab77d16c1ea81841420..01dcd3f43f7c36eaed3cdb33fd9c70017a1c7291 100644 (file)
@@ -1797,7 +1797,8 @@ DEF_CMD(emacs_shell)
                call("doc:set-name", p, 0, NULL, "Shell Command", -1);
                p = call_ret(pane, "attach-history", p, 0, NULL, "*Shell History*",
                             0, NULL, "popup:close");
-               p = pane_register(p, 0, &find_handle.c, "shellcmd");
+               if (p)
+                       p = pane_register(p, 0, &find_handle.c, "shellcmd");
                if (p && ci->comm2)
                        comm_call(ci->comm2, "cb", p);
                return 1;
@@ -2030,7 +2031,8 @@ DEF_CMD(emacs_command)
        call("doc:set-name", p, 0, NULL, "K:Ax command", -1);
        p = call_ret(pane, "attach-history", p, 0, NULL, "*Command History*",
                     0, NULL, "popup:close");
-       pane_register(p, 0, &find_handle.c, "cmd");
+       if (p)
+               pane_register(p, 0, &find_handle.c, "cmd");
        return 1;
 }
 
index 318071665985ba6e781a5178ae02cef49fb76580..2d71ee8590f5252aaacaae1ce3519d04b8a980a5 100644 (file)
@@ -164,7 +164,7 @@ DEF_CMD(complete_free)
        return 1;
 }
 
-static struct pane *complete_pane(struct pane *focus)
+static struct pane *complete_pane(struct pane *focus safe)
 {
        struct pane *complete;
        struct complete_data *cd;
index 4f581a5ad385b34d969bf291e2ed9e978de1fd43..72f0bc81f5c58890fb545d139f811d79f15f6309 100644 (file)
@@ -1840,8 +1840,11 @@ REDEF_CMD(render_lines_attach)
        rl->target_y = -1;
        rl->do_wrap = 1;
        p = ci->focus;
-       if (strcmp(ci->key, "attach-render-text") == 0)
+       if (strcmp(ci->key, "attach-render-text") == 0) {
                p = call_ret(pane, "attach-markup", p);
+               if (!p)
+                       p = ci->focus;
+       }
        p = pane_register(p, 0, &render_lines_handle.c, rl);
        if (!p) {
                free(rl);