[gnome-builder] vim: add basic support for vim splits via ctrl+w operations
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] vim: add basic support for vim splits via ctrl+w operations
- Date: Tue, 20 Jan 2015 23:29:04 +0000 (UTC)
commit 6f45a1d83763d95e11666c0cb3d12e94f7e08964
Author: Christian Hergert <christian hergert me>
Date: Tue Jan 20 15:19:01 2015 -0800
vim: add basic support for vim splits via ctrl+w operations
This supports creation of vertical and horizontal splits as well as
closing the current split. Note that this only plumbs the signals, and
the embedder is responsible for implementing what a split means.
This does not currently implement support for navigation through the
splits. That can be implemented separately from this.
https://bugzilla.gnome.org/show_bug.cgi?id=743020
src/vim/gb-source-vim.c | 137 +++++++++++++++++++++++++++++++++++++++++++++-
src/vim/gb-source-vim.h | 32 +++++++----
2 files changed, 155 insertions(+), 14 deletions(-)
---
diff --git a/src/vim/gb-source-vim.c b/src/vim/gb-source-vim.c
index 9eeef83..9b52531 100644
--- a/src/vim/gb-source-vim.c
+++ b/src/vim/gb-source-vim.c
@@ -98,6 +98,7 @@ struct _GbSourceVimPrivate
guint connected : 1;
guint recording : 1;
guint in_replay : 1;
+ guint in_ctrl_w : 1;
};
typedef enum
@@ -192,6 +193,7 @@ enum
COMMAND_VISIBILITY_TOGGLED,
EXECUTE_COMMAND,
JUMP_TO_DOC,
+ SPLIT,
SWITCH_TO_FILE,
LAST_SIGNAL
};
@@ -2950,6 +2952,7 @@ gb_source_vim_handle_normal (GbSourceVim *vim,
case GDK_KEY_Escape:
gb_source_vim_clear_selection (vim);
gb_source_vim_clear_phrase (vim);
+ vim->priv->in_ctrl_w = FALSE;
return TRUE;
case GDK_KEY_Page_Up:
@@ -3082,6 +3085,15 @@ gb_source_vim_handle_normal (GbSourceVim *vim,
}
break;
+ case GDK_KEY_w:
+ if ((event->state & GDK_CONTROL_MASK) != 0)
+ {
+ gb_source_vim_clear_phrase (vim);
+ vim->priv->in_ctrl_w = TRUE;
+ return TRUE;
+ }
+ break;
+
default:
break;
}
@@ -3217,6 +3229,55 @@ gb_source_vim_handle_command (GbSourceVim *vim,
return TRUE;
}
+static gboolean
+gb_source_vim_handle_ctrl_w (GbSourceVim *vim,
+ GdkEventKey *event)
+{
+ GbSourceVimSplit split = 0;
+ gboolean handled = FALSE;
+
+ g_return_val_if_fail (GB_IS_SOURCE_VIM (vim), FALSE);
+ g_return_val_if_fail (event, FALSE);
+
+ vim->priv->in_ctrl_w = FALSE;
+
+ switch (event->keyval)
+ {
+ case GDK_KEY_S:
+ case GDK_KEY_s:
+ split = GB_SOURCE_VIM_SPLIT_HORIZONTAL;
+ break;
+
+ case GDK_KEY_v:
+ case GDK_KEY_V:
+ split = GB_SOURCE_VIM_SPLIT_VERTICAL;
+ break;
+
+ case GDK_KEY_c:
+ split = GB_SOURCE_VIM_SPLIT_CLOSE;
+ break;
+
+ default:
+ break;
+ }
+
+ if (split)
+ g_signal_emit (vim, gSignals [SPLIT], 0, split, &handled);
+
+ if (!handled)
+ {
+ /*
+ * TODO: emit message about unhandled split.
+ *
+ * Vim will emit a message here about the unhandled split. We should
+ * probably do the same, but that will require that we plumb messages
+ * too. Also a good idea.
+ */
+ }
+
+ return !!split;
+}
+
static void
gb_source_vim_event_after_cb (GtkTextView *text_view,
GdkEventKey *event,
@@ -3242,7 +3303,10 @@ gb_source_vim_key_press_event_cb (GtkTextView *text_view,
switch (vim->priv->mode)
{
case GB_SOURCE_VIM_NORMAL:
- ret = gb_source_vim_handle_normal (vim, event);
+ if (vim->priv->in_ctrl_w)
+ ret = gb_source_vim_handle_ctrl_w (vim, event);
+ else
+ ret = gb_source_vim_handle_normal (vim, event);
break;
case GB_SOURCE_VIM_INSERT:
@@ -4033,6 +4097,30 @@ gb_source_vim_op_edit (GbSourceVim *vim,
g_clear_object (&file);
}
+static void
+gb_source_vim_op_split_horizontal (GbSourceVim *vim,
+ const gchar *command_text)
+{
+ gboolean ret = FALSE;
+
+ g_return_if_fail (GB_IS_SOURCE_VIM (vim));
+
+ g_signal_emit (vim, gSignals [SPLIT], 0,
+ GB_SOURCE_VIM_SPLIT_HORIZONTAL, &ret);
+}
+
+static void
+gb_source_vim_op_split_vertical (GbSourceVim *vim,
+ const gchar *command_text)
+{
+ gboolean ret = FALSE;
+
+ g_return_if_fail (GB_IS_SOURCE_VIM (vim));
+
+ g_signal_emit (vim, gSignals [SPLIT], 0,
+ GB_SOURCE_VIM_SPLIT_VERTICAL, &ret);
+}
+
static GbSourceVimOperation
gb_source_vim_parse_operation (const gchar *command_text)
{
@@ -4059,10 +4147,18 @@ gb_source_vim_parse_operation (const gchar *command_text)
ret = gb_source_vim_op_colorscheme;
else if (g_str_has_prefix (command_text, "%s"))
ret = gb_source_vim_op_search_and_replace;
- else if (g_str_has_prefix (command_text, "s")) /* not ideal */
- ret = gb_source_vim_op_search_and_replace;
+ else if (g_str_equal (command_text, "split") ||
+ g_str_equal (command_text, "sp"))
+ ret = gb_source_vim_op_split_horizontal;
+ else if (g_str_equal (command_text, "vsplit") ||
+ g_str_equal (command_text, "vsp"))
+ ret = gb_source_vim_op_split_vertical;
else if (g_regex_match (goto_line_regex, command_text, 0, NULL))
ret = gb_source_vim_op_goto_line;
+ /* XXX: Keep this last */
+ else if (g_str_has_prefix (command_text, "s") &&
+ !g_ascii_isalnum (command_text[1]))
+ ret = gb_source_vim_op_search_and_replace;
return ret;
}
@@ -5262,6 +5358,24 @@ gb_source_vim_class_init (GbSourceVimClass *klass)
1,
G_TYPE_STRING);
+ /**
+ * GbSourceVim::split:
+ * @type: A #GbSourceVimSplit containing the split type.
+ *
+ * Requests a split operation on the current buffer.
+ */
+ gSignals [SPLIT] =
+ g_signal_new ("split",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GbSourceVimClass, split),
+ g_signal_accumulator_true_handled,
+ NULL,
+ g_cclosure_marshal_generic,
+ G_TYPE_BOOLEAN,
+ 1,
+ GB_TYPE_SOURCE_VIM_SPLIT);
+
gSignals [SWITCH_TO_FILE] =
g_signal_new ("switch-to-file",
G_TYPE_FROM_CLASS (klass),
@@ -5528,3 +5642,20 @@ gb_source_vim_mode_get_type (void)
return type_id;
}
+
+GType
+gb_source_vim_split_get_type (void)
+{
+ static GType type_id;
+ static const GEnumValue values[] = {
+ { GB_SOURCE_VIM_SPLIT_HORIZONTAL, "GB_SOURCE_VIM_SPLIT_HORIZONTAL", "HORIZONTAL" },
+ { GB_SOURCE_VIM_SPLIT_VERTICAL, "GB_SOURCE_VIM_SPLIT_VERTICAL", "VERTICAL" },
+ { GB_SOURCE_VIM_SPLIT_CLOSE, "GB_SOURCE_VIM_SPLIT_CLOSE", "CLOSE" },
+ { 0 }
+ };
+
+ if (!type_id)
+ type_id = g_enum_register_static ("GbSourceVimSplit", values);
+
+ return type_id;
+}
diff --git a/src/vim/gb-source-vim.h b/src/vim/gb-source-vim.h
index 6721225..d06ce69 100644
--- a/src/vim/gb-source-vim.h
+++ b/src/vim/gb-source-vim.h
@@ -25,6 +25,7 @@ G_BEGIN_DECLS
#define GB_TYPE_SOURCE_VIM (gb_source_vim_get_type())
#define GB_TYPE_SOURCE_VIM_MODE (gb_source_vim_mode_get_type())
+#define GB_TYPE_SOURCE_VIM_SPLIT (gb_source_vim_split_get_type())
#define GB_SOURCE_VIM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_SOURCE_VIM, GbSourceVim))
#define GB_SOURCE_VIM_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_SOURCE_VIM, GbSourceVim
const))
#define GB_SOURCE_VIM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GB_TYPE_SOURCE_VIM,
GbSourceVimClass))
@@ -43,6 +44,13 @@ typedef enum
GB_SOURCE_VIM_COMMAND,
} GbSourceVimMode;
+typedef enum
+{
+ GB_SOURCE_VIM_SPLIT_HORIZONTAL = 1,
+ GB_SOURCE_VIM_SPLIT_VERTICAL,
+ GB_SOURCE_VIM_SPLIT_CLOSE,
+} GbSourceVimSplit;
+
struct _GbSourceVim
{
GObject parent;
@@ -55,25 +63,27 @@ struct _GbSourceVimClass
{
GObjectClass parent_class;
- void (*begin_search) (GbSourceVim *vim,
- const gchar *search_text);
- void (*command_visibility_toggled) (GbSourceVim *vim,
- gboolean visibility);
- gboolean (*execute_command) (GbSourceVim *vim,
- const gchar *command);
- void (*jump_to_doc) (GbSourceVim *vim,
- const gchar *search_text);
- void (*switch_to_file) (GbSourceVim *vim,
- GFile *file);
+ void (*begin_search) (GbSourceVim *vim,
+ const gchar *search_text);
+ void (*command_visibility_toggled) (GbSourceVim *vim,
+ gboolean visibility);
+ gboolean (*execute_command) (GbSourceVim *vim,
+ const gchar *command);
+ void (*jump_to_doc) (GbSourceVim *vim,
+ const gchar *search_text);
+ void (*switch_to_file) (GbSourceVim *vim,
+ GFile *file);
+ void (*split) (GbSourceVim *vim,
+ GbSourceVimSplit split);
gpointer _padding1;
gpointer _padding2;
gpointer _padding3;
- gpointer _padding4;
};
GType gb_source_vim_get_type (void);
GType gb_source_vim_mode_get_type (void);
+GType gb_source_vim_split_get_type (void);
GbSourceVim *gb_source_vim_new (GtkTextView *text_view);
GbSourceVimMode gb_source_vim_get_mode (GbSourceVim *vim);
void gb_source_vim_set_mode (GbSourceVim *vim,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]