st-copyurl-20230406-211964d.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
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