commit 35e6403c69410f8be6880c1d554ded5a3afb1c4d
parent ec58f77b6b7bbabaa9cf67dbe3c26feca24c1aec
Author: bakkeby <bakkeby@gmail.com>
Date: Mon, 16 Sep 2019 10:40:16 +0200
Adding copyurl and disable-fonts patch
Diffstat:
9 files changed, 264 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
@@ -11,7 +11,7 @@ Refer to [https://dwm.suckless.org/](https://st.suckless.org/) for details on th
### Changelog:
-2019-09-16 - Added alpha, anysize and bold-is-not-bright patches
+2019-09-16 - Added alpha, anysize, bold-is-not-bright, clipboard, copyurl and disable-fonts patches
### Patches included:
@@ -23,4 +23,15 @@ Refer to [https://dwm.suckless.org/](https://st.suckless.org/) for details on th
- [bold-is-not-bright](https://st.suckless.org/patches/bold-is-not-bright/)
- by default bold text is rendered with a bold font in the bright variant of the current color
- - this patch makes bold text rendered simply as bold, leaving the color unaffected
-\ No newline at end of file
+ - this patch makes bold text rendered simply as bold, leaving the color unaffected
+
+ - [clipboard](https://st.suckless.org/patches/clipboard/)
+ - by default st only sets PRIMARY on selection
+ - this patch makes st set CLIPBOARD on selection
+
+ - [copyurl](https://st.suckless.org/patches/copyurl/)
+ - this patch allows you to select and copy the last URL displayed with Mod+l
+ - multiple invocations cycle through the available URLs
+
+ - [disable-fonts](https://st.suckless.org/patches/disable_bold_italic_fonts/)
+ - this patch adds the option of disabling bold/italic/roman fonts globally
+\ No newline at end of file
diff --git a/config.def.h b/config.def.h
@@ -195,6 +195,9 @@ static Shortcut shortcuts[] = {
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
#endif // CLIPBOARD_PATCH
{ TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
+ #if COPYURL_PATCH || COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH
+ { MODKEY, XK_l, copyurl, {.i = 0} },
+ #endif // COPYURL_PATCH
};
/*
diff --git a/patch/copyurl.c b/patch/copyurl.c
@@ -0,0 +1,185 @@
+#if COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH
+void
+tsetcolor( int row, int start, int end, uint32_t fg, uint32_t bg )
+{
+ int i = start;
+ for( ; i < end; ++i )
+ {
+ term.line[row][i].fg = fg;
+ term.line[row][i].bg = bg;
+ }
+}
+
+char *
+findlastany(char *str, const char** find, size_t len)
+{
+ char* found = NULL;
+ int i = 0;
+ for(found = str + strlen(str) - 1; found >= str; --found) {
+ for(i = 0; i < len; i++) {
+ if(strncmp(found, find[i], strlen(find[i])) == 0) {
+ return found;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/*
+** Select and copy the previous url on screen (do nothing if there's no url).
+**
+** FIXME: doesn't handle urls that span multiple lines; will need to add support
+** for multiline "getsel()" first
+*/
+void
+copyurl(const Arg *arg) {
+ /* () and [] can appear in urls, but excluding them here will reduce false
+ * positives when figuring out where a given url ends.
+ */
+ static char URLCHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789-._~:/?#@!$&'*+,;=%";
+
+ static const char* URLSTRINGS[] = {"http://", "https://"};
+
+ /* remove highlighting from previous selection if any */
+ if(sel.ob.x >= 0 && sel.oe.x >= 0)
+ tsetcolor(sel.nb.y, sel.ob.x, sel.oe.x + 1, defaultfg, defaultbg);
+
+ int i = 0,
+ row = 0, /* row of current URL */
+ col = 0, /* column of current URL start */
+ startrow = 0, /* row of last occurrence */
+ colend = 0, /* column of last occurrence */
+ passes = 0; /* how many rows have been scanned */
+
+ char *linestr = calloc(sizeof(char), term.col+1); /* assume ascii */
+ char *c = NULL,
+ *match = NULL;
+
+ row = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.y : term.bot;
+ LIMIT(row, term.top, term.bot);
+ startrow = row;
+
+ colend = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.x : term.col;
+ LIMIT(colend, 0, term.col);
+
+ /*
+ ** Scan from (term.bot,term.col) to (0,0) and find
+ ** next occurrance of a URL
+ */
+ while (passes !=term.bot + 2) {
+ /* Read in each column of every row until
+ ** we hit previous occurrence of URL
+ */
+ for (col = 0, i = 0; col < colend; ++col,++i) {
+ /* assume ascii */
+ if (term.line[row][col].u > 127)
+ continue;
+ linestr[i] = term.line[row][col].u;
+ }
+ linestr[term.col] = '\0';
+
+ if ((match = findlastany(linestr, URLSTRINGS,
+ sizeof(URLSTRINGS)/sizeof(URLSTRINGS[0]))))
+ break;
+
+ if (--row < term.top)
+ row = term.bot;
+
+ colend = term.col;
+ passes++;
+ };
+
+ if (match) {
+ /* must happen before trim */
+ selclear();
+ sel.ob.x = strlen(linestr) - strlen(match);
+
+ /* trim the rest of the line from the url match */
+ for (c = match; *c != '\0'; ++c)
+ if (!strchr(URLCHARS, *c)) {
+ *c = '\0';
+ break;
+ }
+
+ /* highlight selection by inverting terminal colors */
+ tsetcolor(row, sel.ob.x, sel.ob.x + strlen( match ), defaultbg, defaultfg);
+
+ /* select and copy */
+ sel.mode = 1;
+ sel.type = SEL_REGULAR;
+ sel.oe.x = sel.ob.x + strlen(match)-1;
+ sel.ob.y = sel.oe.y = row;
+ selnormalize();
+ tsetdirt(sel.nb.y, sel.ne.y);
+ xsetsel(getsel());
+ xclipcopy();
+ }
+
+ free(linestr);
+}
+#else
+/* select and copy the previous url on screen (do nothing if there's no url).
+ * known bug: doesn't handle urls that span multiple lines (wontfix), depends on multiline "getsel()"
+ * known bug: only finds first url on line (mightfix)
+ */
+void
+copyurl(const Arg *arg) {
+ /* () and [] can appear in urls, but excluding them here will reduce false
+ * positives when figuring out where a given url ends.
+ */
+ static char URLCHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789-._~:/?#@!$&'*+,;=%";
+
+ int i, row, startrow;
+ char *linestr = calloc(sizeof(char), term.col+1); /* assume ascii */
+ char *c, *match = NULL;
+
+ row = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.y-1 : term.bot;
+ LIMIT(row, term.top, term.bot);
+ startrow = row;
+
+ /* find the start of the last url before selection */
+ do {
+ for (i = 0; i < term.col; ++i) {
+ if (term.line[row][i].u > 127) /* assume ascii */
+ continue;
+ linestr[i] = term.line[row][i].u;
+ }
+ linestr[term.col] = '\0';
+ if ((match = strstr(linestr, "http://"))
+ || (match = strstr(linestr, "https://")))
+ break;
+ if (--row < term.top)
+ row = term.bot;
+ } while (row != startrow);
+
+ if (match) {
+ /* must happen before trim */
+ selclear();
+ sel.ob.x = strlen(linestr) - strlen(match);
+
+ /* trim the rest of the line from the url match */
+ for (c = match; *c != '\0'; ++c)
+ if (!strchr(URLCHARS, *c)) {
+ *c = '\0';
+ break;
+ }
+
+ /* select and copy */
+ sel.mode = 1;
+ sel.type = SEL_REGULAR;
+ sel.oe.x = sel.ob.x + strlen(match)-1;
+ sel.ob.y = sel.oe.y = row;
+ selnormalize();
+ tsetdirt(sel.nb.y, sel.ne.y);
+ xsetsel(getsel());
+ xclipcopy();
+ }
+
+ free(linestr);
+}
+#endif // COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH
+\ No newline at end of file
diff --git a/patch/copyurl.h b/patch/copyurl.h
@@ -0,0 +1,5 @@
+void copyurl(const Arg *);
+#if COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH
+static void tsetcolor(int, int, int, uint32_t, uint32_t);
+static char * findlastany(char *, const char**, size_t);
+#endif // COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH
+\ No newline at end of file
diff --git a/patch/include.c b/patch/include.c
@@ -0,0 +1,5 @@
+/* Patches */
+
+#if COPYURL_PATCH || COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH
+#include "copyurl.c"
+#endif
+\ No newline at end of file
diff --git a/patch/include.h b/patch/include.h
@@ -0,0 +1,5 @@
+/* Patches */
+
+#if COPYURL_PATCH || COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH
+#include "copyurl.h"
+#endif
+\ No newline at end of file
diff --git a/patches.h b/patches.h
@@ -29,4 +29,31 @@
* This patch makes st set CLIPBOARD on selection.
* https://st.suckless.org/patches/clipboard/
*/
-#define CLIPBOARD_PATCH 1
-\ No newline at end of file
+#define CLIPBOARD_PATCH 1
+
+/* Select and copy the last URL displayed with Mod+l. Multiple invocations cycle through the
+ * available URLs.
+ * https://st.suckless.org/patches/copyurl/
+ */
+#define COPYURL_PATCH 1
+
+/* Select and copy the last URL displayed with Mod+l. Multiple invocations cycle through the
+ * available URLs. This variant also highlights the selected URLs.
+ * https://st.suckless.org/patches/copyurl/
+ */
+#define COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH 1
+
+/* This patch adds the option of disabling bold fonts globally.
+ * https://st.suckless.org/patches/disable_bold_italic_fonts/
+ */
+#define DISABLE_BOLD_FONTS_PATCH 0
+
+/* This patch adds the option of disabling italic fonts globally.
+ * https://st.suckless.org/patches/disable_bold_italic_fonts/
+ */
+#define DISABLE_ITALIC_FONTS_PATCH 0
+
+/* This patch adds the option of disabling roman fonts globally.
+ * https://st.suckless.org/patches/disable_bold_italic_fonts/
+ */
+#define DISABLE_ROMAN_FONTS_PATCH 0
diff --git a/st.c b/st.c
@@ -232,6 +232,8 @@ static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
static Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
+#include "patch/include.h"
+
ssize_t
xwrite(int fd, const char *s, size_t len)
{
@@ -2602,3 +2604,5 @@ redraw(void)
tfulldirt();
draw();
}
+
+#include "patch/include.c"
+\ No newline at end of file
diff --git a/x.c b/x.c
@@ -57,9 +57,13 @@ static void zoom(const Arg *);
static void zoomabs(const Arg *);
static void zoomreset(const Arg *);
+#include "patch/include.h"
+
/* config.h for applying patches and the configuration. */
#include "config.h"
+//#include "patch/include.c"
+
/* XEMBED messages */
#define XEMBED_FOCUS_IN 4
#define XEMBED_FOCUS_OUT 5
@@ -1005,17 +1009,23 @@ xloadfonts(char *fontstr, double fontsize)
win.ch = ceilf(dc.font.height * chscale);
FcPatternDel(pattern, FC_SLANT);
+ #if !DISABLE_ITALIC_FONTS_PATCH
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
+ #endif // DISABLE_ITALIC_FONTS_PATCH
if (xloadfont(&dc.ifont, pattern))
die("can't open font %s\n", fontstr);
FcPatternDel(pattern, FC_WEIGHT);
+ #if !DISABLE_BOLD_FONTS_PATCH
FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
+ #endif // DISABLE_BOLD_FONTS_PATCH
if (xloadfont(&dc.ibfont, pattern))
die("can't open font %s\n", fontstr);
FcPatternDel(pattern, FC_SLANT);
+ #if !DISABLE_ROMAN_FONTS_PATCH
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
+ #endif // DISABLE_ROMAN_FONTS_PATCH
if (xloadfont(&dc.bfont, pattern))
die("can't open font %s\n", fontstr);