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