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