]> git.neil.brown.name Git - edlib.git/commitdiff
python: change how modules are loaded into the interpreter
authorNeilBrown <neil@brown.name>
Fri, 2 Jun 2023 07:24:00 +0000 (17:24 +1000)
committerNeilBrown <neil@brown.name>
Wed, 28 Jun 2023 05:40:19 +0000 (15:40 +1000)
Each edlib module is now a separate python module.
They must all "import edlib" and can find the editor pane in
"edlib.editor"
They must also import any modules they use.

Signed-off-by: NeilBrown <neil@brown.name>
24 files changed:
DOC/TODO.md
lang-python.c
python/config.py
python/display-pygtk.py
python/lib-abbrev.py
python/lib-autospell.py
python/lib-compose-email.py
python/lib-diff.py
python/lib-doc-to-text.py
python/lib-glibevents.py
python/lib-html-to-text.py
python/lib-html-w3m.py
python/lib-ical-to-text.py
python/lib-macro.py
python/lib-make.py
python/lib-mergeview.py
python/lib-pdf-to-text.py
python/lib-server.py
python/lib-shellcmd.py
python/lib-textfill.py
python/module-notmuch.py
python/render-c-mode.py
python/render-calc.py
python/render-present.py

index 003888576ab5a8a641bf975bf3d371341a4cd8e4..f9703a51ffda17b6962647e0e3f9e0e24a4322b5 100644 (file)
@@ -18,7 +18,7 @@ the file.
 - [X] ncurses - don't block in nc_external_viewer - at least abort after
       30 seconds, but preferrably switch to a mode which leaves
       everything else running.
-- [ ] lang-python should put each module in a separate module
+- [X] lang-python should put each module in a separate module
       Maybe PyImport_ExecCodeModuleEx() after reading and compile()ing
       the source file.  Or set up path to find edlib modules.
 
@@ -638,7 +638,7 @@ Module features
 ### lang-python
 
 - [ ] repeated alarm(10)/alarm(0) calls slow things down
-- [ ] lang-python should put each module in a separate module
+- [X] lang-python should put each module in a separate module
       Maybe PyImport_ExecCodeModuleEx() after reading and compile()ing
       the source file.  Or set up path to find edlib modules.
 - [ ] array index should allow two args, second being a mark for
index 2c91355cf31c7b90ea3c4d407d3e3ec950000528..70e5fe61a752de7863e3bbf770a8f42f340d8674 100644 (file)
@@ -64,6 +64,7 @@ struct doc_ref {
        int o;
 };
 
+#include <fcntl.h>
 #include <signal.h>
 #include "core.h"
 #include "misc.h"
@@ -334,32 +335,52 @@ out:
 DEF_CMD(python_load_module)
 {
        const char *name = ci->str;
-       FILE *fp;
-       PyObject *globals, *main_mod;
-       PyObject *Ed;
-       char buf [PATH_MAX];
+       int fd;
+       long long size;
+       char *code;
+       char buf[PATH_MAX];
+       char buf2[PATH_MAX];
+       PyObject *builtins, *compile, *args, *bytecode;
 
        if (!name)
                return Enoarg;
        snprintf(buf, sizeof(buf), "%s/python/%s.py", module_dir, name);
-       fp = fopen(buf, "r");
-       if (!fp)
+       fd = open(buf, O_RDONLY);
+       if (fd < 0)
                return Efail;
+       size = lseek(fd, 0, SEEK_END);
+       lseek(fd, 0, SEEK_SET);
+       code = malloc(size+1);
+       if (!code) {
+               close(fd);
+               return Efail;
+       }
+       size = read(fd, code, size);
+       close(fd);
+       if (size <= 0) {
+               free(code);
+               return Efail;
+       }
+       code[size] = 0;
 
        LOG("Loading python module %s from %s", name, buf);
-       main_mod = PyImport_AddModule("__main__");
-       if (main_mod == NULL)
-               return Einval;
-       globals = PyModule_GetDict(main_mod);
-
-       Ed = Pane_Frompane(ci->home);
-       PyDict_SetItemString(globals, "editor", Ed);
-       PyDict_SetItemString(globals, "pane", Pane_Frompane(ci->focus));
-       PyDict_SetItemString(globals, "edlib", EdlibModule);
-       PyRun_FileExFlags(fp, buf, Py_file_input, globals, globals, 0, NULL);
-       PyErr_LOG();
-       Py_DECREF(Ed);
-       fclose(fp);
+
+       builtins = PyEval_GetBuiltins();
+       compile = PyDict_GetItemString(builtins, "compile");
+       args = safe_cast Py_BuildValue("(sss)", code, buf, "exec");
+       bytecode = PyObject_Call(compile, args, NULL);
+       Py_DECREF(args);
+       free(code);
+       if (bytecode == NULL) {
+               PyErr_LOG();
+               return Efail;
+       }
+
+       snprintf(buf2, sizeof(buf2), "edlib.%s", name);
+
+       if (PyImport_ExecCodeModule(buf2, bytecode) == NULL)
+               PyErr_LOG();
+       Py_DECREF(bytecode);
        return 1;
 }
 
@@ -2891,19 +2912,12 @@ static PyMethodDef edlib_methods[] = {
 };
 
 /* This must be visible when the module is loaded so it
- * cannot be static.  spares doesn't like variables that are
+ * cannot be static.  sparse doesn't like variables that are
  * neither extern nor static.  So mark it extern
  */
 extern char *edlib_module_path;
 char *edlib_module_path;
 
-static struct PyModuleDef edlib_mod = {
-       PyModuleDef_HEAD_INIT,
-       .m_name         = "edlib",
-       .m_doc          = "edlib - one more editor is never enough.",
-       .m_methods      = edlib_methods,
-};
-
 void edlib_init(struct pane *ed safe)
 {
        PyObject *m;
@@ -2915,9 +2929,6 @@ void edlib_init(struct pane *ed safe)
        else
                module_dir = ".";
 
-       /* This cast is for sparse, which doesn't seem to cope with L".."
-        * FIXME
-        */
        PyConfig_InitPythonConfig(&config);
        config.isolated = 1;
        PyConfig_SetBytesArgv(&config, 0, argv);
@@ -2936,11 +2947,16 @@ void edlib_init(struct pane *ed safe)
            PyType_Ready(&CommType) < 0)
                return;
 
-       m = PyModule_Create(&edlib_mod);
-
-       if (!m)
+       m = PyImport_AddModule("edlib");
+       if (!m) {
+               PyErr_LOG();
                return;
+       }
+
+       PyModule_SetDocString(m , "edlib - one more editor is never enough");
 
+       PyModule_AddFunctions(m, edlib_methods);
+       PyModule_AddObject(m, "editor", Pane_Frompane(ed));
        PyModule_AddObject(m, "Pane", (PyObject *)&PaneType);
        PyModule_AddObject(m, "PaneIter", (PyObject *)&PaneIterType);
        PyModule_AddObject(m, "Mark", (PyObject *)&MarkType);
@@ -2977,12 +2993,14 @@ void edlib_init(struct pane *ed safe)
        PyModule_AddIntMacro(m, MARK_POINT);
 
        PyModule_AddIntConstant(m, "WEOF", 0x3FFFFF);
-       call_comm("global-set-command", ed, &python_load_module,
-                 0, NULL, "global-load-modules:python");
 
        Edlib_CommandFailed = PyErr_NewException("edlib.commandfailed", NULL, NULL);
        Py_INCREF(Edlib_CommandFailed);
        PyModule_AddObject(m, "commandfailed", Edlib_CommandFailed);
+
        EdlibModule = m;
        ed_pane = ed;
+
+       call_comm("global-set-command", ed, &python_load_module,
+                 0, NULL, "global-load-modules:python");
 }
index 5df740d029874efdc676d651a13a76f8cdbf9cd9..eacacef74eab869a69dd5e83c455ab1b011c4969 100644 (file)
@@ -7,6 +7,7 @@
 # config module with a more abstract language one day.
 # But I want some simple configuration NOW
 
+from edlib import editor
 import os
 
 def config_appeared(key, focus, **a):
@@ -36,8 +37,6 @@ def config_appeared(key, focus, **a):
                                   " *#+|"              # section head
                                   " *[0-9]*\\.)")      # Numbered list
 
-    return edlib.Efallthrough
-
 editor.call("global-set-command", "doc:appeared-config", config_appeared)
 
 # Some modules I want auto-loaded.
index f33d5b5dc11683be2d5201dda9f275a0bb3c46d1..bc1d84b375adfd578d51b7516021c033af776c2c 100644 (file)
@@ -6,10 +6,12 @@
 # receive mouse/keyboard events.
 # provides eventloop function using gtk.main.
 
-import os
+import edlib
+import os, fcntl
 import gi
 import time
 import cairo
+import subprocess
 
 gi.require_version('Gtk', '3.0')
 gi.require_version('PangoCairo', '1.0')
@@ -97,8 +99,7 @@ class EdDisplay(edlib.Pane):
 
     def handle_new(self, key, focus, **a):
         "handle:Display:new"
-        global editor
-        newdisp = EdDisplay(editor, self['DISPLAY'])
+        newdisp = EdDisplay(edlib.editor, self['DISPLAY'])
         p = newdisp.call("editor:activate-display", ret='pane')
         if p:
             focus.call("doc:attach-view", p, 1)
@@ -761,5 +762,5 @@ def new_display2(key, focus, **a):
         focus.call("doc:attach-view", p, 1);
     return 1
 
-editor.call("global-set-command", "attach-display-gtk", new_display)
-editor.call("global-set-command", "interactive-cmd-gtkwindow", new_display2)
+edlib.editor.call("global-set-command", "attach-display-gtk", new_display)
+edlib.editor.call("global-set-command", "interactive-cmd-gtkwindow", new_display2)
index 30da88db3702327f01f1b8df8f18b38eac273ffe..0e7b87e10d27939d55e8d40a117bff300179afbb 100644 (file)
@@ -14,6 +14,8 @@
 #   Anything else is passed to parent, and if that doesn't result
 #     in a callback, we self-destruct
 
+import edlib
+
 class AbbrevPane(edlib.Pane):
     def __init__(self, focus):
         edlib.Pane.__init__(self, focus)
@@ -244,4 +246,4 @@ def abbrev_attach(key, focus, comm2, **a):
         comm2("cb", p)
     return 1
 
-editor.call("global-set-command", "attach-abbrev", abbrev_attach)
+edlib.editor.call("global-set-command", "attach-abbrev", abbrev_attach)
index 37cae7eefc36d881f534ba0976dcbd83a2562061..0231087343000c72303799d4cd41fdd8755bf924 100644 (file)
@@ -21,6 +21,8 @@
 #   choose_range(focus, viewnum, attr, start, end) - changes start and end to be
 #    a contiguous unchecked section in the range
 
+import edlib
+
 def show_range(action, focus, viewnum, attr):
     edlib.LOG("range:", attr, action)
     f,l = focus.vmarks(viewnum)
@@ -316,6 +318,6 @@ def autospell_activate(key, focus, comm2, **a):
 
     return 1
 
-editor.call("global-set-command", "attach-autospell", autospell_attach)
-editor.call("global-set-command", "interactive-cmd-autospell",
+edlib.editor.call("global-set-command", "attach-autospell", autospell_attach)
+edlib.editor.call("global-set-command", "interactive-cmd-autospell",
             autospell_activate)
index 654a17a3b69eccf4d04f3adf09107c8ddff31fe7..4bc044b714e0f0aad3eae9ce12016ec8388a25c0 100644 (file)
 #   The content of filename is url encoded
 #
 
+import edlib
+
+import os
+import subprocess
 import email.utils
 import email.message
 import email.policy
@@ -37,6 +41,7 @@ import email.headerregistry
 import tempfile
 import mimetypes
 import urllib
+import re
 from datetime import date
 
 def read_status(p, key, focus, **a):
@@ -904,4 +909,4 @@ def compose_mode_attach(key, focus, comm2, **a):
         comm2("cb", p)
     return 1
 
-editor.call("global-set-command", "attach-compose-email", compose_mode_attach)
+edlib.editor.call("global-set-command", "attach-compose-email", compose_mode_attach)
index b88d3826bcf065b34e1587addfabc2cb9e6c0ade..bd4487924ce66c605110c1a3d7bd97448fc66802 100644 (file)
@@ -7,6 +7,8 @@
 # - colourizes + and - lines
 # - interprets ':Enter' to find the given line
 
+import edlib
+
 import os.path
 
 def djoin(dir, tail):
@@ -332,6 +334,6 @@ def add_diff(key, focus, **a):
     focus.call("doc:append:view-default", ",diff")
     return 1
 
-editor.call("global-set-command", "attach-diff", diff_view_attach)
-editor.call("global-set-command", "interactive-cmd-diff-mode", add_diff)
-editor.call("global-load-module", "lib-wiggle")
+edlib.editor.call("global-set-command", "attach-diff", diff_view_attach)
+edlib.editor.call("global-set-command", "interactive-cmd-diff-mode", add_diff)
+edlib.editor.call("global-load-module", "lib-wiggle")
index c58ceaf5c65e8c4bd1c465dbc44124caeeefc1fd..4969a101379944b3f120ccd65c85d45802f59e9b 100644 (file)
@@ -6,9 +6,11 @@
 # converts it to text using lowriter.
 # Unfortunately lowriter only reads and writes a file, not a pipe..
 
+import edlib
+
 import subprocess
 import tempfile
-import os
+import os, fcntl
 
 class doc_pane(edlib.Pane):
     def __init__(self, focus, path, newpath, delayed):
@@ -137,5 +139,4 @@ def doc_to_text(key, home, focus, num, str1, comm2, **a):
     comm2("cb", doc)
     return 1
 
-if "editor" in globals():
-    editor.call("global-set-command", "doc-to-text", doc_to_text)
+edlib.editor.call("global-set-command", "doc-to-text", doc_to_text)
index 233ad1b1255f7eb604c0a89b5eb484e82574a30c..cd89b10010864678f5c6577469ec4fbb8acc03aa 100644 (file)
@@ -4,6 +4,8 @@
 
 # edlib module for getting events from GLib
 
+import edlib
+
 import signal
 import gi
 import os
@@ -216,4 +218,4 @@ def register_events(key, focus, comm2, **a):
     events_activate(focus)
     return 1
 
-editor.call("global-set-command", "attach-glibevents", register_events)
+edlib.editor.call("global-set-command", "attach-glibevents", register_events)
index 5ba5725a688ab3195dff09f5a08bf799e4fd6b1a..baf06410bbe1a1b1072f6c45e27a5d0d0e6f9bc3 100644 (file)
@@ -6,6 +6,8 @@
 # converts it from html to markdown, and creates a text pane with the
 # markdown text.
 
+import edlib
+
 import html2text
 
 def html_to_text(key, home, focus, comm2, **a):
@@ -38,5 +40,4 @@ def html_to_text(key, home, focus, comm2, **a):
     comm2("cb", doc)
     return 1
 
-if "editor" in globals():
-    editor.call("global-set-command", "html-to-text", html_to_text)
+edlib.editor.call("global-set-command", "html-to-text", html_to_text)
index 0ad08728747dc2ad2119bfd8b0157674334de806..1d074f373b5b01b99a7774afe90f3fb8296bb632 100644 (file)
@@ -10,6 +10,9 @@
 # applied the changes to the text as render attributes.
 #
 
+import edlib
+
+import os, fcntl
 import subprocess
 
 def get_attr(tagl, tag, attr):
@@ -559,5 +562,4 @@ def map_entities(str):
 
     return ret + str
 
-if "editor" in globals():
-    editor.call("global-set-command", "html-to-text-w3m", html_to_w3m)
+edlib.editor.call("global-set-command", "html-to-text-w3m", html_to_w3m)
index 6d8d1bedf43b59607ef0f54b79e4409d03ccb0f0..abc1f9dd8a888e0e132d80c7da43e0998abfdc56 100644 (file)
@@ -6,6 +6,9 @@
 # converts it from ical to simple text, and creates a text pane with
 # that text.
 
+import edlib
+
+import time
 import icalendar
 
 def ical_to_text(key, home, focus, comm2, **a):
@@ -53,5 +56,4 @@ def ical_to_text(key, home, focus, comm2, **a):
     comm2("cb", doc)
     return 1
 
-if "editor" in globals():
-    editor.call("global-set-command", "ical-to-text", ical_to_text)
+edlib.editor.call("global-set-command", "ical-to-text", ical_to_text)
index 9fd46b443538ef719ef35f2115827dcb9df04cbe..fb28821168254690bdeaacc1ae184bb13c6c98cd 100644 (file)
@@ -16,6 +16,8 @@
 # Other functionality is available simply through global commands.
 #
 
+import edlib
+
 docname = "*Macro History*"
 
 # A macro is a list of keystroke separated by commas
@@ -133,7 +135,7 @@ def name_macro(key, focus, num, str, **a):
         num = 1
     focus.call("history:get-last", num, docname, str)
 
-editor.call("global-set-command", "macro:capture", start_capture)
-editor.call("global-set-command", "macro:finished", end_capture)
-editor.call("global-set-command", "macro:replay", play_macro)
-editor.call("global-set-command", "macro:name", name_macro)
+edlib.editor.call("global-set-command", "macro:capture", start_capture)
+edlib.editor.call("global-set-command", "macro:finished", end_capture)
+edlib.editor.call("global-set-command", "macro:replay", play_macro)
+edlib.editor.call("global-set-command", "macro:name", name_macro)
index a891c45fd7450ae8430cc30adc72b99df3885bfe..e09ef68132ee67cdac5130170a71eaab2607aee4 100644 (file)
@@ -3,6 +3,8 @@
 # May be distributed under terms of GPLv2 - see file:COPYING
 #
 
+import edlib
+
 import os, fcntl, signal
 
 class MakePane(edlib.Pane):
@@ -932,9 +934,9 @@ def next_match(key, focus, num, str1, num2, **a):
 
     return 1
 
-editor.call("global-set-command", "attach-makecmd", make_attach)
-editor.call("global-set-command", "attach-make-viewer", make_view_attach)
-editor.call("global-set-command", "interactive-cmd-make", make_request)
-editor.call("global-set-command", "interactive-cmd-grep", make_request)
-editor.call("global-set-command", "interactive-cmd-git-grep", make_request)
-editor.call("global-set-command", "interactive-cmd-next-match", next_match)
+edlib.editor.call("global-set-command", "attach-makecmd", make_attach)
+edlib.editor.call("global-set-command", "attach-make-viewer", make_view_attach)
+edlib.editor.call("global-set-command", "interactive-cmd-make", make_request)
+edlib.editor.call("global-set-command", "interactive-cmd-grep", make_request)
+edlib.editor.call("global-set-command", "interactive-cmd-git-grep", make_request)
+edlib.editor.call("global-set-command", "interactive-cmd-next-match", next_match)
index 97991bc8f634d6fd165267708374119ed4af21c5..01518445b6ccc805ba78aa993b199a0f482aeead 100644 (file)
@@ -12,6 +12,8 @@
 # If cursor is not on any, it is moved forward to the next one.
 #
 
+import edlib
+
 class MergePane(edlib.Pane):
     def __init__(self, focus):
         edlib.Pane.__init__(self, focus)
@@ -197,6 +199,6 @@ def add_merge(key, focus, mark, **a):
         p.call("K:A-m", focus, mark)
     return 1
 
-editor.call("global-set-command", "attach-merge", merge_view_attach)
-editor.call("global-set-command", "interactive-cmd-merge-mode", add_merge)
-editor.call("global-load-module", "lib-wiggle")
+edlib.editor.call("global-set-command", "attach-merge", merge_view_attach)
+edlib.editor.call("global-set-command", "interactive-cmd-merge-mode", add_merge)
+edlib.editor.call("global-load-module", "lib-wiggle")
index c3040ab5030a0110f862c39f2553754a358f3042..4efbbf13388e208aee1311d90741f3e3504852d2 100644 (file)
@@ -6,6 +6,9 @@
 # converts it from pdf to text, and creates a text doc with the
 # text.
 
+import edlib
+
+import os, fcntl
 import subprocess
 
 class pdf_pane(edlib.Pane):
@@ -128,5 +131,4 @@ def pdf_to_text(key, home, focus, num, comm2, **a):
     comm2("cb", doc)
     return 1
 
-if "editor" in globals():
-    editor.call("global-set-command", "pdf-to-text", pdf_to_text)
+edlib.editor.call("global-set-command", "pdf-to-text", pdf_to_text)
index 500f6d816e807f7a09640006d4173b6284289ee4..5b3c93bbb3b1c45dd2a34d099abb2cedea1ed4b2 100755 (executable)
@@ -12,19 +12,21 @@ else:
     sockpath = "/tmp/edlib-neilb"
 
 try:
+    import edlib
+
     class ServerPane(edlib.Pane):
         # This pane receives requests on a socket and
         # forwards them to the editor.  When a notification
         # arrives, it is sent back to the client
         def __init__(self, sock):
-            edlib.Pane.__init__(self, editor)
+            edlib.Pane.__init__(self, edlib.editor)
             self.sock = sock
             self.term = None
             self.disp = None
             self.doc = None
             self.want_close = False
             self.lineno = None
-            editor.call("event:read", sock.fileno(),
+            edlib.editor.call("event:read", sock.fileno(),
                         self.read)
 
         def read(self, key, **a):
@@ -66,7 +68,7 @@ try:
                     path = msg[5:].decode("utf-8",'ignore')
                     try:
                         # 8==reload
-                        d = editor.call("doc:open", -1, 8, path, ret='pane')
+                        d = edlib.editor.call("doc:open", -1, 8, path, ret='pane')
                     except edlib.commandfailed:
                         d = None
                     if not d:
@@ -108,7 +110,7 @@ try:
                     return 1
                 if msg[:21] == b"doc:request:doc:done:":
                     path = msg[21:].decode("utf-8", 'ignore')
-                    d = editor.call("doc:open", -1, path, ret='pane')
+                    d = edlib.editor.call("doc:open", -1, path, ret='pane')
                     if not d:
                         self.sock.send(b"FAIL")
                         return 1
@@ -128,7 +130,7 @@ try:
                     self.sock.send(b"OK")
                     return 1
                 if cmd == 'x11window' and not self.term:
-                    p = editor.call("interactive-cmd-x11window",
+                    p = edlib.editor.call("interactive-cmd-x11window",
                                     arg, env['XAUTHORITY'], ret='pane')
                     if p:
                         for v in env:
@@ -140,7 +142,7 @@ try:
                     return 1
                 if cmd == 'term' and not self.term:
                     path = arg
-                    p = editor
+                    p = edlib.editor
                     p = p.call("attach-display-ncurses", path, env['TERM'],
                                ret='pane')
                     for v in env:
@@ -394,7 +396,7 @@ else:
         if key != "key":
             focus.call("Message", "Server restarted")
         return 1
-    server_rebind("key", editor)
-    editor.call("global-set-command", "lib-server:done", server_done)
-    editor.call("global-set-command", "interactive-cmd-server-start",
+    server_rebind("key", edlib.editor)
+    edlib.editor.call("global-set-command", "lib-server:done", server_done)
+    edlib.editor.call("global-set-command", "interactive-cmd-server-start",
                 server_rebind)
index 28c65979459bf34cdc088a134733fb965535e386..4e415b2747c5664b027e8b93a1ef1f6a9c23a209 100644 (file)
@@ -3,6 +3,8 @@
 # May be distributed under terms of GPLv2 - see file:COPYING
 #
 
+import edlib
+
 import subprocess, os, fcntl, signal
 
 class ShellPane(edlib.Pane):
@@ -260,5 +262,5 @@ def shell_view_attach(key, focus, comm2, **a):
         comm2("callback", p)
     return 1
 
-editor.call("global-set-command", "attach-shellcmd", shell_attach)
-editor.call("global-set-command", "attach-shell-viewer", shell_view_attach)
+edlib.editor.call("global-set-command", "attach-shellcmd", shell_attach)
+edlib.editor.call("global-set-command", "attach-shell-viewer", shell_view_attach)
index d9da65f9d1788694009f9875d9a7c152929f1f73..f673450e75034ca4520474c090ee0b96a5faf6bf 100644 (file)
@@ -23,6 +23,8 @@
 # is then chosen as the maximal set of non-alphanumerics non-quote
 # characters.
 
+import edlib
+
 import re
 
 def span(line, chars):
@@ -353,6 +355,6 @@ def fill_mode_activate(key, focus, comm2, **a):
     focus.call("doc:append:view-default", ",textfill")
     return 1
 
-editor.call("global-set-command", "attach-textfill", fill_mode_attach)
-editor.call("global-set-command", "interactive-cmd-fill-mode",
+edlib.editor.call("global-set-command", "attach-textfill", fill_mode_attach)
+edlib.editor.call("global-set-command", "interactive-cmd-fill-mode",
             fill_mode_activate)
index db1786514328bc38ff1ed0623524651ede01ea94..60086c9205bc25e17e92a10def69400af48a1606 100644 (file)
 # "query.misc-list" is a subset of current-list for which query:current should not
 # be assumed.
 
+import edlib
+
 from subprocess import Popen, PIPE, DEVNULL, TimeoutExpired
 import re
-import os
-import os.path
+import tempfile
+import os, fcntl
 import json
 import time
 import mimetypes
@@ -608,10 +610,9 @@ class notmuch_main(edlib.Doc):
             comm2("callback", focus, "%d" % self.searches.maxlen)
             return 1
         if str.startswith('config:'):
-            p = subprocess.Popen(['/usr/bin/notmuch', 'config', 'get', str[7:]],
-                                 close_fds = True,
-                                 stderr = subprocess.PIPE,
-                                 stdout = subprocess.PIPE)
+            p = Popen(['/usr/bin/notmuch', 'config', 'get', str[7:]],
+                      close_fds = True,
+                      stderr = PIPE, stdout = PIPE)
             out,err = p.communicate()
             p.wait()
             if out:
@@ -3728,14 +3729,13 @@ def notmuch_search(key, focus, **a):
         p.call("doc:char-s")
     return 1
 
-if "editor" in globals():
-    editor.call("global-set-command", "attach-doc-notmuch", notmuch_doc)
-    editor.call("global-set-command", "attach-render-notmuch:master-view",
-                render_master_view_attach)
-    editor.call("global-set-command", "attach-render-notmuch:threads",
-                render_query_attach)
-    editor.call("global-set-command", "attach-render-notmuch:message",
-                render_message_attach)
-    editor.call("global-set-command", "interactive-cmd-nm", notmuch_mode)
-    editor.call("global-set-command", "interactive-cmd-nmc", notmuch_compose)
-    editor.call("global-set-command", "interactive-cmd-nms", notmuch_search)
+edlib.editor.call("global-set-command", "attach-doc-notmuch", notmuch_doc)
+edlib.editor.call("global-set-command", "attach-render-notmuch:master-view",
+                  render_master_view_attach)
+edlib.editor.call("global-set-command", "attach-render-notmuch:threads",
+                  render_query_attach)
+edlib.editor.call("global-set-command", "attach-render-notmuch:message",
+                  render_message_attach)
+edlib.editor.call("global-set-command", "interactive-cmd-nm", notmuch_mode)
+edlib.editor.call("global-set-command", "interactive-cmd-nmc", notmuch_compose)
+edlib.editor.call("global-set-command", "interactive-cmd-nms", notmuch_search)
index eefa5f0527a8311bf312afde927e2220fa9c052e..27feea27427eebccf951b6880c094a82f92ceae2 100644 (file)
@@ -2,6 +2,8 @@
 # Copyright Neil Brown (c)2018-2023 <neil@brown.name>
 # May be distributed under terms of GPLv2 - see file:COPYING
 
+import edlib
+
 def textwidth(line, w=0):
     for c in line:
         if c == '\t':
@@ -1063,8 +1065,8 @@ def attach_indent(key, focus, **a):
     CModePane(focus)
     return 1
 
-editor.call("global-set-command", "doc:appeared-c-mode", c_mode_appeared)
-editor.call("global-set-command", "doc:appeared-py-mode", py_mode_appeared)
-editor.call("global-set-command", "attach-c-mode", c_mode_attach)
-editor.call("global-set-command", "attach-py-mode", py_mode_attach)
-editor.call("global-set-command", "interactive-cmd-indent", attach_indent)
+edlib.editor.call("global-set-command", "doc:appeared-c-mode", c_mode_appeared)
+edlib.editor.call("global-set-command", "doc:appeared-py-mode", py_mode_appeared)
+edlib.editor.call("global-set-command", "attach-c-mode", c_mode_attach)
+edlib.editor.call("global-set-command", "attach-py-mode", py_mode_attach)
+edlib.editor.call("global-set-command", "interactive-cmd-indent", attach_indent)
index cd70f9b0f984273571c73c6b0b13b54a94dfe13c..7fbaef43d91a05462eaaba0a44faed14967bc235 100644 (file)
@@ -6,6 +6,8 @@
 # starting '>'
 #
 
+import edlib
+
 class CalcView(edlib.Pane):
     def __init__(self, focus):
         edlib.Pane.__init__(self, focus)
@@ -172,7 +174,7 @@ def calc_appeared(key, focus, **a):
         focus["view-default"] = "view-calc"
     return edlib.Efallthrough
 
-editor.call("global-set-command", "attach-view-calc", calc_view_attach)
-editor.call("global-load-module", "lib-calc")
-editor.call("global-set-command", "interactive-cmd-calc", add_calc)
-editor.call("global-set-command", "doc:appeared-calc", calc_appeared)
+edlib.editor.call("global-set-command", "attach-view-calc", calc_view_attach)
+edlib.editor.call("global-load-module", "lib-calc")
+edlib.editor.call("global-set-command", "interactive-cmd-calc", add_calc)
+edlib.editor.call("global-set-command", "doc:appeared-calc", calc_appeared)
index 252ac6626417bccf9cc119d34c8127895bc28bea..83a7b70c8d16ebda643bc8b6433a2c549b988d91 100644 (file)
@@ -60,6 +60,7 @@ default_attrs = "normal 10 family:sans fg:black bg:white left:5 space-after:1 sp
 # When change happens, type changed to 'unknown' which triggers self.mark_lines() to
 # reparse some of the page.
 
+import edlib
 import re
 import os
 
@@ -773,6 +774,6 @@ def markdown_appeared(key, focus, **a):
         focus["view-default"] = vd
     return edlib.Efallthrough
 
-editor.call("global-set-command", "attach-markdown-present", markdown_attach)
-editor.call("global-set-command", "attach-present", present_attach)
-editor.call("global-set-command", "doc:appeared-present", markdown_appeared)
+edlib.editor.call("global-set-command", "attach-markdown-present", markdown_attach)
+edlib.editor.call("global-set-command", "attach-present", present_attach)
+edlib.editor.call("global-set-command", "doc:appeared-present", markdown_appeared)