Patch to add customizable character cursors to st terminal.

Replaces block cursor with any Unicode character or hex codepoint.
Supports strings like "," ";" "●" and hex like "0xf0159".
Falls back to normal block when disabled.

Tested on latest st master.
---
 .../patches/anychar-cursor/index.md           | 28 ++++++
 .../st-anychar-cursor-20260205-b842baa.diff   | 86 +++++++++++++++++++
 2 files changed, 114 insertions(+)
 create mode 100644 st.suckless.org/patches/anychar-cursor/index.md
 create mode 100644 
st.suckless.org/patches/anychar-cursor/st-anychar-cursor-20260205-b842baa.diff

diff --git a/st.suckless.org/patches/anychar-cursor/index.md 
b/st.suckless.org/patches/anychar-cursor/index.md
new file mode 100644
index 0000000..2e39c4a
--- /dev/null
+++ b/st.suckless.org/patches/anychar-cursor/index.md
@@ -0,0 +1,28 @@
+anychar-cursor
+==============
+
+Extends the available cursor shape options to allow the use of arbitrary 
characters as the cursor. It supports both direct Unicode characters (e.g., 
`"●", "→"`) and hex codepoint notation (e.g., `"0xf0159"` for Nerd Font glyphs).
+
+Unlike the existing customcursor patch, which overrides the snowman in case 7, 
this patch replaces only case 0 for user-defined characters, preserving all 
original cursor shapes and functionality.
+
+Usage
+-----
+
+-  Set `cursorshape = 0;` in config.h/config.def.h
+-  Set cursorchar to desired character:
+    - Direct: cursorchar = "❤" or "<"
+    - Hex:    cursorchar = "0x2022"
+
+To return to the default ST cursor:
+
+`static const char *cursorchar = NULL;`
+
+
+Download
+--------
+* 
[st-anychar-cursor-20260205-b842baa.diff](st-anychar-cursor-20260205-b842baa.diff)
+
+Authors
+-------
+* Pearljak - <[email protected]>
+
diff --git 
a/st.suckless.org/patches/anychar-cursor/st-anychar-cursor-20260205-b842baa.diff
 
b/st.suckless.org/patches/anychar-cursor/st-anychar-cursor-20260205-b842baa.diff
new file mode 100644
index 0000000..4d2a32e
--- /dev/null
+++ 
b/st.suckless.org/patches/anychar-cursor/st-anychar-cursor-20260205-b842baa.diff
@@ -0,0 +1,86 @@
+From b842baa02456541db4cb18e7df7df834d269ff7c Mon Sep 17 00:00:00 2001
+From: unplebs <[email protected]>
+Date: Fri, 6 Feb 2026 18:01:06 +0100
+Subject: [PATCH] anychar-cursor: display any character or codepoint as cursor
+---
+
+Extends the cursor shape options to allow using arbitrary characters
+as the cursor. Supports both direct Unicode strings (e.g "●", "→")
+and hex codepoint notation (e.g "0xf0159" for nerd font glyphs).
+
+Unlike the existing customcursor patch which replaces case 7's snowman,
+this replaces case 0 specifically for user-defined characters, keeping
+all existing cursor shapes intact and functional.
+
+Usage:
+  Set cursorshape = 0 in config.h/config.def.h
+  Set cursorchar to desired character:
+    - Direct: cursorchar = "❤" or "<"
+    - Hex:    cursorchar = "0x2022"
+
+
+---
+ config.def.h |  4 ++++
+ x.c          | 28 +++++++++++++++++++++++++++-
+ 2 files changed, 31 insertions(+), 1 deletion(-)
+
+diff --git a/config.def.h b/config.def.h
+index 2cd740a..232a349 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -140,9 +140,13 @@ static unsigned int defaultrcs = 257;
+  * 4: Underline ("_")
+  * 6: Bar ("|")
+  * 7: Snowman ("☃")
++ * 0: AnyChar ("see cursorchar")
+  */
+ static unsigned int cursorshape = 2;
+ 
++// Character to use for cursorshape = 0
++static const char *cursorchar = ";";
++
+ /*
+  * Default columns and rows numbers
+  */
+diff --git a/x.c b/x.c
+index d73152b..86d88f3 100644
+--- a/x.c
++++ b/x.c
+@@ -1564,7 +1564,33 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, 
Glyph og)
+               case 7: /* st extension */
+                       g.u = 0x2603; /* snowman (U+2603) */
+                       /* FALLTHROUGH */
+-              case 0: /* Blinking Block */
++              case 0: /* anychar (user defined) */
++                      {
++                      extern const char *cursorchar;
++                      char utf8[4];
++                      int len;
++                      const char *str_to_draw;
++
++                      if (cursorchar != NULL && cursorchar[0] == '0' && 
cursorchar[1] == 'x') {
++                              unsigned int codepoint = strtoul(cursorchar, 
NULL, 16);
++                              len = utf8encode(codepoint, utf8);
++                              str_to_draw = utf8;
++                      } else if (cursorchar != NULL && cursorchar[0] != '\0') 
{       
++                              str_to_draw = cursorchar;
++                              len = strlen(cursorchar);
++                      } else {
++                              len = utf8encode(';', utf8);
++                              str_to_draw = utf8;
++                      }
++
++                      XftDrawStringUtf8(xw.draw, &drawcol,
++                                                       dc.font.match,
++                                                       borderpx + cx * win.cw,
++                                                       borderpx + cy * win.ch 
+ dc.font.ascent,
++                                                       (FcChar8 
*)str_to_draw, len);
++                      }
++                      break;
++                      /* case 0 draws directly, no fallthrough */
+               case 1: /* Blinking Block (Default) */
+               case 2: /* Steady Block */
+                       xdrawglyph(g, cx, cy);
+-- 
+2.52.0
+
-- 
2.52.0


Reply via email to