]> git.neil.brown.name Git - edlib.git/blob - lang-python.c
Change remaining doc:step callers to doc:char
[edlib.git] / lang-python.c
1 /*
2  * Copyright Neil Brown ©2015-2021 <neil@brown.name>
3  * May be distributed under terms of GPLv2 - see file:COPYING
4  *
5  * Python3 bindings for edlib.
6  * An edlib command "python-load" will read and execute a python
7  * script.
8  * It can use "edlib.editor" to get the editor instance, and can
9  * use "edlib.call()" to issue edlib commands.
10  *
11  * Types available are:
12  *  edlib.pane  - a generic pane.  These form a tree of which edlib.editor
13  *                is the root.
14  *                get/set operations for x,y,z,w,h,cx,cy as numbers
15  *                     changes x,y,w,h call pane_resize()
16  *                     z cannot be changed (only pane_register() does that )
17  *                     cx,cy can be changed freely.
18  *                  'parent' and 'focus' can be read but not written
19  *                method for 'children' provides first child as an iterator.
20  *                method abs() converts relative co-ords to absolute.
21  *                rel() converts absolute co-ords to relative.
22  *  edlib.mark  - these reference locations in a document.  The document is
23  *                not directly accessible, it can only be accessed through
24  *                a pane (which may translate events and results).
25  *                get/set for viewnum (cannot be set)
26  *                iterator for both 'all' and 'view' lists.
27  *                no methods yet.
28  *
29  *  edlib.comm  - a command which can be used to invoke code in other
30  *                module editors.  These look like any other python
31  *                callable.  They cannot be explicitly created, but can
32  *                be received from and passed to other commands.
33  *
34  */
35
36 #ifdef __CHECKER__
37 /* Need to define stuff that pyconfig needs */
38 #define __linux__
39 #define __x86_64__
40 #define __LP64__
41
42
43 //#define PyType_HasFeature __PyType_HasFeature
44 #include <Python.h>
45 #undef PyType_HasFeature __PyType_HasFeature
46 int PyType_HasFeature(PyTypeObject *type, unsigned long feature);
47
48 #undef Py_INCREF
49 #define Py_INCREF(op) (0)
50 #undef Py_DECREF
51 #define Py_DECREF(op) (0)
52 #undef Py_XDECREF
53 #define Py_XDECREF(op) (0)
54 #undef Py_IS_TYPE
55 #define Py_IS_TYPE(ob, type) (ob == (void*)type)
56 #else
57 #include <Python.h>
58 #endif
59 #define MARK_DATA_PTR PyObject
60 #define PRIVATE_DOC_REF
61
62 struct doc_ref {
63         PyObject *c;
64         int o;
65 };
66
67 #include <signal.h>
68 #include "core.h"
69 #include "misc.h"
70 #include "rexel.h"
71
72 #define SAFE_CI {.key=safe_cast NULL,\
73                  .home=safe_cast NULL,\
74                  .focus=safe_cast NULL,\
75                  .comm=safe_cast NULL,\
76         }
77
78 static PyObject *Edlib_CommandFailed;
79 static PyObject *EdlibModule;
80
81 static struct pane *ed_pane;
82
83 static char *module_dir;
84 static char *python_as_string(PyObject *s, PyObject **tofree safe);
85
86 /* Python commands visible to edlib are wrapped in
87  * the python_command.  There is only one per callback,
88  * so that edlib code can compare for equalty.
89  */
90 struct python_command {
91         struct command  c;
92         PyObject        *callable;
93         struct list_head lst;
94 };
95 static LIST_HEAD(exported_commands);
96
97 DEF_CMD(python_call);
98 DEF_CMD(python_pane_call);
99 DEF_CMD(python_doc_call);
100 static void python_free_command(struct command *c safe);
101
102 static struct python_command *export_callable(PyObject *callable safe)
103 {
104         struct python_command *c;
105
106         list_for_each_entry(c, &exported_commands, lst)
107                 if (c->callable == callable) {
108                         command_get(&c->c);
109                         return c;
110                 }
111
112         c = malloc(sizeof(*c));
113         c->c = python_call;
114         c->c.free = python_free_command;
115         c->c.refcnt = 0;
116         command_get(&c->c);
117         Py_INCREF(callable);
118         c->callable = callable;
119         list_add(&c->lst, &exported_commands);
120         return c;
121 }
122
123 typedef struct {
124         PyObject_HEAD;
125         struct pane     *pane;
126         struct command  cmd;
127         struct map      *map;
128         int             map_init;
129 } Pane;
130 static PyTypeObject PaneType;
131
132 typedef struct {
133         PyObject_HEAD;
134         struct pane     *pane;
135 } PaneIter;
136 static PyTypeObject PaneIterType;
137
138 typedef struct {
139         PyObject_HEAD;
140         struct pane     *pane;
141         struct command  cmd;
142         struct map      *map;
143         int             map_init;
144         struct doc      doc;
145 } Doc;
146 static PyTypeObject DocType;
147
148 typedef struct {
149         PyObject_HEAD;
150         struct mark     *mark;
151 } Mark;
152 static PyTypeObject MarkType;
153 static void mark_refcnt(struct mark *m safe, int inc);
154
155 typedef struct {
156         PyObject_HEAD;
157         struct command  *comm;
158 } Comm;
159 static PyTypeObject CommType;
160
161 static inline bool pane_valid(Pane *p safe)
162 {
163         if (p->pane && p->pane->handle)
164                 return True;
165         PyErr_SetString(PyExc_TypeError, "Pane has been freed");
166         return False;
167 }
168
169 static inline bool doc_valid(Doc *p safe)
170 {
171         if (p->pane && p->pane->handle)
172                 return True;
173         PyErr_SetString(PyExc_TypeError, "Doc pane has been freed");
174         return False;
175 }
176
177 static bool get_cmd_info(struct cmd_info *ci safe, PyObject *args safe, PyObject *kwds,
178                          PyObject **s1 safe, PyObject **s2 safe);
179
180 static int in_pane_frompane = 0;
181 static inline PyObject *safe Pane_Frompane(struct pane *p)
182 {
183         Pane *pane;
184         if (p && p->handle && p->handle->func == python_pane_call.func) {
185                 pane = p->data;
186                 Py_INCREF(pane);
187         } else if (p && p->handle && p->handle->func == python_doc_call.func) {
188                 struct doc *doc = p->data;
189                 Doc *pdoc = container_of(doc, Doc, doc);
190                 pane = (Pane*)pdoc;
191                 Py_INCREF(pane);
192         } else {
193                 in_pane_frompane = 1;
194                 pane = (Pane *)PyObject_CallObject((PyObject*)&PaneType, NULL);
195                 in_pane_frompane = 0;
196                 if (pane)
197                         pane->pane = p;
198         }
199         return (PyObject*)pane;
200 }
201
202 static inline PyObject *safe Mark_Frommark(struct mark *m safe)
203 {
204         Mark *mark;
205
206         if (m->mtype == &MarkType && m->mdata) {
207                 /* This is a vmark, re-use the PyObject */
208                 Py_INCREF(m->mdata);
209                 return m->mdata;
210         }
211         mark = (Mark *)PyObject_CallObject((PyObject*)&MarkType, NULL);
212         if (mark)
213                 mark->mark = m;
214         return (PyObject*)mark;
215 }
216
217 static inline PyObject *safe Comm_Fromcomm(struct command *c safe)
218 {
219         Comm *comm = (Comm *)PyObject_CallObject((PyObject*)&CommType, NULL);
220         if (comm)
221                 comm->comm = command_get(c);
222         return (PyObject*)comm;
223 }
224
225 static PyObject *py_LOG(PyObject *self, PyObject *args);
226 static void PyErr_LOG(void)
227 {
228         /* cribbed from https://groups.google.com/forum/#!topic/comp.lang.python/khLrxC6EOKc */
229         char *errorMsg = NULL;
230         PyObject *modIO = NULL;
231         PyObject *modTB = NULL;
232         PyObject *obFuncStringIO = NULL;
233         PyObject *obIO = NULL;
234         PyObject *obFuncTB = NULL;
235         PyObject *argsTB = NULL;
236         PyObject *obResult = NULL;
237         PyObject *tofree = NULL;
238         PyObject *exc_typ, *exc_val, *exc_tb;
239
240         if (!PyErr_Occurred())
241                 return;
242
243         PyErr_Fetch(&exc_typ, &exc_val, &exc_tb);
244         PyErr_NormalizeException(&exc_typ, &exc_val, &exc_tb);
245
246         /* Import the modules we need - StringIO and traceback */
247         errorMsg = "Can't import io";
248         modIO = PyImport_ImportModule("io");
249         if (!modIO)
250                 goto out;
251
252         errorMsg = "Can't import traceback";
253         modTB = PyImport_ImportModule("traceback");
254         if (!modTB)
255                 goto out;
256
257         /* Construct a cStringIO object */
258         errorMsg = "Can't find io.StringIO";
259         obFuncStringIO = PyObject_GetAttrString(modIO, "StringIO");
260         if (!obFuncStringIO)
261                 goto out;
262         errorMsg = "io.StringIO() failed";
263         obIO = PyObject_CallObject(obFuncStringIO, NULL);
264         if (!obIO)
265                 goto out;
266
267         /* Get the traceback.print_exception function, and call it. */
268         errorMsg = "Can't find traceback.print_exception";
269         obFuncTB = PyObject_GetAttrString(modTB, "print_exception");
270         if (!obFuncTB)
271                 goto out;
272         errorMsg = "can't make print_exception arguments";
273         argsTB = Py_BuildValue("OOOOO",
274                                exc_typ ? exc_typ : Py_None,
275                                exc_val ? exc_val : Py_None,
276                                exc_tb  ? exc_tb  : Py_None,
277                                Py_None,
278                                obIO);
279         if (!argsTB)
280                 goto out;
281
282         errorMsg = "traceback.print_exception() failed";
283         obResult = PyObject_CallObject(obFuncTB, argsTB);
284         if (!obResult) {
285                 PyErr_Print();
286                 goto out;
287         }
288
289         /* Now call the getvalue() method in the StringIO instance */
290         Py_DECREF(obFuncStringIO);
291         errorMsg = "cant find getvalue function";
292         obFuncStringIO = PyObject_GetAttrString(obIO, "getvalue");
293         if (!obFuncStringIO)
294                 goto out;
295         Py_XDECREF(obResult);
296         errorMsg = "getvalue() failed.";
297         obResult = PyObject_CallObject(obFuncStringIO, NULL);
298         if (!obResult)
299                 goto out;
300
301         /* And it should be a string all ready to go - report it. */
302         errorMsg = python_as_string(obResult, &tofree);;
303         LOG("Python error:\n%s", errorMsg);
304         if (errorMsg &&
305             (!ed_pane ||
306              call("editor:notify:Message:broadcast",ed_pane, 0, NULL,
307                   "Python Error - see log") <= 0))
308                 /* Failed to alert anyone - write to stderr */
309                 fwrite(errorMsg, 1, strlen(errorMsg), stderr);
310         Py_XDECREF(tofree);
311         errorMsg = NULL;
312 out:
313         if (errorMsg)
314                 LOG(errorMsg);
315         Py_XDECREF(modIO);
316         Py_XDECREF(modTB);
317         Py_XDECREF(obFuncStringIO);
318         Py_XDECREF(obIO);
319         Py_XDECREF(obFuncTB);
320         Py_XDECREF(argsTB);
321         Py_XDECREF(obResult);
322
323         Py_XDECREF(exc_typ);
324         Py_XDECREF(exc_val);
325         Py_XDECREF(exc_tb);
326 }
327
328 DEF_CMD(python_load)
329 {
330         const char *fname = ci->str;
331         FILE *fp;
332         PyObject *globals, *main_mod;
333         PyObject *Ed;
334
335         if (!fname)
336                 return Enoarg;
337         fp = fopen(fname, "r");
338         if (!fp)
339                 return Efail;
340
341         main_mod = PyImport_AddModule("__main__");
342         if (main_mod == NULL)
343                 return Einval;
344         globals = PyModule_GetDict(main_mod);
345
346         Ed = Pane_Frompane(ci->home);
347         PyDict_SetItemString(globals, "editor", Ed);
348         PyDict_SetItemString(globals, "edlib", EdlibModule);
349         PyRun_FileExFlags(fp, fname, Py_file_input, globals, globals, 0, NULL);
350         PyErr_LOG();
351         Py_DECREF(Ed);
352         fclose(fp);
353         return 1;
354 }
355
356 DEF_CMD(python_load_module)
357 {
358         const char *name = ci->str;
359         FILE *fp;
360         PyObject *globals, *main_mod;
361         PyObject *Ed;
362         char buf [PATH_MAX];
363
364         if (!name)
365                 return Enoarg;
366         snprintf(buf, sizeof(buf), "%s/python/%s.py", module_dir, name);
367         fp = fopen(buf, "r");
368         if (!fp)
369                 return Efail;
370
371         LOG("Loading python module %s from %s", name, buf);
372         main_mod = PyImport_AddModule("__main__");
373         if (main_mod == NULL)
374                 return Einval;
375         globals = PyModule_GetDict(main_mod);
376
377         Ed = Pane_Frompane(ci->home);
378         PyDict_SetItemString(globals, "editor", Ed);
379         PyDict_SetItemString(globals, "pane", Pane_Frompane(ci->focus));
380         PyDict_SetItemString(globals, "edlib", EdlibModule);
381         PyRun_FileExFlags(fp, buf, Py_file_input, globals, globals, 0, NULL);
382         PyErr_LOG();
383         Py_DECREF(Ed);
384         fclose(fp);
385         return 1;
386 }
387
388 static PyObject *safe python_string(const char *s safe)
389 {
390         const char *c = s;
391         while (*c && !(*c & 0x80))
392                 c++;
393         if (*c)
394                 /* must be Unicode */
395                 return safe_cast PyUnicode_DecodeUTF8(s, strlen(s), NULL);
396         else
397                 return safe_cast Py_BuildValue("s", s);
398 }
399
400 static char *python_as_string(PyObject *s, PyObject **tofree safe)
401 {
402         if (s && PyUnicode_Check(s)) {
403                 s = PyUnicode_AsUTF8String(s);
404                 *tofree = s;
405         }
406         if (s && PyBytes_Check(s)) {
407                 char *ret = PyBytes_AsString(s);
408                 unsigned char *r = (unsigned char*)ret;
409                 if (r && r[0] == 0xef && r[1] == 0xbb && r[2] == 0xbf)
410                         /* UTF-8 Byte Order Mark */
411                         return ret+3;
412                 else
413                         return ret;
414         }
415         return NULL;
416 }
417
418 static int dict_add(PyObject *kwds, char *name, PyObject *val)
419 {
420         if (!val)
421                 return 0;
422         PyDict_SetItemString(kwds, name, val);
423         Py_DECREF(val);
424         return 1;
425 }
426
427 static void python_interrupt(int sig)
428 {
429         /* Python code has been running for too long,
430          * interrupt it.
431          */
432         kill(getpid(), 2);
433 }
434
435 REDEF_CB(python_call)
436 {
437         struct python_command *pc = container_of(ci->comm, struct python_command, c);
438         PyObject *ret = NULL, *args, *kwds;
439         int rv = 1;
440
441         args = safe_cast Py_BuildValue("(s)", ci->key);
442         kwds = PyDict_New();
443         rv = rv && dict_add(kwds, "home", Pane_Frompane(ci->home));
444         rv = rv && dict_add(kwds, "focus",
445                             Pane_Frompane(ci->focus));
446         rv = rv && dict_add(kwds, "mark",
447                             ci->mark ? Mark_Frommark(ci->mark):
448                             (Py_INCREF(Py_None), Py_None));
449         rv = rv && dict_add(kwds, "mark2",
450                             ci->mark2 ? Mark_Frommark(ci->mark2):
451                             (Py_INCREF(Py_None), Py_None));
452         rv = rv && dict_add(kwds, "str",
453                             ci->str ? python_string(ci->str):
454                             (Py_INCREF(Py_None), safe_cast Py_None));
455         rv = rv && dict_add(kwds, "str2",
456                             ci->str2 ? python_string(ci->str2):
457                             (Py_INCREF(Py_None), safe_cast Py_None));
458         rv = rv && dict_add(kwds, "comm", Comm_Fromcomm(ci->comm));
459         rv = rv && dict_add(kwds, "comm2",
460                             ci->comm2 ? Comm_Fromcomm(ci->comm2):
461                             (Py_INCREF(Py_None), Py_None));
462         rv = rv && dict_add(kwds, "num",
463                             Py_BuildValue("i", ci->num));
464         rv = rv && dict_add(kwds, "rpt_num",
465                             Py_BuildValue("i", RPT_NUM(ci)));
466         rv = rv && dict_add(kwds, "num2",
467                             Py_BuildValue("i", ci->num2));
468         rv = rv && dict_add(kwds, "xy",
469                             Py_BuildValue("ii", ci->x, ci->y));
470
471         if (rv && pc->callable) {
472                 signal(SIGALRM, python_interrupt);
473                 alarm(10);
474                 ret = PyObject_Call(pc->callable, args, kwds);
475                 alarm(0);
476                 signal(SIGALRM, SIG_DFL);
477         }
478
479         Py_DECREF(args);
480         Py_DECREF(kwds);
481         if (!ret) {
482                 PyErr_LOG();
483                 /* FIXME cancel error?? */
484                 return Efail;
485         }
486         if (ret == Py_None)
487                 rv = Efallthrough;
488         else if (PyLong_Check(ret))
489                 rv = PyLong_AsLong(ret);
490         else if (PyBool_Check(ret))
491                 rv = (ret == Py_True);
492         else if (PyUnicode_Check(ret) && PyUnicode_GET_LENGTH(ret) >= 1)
493                 rv = CHAR_RET(PyUnicode_READ_CHAR(ret, 0));
494         else
495                 rv = 1;
496         Py_DECREF(ret);
497         return rv;
498 }
499
500 REDEF_CMD(python_doc_call)
501 {
502         int rv = python_pane_call_func(ci);
503         if (rv == Efallthrough)
504                 rv = key_lookup(doc_default_cmd, ci);
505         return rv;
506 }
507
508 static void do_map_init(Pane *self safe)
509 {
510         int i;
511         PyObject *l = PyObject_Dir((PyObject*)self);
512         int n;
513
514         if (!self->map || !self->pane || !l)
515                 return;
516         n = PyList_Size(l);
517         /* First add the ranges, so individuals can over-ride them */
518         for (i = 0; i < n ; i++) {
519                 PyObject *e = PyList_GetItem(l, i);
520                 PyObject *m = PyObject_GetAttr((PyObject*)self, e);
521
522                 if (m && PyMethod_Check(m)) {
523                         PyObject *doc = PyObject_GetAttrString(m, "__doc__");
524                         if (doc && doc != Py_None) {
525                                 PyObject *tofree = NULL;
526                                 char *docs = python_as_string(doc, &tofree);
527                                 if (docs &&
528                                     strncmp(docs, "handle-range", 12) == 0 &&
529                                     docs[12]) {
530                                         char sep = docs[12];
531                                         char *s1 = strchr(docs+13, sep);
532                                         char *s2 = s1 ? strchr(s1+1, sep) : NULL;
533                                         if (s2) {
534                                                 char *a = strndup(docs+13, s1-(docs+13));
535                                                 char *b = strndup(s1+1, s2-(s1+1));
536
537                                                 struct python_command *comm =
538                                                         export_callable(m);
539                                                 key_add_range(self->map, a, b,
540                                                               &comm->c);
541                                                 free(a); free(b);
542                                                 command_put(&comm->c);
543                                         }
544                                 }
545                                 if (docs &&
546                                     strncmp(docs, "handle-prefix:", 14) == 0) {
547                                         char *a = strconcat(self->pane, docs+14);
548                                         char *b = strconcat(self->pane,
549                                                             a, "\xFF\xFF\xFF\xFF");
550                                         struct python_command *comm =
551                                                 export_callable(m);
552                                         key_add_range(self->map, a, b,
553                                                       &comm->c);
554                                         command_put(&comm->c);
555                                 }
556                                 Py_XDECREF(tofree);
557                         }
558                         Py_XDECREF(doc);
559                 }
560                 Py_XDECREF(m);
561         }
562         /* Now add the non-ranges */
563         for (i = 0; i < n ; i++) {
564                 PyObject *e = PyList_GetItem(l, i);
565                 PyObject *m = PyObject_GetAttr((PyObject*)self, e);
566
567                 if (m && PyMethod_Check(m)) {
568                         PyObject *doc = PyObject_GetAttrString(m, "__doc__");
569                         if (doc && doc != Py_None) {
570                                 PyObject *tofree = NULL;
571                                 char *docs = python_as_string(doc, &tofree);
572                                 if (docs &&
573                                     strncmp(docs, "handle:", 7) == 0) {
574                                         struct python_command *comm =
575                                                 export_callable(m);
576                                         key_add(self->map, docs+7, &comm->c);
577                                         command_put(&comm->c);
578                                 }
579                                 if (docs &&
580                                     strncmp(docs, "handle-list", 11) == 0 &&
581                                     docs[11]) {
582                                         char sep = docs[11];
583                                         char *s1 = docs + 12;
584                                         while (s1 && *s1 && *s1 != sep) {
585                                                 struct python_command *comm =
586                                                         export_callable(m);
587                                                 char *a;
588                                                 char *s2 = strchr(s1, sep);
589                                                 if (s2) {
590                                                         a = strndup(s1, s2-s1);
591                                                         s1 = s2+1;
592                                                 } else {
593                                                         a = strdup(s1);
594                                                         s1 = NULL;
595                                                 }
596                                                 key_add(self->map, a, &comm->c);
597                                                 free(a);
598                                                 command_put(&comm->c);
599                                         }
600                                 }
601                                 Py_XDECREF(tofree);
602                         }
603                         Py_XDECREF(doc);
604                 }
605                 Py_XDECREF(m);
606         }
607         Py_XDECREF(l);
608         self->map_init = 1;
609 }
610
611 REDEF_CB(python_pane_call)
612 {
613         Pane *home = container_of(ci->comm, Pane, cmd);
614
615         if (!home || !home->map)
616                 return Efallthrough;
617
618         if (!home->map_init)
619                 do_map_init(home);
620         return key_lookup(home->map, ci);
621 }
622
623 static Pane *pane_new(PyTypeObject *type safe, PyObject *args, PyObject *kwds)
624 {
625         Pane *self;
626
627         self = (Pane *)type->tp_alloc(type, 0);
628         if (self) {
629                 self->pane = NULL;
630         }
631         return self;
632 }
633
634 static Doc *Doc_new(PyTypeObject *type safe, PyObject *args, PyObject *kwds)
635 {
636         Doc *self;
637
638         self = (Doc *)type->tp_alloc(type, 0);
639         if (self) {
640                 self->pane = NULL;
641         }
642         return self;
643 }
644
645 static void python_pane_free(struct command *c safe)
646 {
647         Pane *p = container_of(c, Pane, cmd);
648         /* pane has been closed */
649         p->pane = NULL;
650         if (p->map)
651                 key_free(p->map);
652         p->map = NULL;
653         if (PyObject_TypeCheck(p, &DocType)) {
654                 Doc *d = (Doc*)p;
655                 doc_free(&d->doc);
656         }
657         Py_DECREF(p);
658 }
659
660 static int __Pane_init(Pane *self safe, PyObject *args, PyObject *kwds,
661                        Pane **parentp safe,
662                        int *zp safe)
663 {
664         Pane *parent = NULL;
665         int ret;
666         static char *keywords[] = {"parent", "z", NULL};
667
668         if (self->pane) {
669                 PyErr_SetString(PyExc_TypeError, "Pane already initialised");
670                 return -1;
671         }
672         /* Pane(parent, handler, data, z=0 */
673         if (in_pane_frompane)
674                 /* An internal Pane_Frompane call - it will set .pane,
675                  * and we don't want a .handler.
676                  */
677                 return 0;
678
679         ret = PyArg_ParseTupleAndKeywords(args, kwds, "|Oi", keywords,
680                                           &parent, zp);
681         if (ret <= 0)
682                 return -1;
683
684         if ((PyObject*)parent == Py_None)
685                 parent = NULL;
686
687         if (parent && !PyObject_TypeCheck(parent, &PaneType)) {
688                 PyErr_SetString(PyExc_TypeError, "First arg must be edlib.Pane or None");
689                 return -1;
690         }
691
692         *parentp = parent;
693
694         self->map = key_alloc();
695         self->cmd = python_pane_call;
696         self->cmd.free = python_pane_free;
697
698         return 1;
699 }
700
701 static int Pane_init(Pane *self safe, PyObject *args, PyObject *kwds)
702 {
703         Pane *parent = NULL;
704         int z = 0;
705         int ret = __Pane_init(self, args, kwds, &parent, &z);
706
707         if (ret <= 0)
708                 return ret;
709
710         /* The pane holds a reference to the Pane through the ->handle
711          * function
712          */
713         Py_INCREF(self);
714         self->pane = pane_register(parent ? parent->pane : NULL,
715                                    z, &self->cmd, self);
716         return 0;
717 }
718
719 static int Doc_init(Doc *self, PyObject *args, PyObject *kwds)
720 {
721         Pane *parent = NULL;
722         int z = 0;
723         int ret = __Pane_init((Pane*safe)self, args, kwds, &parent, &z);
724
725         if (ret <= 0 || !self)
726                 return ret;
727
728         self->cmd.func = python_doc_call_func;
729         self->pane = __doc_register(parent ? parent->pane : NULL,
730                                     &self->cmd, &self->doc, self, 0);
731         self->doc.refcnt = mark_refcnt;
732         return 0;
733 }
734
735 static inline void do_free(PyObject *ob safe)
736 {
737         if (ob->ob_type && ob->ob_type->tp_free)
738                 ob->ob_type->tp_free(ob);
739 }
740
741 static void pane_dealloc(Pane *self safe)
742 {
743         do_free((PyObject*safe)self);
744 }
745
746 static PyObject *pane_children(Pane *self safe, PyObject *args)
747 {
748         PaneIter *ret;
749
750         if (!pane_valid(self))
751                 return NULL;
752         ret = (PaneIter*)PyObject_CallObject((PyObject*)&PaneIterType, NULL);
753         if (ret) {
754                 if (list_empty(&self->pane->children))
755                         ret->pane = NULL;
756                 else
757                         ret->pane = list_first_entry(&self->pane->children,
758                                                      struct pane, siblings);
759         }
760         return (PyObject*)ret;
761 }
762
763 static Pane *pane_iter_new(PyTypeObject *type safe, PyObject *args, PyObject *kwds)
764 {
765         Pane *self;
766
767         self = (Pane *)type->tp_alloc(type, 0);
768         if (self)
769                 self->pane = NULL;
770         return self;
771 }
772
773 static void paneiter_dealloc(PaneIter *self safe)
774 {
775         do_free((PyObject*safe)self);
776 }
777
778 static PyObject *Pane_clone_children(Pane *self safe, PyObject *args)
779 {
780         Pane *other = NULL;
781         int ret;
782
783         if (!pane_valid(self))
784                 return NULL;
785
786         ret = PyArg_ParseTuple(args, "O!", &PaneType, &other);
787         if (ret <= 0 || !other)
788                 return NULL;
789         if (other->pane)
790                 pane_clone_children(self->pane, other->pane);
791         Py_INCREF(Py_None);
792         return Py_None;
793 }
794
795 static PyObject *Pane_focus(Pane *self safe, PyObject *args)
796 {
797         if (!pane_valid(self))
798                 return NULL;
799
800         pane_focus(self->pane);
801         Py_INCREF(Py_None);
802         return Py_None;
803 }
804
805 static PyObject *Pane_has_focus(Pane *self safe, PyObject *args)
806 {
807         if (!pane_valid(self))
808                 return NULL;
809
810         if (pane_has_focus(self->pane)) {
811                 Py_INCREF(Py_True);
812                 return Py_True;
813         } else {
814                 Py_INCREF(Py_False);
815                 return Py_False;
816         }
817 }
818
819 static PyObject *Pane_refresh(Pane *self safe, PyObject *args)
820 {
821         if (!pane_valid(self))
822                 return NULL;
823
824         pane_refresh(self->pane);
825         Py_INCREF(Py_None);
826         return Py_None;
827 }
828
829 static PaneIter *pane_this_iter(PaneIter *self safe)
830 {
831         Py_INCREF(self);
832         return self;
833 }
834
835 static PyObject *pane_iter_next(PaneIter *self safe)
836 {
837         PyObject *ret;
838         if (!self->pane)
839                 /* Reached the end */
840                 return NULL;
841         ret = Pane_Frompane(self->pane);
842         if (self->pane->siblings.next == &self->pane->parent->children)
843                 /* Reached the end of the list */
844                 self->pane = NULL;
845         else
846                 self->pane = list_next_entry(self->pane, siblings);
847         return ret;
848 }
849
850 struct pyret {
851         struct command comm;
852         PyObject *ret;
853         bool return_char;
854 };
855
856 DEF_CB(take_focus)
857 {
858         struct pyret *pr = container_of(ci->comm, struct pyret, comm);
859         struct pane *p = ci->focus;
860
861         if (!p)
862                 return Enoarg;
863         if (pr->ret)
864                 return Efallthrough;
865         pr->ret = Pane_Frompane(ci->focus);
866         return 1;
867 }
868
869 DEF_CB(take_mark)
870 {
871         struct pyret *pr = container_of(ci->comm, struct pyret, comm);
872
873         if (pr->ret)
874                 return Einval;
875         if (!ci->mark)
876                 return Efallthrough;
877         if (ci->mark->viewnum == MARK_UNGROUPED) {
878                 /* Cannot rely on this mark persisting, take a copy */
879                 struct mark *m = mark_dup(ci->mark);
880                 pr->ret = Mark_Frommark(m);
881                 m->mtype = (void*)pr->ret;
882         } else
883                 pr->ret = Mark_Frommark(ci->mark);
884         return 1;
885 }
886
887 DEF_CB(take_mark2)
888 {
889         struct pyret *pr = container_of(ci->comm, struct pyret, comm);
890
891         if (pr->ret)
892                 return Einval;
893         if (!ci->mark2)
894                 return Efallthrough;
895         pr->ret = Mark_Frommark(ci->mark2);
896         return 1;
897 }
898
899 DEF_CB(take_str)
900 {
901         struct pyret *pr = container_of(ci->comm, struct pyret, comm);
902
903         if (pr->ret)
904                 return Einval;
905         if (!ci->str)
906                 return Efallthrough;
907         pr->ret = python_string(ci->str);
908         return 1;
909 }
910
911 DEF_CB(take_bytes)
912 {
913         struct pyret *pr = container_of(ci->comm, struct pyret, comm);
914
915         if (pr->ret)
916                 return Einval;
917         if (!ci->str)
918                 return Efallthrough;
919         pr->ret = safe_cast PyBytes_FromStringAndSize(ci->str, ci->num);
920         return 1;
921 }
922
923 DEF_CB(take_comm)
924 {
925         struct pyret *pr = container_of(ci->comm, struct pyret, comm);
926
927         if (pr->ret)
928                 return Einval;
929         if (!ci->comm2)
930                 return Efallthrough;
931         pr->ret = Comm_Fromcomm(ci->comm2);
932         return 1;
933 }
934
935 static struct command *map_ret(char *ret safe)
936 {
937         if (strcmp(ret, "focus") == 0)
938                 return &take_focus;
939         if (strcmp(ret, "mark") == 0)
940                 return &take_mark;
941         if (strcmp(ret, "mark2") == 0)
942                 return &take_mark2;
943         if (strcmp(ret, "str") == 0)
944                 return &take_str;
945         if (strcmp(ret, "bytes") == 0)
946                 return &take_bytes;
947         if (strcmp(ret, "comm") == 0)
948                 return &take_comm;
949         return NULL;
950 }
951
952 static bool handle_ret(PyObject *kwds, struct cmd_info *ci safe,
953                        struct pyret *pr safe)
954 {
955         char *rets;
956         struct command *c;
957         PyObject *ret, *s3 = NULL;
958
959         memset(pr, 0, sizeof(*pr));
960
961         ret = kwds ? PyDict_GetItemString(kwds, "ret") : NULL;
962         if (!ret)
963                 return True;
964
965         if (!PyUnicode_Check(ret) ||
966             (rets = python_as_string(ret, &s3)) == NULL) {
967                 PyErr_SetString(PyExc_TypeError, "ret= must be given a string");
968                 return False;
969         }
970         if (strcmp(rets, "char") == 0) {
971                 pr->return_char = 1;
972                 ret = NULL;
973         } else {
974                 if (ci->comm2) {
975                         PyErr_SetString(PyExc_TypeError, "ret= not permitted with comm2");
976                         Py_XDECREF(s3);
977                         return False;
978                 }
979                 c = map_ret(rets);
980                 if (!c) {
981                         PyErr_SetString(PyExc_TypeError, "ret= type not valid");
982                         Py_XDECREF(s3);
983                         return False;
984                 }
985                 pr->comm = *c;
986                 ci->comm2 = &pr->comm;
987         }
988         Py_XDECREF(s3);
989         return True;
990 }
991
992 static void set_err(int rv)
993 {
994         switch(rv) {
995         case Enoarg:
996                 PyErr_SetObject(Edlib_CommandFailed,
997                                 PyUnicode_FromFormat("Enoarg"));
998                 break;
999         case Einval:
1000                 PyErr_SetObject(Edlib_CommandFailed,
1001                                 PyUnicode_FromFormat("Einval"));
1002                 break;
1003         case Enosup:
1004                 PyErr_SetObject(Edlib_CommandFailed,
1005                                 PyUnicode_FromFormat("Enosup"));
1006                 break;
1007         case Efail:
1008                 PyErr_SetObject(Edlib_CommandFailed,
1009                                 PyUnicode_FromFormat("Efail"));
1010                 break;
1011         default:
1012                 PyErr_SetObject(Edlib_CommandFailed,
1013                                 PyUnicode_FromFormat("%d", rv));
1014         }
1015 }
1016
1017 static PyObject *choose_ret(int rv, struct pyret *pr safe)
1018 {
1019         if (pr->comm.func && rv >= 0) {
1020                 if (pr->ret)
1021                         return pr->ret;
1022                 Py_INCREF(Py_None);
1023                 return Py_None;
1024         }
1025         Py_XDECREF(pr->ret);
1026         if (rv < Efalse) {
1027                 set_err(rv);
1028                 return NULL;
1029         }
1030         if (pr->return_char) {
1031                 if (rv == 0) {
1032                         Py_INCREF(Py_False);
1033                         return Py_False;
1034                 }
1035                 if (rv == CHAR_RET(WEOF)) {
1036                         Py_INCREF(Py_None);
1037                         return Py_None;
1038                 }
1039                 return PyUnicode_FromFormat("%c", rv & 0x1FFFFF);
1040         }
1041         return PyLong_FromLong(rv);
1042 }
1043
1044 static PyObject *Pane_call(Pane *self safe, PyObject *args safe, PyObject *kwds)
1045 {
1046         struct cmd_info ci = SAFE_CI;
1047         int rv;
1048         PyObject *s1, *s2;
1049         struct pyret pr;
1050         int remain;
1051
1052         if (!pane_valid(self))
1053                 return NULL;
1054
1055         ci.home = self->pane;
1056
1057         if (!get_cmd_info(&ci, args, kwds, &s1, &s2) ||
1058             !handle_ret(kwds, &ci, &pr)) {
1059                 Py_XDECREF(s1); Py_XDECREF(s2);
1060                 command_put(ci.comm2);
1061                 return NULL;
1062         }
1063
1064         remain = alarm(0);
1065         rv = key_handle(&ci);
1066         alarm(remain);
1067
1068         /* Just in case ... */
1069         PyErr_Clear();
1070
1071         Py_XDECREF(s1); Py_XDECREF(s2);
1072         command_put(ci.comm2);
1073
1074         return choose_ret(rv, &pr);
1075 }
1076
1077 static PyObject *pane_direct_call(Pane *self safe, PyObject *args safe, PyObject *kwds)
1078 {
1079         struct cmd_info ci = SAFE_CI;
1080         int rv;
1081         PyObject *s1, *s2;
1082         struct pyret pr;
1083
1084         if (!pane_valid(self))
1085                 return NULL;
1086
1087         ci.home = self->pane;
1088
1089         if (!get_cmd_info(&ci, args, kwds, &s1, &s2) ||
1090             !handle_ret(kwds, &ci, &pr)) {
1091                 Py_XDECREF(s1); Py_XDECREF(s2);
1092                 command_put(ci.comm2);
1093                 return NULL;
1094         }
1095
1096         ci.comm = ci.home->handle;
1097         rv = ci.comm->func(&ci);
1098
1099         Py_XDECREF(s1); Py_XDECREF(s2);
1100         command_put(ci.comm2);
1101         return choose_ret(rv, &pr);
1102 }
1103
1104 static PyObject *Pane_notify(Pane *self safe, PyObject *args safe, PyObject *kwds)
1105 {
1106         struct cmd_info ci = SAFE_CI;
1107         int rv;
1108         PyObject *s1, *s2;
1109
1110         if (!pane_valid(self))
1111                 return NULL;
1112
1113         ci.home = self->pane;
1114
1115         if (!get_cmd_info(&ci, args, kwds, &s1, &s2)) {
1116                 Py_XDECREF(s1); Py_XDECREF(s2);
1117                 command_put(ci.comm2);
1118                 return NULL;
1119         }
1120
1121         rv = home_pane_notify(ci.home, ci.key, ci.focus, ci.num, ci.mark, ci.str,
1122                               ci.num2, ci.mark2, ci.str2,
1123                               ci.comm2);
1124
1125         Py_XDECREF(s1); Py_XDECREF(s2);
1126         command_put(ci.comm2);
1127         if (rv < Efalse) {
1128                 set_err(rv);
1129                 return NULL;
1130         }
1131         return PyLong_FromLong(rv);
1132 }
1133
1134 static PyObject *Pane_mapxy(Pane *self safe, PyObject *args)
1135 {
1136         short x,y;
1137         struct xy xy;
1138         Pane *other = NULL;
1139
1140         int ret = PyArg_ParseTuple(args, "O!hh", &PaneType, &other, &x, &y);
1141         if (ret <= 0 || !self->pane || !other || !other->pane)
1142                 return NULL;
1143
1144         xy = pane_mapxy(other->pane, self->pane, x, y, False);
1145         return Py_BuildValue("ii", xy.x, xy.y);
1146 }
1147
1148 static PyObject *Pane_clipxy(Pane *self safe, PyObject *args)
1149 {
1150         short x,y;
1151         struct xy xy;
1152         Pane *other = NULL;
1153
1154         int ret = PyArg_ParseTuple(args, "O!hh", &PaneType, &other, &x, &y);
1155         if (ret <= 0 || !self->pane || !other || !other->pane)
1156                 return NULL;
1157
1158         xy = pane_mapxy(other->pane, self->pane, x, y, True);
1159         return Py_BuildValue("ii", xy.x, xy.y);
1160 }
1161
1162 static PyObject *Pane_add_notify(Pane *self safe, PyObject *args)
1163 {
1164         Pane *other = NULL;
1165         char *event = NULL;
1166         int ret = PyArg_ParseTuple(args, "O!s", &PaneType, &other, &event);
1167         if (ret <= 0 || !other || !event)
1168                 return NULL;
1169         if (self->pane && other->pane)
1170                 pane_add_notify(self->pane, other->pane, event);
1171
1172         Py_INCREF(Py_None);
1173         return Py_None;
1174 }
1175
1176 static PyObject *Pane_drop_notify(Pane *self safe, PyObject *args)
1177 {
1178         char *event = NULL;
1179         int ret = PyArg_ParseTuple(args, "s", &event);
1180         if (ret <= 0 || !event)
1181                 return NULL;
1182         if (self->pane)
1183                 pane_drop_notifiers(self->pane, event);
1184
1185         Py_INCREF(Py_None);
1186         return Py_None;
1187 }
1188
1189 static PyObject *Pane_damaged(Pane *self safe, PyObject *args)
1190 {
1191         int damage = DAMAGED_REFRESH;
1192         int ret = PyArg_ParseTuple(args, "|i", &damage);
1193         if (ret <= 0)
1194                 return NULL;
1195         if (self->pane)
1196                 pane_damaged(self->pane, damage);
1197
1198         Py_INCREF(Py_None);
1199         return Py_None;
1200 }
1201
1202 static PyObject *Pane_close(Pane *self safe, PyObject *args)
1203 {
1204         struct pane *p = self->pane;
1205         if (p) {
1206                 pane_close(p);
1207                 self->pane = NULL;
1208         }
1209         Py_INCREF(Py_None);
1210         return Py_None;
1211 }
1212
1213 static PyObject *Pane_get_scale(Pane *self safe, PyObject *args)
1214 {
1215         struct pane *p = self->pane;
1216         struct xy xy = {1000, 1000};
1217
1218         if (p)
1219                 xy = pane_scale(p);
1220         return Py_BuildValue("ii", xy.x, xy.y);
1221 }
1222
1223 static PyObject *Pane_mychild(Pane *self safe, PyObject *args)
1224 {
1225         Pane *child = NULL;
1226         int ret = PyArg_ParseTuple(args, "O!", &PaneType, &child);
1227         if (ret <= 0 || !child)
1228                 return NULL;
1229         if (self->pane && child->pane) {
1230                 struct pane *p = pane_my_child(self->pane, child->pane);
1231                 if (p)
1232                         return Pane_Frompane(p);
1233         }
1234         Py_INCREF(Py_None);
1235         return Py_None;
1236 }
1237
1238 static PyObject *Pane_clip(Pane *self safe, PyObject *args)
1239 {
1240         Mark *start = NULL, *end = NULL;
1241         int view = -1;
1242         int tostart = 0;
1243         int ret = PyArg_ParseTuple(args, "iO!O!|i", &view, &MarkType, &start,
1244                                    &MarkType, &end, &tostart);
1245
1246         if (ret > 0 && start && end && self->pane &&
1247             start->mark && end->mark && view >= 0)
1248                 marks_clip(self->pane, start->mark, end->mark, view, self->pane,
1249                            !!tostart);
1250         Py_INCREF(Py_None);
1251         return Py_None;
1252 }
1253
1254 static PyObject *Pane_reparent(Pane *self safe, PyObject *args)
1255 {
1256         Pane *newparent = NULL;
1257         int ret = PyArg_ParseTuple(args, "O!", &PaneType, &newparent);
1258
1259         if (ret > 0 && newparent && self->pane && newparent->pane)
1260                 pane_reparent(self->pane, newparent->pane);
1261         Py_INCREF(Py_None);
1262         return Py_None;
1263 }
1264
1265 static PyObject *Pane_move_after(Pane *self safe, PyObject *args)
1266 {
1267         Pane *peer = NULL;
1268         int ret = PyArg_ParseTuple(args, "O", &peer);
1269
1270         if (ret > 0 && peer && self->pane) {
1271                 if ((PyObject*)peer == Py_None)
1272                         pane_move_after(self->pane, NULL);
1273                 else if (PyObject_TypeCheck(peer, &PaneType) && peer->pane)
1274                         pane_move_after(self->pane, peer->pane);
1275         }
1276         Py_INCREF(Py_None);
1277         return Py_None;
1278 }
1279
1280 static PyObject *Pane_step(Pane *self safe, PyObject *args, int dir, int move)
1281 {
1282         Mark *m = NULL;
1283         int ret = PyArg_ParseTuple(args, "O!", &MarkType, &m);
1284         wint_t wch;
1285
1286         if (!pane_valid(self))
1287                 return NULL;
1288         if (ret <= 0 || !m) {
1289                 PyErr_SetString(PyExc_TypeError, "Arg must be a mark");
1290                 return NULL;
1291         }
1292
1293         if (move)
1294                 wch = doc_move(self->pane, m->mark, dir);
1295         else
1296                 wch = doc_pending(self->pane, m->mark, dir);
1297         if (wch == WEOF) {
1298                 Py_INCREF(Py_None);
1299                 return Py_None;
1300         }
1301         return PyUnicode_FromFormat("%c", wch);
1302 }
1303
1304 static PyObject *Pane_step_next(Pane *self safe, PyObject *args)
1305 {
1306         return Pane_step(self, args, 1, 1);
1307 }
1308
1309 static PyObject *Pane_step_prev(Pane *self safe, PyObject *args)
1310 {
1311         return Pane_step(self, args, -1, 1);
1312 }
1313
1314 static PyObject *Pane_step_following(Pane *self safe, PyObject *args)
1315 {
1316         return Pane_step(self, args, 1, 0);
1317 }
1318
1319 static PyObject *Pane_step_prior(Pane *self safe, PyObject *args)
1320 {
1321         return Pane_step(self, args, -1, 0);
1322 }
1323
1324 static PyMethodDef pane_methods[] = {
1325         {"close", (PyCFunction)Pane_close, METH_NOARGS,
1326          "close the pane"},
1327         {"children", (PyCFunction)pane_children, METH_NOARGS,
1328          "provides an iterator which will iterate over all children"},
1329         {"clone_children", (PyCFunction)Pane_clone_children, METH_VARARGS,
1330          "Clone all children onto the target"},
1331         {"take_focus", (PyCFunction)Pane_focus, METH_NOARGS,
1332          "Claim the focus for this pane"},
1333         {"has_focus", (PyCFunction)Pane_has_focus, METH_NOARGS,
1334          "Check if pane is focus of display"},
1335         {"refresh", (PyCFunction)Pane_refresh, METH_NOARGS,
1336          "Trigger refresh on this pane"},
1337         {"call", (void*)(PyCFunctionWithKeywords)Pane_call, METH_VARARGS|METH_KEYWORDS,
1338          "Call a command from a pane"},
1339         {"notify", (void*)(PyCFunctionWithKeywords)Pane_notify, METH_VARARGS|METH_KEYWORDS,
1340          "Send a notification from a pane"},
1341         {"mapxy", (PyCFunction)Pane_mapxy, METH_VARARGS,
1342          "Convert pane-relative co-ords between panes"},
1343         {"clipxy", (PyCFunction)Pane_clipxy, METH_VARARGS,
1344          "Convert pane-relative co-ords between panes, clipping to all panes"},
1345         {"add_notify", (PyCFunction)Pane_add_notify, METH_VARARGS,
1346          "Add notifier for an event on some other pane"},
1347         {"drop_notify", (PyCFunction)Pane_drop_notify, METH_VARARGS,
1348          "Drop notification to this pane for an event"},
1349         {"damaged", (PyCFunction)Pane_damaged, METH_VARARGS,
1350          "Mark pane as damaged"},
1351         {"scale", (PyCFunction)Pane_get_scale, METH_NOARGS,
1352          "Get the x,y scale numbers for this pane"},
1353         {"mychild", (PyCFunction)Pane_mychild, METH_VARARGS,
1354          "Get ancestor of pane which is my child, or None"},
1355         {"clip", (PyCFunction)Pane_clip, METH_VARARGS,
1356          "clip all 'type' marks in the given range"},
1357         {"reparent", (PyCFunction)Pane_reparent, METH_VARARGS,
1358          "Give a pane a new parent"},
1359         {"move_after", (PyCFunction)Pane_move_after, METH_VARARGS,
1360          "Move a pane after another in order of children"},
1361         {"next", (PyCFunction)Pane_step_next, METH_VARARGS,
1362          "Move mark forward returning the character"},
1363         {"prev", (PyCFunction)Pane_step_prev, METH_VARARGS,
1364          "Move mark back returning the character"},
1365         {"following", (PyCFunction)Pane_step_following, METH_VARARGS,
1366          "returning the character after mark"},
1367         {"prior", (PyCFunction)Pane_step_prior, METH_VARARGS,
1368          "returning the character before mark"},
1369         {NULL}
1370 };
1371
1372 static PyObject *pane_getnum(Pane *p safe, char *which safe)
1373 {
1374         long n = 0;
1375
1376         if (!pane_valid(p))
1377                 return NULL;
1378
1379         switch(*which) {
1380         case 'x': n = p->pane->x; break;
1381         case 'y': n = p->pane->y; break;
1382         case 'w': n = p->pane->w > 0 ? p->pane->w : 1; break;
1383         case 'h': n = p->pane->h > 0 ? p->pane->h : 1; break;
1384         case 'X': n = p->pane->cx; break;
1385         case 'Y': n = p->pane->cy; break;
1386         case 'z': n = p->pane->z; break;
1387         case 'Z': n = p->pane->abs_z; break;
1388         }
1389         return PyLong_FromLong(n);
1390 }
1391
1392 static int pane_setnum(Pane *p safe, PyObject *v, char *which safe)
1393 {
1394         int x,y,w,h;
1395         long val;
1396
1397         if (!pane_valid(p))
1398                 return -1;
1399
1400         if (*which == 'z') {
1401                 PyErr_SetString(PyExc_TypeError, "z cannot be set");
1402                 return -1;
1403         }
1404         if (*which == 'Z') {
1405                 PyErr_SetString(PyExc_TypeError, "abs_z cannot be set");
1406                 return -1;
1407         }
1408         val = PyLong_AsLong(v);
1409         if (val == -1 && PyErr_Occurred())
1410                 return -1;
1411
1412         x = p->pane->x; y = p->pane->y;
1413         w = p->pane->w; h = p->pane->h;
1414         switch(*which) {
1415         case 'x': x = val; break;
1416         case 'y': y = val; break;
1417         case 'w': w = val; break;
1418         case 'h': h = val; break;
1419         case 'X': p->pane->cx = val; return 0;
1420         case 'Y': p->pane->cy = val; return 0;
1421         }
1422         pane_resize(p->pane, x, y, w, h);
1423         return 0;
1424 }
1425
1426 static Pane *pane_getpane(Pane *p safe, char *which safe)
1427 {
1428         struct pane *new = NULL;
1429         Pane *newpane;
1430
1431         if (!pane_valid(p))
1432                 return NULL;
1433
1434         if (*which == 'p')
1435                 new = p->pane->parent;
1436         if (*which == 'f')
1437                 new = p->pane->focus;
1438         if (*which == 'r')
1439                 new = pane_root(p->pane);
1440         if (*which == 'L')
1441                 new = pane_leaf(p->pane);
1442         if (new == NULL) {
1443                 Py_INCREF(Py_None);
1444                 newpane = (Pane*)Py_None;
1445         } else
1446                 newpane = (Pane *)Pane_Frompane(new);
1447
1448         return newpane;
1449 }
1450
1451 static int pane_nosetpane(Pane *p, PyObject *v, void *which)
1452 {
1453         PyErr_SetString(PyExc_TypeError, "Cannot set panes");
1454         return -1;
1455 }
1456
1457 static PyObject *pane_repr(Pane *self safe)
1458 {
1459         char *s = NULL;
1460         PyObject *ret;
1461         if (!pane_valid(self))
1462                 asprintf(&s, "<edlib.Pane FREED!!! %p>", self);
1463         else
1464                 asprintf(&s, "<edlib.Pane %p>", self->pane);
1465         ret = Py_BuildValue("s", s);
1466         free(s);
1467         return ret;
1468 }
1469
1470 static PyObject *doc_repr(Doc *self safe)
1471 {
1472         char *s = NULL;
1473         PyObject *ret;
1474         if (!doc_valid(self))
1475                 asprintf(&s, "<edlib.Doc FREED!!! %p>", self);
1476         else
1477                 asprintf(&s, "<edlib.Doc %p>", self->pane);
1478         ret = Py_BuildValue("s", s);
1479         free(s);
1480         return ret;
1481 }
1482
1483 static long pane_hash(Pane *p safe)
1484 {
1485         return (long)p->pane;
1486 }
1487
1488 static PyObject *pane_cmp(Pane *p1 safe, Pane *p2 safe, int op)
1489 {
1490         Py_RETURN_RICHCOMPARE(p1->pane, p2->pane, op);
1491 }
1492
1493 static PyGetSetDef pane_getseters[] = {
1494         {"x",
1495          (getter)pane_getnum, (setter)pane_setnum,
1496          "X offset in parent", "x" },
1497         {"y",
1498          (getter)pane_getnum, (setter)pane_setnum,
1499          "Y offset in parent", "y" },
1500         {"z",
1501          (getter)pane_getnum, (setter)pane_setnum,
1502          "Z offset in parent", "z" },
1503         {"w",
1504          (getter)pane_getnum, (setter)pane_setnum,
1505          "width of pane", "w" },
1506         {"h",
1507          (getter)pane_getnum, (setter)pane_setnum,
1508          "heigth of pane", "h" },
1509         {"cx",
1510          (getter)pane_getnum, (setter)pane_setnum,
1511          "Cursor X offset in pane", "X" },
1512         {"cy",
1513          (getter)pane_getnum, (setter)pane_setnum,
1514          "Cursor Y offset in pane", "Y" },
1515         {"abs_z",
1516          (getter)pane_getnum, (setter)pane_setnum,
1517          "global Z offset", "Z" },
1518         {"parent",
1519          (getter)pane_getpane, (setter)pane_nosetpane,
1520          "Parent pane", "p"},
1521         {"focus",
1522          (getter)pane_getpane, (setter)pane_nosetpane,
1523          "Focal child", "f"},
1524         {"root",
1525          (getter)pane_getpane, (setter)pane_nosetpane,
1526          "Root pane", "r"},
1527         {"leaf",
1528          (getter)pane_getpane, (setter)pane_nosetpane,
1529          "Leaf pane", "L"},
1530         {NULL}  /* Sentinel */
1531 };
1532
1533 static PyObject *Pane_get_item(Pane *self safe, PyObject *key safe)
1534 {
1535         char *k, *v;
1536         PyObject *t1 = NULL;
1537
1538         if (!pane_valid(self))
1539                 return NULL;
1540
1541         k = python_as_string(key, &t1);
1542         if (!k) {
1543                 PyErr_SetString(PyExc_TypeError, "Key must be a string or unicode");
1544                 return NULL;
1545         }
1546         v = pane_attr_get(self->pane, k);
1547         Py_XDECREF(t1);
1548         if (v)
1549                 return Py_BuildValue("s", v);
1550         Py_INCREF(Py_None);
1551         return Py_None;
1552 }
1553
1554 static int Pane_set_item(Pane *self safe, PyObject *key, PyObject *val)
1555 {
1556         char *k, *v;
1557         PyObject *t1 = NULL, *t2 = NULL;
1558
1559         if (!pane_valid(self))
1560                 return -1;
1561
1562         k = python_as_string(key, &t1);
1563         if (!k) {
1564                 PyErr_SetString(PyExc_TypeError, "Key must be a string or unicode");
1565                 return -1;
1566         }
1567         v = python_as_string(val, &t2);
1568         if (val != Py_None && !v) {
1569                 PyErr_SetString(PyExc_TypeError, "value must be a string or unicode");
1570                 Py_XDECREF(t1);
1571                 return -1;
1572         }
1573         attr_set_str(&self->pane->attrs, k, v);
1574         Py_XDECREF(t1);
1575         Py_XDECREF(t2);
1576         return 0;
1577 }
1578
1579 static PyMappingMethods pane_mapping = {
1580         .mp_length = NULL,
1581         .mp_subscript = (binaryfunc)Pane_get_item,
1582         .mp_ass_subscript = (objobjargproc)Pane_set_item,
1583 };
1584
1585 static PyTypeObject PaneType = {
1586         PyVarObject_HEAD_INIT(NULL, 0)
1587         .tp_name        = "edlib.Pane",
1588         .tp_basicsize   = sizeof(Pane),
1589         .tp_dealloc     = (destructor)pane_dealloc,
1590         .tp_richcompare = (richcmpfunc)pane_cmp,
1591         .tp_repr        = (reprfunc)pane_repr,
1592         .tp_as_mapping  = &pane_mapping,
1593         .tp_hash        = (hashfunc)pane_hash,
1594         .tp_call        = (ternaryfunc)pane_direct_call,
1595         .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
1596         .tp_doc         = "edlib panes",
1597         .tp_methods     = pane_methods,
1598         .tp_getset      = pane_getseters,
1599         .tp_init        = (initproc)Pane_init,
1600         .tp_new         = (newfunc)pane_new,
1601 };
1602
1603 static PyTypeObject PaneIterType = {
1604         PyVarObject_HEAD_INIT(NULL, 0)
1605         .tp_name        = "edlib.PaneIter",
1606         .tp_basicsize   = sizeof(PaneIter),
1607         .tp_dealloc     = (destructor)paneiter_dealloc,
1608         .tp_flags       = Py_TPFLAGS_DEFAULT,
1609         .tp_doc         = "edlib pane iterator",
1610         .tp_iter        = (getiterfunc)pane_this_iter,
1611         .tp_iternext    = (iternextfunc)pane_iter_next,
1612         .tp_new         = (newfunc)pane_iter_new,
1613 };
1614
1615 static PyObject *first_mark(Doc *self safe, PyObject *args)
1616 {
1617         struct mark *m;
1618
1619         if (!doc_valid(self))
1620                 return NULL;
1621
1622         m = mark_first(&self->doc);
1623         if (!m) {
1624                 Py_INCREF(Py_None);
1625                 return Py_None;
1626         }
1627         return Mark_Frommark(m);
1628 }
1629
1630 static PyObject *to_end(Doc *self safe, PyObject *args)
1631 {
1632         Mark *mark = NULL;
1633         int end = 0;
1634         int ret;
1635
1636         if (!doc_valid(self))
1637                 return NULL;
1638
1639         ret = PyArg_ParseTuple(args, "O!i", &MarkType, &mark, &end);
1640         if (ret <= 0 || !mark || !mark->mark) {
1641                 PyErr_SetString(PyExc_TypeError, "Mark undefined or uninitialized");
1642                 return NULL;
1643         }
1644
1645         mark_to_end(self->pane, mark->mark, end);
1646         Py_INCREF(Py_None);
1647         return Py_None;
1648 }
1649
1650 static PyMethodDef doc_methods[] = {
1651         {"first_mark", (PyCFunction)first_mark, METH_NOARGS,
1652          "first mark of document"},
1653         {"to_end", (PyCFunction)to_end, METH_VARARGS,
1654          "Move mark to one end of document"},
1655         {NULL}
1656 };
1657
1658 static PyTypeObject DocType = {
1659         PyVarObject_HEAD_INIT(NULL, 0)
1660         .tp_name        = "edlib.Doc",
1661         .tp_basicsize   = sizeof(Doc),
1662         .tp_dealloc     = (destructor)pane_dealloc,
1663         .tp_repr        = (reprfunc)doc_repr,
1664         .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
1665         .tp_doc         = "edlib document",
1666         .tp_methods     = doc_methods,
1667         .tp_base        = &PaneType,
1668         .tp_init        = (initproc)Doc_init,
1669         .tp_new         = (newfunc)Doc_new,
1670 };
1671
1672 static PyObject *mark_getoffset(Mark *m safe, void *x)
1673 {
1674         struct doc *d;
1675         if (m->mark == NULL) {
1676                 PyErr_SetString(PyExc_TypeError, "Mark is NULL");
1677                 return NULL;
1678         }
1679         d = m->mark->owner->data;
1680         if (d->refcnt == mark_refcnt)
1681                 return PyLong_FromLong(m->mark->ref.o);
1682         return PyLong_FromLong(0);
1683 }
1684
1685 static int mark_setoffset(Mark *m safe, PyObject *v safe, void *x)
1686 {
1687         struct doc *d;
1688         long val;
1689
1690         if (m->mark == NULL) {
1691                 PyErr_SetString(PyExc_TypeError, "Mark is NULL");
1692                 return -1;
1693         }
1694         val = PyLong_AsLong(v);
1695         if (val == -1 && PyErr_Occurred())
1696                 return -1;
1697         d = m->mark->owner->data;
1698         if (d->refcnt == mark_refcnt)
1699                 m->mark->ref.o = val;
1700         else {
1701                 PyErr_SetString(PyExc_TypeError, "Setting offset on non-local mark");
1702                 return -1;
1703         }
1704         return 0;
1705 }
1706
1707 static PyObject *mark_getseq(Mark *m safe, void *x)
1708 {
1709         if (m->mark == NULL) {
1710                 PyErr_SetString(PyExc_TypeError, "Mark is NULL");
1711                 return NULL;
1712         }
1713         return PyLong_FromLong(m->mark->seq);
1714 }
1715
1716 static int mark_nosetseq(Mark *m, PyObject *v, void *which)
1717 {
1718         PyErr_SetString(PyExc_TypeError, "Cannot set mark seq number");
1719         return -1;
1720 }
1721
1722 static void mark_refcnt(struct mark *m safe, int inc)
1723 {
1724         if (!m->ref.c)
1725                 return;
1726         while (inc > 0) {
1727                 Py_INCREF(m->ref.c);
1728                 inc -= 1;
1729         }
1730         while (inc < 0) {
1731                 Py_DECREF(m->ref.c);
1732                 inc += 1;
1733         }
1734 }
1735
1736 static PyObject *mark_getpos(Mark *m safe, void *x)
1737 {
1738         struct doc *d;
1739         if (m->mark == NULL) {
1740                 PyErr_SetString(PyExc_TypeError, "Mark is NULL");
1741                 return NULL;
1742         }
1743         d = m->mark->owner->data;
1744         if (d->refcnt == mark_refcnt && m->mark->ref.c) {
1745                 Py_INCREF(m->mark->ref.c);
1746                 return m->mark->ref.c;
1747         } else {
1748                 Py_INCREF(Py_None);
1749                 return Py_None;
1750         }
1751 }
1752
1753 static int mark_setpos(Mark *m safe, PyObject *v, void *x)
1754 {
1755         struct mark *m2;
1756         struct doc *d;
1757
1758         if (m->mark == NULL) {
1759                 PyErr_SetString(PyExc_TypeError, "Mark is NULL");
1760                 return -1;
1761         }
1762         d = m->mark->owner->data;
1763         if (d->refcnt != mark_refcnt) {
1764                 PyErr_SetString(PyExc_TypeError, "Cannot set ref for non-local mark");
1765                 return -1;
1766         }
1767         d->refcnt(m->mark, -1);
1768         /* If an adjacent mark has a ref.c with a matching value
1769          * use that instead, so that mark_same() works.
1770          */
1771         if ((m2 = mark_next(m->mark)) != NULL &&
1772             ((struct doc *safe)m2->owner->data)->refcnt == mark_refcnt &&
1773             m2->ref.c != NULL &&
1774             PyObject_RichCompareBool(v, m2->ref.c, Py_EQ) == 1)
1775                 m->mark->ref.c = m2->ref.c;
1776         else if ((m2 = mark_prev(m->mark)) != NULL &&
1777                  ((struct doc *safe)m2->owner->data)->refcnt == mark_refcnt &&
1778                  m2->ref.c != NULL &&
1779                  PyObject_RichCompareBool(v, m2->ref.c, Py_EQ) == 1)
1780                 m->mark->ref.c = m2->ref.c;
1781         else
1782                 m->mark->ref.c = v;
1783         d->refcnt(m->mark, 1);
1784         return 0;
1785 }
1786
1787 static PyObject *mark_getview(Mark *m safe, void *x)
1788 {
1789         if (m->mark == NULL) {
1790                 PyErr_SetString(PyExc_TypeError, "Mark is NULL");
1791                 return NULL;
1792         }
1793         return PyLong_FromLong(m->mark->viewnum);
1794 }
1795
1796 static int mark_nosetview(Mark *m, PyObject *v, void *which)
1797 {
1798         PyErr_SetString(PyExc_TypeError, "Cannot set mark viewnum");
1799         return -1;
1800 }
1801
1802 static PyObject *mark_compare(Mark *a safe, Mark *b safe, int op)
1803 {
1804         if ((PyObject*)a == Py_None)
1805                 Py_RETURN_RICHCOMPARE(0, 1, op);
1806         else if ((PyObject*)b == Py_None)
1807                 Py_RETURN_RICHCOMPARE(1, 0, op);
1808         else if (PyObject_TypeCheck(a, &MarkType) == 0 ||
1809                  PyObject_TypeCheck(b, &MarkType) == 0) {
1810                 PyErr_SetString(PyExc_TypeError, "Mark compared with non-Mark");
1811                 return NULL;
1812         } else if (!a->mark || !b->mark)
1813                 return NULL;
1814         else {
1815                 int cmp = a->mark->seq - b->mark->seq;
1816                 if (mark_same(a->mark, b->mark))
1817                         cmp = 0;
1818                 Py_RETURN_RICHCOMPARE(cmp, 0, op);
1819         }
1820 }
1821
1822 static PyGetSetDef mark_getseters[] = {
1823         {"pos",
1824          (getter)mark_getpos, (setter)mark_setpos,
1825          "Position ref", NULL},
1826         {"offset",
1827          (getter)mark_getoffset, (setter)mark_setoffset,
1828          "Position offset", NULL},
1829         {"viewnum",
1830          (getter)mark_getview, (setter)mark_nosetview,
1831          "Index for view list", NULL},
1832         {"seq",
1833          (getter)mark_getseq, (setter)mark_nosetseq,
1834          "Sequence number of mark", NULL},
1835         {NULL}  /* Sentinel */
1836 };
1837
1838 static Mark *mark_new(PyTypeObject *type safe, PyObject *args, PyObject *kwds)
1839 {
1840         Mark *self;
1841
1842         self = (Mark *)type->tp_alloc(type, 0);
1843         if (self) {
1844                 self->mark = NULL;
1845         }
1846         return self;
1847 }
1848
1849 static int Mark_init(Mark *self safe, PyObject *args safe, PyObject *kwds)
1850 {
1851         Pane *doc = NULL;
1852         Pane *owner = NULL;
1853         int view = MARK_UNGROUPED;
1854         Mark *orig = NULL;
1855         static char *keywords[] = {"pane","view","orig", "owner", NULL};
1856         int ret;
1857
1858         if (!PyTuple_Check(args) ||
1859             (PyTuple_GET_SIZE(args) == 0 && kwds == NULL))
1860                 /* Internal Mark_Frommark call */
1861                 return 1;
1862
1863         ret = PyArg_ParseTupleAndKeywords(args, kwds, "|O!iO!O!", keywords,
1864                                           &PaneType, &doc,
1865                                           &view,
1866                                           &MarkType, &orig,
1867                                           &PaneType, &owner);
1868         if (ret <= 0)
1869                 return -1;
1870         if (doc && orig) {
1871                 PyErr_SetString(PyExc_TypeError,
1872                                 "Only one of 'pane' and 'orig' may be set");
1873                 return -1;
1874         }
1875         if (!doc && !orig) {
1876                 PyErr_SetString(PyExc_TypeError,
1877                                 "At least one of 'pane' and 'orig' must be set");
1878                 return -1;
1879         }
1880         if (doc && doc->pane) {
1881                 struct pane *p = doc->pane;
1882                 struct pane *op = owner ? owner->pane : NULL;
1883                 if (!op)
1884                         op = p;
1885                 self->mark = vmark_new(p, view, op);
1886         } else if (orig && orig->mark) {
1887                 self->mark = mark_dup_view(orig->mark);
1888         }
1889         if (!self->mark) {
1890                 PyErr_SetString(PyExc_TypeError, "Mark creation failed");
1891                 return -1;
1892         }
1893         if (self->mark->viewnum >= 0) {
1894                 /* vmarks can use mdata and don't disappear until
1895                  * explicitly released.
1896                  */
1897                 self->mark->mtype = &MarkType;
1898                 self->mark->mdata = (PyObject*)self;
1899                 Py_INCREF(self);
1900         } else {
1901                 /* Other marks cannot use mdata and get freed when
1902                  * the original PyObject is destroyed
1903                  */
1904                 self->mark->mtype = (void*)self;
1905         }
1906         return 1;
1907 }
1908
1909 static void mark_dealloc(Mark *self safe)
1910 {
1911         if (self->mark && self->mark->mtype == (void*)self) {
1912                 /* Python allocated this mark, so can free it. */
1913                 struct mark *m = self->mark;
1914                 self->mark = NULL;
1915                 m->mtype = NULL;
1916                 m->mdata = NULL;
1917                 mark_free(m);
1918         }
1919         do_free((PyObject*safe)self);
1920 }
1921
1922 static PyObject *Mark_to_mark(Mark *self safe, PyObject *args)
1923 {
1924         Mark *other = NULL;
1925         int ret = PyArg_ParseTuple(args, "O!", &MarkType, &other);
1926         if (ret <= 0 || !other || !self->mark || !other->mark)
1927                 return NULL;
1928         mark_to_mark(self->mark, other->mark);
1929
1930         Py_INCREF(Py_None);
1931         return Py_None;
1932 }
1933
1934 static PyObject *Mark_to_mark_noref(Mark *self safe, PyObject *args)
1935 {
1936         Mark *other = NULL;
1937         int ret = PyArg_ParseTuple(args, "O!", &MarkType, &other);
1938         if (ret <= 0 || !other || !self->mark || !other->mark)
1939                 return NULL;
1940         mark_to_mark_noref(self->mark, other->mark);
1941
1942         Py_INCREF(Py_None);
1943         return Py_None;
1944 }
1945
1946 static PyObject *Mark_clip(Mark *self safe, PyObject *args)
1947 {
1948         Mark *start = NULL, *end = NULL;
1949         int tostart = 0;
1950         int ret = PyArg_ParseTuple(args, "O!O!|i", &MarkType, &start,
1951                                    &MarkType, &end, &tostart);
1952
1953         if (ret > 0 && start && end && self->mark &&
1954             start->mark && end->mark)
1955                 mark_clip(self->mark, start->mark, end->mark, !!tostart);
1956
1957         Py_INCREF(Py_None);
1958         return Py_None;
1959 }
1960
1961 static PyObject *Mark_step(Mark *self safe, PyObject *args)
1962 {
1963         /* Convenience function to help implement doc:char */
1964         int forward = 1;
1965         int ret = PyArg_ParseTuple(args, "i", &forward);
1966
1967         if (ret > 0 && self->mark)
1968                 mark_step(self->mark, forward);
1969
1970         Py_INCREF(Py_None);
1971         return Py_None;
1972 }
1973
1974 static PyObject *Mark_next(Mark *self safe, PyObject *args)
1975 {
1976         struct mark *next;
1977         if (!self->mark) {
1978                 PyErr_SetString(PyExc_TypeError, "Mark is NULL");
1979                 return NULL;
1980         }
1981         if (self->mark->viewnum >= 0)
1982                 next = vmark_next(self->mark);
1983         else
1984                 next = NULL;
1985         if (next)
1986                 return Mark_Frommark(next);
1987         Py_INCREF(Py_None);
1988         return Py_None;
1989 }
1990
1991 static PyObject *Mark_prev(Mark *self safe, PyObject *args)
1992 {
1993         struct mark *prev;
1994         if (!self->mark) {
1995                 PyErr_SetString(PyExc_TypeError, "Mark is NULL");
1996                 return NULL;
1997         }
1998         if (self->mark->viewnum >= 0)
1999                 prev = vmark_prev(self->mark);
2000         else
2001                 prev = NULL;
2002         if (prev)
2003                 return Mark_Frommark(prev);
2004         Py_INCREF(Py_None);
2005         return Py_None;
2006 }
2007
2008 static PyObject *Mark_next_any(Mark *self safe, PyObject *args)
2009 {
2010         struct mark *next;
2011         if (!self->mark) {
2012                 PyErr_SetString(PyExc_TypeError, "Mark is NULL");
2013                 return NULL;
2014         }
2015         next = mark_next(self->mark);
2016         if (next)
2017                 return Mark_Frommark(next);
2018         Py_INCREF(Py_None);
2019         return Py_None;
2020 }
2021
2022 static PyObject *Mark_prev_any(Mark *self safe, PyObject *args)
2023 {
2024         struct mark *prev;
2025         if (!self->mark) {
2026                 PyErr_SetString(PyExc_TypeError, "Mark is NULL");
2027                 return NULL;
2028         }
2029         prev = mark_prev(self->mark);
2030         if (prev)
2031                 return Mark_Frommark(prev);
2032         Py_INCREF(Py_None);
2033         return Py_None;
2034 }
2035
2036 static PyObject *Mark_dup(Mark *self safe, PyObject *args)
2037 {
2038         struct mark *new;
2039         if (!self->mark) {
2040                 PyErr_SetString(PyExc_TypeError, "Mark is NULL");
2041                 return NULL;
2042         }
2043         new = mark_dup(self->mark);
2044         if (new) {
2045                 Mark *ret = (Mark*)Mark_Frommark(new);
2046                 /* We want this mark to be freed when the Mark
2047                  * dies
2048                  */
2049                 new->mtype = (void*)ret;
2050                 return (PyObject*)ret;
2051         }
2052
2053         Py_INCREF(Py_None);
2054         return Py_None;
2055 }
2056
2057 static PyObject *Mark_release(Mark *self safe, PyObject *args)
2058 {
2059         struct mark *m = self->mark;
2060
2061         if (!m) {
2062                 PyErr_SetString(PyExc_TypeError, "Mark has been freed");
2063                 return NULL;
2064         }
2065         if (m->viewnum == MARK_UNGROUPED || m->viewnum == MARK_POINT) {
2066                 PyErr_SetString(PyExc_TypeError,
2067                                 "Cannot release ungrouped marks or points");
2068                 return NULL;
2069         }
2070         if (m->mtype == &MarkType) {
2071                 /* We are dropping this mark - there cannot be any other ref */
2072                 ASSERT(m->mdata == (PyObject*)self);
2073                 Py_DECREF(self);
2074                 m->mdata = NULL;
2075                 m->mtype = NULL;
2076                 self->mark = NULL;
2077                 mark_free(m);
2078         }
2079
2080         Py_INCREF(Py_None);
2081         return Py_None;
2082 }
2083
2084 static PyObject *Mark_ack(Mark *self safe, PyObject *args)
2085 {
2086         struct mark *m = self->mark;
2087
2088         if (!m) {
2089                 PyErr_SetString(PyExc_TypeError, "Mark has been freed");
2090                 return NULL;
2091         }
2092         mark_ack(m);
2093         Py_INCREF(Py_None);
2094         return Py_None;
2095 }
2096
2097 static PyMethodDef mark_methods[] = {
2098         {"to_mark", (PyCFunction)Mark_to_mark, METH_VARARGS,
2099          "Move one mark to another"},
2100         {"to_mark_noref", (PyCFunction)Mark_to_mark_noref, METH_VARARGS,
2101          "Move one mark to another but don't update ref"},
2102         {"next", (PyCFunction)Mark_next, METH_NOARGS,
2103          "next vmark"},
2104         {"prev", (PyCFunction)Mark_prev, METH_NOARGS,
2105          "previous vmark"},
2106         {"next_any", (PyCFunction)Mark_next_any, METH_NOARGS,
2107          "next any_mark"},
2108         {"prev_any", (PyCFunction)Mark_prev_any, METH_NOARGS,
2109          "previous any_mark"},
2110         {"dup", (PyCFunction)Mark_dup, METH_NOARGS,
2111          "duplicate a mark, as ungrouped"},
2112         {"clip", (PyCFunction)Mark_clip, METH_VARARGS,
2113          "If this mark is in range, move to end"},
2114         {"release", (PyCFunction)Mark_release, METH_NOARGS,
2115          "release a vmark so it can disappear"},
2116         {"ack", (PyCFunction)Mark_ack, METH_NOARGS,
2117          "acknowledge movement of a point - allow further notifications"},
2118         {"step", (PyCFunction)Mark_step, METH_VARARGS,
2119          "Move mark over any adjacent marks with same reference"},
2120         {NULL}
2121 };
2122
2123 static PyObject *mark_get_item(Mark *self safe, PyObject *key safe)
2124 {
2125         char *k, *v;
2126         PyObject *t1 = NULL;
2127
2128         if (!self->mark) {
2129                 PyErr_SetString(PyExc_TypeError, "Mark is NULL");
2130                 return NULL;
2131         }
2132         k = python_as_string(key, &t1);
2133         if (!k) {
2134                 PyErr_SetString(PyExc_TypeError, "Key must be a string or unicode");
2135                 return NULL;
2136         }
2137         v = attr_find(self->mark->attrs, k);
2138         Py_XDECREF(t1);
2139         if (v)
2140                 return Py_BuildValue("s", v);
2141         Py_INCREF(Py_None);
2142         return Py_None;
2143 }
2144
2145 static int mark_set_item(Mark *self safe, PyObject *key safe, PyObject *val safe)
2146 {
2147         char *k, *v;
2148         PyObject *t1 = NULL, *t2 = NULL;
2149         if (!self->mark) {
2150                 PyErr_SetString(PyExc_TypeError, "Mark is NULL");
2151                 return -1;
2152         }
2153         k = python_as_string(key, &t1);
2154         if (!k) {
2155                 PyErr_SetString(PyExc_TypeError, "Key must be a string or unicode");
2156                 return -1;
2157         }
2158         v = python_as_string(val, &t2);
2159         if (val != Py_None && !v) {
2160                 PyErr_SetString(PyExc_TypeError, "value must be a string or unicode");
2161                 Py_XDECREF(t1);
2162                 return -1;
2163         }
2164         attr_set_str(&self->mark->attrs, k, v);
2165         Py_XDECREF(t1);
2166         Py_XDECREF(t2);
2167         return 0;
2168 }
2169
2170 static PyObject *mark_repr(Mark *self safe)
2171 {
2172         char *s = NULL;
2173         PyObject *ret;
2174
2175         if (self->mark)
2176                 asprintf(&s, "<edlib.Mark seq=%d v=%d i=%d %p>",
2177                          self->mark->seq, self->mark->viewnum,
2178                          self->mark->ref.o, self->mark);
2179         else
2180                 asprintf(&s, "<edlib.Mark NULL %p>", self);
2181         ret = Py_BuildValue("s", s);
2182         free(s);
2183         return ret;
2184 }
2185
2186 static PyMappingMethods mark_mapping = {
2187         .mp_length = NULL,
2188         .mp_subscript = (binaryfunc)mark_get_item,
2189         .mp_ass_subscript = (objobjargproc)mark_set_item,
2190 };
2191
2192 static PyTypeObject MarkType = {
2193         PyVarObject_HEAD_INIT(NULL, 0)
2194         .tp_name        = "edlib.Mark",
2195         .tp_basicsize   = sizeof(Mark),
2196         .tp_dealloc     = (destructor)mark_dealloc,
2197         .tp_as_mapping  = &mark_mapping,
2198         .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
2199         .tp_doc         = "edlib marks",
2200         .tp_richcompare = (richcmpfunc)mark_compare,
2201         .tp_methods     = mark_methods,
2202         .tp_getset      = mark_getseters,
2203         .tp_init        = (initproc)Mark_init,
2204         .tp_new         = (newfunc)mark_new,
2205         .tp_repr        = (reprfunc)mark_repr
2206 };
2207
2208 static void comm_dealloc(Comm *self safe)
2209 {
2210         command_put(self->comm);
2211         do_free((PyObject*safe)self);
2212 }
2213
2214 static PyObject *comm_repr(Comm *self safe)
2215 {
2216         char *s = NULL;
2217         PyObject *ret;
2218
2219         if (self->comm)
2220                 asprintf(&s, "<edlib.Comm refcnt=%d %p>",
2221                          self->comm->refcnt, self->comm);
2222         else
2223                 asprintf(&s, "<edlib.Comm NULL %p>", self);
2224         ret = Py_BuildValue("s", s);
2225         free(s);
2226         return ret;
2227 }
2228
2229 static PyObject *Comm_call(Comm *c safe, PyObject *args safe, PyObject *kwds)
2230 {
2231         struct cmd_info ci = SAFE_CI;
2232         int rv;
2233         PyObject *s1, *s2;
2234         struct pyret pr;
2235
2236         if (!c->comm)
2237                 return NULL;
2238         if (!get_cmd_info(&ci, args, kwds, &s1, &s2) ||
2239             !handle_ret(kwds, &ci, &pr)) {
2240                 Py_XDECREF(s1); Py_XDECREF(s2);
2241                 command_put(ci.comm2);
2242                 return NULL;
2243         }
2244         ci.comm = c->comm;
2245         rv = c->comm->func(&ci);
2246         Py_XDECREF(s1); Py_XDECREF(s2);
2247         command_put(ci.comm2);
2248
2249         return choose_ret(rv, &pr);
2250 }
2251
2252 static PyObject *comm_cmp(Comm *c1 safe, Comm *c2 safe, int op)
2253 {
2254         Py_RETURN_RICHCOMPARE(c1->comm, c2->comm, op);
2255 }
2256
2257 static Comm *comm_new(PyTypeObject *type safe, PyObject *args safe, PyObject *kwds)
2258 {
2259         Comm *self;
2260
2261         self = (Comm *)type->tp_alloc(type, 0);
2262         if (self)
2263                 self->comm = NULL;
2264         return self;
2265 }
2266
2267 static PyTypeObject CommType = {
2268         PyVarObject_HEAD_INIT(NULL, 0)
2269         .tp_name        = "edlib.Comm",
2270         .tp_basicsize   = sizeof(Comm),
2271         .tp_dealloc     = (destructor)comm_dealloc,
2272         .tp_richcompare = (richcmpfunc)comm_cmp,
2273         .tp_repr        = (reprfunc)comm_repr,
2274         .tp_call        = (ternaryfunc)Comm_call,
2275         .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
2276         .tp_doc         = "edlib command",
2277         .tp_new         = (newfunc)comm_new,
2278 };
2279
2280 static void python_free_command(struct command *c safe)
2281 {
2282         struct python_command *pc = container_of(c, struct python_command, c);
2283
2284         if (pc->callable)
2285                 Py_DECREF(pc->callable);
2286         list_del(&pc->lst);
2287         free(pc);
2288 }
2289
2290 /* The 'call' function takes liberties with arg passing.
2291  * Positional args must start with the key, and then are handled based on
2292  * there type.  They can be panes, strigns, ints, pairs, marks, commands.
2293  * Panes are assigned to focus, then home.
2294  * Strings (after the key) are assigned to 'str' then 'str2'.
2295
2296  * Ints are assigned to num then num2
2297  * Pairs (must be of ints) are assigned to x,y then hx,hy.
2298  * Marks are assigned to mark then mark2
2299  * A command is assigned to comm2 (comm is set automatically)
2300  * kwd arguments can also be used, currently
2301  * key, home, focus, xy, hxy, str, str2, mark, mark2, comm2.
2302  * A 'None' arg is ignored - probably a mark or string or something. Just use NULL
2303  */
2304 static bool get_cmd_info(struct cmd_info *ci safe, PyObject *args safe, PyObject *kwds,
2305                          PyObject **s1 safe, PyObject **s2 safe)
2306 {
2307         int argc;
2308         PyObject *a;
2309         int i;
2310         int num_set = 0, num2_set = 0;
2311         int xy_set = 0;
2312
2313         *s1 = *s2 = NULL;
2314
2315         if (!PyTuple_Check(args))
2316                 return False;
2317         argc = PyTuple_GET_SIZE(args);
2318         if (argc >= 1) {
2319                 /* First positional arg must be the key */
2320                 a = PyTuple_GetItem(args, 0);
2321                 if (!PyUnicode_Check(a)) {
2322                         PyErr_SetString(PyExc_TypeError, "First arg must be key");
2323                         return False;
2324                 }
2325                 ci->key = safe_cast PyUnicode_AsUTF8(a);
2326         }
2327         for (i = 1; i < argc; i++) {
2328                 a = PyTuple_GetItem(args, i);
2329                 if (a == Py_None)
2330                         /* quietly ignore */;
2331                 else if (PyObject_TypeCheck(a, &PaneType)) {
2332                         if ((void*)ci->home == NULL)
2333                                 ci->home = safe_cast ((Pane*)a)->pane;
2334                         else if ((void*)ci->focus == NULL)
2335                                 ci->focus = safe_cast ((Pane*)a)->pane;
2336                         else {
2337                                 PyErr_SetString(PyExc_TypeError, "Only 2 Pane args permitted");
2338                                 return False;
2339                         }
2340                 } else if (PyObject_TypeCheck(a, &MarkType)) {
2341                         if (ci->mark == NULL)
2342                                 ci->mark = ((Mark*)a)->mark;
2343                         else if (ci->mark2 == NULL)
2344                                 ci->mark2 = ((Mark*)a)->mark;
2345                         else {
2346                                 PyErr_SetString(PyExc_TypeError, "Only 2 Mark args permitted");
2347                                 return False;
2348                         }
2349                 } else if (PyUnicode_Check(a)) {
2350                         char *str;
2351                         PyObject *s = NULL;
2352                         if (ci->str && ci->str2) {
2353                                 PyErr_SetString(PyExc_TypeError, "Only 3 String args permitted");
2354                                 return False;
2355                         }
2356                         str = python_as_string(a, &s);
2357                         if (!str)
2358                                 return False;
2359                         if (s) {
2360                                 *s2 = *s1;
2361                                 *s1 = s;
2362                         }
2363                         if (ci->str == NULL)
2364                                 ci->str = str;
2365                         else
2366                                 ci->str2 = str;
2367                 } else if (PyLong_Check(a)) {
2368                         if (!num_set) {
2369                                 ci->num = PyLong_AsLong(a);
2370                                 num_set = 1;
2371                         } else if (!num2_set) {
2372                                 ci->num2 = PyLong_AsLong(a);
2373                                 num2_set = 1;
2374                         } else {
2375                                 PyErr_SetString(PyExc_TypeError, "Only 2 Number args permitted");
2376                                 return False;
2377                         }
2378                 } else if (PyTuple_Check(a)) {
2379                         int n = PyTuple_GET_SIZE(a);
2380                         PyObject *n1, *n2;
2381                         if (n != 2) {
2382                                 PyErr_SetString(PyExc_TypeError, "Only 2-element tuples permitted");
2383                                 return False;
2384                         }
2385                         n1 = PyTuple_GetItem(a, 0);
2386                         n2 = PyTuple_GetItem(a, 1);
2387                         if (!PyLong_Check(n1) || !PyLong_Check(n2)) {
2388                                 PyErr_SetString(PyExc_TypeError, "Only tuples of integers permitted");
2389                                 return False;
2390                         }
2391                         if (!xy_set) {
2392                                 ci->x = PyLong_AsLong(n1);
2393                                 ci->y = PyLong_AsLong(n2);
2394                                 xy_set = 1;
2395                         } else {
2396                                 PyErr_SetString(PyExc_TypeError, "Only one tuple permitted");
2397                                 return False;
2398                         }
2399                 } else if (PyObject_TypeCheck(a, &CommType)) {
2400                         Comm *c = (Comm*)a;
2401                         if (ci->comm2 == NULL && c->comm) {
2402                                 ci->comm2 = command_get(c->comm);
2403                         } else {
2404                                 PyErr_SetString(PyExc_TypeError, "Only one callable permitted");
2405                                 return False;
2406                         }
2407                 } else if (PyCallable_Check(a)) {
2408                         struct python_command *pc = export_callable(a);
2409
2410                         if (ci->comm2 == NULL)
2411                                 ci->comm2 = &pc->c;
2412                         else {
2413                                 command_put(&pc->c);
2414                                 PyErr_SetString(PyExc_TypeError, "Only one callable permitted");
2415                                 return False;
2416                         }
2417                 } else {
2418                         PyErr_Format(PyExc_TypeError, "Unsupported arg type %d", i);
2419                         return False;
2420                 }
2421         }
2422         if (kwds && PyDict_Check(kwds)) {
2423                 a = PyDict_GetItemString(kwds, "str");
2424                 if (a && a != Py_None) {
2425                         if (*s1 || ci->str) {
2426                                 PyErr_SetString(PyExc_TypeError,
2427                                                 "'str' given with other strings");
2428                                 return False;
2429                         }
2430                         if (!PyUnicode_Check(a)) {
2431                                 PyErr_SetString(PyExc_TypeError,
2432                                                 "'str' must be string or unicode");
2433                                 return False;
2434                         }
2435                         ci->str = python_as_string(a, s1);
2436                 }
2437                 a = PyDict_GetItemString(kwds, "str2");
2438                 if (a && a != Py_None) {
2439                         if (*s2 || ci->str2) {
2440                                 PyErr_SetString(PyExc_TypeError,
2441                                                 "'str2' given with 2 strings");
2442                                 return False;
2443                         }
2444                         if (!PyUnicode_Check(a)) {
2445                                 PyErr_SetString(PyExc_TypeError,
2446                                                 "'str2' must be string or unicode");
2447                                 return False;
2448                         }
2449                         ci->str2 = python_as_string(a, s2);
2450                 }
2451                 a = PyDict_GetItemString(kwds, "mark");
2452                 if (a && a != Py_None) {
2453                         if (ci->mark) {
2454                                 PyErr_SetString(PyExc_TypeError,
2455                                                 "'mark' given with other marks");
2456                                 return False;
2457                         }
2458                         if (!PyObject_TypeCheck(a, &MarkType)) {
2459                                 PyErr_SetString(PyExc_TypeError,
2460                                                 "'mark' must be an edlib.Mark");
2461                                 return False;
2462                         }
2463                         ci->mark = ((Mark*)a)->mark;
2464                 }
2465                 a = PyDict_GetItemString(kwds, "mark2");
2466                 if (a && a != Py_None) {
2467                         if (ci->mark2) {
2468                                 PyErr_SetString(PyExc_TypeError,
2469                                                 "'mark2' given with 2 other marks");
2470                                 return False;
2471                         }
2472                         if (!PyObject_TypeCheck(a, &MarkType)) {
2473                                 PyErr_SetString(PyExc_TypeError,
2474                                                 "'mark2' must be an edlib.Mark");
2475                                 return False;
2476                         }
2477                         ci->mark2 = ((Mark*)a)->mark;
2478                 }
2479                 a = PyDict_GetItemString(kwds, "num");
2480                 if (a) {
2481                         if (num_set) {
2482                                 PyErr_SetString(PyExc_TypeError,
2483                                                 "'num' given with other numbers");
2484                                 return False;
2485                         }
2486                         if (!PyLong_Check(a)) {
2487                                 PyErr_SetString(PyExc_TypeError,
2488                                                 "'num' must be an integer");
2489                                 return False;
2490                         }
2491                         ci->num = PyLong_AsLong(a);
2492                         num_set = 1;
2493                 }
2494                 a = PyDict_GetItemString(kwds, "num2");
2495                 if (a) {
2496                         if (num2_set) {
2497                                 PyErr_SetString(PyExc_TypeError,
2498                                                 "'num2' given with 2 other numbers");
2499                                 return False;
2500                         }
2501                         if (!PyLong_Check(a)) {
2502                                 PyErr_SetString(PyExc_TypeError,
2503                                                 "'num2' must be an integer");
2504                                 return False;
2505                         }
2506                         ci->num2 = PyLong_AsLong(a);
2507                         num2_set = 1;
2508                 }
2509                 a = PyDict_GetItemString(kwds, "focus");
2510                 if (a && a != Py_None) {
2511                         Pane *p;
2512                         if ((void*)ci->focus) {
2513                                 PyErr_SetString(PyExc_TypeError,
2514                                                 "'focus' given with other pane");
2515                                 return False;
2516                         }
2517                         if (!PyObject_TypeCheck(a, &PaneType)) {
2518                                 PyErr_SetString(PyExc_TypeError,
2519                                                 "'focus' must be a pane");
2520                                 return False;
2521                         }
2522                         p = (Pane*)a;
2523                         if (p->pane)
2524                                 ci->focus = p->pane;
2525                         else {
2526                                 PyErr_SetString(PyExc_TypeError, "focus value invalid");
2527                                 return False;
2528                         }
2529                 }
2530                 a = PyDict_GetItemString(kwds, "xy");
2531                 if (a && a != Py_None) {
2532                         PyObject *n1, *n2;
2533                         if (xy_set) {
2534                                 PyErr_SetString(PyExc_TypeError,
2535                                                 "'xy' given with other tuple");
2536                                 return False;
2537                         }
2538                         if (!PyTuple_Check(a) || PyTuple_GET_SIZE(a) != 2) {
2539                                 PyErr_SetString(PyExc_TypeError,
2540                                                 "'xy' must be a tuple of 2 integers");
2541                                 return False;
2542                         }
2543                         n1 = PyTuple_GetItem(a, 0);
2544                         n2 = PyTuple_GetItem(a, 1);
2545                         if (!PyLong_Check(n1) || !PyLong_Check(n2)) {
2546                                 PyErr_SetString(PyExc_TypeError, "Only tuples of integers permitted");
2547                                 return False;
2548                         }
2549                         ci->x = PyLong_AsLong(n1);
2550                         ci->y = PyLong_AsLong(n2);
2551                         xy_set = 1;
2552                 }
2553                 a = PyDict_GetItemString(kwds, "comm2");
2554                 if (a && a != Py_None) {
2555                         if (ci->comm2) {
2556                                 PyErr_SetString(PyExc_TypeError,
2557                                                 "'comm2' given with other command");
2558                                 return False;
2559                         }
2560                         if (PyObject_TypeCheck(a, &CommType)) {
2561                                 Comm *c = (Comm*)a;
2562                                 if (c->comm)
2563                                         ci->comm2 = command_get(c->comm);
2564                                 else {
2565                                         PyErr_SetString(PyExc_TypeError, "comm2 value invalid");
2566                                         return False;
2567                                 }
2568                         } else if (PyCallable_Check(a)) {
2569                                 struct python_command *pc = export_callable(a);
2570
2571                                 ci->comm2 = &pc->c;
2572                         } else {
2573                                 PyErr_SetString(PyExc_TypeError,
2574                                                 "'comm2' must be a callable");
2575                                 return False;
2576                         }
2577                 }
2578         }
2579         if (!(void*)ci->key) {
2580                 PyErr_SetString(PyExc_TypeError, "No key specified");
2581                 return False;
2582         }
2583         if (!(void*)ci->home) {
2584                 PyErr_SetString(PyExc_TypeError, "No pane specified");
2585                 return False;
2586         }
2587         if (!(void*)ci->focus)
2588                 ci->focus = ci->home;
2589
2590         return True;
2591 }
2592
2593 static PyObject *py_time_start(PyObject *self, PyObject *args)
2594 {
2595         int type;
2596         int ret = PyArg_ParseTuple(args, "i", &type);
2597
2598         if (ret <= 0)
2599                 return NULL;
2600         time_start(type);
2601
2602         Py_INCREF(Py_None);
2603         return Py_None;
2604 }
2605
2606 static PyObject *py_time_stop(PyObject *self, PyObject *args)
2607 {
2608         int type;
2609         int ret = PyArg_ParseTuple(args, "i", &type);
2610
2611         if (ret <= 0)
2612                 return NULL;
2613         time_stop(type);
2614
2615         Py_INCREF(Py_None);
2616         return Py_None;
2617 }
2618
2619 static PyObject *py_LOG(PyObject *self, PyObject *args)
2620 {
2621         int argc = PySequence_Length(args);
2622         int i;
2623         char buf[1024];
2624         int l = 0;
2625
2626         for (i = 0; i < argc; i++) {
2627                 PyObject *o = PySequence_GetItem(args, i);
2628                 PyObject *s, *tofree = NULL;
2629                 char *str;
2630                 unsigned int slen;
2631
2632                 if (!o)
2633                         continue;
2634                 s = PyObject_Str(o);
2635                 Py_DECREF(o);
2636                 if (!s)
2637                         continue;
2638                 str = python_as_string(s, &tofree);
2639                 slen = str ? strlen(str) : 0;
2640                 if (str && slen < sizeof(buf) - l - 2) {
2641                         if (l)
2642                                 buf[l++] = ' ';
2643                         strcpy(buf+l, str);
2644                         l += slen;
2645                 }
2646                 Py_XDECREF(tofree);
2647         }
2648         buf[l] = 0;
2649         if (l)
2650                 LOG("%s", buf);
2651
2652         Py_INCREF(Py_None);
2653         return Py_None;
2654 }
2655
2656 static PyMethodDef edlib_methods[] = {
2657         {"time_start", py_time_start, METH_VARARGS,
2658          "Record start time"},
2659         {"time_stop", py_time_stop, METH_VARARGS,
2660          "Record stop time"},
2661         {"LOG", py_LOG, METH_VARARGS,
2662          "Generate log message"},
2663         {NULL, NULL, 0, NULL}
2664 };
2665
2666 /* This must be visible when the module is loaded so it
2667  * cannot be static.  spares doesn't like variables that are
2668  * neither extern nor static.  So mark it extern
2669  */
2670 extern char *edlib_module_path;
2671 char *edlib_module_path;
2672
2673 static struct PyModuleDef edlib_mod = {
2674         PyModuleDef_HEAD_INIT,
2675         .m_name         = "edlib",
2676         .m_doc          = "edlib - one more editor is never enough.",
2677         .m_methods      = edlib_methods,
2678 };
2679
2680 void edlib_init(struct pane *ed safe)
2681 {
2682         PyObject *m;
2683         wchar_t *argv[1]= { NULL };
2684
2685         if (edlib_module_path)
2686                 module_dir = strdup(edlib_module_path);
2687         else
2688                 module_dir = ".";
2689
2690         /* This cast is for sparse, which doesn't seem to cope with L".."
2691          * FIXME
2692          */
2693         Py_SetProgramName((wchar_t*)L"edlib");
2694         Py_Initialize();
2695         PySys_SetArgv(0, argv);
2696
2697         PaneType.tp_new = PyType_GenericNew;
2698         PaneIterType.tp_new = PyType_GenericNew;
2699         DocType.tp_new = PyType_GenericNew;
2700         MarkType.tp_new = PyType_GenericNew;
2701         CommType.tp_new = PyType_GenericNew;
2702         if (PyType_Ready(&PaneType) < 0 ||
2703             PyType_Ready(&PaneIterType) < 0 ||
2704             PyType_Ready(&DocType) < 0 ||
2705             PyType_Ready(&MarkType) < 0 ||
2706             PyType_Ready(&CommType) < 0)
2707                 return;
2708
2709         m = PyModule_Create(&edlib_mod);
2710
2711         if (!m)
2712                 return;
2713
2714         PyModule_AddObject(m, "Pane", (PyObject *)&PaneType);
2715         PyModule_AddObject(m, "PaneIter", (PyObject *)&PaneIterType);
2716         PyModule_AddObject(m, "Mark", (PyObject *)&MarkType);
2717         PyModule_AddObject(m, "Comm", (PyObject *)&CommType);
2718         PyModule_AddObject(m, "Doc", (PyObject *)&DocType);
2719         PyModule_AddIntMacro(m, DAMAGED_CHILD);
2720         PyModule_AddIntMacro(m, DAMAGED_SIZE);
2721         PyModule_AddIntMacro(m, DAMAGED_VIEW);
2722         PyModule_AddIntMacro(m, DAMAGED_REFRESH);
2723         PyModule_AddIntMacro(m, DAMAGED_POSTORDER);
2724         PyModule_AddIntMacro(m, DAMAGED_CLOSED);
2725         PyModule_AddIntMacro(m, Efallthrough);
2726         PyModule_AddIntMacro(m, Enoarg);
2727         PyModule_AddIntMacro(m, Einval);
2728         PyModule_AddIntMacro(m, Efalse);
2729         PyModule_AddIntMacro(m, Efail);
2730         PyModule_AddIntMacro(m, Enosup);
2731         PyModule_AddIntMacro(m, Efail);
2732         PyModule_AddIntMacro(m, NO_NUMERIC);
2733
2734         PyModule_AddIntMacro(m, TIME_KEY);
2735         PyModule_AddIntMacro(m, TIME_WINDOW);
2736         PyModule_AddIntMacro(m, TIME_READ);
2737         PyModule_AddIntMacro(m, TIME_SIG);
2738         PyModule_AddIntMacro(m, TIME_TIMER);
2739         PyModule_AddIntMacro(m, TIME_IDLE);
2740         PyModule_AddIntMacro(m, TIME_REFRESH);
2741
2742         PyModule_AddIntMacro(m, RXL_ANCHORED);
2743         PyModule_AddIntMacro(m, RXL_BACKTRACK);
2744
2745         PyModule_AddIntMacro(m, MARK_UNGROUPED);
2746         PyModule_AddIntMacro(m, MARK_POINT);
2747
2748         PyModule_AddIntConstant(m, "WEOF", 0x3FFFFF);
2749         call_comm("global-set-command", ed, &python_load, 0, NULL, "python-load");
2750         call_comm("global-set-command", ed, &python_load_module,
2751                   0, NULL, "global-load-modules:python");
2752
2753         Edlib_CommandFailed = PyErr_NewException("edlib.commandfailed", NULL, NULL);
2754         Py_INCREF(Edlib_CommandFailed);
2755         PyModule_AddObject(m, "commandfailed", Edlib_CommandFailed);
2756         EdlibModule = m;
2757         ed_pane = ed;
2758 }