[gnome-builder] plugins/vim: port to GTK 4
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] plugins/vim: port to GTK 4
- Date: Tue, 12 Jul 2022 06:39:20 +0000 (UTC)
commit 21e30bfa4d53d4d2bc6c89f3ea80a92131aed0be
Author: Christian Hergert <chergert redhat com>
Date: Mon Jul 11 23:30:10 2022 -0700
plugins/vim: port to GTK 4
This uses the new Vim emulation C API in GtkSourceView which I added in
GtkSourceView 5.4. The widgets are integrated with the workspace from
the workspace addin. A vim input method is configured when enabled.
src/plugins/vim/gb-vim.c | 1683 -----------
src/plugins/vim/gb-vim.h | 48 -
src/plugins/vim/gbp-vim-command-provider.c | 121 -
src/plugins/vim/gbp-vim-command.c | 154 -
src/plugins/vim/gbp-vim-editor-page-addin.c | 449 +++
...mand-provider.h => gbp-vim-editor-page-addin.h} | 8 +-
src/plugins/vim/gbp-vim-preferences-addin.c | 45 +-
src/plugins/vim/gbp-vim-preferences-addin.h | 2 +-
src/plugins/vim/gbp-vim-workspace-addin.c | 246 ++
...gbp-vim-command.h => gbp-vim-workspace-addin.h} | 19 +-
src/plugins/vim/keybindings/vim.css | 3099 --------------------
src/plugins/vim/meson.build | 5 +-
src/plugins/vim/vim-plugin.c | 12 +-
src/plugins/vim/vim.gresource.xml | 1 -
src/plugins/vim/vim.plugin | 6 +-
15 files changed, 748 insertions(+), 5150 deletions(-)
---
diff --git a/src/plugins/vim/gbp-vim-editor-page-addin.c b/src/plugins/vim/gbp-vim-editor-page-addin.c
new file mode 100644
index 000000000..8cb1f85c2
--- /dev/null
+++ b/src/plugins/vim/gbp-vim-editor-page-addin.c
@@ -0,0 +1,449 @@
+/* gbp-vim-editor-page-addin.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "gbp-vim-editor-page-addin"
+
+#include "config.h"
+
+#include <libide-gui.h>
+#include <libide-editor.h>
+
+#include "gbp-vim-editor-page-addin.h"
+#include "gbp-vim-workspace-addin.h"
+
+static void gbp_vim_editor_page_addin_load (IdeEditorPageAddin *addin,
+ IdeEditorPage *page);
+static void gbp_vim_editor_page_addin_unload (IdeEditorPageAddin *addin,
+ IdeEditorPage *page);
+static void gbp_vim_editor_page_addin_notify_active_cb (GbpVimEditorPageAddin *self,
+ GParamSpec *pspec,
+ GbpVimWorkspaceAddin
*workspace_addin);
+static gboolean gbp_vim_editor_page_addin_execute_command_cb (GbpVimEditorPageAddin *self,
+ const char *command,
+ GtkSourceVimIMContext *im_context);
+static void gbp_vim_editor_page_addin_notify_command_bar_text_cb (GbpVimEditorPageAddin *self,
+ GParamSpec *pspec,
+ GtkSourceVimIMContext *im_context);
+static void gbp_vim_editor_page_addin_notify_command_text_cb (GbpVimEditorPageAddin *self,
+ GParamSpec *pspec,
+ GtkSourceVimIMContext *im_context);
+static void gbp_vim_editor_page_addin_update (GbpVimEditorPageAddin *self);
+
+struct _GbpVimEditorPageAddin
+{
+ GObject parent_instance;
+
+ /* Unowned pointers */
+ IdeEditorPage *page;
+ GbpVimWorkspaceAddin *workspace_addin;
+
+ /* Owned references */
+ GtkEventController *key_controller;
+
+ guint enabled : 1;
+};
+
+static void
+editor_page_addin_iface_init (IdeEditorPageAddinInterface *iface)
+{
+ iface->load = gbp_vim_editor_page_addin_load;
+ iface->unload = gbp_vim_editor_page_addin_unload;
+}
+
+G_DEFINE_FINAL_TYPE_WITH_CODE (GbpVimEditorPageAddin, gbp_vim_editor_page_addin, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_EDITOR_PAGE_ADDIN,
editor_page_addin_iface_init))
+
+static void
+gbp_vim_editor_page_addin_class_init (GbpVimEditorPageAddinClass *klass)
+{
+}
+
+static void
+gbp_vim_editor_page_addin_init (GbpVimEditorPageAddin *self)
+{
+}
+
+static void
+gbp_vim_editor_page_addin_update (GbpVimEditorPageAddin *self)
+{
+ IdeWorkspaceAddin *workspace_addin;
+ IdeSourceView *view;
+ IdeWorkspace *workspace;
+ GtkIMContext *im_context;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_EDITOR_PAGE_ADDIN (self));
+ g_assert (IDE_IS_EDITOR_PAGE (self->page));
+
+ view = ide_editor_page_get_view (self->page);
+ im_context = gtk_event_controller_key_get_im_context (GTK_EVENT_CONTROLLER_KEY (self->key_controller));
+
+ if (self->workspace_addin != NULL)
+ {
+ g_signal_handlers_disconnect_by_func (self->workspace_addin,
+ G_CALLBACK (gbp_vim_editor_page_addin_notify_active_cb),
+ self);
+ self->workspace_addin = NULL;
+ }
+
+ if (!(workspace = ide_widget_get_workspace (GTK_WIDGET (self->page))) ||
+ !(workspace_addin = ide_workspace_addin_find_by_module_name (workspace, "vim")) ||
+ !GBP_IS_VIM_WORKSPACE_ADDIN (workspace_addin))
+ IDE_GOTO (disabled);
+
+ self->workspace_addin = GBP_VIM_WORKSPACE_ADDIN (workspace_addin);
+
+ g_signal_connect_object (self->workspace_addin,
+ "notify::active",
+ G_CALLBACK (gbp_vim_editor_page_addin_notify_active_cb),
+ self,
+ G_CONNECT_SWAPPED);
+
+ if (!gbp_vim_workspace_addin_get_active (self->workspace_addin))
+ IDE_GOTO (disabled);
+
+ if (!self->enabled)
+ {
+ self->enabled = TRUE;
+ gtk_im_context_set_client_widget (im_context, GTK_WIDGET (view));
+ gtk_widget_add_controller (GTK_WIDGET (view), g_object_ref (self->key_controller));
+ }
+
+ IDE_EXIT;
+
+disabled:
+ if (self->enabled)
+ {
+ self->enabled = FALSE;
+ gtk_im_context_set_client_widget (im_context, NULL);
+ gtk_widget_remove_controller (GTK_WIDGET (view), self->key_controller);
+ gtk_event_controller_reset (self->key_controller);
+ }
+
+ IDE_EXIT;
+}
+
+static void
+gbp_vim_editor_page_addin_notify_active_cb (GbpVimEditorPageAddin *self,
+ GParamSpec *pspec,
+ GbpVimWorkspaceAddin *workspace_addin)
+{
+ g_assert (GBP_IS_VIM_EDITOR_PAGE_ADDIN (self));
+ g_assert (GBP_IS_VIM_WORKSPACE_ADDIN (workspace_addin));
+
+ gbp_vim_editor_page_addin_update (self);
+}
+
+static void
+gbp_vim_editor_page_addin_notify_command_bar_text_cb (GbpVimEditorPageAddin *self,
+ GParamSpec *pspec,
+ GtkSourceVimIMContext *im_context)
+{
+ const char *command_bar;
+
+ g_assert (GBP_IS_VIM_EDITOR_PAGE_ADDIN (self));
+ g_assert (GTK_SOURCE_IS_VIM_IM_CONTEXT (im_context));
+
+ command_bar = gtk_source_vim_im_context_get_command_bar_text (im_context);
+
+ if (self->workspace_addin)
+ gbp_vim_workspace_addin_set_command_bar (self->workspace_addin, command_bar);
+}
+
+static void
+gbp_vim_editor_page_addin_notify_command_text_cb (GbpVimEditorPageAddin *self,
+ GParamSpec *pspec,
+ GtkSourceVimIMContext *im_context)
+{
+ const char *command;
+
+ g_assert (GBP_IS_VIM_EDITOR_PAGE_ADDIN (self));
+ g_assert (GTK_SOURCE_IS_VIM_IM_CONTEXT (im_context));
+
+ command = gtk_source_vim_im_context_get_command_text (im_context);
+
+ if (self->workspace_addin)
+ gbp_vim_workspace_addin_set_command (self->workspace_addin, command);
+}
+
+static void
+gbp_vim_editor_page_addin_load (IdeEditorPageAddin *addin,
+ IdeEditorPage *page)
+{
+ GbpVimEditorPageAddin *self = (GbpVimEditorPageAddin *)addin;
+ GtkIMContext *im_context;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_EDITOR_PAGE_ADDIN (self));
+ g_assert (IDE_IS_EDITOR_PAGE (page));
+
+ self->page = page;
+
+ self->key_controller = gtk_event_controller_key_new ();
+ im_context = gtk_source_vim_im_context_new ();
+ gtk_event_controller_set_propagation_phase (self->key_controller, GTK_PHASE_CAPTURE);
+ gtk_event_controller_key_set_im_context (GTK_EVENT_CONTROLLER_KEY (self->key_controller), im_context);
+
+ g_signal_connect_object (im_context,
+ "notify::command-bar-text",
+ G_CALLBACK (gbp_vim_editor_page_addin_notify_command_bar_text_cb),
+ self,
+ G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (im_context,
+ "notify::command-text",
+ G_CALLBACK (gbp_vim_editor_page_addin_notify_command_text_cb),
+ self,
+ G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (im_context,
+ "execute-command",
+ G_CALLBACK (gbp_vim_editor_page_addin_execute_command_cb),
+ self,
+ G_CONNECT_SWAPPED);
+
+ g_object_unref (im_context);
+
+ gbp_vim_editor_page_addin_update (self);
+
+ IDE_EXIT;
+}
+
+static void
+gbp_vim_editor_page_addin_unload (IdeEditorPageAddin *addin,
+ IdeEditorPage *page)
+{
+ GbpVimEditorPageAddin *self = (GbpVimEditorPageAddin *)addin;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_EDITOR_PAGE_ADDIN (self));
+ g_assert (IDE_IS_EDITOR_PAGE (page));
+
+ if (self->enabled)
+ {
+ IdeSourceView *view = ide_editor_page_get_view (page);
+
+ self->enabled = FALSE;
+ gtk_widget_remove_controller (GTK_WIDGET (view), self->key_controller);
+ }
+
+ g_clear_object (&self->key_controller);
+
+ self->page = NULL;
+ self->workspace_addin = NULL;
+
+ IDE_EXIT;
+}
+
+static void
+gbp_vim_editor_page_addin_save_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeEditorPage *page = (IdeEditorPage *)object;
+ g_autoptr(GbpVimEditorPageAddin) self = user_data;
+ g_autoptr(GError) error = NULL;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_EDITOR_PAGE (page));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (GBP_IS_VIM_EDITOR_PAGE_ADDIN (self));
+
+ if (!ide_editor_page_save_finish (page, result, &error))
+ g_warning ("Failed to save page: %s", error->message);
+
+ IDE_EXIT;
+}
+
+static void
+gbp_vim_editor_page_addin_save_and_close_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeEditorPage *page = (IdeEditorPage *)object;
+ g_autoptr(GbpVimEditorPageAddin) self = user_data;
+ g_autoptr(GError) error = NULL;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_EDITOR_PAGE (page));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (GBP_IS_VIM_EDITOR_PAGE_ADDIN (self));
+
+ if (!ide_editor_page_save_finish (page, result, &error))
+ g_warning ("Failed to save page: %s", error->message);
+ else if (self->page != NULL)
+ panel_widget_close (PANEL_WIDGET (self->page));
+
+ IDE_EXIT;
+}
+
+static void
+gbp_vim_editor_page_addin_discard_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeEditorPage *page = (IdeEditorPage *)object;
+ g_autoptr(GbpVimEditorPageAddin) self = user_data;
+ g_autoptr(GError) error = NULL;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_EDITOR_PAGE (page));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (GBP_IS_VIM_EDITOR_PAGE_ADDIN (self));
+
+ if (!ide_editor_page_discard_changes_finish (page, result, &error))
+ g_warning ("Failed to discard changes: %s", error->message);
+
+ IDE_EXIT;
+}
+
+static void
+gbp_vim_editor_page_addin_discard_and_close_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeEditorPage *page = (IdeEditorPage *)object;
+ g_autoptr(GbpVimEditorPageAddin) self = user_data;
+ g_autoptr(GError) error = NULL;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_EDITOR_PAGE (page));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (GBP_IS_VIM_EDITOR_PAGE_ADDIN (self));
+
+ if (!ide_editor_page_discard_changes_finish (page, result, &error))
+ g_warning ("Failed to discard changes: %s", error->message);
+ else if (self->page != NULL)
+ panel_widget_close (PANEL_WIDGET (self->page));
+
+ IDE_EXIT;
+}
+
+static gboolean
+gbp_vim_editor_page_addin_execute_command_cb (GbpVimEditorPageAddin *self,
+ const char *command,
+ GtkSourceVimIMContext *im_context)
+{
+ IdeBuffer *buffer;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_VIM_EDITOR_PAGE_ADDIN (self));
+ g_assert (GTK_SOURCE_IS_VIM_IM_CONTEXT (im_context));
+ g_assert (IDE_IS_EDITOR_PAGE (self->page));
+
+ g_debug ("Request to execute command %s", command);
+
+ buffer = ide_editor_page_get_buffer (self->page);
+
+ if (g_str_equal (command, ":q") ||
+ g_str_equal (command, ":quit") ||
+ g_str_equal (command, "^Wc"))
+ {
+ IdeGrid *grid = IDE_GRID (gtk_widget_get_ancestor (GTK_WIDGET (self->page), IDE_TYPE_GRID));
+ PanelGridColumn *column = PANEL_GRID_COLUMN (gtk_widget_get_ancestor (GTK_WIDGET (self->page),
PANEL_TYPE_GRID_COLUMN));
+ IdeFrame *frame = IDE_FRAME (gtk_widget_get_ancestor (GTK_WIDGET (self->page), IDE_TYPE_FRAME));
+
+ panel_widget_close (PANEL_WIDGET (self->page));
+
+ if (panel_frame_get_empty (PANEL_FRAME (frame)) &&
+ (panel_grid_get_n_columns (PANEL_GRID (grid)) > 1 ||
+ panel_grid_column_get_n_rows (column) > 1))
+ gtk_widget_activate_action (GTK_WIDGET (frame), "frame.close", NULL);
+
+ IDE_RETURN (TRUE);
+ }
+
+ if (g_str_equal (command, ":q!") || g_str_equal (command, ":quit!"))
+ {
+ ide_editor_page_discard_changes_async (self->page,
+ NULL,
+ gbp_vim_editor_page_addin_discard_and_close_cb,
+ g_object_ref (self));
+ IDE_RETURN (TRUE);
+ }
+
+ if (g_str_equal (command, ":w") || g_str_equal (command, ":write"))
+ {
+ ide_editor_page_save_async (self->page,
+ NULL,
+ gbp_vim_editor_page_addin_save_cb,
+ g_object_ref (self));
+ IDE_RETURN (TRUE);
+ }
+
+ if (g_str_equal (command, ":wq"))
+ {
+ ide_editor_page_save_async (self->page,
+ NULL,
+ gbp_vim_editor_page_addin_save_and_close_cb,
+ g_object_ref (self));
+ IDE_RETURN (TRUE);
+ }
+
+ if (g_str_equal (command, ":e!") ||
+ (g_str_equal (command, ":e") &&
+ !gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (buffer))))
+ {
+ ide_editor_page_discard_changes_async (self->page,
+ NULL,
+ gbp_vim_editor_page_addin_discard_cb,
+ g_object_ref (self));
+ IDE_RETURN (TRUE);
+ }
+
+ if (g_str_equal (command, "^Wv"))
+ {
+ g_autoptr(IdePanelPosition) position = ide_page_get_position (IDE_PAGE (self->page));
+ IdePage *new_page = ide_page_create_split (IDE_PAGE (self->page));
+ IdeWorkspace *workspace = ide_widget_get_workspace (GTK_WIDGET (self->page));
+ guint column = 0;
+
+ ide_panel_position_get_column (position, &column);
+ ide_panel_position_set_column (position, column+1);
+ ide_panel_position_set_row (position, 0);
+
+ ide_workspace_add_grid_column (workspace, column+1);
+ ide_workspace_add_page (workspace, new_page, position);
+ }
+
+ if (g_str_equal (command, "^Ws") ||
+ g_str_equal (command, ":split"))
+ {
+ g_autoptr(IdePanelPosition) position = ide_page_get_position (IDE_PAGE (self->page));
+ IdePage *new_page = ide_page_create_split (IDE_PAGE (self->page));
+ IdeWorkspace *workspace = ide_widget_get_workspace (GTK_WIDGET (self->page));
+ guint row = 0;
+
+ ide_panel_position_get_row (position, &row);
+ ide_panel_position_set_row (position, row+1);
+
+ ide_workspace_add_page (workspace, new_page, position);
+ }
+
+ IDE_RETURN (FALSE);
+}
diff --git a/src/plugins/vim/gbp-vim-command-provider.h b/src/plugins/vim/gbp-vim-editor-page-addin.h
similarity index 73%
rename from src/plugins/vim/gbp-vim-command-provider.h
rename to src/plugins/vim/gbp-vim-editor-page-addin.h
index 25a4bc03e..d7edc9b78 100644
--- a/src/plugins/vim/gbp-vim-command-provider.h
+++ b/src/plugins/vim/gbp-vim-editor-page-addin.h
@@ -1,6 +1,6 @@
-/* gbp-vim-command-provider.h
+/* gbp-vim-editor-page-addin.h
*
- * Copyright 2018-2019 Christian Hergert <chergert redhat com>
+ * Copyright 2022 Christian Hergert <chergert redhat com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,8 +24,8 @@
G_BEGIN_DECLS
-#define GBP_TYPE_VIM_COMMAND_PROVIDER (gbp_vim_command_provider_get_type())
+#define GBP_TYPE_VIM_EDITOR_PAGE_ADDIN (gbp_vim_editor_page_addin_get_type())
-G_DECLARE_FINAL_TYPE (GbpVimCommandProvider, gbp_vim_command_provider, GBP, VIM_COMMAND_PROVIDER, GObject)
+G_DECLARE_FINAL_TYPE (GbpVimEditorPageAddin, gbp_vim_editor_page_addin, GBP, VIM_EDITOR_PAGE_ADDIN, GObject)
G_END_DECLS
diff --git a/src/plugins/vim/gbp-vim-preferences-addin.c b/src/plugins/vim/gbp-vim-preferences-addin.c
index b29f090d8..ce99b63ed 100644
--- a/src/plugins/vim/gbp-vim-preferences-addin.c
+++ b/src/plugins/vim/gbp-vim-preferences-addin.c
@@ -23,6 +23,7 @@
#include "config.h"
#include <glib/gi18n.h>
+
#include <libide-gui.h>
#include "gbp-vim-preferences-addin.h"
@@ -30,41 +31,42 @@
struct _GbpVimPreferencesAddin
{
GObject parent_instance;
- guint keybinding_id;
+};
+
+static const IdePreferenceItemEntry items[] = {
+ { "keyboard", "keybindings", "vim", 0, ide_preferences_window_check,
+ N_("Vim"),
+ N_("Emulate keyboard shortcuts from Vim"),
+ "org.gnome.builder.editor", NULL, "keybindings", "'vim'" },
};
static void
-gbp_vim_preferences_addin_load (IdePreferencesAddin *addin,
- DzlPreferences *preferences)
+gbp_vim_preferences_addin_load (IdePreferencesAddin *addin,
+ IdePreferencesWindow *window,
+ IdeContext *context)
{
GbpVimPreferencesAddin *self = (GbpVimPreferencesAddin *)addin;
+ IDE_ENTRY;
+
g_assert (GBP_IS_VIM_PREFERENCES_ADDIN (self));
- g_assert (DZL_IS_PREFERENCES (preferences));
-
- self->keybinding_id = dzl_preferences_add_radio (preferences,
- "keyboard",
- "mode",
- "org.gnome.builder.editor",
- "keybindings",
- NULL,
- "\"vim\"",
- _("Vim"),
- _("Emulates the Vim text editor"),
- NULL,
- 30);
+ g_assert (IDE_IS_PREFERENCES_WINDOW (window));
+
+ ide_preferences_window_add_items (window, items, G_N_ELEMENTS (items), window, NULL);
+
+ IDE_EXIT;
}
static void
-gbp_vim_preferences_addin_unload (IdePreferencesAddin *addin,
- DzlPreferences *preferences)
+gbp_vim_preferences_addin_unload (IdePreferencesAddin *addin,
+ IdePreferencesWindow *window,
+ IdeContext *context)
{
GbpVimPreferencesAddin *self = (GbpVimPreferencesAddin *)addin;
g_assert (GBP_IS_VIM_PREFERENCES_ADDIN (self));
- g_assert (DZL_IS_PREFERENCES (preferences));
+ g_assert (IDE_IS_PREFERENCES_WINDOW (window));
- dzl_preferences_remove_id (preferences, self->keybinding_id);
}
static void
@@ -75,8 +77,7 @@ preferences_addin_iface_init (IdePreferencesAddinInterface *iface)
}
G_DEFINE_FINAL_TYPE_WITH_CODE (GbpVimPreferencesAddin, gbp_vim_preferences_addin, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (IDE_TYPE_PREFERENCES_ADDIN,
- preferences_addin_iface_init))
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_PREFERENCES_ADDIN,
preferences_addin_iface_init))
static void
gbp_vim_preferences_addin_class_init (GbpVimPreferencesAddinClass *klass)
diff --git a/src/plugins/vim/gbp-vim-preferences-addin.h b/src/plugins/vim/gbp-vim-preferences-addin.h
index 7a8663cf4..d20fda95f 100644
--- a/src/plugins/vim/gbp-vim-preferences-addin.h
+++ b/src/plugins/vim/gbp-vim-preferences-addin.h
@@ -1,6 +1,6 @@
/* gbp-vim-preferences-addin.h
*
- * Copyright 2018-2019 Christian Hergert <chergert redhat com>
+ * Copyright 2018-2022 Christian Hergert <chergert redhat com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/plugins/vim/gbp-vim-workspace-addin.c b/src/plugins/vim/gbp-vim-workspace-addin.c
new file mode 100644
index 000000000..c7579c191
--- /dev/null
+++ b/src/plugins/vim/gbp-vim-workspace-addin.c
@@ -0,0 +1,246 @@
+/* gbp-vim-workspace-addin.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "gbp-vim-workspace-addin"
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <libpanel.h>
+
+#include <libide-gui.h>
+
+#include "gbp-vim-workspace-addin.h"
+
+struct _GbpVimWorkspaceAddin
+{
+ GObject parent_instance;
+
+ GSettings *editor_settings;
+
+ GtkLabel *command_bar;
+ GtkLabel *command;
+
+ guint active : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_ACTIVE,
+ N_PROPS
+};
+
+static GParamSpec *properties[N_PROPS];
+
+static void
+on_keybindings_changed_cb (GbpVimWorkspaceAddin *self,
+ const char *key,
+ GSettings *editor_settings)
+{
+ g_autofree char *keybindings = NULL;
+ gboolean active;
+
+ g_assert (GBP_IS_VIM_WORKSPACE_ADDIN (self));
+ g_assert (g_strcmp0 (key, "keybindings") == 0);
+ g_assert (G_IS_SETTINGS (editor_settings));
+
+ keybindings = g_settings_get_string (editor_settings, "keybindings");
+ active = g_strcmp0 (keybindings, "vim") == 0;
+
+ if (active != self->active)
+ {
+ self->active = active;
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIVE]);
+ }
+}
+
+static void
+gbp_vim_workspace_addin_load (IdeWorkspaceAddin *addin,
+ IdeWorkspace *workspace)
+{
+ GbpVimWorkspaceAddin *self = (GbpVimWorkspaceAddin *)addin;
+ g_autofree char *keybindings = NULL;
+ PanelStatusbar *statusbar;
+ PangoAttrList *attrs;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_WORKSPACE_ADDIN (self));
+ g_assert (IDE_IS_WORKSPACE (workspace));
+
+ self->editor_settings = g_settings_new ("org.gnome.builder.editor");
+ keybindings = g_settings_get_string (self->editor_settings, "keybindings");
+ g_signal_connect_object (self->editor_settings,
+ "changed::keybindings",
+ G_CALLBACK (on_keybindings_changed_cb),
+ self,
+ G_CONNECT_SWAPPED);
+
+ self->active = g_strcmp0 (keybindings, "vim") == 0;
+
+ if (!self->active)
+ g_debug ("Vim plugin loaded but inactive as keybindings are currently \"%s\"",
+ keybindings);
+
+ attrs = pango_attr_list_new ();
+ pango_attr_list_insert (attrs, pango_attr_family_new ("Monospace"));
+
+ self->command_bar = g_object_new (GTK_TYPE_LABEL,
+ "attributes", attrs,
+ "hexpand", TRUE,
+ "selectable", TRUE,
+ "visible", FALSE,
+ "xalign", .0f,
+ NULL);
+ self->command = g_object_new (GTK_TYPE_LABEL,
+ "attributes", attrs,
+ "visible", FALSE,
+ "xalign", 1.f,
+ NULL);
+
+ statusbar = ide_workspace_get_statusbar (workspace);
+
+ panel_statusbar_add_prefix (statusbar, 10000, GTK_WIDGET (self->command_bar));
+ panel_statusbar_add_suffix (statusbar, 21000, GTK_WIDGET (self->command));
+
+ pango_attr_list_unref (attrs);
+
+ IDE_EXIT;
+}
+
+static void
+gbp_vim_workspace_addin_unload (IdeWorkspaceAddin *addin,
+ IdeWorkspace *workspace)
+{
+ GbpVimWorkspaceAddin *self = (GbpVimWorkspaceAddin *)addin;
+ PanelStatusbar *statusbar;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_WORKSPACE_ADDIN (self));
+ g_assert (IDE_IS_WORKSPACE (workspace));
+
+ statusbar = ide_workspace_get_statusbar (workspace);
+
+ panel_statusbar_remove (statusbar, GTK_WIDGET (self->command_bar));
+ panel_statusbar_remove (statusbar, GTK_WIDGET (self->command));
+
+ self->command_bar = NULL;
+ self->command = NULL;
+ self->active = FALSE;
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ACTIVE]);
+
+ g_clear_object (&self->editor_settings);
+
+ IDE_EXIT;
+}
+
+static void
+workspace_addin_iface_init (IdeWorkspaceAddinInterface *iface)
+{
+ iface->load = gbp_vim_workspace_addin_load;
+ iface->unload = gbp_vim_workspace_addin_unload;
+}
+
+G_DEFINE_FINAL_TYPE_WITH_CODE (GbpVimWorkspaceAddin, gbp_vim_workspace_addin, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_WORKSPACE_ADDIN, workspace_addin_iface_init))
+
+static void
+gbp_vim_workspace_addin_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GbpVimWorkspaceAddin *self = GBP_VIM_WORKSPACE_ADDIN (object);
+
+ switch (prop_id)
+ {
+ case PROP_ACTIVE:
+ g_value_set_boolean (value, self->active);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gbp_vim_workspace_addin_class_init (GbpVimWorkspaceAddinClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = gbp_vim_workspace_addin_get_property;
+
+ /**
+ * GbpVimWorkspaceAddin:active:
+ *
+ * The "active" property is bound by other vim plugin hooks so that they
+ * may all enable/disable together based on the current keybindings setting
+ * in org.gnome.builder.editor.
+ */
+ properties [PROP_ACTIVE] =
+ g_param_spec_boolean ("active",
+ "Active",
+ "If vim is the active keybindings for the application",
+ FALSE,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+gbp_vim_workspace_addin_init (GbpVimWorkspaceAddin *self)
+{
+}
+
+void
+gbp_vim_workspace_addin_set_command (GbpVimWorkspaceAddin *self,
+ const char *command)
+{
+ g_return_if_fail (GBP_IS_VIM_WORKSPACE_ADDIN (self));
+
+ if (self->command != NULL)
+ {
+ gtk_label_set_label (self->command, command);
+ gtk_widget_set_visible (GTK_WIDGET (self->command), !ide_str_empty0 (command));
+ }
+}
+
+void
+gbp_vim_workspace_addin_set_command_bar (GbpVimWorkspaceAddin *self,
+ const char *command_bar)
+{
+ g_return_if_fail (GBP_IS_VIM_WORKSPACE_ADDIN (self));
+
+ if (self->command_bar != NULL)
+ {
+ gtk_label_set_label (self->command_bar, command_bar);
+ gtk_widget_set_visible (GTK_WIDGET (self->command_bar), !ide_str_empty0 (command_bar));
+ }
+}
+
+gboolean
+gbp_vim_workspace_addin_get_active (GbpVimWorkspaceAddin *self)
+{
+ g_return_val_if_fail (GBP_IS_VIM_WORKSPACE_ADDIN (self), FALSE);
+
+ return self->active;
+}
diff --git a/src/plugins/vim/gbp-vim-command.h b/src/plugins/vim/gbp-vim-workspace-addin.h
similarity index 51%
rename from src/plugins/vim/gbp-vim-command.h
rename to src/plugins/vim/gbp-vim-workspace-addin.h
index 79e5994d1..c03ecf0ed 100644
--- a/src/plugins/vim/gbp-vim-command.h
+++ b/src/plugins/vim/gbp-vim-workspace-addin.h
@@ -1,6 +1,6 @@
-/* gbp-vim-command.h
+/* gbp-vim-workspace-addin.h
*
- * Copyright 2018-2019 Christian Hergert <chergert redhat com>
+ * Copyright 2022 Christian Hergert <chergert redhat com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,17 +20,18 @@
#pragma once
-#include <libide-core.h>
+#include <glib-object.h>
G_BEGIN_DECLS
-#define GBP_TYPE_VIM_COMMAND (gbp_vim_command_get_type())
+#define GBP_TYPE_VIM_WORKSPACE_ADDIN (gbp_vim_workspace_addin_get_type())
-G_DECLARE_FINAL_TYPE (GbpVimCommand, gbp_vim_command, GBP, VIM_COMMAND, IdeObject)
+G_DECLARE_FINAL_TYPE (GbpVimWorkspaceAddin, gbp_vim_workspace_addin, GBP, VIM_WORKSPACE_ADDIN, GObject)
-GbpVimCommand *gbp_vim_command_new (GtkWidget *active_widget,
- const gchar *typed_text,
- const gchar *command,
- const gchar *description);
+gboolean gbp_vim_workspace_addin_get_active (GbpVimWorkspaceAddin *self);
+void gbp_vim_workspace_addin_set_command (GbpVimWorkspaceAddin *self,
+ const char *command);
+void gbp_vim_workspace_addin_set_command_bar (GbpVimWorkspaceAddin *self,
+ const char *command_bar);
G_END_DECLS
diff --git a/src/plugins/vim/meson.build b/src/plugins/vim/meson.build
index fcdcde818..8fdfd0080 100644
--- a/src/plugins/vim/meson.build
+++ b/src/plugins/vim/meson.build
@@ -1,9 +1,8 @@
plugins_sources += files([
'vim-plugin.c',
- 'gb-vim.c',
- 'gbp-vim-command.c',
- 'gbp-vim-command-provider.c',
+ 'gbp-vim-editor-page-addin.c',
'gbp-vim-preferences-addin.c',
+ 'gbp-vim-workspace-addin.c',
])
plugin_vim_resources = gnome.compile_resources(
diff --git a/src/plugins/vim/vim-plugin.c b/src/plugins/vim/vim-plugin.c
index 5a4cca438..417836cd2 100644
--- a/src/plugins/vim/vim-plugin.c
+++ b/src/plugins/vim/vim-plugin.c
@@ -23,19 +23,25 @@
#include "config.h"
#include <libpeas/peas.h>
+
#include <libide-core.h>
#include <libide-gui.h>
+#include <libide-editor.h>
-#include "gbp-vim-command-provider.h"
+#include "gbp-vim-editor-page-addin.h"
#include "gbp-vim-preferences-addin.h"
+#include "gbp-vim-workspace-addin.h"
_IDE_EXTERN void
_gbp_vim_register_types (PeasObjectModule *module)
{
+ peas_object_module_register_extension_type (module,
+ IDE_TYPE_EDITOR_PAGE_ADDIN,
+ GBP_TYPE_VIM_EDITOR_PAGE_ADDIN);
peas_object_module_register_extension_type (module,
IDE_TYPE_PREFERENCES_ADDIN,
GBP_TYPE_VIM_PREFERENCES_ADDIN);
peas_object_module_register_extension_type (module,
- IDE_TYPE_COMMAND_PROVIDER,
- GBP_TYPE_VIM_COMMAND_PROVIDER);
+ IDE_TYPE_WORKSPACE_ADDIN,
+ GBP_TYPE_VIM_WORKSPACE_ADDIN);
}
diff --git a/src/plugins/vim/vim.gresource.xml b/src/plugins/vim/vim.gresource.xml
index 6d08eaaf2..6db9e6389 100644
--- a/src/plugins/vim/vim.gresource.xml
+++ b/src/plugins/vim/vim.gresource.xml
@@ -2,6 +2,5 @@
<gresources>
<gresource prefix="/plugins/vim">
<file>vim.plugin</file>
- <file>keybindings/vim.css</file>
</gresource>
</gresources>
diff --git a/src/plugins/vim/vim.plugin b/src/plugins/vim/vim.plugin
index 5d9d0ef21..6decdc4ad 100644
--- a/src/plugins/vim/vim.plugin
+++ b/src/plugins/vim/vim.plugin
@@ -1,9 +1,11 @@
[Plugin]
Authors=Christian Hergert <christian hergert me>
Builtin=true
-Copyright=Copyright © 2015-2018 Christian Hergert
+Copyright=Copyright © 2015-2022 Christian Hergert
Description=Emulation of various VIM features
Embedded=_gbp_vim_register_types
-Hidden=true
Module=vim
Name=VIM Emulation
+X-Category=keybindings
+X-Workspace-Kind=editor;primary;
+X-Preferences-Kind=application;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]