st-keyboard_select-0.8.2.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
st-keyboard_select-0.8.2.diff (9969B)
---
1 From 45cadc1ce5d8d9dd3493c2e9979e8958d87e8bc5 Mon Sep 17 00:00:00 2001
2 From: Bartosz Sosna <brtsos@gmail.com>
3 Date: Sat, 4 May 2019 00:28:24 +0200
4 Subject: [PATCH] Adjust patch to version st-0.8.2
5
6 ---
7 config.def.h | 1 +
8 st.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++++++
9 st.h | 1 +
10 win.h | 3 +
11 x.c | 15 ++++
12 5 files changed, 242 insertions(+)
13
14 diff --git a/config.def.h b/config.def.h
15 index 482901e..c1e9cce 100644
16 --- a/config.def.h
17 +++ b/config.def.h
18 @@ -178,6 +178,7 @@ static Shortcut shortcuts[] = {
19 { TERMMOD, XK_Y, selpaste, {.i = 0} },
20 { ShiftMask, XK_Insert, selpaste, {.i = 0} },
21 { TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
22 + { TERMMOD, XK_Escape, keyboard_select,{ 0 } },
23 };
24
25 /*
26 diff --git a/st.c b/st.c
27 index ede7ae6..c2116b2 100644
28 --- a/st.c
29 +++ b/st.c
30 @@ -16,6 +16,8 @@
31 #include <termios.h>
32 #include <unistd.h>
33 #include <wchar.h>
34 +#include <X11/keysym.h>
35 +#include <X11/X.h>
36
37 #include "st.h"
38 #include "win.h"
39 @@ -2464,6 +2466,9 @@ tresize(int col, int row)
40 int *bp;
41 TCursor c;
42
43 + if ( row < term.row || col < term.col )
44 + toggle_winmode(trt_kbdselect(XK_Escape, NULL, 0));
45 +
46 if (col < 1 || row < 1) {
47 fprintf(stderr,
48 "tresize: error resizing to %dx%d\n", col, row);
49 @@ -2586,3 +2591,220 @@ redraw(void)
50 tfulldirt();
51 draw();
52 }
53 +
54 +void set_notifmode(int type, KeySym ksym) {
55 + static char *lib[] = { " MOVE ", " SEL "};
56 + static Glyph *g, *deb, *fin;
57 + static int col, bot;
58 +
59 + if ( ksym == -1 ) {
60 + free(g);
61 + col = term.col, bot = term.bot;
62 + g = xmalloc(col * sizeof(Glyph));
63 + memcpy(g, term.line[bot], col * sizeof(Glyph));
64 +
65 + }
66 + else if ( ksym == -2 )
67 + memcpy(term.line[bot], g, col * sizeof(Glyph));
68 +
69 + if ( type < 2 ) {
70 + char *z = lib[type];
71 + for (deb = &term.line[bot][col - 6], fin = &term.line[bot][col]; deb < fin; z++, deb++)
72 + deb->mode = ATTR_REVERSE,
73 + deb->u = *z,
74 + deb->fg = defaultfg, deb->bg = defaultbg;
75 + }
76 + else if ( type < 5 )
77 + memcpy(term.line[bot], g, col * sizeof(Glyph));
78 + else {
79 + for (deb = &term.line[bot][0], fin = &term.line[bot][col]; deb < fin; deb++)
80 + deb->mode = ATTR_REVERSE,
81 + deb->u = ' ',
82 + deb->fg = defaultfg, deb->bg = defaultbg;
83 + term.line[bot][0].u = ksym;
84 + }
85 +
86 + term.dirty[bot] = 1;
87 + drawregion(0, bot, col, bot + 1);
88 +}
89 +
90 +void select_or_drawcursor(int selectsearch_mode, int type) {
91 + int done = 0;
92 +
93 + if ( selectsearch_mode & 1 ) {
94 + selextend(term.c.x, term.c.y, type, done);
95 + xsetsel(getsel());
96 + }
97 + else
98 + xdrawcursor(term.c.x, term.c.y, term.line[term.c.y][term.c.x],
99 + term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
100 +}
101 +
102 +void search(int selectsearch_mode, Rune *target, int ptarget, int incr, int type, TCursor *cu) {
103 + Rune *r;
104 + int i, bound = (term.col * cu->y + cu->x) * (incr > 0) + incr;
105 +
106 + for (i = term.col * term.c.y + term.c.x + incr; i != bound; i += incr) {
107 + for (r = target; r - target < ptarget; r++) {
108 + if ( *r == term.line[(i + r - target) / term.col][(i + r - target) % term.col].u ) {
109 + if ( r - target == ptarget - 1 ) break;
110 + } else {
111 + r = NULL;
112 + break;
113 + }
114 + }
115 + if ( r != NULL ) break;
116 + }
117 +
118 + if ( i != bound ) {
119 + term.c.y = i / term.col, term.c.x = i % term.col;
120 + select_or_drawcursor(selectsearch_mode, type);
121 + }
122 +}
123 +
124 +int trt_kbdselect(KeySym ksym, char *buf, int len) {
125 + static TCursor cu;
126 + static Rune target[64];
127 + static int type = 1, ptarget, in_use;
128 + static int sens, quant;
129 + static char selectsearch_mode;
130 + int i, bound, *xy;
131 +
132 +
133 + if ( selectsearch_mode & 2 ) {
134 + if ( ksym == XK_Return ) {
135 + selectsearch_mode ^= 2;
136 + set_notifmode(selectsearch_mode, -2);
137 + if ( ksym == XK_Escape ) ptarget = 0;
138 + return 0;
139 + }
140 + else if ( ksym == XK_BackSpace ) {
141 + if ( !ptarget ) return 0;
142 + term.line[term.bot][ptarget--].u = ' ';
143 + }
144 + else if ( len < 1 ) {
145 + return 0;
146 + }
147 + else if ( ptarget == term.col || ksym == XK_Escape ) {
148 + return 0;
149 + }
150 + else {
151 + utf8decode(buf, &target[ptarget++], len);
152 + term.line[term.bot][ptarget].u = target[ptarget - 1];
153 + }
154 +
155 + if ( ksym != XK_BackSpace )
156 + search(selectsearch_mode, &target[0], ptarget, sens, type, &cu);
157 +
158 + term.dirty[term.bot] = 1;
159 + drawregion(0, term.bot, term.col, term.bot + 1);
160 + return 0;
161 + }
162 +
163 + switch ( ksym ) {
164 + case -1 :
165 + in_use = 1;
166 + cu.x = term.c.x, cu.y = term.c.y;
167 + set_notifmode(0, ksym);
168 + return MODE_KBDSELECT;
169 + case XK_s :
170 + if ( selectsearch_mode & 1 )
171 + selclear();
172 + else
173 + selstart(term.c.x, term.c.y, 0);
174 + set_notifmode(selectsearch_mode ^= 1, ksym);
175 + break;
176 + case XK_t :
177 + selextend(term.c.x, term.c.y, type ^= 3, i = 0); /* 2 fois */
178 + selextend(term.c.x, term.c.y, type, i = 0);
179 + break;
180 + case XK_slash :
181 + case XK_KP_Divide :
182 + case XK_question :
183 + ksym &= XK_question; /* Divide to slash */
184 + sens = (ksym == XK_slash) ? -1 : 1;
185 + ptarget = 0;
186 + set_notifmode(15, ksym);
187 + selectsearch_mode ^= 2;
188 + break;
189 + case XK_Escape :
190 + if ( !in_use ) break;
191 + selclear();
192 + case XK_Return :
193 + set_notifmode(4, ksym);
194 + term.c.x = cu.x, term.c.y = cu.y;
195 + select_or_drawcursor(selectsearch_mode = 0, type);
196 + in_use = quant = 0;
197 + return MODE_KBDSELECT;
198 + case XK_n :
199 + case XK_N :
200 + if ( ptarget )
201 + search(selectsearch_mode, &target[0], ptarget, (ksym == XK_n) ? -1 : 1, type, &cu);
202 + break;
203 + case XK_BackSpace :
204 + term.c.x = 0;
205 + select_or_drawcursor(selectsearch_mode, type);
206 + break;
207 + case XK_dollar :
208 + term.c.x = term.col - 1;
209 + select_or_drawcursor(selectsearch_mode, type);
210 + break;
211 + case XK_Home :
212 + term.c.x = 0, term.c.y = 0;
213 + select_or_drawcursor(selectsearch_mode, type);
214 + break;
215 + case XK_End :
216 + term.c.x = cu.x, term.c.y = cu.y;
217 + select_or_drawcursor(selectsearch_mode, type);
218 + break;
219 + case XK_Page_Up :
220 + case XK_Page_Down :
221 + term.c.y = (ksym == XK_Prior ) ? 0 : cu.y;
222 + select_or_drawcursor(selectsearch_mode, type);
223 + break;
224 + case XK_exclam :
225 + term.c.x = term.col >> 1;
226 + select_or_drawcursor(selectsearch_mode, type);
227 + break;
228 + case XK_asterisk :
229 + case XK_KP_Multiply :
230 + term.c.x = term.col >> 1;
231 + case XK_underscore :
232 + term.c.y = cu.y >> 1;
233 + select_or_drawcursor(selectsearch_mode, type);
234 + break;
235 + default :
236 + if ( ksym >= XK_0 && ksym <= XK_9 ) { /* 0-9 keyboard */
237 + quant = (quant * 10) + (ksym ^ XK_0);
238 + return 0;
239 + }
240 + else if ( ksym >= XK_KP_0 && ksym <= XK_KP_9 ) { /* 0-9 numpad */
241 + quant = (quant * 10) + (ksym ^ XK_KP_0);
242 + return 0;
243 + }
244 + else if ( ksym == XK_k || ksym == XK_h )
245 + i = ksym & 1;
246 + else if ( ksym == XK_l || ksym == XK_j )
247 + i = ((ksym & 6) | 4) >> 1;
248 + else if ( (XK_Home & ksym) != XK_Home || (i = (ksym ^ XK_Home) - 1) > 3 )
249 + break;
250 +
251 + xy = (i & 1) ? &term.c.y : &term.c.x;
252 + sens = (i & 2) ? 1 : -1;
253 + bound = (i >> 1 ^ 1) ? 0 : (i ^ 3) ? term.col - 1 : term.bot;
254 +
255 + if ( quant == 0 )
256 + quant++;
257 +
258 + if ( *xy == bound && ((sens < 0 && bound == 0) || (sens > 0 && bound > 0)) )
259 + break;
260 +
261 + *xy += quant * sens;
262 + if ( *xy < 0 || ( bound > 0 && *xy > bound) )
263 + *xy = bound;
264 +
265 + select_or_drawcursor(selectsearch_mode, type);
266 + }
267 + quant = 0;
268 + return 0;
269 +}
270 diff --git a/st.h b/st.h
271 index 4da3051..22125e4 100644
272 --- a/st.h
273 +++ b/st.h
274 @@ -109,6 +109,7 @@ size_t utf8encode(Rune, char *);
275 void *xmalloc(size_t);
276 void *xrealloc(void *, size_t);
277 char *xstrdup(char *);
278 +int trt_kbdselect(KeySym, char *, int);
279
280 /* config.h globals */
281 extern char *utmp;
282 diff --git a/win.h b/win.h
283 index a6ef1b9..a240783 100644
284 --- a/win.h
285 +++ b/win.h
286 @@ -21,6 +21,7 @@ enum win_mode {
287 MODE_NUMLOCK = 1 << 17,
288 MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\
289 |MODE_MOUSEMANY,
290 + MODE_KBDSELECT = 1 << 18,
291 };
292
293 void xbell(void);
294 @@ -36,4 +37,6 @@ void xsetmode(int, unsigned int);
295 void xsetpointermotion(int);
296 void xsetsel(char *);
297 int xstartdraw(void);
298 +void toggle_winmode(int);
299 +void keyboard_select(const Arg *);
300 void xximspot(int, int);
301 diff --git a/x.c b/x.c
302 index 5828a3b..5221641 100644
303 --- a/x.c
304 +++ b/x.c
305 @@ -1731,6 +1731,13 @@ kpress(XEvent *ev)
306 return;
307
308 len = XmbLookupString(xw.xic, e, buf, sizeof buf, &ksym, &status);
309 + if ( IS_SET(MODE_KBDSELECT) ) {
310 + if ( match(XK_NO_MOD, e->state) ||
311 + (XK_Shift_L | XK_Shift_R) & e->state )
312 + win.mode ^= trt_kbdselect(ksym, buf, len);
313 + return;
314 + }
315 +
316 /* 1. shortcuts */
317 for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
318 if (ksym == bp->keysym && match(bp->mod, e->state)) {
319 @@ -1914,6 +1921,14 @@ usage(void)
320 " [stty_args ...]\n", argv0, argv0);
321 }
322
323 +void toggle_winmode(int flag) {
324 + win.mode ^= flag;
325 +}
326 +
327 +void keyboard_select(const Arg *dummy) {
328 + win.mode ^= trt_kbdselect(-1, NULL, 0);
329 +}
330 +
331 int
332 main(int argc, char *argv[])
333 {
334 --
335 2.17.1
336