| st-copyurl-20220221-0.8.5.diff - sites - public wiki contents of suckless.org | |
| git clone git://git.suckless.org/sites | |
| Log | |
| Files | |
| Refs | |
| --- | |
| st-copyurl-20220221-0.8.5.diff (3868B) | |
| --- | |
| 1 From 897c3958d01d8df80ebf1666b972b8a658b419ba Mon Sep 17 00:00:00 2001 | |
| 2 From: Santtu Lakkala <[email protected]> | |
| 3 Date: Wed, 16 Feb 2022 20:34:20 +0200 | |
| 4 Subject: [PATCH] Loop through urls on screen and copy to clipboard | |
| 5 | |
| 6 Based on the previous highlighting patches, slightly simplified and | |
| 7 fixes graphical issues with mixed copyurl and selection. | |
| 8 --- | |
| 9 config.def.h | 1 + | |
| 10 st.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
| 11 st.h | 1 + | |
| 12 3 files changed, 84 insertions(+) | |
| 13 | |
| 14 diff --git a/config.def.h b/config.def.h | |
| 15 index 91ab8ca..3f365c7 100644 | |
| 16 --- a/config.def.h | |
| 17 +++ b/config.def.h | |
| 18 @@ -201,6 +201,7 @@ static Shortcut shortcuts[] = { | |
| 19 { TERMMOD, XK_Y, selpaste, {.i = … | |
| 20 { ShiftMask, XK_Insert, selpaste, {.i = … | |
| 21 { TERMMOD, XK_Num_Lock, numlock, {.i = … | |
| 22 + { MODKEY, XK_l, copyurl, {.i = … | |
| 23 }; | |
| 24 | |
| 25 /* | |
| 26 diff --git a/st.c b/st.c | |
| 27 index 51049ba..bf3d81a 100644 | |
| 28 --- a/st.c | |
| 29 +++ b/st.c | |
| 30 @@ -200,6 +200,7 @@ static void tdefutf8(char); | |
| 31 static int32_t tdefcolor(const int *, int *, int); | |
| 32 static void tdeftran(char); | |
| 33 static void tstrsequence(uchar); | |
| 34 +static const char *findlastany(const char *, const char**, size_t); | |
| 35 | |
| 36 static void drawregion(int, int, int, int); | |
| 37 | |
| 38 @@ -2688,3 +2689,84 @@ redraw(void) | |
| 39 tfulldirt(); | |
| 40 draw(); | |
| 41 } | |
| 42 + | |
| 43 +const char * | |
| 44 +findlastany(const char *str, const char**find, size_t len) | |
| 45 +{ | |
| 46 + const char *found = NULL; | |
| 47 + int i = 0; | |
| 48 + | |
| 49 + for (found = str + strlen(str) - 1; found >= str; --found) { | |
| 50 + for(i = 0; i < len; i++) { | |
| 51 + if (strncmp(found, find[i], strlen(find[i])) ==… | |
| 52 + return found; | |
| 53 + } | |
| 54 + } | |
| 55 + } | |
| 56 + | |
| 57 + return NULL; | |
| 58 +} | |
| 59 + | |
| 60 +/* | |
| 61 +** Select and copy the previous url on screen (do nothing if there's no… | |
| 62 +** | |
| 63 +** FIXME: doesn't handle urls that span multiple lines; will need to ad… | |
| 64 +** for multiline "getsel()" first | |
| 65 +*/ | |
| 66 +void | |
| 67 +copyurl(const Arg *arg) { | |
| 68 + /* () and [] can appear in urls, but excluding them here will r… | |
| 69 + * positives when figuring out where a given url ends. | |
| 70 + */ | |
| 71 + static const char URLCHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
| 72 + "abcdefghijklmnopqrstuvwxyz" | |
| 73 + "0123456789-._~:/?#@!$&'*+,;=%"; | |
| 74 + | |
| 75 + static const char* URLSTRINGS[] = {"http://", "https://"}; | |
| 76 + | |
| 77 + int row = 0, /* row of current URL */ | |
| 78 + col = 0, /* column of current URL start */ | |
| 79 + colend = 0, /* column of last occurrence */ | |
| 80 + passes = 0; /* how many rows have been scanned */ | |
| 81 + | |
| 82 + char linestr[term.col + 1]; | |
| 83 + const char *c = NULL, | |
| 84 + *match = NULL; | |
| 85 + | |
| 86 + row = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.y : term.bot; | |
| 87 + LIMIT(row, term.top, term.bot); | |
| 88 + | |
| 89 + colend = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.x : term.col; | |
| 90 + LIMIT(colend, 0, term.col); | |
| 91 + | |
| 92 + /* | |
| 93 + ** Scan from (term.row - 1,term.col - 1) to (0,0) and find | |
| 94 + ** next occurrance of a URL | |
| 95 + */ | |
| 96 + for (passes = 0; passes < term.row; passes++) { | |
| 97 + /* Read in each column of every row until | |
| 98 + ** we hit previous occurrence of URL | |
| 99 + */ | |
| 100 + for (col = 0; col < colend; ++col) | |
| 101 + linestr[col] = term.line[row][col].u < 128 ? te… | |
| 102 + linestr[col] = '\0'; | |
| 103 + | |
| 104 + if ((match = findlastany(linestr, URLSTRINGS, | |
| 105 + sizeof(URLSTRINGS)/size… | |
| 106 + break; | |
| 107 + | |
| 108 + if (--row < 0) | |
| 109 + row = term.row - 1; | |
| 110 + | |
| 111 + colend = term.col; | |
| 112 + }; | |
| 113 + | |
| 114 + if (match) { | |
| 115 + size_t l = strspn(match, URLCHARS); | |
| 116 + selstart(match - linestr, row, 0); | |
| 117 + selextend(match - linestr + l - 1, row, SEL_REGULAR, 0); | |
| 118 + selextend(match - linestr + l - 1, row, SEL_REGULAR, 1); | |
| 119 + xsetsel(getsel()); | |
| 120 + xclipcopy(); | |
| 121 + } | |
| 122 +} | |
| 123 diff --git a/st.h b/st.h | |
| 124 index 519b9bd..0458005 100644 | |
| 125 --- a/st.h | |
| 126 +++ b/st.h | |
| 127 @@ -85,6 +85,7 @@ void printscreen(const Arg *); | |
| 128 void printsel(const Arg *); | |
| 129 void sendbreak(const Arg *); | |
| 130 void toggleprinter(const Arg *); | |
| 131 +void copyurl(const Arg *); | |
| 132 | |
| 133 int tattrset(int); | |
| 134 void tnew(int, int); | |
| 135 -- | |
| 136 2.32.0 | |
| 137 |