st-copyurl-0.8.4.diff (4476B)
1 diff -up ../st-0.8.4/config.def.h ./config.def.h 2 --- ../st-0.8.4/config.def.h 2020-06-19 10:29:45.000000000 +0100 3 +++ ./config.def.h 2021-01-29 22:40:56.451916768 +0000 4 @@ -199,6 +199,7 @@ static Shortcut shortcuts[] = { 5 { TERMMOD, XK_Y, selpaste, {.i = 0} }, 6 { ShiftMask, XK_Insert, selpaste, {.i = 0} }, 7 { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, 8 + { MODKEY, XK_l, copyurl, {.i = 0} }, 9 }; 10 11 /* 12 diff -up ../st-0.8.4/st.c ./st.c 13 --- ../st-0.8.4/st.c 2020-06-19 10:29:45.000000000 +0100 14 +++ ./st.c 2021-01-29 22:41:18.031954197 +0000 15 @@ -200,6 +200,8 @@ static void tdefutf8(char); 16 static int32_t tdefcolor(int *, int *, int); 17 static void tdeftran(char); 18 static void tstrsequence(uchar); 19 +static void tsetcolor(int, int, int, uint32_t, uint32_t); 20 +static char * findlastany(char *, const char**, size_t); 21 22 static void drawregion(int, int, int, int); 23 24 @@ -2595,3 +2597,122 @@ redraw(void) 25 tfulldirt(); 26 draw(); 27 } 28 + 29 +void 30 +tsetcolor( int row, int start, int end, uint32_t fg, uint32_t bg ) 31 +{ 32 + int i = start; 33 + for( ; i < end; ++i ) 34 + { 35 + term.line[row][i].fg = fg; 36 + term.line[row][i].bg = bg; 37 + } 38 +} 39 + 40 +char * 41 +findlastany(char *str, const char** find, size_t len) 42 +{ 43 + char* found = NULL; 44 + int i = 0; 45 + for(found = str + strlen(str) - 1; found >= str; --found) { 46 + for(i = 0; i < len; i++) { 47 + if(strncmp(found, find[i], strlen(find[i])) == 0) { 48 + return found; 49 + } 50 + } 51 + } 52 + 53 + return NULL; 54 +} 55 + 56 +/* 57 +** Select and copy the previous url on screen (do nothing if there's no url). 58 +** 59 +** FIXME: doesn't handle urls that span multiple lines; will need to add support 60 +** for multiline "getsel()" first 61 +*/ 62 +void 63 +copyurl(const Arg *arg) { 64 + /* () and [] can appear in urls, but excluding them here will reduce false 65 + * positives when figuring out where a given url ends. 66 + */ 67 + static char URLCHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 68 + "abcdefghijklmnopqrstuvwxyz" 69 + "0123456789-._~:/?#@!$&'*+,;=%"; 70 + 71 + static const char* URLSTRINGS[] = {"http://", "https://"}; 72 + 73 + /* remove highlighting from previous selection if any */ 74 + if(sel.ob.x >= 0 && sel.oe.x >= 0) 75 + tsetcolor(sel.nb.y, sel.ob.x, sel.oe.x + 1, defaultfg, defaultbg); 76 + 77 + int i = 0, 78 + row = 0, /* row of current URL */ 79 + col = 0, /* column of current URL start */ 80 + startrow = 0, /* row of last occurrence */ 81 + colend = 0, /* column of last occurrence */ 82 + passes = 0; /* how many rows have been scanned */ 83 + 84 + char *linestr = calloc(term.col+1, sizeof(Rune)); 85 + char *c = NULL, 86 + *match = NULL; 87 + 88 + row = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.y : term.bot; 89 + LIMIT(row, term.top, term.bot); 90 + startrow = row; 91 + 92 + colend = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.x : term.col; 93 + LIMIT(colend, 0, term.col); 94 + 95 + /* 96 + ** Scan from (term.bot,term.col) to (0,0) and find 97 + ** next occurrance of a URL 98 + */ 99 + while(passes !=term.bot + 2) { 100 + /* Read in each column of every row until 101 + ** we hit previous occurrence of URL 102 + */ 103 + for (col = 0, i = 0; col < colend; ++col,++i) { 104 + linestr[i] = term.line[row][col].u; 105 + } 106 + linestr[term.col] = '\0'; 107 + 108 + if ((match = findlastany(linestr, URLSTRINGS, 109 + sizeof(URLSTRINGS)/sizeof(URLSTRINGS[0])))) 110 + break; 111 + 112 + if (--row < term.top) 113 + row = term.bot; 114 + 115 + colend = term.col; 116 + passes++; 117 + }; 118 + 119 + if (match) { 120 + /* must happen before trim */ 121 + selclear(); 122 + sel.ob.x = strlen(linestr) - strlen(match); 123 + 124 + /* trim the rest of the line from the url match */ 125 + for (c = match; *c != '\0'; ++c) 126 + if (!strchr(URLCHARS, *c)) { 127 + *c = '\0'; 128 + break; 129 + } 130 + 131 + /* highlight selection by inverting terminal colors */ 132 + tsetcolor(row, sel.ob.x, sel.ob.x + strlen( match ), defaultbg, defaultfg); 133 + 134 + /* select and copy */ 135 + sel.mode = 1; 136 + sel.type = SEL_REGULAR; 137 + sel.oe.x = sel.ob.x + strlen(match)-1; 138 + sel.ob.y = sel.oe.y = row; 139 + selnormalize(); 140 + tsetdirt(sel.nb.y, sel.ne.y); 141 + xsetsel(getsel()); 142 + xclipcopy(); 143 + } 144 + 145 + free(linestr); 146 +} 147 Only in .: st-copyurl-0.8.4.diff 148 Only in .: st-copyurl-20190202-3be4cf1.diff 149 diff -up ../st-0.8.4/st.h ./st.h 150 --- ../st-0.8.4/st.h 2020-06-19 10:29:45.000000000 +0100 151 +++ ./st.h 2021-01-29 22:40:56.451916768 +0000 152 @@ -85,6 +85,7 @@ void printscreen(const Arg *); 153 void printsel(const Arg *); 154 void sendbreak(const Arg *); 155 void toggleprinter(const Arg *); 156 +void copyurl(const Arg *); 157 158 int tattrset(int); 159 void tnew(int, int);