Commit Diff


commit - 8b0779d1065d86c8441a30bed52e05fec2709d1b
commit + 3b5f459ef42c1d975ca5f15ed6402b5658f779f4
blob - 7d47cc85d1786ec85df13c0474d1650b9f8eeaf1
blob + a64352e4f8f4970ab9d19185414dd8e85d6d7194
--- Makefile.am
+++ Makefile.am
@@ -10,6 +10,7 @@ telescope_SOURCES =	cmd.c			\
 			compl.h			\
 			defaults.c		\
 			defaults.h		\
+			downloads.c		\
 			emoji-matcher.c		\
 			fs.c			\
 			gen-emoji-matcher.sh	\
blob - af1433de7080b942fe9b82382dd92b9d9bbf71d9
blob + 4308a59fd694ab21128f3ab9d309afaa7a145492
--- cmd.c
+++ cmd.c
@@ -588,7 +588,7 @@ cmd_list_bookmarks(struct buffer *buffer)
 void
 cmd_toggle_help(struct buffer *buffer)
 {
-	ui_toggle_side_window();
+	ui_toggle_side_window(SIDE_WINDOW_LEFT);
 }
 
 void
@@ -954,4 +954,10 @@ cmd_mini_scroll_down(struct buffer *buffer)
 	buffer->current_line->parent->type = LINE_COMPL;
 	cmd_scroll_down(buffer);
 	buffer->current_line->parent->type = LINE_COMPL_CURRENT;
+}
+
+void
+cmd_toggle_downloads(struct buffer *buffer)
+{
+	ui_toggle_side_window(SIDE_WINDOW_BOTTOM);
 }
blob - 82bf0ee3d076105ab765fec36921a23e3d470c4f
blob + d3e8e03401973d0af7f6105aa76cd809ea4dee79
--- cmd.h
+++ cmd.h
@@ -64,6 +64,7 @@ CMD(cmd_tab_next,		"Focus next tab.");
 CMD(cmd_tab_previous,		"Focus previous tab.");
 CMD(cmd_tab_select,		"Switch to a tab using the minibuffer.");
 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.");
 
blob - bfe716e2534422cfd54bc88659797c8e652bc61f
blob + a0b1ce16d95d70b3bc36ff9a2e5d943fe5aaa938
--- defaults.c
+++ defaults.c
@@ -380,6 +380,7 @@ load_default_keys(void)
 
 	/* global */
 	global_set_key("<f1>",		cmd_toggle_help);
+	global_set_key("<f2>",		cmd_toggle_downloads);
 	global_set_key("C-m",		cmd_push_button);
 	global_set_key("M-enter",	cmd_push_button_new_tab);
 	global_set_key("M-tab",		cmd_previous_button);
blob - /dev/null
blob + 63410a1f03f784a88dde11a6efcbba36c07f66d6 (mode 644)
--- /dev/null
+++ downloads.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "compat.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "telescope.h"
+#include "ui.h"
+
+struct downloads downloads = STAILQ_HEAD_INITIALIZER(downloads);
+
+static void
+no_downloads()
+{
+	struct line	*l;
+
+	if ((l = calloc(1, sizeof(*l))) == NULL)
+		abort();
+
+	l->type = LINE_HELP;
+	l->line = strdup("No downloads");
+
+	TAILQ_INSERT_TAIL(&downloadwin.page.head, l, lines);
+}
+
+void
+recompute_downloads(void)
+{
+	struct download *d;
+	struct line	*l;
+	char		 buf[FMT_SCALED_STRSIZE];
+
+	downloadwin.page.name = "*Downloads*";
+	erase_buffer(&downloadwin);
+
+	if (STAILQ_EMPTY(&downloads)) {
+		no_downloads();
+		return;
+	}
+
+	STAILQ_FOREACH(d, &downloads, entries) {
+		if ((l = calloc(1, sizeof(*l))) == NULL)
+			abort();
+
+		fmt_scaled(d->bytes, buf);
+
+		l->type = LINE_HELP;
+		l->line = strdup(d->path);
+		l->alt = strdup(buf);
+
+		TAILQ_INSERT_TAIL(&downloadwin.page.head, l, lines);
+	}
+}
blob - d43af08f21967eca4a13ecff71102a4ca4893923
blob + c8af1bde86cf787c02f3005817bfb3a87a78a7ee
--- telescope.h
+++ telescope.h
@@ -28,6 +28,9 @@
 
 #define GEMINI_URL_LEN 1024
 
+#define SIDE_WINDOW_LEFT	0x1
+#define SIDE_WINDOW_BOTTOM	0x2
+
 struct imsgev {
 	struct imsgbuf	 ibuf;
 	void		(*handler)(int, short, void *);
@@ -283,7 +286,18 @@ int		 config_setvars(const char *, char *);
 int		 config_setcolor(int, const char *, int, int, int);
 int		 config_setattr(const char *, int, int, int);
 void		 config_apply_style(void);
+
+/* downloads.c */
+extern STAILQ_HEAD(downloads, download) downloads;
+struct download {
+	int			 fd;
+	size_t			 bytes;
+	char			*path;
+	STAILQ_ENTRY(download)	 entries;
+};
 
+void		 recompute_downloads(void);
+
 /* help.c */
 void		 recompute_help(void);
 
blob - 4a4448886f5708b5d114462ae5a673df2c6af942
blob + 7b27a983d7361174f628a5f797108e126415826c
--- ui.c
+++ ui.c
@@ -61,6 +61,7 @@ static void		 line_prefix_and_text(struct vline *, cha
 static void		 print_vline(int, int, WINDOW*, struct vline*);
 static void		 redraw_tabline(void);
 static void		 redraw_window(WINDOW*, int, int, int, struct buffer*);
+static void		 redraw_download(void);
 static void		 redraw_help(void);
 static void		 redraw_body(struct tab*);
 static void		 redraw_modeline(struct tab*);
@@ -93,6 +94,11 @@ static WINDOW		*help;
 struct buffer		 helpwin;
 int			 help_lines, help_cols;
 
+static WINDOW		*download;
+/* not static so we can see them from download.c */
+struct buffer		 downloadwin;
+int			 download_lines;
+
 static int		 side_window;
 static int		 in_side_window;
 
@@ -152,7 +158,9 @@ restore_curs_x(struct buffer *buffer)
 	} else
 		buffer->curs_x = utf8_snwidth(vl->line, buffer->cpoff);
 
-	buffer->curs_x += x_offset;
+	/* small hack: don't olivetti-mode the download pane */
+	if (buffer != &downloadwin)
+		buffer->curs_x += x_offset;
 
 	if (vl == NULL)
 		return;
@@ -177,8 +185,10 @@ current_buffer(void)
 {
 	if (in_minibuffer)
 		return &ministate.buffer;
-	if (in_side_window)
+	if (in_side_window & SIDE_WINDOW_LEFT)
 		return &helpwin;
+	if (in_side_window & SIDE_WINDOW_BOTTOM)
+		return &downloadwin;
 	return &current_tab->buffer;
 }
 
@@ -267,7 +277,7 @@ dispatch_stdio(int fd, short ev, void *d)
 	current_map = base_map;
 
 done:
-	if (side_window)
+	if (side_window & SIDE_WINDOW_LEFT)
 		recompute_help();
 
 	if (should_rearrange_windows)
@@ -310,6 +320,7 @@ static void
 rearrange_windows(void)
 {
 	int		 lines;
+	int		 minibuffer_lines;
 
 	should_rearrange_windows = 0;
 	show_tab_bar = should_show_tab_bar();
@@ -327,9 +338,10 @@ rearrange_windows(void)
 	/* move and resize the windows, in reverse order! */
 
 	if (in_minibuffer == MB_COMPREAD) {
-		mvwin(minibuffer, lines-10, 0);
-		wresize(minibuffer, 10, COLS);
-		lines -= 10;
+		minibuffer_lines = MIN(10, lines/2);
+		mvwin(minibuffer, lines - minibuffer_lines, 0);
+		wresize(minibuffer, minibuffer_lines, COLS);
+		lines -= minibuffer_lines;
 
 		wrap_page(&ministate.compl.buffer, COLS);
 	}
@@ -340,6 +352,15 @@ rearrange_windows(void)
 	mvwin(modeline, --lines, 0);
 	wresize(modeline, 1, COLS);
 
+	if (side_window & SIDE_WINDOW_BOTTOM) {
+		download_lines = MIN(5, lines/2);
+		mvwin(download, lines - download_lines, 0);
+		wresize(download, download_lines, COLS);
+		lines -= download_lines;
+
+		wrap_page(&downloadwin, COLS);
+	}
+
 	body_lines = show_tab_bar ? --lines : lines;
 	body_cols = COLS;
 
@@ -347,7 +368,7 @@ rearrange_windows(void)
 	 * Here we make the assumption that show_tab_bar is either 0
 	 * or 1, and reuse that as argument to mvwin.
 	 */
-	if (side_window) {
+	if (side_window & SIDE_WINDOW_LEFT) {
 		help_cols = 0.3 * COLS;
 		help_lines = lines;
 		mvwin(help, show_tab_bar, 0);
@@ -690,6 +711,12 @@ again:
 	buffer->force_redraw = 0;
 end:
 	wmove(win, buffer->curs_y, buffer->curs_x);
+}
+
+static void
+redraw_download(void)
+{
+	redraw_window(download, 0, download_lines, COLS, &downloadwin);
 }
 
 static void
@@ -871,17 +898,29 @@ place_cursor(int soft)
 		touch = wrefresh;
 
 	if (in_minibuffer) {
-		if (side_window)
+		if (side_window & SIDE_WINDOW_LEFT)
 			touch(help);
+		if (side_window & SIDE_WINDOW_BOTTOM)
+			touch(download);
 		touch(body);
 		touch(echoarea);
-	} else if (in_side_window) {
+	} else if (in_side_window & SIDE_WINDOW_LEFT) {
 		touch(body);
 		touch(echoarea);
+                if (in_side_window & SIDE_WINDOW_BOTTOM)
+			touch(download);
 		touch(help);
-	} else {
-		if (side_window)
+	} else if (in_side_window & SIDE_WINDOW_BOTTOM) {
+		touch(body);
+		touch(echoarea);
+		if (in_side_window & SIDE_WINDOW_LEFT)
 			touch(help);
+		touch(download);
+	} else {
+		if (side_window & SIDE_WINDOW_LEFT)
+			touch(help);
+		if (side_window & SIDE_WINDOW_BOTTOM)
+			touch(download);
 		touch(echoarea);
 		touch(body);
 	}
@@ -893,11 +932,16 @@ redraw_tab(struct tab *tab)
 	if (too_small)
 		return;
 
-	if (side_window) {
+	if (side_window & SIDE_WINDOW_LEFT) {
 		redraw_help();
 		wnoutrefresh(help);
 	}
 
+	if (side_window & SIDE_WINDOW_BOTTOM) {
+		redraw_download();
+		wnoutrefresh(download);
+	}
+
 	if (show_tab_bar)
 		redraw_tabline();
 
@@ -1022,6 +1066,10 @@ ui_init()
 
 	minibuffer_init();
 
+	/* initialize download window */
+	TAILQ_INIT(&downloadwin.head);
+	TAILQ_INIT(&downloadwin.page.head);
+
 	/* initialize help window */
 	TAILQ_INIT(&helpwin.head);
 	TAILQ_INIT(&helpwin.page.head);
@@ -1056,6 +1104,8 @@ ui_init()
 		return 0;
 	if ((minibuffer = newwin(1, 1, 0, 0)) == NULL)
 		return 0;
+	if ((download = newwin(1, 1, 0, 0)) == NULL)
+		return 0;
 	if ((help = newwin(1, 1, 0, 0)) == NULL)
 		return 0;
 
@@ -1123,13 +1173,16 @@ ui_keyname(int k)
 }
 
 void
-ui_toggle_side_window(void)
+ui_toggle_side_window(int kind)
 {
-	side_window = !side_window;
-	if (side_window)
+	if (in_side_window & kind)
+		ui_other_window();
+
+	side_window ^= kind;
+	if (side_window & SIDE_WINDOW_LEFT)
 		recompute_help();
-	else
-		in_side_window = 0;
+	if (side_window & SIDE_WINDOW_BOTTOM)
+		recompute_downloads();
 
 	/*
 	 * ugly hack, but otherwise the window doesn't get updated
@@ -1201,8 +1254,15 @@ ui_read(const char *prompt, void (*fn)(const char*, st
 void
 ui_other_window(void)
 {
-	if (side_window)
-		in_side_window = !in_side_window;
+	if (in_side_window & SIDE_WINDOW_LEFT &&
+	    side_window & SIDE_WINDOW_BOTTOM)
+		in_side_window = SIDE_WINDOW_BOTTOM;
+	else if (in_side_window)
+		in_side_window = 0;
+	else if (!in_side_window && side_window & SIDE_WINDOW_LEFT)
+		in_side_window = SIDE_WINDOW_LEFT;
+	else if (!in_side_window && side_window)
+		in_side_window = SIDE_WINDOW_BOTTOM;
 	else
 		message("No other window to select");
 }
blob - 5b6289bc91bb36beeca2eb44c323fde71555bba1
blob + 145069e54bea933d47bcd2dca0bb2c984bfd151c
--- ui.h
+++ ui.h
@@ -117,6 +117,8 @@ extern struct tab	*current_tab;
 extern struct buffer	 helpwin;
 extern int		 help_lines, help_cols;
 
+extern struct buffer	 downloadwin;
+
 void		 save_excursion(struct excursion *, struct buffer *);
 void		 restore_excursion(struct excursion *, struct buffer *);
 void		 global_key_unbound(void);
@@ -130,7 +132,7 @@ void		 ui_main_loop(void);
 void		 ui_on_tab_loaded(struct tab *);
 void		 ui_on_tab_refresh(struct tab *);
 const char	*ui_keyname(int);
-void		 ui_toggle_side_window(void);
+void		 ui_toggle_side_window(int);
 void		 ui_schedule_redraw(void);
 void		 ui_after_message_hook(void);
 void		 ui_require_input(struct tab *, int, int);