[gnome-builder/gnome-builder-3-18] vim-mode: add , and ; for fFtT command
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/gnome-builder-3-18] vim-mode: add , and ; for fFtT command
- Date: Thu, 15 Oct 2015 14:42:26 +0000 (UTC)
commit 1f667120f2fe09856c82e191e97c61a59e33c7fa
Author: Sebastien Lafargue <slafargue gnome org>
Date: Tue Oct 13 23:16:05 2015 +0200
vim-mode: add , and ; for fFtT command
- We can now use , and ; after f F t T commands like in Vim.
To do so we add a new 'save-search-char' action signal,
usuable from css binding too and two new movements:
previous-search-char and next-search-char
- some fixes about FfTt selections
data/keybindings/vim.css | 102 ++++++++++++++++++++++++++++++-----
libide/ide-source-view-movements.c | 96 +++++++++++++++++++++++++++++++++
libide/ide-source-view-movements.h | 1 +
libide/ide-source-view.c | 33 +++++++++++-
libide/ide-source-view.h | 6 ++
5 files changed, 221 insertions(+), 17 deletions(-)
---
diff --git a/data/keybindings/vim.css b/data/keybindings/vim.css
index 361d472..7ba5745 100644
--- a/data/keybindings/vim.css
+++ b/data/keybindings/vim.css
@@ -279,19 +279,31 @@
"clear-count" () };
/* find matching char */
- bind "f" { "capture-modifier" ()
+ bind "f" { "save-command" ()
+ "capture-modifier" ()
+ "save-search-char" ()
"movement" (next-match-modifier, 0, 1, 1)
"clear-modifier" () };
- bind "t" { "capture-modifier" ()
+ bind "t" { "save-command" ()
+ "capture-modifier" ()
+ "save-search-char" ()
"movement" (next-match-modifier, 0, 1, 1)
"movement" (previous-char, 0, 1, 0)
"clear-modifier" () };
- bind "<shift>f" { "capture-modifier" ()
+ bind "<shift>f" { "save-command" ()
+ "capture-modifier" ()
+ "save-search-char" ()
"movement" (previous-match-modifier, 0, 1, 1)
"clear-modifier" () };
- bind "<shift>t" { "capture-modifier" ()
- "movement" (previous-match-modifier, 0, 0, 1)
+ bind "<shift>t" { "save-command" ()
+ "capture-modifier" ()
+ "save-search-char" ()
+ "movement" (previous-match-modifier, 0, 1, 1)
"clear-modifier" () };
+ bind "comma" { "movement" (previous-match-search-char, 0, 0, 1)
+ "clear-count" () };
+ bind "semicolon" { "movement" (next-match-search-char, 0, 0, 1)
+ "clear-count" () };
bind "n" { "move-search" (tab-forward, 0, 0, 1, 1, 0) };
bind "<shift>n" { "move-search" (tab-backward, 0, 0, 0, 1, 0) };
@@ -549,7 +561,9 @@
"delete-selection" () };
bind "f" { "begin-macro" ()
+ "save-command" ()
"capture-modifier" ()
+ "save-search-char" ()
"set-mode" ("vim-insert", permanent)
"movement" (next-match-modifier, 1, 0, 1)
"copy-clipboard" ()
@@ -558,7 +572,9 @@
"clear-modifier" () };
bind "t" { "begin-macro" ()
+ "save-command" ()
"capture-modifier" ()
+ "save-search-char" ()
"set-mode" ("vim-insert", permanent)
"movement" (next-match-modifier, 1, 1, 1)
"copy-clipboard" ()
@@ -575,22 +591,42 @@
"set-mode" ("vim-insert", permanent) };
bind "<shift>f" { "begin-macro" ()
+ "save-command" ()
"capture-modifier" ()
+ "save-search-char" ()
"set-mode" ("vim-insert", permanent)
- "movement" (previous-match-modifier, 1, 1, 1)
+ "movement" (previous-match-modifier, 1, 0, 1)
"copy-clipboard" ()
"selection-theatric" (shrink)
"delete-selection" ()
"clear-modifier" () };
bind "<shift>t" { "begin-macro" ()
+ "save-command" ()
"capture-modifier" ()
+ "save-search-char" ()
"set-mode" ("vim-insert", permanent)
- "movement" (previous-match-modifier, 1, 0, 1)
+ "movement" (previous-match-modifier, 1, 1, 1)
"copy-clipboard" ()
"selection-theatric" (shrink)
"delete-selection" ()
"clear-modifier" () };
+
+ bind "comma" { "begin-macro" ()
+ "movement" (previous-match-search-char, 1, 0, 1)
+ "set-mode" ("vim-insert", permanent)
+ "copy-clipboard" ()
+ "selection-theatric" (shrink)
+ "delete-selection" ()
+ "clear-count" () };
+
+ bind "semicolon" { "begin-macro" ()
+ "movement" (next-match-search-char, 1, 0, 1)
+ "set-mode" ("vim-insert", permanent)
+ "copy-clipboard" ()
+ "selection-theatric" (shrink)
+ "delete-selection" ()
+ "clear-count" () };
}
@binding-set builder-vim-source-view-normal-c-i
@@ -698,7 +734,9 @@
bind "g" { "set-mode" ("vim-normal-d-g", transient) };
bind "f" { "begin-macro" ()
+ "save-command" ()
"capture-modifier" ()
+ "save-search-char" ()
"movement" (next-match-modifier, 1, 0, 1)
"copy-clipboard" ()
"selection-theatric" (shrink)
@@ -706,7 +744,9 @@
"clear-modifier" ()
"end-macro" () };
bind "t" { "begin-macro" ()
+ "save-command" ()
"capture-modifier" ()
+ "save-search-char" ()
"movement" (next-match-modifier, 1, 1, 1)
"copy-clipboard" ()
"selection-theatric" (shrink)
@@ -715,21 +755,41 @@
"end-macro" () };
bind "<shift>f" { "begin-macro" ()
+ "save-command" ()
"capture-modifier" ()
- "movement" (previous-match-modifier, 1, 1, 1)
+ "save-search-char" ()
+ "movement" (previous-match-modifier, 1, 0, 1)
"copy-clipboard" ()
"selection-theatric" (shrink)
"delete-selection" ()
"clear-modifier" ()
"end-macro" () };
bind "<shift>t" { "begin-macro" ()
+ "save-command" ()
"capture-modifier" ()
- "movement" (previous-match-modifier, 1, 0, 1)
+ "save-search-char" ()
+ "movement" (previous-match-modifier, 1, 1, 1)
"copy-clipboard" ()
"selection-theatric" (shrink)
"delete-selection" ()
"clear-modifier" ()
"end-macro" () };
+ bind "comma" { "begin-macro" ()
+ "movement" (previous-match-search-char, 1, 1, 1)
+ "copy-clipboard" ()
+ "selection-theatric" (shrink)
+ "delete-selection" ()
+ "clear-count" ()
+ "end-macro" () };
+
+ bind "semicolon" { "begin-macro" ()
+ "movement" (next-match-search-char, 1, 0, 1)
+ "copy-clipboard" ()
+ "selection-theatric" (shrink)
+ "delete-selection" ()
+ "clear-count" ()
+ "end-macro" () };
+
bind "d" { "begin-macro" ()
"save-insert-mark" ()
@@ -1247,19 +1307,31 @@
bind "g" { "set-mode" ("vim-visual-g", transient) };
bind "z" { "set-mode" ("vim-visual-z", transient) };
- bind "f" { "capture-modifier" ()
+ bind "f" { "save-command" ()
+ "capture-modifier" ()
+ "save-search-char" ()
"movement" (next-match-modifier, 1, 0, 1)
"clear-modifier" () };
- bind "t" { "capture-modifier" ()
+ bind "t" { "save-command" ()
+ "capture-modifier" ()
+ "save-search-char" ()
"movement" (next-match-modifier, 1, 1, 1)
"clear-modifier" () };
- bind "<shift>f" { "capture-modifier" ()
- "movement" (previous-match-modifier, 1, 1, 1)
- "clear-modifier" () };
- bind "<shift>t" { "capture-modifier" ()
+ bind "<shift>f" { "save-command" ()
+ "capture-modifier" ()
+ "save-search-char" ()
"movement" (previous-match-modifier, 1, 0, 1)
"clear-modifier" () };
+ bind "<shift>t" { "save-command" ()
+ "capture-modifier" ()
+ "save-search-char" ()
+ "movement" (previous-match-modifier, 1, 1, 1)
+ "clear-modifier" () };
+ bind "comma" { "movement" (previous-match-search-char, 1, 0, 1)
+ "clear-count" () };
+ bind "semicolon" { "movement" (next-match-search-char, 1, 0, 1)
+ "clear-count" () };
bind "asciitilde" { "selection-theatric" (expand)
"change-case" (toggle)
diff --git a/libide/ide-source-view-movements.c b/libide/ide-source-view-movements.c
index ebcffa3..f0e60ca 100644
--- a/libide/ide-source-view-movements.c
+++ b/libide/ide-source-view-movements.c
@@ -47,6 +47,7 @@ typedef struct
gint count; /* Repeat count for movement */
gunichar command; /* Command that trigger some movements type. See , and
; in vim */
gunichar modifier; /* For forward/backward char search */
+ gunichar search_char; /* For forward/backward char search according to fFtT
vim modifier */
guint extend_selection : 1; /* If selection should be extended */
guint exclusive : 1; /* See ":help exclusive" in vim */
guint ignore_select : 1; /* Don't update selection after movement */
@@ -1241,6 +1242,88 @@ ide_source_view_movements_previous_match_modifier (Movement *mv)
}
}
+static gboolean
+find_char (gunichar ch,
+ gpointer data)
+{
+ gunichar ch_searched = GPOINTER_TO_UINT (data);
+
+ return (ch == ch_searched);
+}
+
+static void
+ide_source_view_movement_match_search_char (Movement *mv, gboolean is_next_direction)
+{
+ GtkTextIter insert;
+ GtkTextIter limit;
+ gboolean is_forward;
+ gboolean is_till;
+ gboolean is_inclusive_mode;
+ gboolean is_selection_positive;
+ const gchar *mode_name;
+
+ limit = insert = mv->insert;
+ is_forward = (mv->command == 'f' || mv->command == 't');
+ is_till = (mv->command == 't' || mv->command == 'T');
+
+ mode_name = _ide_source_view_get_mode_name (mv->self);
+ is_inclusive_mode = (g_str_has_prefix (mode_name, "vim-visual") ||
+ g_str_has_prefix (mode_name, "vim-normal-c") ||
+ g_str_has_prefix (mode_name, "vim-normal-d"));
+
+ is_selection_positive = (gtk_text_iter_compare (&insert, &mv->selection) >= 0);
+
+ if (mv->modifier == 0)
+ return;
+
+ if ((is_forward && is_next_direction) || (!is_forward && !is_next_direction))
+ {
+ /* We search to the right */
+ gtk_text_iter_forward_to_line_end (&limit);
+
+ if (is_till)
+ gtk_text_iter_forward_char (&insert);
+
+ if (is_inclusive_mode && is_selection_positive)
+ gtk_text_iter_backward_char (&insert);
+
+ if (gtk_text_iter_forward_find_char (&insert, find_char, GUINT_TO_POINTER (mv->modifier), &limit))
+ {
+ if (is_till)
+ gtk_text_iter_backward_char (&insert);
+
+ is_selection_positive = (gtk_text_iter_compare (&insert, &mv->selection) >= 0);
+ if (is_inclusive_mode && is_selection_positive)
+ gtk_text_iter_forward_char (&insert);
+
+ mv->insert = insert;
+ }
+ }
+ else
+ {
+ /* We search to the left */
+ gtk_text_iter_set_line_offset (&limit, 0);
+
+ if (is_till)
+ gtk_text_iter_backward_char (&insert);
+
+ if (is_inclusive_mode && is_selection_positive)
+ gtk_text_iter_backward_char (&insert);
+
+ if (gtk_text_iter_backward_find_char (&insert, find_char, GUINT_TO_POINTER (mv->modifier), &limit))
+ {
+ if (is_till)
+ gtk_text_iter_forward_char (&insert);
+
+ is_selection_positive = (gtk_text_iter_compare (&insert, &mv->selection) >= 0);
+ if (is_inclusive_mode && is_selection_positive)
+ gtk_text_iter_forward_char (&insert);
+
+ mv->insert = insert;
+ }
+ }
+}
+
void
_ide_source_view_apply_movement (IdeSourceView *self,
IdeSourceViewMovement movement,
@@ -1249,6 +1332,7 @@ _ide_source_view_apply_movement (IdeSourceView *self,
guint count,
gunichar command,
gunichar modifier,
+ gunichar search_char,
gint *target_offset)
{
Movement mv = { 0 };
@@ -1507,6 +1591,18 @@ _ide_source_view_apply_movement (IdeSourceView *self,
ide_source_view_movements_previous_match_modifier (&mv);
break;
+ case IDE_SOURCE_VIEW_MOVEMENT_PREVIOUS_MATCH_SEARCH_CHAR:
+ mv.modifier = search_char;
+ for (i = MAX (1, mv.count); i > 0; i--)
+ ide_source_view_movement_match_search_char (&mv, FALSE);
+ break;
+
+ case IDE_SOURCE_VIEW_MOVEMENT_NEXT_MATCH_SEARCH_CHAR:
+ mv.modifier = search_char;
+ for (i = MAX (1, mv.count); i > 0; i--)
+ ide_source_view_movement_match_search_char (&mv, TRUE);
+ break;
+
default:
g_return_if_reached ();
}
diff --git a/libide/ide-source-view-movements.h b/libide/ide-source-view-movements.h
index cb1106d..c80235e 100644
--- a/libide/ide-source-view-movements.h
+++ b/libide/ide-source-view-movements.h
@@ -30,6 +30,7 @@ void _ide_source_view_apply_movement (IdeSourceView *source_view,
guint count,
gunichar command,
gunichar modifier,
+ gunichar search_char,
gint *target_offset);
G_END_DECLS
diff --git a/libide/ide-source-view.c b/libide/ide-source-view.c
index f0673c4..ede08fc 100644
--- a/libide/ide-source-view.c
+++ b/libide/ide-source-view.c
@@ -118,6 +118,7 @@ typedef struct
gint target_line_offset;
gunichar command;
gunichar modifier;
+ gunichar search_char;
guint count;
guint delayed_scroll_replay;
@@ -245,6 +246,7 @@ enum {
RESTORE_INSERT_MARK,
SAVE_COMMAND,
SAVE_INSERT_MARK,
+ SAVE_SEARCH_CHAR,
SELECTION_THEATRIC,
SET_MODE,
SET_OVERWRITE,
@@ -3158,8 +3160,13 @@ ide_source_view_real_movement (IdeSourceView *self,
priv->scrolling_to_scroll_mark = FALSE;
_ide_source_view_apply_movement (self,
- movement, extend_selection, exclusive,
- count, priv->command, priv->modifier,
+ movement,
+ extend_selection,
+ exclusive,
+ count,
+ priv->command,
+ priv->modifier,
+ priv->search_char,
&priv->target_line_offset);
}
@@ -3574,6 +3581,17 @@ ide_source_view_real_save_command (IdeSourceView *self)
}
static void
+ide_source_view_real_save_search_char (IdeSourceView *self)
+{
+ IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
+
+ g_assert (IDE_IS_SOURCE_VIEW (self));
+
+ if (priv->modifier)
+ priv->search_char = priv->modifier;
+}
+
+static void
ide_source_view__completion_hide_cb (IdeSourceView *self,
GtkSourceCompletion *completion)
{
@@ -5490,6 +5508,7 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
klass->restore_insert_mark = ide_source_view_real_restore_insert_mark;
klass->save_command = ide_source_view_real_save_command;
klass->save_insert_mark = ide_source_view_real_save_insert_mark;
+ klass->save_search_char = ide_source_view_real_save_search_char;
klass->selection_theatric = ide_source_view_real_selection_theatric;
klass->set_mode = ide_source_view_real_set_mode;
klass->set_overwrite = ide_source_view_real_set_overwrite;
@@ -5745,6 +5764,16 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
G_TYPE_NONE,
0);
+ gSignals [SAVE_SEARCH_CHAR] =
+ g_signal_new ("save-search-char",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (IdeSourceViewClass, save_search_char),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
/**
* IdeSourceView::capture-modifier:
*
diff --git a/libide/ide-source-view.h b/libide/ide-source-view.h
index 265e163..84d30e6 100644
--- a/libide/ide-source-view.h
+++ b/libide/ide-source-view.h
@@ -116,6 +116,8 @@ typedef enum
* @IDE_SOURCE_VIEW_MOVEMENT_SCROLL_SCREEN_TOP: scroll until insert cursor is at screen top.
* @IDE_SOURCE_VIEW_MOVEMENT_SCROLL_SCREEN_CENTER: scroll until insert cursor is at screen center.
* @IDE_SOURCE_VIEW_MOVEMENT_SCROLL_SCREEN_BOTTOM: scroll until insert cursor is at screen bottom.
+ * @IDE_SOURCE_VIEW_MOVEMENT_NEXT_MATCH_SEARCH_CHAR: move to the next matching char according to f and t in
vim.
+ * @IDE_SOURCE_VIEW_MOVEMENT_PREVIOUS_MATCH_SEARCH_CHAR: move to the previous matching char according to F
and T in vim.
*
* The type of movement.
*
@@ -190,6 +192,9 @@ typedef enum
IDE_SOURCE_VIEW_MOVEMENT_NEXT_MATCH_MODIFIER,
IDE_SOURCE_VIEW_MOVEMENT_PREVIOUS_MATCH_MODIFIER,
+
+ IDE_SOURCE_VIEW_MOVEMENT_NEXT_MATCH_SEARCH_CHAR,
+ IDE_SOURCE_VIEW_MOVEMENT_PREVIOUS_MATCH_SEARCH_CHAR,
} IdeSourceViewMovement;
struct _IdeSourceViewClass
@@ -252,6 +257,7 @@ struct _IdeSourceViewClass
void (*request_documentation) (IdeSourceView *self);
void (*restore_insert_mark) (IdeSourceView *self);
void (*save_command) (IdeSourceView *self);
+ void (*save_search_char) (IdeSourceView *self);
void (*save_insert_mark) (IdeSourceView *self);
void (*selection_theatric) (IdeSourceView *self,
IdeSourceViewTheatric theatric);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]