Compare commits

..

12 Commits

Author SHA1 Message Date
thad-w541
593fcd7513 upd8 2025-10-31 18:40:54 -05:00
thad-w541
7e405dd376 x 2025-10-28 22:21:05 -05:00
thad-w541
ccfe9f23a3 initish - this is broken 2025-10-27 08:44:46 -05:00
Hiltjo Posthuma
6e97047474 bump version to 0.9.3 2025-08-09 14:35:14 +02:00
Hiltjo Posthuma
5a4666c19e add a few comments 2025-08-09 14:22:28 +02:00
Ayman Bagabas
d6c431859c Support OSC 110, 111, and 112 for resetting colors
This adds support for OSC 110, 111, and 112 escape sequences to reset
the foreground, background, and cursor colors in the terminal. The
changes include handling these sequences in the `strhandle` function of
`st.c`, allowing applications to reset colors to their default values.

The OSC sequences originated from Xterm control sequences and are now
widely used in terminal applications and supported by many terminal
emulators. For applications, this allows them to reset colors to
default values without needing to know the colors beforehand.

Signed-off-by: Ayman Bagabas <ayman.bagabas@gmail.com>
2025-08-09 12:34:01 +02:00
sasha
f114bcedd1 Eat up "CSI 58" sequences
This is used in the wild by systemd systemctl for example and st
misinterpreted it as "blink", because it didn't know "58", then saw "5"
as "blink", and then didn't know "245".

This should print "foo" as normal text:

    printf '\e[58:5:245mfoo\n'
    printf '\e[58:2:50💯200mfoo\n'
2025-07-27 20:06:54 +02:00
Johannes Altmanninger
98610fcd37 Do not interpret CSI ? u as DECRC
The kitty keyboard protocol docs recommend CSI ? u to query support for
that protocol, see https://sw.kovidgoyal.net/kitty/keyboard-protocol/

For better or worse, fish shell uses this query to work around bugs
in other terminals triggered by requesting that protocol via CSI = 5 u.

Unfortunately, st interprets CSI ? u as DECRC (restore cursor
position). reproduce with 'printf "\x1b[?u"; cat'.

fish could work around this by switching to the alternate screen
before running this query; but that might cause tearing on terminals
that don't support Synchronized Output. I'm not sure.

In the meantime, let's correct our parser.

This adds a redundant else-after-return, for consistency with the
surrounding code.
2025-01-30 17:50:37 +01:00
Markus Rinne
6009e6e25b Clear screen: Fix edge case
With sequence \e[1J, if cursor is on second line, clear the first line.
2024-12-06 13:42:50 +01:00
Lucas de Sena
a0274bc20e fix BadMatch error when embedding on some windows
When embedded, st fails with BadMatch error if the embedder's window has
non-default colormap/depth/visual.  This commit fixes that by creating
st's window inside root and then reparent it into embedder.

The reference window for dc.gc is also changed to match root's visuals.

A similar commit had been made for dmenu[1].
See this issue[2] on github for context.

[1]: https://git.suckless.org/dmenu/commit/0fe460dbd469a1d5b6a7140d0e1801935e4a923b.html
[2]: https://github.com/phillbush/xfiles/issues/47
2024-08-09 13:34:56 +02:00
Hiltjo Posthuma
5dbcca4926 support colons in SGR character attributes
Patch by Mikhail Kot <to@myrrc.dev>
With some modifications to behave more like xterm (see note below).

Example:

	printf '\033[48;2;255:0:0mtest\n'

https://invisible-island.net/xterm/ctlseqs/ctlseqs.html

Some notes:

"CSI Pm m  Character Attributes (SGR).
[...]
o   xterm allows either colons (standard) or semicolons
(legacy) to separate the subparameters (but after the
first colon, colons must be used).
2024-05-01 20:45:39 +02:00
Hiltjo Posthuma
d63b9eb902 bump version to 0.9.2 2024-04-05 12:18:41 +02:00
7 changed files with 1036 additions and 49 deletions

View File

@@ -93,46 +93,87 @@ char *termname = "st-256color";
*/ */
unsigned int tabspaces = 8; unsigned int tabspaces = 8;
/* Terminal colors (16 first used in escape sequence) */ typedef struct {
static const char *colorname[] = { const char* const colors[258]; /* terminal colors */
/* 8 normal colors */ unsigned int fg; /* foreground */
"black", unsigned int bg; /* background */
"red3", unsigned int cs; /* cursor */
"green3", unsigned int rcs; /* reverse cursor */
"yellow3", } ColorScheme;
"blue2", /*
"magenta3", * Terminal colors (16 first used in escape sequence,
"cyan3", * 2 last for custom cursor color),
"gray90", * foreground, background, cursor, reverse cursor
*/
static const ColorScheme schemes[] = {
// st (dark)
{{"black", "red3", "green3", "yellow3",
"blue2", "magenta3", "cyan3", "gray90",
"gray50", "red", "green", "yellow",
"#5c5cff", "magenta", "cyan", "white",
[256]="#cccccc", "#555555"}, 7, 0, 256, 257},
/* 8 bright colors */ // Alacritty (dark)
"gray50", {{"#1d1f21", "#cc6666", "#b5bd68", "#f0c674",
"red", "#81a2be", "#b294bb", "#8abeb7", "#c5c8c6",
"green", "#666666", "#d54e53", "#b9ca4a", "#e7c547",
"yellow", "#7aa6da", "#c397d8", "#70c0b1", "#eaeaea",
"#5c5cff", [256]="#cccccc", "#555555"}, 7, 0, 256, 257},
"magenta",
"cyan",
"white",
[255] = 0, // One Half dark
{{"#282c34", "#e06c75", "#98c379", "#e5c07b",
"#61afef", "#c678dd", "#56b6c2", "#dcdfe4",
"#282c34", "#e06c75", "#98c379", "#e5c07b",
"#61afef", "#c678dd", "#56b6c2", "#dcdfe4",
[256]="#cccccc", "#555555"}, 7, 0, 256, 257},
/* more colors can be added after 255 to use with DefaultXX */ // One Half light
"#cccccc", {{"#fafafa", "#e45649", "#50a14f", "#c18401",
"#555555", "#0184bc", "#a626a4", "#0997b3", "#383a42",
"gray90", /* default foreground colour */ "#fafafa", "#e45649", "#50a14f", "#c18401",
"black", /* default background colour */ "#0184bc", "#a626a4", "#0997b3", "#383a42",
[256]="#cccccc", "#555555"}, 7, 0, 256, 257},
// Solarized dark
{{"#073642", "#dc322f", "#859900", "#b58900",
"#268bd2", "#d33682", "#2aa198", "#eee8d5",
"#002b36", "#cb4b16", "#586e75", "#657b83",
"#839496", "#6c71c4", "#93a1a1", "#fdf6e3",
[256]="#93a1a1", "#fdf6e3"}, 12, 8, 256, 257},
// Solarized light
{{"#eee8d5", "#dc322f", "#859900", "#b58900",
"#268bd2", "#d33682", "#2aa198", "#073642",
"#fdf6e3", "#cb4b16", "#93a1a1", "#839496",
"#657b83", "#6c71c4", "#586e75", "#002b36",
[256]="#586e75", "#002b36"}, 12, 8, 256, 257},
// Gruvbox dark
{{"#282828", "#cc241d", "#98971a", "#d79921",
"#458588", "#b16286", "#689d6a", "#a89984",
"#928374", "#fb4934", "#b8bb26", "#fabd2f",
"#83a598", "#d3869b", "#8ec07c", "#ebdbb2",
[256]="#ebdbb2", "#555555"}, 15, 0, 256, 257},
// Gruvbox light
{{"#fbf1c7", "#cc241d", "#98971a", "#d79921",
"#458588", "#b16286", "#689d6a", "#7c6f64",
"#928374", "#9d0006", "#79740e", "#b57614",
"#076678", "#8f3f71", "#427b58", "#3c3836",
[256]="#3c3836", "#555555"}, 15, 0, 256, 257},
}; };
static const char * const * colorname;
int colorscheme = 6;
/* /*
* Default colors (colorname index) * Default colors (colorname index)
* foreground, background, cursor, reverse cursor * foreground, background, cursor, reverse cursor
*/ */
unsigned int defaultfg = 258; unsigned int defaultfg;
unsigned int defaultbg = 259; unsigned int defaultbg;
unsigned int defaultcs = 256; unsigned int defaultcs;
static unsigned int defaultrcs = 257; static unsigned int defaultrcs;
/* /*
* Default shape of cursor * Default shape of cursor
@@ -201,6 +242,17 @@ static Shortcut shortcuts[] = {
{ TERMMOD, XK_Y, selpaste, {.i = 0} }, { TERMMOD, XK_Y, selpaste, {.i = 0} },
{ ShiftMask, XK_Insert, selpaste, {.i = 0} }, { ShiftMask, XK_Insert, selpaste, {.i = 0} },
{ TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, { TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
{ MODKEY, XK_1, selectscheme, {.i = 0} },
{ MODKEY, XK_2, selectscheme, {.i = 1} },
{ MODKEY, XK_3, selectscheme, {.i = 2} },
{ MODKEY, XK_4, selectscheme, {.i = 3} },
{ MODKEY, XK_5, selectscheme, {.i = 4} },
{ MODKEY, XK_6, selectscheme, {.i = 5} },
{ MODKEY, XK_7, selectscheme, {.i = 6} },
{ MODKEY, XK_8, selectscheme, {.i = 7} },
{ MODKEY, XK_9, selectscheme, {.i = 8} },
{ MODKEY, XK_0, nextscheme, {.i = +1} },
{ MODKEY|ControlMask, XK_0, nextscheme, {.i = -1} },
}; };
/* /*

526
config.h Normal file
View File

@@ -0,0 +1,526 @@
/* See LICENSE file for copyright and license details. */
/*
* appearance
*
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
*/
static char *font = "Noto Mono:pixelsize=12:antialias=true:autohint=true";
static int borderpx = 12;
/*
* What program is execed by st depends of these precedence rules:
* 1: program passed with -e
* 2: scroll and/or utmp
* 3: SHELL environment variable
* 4: value of shell in /etc/passwd
* 5: value of shell in config.h
*/
static char *shell = "/bin/sh";
char *utmp = NULL;
/* scroll program: to enable use a string like "scroll" */
char *scroll = NULL;
char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
/* identification sequence returned in DA and DECID */
char *vtiden = "\033[?6c";
/* Kerning / character bounding-box multipliers */
static float cwscale = 1.0;
static float chscale = 1.0;
/*
* word delimiter string
*
* More advanced example: L" `'\"()[]{}"
*/
wchar_t *worddelimiters = L" ";
/* selection timeouts (in milliseconds) */
static unsigned int doubleclicktimeout = 300;
static unsigned int tripleclicktimeout = 600;
/* alt screens */
int allowaltscreen = 1;
/* allow certain non-interactive (insecure) window operations such as:
setting the clipboard text */
int allowwindowops = 0;
/*
* draw latency range in ms - from new content/keypress/etc until drawing.
* within this range, st draws when content stops arriving (idle). mostly it's
* near minlatency, but it waits longer for slow updates to avoid partial draw.
* low minlatency will tear/flicker more, as it can "detect" idle too early.
*/
static double minlatency = 2;
static double maxlatency = 33;
/*
* blinking timeout (set to 0 to disable blinking) for the terminal blinking
* attribute.
*/
static unsigned int blinktimeout = 800;
/*
* thickness of underline and bar cursors
*/
static unsigned int cursorthickness = 2;
/*
* bell volume. It must be a value between -100 and 100. Use 0 for disabling
* it
*/
static int bellvolume = 0;
/* default TERM value */
char *termname = "st-256color";
/*
* spaces per tab
*
* When you are changing this value, don't forget to adapt the »it« value in
* the st.info and appropriately install the st.info in the environment where
* you use this st version.
*
* it#$tabspaces,
*
* Secondly make sure your kernel is not expanding tabs. When running `stty
* -a` »tab0« should appear. You can tell the terminal to not expand tabs by
* running following command:
*
* stty tabs
*/
unsigned int tabspaces = 8;
typedef struct {
const char* const colors[258]; /* terminal colors */
unsigned int fg; /* foreground */
unsigned int bg; /* background */
unsigned int cs; /* cursor */
unsigned int rcs; /* reverse cursor */
} ColorScheme;
/*
* Terminal colors (16 first used in escape sequence,
* 2 last for custom cursor color),
* foreground, background, cursor, reverse cursor
*/
static const ColorScheme schemes[] = {
// st (dark)
{{"black", "red3", "green3", "yellow3",
"blue2", "magenta3", "cyan3", "gray90",
"gray50", "red", "green", "yellow",
"#5c5cff", "magenta", "cyan", "white",
[256]="#cccccc", "#555555"}, 7, 0, 256, 257},
// Alacritty (dark)
{{"#1d1f21", "#cc6666", "#b5bd68", "#f0c674",
"#81a2be", "#b294bb", "#8abeb7", "#c5c8c6",
"#666666", "#d54e53", "#b9ca4a", "#e7c547",
"#7aa6da", "#c397d8", "#70c0b1", "#eaeaea",
[256]="#cccccc", "#555555"}, 7, 0, 256, 257},
// One Half dark
{{"#282c34", "#e06c75", "#98c379", "#e5c07b",
"#61afef", "#c678dd", "#56b6c2", "#dcdfe4",
"#282c34", "#e06c75", "#98c379", "#e5c07b",
"#61afef", "#c678dd", "#56b6c2", "#dcdfe4",
[256]="#cccccc", "#555555"}, 7, 0, 256, 257},
// One Half light
{{"#fafafa", "#e45649", "#50a14f", "#c18401",
"#0184bc", "#a626a4", "#0997b3", "#383a42",
"#fafafa", "#e45649", "#50a14f", "#c18401",
"#0184bc", "#a626a4", "#0997b3", "#383a42",
[256]="#cccccc", "#555555"}, 7, 0, 256, 257},
// Solarized dark
{{"#073642", "#dc322f", "#859900", "#b58900",
"#268bd2", "#d33682", "#2aa198", "#eee8d5",
"#002b36", "#cb4b16", "#586e75", "#657b83",
"#839496", "#6c71c4", "#93a1a1", "#fdf6e3",
[256]="#93a1a1", "#fdf6e3"}, 12, 8, 256, 257},
// Solarized light
{{"#eee8d5", "#dc322f", "#859900", "#b58900",
"#268bd2", "#d33682", "#2aa198", "#073642",
"#fdf6e3", "#cb4b16", "#93a1a1", "#839496",
"#657b83", "#6c71c4", "#586e75", "#002b36",
[256]="#586e75", "#002b36"}, 12, 8, 256, 257},
// Gruvbox dark
{{"#282828", "#cc241d", "#98971a", "#d79921",
"#458588", "#b16286", "#689d6a", "#a89984",
"#928374", "#fb4934", "#b8bb26", "#fabd2f",
"#83a598", "#d3869b", "#8ec07c", "#ebdbb2",
[256]="#ebdbb2", "#555555"}, 15, 0, 256, 257},
// Gruvbox light
{{"#fbf1c7", "#cc241d", "#98971a", "#d79921",
"#458588", "#b16286", "#689d6a", "#7c6f64",
"#928374", "#9d0006", "#79740e", "#b57614",
"#076678", "#8f3f71", "#427b58", "#3c3836",
[256]="#3c3836", "#555555"}, 15, 0, 256, 257},
};
static const char * const * colorname;
int colorscheme = 6;
/*
* Default colors (colorname index)
* foreground, background, cursor, reverse cursor
*/
unsigned int defaultfg;
unsigned int defaultbg;
unsigned int defaultcs;
static unsigned int defaultrcs;
/*
* Default shape of cursor
* 2: Block ("█")
* 4: Underline ("_")
* 6: Bar ("|")
* 7: Snowman ("☃")
*/
static unsigned int cursorshape = 2;
/*
* Default columns and rows numbers
*/
static unsigned int cols = 80;
static unsigned int rows = 24;
/*
* Default colour and shape of the mouse cursor
*/
static unsigned int mouseshape = XC_xterm;
static unsigned int mousefg = 7;
static unsigned int mousebg = 0;
/*
* Color used to display font attributes when fontconfig selected a font which
* doesn't match the ones requested.
*/
static unsigned int defaultattr = 11;
/*
* Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set).
* Note that if you want to use ShiftMask with selmasks, set this to an other
* modifier, set to 0 to not use it.
*/
static uint forcemousemod = ShiftMask;
/*
* Internal mouse shortcuts.
* Beware that overloading Button1 will disable the selection.
*/
static MouseShortcut mshortcuts[] = {
/* mask button function argument release */
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
{ ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
{ ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
};
/* Internal keyboard shortcuts. */
#define MODKEY Mod1Mask
#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} },
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
{ TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
{ MODKEY, XK_1, selectscheme, {.i = 0} },
{ MODKEY, XK_2, selectscheme, {.i = 1} },
{ MODKEY, XK_3, selectscheme, {.i = 2} },
{ MODKEY, XK_4, selectscheme, {.i = 3} },
{ MODKEY, XK_5, selectscheme, {.i = 4} },
{ MODKEY, XK_6, selectscheme, {.i = 5} },
{ MODKEY, XK_7, selectscheme, {.i = 6} },
{ MODKEY, XK_8, selectscheme, {.i = 7} },
{ MODKEY, XK_9, selectscheme, {.i = 8} },
{ MODKEY, XK_0, nextscheme, {.i = +1} },
{ MODKEY|ControlMask, XK_0, nextscheme, {.i = -1} },
};
/*
* Special keys (change & recompile st.info accordingly)
*
* Mask value:
* * Use XK_ANY_MOD to match the key no matter modifiers state
* * Use XK_NO_MOD to match the key alone (no modifiers)
* appkey value:
* * 0: no value
* * > 0: keypad application mode enabled
* * = 2: term.numlock = 1
* * < 0: keypad application mode disabled
* appcursor value:
* * 0: no value
* * > 0: cursor application mode enabled
* * < 0: cursor application mode disabled
*
* Be careful with the order of the definitions because st searches in
* this table sequentially, so any XK_ANY_MOD must be in the last
* position for a key.
*/
/*
* If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
* to be mapped below, add them to this array.
*/
static KeySym mappedkeys[] = { -1 };
/*
* State bits to ignore when matching key or button events. By default,
* numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
*/
static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
/*
* This is the huge key array which defines all compatibility to the Linux
* world. Please decide about changes wisely.
*/
static Key key[] = {
/* keysym mask string appkey appcursor */
{ XK_KP_Home, ShiftMask, "\033[2J", 0, -1},
{ XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1},
{ XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1},
{ XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1},
{ XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0},
{ XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1},
{ XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1},
{ XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0},
{ XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1},
{ XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1},
{ XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0},
{ XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1},
{ XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1},
{ XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0},
{ XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1},
{ XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1},
{ XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0},
{ XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
{ XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0},
{ XK_KP_End, ControlMask, "\033[J", -1, 0},
{ XK_KP_End, ControlMask, "\033[1;5F", +1, 0},
{ XK_KP_End, ShiftMask, "\033[K", -1, 0},
{ XK_KP_End, ShiftMask, "\033[1;2F", +1, 0},
{ XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0},
{ XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0},
{ XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0},
{ XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0},
{ XK_KP_Insert, ShiftMask, "\033[4l", -1, 0},
{ XK_KP_Insert, ControlMask, "\033[L", -1, 0},
{ XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0},
{ XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
{ XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
{ XK_KP_Delete, ControlMask, "\033[M", -1, 0},
{ XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0},
{ XK_KP_Delete, ShiftMask, "\033[2K", -1, 0},
{ XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0},
{ XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0},
{ XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
{ XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0},
{ XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0},
{ XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0},
{ XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0},
{ XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0},
{ XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0},
{ XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0},
{ XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0},
{ XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0},
{ XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0},
{ XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0},
{ XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0},
{ XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0},
{ XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0},
{ XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0},
{ XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0},
{ XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0},
{ XK_Up, ShiftMask, "\033[1;2A", 0, 0},
{ XK_Up, Mod1Mask, "\033[1;3A", 0, 0},
{ XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0},
{ XK_Up, ControlMask, "\033[1;5A", 0, 0},
{ XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0},
{ XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0},
{ XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0},
{ XK_Up, XK_ANY_MOD, "\033[A", 0, -1},
{ XK_Up, XK_ANY_MOD, "\033OA", 0, +1},
{ XK_Down, ShiftMask, "\033[1;2B", 0, 0},
{ XK_Down, Mod1Mask, "\033[1;3B", 0, 0},
{ XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0},
{ XK_Down, ControlMask, "\033[1;5B", 0, 0},
{ XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0},
{ XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0},
{ XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0},
{ XK_Down, XK_ANY_MOD, "\033[B", 0, -1},
{ XK_Down, XK_ANY_MOD, "\033OB", 0, +1},
{ XK_Left, ShiftMask, "\033[1;2D", 0, 0},
{ XK_Left, Mod1Mask, "\033[1;3D", 0, 0},
{ XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0},
{ XK_Left, ControlMask, "\033[1;5D", 0, 0},
{ XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0},
{ XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0},
{ XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0},
{ XK_Left, XK_ANY_MOD, "\033[D", 0, -1},
{ XK_Left, XK_ANY_MOD, "\033OD", 0, +1},
{ XK_Right, ShiftMask, "\033[1;2C", 0, 0},
{ XK_Right, Mod1Mask, "\033[1;3C", 0, 0},
{ XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0},
{ XK_Right, ControlMask, "\033[1;5C", 0, 0},
{ XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0},
{ XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0},
{ XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0},
{ XK_Right, XK_ANY_MOD, "\033[C", 0, -1},
{ XK_Right, XK_ANY_MOD, "\033OC", 0, +1},
{ XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0},
{ XK_Return, Mod1Mask, "\033\r", 0, 0},
{ XK_Return, XK_ANY_MOD, "\r", 0, 0},
{ XK_Insert, ShiftMask, "\033[4l", -1, 0},
{ XK_Insert, ShiftMask, "\033[2;2~", +1, 0},
{ XK_Insert, ControlMask, "\033[L", -1, 0},
{ XK_Insert, ControlMask, "\033[2;5~", +1, 0},
{ XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
{ XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
{ XK_Delete, ControlMask, "\033[M", -1, 0},
{ XK_Delete, ControlMask, "\033[3;5~", +1, 0},
{ XK_Delete, ShiftMask, "\033[2K", -1, 0},
{ XK_Delete, ShiftMask, "\033[3;2~", +1, 0},
{ XK_Delete, XK_ANY_MOD, "\033[P", -1, 0},
{ XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
{ XK_BackSpace, XK_NO_MOD, "\177", 0, 0},
{ XK_BackSpace, Mod1Mask, "\033\177", 0, 0},
{ XK_Home, ShiftMask, "\033[2J", 0, -1},
{ XK_Home, ShiftMask, "\033[1;2H", 0, +1},
{ XK_Home, XK_ANY_MOD, "\033[H", 0, -1},
{ XK_Home, XK_ANY_MOD, "\033[1~", 0, +1},
{ XK_End, ControlMask, "\033[J", -1, 0},
{ XK_End, ControlMask, "\033[1;5F", +1, 0},
{ XK_End, ShiftMask, "\033[K", -1, 0},
{ XK_End, ShiftMask, "\033[1;2F", +1, 0},
{ XK_End, XK_ANY_MOD, "\033[4~", 0, 0},
{ XK_Prior, ControlMask, "\033[5;5~", 0, 0},
{ XK_Prior, ShiftMask, "\033[5;2~", 0, 0},
{ XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
{ XK_Next, ControlMask, "\033[6;5~", 0, 0},
{ XK_Next, ShiftMask, "\033[6;2~", 0, 0},
{ XK_Next, XK_ANY_MOD, "\033[6~", 0, 0},
{ XK_F1, XK_NO_MOD, "\033OP" , 0, 0},
{ XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0},
{ XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0},
{ XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0},
{ XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0},
{ XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0},
{ XK_F2, XK_NO_MOD, "\033OQ" , 0, 0},
{ XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0},
{ XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0},
{ XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0},
{ XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0},
{ XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0},
{ XK_F3, XK_NO_MOD, "\033OR" , 0, 0},
{ XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0},
{ XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0},
{ XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0},
{ XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0},
{ XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0},
{ XK_F4, XK_NO_MOD, "\033OS" , 0, 0},
{ XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0},
{ XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0},
{ XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0},
{ XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0},
{ XK_F5, XK_NO_MOD, "\033[15~", 0, 0},
{ XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0},
{ XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0},
{ XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0},
{ XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0},
{ XK_F6, XK_NO_MOD, "\033[17~", 0, 0},
{ XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0},
{ XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0},
{ XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0},
{ XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0},
{ XK_F7, XK_NO_MOD, "\033[18~", 0, 0},
{ XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0},
{ XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0},
{ XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0},
{ XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0},
{ XK_F8, XK_NO_MOD, "\033[19~", 0, 0},
{ XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0},
{ XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0},
{ XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0},
{ XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0},
{ XK_F9, XK_NO_MOD, "\033[20~", 0, 0},
{ XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0},
{ XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0},
{ XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0},
{ XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0},
{ XK_F10, XK_NO_MOD, "\033[21~", 0, 0},
{ XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0},
{ XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0},
{ XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0},
{ XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0},
{ XK_F11, XK_NO_MOD, "\033[23~", 0, 0},
{ XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0},
{ XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0},
{ XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0},
{ XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0},
{ XK_F12, XK_NO_MOD, "\033[24~", 0, 0},
{ XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0},
{ XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0},
{ XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0},
{ XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0},
{ XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0},
{ XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0},
{ XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0},
{ XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0},
{ XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0},
{ XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0},
{ XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0},
{ XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0},
{ XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0},
{ XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0},
{ XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0},
{ XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0},
{ XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0},
{ XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0},
{ XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0},
{ XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0},
{ XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0},
{ XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0},
{ XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0},
{ XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0},
{ XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0},
{ XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0},
{ XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0},
};
/*
* Selection types' masks.
* Use the same masks as usual.
* Button1Mask is always unset, to make masks match between ButtonPress.
* ButtonRelease and MotionNotify.
* If no match is found, regular selection is used.
*/
static uint selmasks[] = {
[SEL_RECTANGULAR] = Mod1Mask,
};
/*
* Printable characters in ASCII, used to estimate the advance width
* of single wide characters.
*/
static char ascii_printable[] =
" !\"#$%&'()*+,-./0123456789:;<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
"`abcdefghijklmnopqrstuvwxyz{|}~";

View File

@@ -1,5 +1,5 @@
# st version # st version
VERSION = 0.9.1 VERSION = 0.9.3
# Customize below to fit your system # Customize below to fit your system

306
st-colorschemes-0.8.5.diff Normal file
View File

@@ -0,0 +1,306 @@
From 9bfbafa1e98c13c039bea4790941e51b3a8054b4 Mon Sep 17 00:00:00 2001
From: Max Schillinger <maxschillinger@web.de>
Date: Thu, 23 Jun 2022 21:58:37 +0200
Subject: [PATCH] Add multiple color schemes and key bindings to change them
This commits adds these color schemes:
- the default (dark) st color scheme
- the default (dark) alacritty color scheme
- One Half (dark & light)
- Solarized (dark & light)
- Gruvbox (dark & light)
Select one with Alt+1..8.
Select the next one with Alt+0.
Select the previous one with Ctrl+Alt+0.
---
config.def.h | 118 +++++++++++++++++++++++++++++++++++++--------------
st.c | 22 ++++++++++
st.h | 2 +
x.c | 52 ++++++++++++++++++++++-
4 files changed, 160 insertions(+), 34 deletions(-)
diff --git a/config.def.h b/config.def.h
index 91ab8ca..38777fe 100644
--- a/config.def.h
+++ b/config.def.h
@@ -93,46 +93,87 @@ char *termname = "st-256color";
*/
unsigned int tabspaces = 8;
-/* Terminal colors (16 first used in escape sequence) */
-static const char *colorname[] = {
- /* 8 normal colors */
- "black",
- "red3",
- "green3",
- "yellow3",
- "blue2",
- "magenta3",
- "cyan3",
- "gray90",
-
- /* 8 bright colors */
- "gray50",
- "red",
- "green",
- "yellow",
- "#5c5cff",
- "magenta",
- "cyan",
- "white",
-
- [255] = 0,
-
- /* more colors can be added after 255 to use with DefaultXX */
- "#cccccc",
- "#555555",
- "gray90", /* default foreground colour */
- "black", /* default background colour */
+typedef struct {
+ const char* const colors[258]; /* terminal colors */
+ unsigned int fg; /* foreground */
+ unsigned int bg; /* background */
+ unsigned int cs; /* cursor */
+ unsigned int rcs; /* reverse cursor */
+} ColorScheme;
+/*
+ * Terminal colors (16 first used in escape sequence,
+ * 2 last for custom cursor color),
+ * foreground, background, cursor, reverse cursor
+ */
+static const ColorScheme schemes[] = {
+ // st (dark)
+ {{"black", "red3", "green3", "yellow3",
+ "blue2", "magenta3", "cyan3", "gray90",
+ "gray50", "red", "green", "yellow",
+ "#5c5cff", "magenta", "cyan", "white",
+ [256]="#cccccc", "#555555"}, 7, 0, 256, 257},
+
+ // Alacritty (dark)
+ {{"#1d1f21", "#cc6666", "#b5bd68", "#f0c674",
+ "#81a2be", "#b294bb", "#8abeb7", "#c5c8c6",
+ "#666666", "#d54e53", "#b9ca4a", "#e7c547",
+ "#7aa6da", "#c397d8", "#70c0b1", "#eaeaea",
+ [256]="#cccccc", "#555555"}, 7, 0, 256, 257},
+
+ // One Half dark
+ {{"#282c34", "#e06c75", "#98c379", "#e5c07b",
+ "#61afef", "#c678dd", "#56b6c2", "#dcdfe4",
+ "#282c34", "#e06c75", "#98c379", "#e5c07b",
+ "#61afef", "#c678dd", "#56b6c2", "#dcdfe4",
+ [256]="#cccccc", "#555555"}, 7, 0, 256, 257},
+
+ // One Half light
+ {{"#fafafa", "#e45649", "#50a14f", "#c18401",
+ "#0184bc", "#a626a4", "#0997b3", "#383a42",
+ "#fafafa", "#e45649", "#50a14f", "#c18401",
+ "#0184bc", "#a626a4", "#0997b3", "#383a42",
+ [256]="#cccccc", "#555555"}, 7, 0, 256, 257},
+
+ // Solarized dark
+ {{"#073642", "#dc322f", "#859900", "#b58900",
+ "#268bd2", "#d33682", "#2aa198", "#eee8d5",
+ "#002b36", "#cb4b16", "#586e75", "#657b83",
+ "#839496", "#6c71c4", "#93a1a1", "#fdf6e3",
+ [256]="#93a1a1", "#fdf6e3"}, 12, 8, 256, 257},
+
+ // Solarized light
+ {{"#eee8d5", "#dc322f", "#859900", "#b58900",
+ "#268bd2", "#d33682", "#2aa198", "#073642",
+ "#fdf6e3", "#cb4b16", "#93a1a1", "#839496",
+ "#657b83", "#6c71c4", "#586e75", "#002b36",
+ [256]="#586e75", "#002b36"}, 12, 8, 256, 257},
+
+ // Gruvbox dark
+ {{"#282828", "#cc241d", "#98971a", "#d79921",
+ "#458588", "#b16286", "#689d6a", "#a89984",
+ "#928374", "#fb4934", "#b8bb26", "#fabd2f",
+ "#83a598", "#d3869b", "#8ec07c", "#ebdbb2",
+ [256]="#ebdbb2", "#555555"}, 15, 0, 256, 257},
+
+ // Gruvbox light
+ {{"#fbf1c7", "#cc241d", "#98971a", "#d79921",
+ "#458588", "#b16286", "#689d6a", "#7c6f64",
+ "#928374", "#9d0006", "#79740e", "#b57614",
+ "#076678", "#8f3f71", "#427b58", "#3c3836",
+ [256]="#3c3836", "#555555"}, 15, 0, 256, 257},
};
+static const char * const * colorname;
+int colorscheme = 0;
/*
* Default colors (colorname index)
* foreground, background, cursor, reverse cursor
*/
-unsigned int defaultfg = 258;
-unsigned int defaultbg = 259;
-unsigned int defaultcs = 256;
-static unsigned int defaultrcs = 257;
+unsigned int defaultfg;
+unsigned int defaultbg;
+unsigned int defaultcs;
+static unsigned int defaultrcs;
/*
* Default shape of cursor
@@ -201,6 +242,17 @@ static Shortcut shortcuts[] = {
{ TERMMOD, XK_Y, selpaste, {.i = 0} },
{ ShiftMask, XK_Insert, selpaste, {.i = 0} },
{ TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
+ { MODKEY, XK_1, selectscheme, {.i = 0} },
+ { MODKEY, XK_2, selectscheme, {.i = 1} },
+ { MODKEY, XK_3, selectscheme, {.i = 2} },
+ { MODKEY, XK_4, selectscheme, {.i = 3} },
+ { MODKEY, XK_5, selectscheme, {.i = 4} },
+ { MODKEY, XK_6, selectscheme, {.i = 5} },
+ { MODKEY, XK_7, selectscheme, {.i = 6} },
+ { MODKEY, XK_8, selectscheme, {.i = 7} },
+ { MODKEY, XK_9, selectscheme, {.i = 8} },
+ { MODKEY, XK_0, nextscheme, {.i = +1} },
+ { MODKEY|ControlMask, XK_0, nextscheme, {.i = -1} },
};
/*
diff --git a/st.c b/st.c
index 51049ba..3ffe333 100644
--- a/st.c
+++ b/st.c
@@ -2196,6 +2196,28 @@ tstrsequence(uchar c)
term.esc |= ESC_STR;
}
+void
+tupdatebgcolor(int oldbg, int newbg)
+{
+ for (int y = 0; y < term.row; y++) {
+ for (int x = 0; x < term.col; x++) {
+ if (term.line[y][x].bg == oldbg)
+ term.line[y][x].bg = newbg;
+ }
+ }
+}
+
+void
+tupdatefgcolor(int oldfg, int newfg)
+{
+ for (int y = 0; y < term.row; y++) {
+ for (int x = 0; x < term.col; x++) {
+ if (term.line[y][x].fg == oldfg)
+ term.line[y][x].fg = newfg;
+ }
+ }
+}
+
void
tcontrolcode(uchar ascii)
{
diff --git a/st.h b/st.h
index 519b9bd..2700de5 100644
--- a/st.h
+++ b/st.h
@@ -90,6 +90,8 @@ int tattrset(int);
void tnew(int, int);
void tresize(int, int);
void tsetdirtattr(int);
+void tupdatebgcolor(int, int);
+void tupdatefgcolor(int, int);
void ttyhangup(void);
int ttynew(const char *, char *, const char *, char **);
size_t ttyread(void);
diff --git a/x.c b/x.c
index 8a16faa..bc0a48c 100644
--- a/x.c
+++ b/x.c
@@ -59,6 +59,8 @@ static void zoom(const Arg *);
static void zoomabs(const Arg *);
static void zoomreset(const Arg *);
static void ttysend(const Arg *);
+static void nextscheme(const Arg *);
+static void selectscheme(const Arg *);
/* config.h for applying patches and the configuration. */
#include "config.h"
@@ -185,6 +187,7 @@ static void mousesel(XEvent *, int);
static void mousereport(XEvent *);
static char *kmap(KeySym, uint);
static int match(uint, uint);
+static void updatescheme(void);
static void run(void);
static void usage(void);
@@ -785,7 +788,7 @@ xloadcols(void)
for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp)
XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
} else {
- dc.collen = MAX(LEN(colorname), 256);
+ dc.collen = 258;
dc.col = xmalloc(dc.collen * sizeof(Color));
}
@@ -2008,6 +2011,47 @@ usage(void)
" [stty_args ...]\n", argv0, argv0);
}
+void
+nextscheme(const Arg *arg)
+{
+ colorscheme += arg->i;
+ if (colorscheme >= (int)LEN(schemes))
+ colorscheme = 0;
+ else if (colorscheme < 0)
+ colorscheme = LEN(schemes) - 1;
+ updatescheme();
+}
+
+void
+selectscheme(const Arg *arg)
+{
+ if (BETWEEN(arg->i, 0, LEN(schemes)-1)) {
+ colorscheme = arg->i;
+ updatescheme();
+ }
+}
+
+void
+updatescheme(void)
+{
+ int oldbg, oldfg;
+
+ oldbg = defaultbg;
+ oldfg = defaultfg;
+ colorname = schemes[colorscheme].colors;
+ defaultbg = schemes[colorscheme].bg;
+ defaultfg = schemes[colorscheme].fg;
+ defaultcs = schemes[colorscheme].cs;
+ defaultrcs = schemes[colorscheme].rcs;
+ xloadcols();
+ if (defaultbg != oldbg)
+ tupdatebgcolor(oldbg, defaultbg);
+ if (defaultfg != oldfg)
+ tupdatefgcolor(oldfg, defaultfg);
+ cresize(win.w, win.h);
+ redraw();
+}
+
int
main(int argc, char *argv[])
{
@@ -2060,6 +2104,12 @@ main(int argc, char *argv[])
} ARGEND;
run:
+ colorname = schemes[colorscheme].colors;
+ defaultbg = schemes[colorscheme].bg;
+ defaultfg = schemes[colorscheme].fg;
+ defaultcs = schemes[colorscheme].cs;
+ defaultrcs = schemes[colorscheme].rcs;
+
if (argc > 0) /* eat all remaining arguments */
opt_cmd = argv;
--
2.36.1

74
st.c
View File

@@ -1132,6 +1132,7 @@ csiparse(void)
{ {
char *p = csiescseq.buf, *np; char *p = csiescseq.buf, *np;
long int v; long int v;
int sep = ';'; /* colon or semi-colon, but not both */
csiescseq.narg = 0; csiescseq.narg = 0;
if (*p == '?') { if (*p == '?') {
@@ -1149,7 +1150,9 @@ csiparse(void)
v = -1; v = -1;
csiescseq.arg[csiescseq.narg++] = v; csiescseq.arg[csiescseq.narg++] = v;
p = np; 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; break;
p++; p++;
} }
@@ -1417,16 +1420,22 @@ tsetattr(const int *attr, int l)
if ((idx = tdefcolor(attr, &i, l)) >= 0) if ((idx = tdefcolor(attr, &i, l)) >= 0)
term.c.attr.fg = idx; term.c.attr.fg = idx;
break; break;
case 39: case 39: /* set foreground color to default */
term.c.attr.fg = defaultfg; term.c.attr.fg = defaultfg;
break; break;
case 48: case 48:
if ((idx = tdefcolor(attr, &i, l)) >= 0) if ((idx = tdefcolor(attr, &i, l)) >= 0)
term.c.attr.bg = idx; term.c.attr.bg = idx;
break; break;
case 49: case 49: /* set background color to default */
term.c.attr.bg = defaultbg; term.c.attr.bg = defaultbg;
break; break;
case 58:
/* This starts a sequence to change the color of
* "underline" pixels. We don't support that and
* instead eat up a following "5;n" or "2;r;g;b". */
tdefcolor(attr, &i, l);
break;
default: default:
if (BETWEEN(attr[i], 30, 37)) { if (BETWEEN(attr[i], 30, 37)) {
term.c.attr.fg = attr[i] - 30; term.c.attr.fg = attr[i] - 30;
@@ -1523,7 +1532,7 @@ tsetmode(int priv, int set, const int *args, int narg)
case 1006: /* 1006: extended reporting mode */ case 1006: /* 1006: extended reporting mode */
xsetmode(set, MODE_MOUSESGR); xsetmode(set, MODE_MOUSESGR);
break; break;
case 1034: case 1034: /* 1034: enable 8-bit mode for keyboard input */
xsetmode(set, MODE_8BIT); xsetmode(set, MODE_8BIT);
break; break;
case 1049: /* swap screen & set/restore cursor as xterm */ case 1049: /* swap screen & set/restore cursor as xterm */
@@ -1531,8 +1540,8 @@ tsetmode(int priv, int set, const int *args, int narg)
break; break;
tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD);
/* FALLTHROUGH */ /* FALLTHROUGH */
case 47: /* swap screen */ case 47: /* swap screen buffer */
case 1047: case 1047: /* swap screen buffer */
if (!allowaltscreen) if (!allowaltscreen)
break; break;
alt = IS_SET(MODE_ALTSCREEN); alt = IS_SET(MODE_ALTSCREEN);
@@ -1545,7 +1554,7 @@ tsetmode(int priv, int set, const int *args, int narg)
if (*args != 1049) if (*args != 1049)
break; break;
/* FALLTHROUGH */ /* FALLTHROUGH */
case 1048: case 1048: /* save/restore cursor (like DECSC/DECRC) */
tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD);
break; break;
case 2004: /* 2004: bracketed paste mode */ case 2004: /* 2004: bracketed paste mode */
@@ -1702,7 +1711,7 @@ csihandle(void)
} }
break; break;
case 1: /* above */ 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, 0, term.col-1, term.c.y-1);
tclearregion(0, term.c.y, term.c.x, term.c.y); tclearregion(0, term.c.y, term.c.x, term.c.y);
break; break;
@@ -1798,7 +1807,11 @@ csihandle(void)
tcursor(CURSOR_SAVE); tcursor(CURSOR_SAVE);
break; break;
case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */ case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */
tcursor(CURSOR_LOAD); if (csiescseq.priv) {
goto unknown;
} else {
tcursor(CURSOR_LOAD);
}
break; break;
case ' ': case ' ':
switch (csiescseq.mode[1]) { switch (csiescseq.mode[1]) {
@@ -1900,7 +1913,7 @@ strhandle(void)
if (narg > 1) if (narg > 1)
xsettitle(strescseq.args[1]); xsettitle(strescseq.args[1]);
return; return;
case 52: case 52: /* manipulate selection data */
if (narg > 2 && allowwindowops) { if (narg > 2 && allowwindowops) {
dec = base64dec(strescseq.args[2]); dec = base64dec(strescseq.args[2]);
if (dec) { if (dec) {
@@ -1911,9 +1924,9 @@ strhandle(void)
} }
} }
return; return;
case 10: case 10: /* set dynamic VT100 text foreground color */
case 11: case 11: /* set dynamic VT100 text background color */
case 12: case 12: /* set dynamic text cursor color */
if (narg < 2) if (narg < 2)
break; break;
p = strescseq.args[1]; p = strescseq.args[1];
@@ -1954,6 +1967,19 @@ strhandle(void)
tfulldirt(); tfulldirt();
} }
return; return;
case 110: /* reset dynamic VT100 text foreground color */
case 111: /* reset dynamic VT100 text background color */
case 112: /* reset dynamic text cursor color */
if (narg != 1)
break;
if ((j = par - 110) < 0 || j >= LEN(osc_table))
break; /* shouldn't be possible */
if (xsetcolorname(osc_table[j].idx, NULL)) {
fprintf(stderr, "erresc: %s color not found\n", osc_table[j].str);
} else {
tfulldirt();
}
return;
} }
break; break;
case 'k': /* old title set compatibility */ case 'k': /* old title set compatibility */
@@ -2172,6 +2198,28 @@ tstrsequence(uchar c)
term.esc |= ESC_STR; term.esc |= ESC_STR;
} }
void
tupdatebgcolor(int oldbg, int newbg)
{
for (int y = 0; y < term.row; y++) {
for (int x = 0; x < term.col; x++) {
if (term.line[y][x].bg == oldbg)
term.line[y][x].bg = newbg;
}
}
}
void
tupdatefgcolor(int oldfg, int newfg)
{
for (int y = 0; y < term.row; y++) {
for (int x = 0; x < term.col; x++) {
if (term.line[y][x].fg == oldfg)
term.line[y][x].fg = newfg;
}
}
}
void void
tcontrolcode(uchar ascii) tcontrolcode(uchar ascii)
{ {

2
st.h
View File

@@ -90,6 +90,8 @@ int tattrset(int);
void tnew(int, int); void tnew(int, int);
void tresize(int, int); void tresize(int, int);
void tsetdirtattr(int); void tsetdirtattr(int);
void tupdatebgcolor(int, int);
void tupdatefgcolor(int, int);
void ttyhangup(void); void ttyhangup(void);
int ttynew(const char *, char *, const char *, char **); int ttynew(const char *, char *, const char *, char **);
size_t ttyread(void); size_t ttyread(void);

63
x.c
View File

@@ -59,6 +59,8 @@ static void zoom(const Arg *);
static void zoomabs(const Arg *); static void zoomabs(const Arg *);
static void zoomreset(const Arg *); static void zoomreset(const Arg *);
static void ttysend(const Arg *); static void ttysend(const Arg *);
static void nextscheme(const Arg *);
static void selectscheme(const Arg *);
/* config.h for applying patches and the configuration. */ /* config.h for applying patches and the configuration. */
#include "config.h" #include "config.h"
@@ -185,6 +187,7 @@ static void mousesel(XEvent *, int);
static void mousereport(XEvent *); static void mousereport(XEvent *);
static char *kmap(KeySym, uint); static char *kmap(KeySym, uint);
static int match(uint, uint); static int match(uint, uint);
static void updatescheme(void);
static void run(void); static void run(void);
static void usage(void); static void usage(void);
@@ -801,7 +804,7 @@ xloadcols(void)
for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp) for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp)
XftColorFree(xw.dpy, xw.vis, xw.cmap, cp); XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
} else { } else {
dc.collen = MAX(LEN(colorname), 256); dc.collen = 258;
dc.col = xmalloc(dc.collen * sizeof(Color)); dc.col = xmalloc(dc.collen * sizeof(Color));
} }
@@ -1131,7 +1134,7 @@ xinit(int cols, int rows)
{ {
XGCValues gcvalues; XGCValues gcvalues;
Cursor cursor; Cursor cursor;
Window parent; Window parent, root;
pid_t thispid = getpid(); pid_t thispid = getpid();
XColor xmousefg, xmousebg; XColor xmousefg, xmousebg;
@@ -1168,16 +1171,19 @@ xinit(int cols, int rows)
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
xw.attrs.colormap = xw.cmap; xw.attrs.colormap = xw.cmap;
root = XRootWindow(xw.dpy, xw.scr);
if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0))))
parent = XRootWindow(xw.dpy, xw.scr); parent = root;
xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, xw.win = XCreateWindow(xw.dpy, root, xw.l, xw.t,
win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
| CWEventMask | CWColormap, &xw.attrs); | CWEventMask | CWColormap, &xw.attrs);
if (parent != root)
XReparentWindow(xw.dpy, xw.win, parent, xw.l, xw.t);
memset(&gcvalues, 0, sizeof(gcvalues)); memset(&gcvalues, 0, sizeof(gcvalues));
gcvalues.graphics_exposures = False; gcvalues.graphics_exposures = False;
dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, dc.gc = XCreateGC(xw.dpy, xw.win, GCGraphicsExposures,
&gcvalues); &gcvalues);
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
DefaultDepth(xw.dpy, xw.scr)); DefaultDepth(xw.dpy, xw.scr));
@@ -2033,6 +2039,47 @@ usage(void)
" [stty_args ...]\n", argv0, argv0); " [stty_args ...]\n", argv0, argv0);
} }
void
nextscheme(const Arg *arg)
{
colorscheme += arg->i;
if (colorscheme >= (int)LEN(schemes))
colorscheme = 0;
else if (colorscheme < 0)
colorscheme = LEN(schemes) - 1;
updatescheme();
}
void
selectscheme(const Arg *arg)
{
if (BETWEEN(arg->i, 0, LEN(schemes)-1)) {
colorscheme = arg->i;
updatescheme();
}
}
void
updatescheme(void)
{
int oldbg, oldfg;
oldbg = defaultbg;
oldfg = defaultfg;
colorname = schemes[colorscheme].colors;
defaultbg = schemes[colorscheme].bg;
defaultfg = schemes[colorscheme].fg;
defaultcs = schemes[colorscheme].cs;
defaultrcs = schemes[colorscheme].rcs;
xloadcols();
if (defaultbg != oldbg)
tupdatebgcolor(oldbg, defaultbg);
if (defaultfg != oldfg)
tupdatefgcolor(oldfg, defaultfg);
cresize(win.w, win.h);
redraw();
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
@@ -2085,6 +2132,12 @@ main(int argc, char *argv[])
} ARGEND; } ARGEND;
run: run:
colorname = schemes[colorscheme].colors;
defaultbg = schemes[colorscheme].bg;
defaultfg = schemes[colorscheme].fg;
defaultcs = schemes[colorscheme].cs;
defaultrcs = schemes[colorscheme].rcs;
if (argc > 0) /* eat all remaining arguments */ if (argc > 0) /* eat all remaining arguments */
opt_cmd = argv; opt_cmd = argv;