st-copyurl-multiline-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-multiline-20230406-211964d.diff (4361B)
---
1 From 7405bdc89e4c43cfbeabd0d4d822bc62d1e76730 Mon Sep 17 00:00:00 2001
2 From: Gildasio Junior <gildasiojunior@riseup.net>
3 Date: Thu, 6 Apr 2023 14:51:06 -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 | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++
14 st.h | 1 +
15 3 files changed, 104 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..c451015 100644
32 --- a/st.c
33 +++ b/st.c
34 @@ -152,6 +152,11 @@ typedef struct {
35 int narg; /* nb of args */
36 } STREscape;
37
38 +typedef struct {
39 + int state;
40 + size_t length;
41 +} URLdfa;
42 +
43 static void execsh(char *, char **);
44 static void stty(char **);
45 static void sigchld(int);
46 @@ -201,6 +206,7 @@ static void tdefutf8(char);
47 static int32_t tdefcolor(const int *, int *, int);
48 static void tdeftran(char);
49 static void tstrsequence(uchar);
50 +static int daddch(URLdfa *, char);
51
52 static void drawregion(int, int, int, int);
53
54 @@ -2666,3 +2672,98 @@ redraw(void)
55 tfulldirt();
56 draw();
57 }
58 +
59 +int
60 +daddch(URLdfa *dfa, char c)
61 +{
62 + /* () and [] can appear in urls, but excluding them here will reduce false
63 + * positives when figuring out where a given url ends.
64 + */
65 + static const char URLCHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
66 + "abcdefghijklmnopqrstuvwxyz"
67 + "0123456789-._~:/?#@!$&'*+,;=%";
68 + static const char RPFX[] = "//:sptth";
69 +
70 + if (!strchr(URLCHARS, c)) {
71 + dfa->length = 0;
72 + dfa->state = 0;
73 +
74 + return 0;
75 + }
76 +
77 + dfa->length++;
78 +
79 + if (dfa->state == 2 && c == '/') {
80 + dfa->state = 0;
81 + } else if (dfa->state == 3 && c == 'p') {
82 + dfa->state++;
83 + } else if (c != RPFX[dfa->state]) {
84 + dfa->state = 0;
85 + return 0;
86 + }
87 +
88 + if (dfa->state++ == 7) {
89 + dfa->state = 0;
90 + return 1;
91 + }
92 +
93 + return 0;
94 +}
95 +
96 +/*
97 +** Select and copy the previous url on screen (do nothing if there's no url).
98 +*/
99 +void
100 +copyurl(const Arg *arg) {
101 + int row = 0, /* row of current URL */
102 + col = 0, /* column of current URL start */
103 + colend = 0, /* column of last occurrence */
104 + passes = 0; /* how many rows have been scanned */
105 +
106 + const char *c = NULL,
107 + *match = NULL;
108 + URLdfa dfa = { 0 };
109 +
110 + row = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.y : term.bot;
111 + LIMIT(row, term.top, term.bot);
112 +
113 + colend = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.x : term.col;
114 + LIMIT(colend, 0, term.col);
115 +
116 + /*
117 + ** Scan from (term.row - 1,term.col - 1) to (0,0) and find
118 + ** next occurrance of a URL
119 + */
120 + for (passes = 0; passes < term.row; passes++) {
121 + /* Read in each column of every row until
122 + ** we hit previous occurrence of URL
123 + */
124 + for (col = colend; col--;)
125 + if (daddch(&dfa, term.line[row][col].u < 128 ? term.line[row][col].u : ' '))
126 + break;
127 +
128 + if (col >= 0)
129 + break;
130 +
131 + /* .i = 0 --> botton-up
132 + * .i = 1 --> top-down
133 + */
134 + if (!arg->i) {
135 + if (--row < 0)
136 + row = term.row - 1;
137 + } else {
138 + if (++row >= term.row)
139 + row = 0;
140 + }
141 +
142 + colend = term.col;
143 + }
144 +
145 + if (passes < term.row) {
146 + selstart(col, row, 0);
147 + selextend((col + dfa.length - 1) % term.col, row + (col + dfa.length - 1) / term.col, SEL_REGULAR, 0);
148 + selextend((col + dfa.length - 1) % term.col, row + (col + dfa.length - 1) / term.col, SEL_REGULAR, 1);
149 + xsetsel(getsel());
150 + xclipcopy();
151 + }
152 +}
153 diff --git a/st.h b/st.h
154 index fd3b0d8..baa8f29 100644
155 --- a/st.h
156 +++ b/st.h
157 @@ -85,6 +85,7 @@ void printscreen(const Arg *);
158 void printsel(const Arg *);
159 void sendbreak(const Arg *);
160 void toggleprinter(const Arg *);
161 +void copyurl(const Arg *);
162
163 int tattrset(int);
164 void tnew(int, int);
165 --
166 2.40.0
167