st-copyurl-multiline-20230406-211964d.diff - sites - public wiki contents of su… | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
st-copyurl-multiline-20230406-211964d.diff (4361B) | |
--- | |
1 From 7405bdc89e4c43cfbeabd0d4d822bc62d1e76730 Mon Sep 17 00:00:00 2001 | |
2 From: Gildasio Junior <[email protected]> | |
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 = … | |
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..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 r… | |
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… | |
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 ? … | |
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… | |
148 + selextend((col + dfa.length - 1) % term.col, row + (col… | |
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 |