Last active
June 5, 2020 00:03
-
-
Save Sweets/736faca379d31990d3e6c2e69354a832 to your computer and use it in GitHub Desktop.
st unicode patch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 5d624a8d424dc62f881fe91793c2eaef4879fd9a Mon Sep 17 00:00:00 2001 | |
From: Sweets <redacted> | |
Date: Tue, 27 Mar 2018 20:14:41 -0500 | |
Subject: [PATCH] Unicode input support (TERMMOD+u, ctrl+shift+u by default) | |
--- | |
config.def.h | 27 +++++++------- | |
st.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- | |
st.h | 1 + | |
3 files changed, 117 insertions(+), 30 deletions(-) | |
diff --git a/config.def.h b/config.def.h | |
index 82b1b09..d792256 100644 | |
--- a/config.def.h | |
+++ b/config.def.h | |
@@ -165,19 +165,20 @@ static MouseShortcut mshortcuts[] = { | |
#define TERMMOD (ControlMask|ShiftMask) | |
static Shortcut shortcuts[] = { | |
- /* mask keysym function argument */ | |
- { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} }, | |
- { ControlMask, XK_Print, toggleprinter, {.i = 0} }, | |
- { ShiftMask, XK_Print, printscreen, {.i = 0} }, | |
- { XK_ANY_MOD, XK_Print, printsel, {.i = 0} }, | |
- { TERMMOD, XK_Prior, zoom, {.f = +1} }, | |
- { TERMMOD, XK_Next, zoom, {.f = -1} }, | |
- { TERMMOD, XK_Home, zoomreset, {.f = 0} }, | |
- { TERMMOD, XK_C, clipcopy, {.i = 0} }, | |
- { TERMMOD, XK_V, clippaste, {.i = 0} }, | |
- { TERMMOD, XK_Y, selpaste, {.i = 0} }, | |
- { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, | |
- { TERMMOD, XK_I, iso14755, {.i = 0} }, | |
+ /* mask keysym function argument */ | |
+ { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} }, | |
+ { ControlMask, XK_Print, toggleprinter, {.i = 0} }, | |
+ { ShiftMask, XK_Print, printscreen, {.i = 0} }, | |
+ { XK_ANY_MOD, XK_Print, printsel, {.i = 0} }, | |
+ { TERMMOD, XK_Prior, zoom, {.f = +1} }, | |
+ { TERMMOD, XK_Next, zoom, {.f = -1} }, | |
+ { TERMMOD, XK_Home, zoomreset, {.f = 0} }, | |
+ { TERMMOD, XK_C, clipcopy, {.i = 0} }, | |
+ { TERMMOD, XK_V, clippaste, {.i = 0} }, | |
+ { TERMMOD, XK_Y, selpaste, {.i = 0} }, | |
+ { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, | |
+ { TERMMOD, XK_I, iso14755, {.i = 0} }, | |
+ { TERMMOD, XK_U, toggleunicodemode, {.i = -1} }, | |
}; | |
/* | |
diff --git a/st.c b/st.c | |
index 46c954b..99a394b 100644 | |
--- a/st.c | |
+++ b/st.c | |
@@ -44,6 +44,10 @@ | |
#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) | |
#define ISDELIM(u) (utf8strchr(worddelimiters, u) != NULL) | |
+#define ISUNICHR(u) ((48 <= u && u <= 57) || \ | |
+ (65 <= u && u <= 70) || \ | |
+ (97 <= u && u <= 102)) | |
+ | |
/* constants */ | |
#define ISO14755CMD "dmenu -w \"$WINDOWID\" -p codepoint: </dev/null" | |
@@ -236,6 +240,12 @@ static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; | |
static Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; | |
static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; | |
+/* unicode */ | |
+ | |
+int unicodemode = 0; | |
+unsigned int unicodebufferindex = 0; | |
+char unicodebuffer[5] = {0, 0, 0, 0, '\0'}; | |
+ | |
ssize_t | |
xwrite(int fd, const char *s, size_t len) | |
{ | |
@@ -843,26 +853,78 @@ ttywrite(const char *s, size_t n, int may_echo) | |
{ | |
const char *next; | |
- if (may_echo && IS_SET(MODE_ECHO)) | |
- twrite(s, n, 1); | |
+ int unichr; | |
+ char uniptr[UTF_SIZ]; | |
+ size_t unilen; | |
- if (!IS_SET(MODE_CRLF)) { | |
- ttywriteraw(s, n); | |
- return; | |
- } | |
+ if (unicodemode) { | |
+ | |
+ if (*s == (char)127) { | |
+ /* backspace */ | |
+ if (unicodebufferindex > 0) { | |
+ unicodebuffer[unicodebufferindex] = 0; | |
+ unicodebufferindex--; | |
+ } | |
+ | |
+ unichr = (int)strtol(unicodebuffer, NULL, 16); | |
+ | |
+ if (unichr > 32) { | |
+ tmoveto(term.c.x - 1, term.c.y); | |
+ tputc(unichr); | |
+ } | |
+ } else if (*s == '\r') { | |
+ /* submit */ | |
+ unichr = (int)strtol(unicodebuffer, NULL, 16); | |
+ unilen = utf8encode(unichr, uniptr); | |
+ | |
+ if (unichr > 32) { | |
+ tmoveto(term.c.x - 1, term.c.y); | |
+ ttywriteraw((const char *)uniptr, unilen); | |
+ } | |
+ | |
+ toggleunicodemode(NULL); | |
+ } else if (*s == '\033') { | |
+ /* cancel */ | |
+ toggleunicodemode(NULL); | |
+ } else if (ISUNICHR(*s)) { | |
+ | |
+ if (unicodebufferindex < 4) { | |
+ unicodebuffer[unicodebufferindex] = *s; | |
+ unicodebufferindex++; | |
+ | |
+ unichr = (int)strtol(unicodebuffer, NULL, 16); | |
+ | |
+ if (unichr > 32) { | |
+ tmoveto(term.c.x - 1, term.c.y); | |
+ tputc(unichr); | |
+ } | |
+ } | |
- /* This is similar to how the kernel handles ONLCR for ttys */ | |
- while (n > 0) { | |
- if (*s == '\r') { | |
- next = s + 1; | |
- ttywriteraw("\r\n", 2); | |
- } else { | |
- next = memchr(s, '\r', n); | |
- DEFAULT(next, s + n); | |
- ttywriteraw(s, next - s); | |
} | |
- n -= next - s; | |
- s = next; | |
+ | |
+ } else { | |
+ | |
+ if (may_echo && IS_SET(MODE_ECHO)) | |
+ twrite(s, n, 1); | |
+ | |
+ if (!IS_SET(MODE_CRLF)) { | |
+ ttywriteraw(s, n); | |
+ return; | |
+ } | |
+ | |
+ /* This is similar to how the kernel handles ONLCR for ttys */ | |
+ while (n > 0) { | |
+ if (*s == '\r') { | |
+ next = s + 1; | |
+ ttywriteraw("\r\n", 2); | |
+ } else { | |
+ next = memchr(s, '\r', n); | |
+ DEFAULT(next, s + n); | |
+ ttywriteraw(s, next - s); | |
+ } | |
+ n -= next - s; | |
+ s = next; | |
+ } | |
} | |
} | |
@@ -2471,6 +2533,7 @@ twrite(const char *buf, int buflen, int show_ctrl) | |
u = buf[n] & 0xFF; | |
charsize = 1; | |
} | |
+ | |
if (show_ctrl && ISCONTROL(u)) { | |
if (u & 0x80) { | |
u &= 0x7f; | |
@@ -2568,6 +2631,28 @@ tresize(int col, int row) | |
term.c = c; | |
} | |
+void | |
+toggleunicodemode(const Arg *a) | |
+{ | |
+ int index, len; | |
+ Rune u; | |
+ char *ptr; | |
+ | |
+ if (unicodemode) { | |
+ unicodemode = 0; | |
+ | |
+ unicodebufferindex = 0; | |
+ | |
+ /* processing */ | |
+ | |
+ unicodebuffer[0] = unicodebuffer[1] = unicodebuffer[2] = \ | |
+ unicodebuffer[3] = 0; | |
+ } else { | |
+ unicodemode = 1; | |
+ tputc('u'); | |
+ } | |
+} | |
+ | |
void | |
resettitle(void) | |
{ | |
diff --git a/st.h b/st.h | |
index dac64d8..c6755c4 100644 | |
--- a/st.h | |
+++ b/st.h | |
@@ -85,6 +85,7 @@ void printscreen(const Arg *); | |
void printsel(const Arg *); | |
void sendbreak(const Arg *); | |
void toggleprinter(const Arg *); | |
+void toggleunicodemode(const Arg *); | |
int tattrset(int); | |
void tnew(int, int); | |
-- | |
2.16.2 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment