]> git.neil.brown.name Git - edlib.git/commitdiff
emacs: support shows shell output in a popup.
authorNeilBrown <neil@brown.name>
Thu, 27 Jul 2023 10:32:59 +0000 (20:32 +1000)
committerNeilBrown <neil@brown.name>
Thu, 27 Jul 2023 10:32:59 +0000 (20:32 +1000)
With a prefix arg of 0 or 1, shellcmd still interpolates the output into
the current buffer.
With a prefix arg of 4, it now shows the output in a popup window, like
visiting a file with
  Cx 4 4 f

Signed-off-by: NeilBrown <neil@brown.name>
DOC/TODO.md
mode-emacs.c
python/lib-shellcmd.py

index 972c8dde0710962bb217295ecc12e046be9e124b..37a2b51c3e0abac76a390a05293fc71b2bab4662 100644 (file)
@@ -11,7 +11,7 @@ the file.
 
 - [X] factor our list-sort code.
 - [X] when cx-b and default doc name is v.long, shift gets confused
-- [ ] How to run shell command in "44" window??
+- [X] How to run shell command in "44" window??
 - [X] In c-mode, if ) is at end of line then highlighting it causes the
       line to wrap
 - [ ] mail compose should refuse to submit email with no valid 'to' address
index 02478dcb985309664ab9a69b574527d64179de7d..fdb824c598365d787493d51d65ee43a6fde31338 100644 (file)
@@ -1737,7 +1737,11 @@ DEF_CB(shellcb)
                        return 2;
        }
        if (strcmp(ci->key, "cb:eof") != 0) {
-               struct pane *par = call_ret(pane, "OtherPane", ci->home);
+               struct pane *par;
+               if (ci->str && strchr(ci->str, 'P'))
+                       par = call_ret(pane, "PopupTile", ci->home, 0, NULL, "MD3tsa");
+               else
+                       par = call_ret(pane, "OtherPane", ci->home);
                if (par)
                        home_call(ci->focus, "doc:attach-view", par, 1);
                return 1;
@@ -1775,7 +1779,7 @@ DEF_CMD(emacs_shell)
        struct pane *p, *doc, *par, *sc;
        char *path, *input = NULL;
        struct pcb cb;
-       int interpolate, pipe;
+       bool interpolate, pipe, popup;
 
        if (strcmp(ci->key, "Shell Command") != 0) {
                char *dirname;
@@ -1788,10 +1792,12 @@ DEF_CMD(emacs_shell)
                dirname = call_ret(strsave, "get-attr", ci->focus, 0, NULL, "dirname");
                attr_set_str(&p->attrs, "dirname", dirname ?: ".");
                attr_set_str(&p->attrs, "prompt", "Shell command");
-               if (ci->num != NO_NUMERIC)
-                       strcat(aux, "i");
+               if (ci->num == 0 || ci->num == 1)
+                       strcat(aux, "i"); // interpolate
+               if (ci->num == 4)
+                       strcat(aux, "P"); // popup
                if (strcmp(ci->key, "K:A-|") == 0)
-                       strcat(aux, "p");
+                       strcat(aux, "p"); // pipe from selection
                attr_set_str(&p->attrs, "popup-aux", aux);
                attr_set_str(&p->attrs, "done-key", "Shell Command");
                call("doc:set-name", p, 0, NULL, "Shell Command", -1);
@@ -1812,6 +1818,7 @@ DEF_CMD(emacs_shell)
 
        interpolate = ci->str2 && strchr(ci->str2, 'i');
        pipe = ci->str2 && strchr(ci->str2, 'p');
+       popup = ci->str2 && strchr(ci->str2, 'P');
 
        if (pipe) {
                struct mark *mk = call_ret(mark2, "doc:point", ci->focus);
@@ -1864,10 +1871,14 @@ DEF_CMD(emacs_shell)
                        if (!interpolate)
                                home_call_comm(sc, "shellcmd:set-callback",
                                               ci->focus, &shellcb,
-                                              500, NULL, NULL,
+                                              500, NULL, popup ? "P": "",
                                               2);
                } else {
-                       par = call_ret(pane, "OtherPane", ci->focus);
+                       if (popup)
+                               par = call_ret(pane, "PopupTile", ci->focus,
+                                              0, NULL, "MD3tsa");
+                       else
+                               par = call_ret(pane, "OtherPane", ci->focus);
                        if (!par)
                                return Efail;
                        home_call(doc, "doc:attach-view", par, 1);
index 8975fdba200f1badb342449ca90423616e57a4f0..e98a4ad0cdd2cc981d7eb0e4b7d037075acdcef6 100644 (file)
@@ -11,6 +11,7 @@ class ShellPane(edlib.Pane):
     def __init__(self, focus, reusable, add_footer=True):
         edlib.Pane.__init__(self, focus)
         self.callback = None
+        self.callback_arg = None
         self.cb_pane = None
         self.cb_lines = 0
         self.line = b''
@@ -120,7 +121,7 @@ class ShellPane(edlib.Pane):
             if self.cb_pane:
                 p = self.cb_pane
                 self.cb_pane = None
-                self.callback("cb:eof", p, ret, self)
+                self.callback("cb:eof", p, ret, self, self.callback_arg)
             if not self.add_footer:
                 pass
             elif not ret:
@@ -142,7 +143,7 @@ class ShellPane(edlib.Pane):
                     p = self.cb_pane
                     self.cb_pane = None
                     self.cb_lines = 0
-                    if self.callback("cb:lines", p, self) > 1:
+                    if self.callback("cb:lines", p, self, self.callback_arg) > 1:
                         # it still wants EOF
                         self.cb_pane = p
             self.call("doc:replace", l[:i+1].decode("utf-8", 'ignore'))
@@ -183,14 +184,16 @@ class ShellPane(edlib.Pane):
             self.call("doc:replace", "\nProcess signalled\n")
         return 1
 
-    def handle_callback(self, key, focus, num, num2, comm2, **a):
+    def handle_callback(self, key, focus, num, num2, str1, comm2, **a):
         "handle:shellcmd:set-callback"
         # comm2 is recorded as a callback to call on focus after
         # num msecs or num2 lines of output.  Callback is called
         # when command finishes if not before
+        # str1 saved and included in the callback
         if not focus or not comm2:
             return edlib.Einval
         self.callback = comm2
+        self.callback_arg = str1
         self.cb_pane = focus
         self.add_notify(focus, "Notify:Close")
         self.cb_lines = num2
@@ -202,7 +205,7 @@ class ShellPane(edlib.Pane):
         if self.cb_pane:
             p = self.cb_pane
             self.cb_pane = None
-            if self.callback("cb:timer", p, self) > 1:
+            if self.callback("cb:timer", p, self, self.callback_arg) > 1:
                 # still want moer
                 self.cb_pane = p
         return edlib.Efalse