[gnome-builder] vim: recording of command keys
- From: Sébastien Lafargue <slafargue src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] vim: recording of command keys
- Date: Sun, 15 Nov 2015 22:57:24 +0000 (UTC)
commit 343f7cc22fcb8da1115c5af1b9197d054f5a9f56
Author: Sebastien Lafargue <slafargue gnome org>
Date: Sun Nov 15 23:56:04 2015 +0100
vim: recording of command keys
we record in a string the keys sequence, using
symbolic names for invisible codes and modifiers
Permanent mode keys are not recorded but Transient mode keys are.
The string is cleared when we end up in a Permanent mode.
libide/ide-source-view-movements.c | 1 +
libide/ide-source-view-movements.h | 1 +
libide/ide-source-view.c | 130 +++++++++++++++++++++++++++++++++++-
3 files changed, 131 insertions(+), 1 deletions(-)
---
diff --git a/libide/ide-source-view-movements.c b/libide/ide-source-view-movements.c
index 29ed3c5..67e9b21 100644
--- a/libide/ide-source-view-movements.c
+++ b/libide/ide-source-view-movements.c
@@ -1949,6 +1949,7 @@ _ide_source_view_apply_movement (IdeSourceView *self,
gboolean extend_selection,
gboolean exclusive,
guint count,
+ GString *command_str,
gunichar command,
gunichar modifier,
gunichar search_char,
diff --git a/libide/ide-source-view-movements.h b/libide/ide-source-view-movements.h
index 1afde8c..6f9f086 100644
--- a/libide/ide-source-view-movements.h
+++ b/libide/ide-source-view-movements.h
@@ -28,6 +28,7 @@ void _ide_source_view_apply_movement (IdeSourceView *source_view,
gboolean extend_selection,
gboolean exclusive,
guint count,
+ GString *command_str,
gunichar command,
gunichar modifier,
gunichar search_char,
diff --git a/libide/ide-source-view.c b/libide/ide-source-view.c
index 7708a46..53d3f89 100644
--- a/libide/ide-source-view.c
+++ b/libide/ide-source-view.c
@@ -72,6 +72,8 @@
#define FIXIT_LABEL_LEN_MAX 30
#define SCROLL_REPLAY_DELAY 1000
+#define ALL_ACCELS_MASK (GDK_CONTROL_MASK | GDK_SHIFT_MASK | GDK_MOD1_MASK)
+
#define _GDK_RECTANGLE_X2(rect) _ide_cairo_rectangle_x2(rect)
#define _GDK_RECTANGLE_Y2(rect) _ide_cairo_rectangle_y2(rect)
#define _GDK_RECTANGLE_CONTAINS(rect,other) _ide_cairo_rectangle_contains_rectangle(rect,other)
@@ -116,6 +118,7 @@ typedef struct
guint change_sequence;
gint target_line_offset;
+ GString *command_str;
gunichar command;
gunichar modifier;
gunichar search_char;
@@ -2001,12 +2004,112 @@ ide_source_view_do_indent (IdeSourceView *self,
IDE_EXIT;
}
+static inline gboolean
+compare_keys (GdkKeymap *keymap,
+ GdkEventKey *event,
+ GtkBindingEntry *binding_entry,
+ guint *new_keyval,
+ GdkModifierType *state_consumed)
+{
+ gdk_keymap_translate_keyboard_state (keymap,
+ event->hardware_keycode, event->state, event->group,
+ new_keyval, NULL, NULL, state_consumed);
+
+ if (g_ascii_isupper (*new_keyval))
+ {
+ *new_keyval = gdk_keyval_to_lower (*new_keyval);
+ *state_consumed &= ~GDK_SHIFT_MASK;
+ }
+
+ return (*new_keyval == binding_entry->keyval &&
+ (event->state & ~(*state_consumed) & ALL_ACCELS_MASK) == (binding_entry->modifiers &
ALL_ACCELS_MASK));
+}
+
+static gboolean
+is_key_vim_binded (GtkWidget *widget,
+ GdkEventKey *event,
+ guint *new_keyval,
+ GdkModifierType *state_consumed)
+{
+ GdkKeymap *keymap;
+ GtkBindingSet *binding_set;
+ GtkBindingEntry *binding_entry;
+ GtkStyleContext *context;
+ GtkStateFlags state;
+ GPtrArray *binding_set_array;
+
+
+ IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (IDE_SOURCE_VIEW (widget));
+
+ context = gtk_widget_get_style_context (GTK_WIDGET (priv->mode));
+ keymap = gdk_keymap_get_default ();
+ state = gtk_widget_get_state_flags (GTK_WIDGET (priv->mode));
+
+ gtk_style_context_get (context, state, "gtk-key-bindings", &binding_set_array, NULL);
+ if (binding_set_array)
+ {
+ for (gint i = 0; i < binding_set_array->len; i++)
+ {
+ binding_set = g_ptr_array_index (binding_set_array, i);
+ if (g_str_has_prefix (binding_set->set_name, "builder-vim"))
+ {
+ binding_entry = binding_set->entries;
+ while (binding_entry)
+ {
+ if (compare_keys (keymap, event, binding_entry, new_keyval, state_consumed))
+ {
+ g_ptr_array_unref (binding_set_array);
+ return TRUE;
+ }
+
+ binding_entry = binding_entry->set_next;
+ }
+ }
+ }
+
+ g_ptr_array_unref (binding_set_array);
+ }
+
+ return FALSE;
+}
+
+static void
+command_string_append_to (GString *command_str,
+ guint keyval,
+ GdkModifierType state)
+{
+ if (state & GDK_CONTROL_MASK)
+ g_string_append (command_str, "<ctrl>");
+
+ if (state & GDK_SHIFT_MASK)
+ g_string_append (command_str, "<shift>");
+
+ if (state & GDK_MOD1_MASK)
+ g_string_append (command_str, "<alt>");
+
+ if (keyval >= '!' && keyval <= '~' )
+ g_string_append_c (command_str, keyval);
+ else
+ {
+ if (!ide_str_empty0 (command_str->str) &&
+ (state & ALL_ACCELS_MASK) == 0 &&
+ *(command_str->str + command_str->len - 1) != ' ')
+ g_string_append (command_str, " ");
+
+ g_string_append (command_str, gdk_keyval_name (keyval));
+ g_string_append (command_str, " ");
+ }
+}
+
static gboolean
ide_source_view_do_mode (IdeSourceView *self,
GdkEventKey *event)
{
IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
g_autofree gchar *suggested_default = NULL;
+ guint new_keyval;
+ GdkModifierType state;
+ GdkModifierType state_consumed;
gboolean ret = FALSE;
g_assert (IDE_IS_SOURCE_VIEW (self));
@@ -2034,6 +2137,12 @@ ide_source_view_do_mode (IdeSourceView *self,
/* hold a reference incase binding changes mode */
mode = g_object_ref (priv->mode);
+ if (is_key_vim_binded (GTK_WIDGET (self), event, &new_keyval, &state_consumed))
+ {
+ state = event->state & ~(state_consumed);
+ command_string_append_to (priv->command_str, new_keyval, state);
+ }
+
/* lookup what this mode thinks our next default should be */
suggested_default = g_strdup (ide_source_view_mode_get_default_mode (priv->mode));
@@ -2055,6 +2164,9 @@ ide_source_view_do_mode (IdeSourceView *self,
if (!priv->mode)
ide_source_view_real_set_mode (self, suggested_default, IDE_SOURCE_VIEW_MODE_TYPE_PERMANENT);
+ if (ide_source_view_mode_get_mode_type (priv->mode) == IDE_SOURCE_VIEW_MODE_TYPE_PERMANENT)
+ g_string_erase (priv->command_str, 0, -1);
+
if (ide_source_view_mode_get_keep_mark_on_char (priv->mode))
{
GtkTextBuffer *buffer;
@@ -2126,7 +2238,19 @@ ide_source_view_key_press_event (GtkWidget *widget,
if (priv->waiting_for_capture)
{
if (!is_modifier_key (event))
- _ide_source_view_set_modifier (self, gdk_keyval_to_unicode (event->keyval));
+ {
+ guint new_keyval;
+ GdkModifierType state_consumed;
+ GdkKeymap *keymap = gdk_keymap_get_default ();
+
+ _ide_source_view_set_modifier (self, gdk_keyval_to_unicode (event->keyval));
+ gdk_keymap_translate_keyboard_state (keymap,
+ event->hardware_keycode, event->state, event->group,
+ &new_keyval, NULL, NULL, &state_consumed);
+
+ command_string_append_to (priv->command_str, new_keyval, event->state & ~(state_consumed));
+ }
+
return TRUE;
}
@@ -3020,6 +3144,7 @@ ide_source_view_real_movement (IdeSourceView *self,
extend_selection,
exclusive,
count,
+ priv->command_str,
priv->command,
priv->modifier,
priv->search_char,
@@ -5119,6 +5244,8 @@ ide_source_view_dispose (GObject *object)
g_clear_object (&priv->buffer_signals);
g_clear_object (&priv->file_setting_bindings);
+ g_clear_pointer (&priv->command_str, g_string_free);
+
G_OBJECT_CLASS (ide_source_view_parent_class)->dispose (object);
}
@@ -6177,6 +6304,7 @@ ide_source_view_init (IdeSourceView *self)
priv->show_line_diagnostics = TRUE;
priv->font_scale = FONT_SCALE_NORMAL;
priv->search_direction = GTK_DIR_DOWN;
+ priv->command_str = g_string_sized_new (32);
priv->completion_providers_signals = egg_signal_group_new (IDE_TYPE_EXTENSION_SET_ADAPTER);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]