Recently Written · git

sacc

Mirror of git://bitreich.org/sacc, the sacc gopher client from bitreich.org.

git clone https://github.com/equwal/sacc

Log | Files | Refs


commit c2e060c906af4fd970cb2b9ee2e3c05c83db1582
Quentin Rameau <quinq@fifth.space>
2021-11-13 12:34:01 +0100

Add yank feature to sacc

Thanks to adc (Anders Damsgaard <anders@adamsgaard.dk>) and
Evil_Bob (Hiltjo Posthuma <hiltjo@codemadness.org>) for
their suggestions, patches, and peer pressure.

 LICENSE      |  1 +
 common.h     |  1 +
 config.def.h |  5 +++++
 sacc.1       |  6 ++++++
 sacc.c       | 23 +++++++++++++++++++++++
 ui_ti.c      | 10 ++++++++++
 ui_txt.c     |  8 ++++++++
 7 files changed, 54 insertions(+)
diff --git a/LICENSE b/LICENSE
index da0c220..6bf2c2e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -8,6 +8,7 @@ Copyright (c) 2018 Ivan J. <parazyd@dyne.org>
 Copyright (c) 2018 Leonardo Taccari <iamleot@gmail.com>
 Copyright (c) 2018 Stefan Hagen <sh+git@codevoid.de>
 Copyright (c) 2021 escapeinsert <ben@0x1bi.net>
+Copyright (c) 2021 Anders Damsgaard <anders@adamsgaard.dk>
 
 Permission to use, copy, modify, and distribute this software for any
 purpose with or without fee is hereby granted, provided that the above
diff --git a/common.h b/common.h
index eeeca27..622067f 100644
--- a/common.h
+++ b/common.h
@@ -53,6 +53,7 @@ extern char *strcasestr(const char *, const char *);
 #endif /* NEED_STRCASESTR */
 extern const char *typedisplay(char);
 extern int itemuri(Item *, char *, size_t);
+extern void yankitem(Item *);
 extern void uicleanup(void);
 extern void uidisplay(Item *);
 extern char *uiprompt(char *, ...);
diff --git a/config.def.h b/config.def.h
index dbc4f2f..e96a877 100644
--- a/config.def.h
+++ b/config.def.h
@@ -13,6 +13,8 @@
 #define _key_pgprev	'h' /* view previous item */
 #define _key_cururi	'U' /* print page uri */
 #define _key_seluri	'u' /* print item uri */
+#define _key_yankcur	'Y' /* yank page uri */
+#define _key_yanksel	'y' /* yank item uri */
 #define _key_fetch	'L' /* refetch current item */
 #define _key_help	'?' /* display help */
 #define _key_quit	'q' /* exit sacc */
@@ -22,6 +24,9 @@
 
 #ifdef NEED_CONF
 
+/* default yanker */
+static char *yanker = "xclip";
+
 /* default plumber */
 static char *plumber = "xdg-open";
 
diff --git a/sacc.1 b/sacc.1
index b2c6739..40401b3 100644
--- a/sacc.1
+++ b/sacc.1
@@ -65,6 +65,12 @@ Print the URI of the current page.
 .B u
 Print the URI of the highlighted item.
 .TP
+.B Y
+Yank the current page URI to an external program.
+.TP
+.B y
+Yank the highlighted item URI to an external program.
+.TP
 .B ?
 Show the help message of shortcuts.
 .TP
diff --git a/sacc.c b/sacc.c
index 1525573..6af6ac2 100644
--- a/sacc.c
+++ b/sacc.c
@@ -28,6 +28,7 @@ void (*diag)(char *, ...);
 
 static const char *ident = "@(#) sacc(omys): " VERSION;
 
+static char intbuf[256]; /* 256B ought to be enough for any URI */
 static char *mainurl;
 static Item *mainentry;
 static int devnullfd;
@@ -678,6 +679,21 @@ fetchitem(Item *item)
 	return ((item->raw = raw) != NULL);
 }
 
+static void
+pipeuri(char *cmd, char *msg, char *uri)
+{
+	FILE *sel;
+
+	if ((sel = popen(cmd, "w")) == NULL) {
+		diag("URI not %s\n", msg);
+		return;
+	}
+
+	fputs(uri, sel);
+	pclose(sel);
+	diag("%s \"%s\"", msg, uri);
+}
+
 static void
 execuri(char *cmd, char *msg, char *uri)
 {
@@ -757,6 +773,13 @@ cleanup:
 	return;
 }
 
+void
+yankitem(Item *item)
+{
+	itemuri(item, intbuf, sizeof(intbuf));
+	pipeuri(yanker, "Yanked", intbuf);
+}
+
 static int
 dig(Item *entry, Item *item)
 {
diff --git a/ui_ti.c b/ui_ti.c
index a71571d..4bfd6f5 100644
--- a/ui_ti.c
+++ b/ui_ti.c
@@ -138,6 +138,8 @@ help(Item *entry)
 		       S(_key_searchprev) ": search string backward.\n"
 		       S(_key_cururi) ": print page URI.\n"
 		       S(_key_seluri) ": print item URI.\n"
+		       S(_key_yankcur) ": yank page URI to external program.\n"
+		       S(_key_yanksel) ": yank item URI to external program.\n"
 		       S(_key_help) ": show this help.\n"
 		       "^D, " S(_key_quit) ": exit sacc.\n"
 	};
@@ -533,6 +535,14 @@ uiselectitem(Item *entry)
 			if (dir)
 				displayuri(&dir->items[dir->curline]);
 			continue;
+		case _key_yankcur:
+			if (dir)
+				yankitem(entry);
+			continue;
+		case _key_yanksel:
+			if (dir)
+				yankitem(&dir->items[dir->curline]);
+			continue;
 		case _key_help: /* FALLTHROUGH */
 			return help(entry);
 		default:
diff --git a/ui_txt.c b/ui_txt.c
index 0e01f2b..80b2e4c 100644
--- a/ui_txt.c
+++ b/ui_txt.c
@@ -55,6 +55,8 @@ help(void)
 	     "p: show previous page.\n"
 	     "t: go to the top of the page\n"
 	     "b: go to the bottom of the page\n"
+	     "Y: yank page URI.\n"
+	     "y#: yank item number # URI.\n"
 	     "/str: search for string \"str\"\n"
 	     "!: refetch failed item.\n"
 	     "^D, q: quit.\n"
@@ -271,6 +273,12 @@ uiselectitem(Item *entry)
 			if (item > 0 && item <= nitems)
 				printuri(&dir->items[item-1], item);
 			continue;
+		case 'Y':
+			yankitem(entry);
+			continue;
+		case 'y':
+			if (item > 0 && item <= nitems)
+				yankitem(&dir->items[item-1]);
 		case '/':
 			if (*sstr)
 				searchinline(sstr, entry);