[gnome-builder/wip/libide] libide: improve backward word end movements



commit 259ed5ac92d549f45a7afcdc12e281ad0621c961
Author: Christian Hergert <christian hergert me>
Date:   Sun Mar 8 18:42:55 2015 -0700

    libide: improve backward word end movements

 libide/ide-source-view-movements.c |   46 +++++++++++++++++++++---------------
 libide/ide-vim-iter.c              |   44 ++++++++++++++++++++++++++++++++++
 libide/ide-vim-iter.h              |    2 +
 3 files changed, 73 insertions(+), 19 deletions(-)
---
diff --git a/libide/ide-source-view-movements.c b/libide/ide-source-view-movements.c
index f99fed2..ad04b00 100644
--- a/libide/ide-source-view-movements.c
+++ b/libide/ide-source-view-movements.c
@@ -946,37 +946,45 @@ ide_source_view_movements_previous_word_end (Movement *mv)
 
   copy = mv->insert;
 
-  _ide_source_iter_backward_visible_word_starts (&mv->insert, 2);
-  _ide_source_iter_forward_visible_word_end (&mv->insert);
+  _ide_vim_iter_backward_word_end (&mv->insert);
 
   /*
    * Vim treats an empty line as a word.
    */
-  if (gtk_text_iter_backward_char (&copy))
-    if (gtk_text_iter_get_char (&copy) == '\n')
-      mv->insert = copy;
-
-  /*
-   * Ensure we are strictly before our previous position.
-   */
-  if (gtk_text_iter_compare (&mv->insert, &copy) > 0)
-    gtk_text_buffer_get_start_iter (gtk_text_iter_get_buffer (&mv->insert), &mv->insert);
+  while ((gtk_text_iter_compare (&copy, &mv->insert) > 0) &&
+         gtk_text_iter_backward_char (&copy))
+    {
+      if (gtk_text_iter_starts_line (&copy) &&
+          gtk_text_iter_ends_line (&copy))
+        mv->insert = copy;
+    }
 
-  if (mv->exclusive && !gtk_text_iter_starts_line (&mv->insert))
-    gtk_text_iter_backward_char (&mv->insert);
+  if (!mv->exclusive && !gtk_text_iter_ends_line (&mv->insert))
+    gtk_text_iter_forward_char (&mv->insert);
 }
 
 static void
 ide_source_view_movements_previous_full_word_end (Movement *mv)
 {
-  if (!_ide_source_iter_starts_full_word (&mv->insert))
-    _ide_source_iter_backward_full_word_start (&mv->insert);
+  GtkTextIter copy;
 
-  _ide_source_iter_backward_full_word_start (&mv->insert);
-  _ide_source_iter_forward_full_word_end (&mv->insert);
+  copy = mv->insert;
+
+  _ide_vim_iter_backward_WORD_end (&mv->insert);
 
-  if (mv->exclusive && !gtk_text_iter_starts_line (&mv->insert))
-    gtk_text_iter_backward_char (&mv->insert);
+  /*
+   * Vim treats an empty line as a word.
+   */
+  while ((gtk_text_iter_compare (&copy, &mv->insert) > 0) &&
+         gtk_text_iter_backward_char (&copy))
+    {
+      if (gtk_text_iter_starts_line (&copy) &&
+          gtk_text_iter_ends_line (&copy))
+        mv->insert = copy;
+    }
+
+  if (!mv->exclusive && !gtk_text_iter_ends_line (&mv->insert))
+    gtk_text_iter_forward_char (&mv->insert);
 }
 
 static void
diff --git a/libide/ide-vim-iter.c b/libide/ide-vim-iter.c
index 9986d2a..f4c0ef5 100644
--- a/libide/ide-vim-iter.c
+++ b/libide/ide-vim-iter.c
@@ -411,3 +411,47 @@ _ide_vim_iter_forward_WORD_end (GtkTextIter *iter)
 {
   return _ide_vim_iter_forward_classified_end (iter, _ide_vim_WORD_classify);
 }
+
+static gboolean
+_ide_vim_iter_backward_classified_end (GtkTextIter *iter,
+                                       gint (*classify) (gunichar))
+{
+  gunichar ch;
+  gint begin_class;
+  gint cur_class;
+
+  g_assert (iter);
+
+  ch = gtk_text_iter_get_char (iter);
+  begin_class = classify (ch);
+
+  for (;;)
+    {
+      if (!gtk_text_iter_backward_char (iter))
+        return FALSE;
+
+      ch = gtk_text_iter_get_char (iter);
+      cur_class = classify (ch);
+
+      /* reset begin_class if we hit space, we can take anything after that */
+      if (cur_class == CLASS_SPACE)
+        begin_class = CLASS_SPACE;
+
+      if (cur_class != begin_class && cur_class != CLASS_SPACE)
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
+gboolean
+_ide_vim_iter_backward_word_end (GtkTextIter *iter)
+{
+  return _ide_vim_iter_backward_classified_end (iter, _ide_vim_word_classify);
+}
+
+gboolean
+_ide_vim_iter_backward_WORD_end (GtkTextIter *iter)
+{
+  return _ide_vim_iter_backward_classified_end (iter, _ide_vim_WORD_classify);
+}
diff --git a/libide/ide-vim-iter.h b/libide/ide-vim-iter.h
index 09578db..63a8c5d 100644
--- a/libide/ide-vim-iter.h
+++ b/libide/ide-vim-iter.h
@@ -31,6 +31,8 @@ gboolean _ide_vim_iter_backward_paragraph_start (GtkTextIter *iter);
 gboolean _ide_vim_iter_forward_paragraph_end    (GtkTextIter *iter);
 gboolean _ide_vim_iter_backward_sentence_start  (GtkTextIter *iter);
 gboolean _ide_vim_iter_forward_sentence_end     (GtkTextIter *iter);
+gboolean _ide_vim_iter_backward_WORD_end        (GtkTextIter *iter);
+gboolean _ide_vim_iter_backward_word_end        (GtkTextIter *iter);
 
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]