commit 1640c84783b813243dae7c10de23553e6be1f220 from: Oliver Lowe date: Mon Aug 18 09:48:51 2025 UTC Quote depth with zig phew that's better commit - e789c3054683a2bbda2e551ff9a367b5efec6830 commit + 1640c84783b813243dae7c10de23553e6be1f220 blob - 8db9a13d44b88deb56ccabab2e881288d936beea blob + b9997bc67ed74160a3130b30c3d8e416a188e05e --- src/Makefile.am +++ src/Makefile.am @@ -493,8 +493,8 @@ AM_CPPFLAGS = \ $(NETTLE_CFLAGS) \ $(GPGME_CFLAGS) \ $(LIBETPAN_CPPFLAGS) \ - $(SVG_CFLAGS) \ - $(VALGRIND_CFLAGS) + $(VALGRIND_CFLAGS) \ + -Ifence/zig-out/include #no-unused-function because of bison stuff matcher_parser_lex.$(OBJEXT) : AM_CFLAGS += -Wno-unused-function blob - fc17d0051f0c5454215d01d5519eeb07e8f9923b blob + c0664e3d644450a249540c36ac419b0efceb61cf --- src/common/utils.c +++ src/common/utils.c @@ -956,51 +956,7 @@ static const gchar * line_has_quote_char_last(const gc return position; } -gint get_quote_level(const gchar *str, const gchar *quote_chars) -{ - const gchar *first_pos; - const gchar *last_pos; - const gchar *p = str; - gint quote_level = -1; - /* speed up line processing by only searching to the last '>' */ - if ((first_pos = line_has_quote_char(str, quote_chars)) != NULL) { - /* skip a line if it contains a '<' before the initial '>' */ - if (memchr(str, '<', first_pos - str) != NULL) - return -1; - last_pos = line_has_quote_char_last(first_pos, quote_chars); - } else - return -1; - - while (p <= last_pos) { - while (p < last_pos) { - if (g_ascii_isspace(*p)) - p++; - else - break; - } - - if (strchr(quote_chars, *p)) - quote_level++; - else if (*p != '-' && !g_ascii_isspace(*p) && p <= last_pos) { - /* any characters are allowed except '-','<' and space */ - while (*p != '-' && *p != '<' - && !strchr(quote_chars, *p) - && !g_ascii_isspace(*p) - && p < last_pos) - p++; - if (strchr(quote_chars, *p)) - quote_level++; - else - break; - } - - p++; - } - - return quote_level; -} - gint check_line_length(const gchar *str, gint max_chars, gint *line) { const gchar *p = str, *q; blob - 2d8017dc723619bd1b9ccf56e8793a6b33d88d78 blob + a609ec624b61fcb50c7e694e209fbb0078560182 --- src/common/utils.h +++ src/common/utils.h @@ -359,8 +359,6 @@ void subst_chars (gchar *str, void subst_for_filename (gchar *str); void subst_for_shellsafe_filename (gchar *str); gboolean is_ascii_str (const gchar *str); -gint get_quote_level (const gchar *str, - const gchar *quote_chars); gint check_line_length (const gchar *str, gint max_chars, gint *line); blob - bc6734d20eca01fd2ac92bddf2b93b8218cf0ffa blob + ef28bb91721aa2eff56a238da38794d67023ad87 --- src/compose.c +++ src/compose.c @@ -101,6 +101,7 @@ #include "spell_entry.h" #include "headers.h" #include "file-utils.h" +#include "fence.h" enum { @@ -4405,10 +4406,9 @@ static gboolean compose_beautify_paragraph(Compose *co quote_str = compose_get_quote_str(buffer, &iter, "e_len); if (quote_str) { -/* debug_print("compose_beautify_paragraph(): quote_str = '%s'\n", quote_str); */ if (startq_offset == -1) startq_offset = gtk_text_iter_get_offset(&iter); - quotelevel = get_quote_level(quote_str, prefs_common.quote_chars); + quotelevel = quote_depth(quote_str); if (quotelevel > 2) { /* recycle colors */ if (prefs_common.recycle_quote_colors) blob - 6cb921dab42ee502a8a04c6b911163e8507b2dce blob + 8ed50fe25e21cce9ceb3ffa3225a288571cb5390 --- src/fence/src/fence.h +++ src/fence/src/fence.h @@ -1 +1,2 @@ char fence_is_top_level_domain(char *domain); +int quote_depth(char *line); blob - 46ed35318d36a5814051b1ec9dbcc4718655e204 blob + 2092b5b9e7ff5f37e9c1d1eb62d2140c0519bbf1 --- src/fence/src/root.zig +++ src/fence/src/root.zig @@ -22,6 +22,48 @@ fn isRfc822Char(c: u8) bool { return true; } +fn quoteDepth(line: []const u8) u8 { + const ln = std.mem.trim(u8, line, &std.ascii.whitespace); + const first = std.mem.indexOfScalar(u8, ln, '>') orelse return 0; + if (first != 0) return 0; + + var depth: u8 = 0; + const last = std.mem.lastIndexOfScalar(u8, ln, '>') orelse return 1; + for (line[first..last+1]) |c| { + if (c == '>') { + if (depth == 0xff) return depth; + depth += 1; + continue; + } + if (std.ascii.isWhitespace(c)) continue; + break; + } + return depth; +} + +export fn quote_depth(line: [*:0]const u8) c_int { + const n = quoteDepth(std.mem.span(line)); + return @as(c_int, n); +} + +test "quote depth" { + const tests = [_]struct{[]const u8, u8}{ + .{">>> hello", 3}, + .{"> >> hello", 3}, + .{" > hello >", 1}, + .{"hello>>", 0}, + .{">> hello >>", 2}, + .{"> \t> hello", 2}, + .{">", 1}, + .{ "xxx > hello >>", 0}, + }; + for (tests) |t| { + const got = quoteDepth(t[0]); + errdefer std.debug.print("quote depth for \"{s}\"\n", .{t[0]}); + try testing.expectEqual(t[1], got); + } +} + test "check domains" { try testing.expect(isTopLevelDomain("com")); try testing.expect(isTopLevelDomain("69yamum") == false); blob - 64554140d670ebbc70a7303f4673478ed6731f89 blob + f8e5ff70df3b57d34bc77e3e515367f94581eb2f --- src/prefs_common.c +++ src/prefs_common.c @@ -502,9 +502,9 @@ static PrefParam param[] = { {"quote_level1_color", "#0000b3", &prefs_common.color[COL_QUOTE_LEVEL1], P_COLOR, NULL, NULL, NULL}, - {"quote_level2_color", "#0000b3", &prefs_common.color[COL_QUOTE_LEVEL2], + {"quote_level2_color", "#b35a00", &prefs_common.color[COL_QUOTE_LEVEL2], P_COLOR, NULL, NULL, NULL}, - {"quote_level3_color", "#0000b3", &prefs_common.color[COL_QUOTE_LEVEL3], + {"quote_level3_color", "#5ab300", &prefs_common.color[COL_QUOTE_LEVEL3], P_COLOR, NULL, NULL, NULL}, {"enable_bgcolor", "FALSE", &prefs_common.enable_bgcolor, P_BOOL, NULL, NULL, NULL}, blob - 70499fccc5c2e9bf22147a7d46d661fa6455d48d blob + 6e0d34665e2ed70dc50e65b5de5adf2bcf68f322 --- src/textview.c +++ src/textview.c @@ -62,6 +62,7 @@ #include "hooks.h" #include "avatars.h" #include "file-utils.h" +#include "fence.h" static GdkRGBA quote_colors[3] = { {0, 0, 0, 1}, @@ -1423,7 +1424,7 @@ static void textview_write_line(TextView *textview, co if (prefs_common.enable_color && !textview->is_attachment && line_has_quote_char(buf, prefs_common.quote_chars)) { - real_quotelevel = get_quote_level(buf, prefs_common.quote_chars); + real_quotelevel = quote_depth(buf); quotelevel = real_quotelevel; /* set up the correct foreground color */ if (quotelevel > 2) {