From 655857e77563fedfe14e5f8716e8b42b362d1173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1lm=C3=A1n=20=E2=80=9EKAMI=E2=80=9D=20Szalai?= Date: Sat, 22 Aug 2026 16:01:37 +0200 Subject: [PATCH] Speed up cursor column calculation in the status bar for long lines The status bar position indicator computed the column number by stepping through a GtkTextIter one character at a time from the start of the current line to the cursor, calling gtk_text_iter_get_char and gtk_text_iter_forward_char in a loop. This function runs on essentially every cursor movement, including while typing, so on a very long line, such as a minified script or a large single-line JSON file, it added a noticeable delay on each keystroke because the cost scaled with the cursor's column position. The loop now fetches the text between the start of the line and the cursor with a single gtk_text_iter_get_slice call and walks the resulting plain UTF-8 string instead, which avoids the repeated iterator validation and buffer lookups of the old approach while producing the exact same column number, including the same tab-expansion handling. --- xed/xed-window.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/xed/xed-window.c b/xed/xed-window.c index 05ee7ecc..a8f5c569 100644 --- a/xed/xed-window.c +++ b/xed/xed-window.c @@ -1771,6 +1771,8 @@ update_cursor_position_statusbar (GtkTextBuffer *buffer, GtkTextIter start; guint tab_size; XedView *view; + gchar *line_start_text; + const gchar *p; xed_debug (DEBUG_WINDOW); @@ -1791,10 +1793,15 @@ update_cursor_position_statusbar (GtkTextBuffer *buffer, tab_size = gtk_source_view_get_tab_width (GTK_SOURCE_VIEW(view)); - while (!gtk_text_iter_equal (&start, &iter)) + /* Walk a plain C string instead of stepping a GtkTextIter one character + * at a time: each GtkTextIter call re-validates the iterator and does a + * BTree lookup, which gets very slow on long lines (e.g. minified code). + */ + line_start_text = gtk_text_iter_get_slice (&start, &iter); + + for (p = line_start_text; *p != '\0'; p = g_utf8_next_char (p)) { - /* FIXME: Are we Unicode compliant here? */ - if (gtk_text_iter_get_char (&start) == '\t') + if (g_utf8_get_char (p) == '\t') { col += (tab_size - (col % tab_size)); } @@ -1802,9 +1809,10 @@ update_cursor_position_statusbar (GtkTextBuffer *buffer, { ++col; } - gtk_text_iter_forward_char (&start); } + g_free (line_start_text); + xed_statusbar_set_cursor_position (XED_STATUSBAR(window->priv->statusbar), row + 1, col + 1); }