Compare commits

..

10 Commits

Author SHA1 Message Date
1478e0d6ed Added .gitignore 2023-06-20 22:59:57 +02:00
Hiltjo Posthuma
211964d56e ignore C1 control characters in UTF-8 mode
Ignore processing and printing C1 control characters in UTF-8 mode.
These are in the range: 0x80 - 0x9f.

By default in st the mode is set to UTF-8.

This matches more the behaviour of xterm with the options -u8 or +u8 also.
Also see the xterm resource "allowC1Printable".

Let me know if this breaks something, in most cases I don't think so.

As usual a very good reference is:
https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
2023-02-07 20:00:59 +01:00
Adam Price
f17abd25b3 Add support for DSR response "OK" escape sequence
"VT100 defines an escape sequence [1] called Device Status Report (DSR). When
the DSR sequence received is `csi 5n`, an "OK" response `csi 0n` is returned.
This patch adds that "OK" response.

I encountered this missing sequence when I noticed that fzf [2] would clobber
my prompt whenever completing a find.

To test that ST doesn't currently respond to `csi 5n`, use fzf's shell
extension in ST's repo to complete the path for a file.

    my-fancy-prompt $ vim **<tab>
    <select a file>
    st.c

Select a file with <enter>, and notice that fzf clobbers some or all of your
prompt.

After applying this patch, do the same test as above and notice that fzf has no
longer clobbered your prompt by placing the file name in the correct position
in your command.

    my-fancy-prompt $ vim **<tab>
    <select a file>
    my-fancy prompt $ vim st.c

Thank you for considering my first patch submission.

[1] https://www.xfree86.org/current/ctlseqs.html#VT100%20Mode
[2] https://github.com/junegunn/fzf
"

Patch slightly adapted with input from the mailinglist,
2023-02-07 19:57:34 +01:00
Hiltjo Posthuma
7e8050cc62 Fixed OSC color reset without parameter->resets all colors
Adapted from (garbled) patch by wim <wim@thinkerwim.org>

Additional notes: it should reset all the colors using xloadcols().
To reproduce: set a different (theme) color using some escape code, then reset
it:

	printf '\x1b]104\x07'
2023-02-05 13:29:35 +01:00
Hiltjo Posthuma
e5e959835b fix buffer overflow when handling long composed input
To reproduce the issue:

"
If you already have the multi-key enabled on your system, then add this line
to your ~/.XCompose file:

[...]
<question> <T> <E> <S> <T> <question> :
"1234567890123456789012345678901234567890123456789012345678901234567890"
"

Reported by and an initial patch by Andy Gozas <andy@gozas.me>, thanks!

Adapted the patch, for now st (like dmenu) handles a fixed amount of composed
characters, or otherwise ignores it. This is done for simplicity sake.
2022-10-25 17:11:11 +02:00
Hiltjo Posthuma
68d1ad9b54 bump version to 0.9 2022-10-04 19:40:30 +02:00
Hiltjo Posthuma
0008519903 FAQ: document the color emojis crash issue which affected some systems is fixed
It is fixed in libXft 2.3.6:

https://gitlab.freedesktop.org/xorg/lib/libxft/-/blob/libXft-2.3.5/NEWS
2022-09-16 23:07:09 +02:00
Tom Schwindl
72fd32736a st: use `void' to indicate an empty parameter list 2022-08-18 17:14:10 +02:00
Hiltjo Posthuma
baa9357e96 Makefile: add manual path for OpenBSD 2022-05-01 18:38:40 +02:00
NRK
8629d9a1da code-golfing: cleanup osc color related code
* adds missing function prototype
* move xgetcolor() prototype to win.h (that's where all the other x.c
  func prototype seems to be declared at)
* check for snprintf error/truncation
* reduces code duplication for osc 10/11/12
* unify osc_color_response() and osc4_color_response() into a single function

the latter two was suggested by Quentin Rameau in his patch review on
the hackers list.
2022-04-19 11:43:37 +02:00
7 changed files with 62 additions and 68 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.o
*.orig

3
FAQ
View File

@ -248,3 +248,6 @@ fonts:
Please don't bother reporting this bug to st, but notify the upstream Xft Please don't bother reporting this bug to st, but notify the upstream Xft
developers about fixing this bug. developers about fixing this bug.
As of 2022-09-05 this now seems to be finally fixed in libXft 2.3.5:
https://gitlab.freedesktop.org/xorg/lib/libxft/-/blob/libXft-2.3.5/NEWS

View File

@ -1,5 +1,5 @@
# st version # st version
VERSION = 0.8.5 VERSION = 0.9
# Customize below to fit your system # Customize below to fit your system
@ -30,6 +30,7 @@ STLDFLAGS = $(LIBS) $(LDFLAGS)
#LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \ #LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \
# `$(PKG_CONFIG) --libs fontconfig` \ # `$(PKG_CONFIG) --libs fontconfig` \
# `$(PKG_CONFIG) --libs freetype2` # `$(PKG_CONFIG) --libs freetype2`
#MANPREFIX = ${PREFIX}/man
# compiler and linker # compiler and linker
# CC = c99 # CC = c99

110
st.c
View File

@ -161,6 +161,7 @@ static void csidump(void);
static void csihandle(void); static void csihandle(void);
static void csiparse(void); static void csiparse(void);
static void csireset(void); static void csireset(void);
static void osc_color_response(int, int, int);
static int eschandle(uchar); static int eschandle(uchar);
static void strdump(void); static void strdump(void);
static void strhandle(void); static void strhandle(void);
@ -938,7 +939,7 @@ ttyresize(int tw, int th)
} }
void void
ttyhangup() ttyhangup(void)
{ {
/* Send SIGHUP to shell */ /* Send SIGHUP to shell */
kill(pid, SIGHUP); kill(pid, SIGHUP);
@ -1768,11 +1769,18 @@ csihandle(void)
case 'm': /* SGR -- Terminal attribute (color) */ case 'm': /* SGR -- Terminal attribute (color) */
tsetattr(csiescseq.arg, csiescseq.narg); tsetattr(csiescseq.arg, csiescseq.narg);
break; break;
case 'n': /* DSR Device Status Report (cursor position) */ case 'n': /* DSR -- Device Status Report */
if (csiescseq.arg[0] == 6) { 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) "<row>;<column>R" */
len = snprintf(buf, sizeof(buf), "\033[%i;%iR", 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); ttywrite(buf, len, 0);
break;
default:
goto unknown;
} }
break; break;
case 'r': /* DECSTBM -- Set Scrolling Region */ case 'r': /* DECSTBM -- Set Scrolling Region */
@ -1835,39 +1843,28 @@ csireset(void)
} }
void void
osc4_color_response(int num) osc_color_response(int num, int index, int is_osc4)
{ {
int n; int n;
char buf[32]; char buf[32];
unsigned char r, g, b; unsigned char r, g, b;
if (xgetcolor(num, &r, &g, &b)) { if (xgetcolor(is_osc4 ? num : index, &r, &g, &b)) {
fprintf(stderr, "erresc: failed to fetch osc4 color %d\n", num); fprintf(stderr, "erresc: failed to fetch %s color %d\n",
is_osc4 ? "osc4" : "osc",
is_osc4 ? num : index);
return; return;
} }
n = snprintf(buf, sizeof buf, "\033]4;%d;rgb:%02x%02x/%02x%02x/%02x%02x\007", n = snprintf(buf, sizeof buf, "\033]%s%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
num, r, r, g, g, b, b); is_osc4 ? "4;" : "", num, r, r, g, g, b, b);
if (n < 0 || n >= sizeof(buf)) {
ttywrite(buf, n, 1); fprintf(stderr, "error: %s while printing %s response\n",
} n < 0 ? "snprintf failed" : "truncation occurred",
is_osc4 ? "osc4" : "osc");
void } else {
osc_color_response(int index, int num) ttywrite(buf, n, 1);
{
int n;
char buf[32];
unsigned char r, g, b;
if (xgetcolor(index, &r, &g, &b)) {
fprintf(stderr, "erresc: failed to fetch osc color %d\n", index);
return;
} }
n = snprintf(buf, sizeof buf, "\033]%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
num, r, r, g, g, b, b);
ttywrite(buf, n, 1);
} }
void void
@ -1875,6 +1872,11 @@ strhandle(void)
{ {
char *p = NULL, *dec; char *p = NULL, *dec;
int j, narg, par; int j, narg, par;
const struct { int idx; char *str; } osc_table[] = {
{ defaultfg, "foreground" },
{ defaultbg, "background" },
{ defaultcs, "cursor" }
};
term.esc &= ~(ESC_STR_END|ESC_STR); term.esc &= ~(ESC_STR_END|ESC_STR);
strparse(); strparse();
@ -1909,43 +1911,22 @@ strhandle(void)
} }
return; return;
case 10: case 10:
if (narg < 2)
break;
p = strescseq.args[1];
if (!strcmp(p, "?"))
osc_color_response(defaultfg, 10);
else if (xsetcolorname(defaultfg, p))
fprintf(stderr, "erresc: invalid foreground color: %s\n", p);
else
tfulldirt();
return;
case 11: case 11:
if (narg < 2)
break;
p = strescseq.args[1];
if (!strcmp(p, "?"))
osc_color_response(defaultbg, 11);
else if (xsetcolorname(defaultbg, p))
fprintf(stderr, "erresc: invalid background color: %s\n", p);
else
tfulldirt();
return;
case 12: case 12:
if (narg < 2) if (narg < 2)
break; break;
p = strescseq.args[1]; p = strescseq.args[1];
if ((j = par - 10) < 0 || j >= LEN(osc_table))
break; /* shouldn't be possible */
if (!strcmp(p, "?")) if (!strcmp(p, "?")) {
osc_color_response(defaultcs, 12); osc_color_response(par, osc_table[j].idx, 0);
else if (xsetcolorname(defaultcs, p)) } else if (xsetcolorname(osc_table[j].idx, p)) {
fprintf(stderr, "erresc: invalid cursor color: %s\n", p); fprintf(stderr, "erresc: invalid %s color: %s\n",
else osc_table[j].str, p);
} else {
tfulldirt(); tfulldirt();
}
return; return;
case 4: /* color set */ case 4: /* color set */
if (narg < 3) if (narg < 3)
@ -1955,11 +1936,13 @@ strhandle(void)
case 104: /* color reset */ case 104: /* color reset */
j = (narg > 1) ? atoi(strescseq.args[1]) : -1; j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
if (p && !strcmp(p, "?")) if (p && !strcmp(p, "?")) {
osc4_color_response(j); osc_color_response(j, 0, 1);
else if (xsetcolorname(j, p)) { } else if (xsetcolorname(j, p)) {
if (par == 104 && narg <= 1) if (par == 104 && narg <= 1) {
xloadcols();
return; /* color reset without parameter */ return; /* color reset without parameter */
}
fprintf(stderr, "erresc: invalid color j=%d, p=%s\n", fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",
j, p ? p : "(null)"); j, p ? p : "(null)");
} else { } else {
@ -2439,6 +2422,9 @@ check_control_code:
* they must not cause conflicts with sequences. * they must not cause conflicts with sequences.
*/ */
if (control) { if (control) {
/* in UTF-8 mode ignore handling C1 control characters */
if (IS_SET(MODE_UTF8) && ISCONTROLC1(u))
return;
tcontrolcode(u); tcontrolcode(u);
/* /*
* control codes are not shown ever * control codes are not shown ever

2
st.h
View File

@ -111,8 +111,6 @@ void *xmalloc(size_t);
void *xrealloc(void *, size_t); void *xrealloc(void *, size_t);
char *xstrdup(const char *); char *xstrdup(const char *);
int xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b);
/* config.h globals */ /* config.h globals */
extern char *utmp; extern char *utmp;
extern char *scroll; extern char *scroll;

1
win.h
View File

@ -30,6 +30,7 @@ void xdrawline(Line, int, int, int);
void xfinishdraw(void); void xfinishdraw(void);
void xloadcols(void); void xloadcols(void);
int xsetcolorname(int, const char *); int xsetcolorname(int, const char *);
int xgetcolor(int, unsigned char *, unsigned char *, unsigned char *);
void xseticontitle(char *); void xseticontitle(char *);
void xsettitle(char *); void xsettitle(char *);
int xsetcursor(int); int xsetcursor(int);

9
x.c
View File

@ -1833,7 +1833,7 @@ void
kpress(XEvent *ev) kpress(XEvent *ev)
{ {
XKeyEvent *e = &ev->xkey; XKeyEvent *e = &ev->xkey;
KeySym ksym; KeySym ksym = NoSymbol;
char buf[64], *customkey; char buf[64], *customkey;
int len; int len;
Rune c; Rune c;
@ -1843,10 +1843,13 @@ kpress(XEvent *ev)
if (IS_SET(MODE_KBDLOCK)) if (IS_SET(MODE_KBDLOCK))
return; return;
if (xw.ime.xic) if (xw.ime.xic) {
len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status); len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status);
else if (status == XBufferOverflow)
return;
} else {
len = XLookupString(e, buf, sizeof buf, &ksym, NULL); len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
}
/* 1. shortcuts */ /* 1. shortcuts */
for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
if (ksym == bp->keysym && match(bp->mod, e->state)) { if (ksym == bp->keysym && match(bp->mod, e->state)) {