[gtksourceview/wip/chergert/vim] improve backward sentence start
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/vim] improve backward sentence start
- Date: Mon, 25 Oct 2021 02:23:54 +0000 (UTC)
commit c233226ce2d697c35a8da7b9b627cdab4667f15d
Author: Christian Hergert <chergert redhat com>
Date: Sun Oct 24 19:23:49 2021 -0700
improve backward sentence start
gtksourceview/vim/gtk-source-vim-motion.c | 211 ++++++++++++++++++++++--------
1 file changed, 156 insertions(+), 55 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-motion.c b/gtksourceview/vim/gtk-source-vim-motion.c
index bd19ff12..ae4d8860 100644
--- a/gtksourceview/vim/gtk-source-vim-motion.c
+++ b/gtksourceview/vim/gtk-source-vim-motion.c
@@ -461,21 +461,6 @@ motion_prev_line (GtkTextIter *iter,
return FALSE;
}
-static gboolean
-motion_next_line (GtkTextIter *iter,
- GtkSourceVimMotion *state)
-{
- GtkTextIter before = *iter;
-
- if (gtk_text_iter_forward_to_line_end (iter))
- gtk_text_iter_forward_char (iter);
-
- if (gtk_text_iter_is_end (iter))
- gtk_text_iter_backward_char (iter);
-
- return !gtk_text_iter_equal (&before, iter);
-}
-
static gboolean
motion_next_line_first_char (GtkTextIter *iter,
GtkSourceVimMotion *state)
@@ -781,86 +766,202 @@ motion_backward_paragraph_start (GtkTextIter *iter,
GtkTextIter before = *iter;
/* Work our way past the current empty lines */
- if (line_is_empty (iter))
+ while (line_is_empty (iter))
{
- while (line_is_empty (iter))
- {
- if (!gtk_text_iter_backward_line (iter))
- return FALSE;
- }
+ if (!gtk_text_iter_backward_line (iter))
+ goto finish;
}
/* Now find first line that is empty */
while (!line_is_empty (iter))
{
if (!gtk_text_iter_backward_line (iter))
- return FALSE;
+ goto finish;
}
+finish:
return !gtk_text_iter_equal (&before, iter);
}
-static gboolean
-motion_backward_sentence_start (GtkTextIter *iter,
- GtkSourceVimMotion *state)
-{
- return gtk_text_iter_backward_sentence_start (iter);
-}
-
static gboolean
motion_forward_sentence_start (GtkTextIter *iter,
GtkSourceVimMotion *state)
{
GtkTextIter before = *iter;
- gboolean last_was_newline = FALSE;
+ guint newline_count = 0;
- do
+ /* If we're at the end of a sentence, then walk past any trailing
+ * characters after the punctuation, and then skip space up until
+ * another non-space character.
+ */
+ switch (gtk_text_iter_get_char (iter))
{
- if (!gtk_text_iter_forward_char (iter))
+ case '.':
+ case '!':
+ case '?':
+ case '\n':
+ while (!g_unichar_isspace (gtk_text_iter_get_char (iter)))
+ {
+ if (!gtk_text_iter_forward_char (iter))
+ goto finish;
+ }
+ while (g_unichar_isspace (gtk_text_iter_get_char (iter)))
+ {
+ if (!gtk_text_iter_forward_char (iter))
+ goto finish;
+ }
+ return TRUE;
+
+ default:
break;
+ }
+ while (gtk_text_iter_forward_char (iter))
+ {
switch (gtk_text_iter_get_char (iter))
{
case '\n':
- /* \n\n or more is a paragraph break */
- if (last_was_newline)
+ newline_count++;
+ if (newline_count == 1)
+ break;
+ G_GNUC_FALLTHROUGH;
+ case '.':
+ case '!':
+ case '?':
+ while (!g_unichar_isspace (gtk_text_iter_get_char (iter)))
{
- while (gtk_text_iter_ends_line (iter) &&
- gtk_text_iter_forward_char (iter)) { /* do nothing */ }
+ if (!gtk_text_iter_forward_char (iter))
+ goto finish;
+ }
+ while (g_unichar_isspace (gtk_text_iter_get_char (iter)))
+ {
+ if (!gtk_text_iter_forward_char (iter))
+ goto finish;
+ }
+ return TRUE;
- while (!gtk_text_iter_ends_line (iter) &&
- g_unichar_isspace (gtk_text_iter_get_char (iter)))
- {
- if (!gtk_text_iter_forward_char (iter))
- break;
- }
+ default:
+ break;
+ }
+ }
- return TRUE;
- }
+finish:
+ if (gtk_text_iter_is_end (iter) && !gtk_text_iter_starts_line (iter))
+ gtk_text_iter_backward_char (iter);
- last_was_newline = TRUE;
+ return !gtk_text_iter_equal (&before, iter);
+}
+
+static gboolean
+backward_sentence_end (GtkTextIter *iter)
+{
+ GtkTextIter before = *iter;
+
+ if (line_is_empty (iter))
+ {
+ while (gtk_text_iter_backward_char (iter))
+ {
+ if (!g_unichar_isspace (gtk_text_iter_get_char (iter)))
break;
+ }
+ goto finish;
+ }
+
+ while (gtk_text_iter_backward_char (iter))
+ {
+ switch (gtk_text_iter_get_char (iter))
+ {
case '.':
case '!':
case '?':
- do
- {
- if (!gtk_text_iter_forward_char (iter))
- return TRUE;
+ goto finish;
- if (g_unichar_isspace (gtk_text_iter_get_char (iter)))
- continue;
+ case '\n':
+ if (gtk_text_iter_starts_line (iter))
+ {
+ while (gtk_text_iter_backward_char (iter))
+ {
+ if (!g_unichar_isspace (gtk_text_iter_get_char (iter)))
+ break;
+ }
- return TRUE;
- } while (TRUE);
+ goto finish;
+ }
break;
default:
- last_was_newline = FALSE;
break;
}
- } while (TRUE);
+ }
+
+finish:
+ if (gtk_text_iter_is_end (iter) && !gtk_text_iter_starts_line (iter))
+ gtk_text_iter_backward_char (iter);
+
+ return !gtk_text_iter_equal (&before, iter);
+}
+
+static gboolean
+motion_backward_sentence_start (GtkTextIter *iter,
+ GtkSourceVimMotion *state)
+{
+ GtkTextIter *winner = NULL;
+ GtkTextIter before = *iter;
+ GtkTextIter para;
+ GtkTextIter sentence;
+ GtkTextIter two_sentence;
+ int distance = G_MAXINT;
+
+ para = *iter;
+ motion_backward_paragraph_start (¶, state);
+
+ sentence = *iter;
+ backward_sentence_end (&sentence);
+ motion_forward_sentence_start (&sentence, state);
+
+ two_sentence = *iter;
+ backward_sentence_end (&two_sentence);
+ backward_sentence_end (&two_sentence);
+ motion_forward_sentence_start (&two_sentence, state);
+
+ if (gtk_text_iter_compare (¶, iter) < 0)
+ {
+ int diff = (int)gtk_text_iter_get_offset (iter) - (int)gtk_text_iter_get_offset (¶);
+
+ if (diff < distance)
+ {
+ distance = diff;
+ winner = ¶
+ }
+ }
+
+ if (gtk_text_iter_compare (&sentence, iter) < 0)
+ {
+ int diff = (int)gtk_text_iter_get_offset (iter) - (int)gtk_text_iter_get_offset (&sentence);
+
+ if (diff < distance)
+ {
+ distance = diff;
+ winner = &sentence;
+ }
+ }
+
+ if (gtk_text_iter_compare (&two_sentence, iter) < 0)
+ {
+ int diff = (int)gtk_text_iter_get_offset (iter) - (int)gtk_text_iter_get_offset
(&two_sentence);
+
+ if (diff < distance)
+ {
+ distance = diff;
+ winner = &two_sentence;
+ }
+ }
+
+ if (winner != NULL)
+ *iter = *winner;
+ else
+ gtk_text_iter_set_offset (iter, 0);
return !gtk_text_iter_equal (&before, iter);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]