st-copyurl-20230406-211964d.diff - sites - public wiki contents of suckless.org | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
st-copyurl-20230406-211964d.diff (4255B) | |
--- | |
1 From 8b07fb9ab581eb31714f0dd25a419926a7f34cc6 Mon Sep 17 00:00:00 2001 | |
2 From: Gildasio Junior <[email protected]> | |
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 = … | |
23 { ShiftMask, XK_Insert, selpaste, {.i = … | |
24 { TERMMOD, XK_Num_Lock, numlock, {.i = … | |
25 + { MODKEY, XK_l, copyurl, {.i = … | |
26 + { MODKEY|ShiftMask, XK_L, copyurl, {.i = … | |
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])) ==… | |
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… | |
66 +** | |
67 +** FIXME: doesn't handle urls that span multiple lines; will need to ad… | |
68 +** for multiline "getsel()" first | |
69 +*/ | |
70 +void | |
71 +copyurl(const Arg *arg) { | |
72 + /* () and [] can appear in urls, but excluding them here will r… | |
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 ? te… | |
106 + linestr[col] = '\0'; | |
107 + | |
108 + if ((match = findlastany(linestr, URLSTRINGS, | |
109 + sizeof(URLSTRINGS)/size… | |
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 |