st-copyurl-20230406-211964d.diff (4255B)
1 From 8b07fb9ab581eb31714f0dd25a419926a7f34cc6 Mon Sep 17 00:00:00 2001 2 From: Gildasio Junior <gildasiojunior@riseup.net> 3 Date: Thu, 6 Apr 2023 14:54:23 -0300 4 Subject: [PATCH] Loop through urls on screen in both directions 5 6 Using previous patches one can loop through urls in the screen in one 7 direction: botton-up. This patch add a way that can go in the opposite 8 direction: top-down. 9 10 This is usefull in a screen with lots of urls. 11 --- 12 config.def.h | 2 ++ 13 st.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 14 st.h | 1 + 15 3 files changed, 93 insertions(+) 16 17 diff --git a/config.def.h b/config.def.h 18 index 91ab8ca..4df78eb 100644 19 --- a/config.def.h 20 +++ b/config.def.h 21 @@ -201,6 +201,8 @@ static Shortcut shortcuts[] = { 22 { TERMMOD, XK_Y, selpaste, {.i = 0} }, 23 { ShiftMask, XK_Insert, selpaste, {.i = 0} }, 24 { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, 25 + { MODKEY, XK_l, copyurl, {.i = 0} }, 26 + { MODKEY|ShiftMask, XK_L, copyurl, {.i = 1} }, 27 }; 28 29 /* 30 diff --git a/st.c b/st.c 31 index 134e724..1b321ab 100644 32 --- a/st.c 33 +++ b/st.c 34 @@ -201,6 +201,7 @@ static void tdefutf8(char); 35 static int32_t tdefcolor(const int *, int *, int); 36 static void tdeftran(char); 37 static void tstrsequence(uchar); 38 +static const char *findlastany(const char *, const char**, size_t); 39 40 static void drawregion(int, int, int, int); 41 42 @@ -2666,3 +2667,92 @@ redraw(void) 43 tfulldirt(); 44 draw(); 45 } 46 + 47 +const char * 48 +findlastany(const char *str, const char**find, size_t len) 49 +{ 50 + const char *found = NULL; 51 + int i = 0; 52 + 53 + for (found = str + strlen(str) - 1; found >= str; --found) { 54 + for(i = 0; i < len; i++) { 55 + if (strncmp(found, find[i], strlen(find[i])) == 0) { 56 + return found; 57 + } 58 + } 59 + } 60 + 61 + return NULL; 62 +} 63 + 64 +/* 65 +** Select and copy the previous url on screen (do nothing if there's no url). 66 +** 67 +** FIXME: doesn't handle urls that span multiple lines; will need to add support 68 +** for multiline "getsel()" first 69 +*/ 70 +void 71 +copyurl(const Arg *arg) { 72 + /* () and [] can appear in urls, but excluding them here will reduce false 73 + * positives when figuring out where a given url ends. 74 + */ 75 + static const char URLCHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 76 + "abcdefghijklmnopqrstuvwxyz" 77 + "0123456789-._~:/?#@!$&'*+,;=%"; 78 + 79 + static const char* URLSTRINGS[] = {"http://", "https://"}; 80 + 81 + int row = 0, /* row of current URL */ 82 + col = 0, /* column of current URL start */ 83 + colend = 0, /* column of last occurrence */ 84 + passes = 0; /* how many rows have been scanned */ 85 + 86 + char linestr[term.col + 1]; 87 + const char *c = NULL, 88 + *match = NULL; 89 + 90 + row = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.y : term.bot; 91 + LIMIT(row, term.top, term.bot); 92 + 93 + colend = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.x : term.col; 94 + LIMIT(colend, 0, term.col); 95 + 96 + /* 97 + ** Scan from (term.row - 1,term.col - 1) to (0,0) and find 98 + ** next occurrance of a URL 99 + */ 100 + for (passes = 0; passes < term.row; passes++) { 101 + /* Read in each column of every row until 102 + ** we hit previous occurrence of URL 103 + */ 104 + for (col = 0; col < colend; ++col) 105 + linestr[col] = term.line[row][col].u < 128 ? term.line[row][col].u : ' '; 106 + linestr[col] = '\0'; 107 + 108 + if ((match = findlastany(linestr, URLSTRINGS, 109 + sizeof(URLSTRINGS)/sizeof(URLSTRINGS[0])))) 110 + break; 111 + 112 + /* .i = 0 --> botton-up 113 + * .i = 1 --> top-down 114 + * */ 115 + if (!arg->i) { 116 + if (--row < 0) 117 + row = term.row - 1; 118 + } else { 119 + if (++row >= term.row) 120 + row = 0; 121 + } 122 + 123 + colend = term.col; 124 + }; 125 + 126 + if (match) { 127 + size_t l = strspn(match, URLCHARS); 128 + selstart(match - linestr, row, 0); 129 + selextend(match - linestr + l - 1, row, SEL_REGULAR, 0); 130 + selextend(match - linestr + l - 1, row, SEL_REGULAR, 1); 131 + xsetsel(getsel()); 132 + xclipcopy(); 133 + } 134 +} 135 diff --git a/st.h b/st.h 136 index fd3b0d8..baa8f29 100644 137 --- a/st.h 138 +++ b/st.h 139 @@ -85,6 +85,7 @@ void printscreen(const Arg *); 140 void printsel(const Arg *); 141 void sendbreak(const Arg *); 142 void toggleprinter(const Arg *); 143 +void copyurl(const Arg *); 144 145 int tattrset(int); 146 void tnew(int, int); 147 -- 148 2.40.0 149