]> git.neil.brown.name Git - edlib.git/commitdiff
Move running of xdg-open to the Display
authorNeilBrown <neil@brown.name>
Fri, 23 Apr 2021 08:02:50 +0000 (18:02 +1000)
committerNeilBrown <neil@brown.name>
Thu, 6 May 2021 11:22:31 +0000 (21:22 +1000)
Displays now handle Display:external-viewer which will run
xdg-open if that is likely to work.  i.e. if DISPLAY exists.
If not, ncurses will drop out of curses mode and display the
xdg-open command so that it can be clicked or copy-pasted
somewhere.

Signed-off-by: NeilBrown <neil@brown.name>
DOC/TODO.md
display-ncurses.c
python/display-pygtk.py
python/module-notmuch.py

index 51f820936c6078f5a3d82f2efca9a5258b8c6a19..516a338ee55be6345136c76c1a9db4767ca202c8 100644 (file)
@@ -5,7 +5,7 @@ Current priorities
 ------------------
 
 - [X] spell-checker refinements
-- [ ] provide a way for ncurses to switch out of display mode
+- [X] provide a way for ncurses to switch out of display mode
       and to show a URL (or similar) which can be copied from terminal
 - [ ] fix bugs
 - [ ] make notmuch usable
@@ -295,6 +295,7 @@ Module features
 
 ### ncurses
 
+- [ ] external-viewer for different host could output file in base64 for copy/paste??
 - [ ] add full list of colour names (to lib-colourmap)
 - [ ] allow a pane to require 'true-colour' and discover number of colours available
       Colour map gets changed when it becomes the focus.
@@ -604,10 +605,10 @@ Module features
 - [ ] save function - doc:save-file given file name or fd
 - [ ] wiggle-highlight patches found in email
 - [X] brief summary of part type in button line
-- [ ] open function
-- [ ] make URLs clickable
+- [X] open function
+- [X] make URLs clickable
 - [ ] detect and hide cited text
-- [ ] detect and highlight links
+- [X] detect and highlight links
 - [ ] Make long to/cc headers truncate unless selected.
 - [X] select parts from multipart
 - [X] buttons for non-displayable
index 0e2e5360c27ab5a58391444350dcbf17e2502e0b..1921a0fb11cd7733c1ab10bd2f4228f9e776431d 100644 (file)
@@ -58,7 +58,7 @@ struct display_data {
        int                     report_position;
        long                    last_event;
 
-       char                    *rs1, *rs2, *rs3;
+       char                    *rs1, *rs2, *rs3, *clear;
        char                    attr_buf[1024];
        #ifdef RECORD_REPLAY
        FILE                    *log;
@@ -444,6 +444,62 @@ static int nc_putc(int ch)
        return 1;
 }
 
+DEF_CMD(nc_external_viewer)
+{
+       struct pane *p = ci->home;
+       struct display_data *dd = p->data;
+       char *disp = pane_attr_get(p, "DISPLAY");
+       int pid;
+       char buf[100];
+       int n;
+
+       if (!ci->str)
+               return Enoarg;
+       if (disp && *disp) {
+               switch (pid = fork()) {
+               case -1:
+                       return Efail;
+               case 0: /* Child */
+                       setenv("DISPLAY", disp, 1);
+                       /* FIXME reopen stderr etc */
+                       execlp("xdg-open", "xdg-open", ci->str, NULL);
+                       exit(1);
+               default: /* parent */
+                       /* FIXME record pid?? */
+                       break;
+               }
+               return 1;
+       }
+       /* handle no-display case */
+       set_screen(p);
+       n = 0;
+       ioctl(fileno(dd->scr_file), FIONREAD, &n);
+       if (n)
+               n -= read(fileno(dd->scr_file), buf,
+                         n <= (int)sizeof(buf) ? n : (int)sizeof(buf));
+       endwin();
+
+       /* Endwin doesn't seem to reset properly, at least on xfce-terminal.
+        * So do it manually
+        */
+       if (dd->rs1)
+               tputs(dd->rs1, 1, nc_putc);
+       if (dd->rs2)
+               tputs(dd->rs2, 1, nc_putc);
+       if (dd->rs3)
+               tputs(dd->rs3, 1, nc_putc);
+       if (dd->clear)
+               tputs(dd->clear, 1, nc_putc);
+       fflush(dd->scr_file);
+
+       fprintf(dd->scr_file, "# Consider copy-pasting following\n");
+       fprintf(dd->scr_file, "xdg-open %s\n", ci->str);
+       fprintf(dd->scr_file, "# Press Enter to continue\n");
+       n = read(fileno(dd->scr_file), buf, sizeof(buf));
+       doupdate();
+       return 1;
+}
+
 static void ncurses_end(struct pane *p safe)
 {
        struct display_data *dd = p->data;
@@ -957,6 +1013,7 @@ static struct pane *ncurses_init(struct pane *ed,
        dd->rs3 = tgetstr("rs3", &area);
        if (!dd->rs3)
                dd->rs3 = tgetstr("is3", &area);
+       dd->clear = tgetstr("clear", &area);
 
        call("editor:request:all-displays", p);
        if (!prepare_recrep(p)) {
@@ -1282,6 +1339,7 @@ void edlib_init(struct pane *ed safe)
        key_add(nc_map, "Display:refresh", &force_redraw);
        key_add(nc_map, "Display:close", &nc_close_display);
        key_add(nc_map, "Display:set-noclose", &nc_set_noclose);
+       key_add(nc_map, "Display:external-viewer", &nc_external_viewer);
        key_add(nc_map, "Close", &nc_close);
        key_add(nc_map, "Free", &edlib_do_free);
        key_add(nc_map, "pane-clear", &nc_clear);
index 08d20bfb49b4d065c033f8eea69d538215358fdf..2762241bc006e3eb0b56dcf35a1a194f1f1c801e 100644 (file)
@@ -73,13 +73,25 @@ class EdDisplay(edlib.Pane):
             self.win.unfullscreen()
         return 1
 
-    def handle_new(self, key, home, **a):
+    def handle_new(self, key, **a):
         "handle:Display:new"
         global editor
         p = editor.call("attach-input", ret='focus')
         p['DISPLAY'] = self['DISPLAY']
         newdisp = EdDisplay(p)
-        home.clone_children(newdisp)
+        self.clone_children(newdisp)
+        return 1
+
+    def handle_external(self, key, str, **a):
+        "handle:Display:external-viewer"
+        disp = self['DISPLAY']
+        if not str or not disp:
+            return edlib.Enoarg
+        env = os.environ.copy()
+        env['DISPLAY'] = disp
+
+        subprocess.Popen(["xdg-open", str], env=env,
+                         stderr = subprocess.DEVNULL)
         return 1
 
     def handle_close(self, key, **a):
index 2641a8dcf688fcf8df5454717c9e5b42c9005875..2f86e867b8baaedc7e4891a9b31207d15d9630de 100644 (file)
@@ -2423,7 +2423,7 @@ class notmuch_message_view(edlib.Pane):
         fd, path = tempfile.mkstemp(suffix, prefix)
         os.write(fd, content)
         os.close(fd)
-        subprocess.Popen(["xdg-open", path], stderr = DEVNULL)
+        focus.call("Display:external-viewer", path)
         return 1
 
     def handle_map_attr(self, key, focus, mark, str, str2, comm2, **a):
@@ -2461,7 +2461,7 @@ class notmuch_message_view(edlib.Pane):
 
         url = focus.call("doc:get-attr", m, "url", ret='str')
         focus.call("Message", "Opening url <%s>" % url)
-        subprocess.Popen(["xdg-open", url], stderr = DEVNULL)
+        focus.call("Display:external-viewer", url)
         return 1
 
 def notmuch_doc(key, home, focus, comm2, **a):