diff -r 704261718508 st.c --- a/st.c Thu Oct 06 21:32:34 2011 +0200 +++ b/st.c Tue Oct 18 12:20:03 2011 +0200 @@ -208,6 +208,7 @@ static void ttyread(void); static void ttyresize(int, int); static void ttywrite(const char *, size_t); +static void ttyprintf(const char *, ...); static void xdraws(char *, Glyph, int, int, int, int); static void xhints(void); @@ -733,10 +734,27 @@ void ttywrite(const char *s, size_t n) { - if(write(cmdfd, s, n) == -1) + if(write(cmdfd, s, n) < 0) die("write error on tty: %s\n", SERRNO); } +/* tty helper: slow, use it for non-frequent small stuff */ +void +ttyprintf(const char *f, ...) { + char buf[1024]; + va_list ap; + int n = 0; + + va_start(ap, f); + n = vsnprintf(buf, sizeof(buf), f, ap); + va_end(ap); + + if(n < 0 || n >= sizeof(buf)) + die("ttyprintf: vnsprintf failed (%d/%d)", n, sizeof(buf)); + + ttywrite(buf, strlen(buf)); +} + void ttyresize(int x, int y) { struct winsize w; @@ -1890,8 +1908,10 @@ int len; int meta; int shift; + int ctrl; Status status; + ctrl = e->state & ControlMask; meta = e->state & Mod1Mask; shift = e->state & ShiftMask; len = XmbLookupString(xw.xic, e, buf, sizeof(buf), &ksym, &status); @@ -1905,11 +1925,21 @@ case XK_Up: case XK_Down: case XK_Left: - case XK_Right: - /* XXX: shift up/down doesn't work */ - sprintf(buf, "\033%c%c", IS_SET(MODE_APPKEYPAD) ? 'O' : '[', (shift ? "dacb":"DACB")[ksym - XK_Left]); - ttywrite(buf, 3); + case XK_Right: { + char cursor = "DACB"[ksym - XK_Left]; + char mode = IS_SET(MODE_APPKEYPAD) ? 'O' : '['; + int n = 1; + + if(shift) n += 1; + if(meta) n += 2; + if(ctrl) n += 4; + + if(n > 1) + ttyprintf("\033%c1;%d%c", mode, n, cursor); + else + ttyprintf("\033%c%c", mode, cursor); break; + } case XK_Insert: if(shift) selpaste();