Commit Diff


commit - d54dd8160b88709f3d243e1410a781e5de7fc187
commit + 868b3a8f52ea2f90a1965661798d977d307e3b38
blob - 50e9680b2b04b69c68ec24ec802de40ee532834a
blob + b208291f42a1cd30436808fbdff5f93802ce7063
--- cmd.c
+++ cmd.c
@@ -1008,3 +1008,34 @@ cmd_reply_last_input(struct buffer *buffer)
 	message("%s", current_tab->last_input_url);
 	ui_require_input(current_tab, 0, ir_select_reply);
 }
+
+void
+cmd_write_buffer(struct buffer *buffer)
+{
+	const char *f, *url;
+	char path[PATH_MAX];
+
+	GUARD_RECURSIVE_MINIBUFFER();
+
+	if (safe_mode) {
+		message("Can't write buffer in safe-mode.");
+		return;
+	}
+
+	url = current_tab->hist_cur->h;
+
+	if ((f = strrchr(url, '/')) != NULL)
+		f++;
+	if (f == NULL || *f == '\0') {
+		/* guess a decent file name based on the protocol used */
+		if (!strncmp(url, "gemini://", 9))
+			f = "index.gmi";
+		else
+			f = "index.txt";
+	}
+
+	strlcpy(path, download_path, sizeof(path));
+	strlcat(path, f, sizeof(path));
+
+	ui_read("Write file", write_buffer, current_tab, path);
+}
blob - c245256af26ce8c175b5be142923192db179fa0f
blob + a8bb49116b2901be99e92fbcce1554a3d848d710
--- downloads.c
+++ downloads.c
@@ -80,7 +80,7 @@ end:
 }
 
 void
-enqueue_download(uint32_t id, const char *path)
+enqueue_download(uint32_t id, const char *path, int buffer)
 {
 	struct download *d;
 
@@ -90,10 +90,17 @@ enqueue_download(uint32_t id, const char *path)
 	d->id = id;
 	d->fd = -1;
 	d->path = strdup(path);
+	d->buffer = buffer;
 
-	STAILQ_INSERT_TAIL(&downloads, d, entries);
+	STAILQ_INSERT_HEAD(&downloads, d, entries);
 }
 
+void
+dequeue_first_download(void)
+{
+	STAILQ_REMOVE_HEAD(&downloads, entries);
+}
+
 struct download *
 download_by_id(uint32_t id)
 {
blob - a4fd3fbd593dc70791e26dc9239884f3769cacbd
blob + 487a84ca1a77f81087fd8534d19f5827a93ceee8
--- include/cmd.h
+++ include/cmd.h
@@ -77,3 +77,4 @@ CMD(cmd_toc,			"Jump to a heading using the minibuffer
 CMD(cmd_toggle_downloads,	"Toggle the downloads side window.");
 CMD(cmd_toggle_help,		"Toggle side window with help.");
 CMD(cmd_toggle_pre_wrap,	"Toggle the wrapping of preformatted blocks.");
+CMD(cmd_write_buffer,		"Save the current buffer to the disk.");
blob - a8675f3269afa1e8fa7a1e9cacee89e03d32d3be
blob + 899095748a8c6c35c1cae68b7e59082e7640ab9a
--- include/telescope.h
+++ include/telescope.h
@@ -302,11 +302,13 @@ struct download {
 	int			 fd;
 	size_t			 bytes;
 	char			*path;
+	int			 buffer;
 	STAILQ_ENTRY(download)	 entries;
 };
 
 void		 recompute_downloads(void);
-void		 enqueue_download(uint32_t, const char *);
+void		 enqueue_download(uint32_t, const char *, int);
+void		 dequeue_first_download(void);
 struct download	*download_by_id(uint32_t);
 
 /* help.c */
@@ -348,6 +350,7 @@ void		 load_url_in_tab(struct tab *, const char *, con
 int		 load_previous_page(struct tab*);
 int		 load_next_page(struct tab*);
 void		 add_to_bookmarks(const char*);
+void		 write_buffer(const char *, struct tab *);
 void		 humanify_url(const char *, char *, size_t);
 int		 ui_send_net(int, uint32_t, const void *, uint16_t);
 int		 ui_send_fs(int, uint32_t, const void *, uint16_t);
blob - 06cfcc999fdf902c64b2202a599a30d781459224
blob + e73a1f84635f5fd473bf049eab77975295efdacb
--- telescope.c
+++ telescope.c
@@ -478,7 +478,7 @@ handle_save_page_path(const char *path, struct tab *ta
 
 	ui_show_downloads_pane();
 
-	enqueue_download(tab->id, path);
+	enqueue_download(tab->id, path, 0);
 	ui_send_fs(IMSG_FILE_OPEN, tab->id, path, strlen(path)+1);
 
 	/*
@@ -506,7 +506,20 @@ handle_imsg_file_opened(struct imsg *imsg, size_t data
 		if (e[datalen-1] != '\0')
 			die();
 		message("Can't open file %s: %s", d->path, e);
-	} else {
+	} else if (d->buffer) {
+		FILE *fp;
+		int r;
+
+		if ((fp = fdopen(imsg->fd, "w")) != NULL) {
+			r = parser_serialize(current_tab, (printfn)fprintf,
+			    fp);
+			if (!r)
+				message("Failed to save the page.");
+			fclose(fp);
+		}
+
+		dequeue_first_download();
+	}else {
 		d->fd = imsg->fd;
 		ui_send_net(IMSG_PROCEED, d->id, NULL, 0);
 	}
@@ -1100,6 +1113,16 @@ add_to_bookmarks(const char *str)
 	    str, strlen(str)+1);
 }
 
+void
+write_buffer(const char *path, struct tab *tab)
+{
+	if (path == NULL)
+		return;
+
+	enqueue_download(tab->id, path, 1);
+	ui_send_fs(IMSG_FILE_OPEN, tab->id, path, strlen(path)+1);
+}
+
 /*
  * Given a user-entered URL, apply some heuristics to use it:
  *