Skip to content

Instantly share code, notes, and snippets.

@Sweets
Last active June 5, 2020 00:03
Show Gist options
  • Save Sweets/736faca379d31990d3e6c2e69354a832 to your computer and use it in GitHub Desktop.
Save Sweets/736faca379d31990d3e6c2e69354a832 to your computer and use it in GitHub Desktop.
st unicode patch
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