Commit Diff


commit - b9a64d45f6bf202e384c314e9e8b2b303e5d4f49
commit + 4e32d3a6c187dd9646ba4aa80a69082adf3b3c46
blob - f137ba2586ebfbe7c474fbb7bb5b47c357206b4e
blob + 57d01ea586adb3381066c9342720bcb3642f4165
--- cmd.c
+++ cmd.c
@@ -287,43 +287,6 @@ void
 cmd_kill_telescope(struct buffer *buffer)
 {
 	yornp("really quit?", kill_telescope_cb, NULL);
-}
-
-#include <curses.h>
-#include <unistd.h>
-#include <sys/wait.h>
-#include <errno.h>
-static void
-do_exec_command(const char *cmd, struct tab *t)
-{
-	int s;
-	pid_t p;
-
-	if (cmd == NULL)
-		return;
-
-	endwin();
-
-	switch (p = fork()) {
-	case -1:
-		message("failed to fork: %s", strerror(errno));
-		return;
-	case 0:
-		execl("/bin/sh", "sh", "-c", cmd, NULL);
-		warn("exec \"%s\" failed", cmd);
-		_exit(1);
-	}
-
-again:
-	if (waitpid(p, &s, 0) == -1) {
-		if (errno == EINTR)
-			goto again;
-	}
-
-	refresh();
-	clear();
-	ui_schedule_redraw();
-	/* rearrange_windows(); */
 }
 
 void
@@ -353,13 +316,6 @@ cmd_push_button(struct buffer *buffer)
 			else
 				buffer->line_max++;
 		}
-		break;
-	case LINE_DOWNLOAD:
-	case LINE_DOWNLOAD_DONE:
-		minibuffer_read("Execute: ", do_exec_command,
-		    NULL);
-		snprintf(ministate.buf, sizeof(ministate.buf),
-		    "xdg-open %s", vl->parent->alt);
 		break;
 	default:
 		break;
blob - a38bc8415b1dc64af1c6a14e701604bae142a54e
blob + ab7dfac0e780c559474ab835780372a9a766a5fe
--- defaults.c
+++ defaults.c
@@ -31,6 +31,7 @@
 
 char	*default_protocol = NULL;
 char	*download_path = NULL;
+char 	*external_cmd = NULL;
 char	*new_tab_url = NULL;
 char	*default_search_engine = NULL;
 
@@ -640,6 +641,17 @@ config_setvars(const char *var, char *val)
 		free(download_path);
 		if (asprintf(&download_path, "%s%s%s", prfx, v, sufx) == -1) {
 			download_path = NULL;
+			return 0;
+		}
+
+		free(val);
+		return 1;
+	}
+
+	if (!strcmp(var, "external-cmd")) {
+		free(external_cmd);
+		if (asprintf(&external_cmd, "%s", val) == -1) {
+			external_cmd = NULL;
 			return 0;
 		}
 
blob - b860d8acb7d1d179cdbbb5ca9afaee909897795b
blob + 7e92fa6f65721da39557a0eb7ff0d2a60ddf7659
--- defaults.h
+++ defaults.h
@@ -20,6 +20,7 @@
 extern char	*default_protocol;
 extern char	*default_search_engine;
 extern char	*download_path;
+extern char	*external_cmd;
 extern char	*new_tab_url;
 
 extern int	 autosave;
blob - dc784197db4eb51e31bdc315d3c7535d9233e4bf
blob + e09140d922a771d979ee481e4eb31352c4c44407
--- downloads.c
+++ downloads.c
@@ -18,6 +18,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "telescope.h"
 #include "ui.h"
@@ -108,3 +109,16 @@ download_by_id(uint32_t id)
 
 	return NULL;
 }
+
+void
+download_finished(struct download *d)
+{
+	if (d == NULL)
+		return;
+
+	close(d->fd);
+	d->fd = -1;
+
+	ui_on_download_refresh();
+	ui_prompt_download_cmd(d->path);
+}
blob - dd3d8b9e6504a40177f2f4496cf52b0c61532078
blob + 8be25419f42f2e68c711fad7150e00c61acc1ff8
--- telescope.c
+++ telescope.c
@@ -532,7 +532,12 @@ handle_dispatch_imsg(int fd, int event, void *data)
 		case IMSG_EOF:
 			if ((tab = tab_by_id(imsg_get_id(&imsg))) == NULL &&
 			    ((d = download_by_id(imsg_get_id(&imsg)))) == NULL)
+				return;
+
+			if (tab == NULL && d != NULL) {
+				download_finished(d);
 				return;
+			}
 
 			if (tab != NULL) {
 				if (!parser_free(tab))
@@ -553,10 +558,6 @@ handle_dispatch_imsg(int fd, int event, void *data)
 
 				ui_on_tab_refresh(tab);
 				ui_on_tab_loaded(tab);
-			} else {
-				close(d->fd);
-				d->fd = -1;
-				ui_on_download_refresh();
 			}
 			break;
 		default:
@@ -1145,6 +1146,10 @@ main(int argc, char * const *argv)
 
 	if (download_path == NULL &&
 	    (download_path = strdup("/tmp/")) == NULL)
+		errx(1, "strdup");
+
+	if (external_cmd == NULL &&
+	    (external_cmd = strdup("xdg-open")) == NULL)
 		errx(1, "strdup");
 
 	if (argc != 0) {
blob - a099c7f70b13aef4d6ea62cf11276bf5f31af07d
blob + 92616f9dee3cedae427c719c0139cf370e7c09f0
--- telescope.h
+++ telescope.h
@@ -222,6 +222,7 @@ struct download {
 void		 recompute_downloads(void);
 struct download	*enqueue_download(uint32_t, const char *);
 struct download	*download_by_id(uint32_t);
+void 	 	 download_finished(struct download *);
 
 /* help.c */
 void		 recompute_help(void);
blob - 48370bf48558b0666a827c6e7a7a0fda37ce158e
blob + 544bdc943f403061887766c3145a424ba3a818d2
--- ui.c
+++ ui.c
@@ -33,9 +33,11 @@
 #include "compat.h"
 
 #include <sys/time.h>
+#include <sys/wait.h>
 
 #include <assert.h>
 #include <curses.h>
+#include <errno.h>
 #include <locale.h>
 #include <signal.h>
 #include <stdarg.h>
@@ -80,6 +82,7 @@ static void		 place_cursor(int);
 static void		 redraw_tab(struct tab*);
 static void		 update_loading_anim(int, int, void*);
 static void		 stop_loading_anim(struct tab*);
+static void 		 exec_external_cmd(const char *, struct tab *);
 
 static int		 should_rearrange_windows;
 static int		 show_tab_bar;
@@ -1236,6 +1239,16 @@ ui_on_download_refresh(void)
 }
 
 void
+ui_prompt_download_cmd(char *path)
+{
+	char cmd[8192];
+
+	snprintf(cmd, sizeof(cmd), "%s %s", external_cmd, path);
+
+	ui_read("Execute", exec_external_cmd, current_tab, cmd);
+}
+
+void
 ui_remotely_open_link(const char *uri)
 {
 	new_tab(uri, NULL, NULL);
@@ -1360,5 +1373,38 @@ ui_suspend(void)
 void
 ui_end(void)
 {
+	endwin();
+}
+
+static void
+exec_external_cmd(const char *cmd, struct tab *tab)
+{
+	int s;
+	pid_t p;
+
+	if (cmd == NULL)
+		return;
+
 	endwin();
+
+	switch (p = fork()) {
+	case -1:
+		message("failed to fork: %s", strerror(errno));
+		return;
+	case 0:
+		execl("/bin/sh", "sh", "-c", cmd, NULL);
+		warn("exec \"%s\" failed", cmd);
+		_exit(1);
+	}
+
+again:
+	if (waitpid(p, &s, 0) == -1) {
+		if (errno == EINTR)
+			goto again;
+	}
+
+	refresh();
+	clear();
+	ui_schedule_redraw();
 }
+
blob - 417738236a3ca7b6c5a51481129087f66e2ae84e
blob + 912098a047c9ce38fd2047bfc3de08577b33b6f3
--- ui.h
+++ ui.h
@@ -145,6 +145,7 @@ void		 ui_main_loop(void);
 void		 ui_on_tab_loaded(struct tab *);
 void		 ui_on_tab_refresh(struct tab *);
 void		 ui_on_download_refresh(void);
+void 		 ui_prompt_download_cmd(char *);
 void		 ui_remotely_open_link(const char *);
 const char	*ui_keyname(int);
 void		 ui_toggle_side_window(int);