aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAurélien Aptel <aurelien.aptel@gmail.com>2011-04-22 00:18:53 +0200
committerAurélien Aptel <aurelien.aptel@gmail.com>2011-04-22 00:18:53 +0200
commite4dd367a4f0f07d5e721adf97f882642e520f1ca (patch)
tree6665171645be9750ffcc409613887911c0e2ceaf
parent043fb982c5d4402c7635544753c0e59547f45277 (diff)
downloadst-patched-e4dd367a4f0f07d5e721adf97f882642e520f1ca.tar.bz2
st-patched-e4dd367a4f0f07d5e721adf97f882642e520f1ca.tar.xz
st-patched-e4dd367a4f0f07d5e721adf97f882642e520f1ca.zip
selection clicks, shift+arrow keys, fast(er) redraw, key mask in config.h (thx Magnus Leuthner)
-rw-r--r--config.def.h47
-rw-r--r--st.c136
-rw-r--r--st.info4
3 files changed, 126 insertions, 61 deletions
diff --git a/config.def.h b/config.def.h
index ced3000..c1afd88 100644
--- a/config.def.h
+++ b/config.def.h
@@ -26,32 +26,33 @@ static const char *colorname[] = {
26}; 26};
27 27
28/* Default colors (colorname index) */ 28/* Default colors (colorname index) */
29/* foreground, background, cursor */ 29/* foreground, background, cursor */
30#define DefaultFG 7 30#define DefaultFG 7
31#define DefaultBG 0 31#define DefaultBG 0
32#define DefaultCS 1 32#define DefaultCS 1
33 33
34/* Special keys */ 34/* Special keys (change & recompile st.info accordingly) */
35/* key, mask, output */
35static Key key[] = { 36static Key key[] = {
36 { XK_BackSpace, "\177" }, 37 { XK_BackSpace, 0, "\177" },
37 { XK_Insert, "\033[2~" }, 38 { XK_Insert, 0, "\033[2~" },
38 { XK_Delete, "\033[3~" }, 39 { XK_Delete, 0, "\033[3~" },
39 { XK_Home, "\033[1~" }, 40 { XK_Home, 0, "\033[1~" },
40 { XK_End, "\033[4~" }, 41 { XK_End, 0, "\033[4~" },
41 { XK_Prior, "\033[5~" }, 42 { XK_Prior, 0, "\033[5~" },
42 { XK_Next, "\033[6~" }, 43 { XK_Next, 0, "\033[6~" },
43 { XK_F1, "\033OP" }, 44 { XK_F1, 0, "\033OP" },
44 { XK_F2, "\033OQ" }, 45 { XK_F2, 0, "\033OQ" },
45 { XK_F3, "\033OR" }, 46 { XK_F3, 0, "\033OR" },
46 { XK_F4, "\033OS" }, 47 { XK_F4, 0, "\033OS" },
47 { XK_F5, "\033[15~" }, 48 { XK_F5, 0, "\033[15~" },
48 { XK_F6, "\033[17~" }, 49 { XK_F6, 0, "\033[17~" },
49 { XK_F7, "\033[18~" }, 50 { XK_F7, 0, "\033[18~" },
50 { XK_F8, "\033[19~" }, 51 { XK_F8, 0, "\033[19~" },
51 { XK_F9, "\033[20~" }, 52 { XK_F9, 0, "\033[20~" },
52 { XK_F10, "\033[21~" }, 53 { XK_F10, 0, "\033[21~" },
53 { XK_F11, "\033[23~" }, 54 { XK_F11, 0, "\033[23~" },
54 { XK_F12, "\033[24~" }, 55 { XK_F12, 0, "\033[24~" },
55}; 56};
56 57
57/* Line drawing characters (sometime specific to each font...) */ 58/* Line drawing characters (sometime specific to each font...) */
@@ -61,3 +62,7 @@ static char gfx[] = {
61 ['i'] = '#', 62 ['i'] = '#',
62 [255] = 0, 63 [255] = 0,
63}; 64};
65
66/* double-click timeout (in milliseconds) between clicks for selection */
67#define DOUBLECLICK_TIMEOUT 300
68#define TRIPLECLICK_TIMEOUT (2*DOUBLECLICK_TIMEOUT)
diff --git a/st.c b/st.c
index a6fb766..11ea9fc 100644
--- a/st.c
+++ b/st.c
@@ -22,6 +22,9 @@
22#include <X11/cursorfont.h> 22#include <X11/cursorfont.h>
23#include <X11/keysym.h> 23#include <X11/keysym.h>
24 24
25#include <sys/time.h>
26#include <time.h>
27
25#if defined(__linux) 28#if defined(__linux)
26 #include <pty.h> 29 #include <pty.h>
27#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) 30#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
@@ -45,11 +48,12 @@
45#define MIN(a, b) ((a) < (b) ? (a) : (b)) 48#define MIN(a, b) ((a) < (b) ? (a) : (b))
46#define MAX(a, b) ((a) < (b) ? (b) : (a)) 49#define MAX(a, b) ((a) < (b) ? (b) : (a))
47#define LEN(a) (sizeof(a) / sizeof(a[0])) 50#define LEN(a) (sizeof(a) / sizeof(a[0]))
48#define DEFAULT(a, b) (a) = (a) ? (a) : (b) 51#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
49#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) 52#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b))
50#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) 53#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
51#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg) 54#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg)
52#define IS_SET(flag) (term.mode & (flag)) 55#define IS_SET(flag) (term.mode & (flag))
56#define TIMEDIFFERENCE(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + (t1.tv_usec-t2.tv_usec)/1000)
53 57
54/* Attribute, Cursor, Character state, Terminal mode, Screen draw mode */ 58/* Attribute, Cursor, Character state, Terminal mode, Screen draw mode */
55enum { ATTR_NULL=0 , ATTR_REVERSE=1 , ATTR_UNDERLINE=2, ATTR_BOLD=4, ATTR_GFX=8 }; 59enum { ATTR_NULL=0 , ATTR_REVERSE=1 , ATTR_UNDERLINE=2, ATTR_BOLD=4, ATTR_GFX=8 };
@@ -57,10 +61,9 @@ enum { CURSOR_UP, CURSOR_DOWN, CURSOR_LEFT, CURSOR_RIGHT,
57 CURSOR_SAVE, CURSOR_LOAD }; 61 CURSOR_SAVE, CURSOR_LOAD };
58enum { CURSOR_DEFAULT = 0, CURSOR_HIDE = 1, CURSOR_WRAPNEXT = 2 }; 62enum { CURSOR_DEFAULT = 0, CURSOR_HIDE = 1, CURSOR_WRAPNEXT = 2 };
59enum { GLYPH_SET=1, GLYPH_DIRTY=2 }; 63enum { GLYPH_SET=1, GLYPH_DIRTY=2 };
60enum { MODE_WRAP=1, MODE_INSERT=2, MODE_APPKEYPAD=4, MODE_ALTSCREEN=8, 64enum { MODE_WRAP=1, MODE_INSERT=2, MODE_APPKEYPAD=4, MODE_ALTSCREEN=8,
61 MODE_CRLF=16 }; 65 MODE_CRLF=16 };
62enum { ESC_START=1, ESC_CSI=2, ESC_OSC=4, ESC_TITLE=8, ESC_ALTCHARSET=16 }; 66enum { ESC_START=1, ESC_CSI=2, ESC_OSC=4, ESC_TITLE=8, ESC_ALTCHARSET=16 };
63enum { SCREEN_UPDATE, SCREEN_REDRAW };
64enum { WIN_VISIBLE=1, WIN_REDRAW=2, WIN_FOCUSED=4 }; 67enum { WIN_VISIBLE=1, WIN_REDRAW=2, WIN_FOCUSED=4 };
65 68
66#undef B0 69#undef B0
@@ -87,21 +90,21 @@ typedef struct {
87/* ESC '[' [[ [<priv>] <arg> [;]] <mode>] */ 90/* ESC '[' [[ [<priv>] <arg> [;]] <mode>] */
88typedef struct { 91typedef struct {
89 char buf[ESC_BUF_SIZ]; /* raw string */ 92 char buf[ESC_BUF_SIZ]; /* raw string */
90 int len; /* raw string length */ 93 int len; /* raw string length */
91 char priv; 94 char priv;
92 int arg[ESC_ARG_SIZ]; 95 int arg[ESC_ARG_SIZ];
93 int narg; /* nb of args */ 96 int narg; /* nb of args */
94 char mode; 97 char mode;
95} CSIEscape; 98} CSIEscape;
96 99
97/* Internal representation of the screen */ 100/* Internal representation of the screen */
98typedef struct { 101typedef struct {
99 int row; /* nb row */ 102 int row; /* nb row */
100 int col; /* nb col */ 103 int col; /* nb col */
101 Line* line; /* screen */ 104 Line* line; /* screen */
102 Line* alt; /* alternate screen */ 105 Line* alt; /* alternate screen */
103 TCursor c; /* cursor */ 106 TCursor c; /* cursor */
104 int top; /* top scroll limit */ 107 int top; /* top scroll limit */
105 int bot; /* bottom scroll limit */ 108 int bot; /* bottom scroll limit */
106 int mode; /* terminal mode flags */ 109 int mode; /* terminal mode flags */
107 int esc; /* escape state flags */ 110 int esc; /* escape state flags */
@@ -118,17 +121,18 @@ typedef struct {
118 XIM xim; 121 XIM xim;
119 XIC xic; 122 XIC xic;
120 int scr; 123 int scr;
121 int w; /* window width */ 124 int w; /* window width */
122 int h; /* window height */ 125 int h; /* window height */
123 int bufw; /* pixmap width */ 126 int bufw; /* pixmap width */
124 int bufh; /* pixmap height */ 127 int bufh; /* pixmap height */
125 int ch; /* char height */ 128 int ch; /* char height */
126 int cw; /* char width */ 129 int cw; /* char width */
127 char state; /* focus, redraw, visible */ 130 char state; /* focus, redraw, visible */
128} XWindow; 131} XWindow;
129 132
130typedef struct { 133typedef struct {
131 KeySym k; 134 KeySym k;
135 unsigned int mask;
132 char s[ESC_BUF_SIZ]; 136 char s[ESC_BUF_SIZ];
133} Key; 137} Key;
134 138
@@ -150,15 +154,18 @@ typedef struct {
150 int mode; 154 int mode;
151 int bx, by; 155 int bx, by;
152 int ex, ey; 156 int ex, ey;
153 struct {int x, y;} b, e; 157 struct {int x, y;} b, e;
154 char *clip; 158 char *clip;
155 Atom xtarget; 159 Atom xtarget;
160 struct timeval tclick1;
161 struct timeval tclick2;
156} Selection; 162} Selection;
157 163
158#include "config.h" 164#include "config.h"
159 165
160static void die(const char *errstr, ...); 166static void die(const char *errstr, ...);
161static void draw(int); 167static void draw();
168static void drawregion(int, int, int, int);
162static void execsh(void); 169static void execsh(void);
163static void sigchld(int); 170static void sigchld(int);
164static void run(void); 171static void run(void);
@@ -206,7 +213,7 @@ static void xresize(int, int);
206static void expose(XEvent *); 213static void expose(XEvent *);
207static void visibility(XEvent *); 214static void visibility(XEvent *);
208static void unmap(XEvent *); 215static void unmap(XEvent *);
209static char* kmap(KeySym); 216static char* kmap(KeySym, unsigned int state);
210static void kpress(XEvent *); 217static void kpress(XEvent *);
211static void resize(XEvent *); 218static void resize(XEvent *);
212static void focus(XEvent *); 219static void focus(XEvent *);
@@ -219,7 +226,7 @@ static void selrequest(XEvent *);
219static void selinit(void); 226static void selinit(void);
220static inline int selected(int, int); 227static inline int selected(int, int);
221static void selcopy(void); 228static void selcopy(void);
222static void selpaste(void); 229static void selpaste();
223 230
224static int utf8decode(char *, long *); 231static int utf8decode(char *, long *);
225static int utf8encode(long *, char *); 232static int utf8encode(long *, char *);
@@ -340,7 +347,7 @@ isfullutf8(char *s, int b) {
340 else if((*c1&(B7|B6|B5)) == (B7|B6) && b == 1) 347 else if((*c1&(B7|B6|B5)) == (B7|B6) && b == 1)
341 return 0; 348 return 0;
342 else if((*c1&(B7|B6|B5|B4)) == (B7|B6|B5) && 349 else if((*c1&(B7|B6|B5|B4)) == (B7|B6|B5) &&
343 ((b == 1) || 350 ((b == 1) ||
344 ((b == 2) && (*c2&(B7|B6)) == B7))) 351 ((b == 2) && (*c2&(B7|B6)) == B7)))
345 return 0; 352 return 0;
346 else if((*c1&(B7|B6|B5|B4|B3)) == (B7|B6|B5|B4) && 353 else if((*c1&(B7|B6|B5|B4|B3)) == (B7|B6|B5|B4) &&
@@ -362,12 +369,14 @@ utf8size(char *s) {
362 return 2; 369 return 2;
363 else if ((c&(B7|B6|B5|B4)) == (B7|B6|B5)) 370 else if ((c&(B7|B6|B5|B4)) == (B7|B6|B5))
364 return 3; 371 return 3;
365 else 372 else
366 return 4; 373 return 4;
367} 374}
368 375
369void 376void
370selinit(void) { 377selinit(void) {
378 sel.tclick1.tv_sec = 0;
379 sel.tclick1.tv_usec = 0;
371 sel.mode = 0; 380 sel.mode = 0;
372 sel.bx = -1; 381 sel.bx = -1;
373 sel.clip = NULL; 382 sel.clip = NULL;
@@ -376,14 +385,14 @@ selinit(void) {
376 sel.xtarget = XA_STRING; 385 sel.xtarget = XA_STRING;
377} 386}
378 387
379static inline int 388static inline int
380selected(int x, int y) { 389selected(int x, int y) {
381 if(sel.ey == y && sel.by == y) { 390 if(sel.ey == y && sel.by == y) {
382 int bx = MIN(sel.bx, sel.ex); 391 int bx = MIN(sel.bx, sel.ex);
383 int ex = MAX(sel.bx, sel.ex); 392 int ex = MAX(sel.bx, sel.ex);
384 return BETWEEN(x, bx, ex); 393 return BETWEEN(x, bx, ex);
385 } 394 }
386 return ((sel.b.y < y&&y < sel.e.y) || (y==sel.e.y && x<=sel.e.x)) 395 return ((sel.b.y < y&&y < sel.e.y) || (y==sel.e.y && x<=sel.e.x))
387 || (y==sel.b.y && x>=sel.b.x && (x<=sel.e.x || sel.b.y!=sel.e.y)); 396 || (y==sel.b.y && x>=sel.b.x && (x<=sel.e.x || sel.b.y!=sel.e.y));
388} 397}
389 398
@@ -511,30 +520,63 @@ xsetsel(char *str) {
511 XFlush(xw.dpy); 520 XFlush(xw.dpy);
512} 521}
513 522
514/* TODO: doubleclick to select word */
515void 523void
516brelease(XEvent *e) { 524brelease(XEvent *e) {
517 int b; 525 int b;
518 sel.mode = 0; 526 sel.mode = 0;
519 getbuttoninfo(e, &b, &sel.ex, &sel.ey); 527 getbuttoninfo(e, &b, &sel.ex, &sel.ey);
520 if(sel.bx==sel.ex && sel.by==sel.ey) { 528
529 if(sel.bx == sel.ex && sel.by == sel.ey) {
521 sel.bx = -1; 530 sel.bx = -1;
522 if(b==2) 531 if(b == 2)
523 selpaste(); 532 selpaste();
533
534 else if(b == 1) {
535 /* double click to select word */
536 struct timeval now;
537 gettimeofday(&now, NULL);
538
539 if(TIMEDIFFERENCE(now, sel.tclick1) <= DOUBLECLICK_TIMEOUT) {
540 sel.bx = sel.ex;
541 while(term.line[sel.ey][sel.bx-1].state & GLYPH_SET &&
542 term.line[sel.ey][sel.bx-1].c[0] != ' ') sel.bx--;
543 sel.b.x = sel.bx;
544 while(term.line[sel.ey][sel.ex+1].state & GLYPH_SET &&
545 term.line[sel.ey][sel.ex+1].c[0] != ' ') sel.ex++;
546 sel.e.x = sel.ex;
547 sel.b.y = sel.e.y = sel.ey;
548 selcopy();
549 }
550
551 /* triple click on the line */
552 if(TIMEDIFFERENCE(now, sel.tclick2) <= TRIPLECLICK_TIMEOUT) {
553 sel.b.x = sel.bx = 0;
554 sel.e.x = sel.ex = term.col;
555 sel.b.y = sel.e.y = sel.ey;
556 selcopy();
557 }
558 }
524 } else { 559 } else {
525 if(b==1) 560 if(b == 1)
526 selcopy(); 561 selcopy();
527 } 562 }
528 draw(1); 563 memcpy(&sel.tclick2, &sel.tclick1, sizeof(struct timeval));
564 gettimeofday(&sel.tclick1, NULL);
565 draw();
529} 566}
530 567
531void 568void
532bmotion(XEvent *e) { 569bmotion(XEvent *e) {
533 if (sel.mode) { 570 if(sel.mode) {
571 int oldey = sel.ey,
572 oldex = sel.ex;
534 getbuttoninfo(e, NULL, &sel.ex, &sel.ey); 573 getbuttoninfo(e, NULL, &sel.ex, &sel.ey);
535 /* XXX: draw() can't keep up, disabled for now. 574
536 selection is visible on button release. 575 if(oldey != sel.ey || oldex != sel.ex) {
537 draw(1); */ 576 int starty = MIN(oldey, sel.ey);
577 int endy = MAX(oldey, sel.ey);
578 drawregion(0, (starty > 0 ? starty : 0), term.col, (sel.ey < term.row ? endy+1 : term.row));
579 }
538 } 580 }
539} 581}
540 582
@@ -641,6 +683,10 @@ ttyread(void) {
641 683
642void 684void
643ttywrite(const char *s, size_t n) { 685ttywrite(const char *s, size_t n) {
686 {size_t nn;
687 for(nn = 0; nn < n; nn++)
688 dump(s[nn]);
689 }
644 if(write(cmdfd, s, n) == -1) 690 if(write(cmdfd, s, n) == -1)
645 die("write error on tty: %s\n", SERRNO); 691 die("write error on tty: %s\n", SERRNO);
646} 692}
@@ -1640,8 +1686,13 @@ xdrawc(int x, int y, Glyph g) {
1640 dc.gc, r.x, r.y+dc.font.ascent, g.c, sl); 1686 dc.gc, r.x, r.y+dc.font.ascent, g.c, sl);
1641} 1687}
1642 1688
1689void
1690drawregion(int x0, int x1, int y0, int y1) {
1691 draw();
1692}
1693
1643void 1694void
1644draw(int dummy) { 1695draw() {
1645 int x, y; 1696 int x, y;
1646 1697
1647 xclear(0, 0, term.col-1, term.row-1); 1698 xclear(0, 0, term.col-1, term.row-1);
@@ -1657,8 +1708,13 @@ draw(int dummy) {
1657 1708
1658#else 1709#else
1659/* optimized drawing routine */ 1710/* optimized drawing routine */
1711void
1712draw() {
1713 drawregion(0, 0, term.col, term.row);
1714}
1715
1660void 1716void
1661draw(int redraw_all) { 1717drawregion(int x1, int y1, int x2, int y2) {
1662 int ic, ib, x, y, ox, sl; 1718 int ic, ib, x, y, ox, sl;
1663 Glyph base, new; 1719 Glyph base, new;
1664 char buf[DRAW_BUF_SIZ]; 1720 char buf[DRAW_BUF_SIZ];
@@ -1666,13 +1722,13 @@ draw(int redraw_all) {
1666 if(!(xw.state & WIN_VISIBLE)) 1722 if(!(xw.state & WIN_VISIBLE))
1667 return; 1723 return;
1668 1724
1669 xclear(0, 0, term.col-1, term.row-1); 1725 xclear(x1, y1, x2-1, y2-1);
1670 for(y = 0; y < term.row; y++) { 1726 for(y = y1; y < y2; y++) {
1671 base = term.line[y][0]; 1727 base = term.line[y][0];
1672 ic = ib = ox = 0; 1728 ic = ib = ox = 0;
1673 for(x = 0; x < term.col; x++) { 1729 for(x = x1; x < x2; x++) {
1674 new = term.line[y][x]; 1730 new = term.line[y][x];
1675 if(sel.bx!=-1 && *(new.c) && selected(x, y)) 1731 if(sel.bx != -1 && *(new.c) && selected(x, y))
1676 new.mode ^= ATTR_REVERSE; 1732 new.mode ^= ATTR_REVERSE;
1677 if(ib > 0 && (!(new.state & GLYPH_SET) || ATTRCMP(base, new) || 1733 if(ib > 0 && (!(new.state & GLYPH_SET) || ATTRCMP(base, new) ||
1678 ib >= DRAW_BUF_SIZ-UTF_SIZ)) { 1734 ib >= DRAW_BUF_SIZ-UTF_SIZ)) {
@@ -1705,7 +1761,7 @@ expose(XEvent *ev) {
1705 if(xw.state & WIN_REDRAW) { 1761 if(xw.state & WIN_REDRAW) {
1706 if(!e->count) { 1762 if(!e->count) {
1707 xw.state &= ~WIN_REDRAW; 1763 xw.state &= ~WIN_REDRAW;
1708 draw(SCREEN_REDRAW); 1764 draw();
1709 } 1765 }
1710 } else 1766 } else
1711 XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, e->x-BORDER, e->y-BORDER, 1767 XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, e->x-BORDER, e->y-BORDER,
@@ -1742,14 +1798,14 @@ focus(XEvent *ev) {
1742 xseturgency(0); 1798 xseturgency(0);
1743 } else 1799 } else
1744 xw.state &= ~WIN_FOCUSED; 1800 xw.state &= ~WIN_FOCUSED;
1745 draw(SCREEN_UPDATE); 1801 draw();
1746} 1802}
1747 1803
1748char* 1804char*
1749kmap(KeySym k) { 1805kmap(KeySym k, unsigned int state) {
1750 int i; 1806 int i;
1751 for(i = 0; i < LEN(key); i++) 1807 for(i = 0; i < LEN(key); i++)
1752 if(key[i].k == k) 1808 if(key[i].k == k && (key[i].mask == 0 || key[i].mask & state))
1753 return (char*)key[i].s; 1809 return (char*)key[i].s;
1754 return NULL; 1810 return NULL;
1755} 1811}
@@ -1770,7 +1826,7 @@ kpress(XEvent *ev) {
1770 len = XmbLookupString(xw.xic, e, buf, sizeof(buf), &ksym, &status); 1826 len = XmbLookupString(xw.xic, e, buf, sizeof(buf), &ksym, &status);
1771 1827
1772 /* 1. custom keys from config.h */ 1828 /* 1. custom keys from config.h */
1773 if((customkey = kmap(ksym))) 1829 if((customkey = kmap(ksym, e->state)))
1774 ttywrite(customkey, strlen(customkey)); 1830 ttywrite(customkey, strlen(customkey));
1775 /* 2. hardcoded (overrides X lookup) */ 1831 /* 2. hardcoded (overrides X lookup) */
1776 else 1832 else
@@ -1779,7 +1835,7 @@ kpress(XEvent *ev) {
1779 case XK_Down: 1835 case XK_Down:
1780 case XK_Left: 1836 case XK_Left:
1781 case XK_Right: 1837 case XK_Right:
1782 sprintf(buf, "\033%c%c", IS_SET(MODE_APPKEYPAD) ? 'O' : '[', "DACB"[ksym - XK_Left]); 1838 sprintf(buf, "\033%c%c", IS_SET(MODE_APPKEYPAD) ? 'O' : '[', (shift ? "dacb":"DACB")[ksym - XK_Left]);
1783 ttywrite(buf, 3); 1839 ttywrite(buf, 3);
1784 break; 1840 break;
1785 case XK_Insert: 1841 case XK_Insert:
@@ -1817,7 +1873,7 @@ resize(XEvent *e) {
1817 if(col == term.col && row == term.row) 1873 if(col == term.col && row == term.row)
1818 return; 1874 return;
1819 if(tresize(col, row)) 1875 if(tresize(col, row))
1820 draw(SCREEN_REDRAW); 1876 draw();
1821 ttyresize(col, row); 1877 ttyresize(col, row);
1822 xresize(col, row); 1878 xresize(col, row);
1823} 1879}
@@ -1839,7 +1895,7 @@ run(void) {
1839 } 1895 }
1840 if(FD_ISSET(cmdfd, &rfd)) { 1896 if(FD_ISSET(cmdfd, &rfd)) {
1841 ttyread(); 1897 ttyread();
1842 draw(SCREEN_UPDATE); 1898 draw();
1843 } 1899 }
1844 while(XPending(xw.dpy)) { 1900 while(XPending(xw.dpy)) {
1845 XNextEvent(xw.dpy, &ev); 1901 XNextEvent(xw.dpy, &ev);
diff --git a/st.info b/st.info
index 863c387..6be3eaf 100644
--- a/st.info
+++ b/st.info
@@ -49,6 +49,10 @@ st| simpleterm,
49 kcud1=\E[B, 49 kcud1=\E[B,
50 kcuf1=\E[C, 50 kcuf1=\E[C,
51 kcuu1=\E[A, 51 kcuu1=\E[A,
52 kLFT=\E[d,
53 kRIT=\E[c,
54 kind=\E[a,
55 kri=\E[b,
52 kdch1=\E[3~, 56 kdch1=\E[3~,
53 kich1=\E[2~, 57 kich1=\E[2~,
54 kend=\E[4~, 58 kend=\E[4~,