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 |