Introduction
Introduction Statistics Contact Development Disclaimer Help
st-clickurl-nocontrol-0.8.5.diff - sites - public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log
Files
Refs
---
st-clickurl-nocontrol-0.8.5.diff (5591B)
---
1 From 8d13e4a296f0b2a625df10c8ee6d2fc96ec97580 Mon Sep 17 00:00:00 2001
2 From: Kyle Chui <[email protected]>
3 Date: Tue, 9 Apr 2024 16:31:25 -0700
4 Subject: [PATCH] Underline URLs and follow with click
5
6 ---
7 config.def.h | 11 +++++++
8 st.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++
9 st.h | 9 ++++++
10 x.c | 12 ++++++-
11 4 files changed, 119 insertions(+), 1 deletion(-)
12
13 diff --git a/config.def.h b/config.def.h
14 index 91ab8ca..4961830 100644
15 --- a/config.def.h
16 +++ b/config.def.h
17 @@ -472,3 +472,14 @@ static char ascii_printable[] =
18 " !\"#$%&'()*+,-./0123456789:;<=>?"
19 "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
20 "`abcdefghijklmnopqrstuvwxyz{|}~";
21 +
22 +/*
23 + * Open urls starting with urlprefixes, contatining urlchars
24 + * by passing as ARG1 to urlhandler.
25 + */
26 +char* urlhandler = "xdg-open";
27 +char urlchars[] =
28 + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
29 + "abcdefghijklmnopqrstuvwxyz"
30 + "0123456789-._~:/?#@!$&'*+,;=%";
31 +char* urlprefixes[] = {"http://", "https://", NULL};
32 diff --git a/st.c b/st.c
33 index 51049ba..a7eb86e 100644
34 --- a/st.c
35 +++ b/st.c
36 @@ -643,6 +643,92 @@ getsel(void)
37 return str;
38 }
39
40 +char *
41 +strstrany(char* s, char** strs) {
42 + char *match;
43 + for (int i = 0; strs[i]; i++) {
44 + if ((match = strstr(s, strs[i]))) {
45 + return match;
46 + }
47 + }
48 + return NULL;
49 +}
50 +
51 +void
52 +highlighturlsline(int row)
53 +{
54 + char *linestr = calloc(sizeof(char), term.col+1); /* assume asc…
55 + char *match;
56 + for (int j = 0; j < term.col; j++) {
57 + if (term.line[row][j].u < 127) {
58 + linestr[j] = term.line[row][j].u;
59 + }
60 + linestr[term.col] = '\0';
61 + }
62 + int url_start = -1;
63 + while ((match = strstrany(linestr + url_start + 1, urlprefixes)…
64 + url_start = match - linestr;
65 + for (int c = url_start; c < term.col && strchr(urlchars…
66 + term.line[row][c].mode |= ATTR_URL;
67 + tsetdirt(row, c);
68 + }
69 + }
70 + free(linestr);
71 +}
72 +
73 +void
74 +unhighlighturlsline(int row)
75 +{
76 + for (int j = 0; j < term.col; j++) {
77 + Glyph* g = &term.line[row][j];
78 + if (g->mode & ATTR_URL) {
79 + g->mode &= ~ATTR_URL;
80 + tsetdirt(row, j);
81 + }
82 + }
83 + return;
84 +}
85 +
86 +int
87 +followurl(int col, int row) {
88 + char *linestr = calloc(sizeof(char), term.col+1); /* assume asc…
89 + char *match;
90 + for (int i = 0; i < term.col; i++) {
91 + if (term.line[row][i].u < 127) {
92 + linestr[i] = term.line[row][i].u;
93 + }
94 + linestr[term.col] = '\0';
95 + }
96 + int url_start = -1, found_url = 0;
97 + while ((match = strstrany(linestr + url_start + 1, urlprefixes)…
98 + url_start = match - linestr;
99 + int url_end = url_start;
100 + for (int c = url_start; c < term.col && strchr(urlchars…
101 + url_end++;
102 + }
103 + if (url_start <= col && col < url_end) {
104 + found_url = 1;
105 + linestr[url_end] = '\0';
106 + break;
107 + }
108 + }
109 + if (!found_url) {
110 + free(linestr);
111 + return 0;
112 + }
113 +
114 + pid_t chpid;
115 + if ((chpid = fork()) == 0) {
116 + if (fork() == 0)
117 + execlp(urlhandler, urlhandler, linestr + url_st…
118 + exit(1);
119 + }
120 + if (chpid > 0)
121 + waitpid(chpid, NULL, 0);
122 + free(linestr);
123 + return 1;
124 +}
125 +
126 void
127 selclear(void)
128 {
129 @@ -2652,6 +2738,8 @@ drawregion(int x1, int y1, int x2, int y2)
130 continue;
131
132 term.dirty[y] = 0;
133 + unhighlighturlsline(y);
134 + highlighturlsline(y);
135 xdrawline(term.line[y], x1, y, x2);
136 }
137 }
138 diff --git a/st.h b/st.h
139 index 519b9bd..5efc27e 100644
140 --- a/st.h
141 +++ b/st.h
142 @@ -33,6 +33,7 @@ enum glyph_attribute {
143 ATTR_WRAP = 1 << 8,
144 ATTR_WIDE = 1 << 9,
145 ATTR_WDUMMY = 1 << 10,
146 + ATTR_URL = 1 << 11,
147 ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
148 };
149
150 @@ -105,6 +106,10 @@ void selextend(int, int, int, int);
151 int selected(int, int);
152 char *getsel(void);
153
154 +void highlighturlsline(int);
155 +void unhighlighturlsline(int);
156 +int followurl(int, int);
157 +
158 size_t utf8encode(Rune, char *);
159
160 void *xmalloc(size_t);
161 @@ -126,3 +131,7 @@ extern unsigned int tabspaces;
162 extern unsigned int defaultfg;
163 extern unsigned int defaultbg;
164 extern unsigned int defaultcs;
165 +extern char *urlhandler;
166 +extern char urlchars[];
167 +extern char *urlprefixes[];
168 +extern int nurlprefixes;
169 diff --git a/x.c b/x.c
170 index 8a16faa..c721f8b 100644
171 --- a/x.c
172 +++ b/x.c
173 @@ -191,6 +191,7 @@ static void usage(void);
174
175 static void (*handler[LASTEvent])(XEvent *) = {
176 [KeyPress] = kpress,
177 + [KeyRelease] = kpress,
178 [ClientMessage] = cmessage,
179 [ConfigureNotify] = resize,
180 [VisibilityNotify] = visibility,
181 @@ -445,6 +446,10 @@ mouseaction(XEvent *e, uint release)
182 /* ignore Button<N>mask for Button<N> - it's set on release */
183 uint state = e->xbutton.state & ~buttonmask(e->xbutton.button);
184
185 + if (release == 0 && e->xbutton.button == Button1) {
186 + return followurl(evcol(e), evrow(e));
187 + }
188 +
189 for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
190 if (ms->release == release &&
191 ms->button == e->xbutton.button &&
192 @@ -1476,7 +1481,7 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs,…
193 XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
194
195 /* Render underline and strikethrough. */
196 - if (base.mode & ATTR_UNDERLINE) {
197 + if (base.mode & ATTR_UNDERLINE || base.mode & ATTR_URL) {
198 XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + …
199 width, 1);
200 }
201 @@ -1831,6 +1836,11 @@ kpress(XEvent *ev)
202 len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &…
203 else
204 len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
205 +
206 + /* KeyRelease not relevant to shortcuts */
207 + if (ev->type == KeyRelease)
208 + return;
209 +
210 /* 1. shortcuts */
211 for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
212 if (ksym == bp->keysym && match(bp->mod, e->state)) {
213 --
214 2.42.0
215
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.