X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=st.c;h=b9f66e71163f0707bb477f9fa5346f5dad27683d;hb=HEAD;hp=34c27adf3f755bd60cc6b45f1c34af8bb48c98bb;hpb=7e8050cc621f27002eaf1be8114dee2497beff91;p=st.git diff --git a/st.c b/st.c index 34c27ad..db0fee4 100644 --- a/st.c +++ b/st.c @@ -4,11 +4,12 @@ #include #include #include +#include #include +#include #include #include #include -#include #include #include #include @@ -339,10 +340,31 @@ utf8encodebyte(Rune u, size_t i) return utfbyte[i] | (u & ~utfmask[i]); } +// ./list-emojis emojis.c.in +#include "emojis.c.in" + +static int +uint32comparator(const void *a, const void *b) +{ + return *(uint32_t *)a - *(uint32_t *)b; +} + +int +isEmoji(const Rune u) +{ + const uint32_t want = (uint32_t)u; + return bsearch( + &want, + emojis, + (sizeof emojis)/sizeof(uint32_t), + sizeof(uint32_t), + uint32comparator) != NULL; +} + size_t utf8validate(Rune *u, size_t i) { - if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) + if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF) || isEmoji(*u)) *u = UTF_INVALID; for (i = 1; *u > utfmax[i]; ++i) ; @@ -1097,7 +1119,7 @@ tscrollup(int orig, int n) void selscroll(int orig, int n) { - if (sel.ob.x == -1) + if (sel.ob.x == -1 || sel.alt != IS_SET(MODE_ALTSCREEN)) return; if (BETWEEN(sel.nb.y, orig, term.bot) != BETWEEN(sel.ne.y, orig, term.bot)) { @@ -1132,6 +1154,7 @@ csiparse(void) { char *p = csiescseq.buf, *np; long int v; + int sep = ';'; /* colon or semi-colon, but not both */ csiescseq.narg = 0; if (*p == '?') { @@ -1149,7 +1172,9 @@ csiparse(void) v = -1; csiescseq.arg[csiescseq.narg++] = v; p = np; - if (*p != ';' || csiescseq.narg == ESC_ARG_SIZ) + if (sep == ';' && *p == ':') + sep = ':'; /* allow override to colon once */ + if (*p != sep || csiescseq.narg == ESC_ARG_SIZ) break; p++; } @@ -1643,7 +1668,7 @@ csihandle(void) ttywrite(vtiden, strlen(vtiden), 0); break; case 'b': /* REP -- if last char is printable print it more times */ - DEFAULT(csiescseq.arg[0], 1); + LIMIT(csiescseq.arg[0], 1, 65535); if (term.lastc) while (csiescseq.arg[0]-- > 0) tputc(term.lastc); @@ -1702,7 +1727,7 @@ csihandle(void) } break; case 1: /* above */ - if (term.c.y > 1) + if (term.c.y > 0) tclearregion(0, 0, term.col-1, term.c.y-1); tclearregion(0, term.c.y, term.c.x, term.c.y); break; @@ -1728,6 +1753,7 @@ csihandle(void) } break; case 'S': /* SU -- Scroll line up */ + if (csiescseq.priv) break; DEFAULT(csiescseq.arg[0], 1); tscrollup(term.top, csiescseq.arg[0]); break; @@ -1769,11 +1795,18 @@ csihandle(void) case 'm': /* SGR -- Terminal attribute (color) */ tsetattr(csiescseq.arg, csiescseq.narg); break; - case 'n': /* DSR – Device Status Report (cursor position) */ - if (csiescseq.arg[0] == 6) { + case 'n': /* DSR -- Device Status Report */ + switch (csiescseq.arg[0]) { + case 5: /* Status Report "OK" `0n` */ + ttywrite("\033[0n", sizeof("\033[0n") - 1, 0); + break; + case 6: /* Report Cursor Position (CPR) ";R" */ len = snprintf(buf, sizeof(buf), "\033[%i;%iR", - term.c.y+1, term.c.x+1); + term.c.y+1, term.c.x+1); ttywrite(buf, len, 0); + break; + default: + goto unknown; } break; case 'r': /* DECSTBM -- Set Scrolling Region */ @@ -1790,7 +1823,11 @@ csihandle(void) tcursor(CURSOR_SAVE); break; case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */ - tcursor(CURSOR_LOAD); + if (csiescseq.priv) { + goto unknown; + } else { + tcursor(CURSOR_LOAD); + } break; case ' ': switch (csiescseq.mode[1]) { @@ -2323,6 +2360,7 @@ eschandle(uchar ascii) treset(); resettitle(); xloadcols(); + xsetmode(0, MODE_HIDE); break; case '=': /* DECPAM -- Application keypad */ xsetmode(1, MODE_APPKEYPAD); @@ -2415,6 +2453,9 @@ check_control_code: * they must not cause conflicts with sequences. */ if (control) { + /* in UTF-8 mode ignore handling C1 control characters */ + if (IS_SET(MODE_UTF8) && ISCONTROLC1(u)) + return; tcontrolcode(u); /* * control codes are not shown ever @@ -2461,11 +2502,16 @@ check_control_code: gp = &term.line[term.c.y][term.c.x]; } - if (IS_SET(MODE_INSERT) && term.c.x+width < term.col) + if (IS_SET(MODE_INSERT) && term.c.x+width < term.col) { memmove(gp+width, gp, (term.col - term.c.x - width) * sizeof(Glyph)); + gp->mode &= ~ATTR_WIDE; + } if (term.c.x+width > term.col) { - tnewline(1); + if (IS_SET(MODE_WRAP)) + tnewline(1); + else + tmoveto(term.col - width, term.c.y); gp = &term.line[term.c.y][term.c.x]; }