[gnome-builder/wip/scrolloff] gb-source-vim: Add support for vim scrolloff
- From: Carlos Soriano Sánchez <csoriano src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/scrolloff] gb-source-vim: Add support for vim scrolloff
- Date: Tue, 6 Jan 2015 10:06:19 +0000 (UTC)
commit 583b8f51330b2cbecff45b4435aae57de67956c1
Author: Carlos Soriano <carlos soriano89 gmail com>
Date: Tue Jan 6 00:01:02 2015 +0100
gb-source-vim: Add support for vim scrolloff
Vim scrolloff allow the user to set a margin of a number of lines
while moving through the buffer.
Add support to it and add a setting to let the user adjust the number
of lines.
As a detail, a scrolloff greater than half of the number of lines in the
buffer keeps the current line always in the middle.
https://bugzilla.gnome.org/show_bug.cgi?id=742442
configure.ac | 1 +
data/gsettings.mk | 1 +
data/org.gnome.builder.editor.vim.gschema.xml.in | 8 ++
src/gnome-builder.mk | 2 +
src/preferences/gb-preferences-page-vim.c | 94 +++++++++++++++
src/preferences/gb-preferences-page-vim.h | 55 +++++++++
src/preferences/gb-preferences-page.c | 22 ++++
src/preferences/gb-preferences-page.h | 17 ++-
src/preferences/gb-preferences-window.c | 38 ++++++-
src/resources/gnome-builder.gresource.xml | 1 +
src/resources/ui/gb-preferences-page-vim.ui | 90 ++++++++++++++
src/resources/ui/gb-preferences-window.ui | 9 ++
src/vim/gb-source-vim.c | 136 ++++++++++++++++++----
13 files changed, 445 insertions(+), 29 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index b4e0b7f..23eb9ee 100644
--- a/configure.ac
+++ b/configure.ac
@@ -51,6 +51,7 @@ AC_CONFIG_FILES([
data/icons/Makefile
data/org.gnome.builder.editor.gschema.xml
data/org.gnome.builder.editor.language.gschema.xml
+ data/org.gnome.builder.editor.vim.gschema.xml
])
# Last change to configure things and write configuration files.
diff --git a/data/gsettings.mk b/data/gsettings.mk
index e15f2b6..fbd3e0b 100644
--- a/data/gsettings.mk
+++ b/data/gsettings.mk
@@ -1,5 +1,6 @@
gsettingsschema_in_files = \
data/org.gnome.builder.editor.gschema.xml.in \
+ data/org.gnome.builder.editor.vim.gschema.xml.in \
data/org.gnome.builder.editor.language.gschema.xml.in
gsettings_SCHEMAS = $(gsettingsschema_in_files:.xml.in=.xml)
diff --git a/data/org.gnome.builder.editor.vim.gschema.xml.in
b/data/org.gnome.builder.editor.vim.gschema.xml.in
new file mode 100644
index 0000000..9f2a829
--- /dev/null
+++ b/data/org.gnome.builder.editor.vim.gschema.xml.in
@@ -0,0 +1,8 @@
+<schemalist>
+ <schema id="org.gnome.builder.editor.vim" path="/org/gnome/builder/editor/vim/"
gettext-domain="gnome-builder">
+ <key name="scroll-off" type="i">
+ <range min="0" max="999"/>
+ <default>0</default>
+ </key>
+ </schema>
+</schemalist>
diff --git a/src/gnome-builder.mk b/src/gnome-builder.mk
index bcdc5f9..6c877ac 100644
--- a/src/gnome-builder.mk
+++ b/src/gnome-builder.mk
@@ -141,6 +141,8 @@ libgnome_builder_la_SOURCES = \
src/preferences/gb-preferences-page-git.h \
src/preferences/gb-preferences-page-language.c \
src/preferences/gb-preferences-page-language.h \
+ src/preferences/gb-preferences-page-vim.c \
+ src/preferences/gb-preferences-page-vim.h \
src/preferences/gb-preferences-page.c \
src/preferences/gb-preferences-page.h \
src/preferences/gb-preferences-window.c \
diff --git a/src/preferences/gb-preferences-page-vim.c b/src/preferences/gb-preferences-page-vim.c
new file mode 100644
index 0000000..deb642d
--- /dev/null
+++ b/src/preferences/gb-preferences-page-vim.c
@@ -0,0 +1,94 @@
+/* gb-preferences-page-vim.c
+ *
+ * Copyright (C) 2015 Carlos Soriano <csoriano gnome org>
+ *
+ * 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/>.
+ */
+
+#define G_LOG_DOMAIN "prefs-page-editor"
+
+#include <glib/gi18n.h>
+
+#include "gb-preferences-page-vim.h"
+
+struct _GbPreferencesPageVimPrivate
+{
+ GSettings *settings;
+
+ /* Widgets owned by Template */
+ GtkSpinButton *scroll_off_spin;
+
+ /* Template widgets used for filtering */
+ GtkWidget *scroll_off_container;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GbPreferencesPageVim, gb_preferences_page_vim,
+ GB_TYPE_PREFERENCES_PAGE)
+
+static void
+gb_preferences_page_vim_constructed (GObject *object)
+{
+ GbPreferencesPageVimPrivate *priv;
+ GbPreferencesPageVim *vim = (GbPreferencesPageVim *)object;
+
+ g_return_if_fail (GB_IS_PREFERENCES_PAGE_VIM (vim));
+
+ priv = vim->priv;
+
+ priv->settings = g_settings_new ("org.gnome.builder.editor.vim");
+
+ g_settings_bind (priv->settings, "scroll-off", priv->scroll_off_spin, "value",
+ G_SETTINGS_BIND_DEFAULT);
+}
+
+static void
+gb_preferences_page_vim_finalize (GObject *object)
+{
+ GbPreferencesPageVimPrivate *priv = GB_PREFERENCES_PAGE_VIM (object)->priv;
+
+ g_clear_object (&priv->settings);
+
+ G_OBJECT_CLASS (gb_preferences_page_vim_parent_class)->finalize (object);
+}
+
+static void
+gb_preferences_page_vim_class_init (GbPreferencesPageVimClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = gb_preferences_page_vim_finalize;
+ object_class->constructed = gb_preferences_page_vim_constructed;
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/org/gnome/builder/ui/gb-preferences-page-vim.ui");
+
+ gtk_widget_class_bind_template_child_private (widget_class, GbPreferencesPageVim, scroll_off_spin);
+
+ gtk_widget_class_bind_template_child_private (widget_class, GbPreferencesPageVim, scroll_off_container);
+}
+
+static void
+gb_preferences_page_vim_init (GbPreferencesPageVim *self)
+{
+ self->priv = gb_preferences_page_vim_get_instance_private (self);
+
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ gb_preferences_page_set_keywords_for_widget (GB_PREFERENCES_PAGE (self),
+ _("lines margin scrolloff scroll off"),
+ self->priv->scroll_off_container,
+ self->priv->scroll_off_spin,
+ NULL);
+}
diff --git a/src/preferences/gb-preferences-page-vim.h b/src/preferences/gb-preferences-page-vim.h
new file mode 100644
index 0000000..f3a7b0e
--- /dev/null
+++ b/src/preferences/gb-preferences-page-vim.h
@@ -0,0 +1,55 @@
+/* gb-preferences-page-vim.h
+ *
+ * Copyright (C) 2015 Carlos Soriano <csoriano gnome org>
+ *
+ * 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/>.
+ */
+
+#ifndef GB_PREFERENCES_PAGE_VIM_H
+#define GB_PREFERENCES_PAGE_VIM_H
+
+#include "gb-preferences-page.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_PREFERENCES_PAGE_VIM (gb_preferences_page_vim_get_type())
+#define GB_PREFERENCES_PAGE_VIM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GB_TYPE_PREFERENCES_PAGE_VIM, GbPreferencesPageVim))
+#define GB_PREFERENCES_PAGE_VIM_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GB_TYPE_PREFERENCES_PAGE_VIM, GbPreferencesPageVim const))
+#define GB_PREFERENCES_PAGE_VIM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
GB_TYPE_PREFERENCES_PAGE_VIM, GbPreferencesPageVimClass))
+#define GB_IS_PREFERENCES_PAGE_VIM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
GB_TYPE_PREFERENCES_PAGE_VIM))
+#define GB_IS_PREFERENCES_PAGE_VIM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
GB_TYPE_PREFERENCES_PAGE_VIM))
+#define GB_PREFERENCES_PAGE_VIM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
GB_TYPE_PREFERENCES_PAGE_VIM, GbPreferencesPageVimClass))
+
+typedef struct _GbPreferencesPageVim GbPreferencesPageVim;
+typedef struct _GbPreferencesPageVimClass GbPreferencesPageVimClass;
+typedef struct _GbPreferencesPageVimPrivate GbPreferencesPageVimPrivate;
+
+struct _GbPreferencesPageVim
+{
+ GbPreferencesPage parent;
+
+ /*< private >*/
+ GbPreferencesPageVimPrivate *priv;
+};
+
+struct _GbPreferencesPageVimClass
+{
+ GbPreferencesPageClass parent;
+};
+
+GType gb_preferences_page_vim_get_type (void);
+
+G_END_DECLS
+
+#endif /* GB_PREFERENCES_PAGE_VIM_H */
diff --git a/src/preferences/gb-preferences-page.c b/src/preferences/gb-preferences-page.c
index aef24e5..fbc07d1 100644
--- a/src/preferences/gb-preferences-page.c
+++ b/src/preferences/gb-preferences-page.c
@@ -28,6 +28,7 @@ struct _GbPreferencesPagePrivate
{
GHashTable *widgets;
gchar *title;
+ gboolean active;
};
G_DEFINE_TYPE_WITH_PRIVATE (GbPreferencesPage, gb_preferences_page,
@@ -155,6 +156,23 @@ gb_preferences_page_set_title (GbPreferencesPage *page,
}
}
+gboolean
+gb_preferences_page_get_active (GbPreferencesPage *page)
+{
+ g_return_val_if_fail (GB_IS_PREFERENCES_PAGE (page), FALSE);
+
+ return page->priv->active;
+}
+
+void
+gb_preferences_page_set_active (GbPreferencesPage *page,
+ gboolean active)
+{
+ g_return_if_fail (GB_IS_PREFERENCES_PAGE (page));
+
+ page->priv->active = active;
+}
+
static void
gb_preferences_page_finalize (GObject *object)
{
@@ -230,4 +248,8 @@ gb_preferences_page_init (GbPreferencesPage *self)
self->priv = gb_preferences_page_get_instance_private (self);
self->priv->widgets = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, NULL);
+ /* Make it active by default. If some page has to be disabled
+ * let the preferences window make it disabled.
+ */
+ self->priv->active = TRUE;
}
diff --git a/src/preferences/gb-preferences-page.h b/src/preferences/gb-preferences-page.h
index e475859..5d4f93a 100644
--- a/src/preferences/gb-preferences-page.h
+++ b/src/preferences/gb-preferences-page.h
@@ -48,13 +48,16 @@ struct _GbPreferencesPageClass
GtkBinClass parent;
};
-GType gb_preferences_page_get_type (void);
-guint gb_preferences_page_set_keywords (GbPreferencesPage *page,
- const gchar * const *keywords);
-void gb_preferences_page_set_keywords_for_widget (GbPreferencesPage *page,
- const gchar *keywords,
- GtkWidget *first_widget,
- ...) G_GNUC_NULL_TERMINATED;
+GType gb_preferences_page_get_type (void);
+guint gb_preferences_page_set_keywords (GbPreferencesPage *page,
+ const gchar * const *keywords);
+void gb_preferences_page_set_keywords_for_widget (GbPreferencesPage *page,
+ const gchar *keywords,
+ GtkWidget *first_widget,
+ ...) G_GNUC_NULL_TERMINATED;
+gboolean gb_preferences_page_get_active (GbPreferencesPage *page);
+void gb_preferences_page_set_active (GbPreferencesPage *page,
+ gboolean active);
G_END_DECLS
diff --git a/src/preferences/gb-preferences-window.c b/src/preferences/gb-preferences-window.c
index 35d4427..bb21f9c 100644
--- a/src/preferences/gb-preferences-window.c
+++ b/src/preferences/gb-preferences-window.c
@@ -27,6 +27,8 @@
#include "gb-preferences-page-editor.h"
#include "gb-preferences-page-git.h"
#include "gb-preferences-page-language.h"
+#include "gb-preferences-page-vim.h"
+#include "gb-preferences-page.h"
#include "gb-preferences-window.h"
struct _GbPreferencesWindowPrivate
@@ -35,6 +37,10 @@ struct _GbPreferencesWindowPrivate
GtkSearchEntry *search_entry;
GtkSearchBar *search_bar;
GtkStack *stack;
+
+ GtkWidget *vim_page;
+
+ GSettings *editor_settings;
};
G_DEFINE_TYPE_WITH_PRIVATE (GbPreferencesWindow, gb_preferences_window,
@@ -110,7 +116,8 @@ gb_preferences_window_search_changed (GbPreferencesWindow *window,
if (0 == gb_preferences_page_set_keywords (page, (const gchar * const *)keywords))
gtk_widget_set_visible (GTK_WIDGET (page), FALSE);
else
- gtk_widget_set_visible (GTK_WIDGET (page), TRUE);
+ gtk_widget_set_visible (GTK_WIDGET (page),
+ gb_preferences_page_get_active (page));
}
g_list_free (pages);
@@ -143,6 +150,10 @@ gb_preferences_window_constructed (GObject *object)
static void
gb_preferences_window_finalize (GObject *object)
{
+ GbPreferencesWindowPrivate *priv = GB_PREFERENCES_WINDOW (object)->priv;
+
+ g_clear_object (&priv->editor_settings);
+
G_OBJECT_CLASS (gb_preferences_window_parent_class)->finalize (object);
}
@@ -173,6 +184,21 @@ gb_preferences_window_set_property (GObject *object,
}
static void
+gb_prefereces_window_vim_mode_changed (GbPreferencesWindow *window,
+ const gchar *key,
+ GSettings *settings)
+{
+ gboolean active;
+ g_return_if_fail (GB_IS_PREFERENCES_WINDOW (window));
+ g_return_if_fail (G_IS_SETTINGS (settings));
+
+ active = g_settings_get_boolean (settings, "vim-mode");
+ gtk_widget_set_visible (window->priv->vim_page, active);
+ gb_preferences_page_set_active (GB_PREFERENCES_PAGE (window->priv->vim_page),
+ active);
+}
+
+static void
gb_preferences_window_class_init (GbPreferencesWindowClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -206,10 +232,12 @@ gb_preferences_window_class_init (GbPreferencesWindowClass *klass)
gtk_widget_class_bind_template_child_private (widget_class, GbPreferencesWindow, search_bar);
gtk_widget_class_bind_template_child_private (widget_class, GbPreferencesWindow, search_entry);
gtk_widget_class_bind_template_child_private (widget_class, GbPreferencesWindow, stack);
+ gtk_widget_class_bind_template_child_private (widget_class, GbPreferencesWindow, vim_page);
g_type_ensure (GB_TYPE_PREFERENCES_PAGE_GIT);
g_type_ensure (GB_TYPE_PREFERENCES_PAGE_EDITOR);
g_type_ensure (GB_TYPE_PREFERENCES_PAGE_LANGUAGE);
+ g_type_ensure (GB_TYPE_PREFERENCES_PAGE_VIM);
}
static void
@@ -218,4 +246,12 @@ gb_preferences_window_init (GbPreferencesWindow *self)
self->priv = gb_preferences_window_get_instance_private (self);
gtk_widget_init_template (GTK_WIDGET (self));
+
+ self->priv->editor_settings = g_settings_new ("org.gnome.builder.editor");
+ g_signal_connect_object (self->priv->editor_settings,
+ "changed::vim-mode",
+ G_CALLBACK (gb_prefereces_window_vim_mode_changed),
+ self,
+ G_CONNECT_SWAPPED);
+ gb_prefereces_window_vim_mode_changed (self, NULL, self->priv->editor_settings);
}
diff --git a/src/resources/gnome-builder.gresource.xml b/src/resources/gnome-builder.gresource.xml
index 2c046a5..3cfe32b 100644
--- a/src/resources/gnome-builder.gresource.xml
+++ b/src/resources/gnome-builder.gresource.xml
@@ -39,6 +39,7 @@
<file>ui/gb-preferences-page-editor.ui</file>
<file>ui/gb-preferences-page-git.ui</file>
<file>ui/gb-preferences-page-language.ui</file>
+ <file>ui/gb-preferences-page-vim.ui</file>
<file>ui/gb-search-box.ui</file>
<file>ui/gb-search-display.ui</file>
<file>ui/gb-workbench.ui</file>
diff --git a/src/resources/ui/gb-preferences-page-vim.ui b/src/resources/ui/gb-preferences-page-vim.ui
new file mode 100644
index 0000000..e55f692
--- /dev/null
+++ b/src/resources/ui/gb-preferences-page-vim.ui
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.8 -->
+ <template class="GbPreferencesPageVim" parent="GbPreferencesPage">
+ <child>
+ <object class="GtkBox">
+ <property name="visible">true</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkSpinButton" id="scroll_off_spin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ <property name="adjustment">scroll_off_adjustment</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="scroll_off_container">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes"><b>Scroll Off</b></property>
+ <property name="use_markup">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Margin in lines for cursor movement.</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="GtkAdjustment" id="scroll_off_adjustment">
+ <property name="lower">0</property>
+ <property name="upper">999</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">1</property>
+ <property name="value">0</property>
+ </object>
+</interface>
diff --git a/src/resources/ui/gb-preferences-window.ui b/src/resources/ui/gb-preferences-window.ui
index d2e38d6..1859c80 100644
--- a/src/resources/ui/gb-preferences-window.ui
+++ b/src/resources/ui/gb-preferences-window.ui
@@ -132,6 +132,15 @@
<property name="title" translatable="yes">Git</property>
</packing>
</child>
+ <child>
+ <object class="GbPreferencesPageVim" id="vim_page">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="name">vim</property>
+ <property name="title" translatable="yes">Vim</property>
+ </packing>
+ </child>
</object>
</child>
</object>
diff --git a/src/vim/gb-source-vim.c b/src/vim/gb-source-vim.c
index 5694d81..b5e4ea6 100644
--- a/src/vim/gb-source-vim.c
+++ b/src/vim/gb-source-vim.c
@@ -17,7 +17,6 @@
*/
#define G_LOG_DOMAIN "vim"
-#define SCROLL_OFF 3
#include <errno.h>
#include <glib/gi18n.h>
@@ -81,6 +80,7 @@ struct _GbSourceVimPrivate
GtkSourceSearchSettings *search_settings;
GPtrArray *captured_events;
GbSourceVimMode mode;
+ GSettings *vim_settings;
gulong key_press_event_handler;
gulong key_release_event_handler;
gulong focus_in_event_handler;
@@ -90,6 +90,7 @@ struct _GbSourceVimPrivate
guint stash_line;
guint stash_line_offset;
guint anim_timeout;
+ guint scroll_off;
gchar recording_trigger;
gchar recording_modifier;
guint enabled : 1;
@@ -108,6 +109,14 @@ typedef enum
typedef enum
{
+ GB_SOURCE_VIM_ALIGMENT_NONE,
+ GB_SOURCE_VIM_ALIGMENT_KEEP,
+ GB_SOURCE_VIM_ALIGMENT_TOP,
+ GB_SOURCE_VIM_ALIGMENT_BOTTOM
+} GbSourceVimAligment;
+
+typedef enum
+{
GB_SOURCE_VIM_COMMAND_NOOP,
GB_SOURCE_VIM_COMMAND_MOVEMENT,
GB_SOURCE_VIM_COMMAND_CHANGE,
@@ -139,6 +148,12 @@ typedef struct
GbSourceVimCommandFlags flags;
} GbSourceVimCommand;
+typedef struct
+{
+ gfloat yalign;
+ gint line;
+} GbSourceVimAdjustedScroll;
+
typedef enum
{
GB_SOURCE_VIM_PHRASE_FAILED,
@@ -209,6 +224,10 @@ static void gb_source_vim_cmd_delete_to_end (GbSourceVim *vim,
static void gb_source_vim_cmd_insert_before_line (GbSourceVim *vim,
guint count,
gchar modifier);
+static GbSourceVimAdjustedScroll
+gb_source_vim_adjust_scroll (GbSourceVim *vim,
+ gint line,
+ GbSourceVimAligment aligment);
GbSourceVim *
gb_source_vim_new (GtkTextView *text_view)
@@ -1458,6 +1477,7 @@ gb_source_vim_move_down (GbSourceVim *vim)
GtkTextIter selection;
gboolean has_selection;
guint line;
+ GbSourceVimAdjustedScroll scroll;
guint offset;
g_assert (GB_IS_SOURCE_VIM (vim));
@@ -1530,6 +1550,9 @@ select_to_end:
move_mark:
insert = gtk_text_buffer_get_insert (buffer);
gtk_text_view_scroll_mark_onscreen (vim->priv->text_view, insert);
+ scroll= gb_source_vim_adjust_scroll (vim, line + 1, GB_SOURCE_VIM_ALIGMENT_NONE);
+ gtk_text_view_scroll_to_iter (vim->priv->text_view, &iter, 0.0,
+ TRUE, 0.5, scroll.yalign);
}
static void
@@ -1542,6 +1565,7 @@ gb_source_vim_move_up (GbSourceVim *vim)
GtkTextIter selection;
gboolean has_selection;
guint line;
+ GbSourceVimAdjustedScroll scroll;
guint offset;
g_assert (GB_IS_SOURCE_VIM (vim));
@@ -1598,6 +1622,9 @@ gb_source_vim_move_up (GbSourceVim *vim)
move_mark:
insert = gtk_text_buffer_get_insert (buffer);
gtk_text_view_scroll_mark_onscreen (vim->priv->text_view, insert);
+ scroll= gb_source_vim_adjust_scroll (vim, line - 1, GB_SOURCE_VIM_ALIGMENT_NONE);
+ gtk_text_view_scroll_to_iter (vim->priv->text_view, &iter, 0.0,
+ TRUE, 0.5, scroll.yalign);
}
static void
@@ -2626,6 +2653,64 @@ gb_source_vim_move_to_iter (GbSourceVim *vim,
TRUE, 0.5, yalign);
}
+static GbSourceVimAdjustedScroll
+gb_source_vim_adjust_scroll (GbSourceVim *vim,
+ gint line,
+ GbSourceVimAligment aligment)
+{
+ GdkRectangle rect;
+ gint line_top, line_bottom, line_current;
+ gint page_lines;
+ GtkTextIter iter_top, iter_bottom, iter_current;
+ GtkTextBuffer *buffer;
+ gfloat min_yalign, max_yalign, yalign;
+ GbSourceVimAdjustedScroll result;
+
+ g_assert (GB_IS_SOURCE_VIM (vim));
+
+ gtk_text_view_get_visible_rect (vim->priv->text_view, &rect);
+ gtk_text_view_get_iter_at_location (vim->priv->text_view, &iter_top,
+ rect.x, rect.y);
+ gtk_text_view_get_iter_at_location (vim->priv->text_view, &iter_bottom,
+ rect.x, rect.y + rect.height);
+
+ buffer = gtk_text_view_get_buffer (vim->priv->text_view);
+ gtk_text_buffer_get_selection_bounds (buffer, &iter_current, NULL);
+
+ line_top = gtk_text_iter_get_line (&iter_top);
+ line_bottom = gtk_text_iter_get_line (&iter_bottom);
+ line_current = gtk_text_iter_get_line (&iter_current);
+ page_lines = line_bottom - line_top;
+ min_yalign = MIN (vim->priv->scroll_off / (float) page_lines, 0.5);
+ max_yalign = 1.0 - min_yalign;
+ yalign = (line - line_top) / (float) page_lines;
+
+ switch (aligment)
+ {
+ case GB_SOURCE_VIM_ALIGMENT_NONE:
+ result.yalign = CLAMP (yalign, min_yalign, max_yalign);
+ result.line = line;
+ break;
+ case GB_SOURCE_VIM_ALIGMENT_KEEP:
+ result.yalign = MAX (0.0, (float)(line_current - line_top) /
+ (float)(line_bottom - line_top));
+ result.line = line;
+ break;
+ case GB_SOURCE_VIM_ALIGMENT_TOP:
+ result.yalign = CLAMP (0.0, min_yalign, max_yalign);
+ result.line = line + result.yalign * page_lines;
+ break;
+ case GB_SOURCE_VIM_ALIGMENT_BOTTOM:
+ result.yalign = CLAMP (1.0, min_yalign, max_yalign);
+ result.line = line - (1.0 - result.yalign) * page_lines;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ return result;
+}
+
static void
gb_source_vim_move_page (GbSourceVim *vim,
GbSourceVimPageDirectionType direction)
@@ -2635,7 +2720,7 @@ gb_source_vim_move_page (GbSourceVim *vim,
guint offset;
gint line, line_top, line_bottom, line_current;
GtkTextBuffer *buffer;
- gfloat yalign = 0.0;
+ GbSourceVimAdjustedScroll adjusted_scroll;
g_assert (GB_IS_SOURCE_VIM (vim));
@@ -2652,47 +2737,36 @@ gb_source_vim_move_page (GbSourceVim *vim,
line_bottom = gtk_text_iter_get_line (&iter_bottom);
line_current = gtk_text_iter_get_line (&iter_current);
- if (direction == GB_SOURCE_VIM_HALF_PAGE_UP ||
- direction == GB_SOURCE_VIM_HALF_PAGE_DOWN)
- {
- /* keep current yalign */
- if (line_bottom != line_top)
- yalign = MAX (0.0, (float)(line_current - line_top) /
- (float)(line_bottom - line_top));
- }
-
switch (direction)
{
case GB_SOURCE_VIM_HALF_PAGE_UP:
line = line_current - (line_bottom - line_top) / 2;
+ adjusted_scroll = gb_source_vim_adjust_scroll (vim, line, GB_SOURCE_VIM_ALIGMENT_KEEP);
break;
case GB_SOURCE_VIM_HALF_PAGE_DOWN:
line = line_current + (line_bottom - line_top) / 2;
+ adjusted_scroll = gb_source_vim_adjust_scroll (vim, line, GB_SOURCE_VIM_ALIGMENT_KEEP);
break;
case GB_SOURCE_VIM_PAGE_UP:
- yalign = 1.0;
- line = gtk_text_iter_get_line (&iter_top) + SCROLL_OFF;
+ line = gtk_text_iter_get_line (&iter_top);
+ adjusted_scroll = gb_source_vim_adjust_scroll (vim, line, GB_SOURCE_VIM_ALIGMENT_BOTTOM);
break;
case GB_SOURCE_VIM_PAGE_DOWN:
- yalign = 0.0;
- /*
- * rect.y + rect.height is the next line after the end of the buffer so
- * now we have to decrease one more.
- */
- line = MAX (0, gtk_text_iter_get_line (&iter_bottom) - SCROLL_OFF - 1);
+ line = MAX (0, gtk_text_iter_get_line (&iter_bottom));
+ adjusted_scroll = gb_source_vim_adjust_scroll (vim, line, GB_SOURCE_VIM_ALIGMENT_TOP);
break;
default:
g_assert_not_reached();
}
- gtk_text_iter_set_line (&iter_current, line);
+ gtk_text_iter_set_line (&iter_current, adjusted_scroll.line);
for (offset = vim->priv->target_line_offset; offset; offset--)
if (gtk_text_iter_ends_line (&iter_current) ||
!gtk_text_iter_forward_char (&iter_current))
break;
- gb_source_vim_move_to_iter (vim, &iter_current, yalign);
+ gb_source_vim_move_to_iter (vim, &iter_current, adjusted_scroll.yalign);
}
static void
@@ -3951,6 +4025,7 @@ gb_source_vim_finalize (GObject *object)
}
g_clear_object (&priv->search_settings);
+ g_clear_object (&priv->vim_settings);
g_string_free (priv->phrase, TRUE);
priv->phrase = NULL;
@@ -5248,6 +5323,17 @@ gb_source_vim_class_init (GbSourceVimClass *klass)
}
static void
+gb_source_vim_scroll_off_changed (GbSourceVim *vim,
+ const gchar *key,
+ GSettings *settings)
+{
+ g_return_if_fail (GB_IS_SOURCE_VIM (vim));
+ g_return_if_fail (G_IS_SETTINGS (settings));
+
+ vim->priv->scroll_off = g_settings_get_int (settings, "scroll-off");
+}
+
+static void
gb_source_vim_init (GbSourceVim *vim)
{
vim->priv = gb_source_vim_get_instance_private (vim);
@@ -5257,6 +5343,14 @@ gb_source_vim_init (GbSourceVim *vim)
vim->priv->search_settings = gtk_source_search_settings_new ();
vim->priv->captured_events =
g_ptr_array_new_with_free_func ((GDestroyNotify)gdk_event_free);
+
+ vim->priv->vim_settings= g_settings_new ("org.gnome.builder.editor.vim");
+ g_signal_connect_object (vim->priv->vim_settings,
+ "changed::scroll-off",
+ G_CALLBACK (gb_source_vim_scroll_off_changed),
+ vim,
+ G_CONNECT_SWAPPED);
+ gb_source_vim_scroll_off_changed (vim, NULL, vim->priv->vim_settings);
}
GType
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]