чување 76829c9d18d566c0d364f9145a7ea4271b6dd17c
родитељ 6ed1c5a1f6d7ae59a0d15141399958c6a04586d2
Аутор: Страхиња Радић <sr@strahinja.org>
Датум: Thu, 8 Aug 2024 21:36:03 +0200
patch/syntax.patch: Account for systems where wchar_t is 16-bit
Diffstat:
| M | patch/syntax.patch | | | 302 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
измењених датотека: 1, додавања: 158(+), брисања: 144(-)
diff --git a/patch/syntax.patch b/patch/syntax.patch
@@ -1,6 +1,6 @@
-From 7986fc8772e59f32706c3ba8289550657b8f9df6 Mon Sep 17 00:00:00 2001
+From 9fba930eb350fc45fab6d21c12fb9efc1d9c18fe Mon Sep 17 00:00:00 2001
From: Страхиња Радић <sr@strahinja.org>
-Date: Thu Aug 8 09:49:22 2024 UTC
+Date: Thu Aug 8 19:35:11 2024 UTC
Subject: [PATCH] Add syntax highlighting
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
@@ -8,13 +8,13 @@ Content-Transfer-Encoding: 8bit
---
config.def.h | 7+ 0-
- draw.c | 481+ 29-
- draw.h | 62+ 6-
+ draw.c | 487+ 29-
+ draw.h | 63+ 6-
sled.c | 82+ 16-
- 4 files changed, 632 insertions(+), 51 deletions(-)
+ 4 files changed, 639 insertions(+), 51 deletions(-)
diff --git a/config.def.h b/config.def.h
-index e42175108..7986fc877 100644
+index f72c9de89..9fba930eb 100644
--- a/config.def.h
+++ b/config.def.h
@@ -239,6 +239,13 @@ static const struct Key command_keys[] = {
@@ -32,7 +32,7 @@ index e42175108..7986fc877 100644
{.format = "%s%s",
.callback = format_filename,
diff --git a/draw.c b/draw.c
-index e42175108..7986fc877 100644
+index f72c9de89..9fba930eb 100644
--- a/draw.c
+++ b/draw.c
@@ -3,6 +3,7 @@
@@ -43,132 +43,129 @@ index e42175108..7986fc877 100644
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
-@@ -14,6 +15,28 @@
+@@ -14,6 +15,25 @@
#include "util.h"
#include "version.h"
+/* Keyword initializer specification macro */
-+#define KW(literal) \
-+ { \
-+ .text = (uint32_t*)literal, \
-+ .size = sizeof(literal) / sizeof(uint32_t) \
++#define KW(literal) \
++ { \
++ .text = literal, .size = sizeof(literal) / sizeof(*literal) \
+ }
+/* Single-line comment specification macro */
-+#define SLC(com) \
-+ { \
-+ .start_text = (uint32_t*)com, \
-+ .start_size = sizeof(com) / sizeof(uint32_t), \
-+ .end_text = NULL, .end_size = -1 \
++#define SLC(com) \
++ { \
++ .start_text = com, .start_size = sizeof(com) / sizeof(*com), \
++ .end_text = NULL, .end_size = -1 \
+ }
+/* Area comment specification macro */
-+#define AC(com1, com2) \
-+ { \
-+ .start_text = (uint32_t*)com1, \
-+ .start_size = sizeof(com1) / sizeof(uint32_t), \
-+ .end_text = (uint32_t*)com2, \
-+ .end_size = sizeof(com2) / sizeof(uint32_t) \
++#define AC(com1, com2) \
++ { \
++ .start_text = com1, \
++ .start_size = sizeof(com1) / sizeof(*com1), .end_text = com2, \
++ .end_size = sizeof(com2) / sizeof(*com2) \
+ }
+
enum {
UNKNOWN_MODE,
COMMAND_MODE,
-@@ -88,6 +111,95 @@ static const struct {
+@@ -88,6 +108,95 @@ static const struct {
{ .boundary = 99, .width = 3 },
{ .boundary = 9, .width = 2 }
};
+extern const struct Color syntax_colors[];
+const struct Keyword c_keywords[] = {
-+ KW(L"auto"), KW(L"break"), KW(L"case"), KW(L"char"), KW(L"const"),
-+ KW(L"continue"), KW(L"default"), KW(L"do"), KW(L"double"), KW(L"else"),
-+ KW(L"enum"), KW(L"extern"), KW(L"float"), KW(L"for"), KW(L"goto"),
-+ KW(L"if"), KW(L"inline"), KW(L"int"), KW(L"long"), KW(L"register"),
-+ KW(L"restrict"), KW(L"return"), KW(L"short"), KW(L"signed"),
-+ KW(L"sizeof"), KW(L"static"), KW(L"struct"), KW(L"switch"),
-+ KW(L"typedef"), KW(L"union"), KW(L"unsigned"), KW(L"void"),
-+ KW(L"volatile"), KW(L"while"), KW(L"_Bool"), KW(L"_Complex"),
-+ KW(L"_Imaginary"),
++ KW("auto"), KW("break"), KW("case"), KW("char"), KW("const"),
++ KW("continue"), KW("default"), KW("do"), KW("double"), KW("else"),
++ KW("enum"), KW("extern"), KW("float"), KW("for"), KW("goto"),
++ KW("if"), KW("inline"), KW("int"), KW("long"), KW("register"),
++ KW("restrict"), KW("return"), KW("short"), KW("signed"),
++ KW("sizeof"), KW("static"), KW("struct"), KW("switch"),
++ KW("typedef"), KW("union"), KW("unsigned"), KW("void"),
++ KW("volatile"), KW("while"), KW("_Bool"), KW("_Complex"),
++ KW("_Imaginary"),
+ { .text = NULL }
+};
+const struct Comment c_comments[] = {
-+ SLC(L"//"),
-+ AC(L"/*", L"*/"),
++ SLC("//"),
++ AC("/*", "*/"),
+ { .start_text = NULL }
+};
+const struct Operator c_operators[] = {
-+ KW(L"<<="), KW(L">>="), KW(L"<<"), KW(L">>"),
-+ KW(L"+="), KW(L"-="), KW(L"*="), KW(L"/="), KW(L"%="),
-+ KW(L"&="), KW(L"|="), KW(L"^="),
-+ KW(L"=="), KW(L"!="), KW(L"<="), KW(L">="),
-+ KW(L"->"),
-+ KW(L"++"), KW(L"--"),
-+ KW(L"&&"), KW(L"||"),
-+ KW(L"="), KW(L"+"), KW(L"-"), KW(L"~"), KW(L"*"), KW(L"/"), KW(L"%"),
-+ KW(L"&"), KW(L"|"), KW(L"^"), KW(L"!"),
-+ KW(L"<"), KW(L">"),
-+ KW(L","), KW(L";"), KW(L":"), KW(L"?"), KW(L"."),
-+ KW(L"("), KW(L")"), KW(L"["), KW(L"]"), KW(L"{"), KW(L"}"),
++ KW("<<="), KW(">>="), KW("<<"), KW(">>"),
++ KW("+="), KW("-="), KW("*="), KW("/="), KW("%="),
++ KW("&="), KW("|="), KW("^="),
++ KW("=="), KW("!="), KW("<="), KW(">="),
++ KW("->"),
++ KW("++"), KW("--"),
++ KW("&&"), KW("||"),
++ KW("="), KW("+"), KW("-"), KW("~"), KW("*"), KW("/"), KW("%"),
++ KW("&"), KW("|"), KW("^"), KW("!"),
++ KW("<"), KW(">"),
++ KW(","), KW(";"), KW(":"), KW("?"), KW("."),
++ KW("("), KW(")"), KW("["), KW("]"), KW("{"), KW("}"),
+ { .text = NULL }
+};
+const struct Keyword shell_keywords[] = {
-+ KW(L"!"), KW(L"{"), KW(L"}"),
-+ KW(L"case"), KW(L"do"), KW(L"done"), KW(L"elif"), KW(L"else"),
-+ KW(L"esac"), KW(L"fi"), KW(L"for"), KW(L"if"), KW(L"in"), KW(L"then"),
-+ KW(L"until"), KW(L"while"), KW(L"[["), KW(L"]]"), KW(L"function"),
-+ KW(L"select"), KW(L"admin"), KW(L"alias"), KW(L"ar"), KW(L"asa"),
-+ KW(L"at"), KW(L"awk"), KW(L"basename"), KW(L"batch"), KW(L"bc"),
-+ KW(L"bg"), KW(L"break"), KW(L"c99"), KW(L"cal"), KW(L"cat"), KW(L"cd"),
-+ KW(L"cflow"), KW(L"chgrp"), KW(L"chmod"), KW(L"chown"), KW(L"cksum"),
-+ KW(L"cmp"), KW(L"colon"), KW(L"comm"), KW(L"command"), KW(L"compress"),
-+ KW(L"continue"), KW(L"cp"), KW(L"crontab"), KW(L"csplit"), KW(L"ctags"),
-+ KW(L"cut"), KW(L"cxref"), KW(L"date"), KW(L"dd"), KW(L"delta"),
-+ KW(L"df"), KW(L"diff"), KW(L"dirname"), KW(L"dot"), KW(L"du"),
-+ KW(L"echo"), KW(L"ed"), KW(L"env"), KW(L"eval"), KW(L"ex"), KW(L"exec"),
-+ KW(L"exit"), KW(L"expand"), KW(L"export"), KW(L"expr"), KW(L"false"),
-+ KW(L"fc"), KW(L"fg"), KW(L"file"), KW(L"find"), KW(L"fold"),
-+ KW(L"fort77"), KW(L"fuser"), KW(L"gencat"), KW(L"get"), KW(L"getconf"),
-+ KW(L"getopts"), KW(L"grep"), KW(L"hash"), KW(L"head"), KW(L"iconv"),
-+ KW(L"id"), KW(L"ipcrm"), KW(L"ipcs"), KW(L"jobs"), KW(L"join"),
-+ KW(L"kill"), KW(L"lex"), KW(L"link"), KW(L"ln"), KW(L"locale"),
-+ KW(L"localedef"), KW(L"logger"), KW(L"logname"), KW(L"lp"), KW(L"ls"),
-+ KW(L"m4"), KW(L"mailx"), KW(L"make"), KW(L"man"), KW(L"mesg"),
-+ KW(L"mkdir"), KW(L"mkfifo"), KW(L"more"), KW(L"mv"), KW(L"newgrp"),
-+ KW(L"nice"), KW(L"nl"), KW(L"nm"), KW(L"nohup"), KW(L"od"),
-+ KW(L"paste"), KW(L"patch"), KW(L"pathchk"), KW(L"pax"), KW(L"pr"),
-+ KW(L"printf"), KW(L"prs"), KW(L"ps"), KW(L"pwd"), KW(L"qalter"),
-+ KW(L"qdel"), KW(L"qhold"), KW(L"qmove"), KW(L"qmsg"), KW(L"qrerun"),
-+ KW(L"qrls"), KW(L"qselect"), KW(L"qsig"), KW(L"qstat"), KW(L"qsub"),
-+ KW(L"read"), KW(L"readonly"), KW(L"renice"), KW(L"return"), KW(L"rm"),
-+ KW(L"rmdel"), KW(L"rmdir"), KW(L"sact"), KW(L"sccs"), KW(L"sed"),
-+ KW(L"set"), KW(L"sh"), KW(L"shift"), KW(L"sleep"), KW(L"sort"),
-+ KW(L"split"), KW(L"strings"), KW(L"strip"), KW(L"stty"), KW(L"tabs"),
-+ KW(L"tail"), KW(L"talk"), KW(L"tee"), KW(L"test"), KW(L"time"),
-+ KW(L"times"), KW(L"touch"), KW(L"tput"), KW(L"tr"), KW(L"trap"),
-+ KW(L"true"), KW(L"tsort"), KW(L"tty"), KW(L"type"), KW(L"ulimit"),
-+ KW(L"umask"), KW(L"unalias"), KW(L"uname"), KW(L"uncompress"),
-+ KW(L"unexpand"), KW(L"unget"), KW(L"uniq"), KW(L"unlink"), KW(L"unset"),
-+ KW(L"uucp"), KW(L"uudecode"), KW(L"uuencode"), KW(L"uustat"),
-+ KW(L"uux"), KW(L"val"), KW(L"vi"), KW(L"wait"), KW(L"wc"), KW(L"what"),
-+ KW(L"who"), KW(L"write"), KW(L"xargs"), KW(L"yacc"), KW(L"zcat"),
-+ KW(L"break"), KW(L":"), KW(L"."), KW(L"continue"), KW(L"eval"),
-+ KW(L"exec"), KW(L"exit"), KW(L"export"), KW(L"readonly"), KW(L"return"),
-+ KW(L"set"), KW(L"shift"), KW(L"times"), KW(L"trap"), KW(L"unset"),
++ KW("!"), KW("{"), KW("}"),
++ KW("case"), KW("do"), KW("done"), KW("elif"), KW("else"),
++ KW("esac"), KW("fi"), KW("for"), KW("if"), KW("in"), KW("then"),
++ KW("until"), KW("while"), KW("[["), KW("]]"), KW("function"),
++ KW("select"), KW("admin"), KW("alias"), KW("ar"), KW("asa"),
++ KW("at"), KW("awk"), KW("basename"), KW("batch"), KW("bc"),
++ KW("bg"), KW("break"), KW("c99"), KW("cal"), KW("cat"), KW("cd"),
++ KW("cflow"), KW("chgrp"), KW("chmod"), KW("chown"), KW("cksum"),
++ KW("cmp"), KW("colon"), KW("comm"), KW("command"), KW("compress"),
++ KW("continue"), KW("cp"), KW("crontab"), KW("csplit"), KW("ctags"),
++ KW("cut"), KW("cxref"), KW("date"), KW("dd"), KW("delta"),
++ KW("df"), KW("diff"), KW("dirname"), KW("dot"), KW("du"),
++ KW("echo"), KW("ed"), KW("env"), KW("eval"), KW("ex"), KW("exec"),
++ KW("exit"), KW("expand"), KW("export"), KW("expr"), KW("false"),
++ KW("fc"), KW("fg"), KW("file"), KW("find"), KW("fold"),
++ KW("fort77"), KW("fuser"), KW("gencat"), KW("get"), KW("getconf"),
++ KW("getopts"), KW("grep"), KW("hash"), KW("head"), KW("iconv"),
++ KW("id"), KW("ipcrm"), KW("ipcs"), KW("jobs"), KW("join"),
++ KW("kill"), KW("lex"), KW("link"), KW("ln"), KW("locale"),
++ KW("localedef"), KW("logger"), KW("logname"), KW("lp"), KW("ls"),
++ KW("m4"), KW("mailx"), KW("make"), KW("man"), KW("mesg"),
++ KW("mkdir"), KW("mkfifo"), KW("more"), KW("mv"), KW("newgrp"),
++ KW("nice"), KW("nl"), KW("nm"), KW("nohup"), KW("od"),
++ KW("paste"), KW("patch"), KW("pathchk"), KW("pax"), KW("pr"),
++ KW("printf"), KW("prs"), KW("ps"), KW("pwd"), KW("qalter"),
++ KW("qdel"), KW("qhold"), KW("qmove"), KW("qmsg"), KW("qrerun"),
++ KW("qrls"), KW("qselect"), KW("qsig"), KW("qstat"), KW("qsub"),
++ KW("read"), KW("readonly"), KW("renice"), KW("return"), KW("rm"),
++ KW("rmdel"), KW("rmdir"), KW("sact"), KW("sccs"), KW("sed"),
++ KW("set"), KW("sh"), KW("shift"), KW("sleep"), KW("sort"),
++ KW("split"), KW("strings"), KW("strip"), KW("stty"), KW("tabs"),
++ KW("tail"), KW("talk"), KW("tee"), KW("test"), KW("time"),
++ KW("times"), KW("touch"), KW("tput"), KW("tr"), KW("trap"),
++ KW("true"), KW("tsort"), KW("tty"), KW("type"), KW("ulimit"),
++ KW("umask"), KW("unalias"), KW("uname"), KW("uncompress"),
++ KW("unexpand"), KW("unget"), KW("uniq"), KW("unlink"), KW("unset"),
++ KW("uucp"), KW("uudecode"), KW("uuencode"), KW("uustat"),
++ KW("uux"), KW("val"), KW("vi"), KW("wait"), KW("wc"), KW("what"),
++ KW("who"), KW("write"), KW("xargs"), KW("yacc"), KW("zcat"),
++ KW("break"), KW(":"), KW("."), KW("continue"), KW("eval"),
++ KW("exec"), KW("exit"), KW("export"), KW("readonly"), KW("return"),
++ KW("set"), KW("shift"), KW("times"), KW("trap"), KW("unset"),
+ {.text = NULL}
+};
+const struct Comment shell_comments[] = {
-+ SLC(L"#"),
++ SLC("#"),
+ {.start_text = NULL}
+};
+const struct Operator shell_operators[] = {
-+ KW(L"<<"), KW(L">>"),
-+ KW(L"&&"), KW(L"||"), KW(L"$"), KW(L"`"), KW(L"="),
-+ KW(L"<"), KW(L">"),
-+ KW(L";"), KW(L"("), KW(L")"), KW(L"["), KW(L"]"), KW(L"{"), KW(L"}"),
++ KW("<<"), KW(">>"),
++ KW("&&"), KW("||"), KW("$"), KW("`"), KW("="),
++ KW("<"), KW(">"),
++ KW(";"), KW("("), KW(")"), KW("["), KW("]"), KW("{"), KW("}"),
+ {.text = NULL}
+};
const char* go_to_dialog_title = "Go to line";
const char* prompt_dirty = "File changed, save [y/n/ESC]?";
const char* prompt_overwrite = "Not empty, overwrite? [y/n/ESC]?";
-@@ -96,6 +208,46 @@ const char* replace_dialog_title = "Replace with";
+@@ -96,6 +205,46 @@ const char* replace_dialog_title = "Replace with";
const char* search_dialog_title = "Search text";
/* clang-format on */
@@ -215,7 +212,7 @@ index e42175108..7986fc877 100644
void get_selection(int* ssr, int* ssc, int* ser, int* sec,
const struct DrawState* state);
-@@ -265,15 +417,15 @@ draw_help(const struct DrawState* state)
+@@ -265,15 +414,15 @@ draw_help(const struct DrawState* state)
endy = h > maxy - 1 ? maxy - 2 : starty + h;
draw_box(startx, endx, starty, endy, DLG_FG, DLG_BG);
@@ -234,7 +231,7 @@ index e42175108..7986fc877 100644
return 1;
row++;
}
-@@ -308,15 +460,16 @@ draw_input_dialog(const struct DrawState* state)
+@@ -308,15 +457,16 @@ draw_input_dialog(const struct DrawState* state)
INPUT_EDIT_BG);
if (state->input_title)
if (draw_string(startx, starty, TITLE_FG, TITLE_BG,
@@ -256,7 +253,7 @@ index e42175108..7986fc877 100644
tb_set_cursor(startx + 2 + state->input_display_column
- state->input_first_shown_column,
starty + 1);
-@@ -337,7 +490,7 @@ draw_line_number(const struct DrawState* state, const
+@@ -337,7 +487,7 @@ draw_line_number(const struct DrawState* state, const
pnumbuf = numbuf_end - numbuf > state->line_numbers_width
? numbuf_end - state->line_numbers_width
: numbuf;
@@ -265,7 +262,7 @@ index e42175108..7986fc877 100644
numbuf_end - numbuf + 1, state->line_numbers_width, 0,
0, RIGHT, 0, 1, NULL, 0, 0, 0, 0, 0, 0);
}
-@@ -417,9 +570,10 @@ draw_screen(const struct DrawState* state)
+@@ -417,9 +567,10 @@ draw_screen(const struct DrawState* state)
u32_draw_string(state->line_numbers
? state->line_numbers_width + 2
: 0,
@@ -279,7 +276,7 @@ index e42175108..7986fc877 100644
i++;
cy++;
}
-@@ -449,22 +603,22 @@ draw_status(const struct DrawState* state)
+@@ -449,22 +600,22 @@ draw_status(const struct DrawState* state)
if (IN(state->mode, M_PROMPT) && *state->prompt)
{
if (draw_string(0, state->maxy - 1, PROMPT_FG, PROMPT_BG,
@@ -308,7 +305,7 @@ index e42175108..7986fc877 100644
return 1;
}
else
-@@ -487,7 +641,7 @@ draw_status(const struct DrawState* state)
+@@ -487,7 +638,7 @@ draw_status(const struct DrawState* state)
if (pseg == status_segments + LEN(status_segments) - 1)
seg_size = maxx - 1 - current_start;
if (draw_string(current_start, state->maxy - 1,
@@ -317,7 +314,7 @@ index e42175108..7986fc877 100644
MIN(seg_size, (ssize_t)(strlen(buf) + 2)),
last ? seg_size + 1 : seg_size, 1, 1,
pseg->alignment, 0, 1, NULL, 0, 0, 0, 0, 0,
-@@ -522,8 +676,9 @@ draw_status(const struct DrawState* state)
+@@ -522,8 +673,9 @@ draw_status(const struct DrawState* state)
* */
int
draw_string(const int x, const int y, const uint16_t fg, const uint16_t bg,
@@ -329,7 +326,7 @@ index e42175108..7986fc877 100644
const uint32_t* srch, const uint16_t sfg, const uint16_t sbg,
const int ssi, const int sei, const uint16_t slfg, const uint16_t slbg)
{
-@@ -533,8 +688,8 @@ draw_string(const int x, const int y, const uint16_t f
+@@ -533,8 +685,8 @@ draw_string(const int x, const int y, const uint16_t f
if (!us)
return 1;
u8_string_to_unicode(us, s, mc);
@@ -340,7 +337,7 @@ index e42175108..7986fc877 100644
free(us);
return 0;
}
-@@ -639,6 +794,8 @@ free_bufferline(struct BufferLine* bl)
+@@ -639,6 +791,8 @@ free_bufferline(struct BufferLine* bl)
bl->length = 0;
bl->fg = 0;
bl->bg = 0;
@@ -349,7 +346,7 @@ index e42175108..7986fc877 100644
}
void
-@@ -677,6 +834,7 @@ init_bufferline(struct BufferLine* bl)
+@@ -677,6 +831,7 @@ init_bufferline(struct BufferLine* bl)
bl->size = 0;
bl->fg = 0;
bl->bg = 0;
@@ -357,7 +354,7 @@ index e42175108..7986fc877 100644
}
void
-@@ -702,6 +860,11 @@ init_drawstate(struct DrawState* state, char* error, c
+@@ -702,6 +857,11 @@ init_drawstate(struct DrawState* state, char* error, c
state->orig_real_filename = NULL;
state->backup_filename = NULL;
state->rfn_len = 0;
@@ -369,7 +366,7 @@ index e42175108..7986fc877 100644
}
state->input = NULL;
state->search = NULL;
-@@ -760,7 +923,273 @@ recalculate_size(struct DrawState* state)
+@@ -760,7 +920,282 @@ recalculate_size(struct DrawState* state)
recalculate_line_numbers(state);
}
@@ -406,9 +403,6 @@ index e42175108..7986fc877 100644
+ struct Keyword* keyword;
+ struct Comment* comment;
+ struct Operator* operator;
-+ struct Keyword* klist;
-+ struct Comment* clist;
-+ struct Operator* olist;
+ char* temp;
+ ssize_t i, li, ti, comment_start, quote_start, literal_start;
+ uint32_t quote;
@@ -419,9 +413,6 @@ index e42175108..7986fc877 100644
+ && (state->operators != NULL)
+ && (state->buffer[state->first_shown.row].text != NULL));
+
-+ klist = state->keywords;
-+ clist = state->comments;
-+ olist = state->operators;
+ li = 0;
+ quote = 0;
+ comment_index = -1;
@@ -454,14 +445,21 @@ index e42175108..7986fc877 100644
+ seen_end_comment = 0;
+ while (ti < curline->length)
+ {
-+ seen_end_comment = u32_starts_with(&curline->text[ti],
-+ clist[comment_index].end_text);
++ size_t ucsize
++ = 6 * state->comments[comment_index].end_size
++ + 1;
++ uint32_t ucomm[ucsize];
++ u8_string_to_unicode(ucomm,
++ state->comments[comment_index].end_text,
++ ucsize - 1);
++ seen_end_comment
++ = u32_starts_with(&curline->text[ti], ucomm);
+ if (seen_end_comment)
+ break;
+ ti++;
+ }
-+ assert(clist[comment_index].end_size > 1);
-+ ti += clist[comment_index].end_size - 1;
++ assert(state->comments[comment_index].end_size > 1);
++ ti += state->comments[comment_index].end_size - 1;
+ if (seen_end_comment)
+ comment_index = -1;
+ if (syntax_add(curline, SE_COMMENT, comment_start,
@@ -484,12 +482,14 @@ index e42175108..7986fc877 100644
+ }
+
+ i = 0;
-+ comment = &clist[0];
++ comment = state->comments;
+ while (comment->start_text != NULL)
+ {
++ size_t ucsize = 6 * comment->start_size + 1;
++ uint32_t ucomm[ucsize];
++ u8_string_to_unicode(ucomm, comment->start_text, ucsize - 1);
+ if ((curline->length >= ti + comment->start_size - 1)
-+ && (u32_starts_with(&curline->text[ti],
-+ comment->start_text)))
++ && (u32_starts_with(&curline->text[ti], ucomm)))
+ {
+ assert(comment->start_size > 1);
+ if (comment->end_text != NULL)
@@ -514,7 +514,7 @@ index e42175108..7986fc877 100644
+ goto recalc_syn_comment_rest_of_line;
+ }
+ i++;
-+ comment = &clist[i];
++ comment = state->comments + i;
+ }
+
+ /* Check for string literals */
@@ -576,16 +576,19 @@ index e42175108..7986fc877 100644
+
+ /* Check for keywords */
+ i = 0;
-+ keyword = klist;
++ keyword = state->keywords;
+ while (keyword->text != NULL)
+ {
++ size_t ucsize = 6 * keyword->size + 1;
++ uint32_t ucomm[ucsize];
++ u8_string_to_unicode(ucomm, keyword->text, ucsize - 1);
+ if ((curline->length >= ti + keyword->size - 1)
+ && ((ti == 0)
+ || ((ti > 0) && !isalnum(curline->text[ti - 1])
+ && curline->text[ti - 1] != L'_'))
+ && (!isalnum(curline->text[ti + keyword->size - 1]))
+ && (curline->text[ti + keyword->size - 1] != L'_')
-+ && (u32_starts_with(&curline->text[ti], keyword->text)))
++ && (u32_starts_with(&curline->text[ti], ucomm)))
+ {
+ /* Add new syntax region */
+ assert(keyword->size > 1);
@@ -602,18 +605,21 @@ index e42175108..7986fc877 100644
+ goto recalc_syn_next_token;
+ }
+ i++;
-+ keyword = &klist[i];
++ keyword = state->keywords + i;
+ }
+
+ /* Check for operators */
+ i = 0;
+ /* clang-format off */
-+ operator = olist;
++ operator = state->operators;
+ /* clang-format on */
+ while (operator->text != NULL)
+ {
++ size_t ucsize = 6 * operator->size + 1;
++ uint32_t ucomm[ucsize];
++ u8_string_to_unicode(ucomm, operator->text, ucsize - 1);
+ if ((curline->length >= ti + operator->size - 1)
-+ && (u32_starts_with(&curline->text[ti], operator->text)))
++ && (u32_starts_with(&curline->text[ti], ucomm)))
+ {
+ /* Add new syntax region */
+ assert(operator->size> 1);
@@ -631,7 +637,7 @@ index e42175108..7986fc877 100644
+ }
+ i++;
+ /* clang-format off */
-+ operator = &olist[i];
++ operator = state->operators + i;
+ /* clang-format on */
+ }
+
@@ -643,7 +649,7 @@ index e42175108..7986fc877 100644
redraw_status(struct DrawState* state)
{
assert(state != NULL);
-@@ -791,7 +1220,8 @@ redraw_status(struct DrawState* state)
+@@ -791,7 +1226,8 @@ redraw_status(struct DrawState* state)
* */
void
u32_draw_string(const int x, const int y, const uint16_t fg, const uint16_t bg,
@@ -653,7 +659,7 @@ index e42175108..7986fc877 100644
const int p_r, const Alignment align, const int ds, const int fill,
const uint32_t* srch, const uint16_t sfg, const uint16_t sbg,
const int ssi, const int sei, const uint16_t slfg, const uint16_t slbg)
-@@ -829,6 +1259,8 @@ u32_draw_string(const int x, const int y, const uint16
+@@ -829,6 +1265,8 @@ u32_draw_string(const int x, const int y, const uint16
int w = 0; /* actual on-screen rune width */
@@ -662,7 +668,7 @@ index e42175108..7986fc877 100644
const int ts = TAB_SIZE;
const uint32_t* ps = s; /* pointer to current character in
-@@ -837,11 +1269,23 @@ u32_draw_string(const int x, const int y, const uint16
+@@ -837,11 +1275,23 @@ u32_draw_string(const int x, const int y, const uint16
uint16_t cfg = fg; /* current fg */
uint16_t cbg = bg; /* current bg */
@@ -686,7 +692,7 @@ index e42175108..7986fc877 100644
c = mc - p_l - p_r;
if (align == LEFT)
-@@ -873,7 +1317,12 @@ u32_draw_string(const int x, const int y, const uint16
+@@ -873,7 +1323,12 @@ u32_draw_string(const int x, const int y, const uint16
*/
while (*ps && sc < c)
{
@@ -700,7 +706,7 @@ index e42175108..7986fc877 100644
{
cfg = slfg;
cbg = slbg;
-@@ -890,6 +1339,9 @@ u32_draw_string(const int x, const int y, const uint16
+@@ -890,6 +1345,9 @@ u32_draw_string(const int x, const int y, const uint16
}
}
@@ -710,7 +716,7 @@ index e42175108..7986fc877 100644
if (*ps == '\t')
{
if (ssc < ds)
-@@ -1005,11 +1457,11 @@ u32_draw_string(const int x, const int y, const uint16
+@@ -1005,11 +1463,11 @@ u32_draw_string(const int x, const int y, const uint16
}
ssc += w;
}
@@ -727,10 +733,18 @@ index e42175108..7986fc877 100644
}
diff --git a/draw.h b/draw.h
-index e42175108..7986fc877 100644
+index f72c9de89..9fba930eb 100644
--- a/draw.h
+++ b/draw.h
-@@ -37,17 +37,58 @@ enum {
+@@ -1,6 +1,7 @@
+ /* This program is licensed under the terms of GNU GPL v3 or (at your option)
+ * any later version. Copyright (C) 2022-2024 Страхиња Радић.
+ * See the file LICENSE for exact copyright and license details. */
++
+ #include <stddef.h>
+ #include <sys/types.h>
+ #include <termios.h>
+@@ -37,17 +38,58 @@ enum {
typedef enum { LEFT, CENTER, RIGHT } Alignment;
@@ -745,19 +759,19 @@ index e42175108..7986fc877 100644
+} SyntaxElement;
+
+struct Keyword {
-+ uint32_t* text;
++ char* text;
+ int size;
+};
+
+struct Comment {
-+ uint32_t* start_text;
-+ uint32_t* end_text;
++ char* start_text;
++ char* end_text;
+ int start_size;
+ int end_size;
+};
+
+struct Operator {
-+ uint32_t* text;
++ char* text;
+ int size;
+};
+
@@ -789,7 +803,7 @@ index e42175108..7986fc877 100644
};
struct DrawState {
-@@ -87,12 +128,17 @@ struct DrawState {
+@@ -87,12 +129,17 @@ struct DrawState {
int dirty;
int new_file;
int recalculate_size;
@@ -807,7 +821,7 @@ index e42175108..7986fc877 100644
};
struct Key {
-@@ -109,6 +155,13 @@ struct StatusSegment {
+@@ -109,6 +156,13 @@ struct StatusSegment {
Alignment alignment;
};
@@ -821,7 +835,7 @@ index e42175108..7986fc877 100644
void assign_coord(struct Coord* dest, const struct Coord src);
ssize_t buffer_length(uint32_t* buffer, const ssize_t max_index);
int calculate_help_width(const struct DrawState* state);
-@@ -125,7 +178,8 @@ void draw_rect(const int startx, const int endx, const
+@@ -125,7 +179,8 @@ void draw_rect(const int startx, const int endx, const
int draw_screen(const struct DrawState* state);
int draw_status(const struct DrawState* state);
int draw_string(const int x, const int y, const uint16_t fg, const uint16_t bg,
@@ -831,7 +845,7 @@ index e42175108..7986fc877 100644
const int padding_left, const int padding_right, const Alignment align,
const int ds, const int fill, const uint32_t* srch, const uint16_t sfg,
const uint16_t sbg, const int ssi, const int sei, const uint16_t slfg,
-@@ -148,10 +202,12 @@ void init_drawstate(struct DrawState* state, char* err
+@@ -148,10 +203,12 @@ void init_drawstate(struct DrawState* state, char* err
const int skip_filenames_init);
void recalculate_line_numbers(struct DrawState* state);
void recalculate_size(struct DrawState* state);
@@ -850,7 +864,7 @@ index e42175108..7986fc877 100644
+ const uint16_t sbg, const int ssi, const int sei, const uint16_t slfg,
+ const uint16_t slbg);
diff --git a/sled.c b/sled.c
-index e42175108..7986fc877 100644
+index f72c9de89..9fba930eb 100644
--- a/sled.c
+++ b/sled.c
@@ -67,6 +67,18 @@ extern const char* prompt_reread_dirty;