]> Sergey Matveev's repositories - st.git/blobdiff - st.c
My config
[st.git] / st.c
diff --git a/st.c b/st.c
index 683493d3aa66fc346eb0eadc1c6e8f8bdd08dac8..db0fee4ca963c923f2c6b756b209a26feed0ffbc 100644 (file)
--- a/st.c
+++ b/st.c
@@ -4,11 +4,12 @@
 #include <fcntl.h>
 #include <limits.h>
 #include <pwd.h>
+#include <signal.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <signal.h>
 #include <sys/ioctl.h>
 #include <sys/select.h>
 #include <sys/types.h>
@@ -86,8 +87,8 @@ enum escape_state {
 
 typedef struct {
        Glyph attr; /* current char attributes */
-       int x; /* terminal column */
-       int y; /* terminal row */
+       int x;
+       int y;
        char state;
 } TCursor;
 
@@ -339,10 +340,31 @@ utf8encodebyte(Rune u, size_t i)
        return utfbyte[i] | (u & ~utfmask[i]);
 }
 
+// ./list-emojis <libgrapheme/data/emoji-data.txt >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)
                ;
@@ -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++;
        }
@@ -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;
@@ -1798,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]) {
@@ -2175,16 +2204,12 @@ tstrsequence(uchar c)
 void
 tcontrolcode(uchar ascii)
 {
-       size_t i;
-
        switch (ascii) {
        case '\t':   /* HT */
                tputtab(1);
                return;
        case '\b':   /* BS */
-               for (i = 1; term.c.x && term.line[term.c.y][term.c.x - i].u == 0; ++i)
-                       ;
-               tmoveto(term.c.x - i, term.c.y);
+               tmoveto(term.c.x-1, term.c.y);
                return;
        case '\r':   /* CR */
                tmoveto(0, term.c.y);