Commit Diff


commit - ab2d4a19eba9dc6b597634138184c250f1136b41
commit + fbadd3951ada7cc08104a4993d81431e0a0b4190
blob - 728c4662141cb8c65e3e191d6145497614cba594
blob + 68a620ecd1342af448f5de1bd4c047cf7a230eef
--- cmd.c
+++ cmd.c
@@ -237,7 +237,7 @@ cmd_push_button(struct buffer *buffer)
 	vl = buffer->current_line;
 	switch (vl->parent->type) {
 	case LINE_LINK:
-		load_url_in_tab(current_tab(), vl->parent->meta.alt);
+		load_url_in_tab(current_tab(), vl->parent->alt);
 		break;
 	case LINE_PRE_START:
 		l = TAILQ_NEXT(vl->parent, lines);
@@ -265,7 +265,7 @@ cmd_push_button_new_tab(struct buffer *buffer)
 	if (vl->parent->type != LINE_LINK)
 		return;
 
-	new_tab(vl->parent->meta.alt);
+	new_tab(vl->parent->alt);
 }
 
 void
blob - f513428dfdf1d983bf63609a8d00d9a32eac1d56
blob + 9aec531693db39d92f58303de9247f0ed2559991
--- defaults.c
+++ defaults.c
@@ -32,6 +32,7 @@ int hide_pre_context = 0;
 int hide_pre_blocks = 0;
 int hide_pre_closing_line = 0;
 int dont_wrap_pre = 0;
+int emojify_link = 1;
 
 struct lineprefix line_prefixes[] = {
 	[LINE_TEXT] =		{ "",		"" },
@@ -415,6 +416,8 @@ config_setvari(const char *var, int val)
 		hide_pre_closing_line = !!val;
 	} else if (!strcmp(var, "dont-wrap-pre")) {
 		dont_wrap_pre = !!val;
+	} else if (!strcmp(var, "emojify-link")) {
+		emojify_link = !!val;
 	} else {
 		return 0;
 	}
blob - d0ace0015bc35e6b0f553b07086557300bd06a42
blob + 1d91b1fe9ee0438328449bad1c2fc216bc653857
--- defaults.h
+++ defaults.h
@@ -25,6 +25,7 @@ extern int	 hide_pre_context;
 extern int	 hide_pre_blocks;
 extern int	 hide_pre_closing_line;
 extern int	 dont_wrap_pre;
+extern int	 emojify_link;
 
 struct lineprefix {
 	const char	*prfx1;
blob - e11b87839a18dcbf89ac1cacc57ee991cab79804
blob + 8b612716edf3923aa419543f2a9568e7f11b8044
--- gemtext.c
+++ gemtext.c
@@ -25,6 +25,7 @@
 #include "defaults.h"
 #include "parser.h"
 #include "telescope.h"
+#include "utf8.h"
 
 #include <ctype.h>
 #include <string.h>
@@ -79,7 +80,7 @@ emit_line(struct parser *p, enum line_type type, char 
 
 	l->type = type;
 	l->line = line;
-	l->meta.alt = alt;
+	l->alt = alt;
 
 	switch (l->type) {
 	case LINE_PRE_START:
@@ -94,8 +95,12 @@ emit_line(struct parser *p, enum line_type type, char 
 		if (hide_pre_blocks)
 			l->flags = L_HIDDEN;
 		break;
+	case LINE_LINK:
+		if (emojify_link &&
+		    !emojied_line(line, (const char **)&l->data))
+			l->data = NULL;
+		break;
 	default:
-		l->flags = 0;
 		break;
 	}
 
blob - 8203bdfacf79e6b373172854a84ea30803f2b611
blob + 939a3605495e7bb2561baf8fa99a9a2609c3a561
--- minibuffer.c
+++ minibuffer.c
@@ -92,7 +92,7 @@ minibuffer_metadata(void)
 	if (vl == NULL || vl->parent->flags & L_HIDDEN)
 		return NULL;
 
-	return vl->parent->meta.data;
+	return vl->parent->data;
 }
 
 static void
@@ -263,7 +263,7 @@ ls_select(void)
 	}
 
 	exit_minibuffer();
-	load_url_in_tab(current_tab(), l->meta.alt);
+	load_url_in_tab(current_tab(), l->alt);
 }
 
 static inline void
@@ -379,7 +379,7 @@ populate_compl_buffer(complfn *fn, void *data)
 			abort();
 
 		l->type = LINE_COMPL;
-		l->meta.data = linedata;
+		l->data = linedata;
 		if ((l->line = strdup(s)) == NULL)
 			abort();
 
blob - 3c9eb0a2a465a7d8e4a3bfb81a62716d3eac38aa
blob + e48bb64b22125b338476d7be7e34cddae2690c24
--- telescope.h
+++ telescope.h
@@ -93,10 +93,8 @@ enum line_type {
 struct line {
 	enum line_type		 type;
 	char			*line;
-	union {
-		char		*alt;
-		void		*data;
-	} meta;
+	char			*alt;
+	void			*data;
 	int			 flags;
 	TAILQ_ENTRY(line)	 lines;
 };
blob - 3d9ae7c7a7c78a09dcc103d0f06b177b4abc5d4c
blob + 076e5d516eb3a05fe5aaa7e0418cf76b42dd9b1d
--- ui.c
+++ ui.c
@@ -148,6 +148,8 @@ restore_curs_x(struct buffer *buffer)
 	vl = buffer->current_line;
 	if (vl == NULL || vl->line == NULL)
 		buffer->curs_x = buffer->cpoff = 0;
+	else if (vl->parent->data != NULL)
+		buffer->curs_x = utf8_snwidth(vl->parent->data+1, buffer->cpoff) + 1;
 	else
 		buffer->curs_x = utf8_snwidth(vl->line, buffer->cpoff);
 
@@ -467,20 +469,35 @@ wrap_page(struct buffer *buffer, int width)
 	return 1;
 }
 
+/*
+ * Core part of the rendering.  It prints a vline starting from the
+ * current cursor position.  Printing a vline consists of skipping
+ * `off' columns (for olivetti-mode), print the correct prefix (which
+ * may be the emoji in case of emojified links-lines), printing the
+ * text itself, filling until width - off and filling off columns
+ * again.
+ */
 static void
 print_vline(int off, int width, WINDOW *window, struct vline *vl)
 {
-	const char *text;
-	const char *prfx;
+	/*
+	 * Believe me or not, I've seen emoji ten code points long!
+	 * That means, to stay large, 4*10 bytes + NUL.
+	 */
+	char emojibuf[41] = {0};
+	char *space, *t;
+	const char *text, *prfx;
 	struct line_face *f;
-	int i, left, x, y;
+	int i, left, x, y, emojified, cont;
+	long len = sizeof(emojibuf);
 
 	f = &line_faces[vl->parent->type];
 
 	/* unused, set by getyx */
 	(void)y;
 
-	if (!vl->flags)
+	cont = vl->flags & L_CONTINUATION;
+	if (!cont)
 		prfx = line_prefixes[vl->parent->type].prfx1;
 	else
 		prfx = line_prefixes[vl->parent->type].prfx2;
@@ -495,11 +512,30 @@ print_vline(int off, int width, WINDOW *window, struct
 	wattr_off(window, body_face.left, NULL);
 
 	wattr_on(window, f->prefix, NULL);
-	wprintw(window, "%s", prfx);
+	emojified = 0;
+	space = vl->parent->data;
+	if (vl->parent->type == LINE_LINK && space != NULL) {
+		emojified = 1;
+		if (cont) {
+			len = utf8_swidth_between(vl->parent->line, space) + 1;
+			for (i = 0; i < len; ++i)
+				wprintw(window, " ");
+		} else {
+			strlcpy(emojibuf, text, sizeof(emojibuf));
+			if ((t = strchr(emojibuf, ' ')) != NULL)
+				*t = '\0';
+			wprintw(window, "%s ", emojibuf);
+		}
+	} else {
+		wprintw(window, "%s", prfx);
+	}
 	wattr_off(window, f->prefix, NULL);
 
 	wattr_on(window, f->text, NULL);
-	wprintw(window, "%s", text);
+	if (emojified && !cont)
+		wprintw(window, "%s", text + (space - vl->parent->line) + 1);
+	else
+		wprintw(window, "%s", text);
 	wattr_off(window, f->text, NULL);
 
 	getyx(window, y, x);
@@ -827,7 +863,7 @@ do_redraw_echoarea(void)
 		if (tab->buffer.current_line != NULL &&
 		    tab->buffer.current_line->parent->type == LINE_LINK)
 			waddstr(echoarea,
-			    tab->buffer.current_line->parent->meta.alt);
+			    tab->buffer.current_line->parent->alt);
 	}
 }
 
@@ -945,7 +981,7 @@ emit_help_item(char *prfx, void *fn)
 		abort();
 
 	l->type = LINE_TEXT;
-	l->meta.alt = NULL;
+	l->alt = NULL;
 
 	asprintf(&l->line, "%s %s", prfx, cmd->cmd);
 
blob - 6f721e1cf457c9cca3fa254d23f6b3d885d30887
blob + 70975cbd212b49ba2cc9867408a524662782caa8
--- wrap.c
+++ wrap.c
@@ -52,11 +52,7 @@ empty_linelist(struct buffer *buffer)
 	TAILQ_FOREACH_SAFE(l, &buffer->page.head, lines, lt) {
 		TAILQ_REMOVE(&buffer->page.head, l, lines);
 		free(l->line);
-
-		if (l->type != LINE_COMPL &&
-		    l->type != LINE_COMPL_CURRENT)
-			free(l->meta.alt);
-
+		free(l->alt);
 		free(l);
 	}
 }