[gnome-builder] editor: refactor settings out of editor tab and into source view



commit cd8587e4592e3bc2395f593953b05d6211f1f08b
Author: Christian Hergert <christian hergert me>
Date:   Fri Nov 21 01:11:15 2014 -0800

    editor: refactor settings out of editor tab and into source view

 src/editor/gb-editor-tab-private.h |    5 -
 src/editor/gb-editor-tab.c         |  272 ++----------------------------------
 src/editor/gb-source-view.c        |  272 ++++++++++++++++++++++++++++++++++--
 3 files changed, 266 insertions(+), 283 deletions(-)
---
diff --git a/src/editor/gb-editor-tab-private.h b/src/editor/gb-editor-tab-private.h
index bb1393d..51aeb6a 100644
--- a/src/editor/gb-editor-tab-private.h
+++ b/src/editor/gb-editor-tab-private.h
@@ -45,11 +45,6 @@ struct _GbEditorTabPrivate
   GbEditorDocument *document;
 
   /*
-   * Variants completion providers.
-   */
-  GtkSourceCompletionProvider *words_provider;
-
-  /*
    * Search releated components.
    */
   GbSourceSearchHighlighter *search_highlighter;
diff --git a/src/editor/gb-editor-tab.c b/src/editor/gb-editor-tab.c
index 0b6989c..52e6b9f 100644
--- a/src/editor/gb-editor-tab.c
+++ b/src/editor/gb-editor-tab.c
@@ -19,7 +19,6 @@
 #define G_LOG_DOMAIN "editor"
 
 #include <glib/gi18n.h>
-#include <gtksourceview/completion-providers/words/gtksourcecompletionwords.h>
 
 #include "gb-editor-code-assistant.h"
 #include "gb-editor-file-mark.h"
@@ -44,9 +43,7 @@
 enum {
   PROP_0,
   PROP_DOCUMENT,
-  PROP_ENABLE_WORD_COMPLETION,
   PROP_FILE,
-  PROP_SETTINGS,
   LAST_PROP
 };
 
@@ -60,44 +57,6 @@ gb_editor_tab_new (void)
   return g_object_new (GB_TYPE_EDITOR_TAB, NULL);
 }
 
-gboolean
-gb_editor_tab_get_enable_word_completion (GbEditorTab *tab)
-{
-  g_return_val_if_fail (GB_IS_EDITOR_TAB (tab), FALSE);
-
-  return tab->priv->enable_word_completion;
-}
-
-void
-gb_editor_tab_set_enable_word_completion (GbEditorTab *tab,
-                                          gboolean     enable_word_completion)
-{
-  GtkSourceCompletion *completion;
-  GtkSourceView *source_view;
-
-  g_return_if_fail (GB_IS_EDITOR_TAB (tab));
-
-  source_view = GTK_SOURCE_VIEW (tab->priv->source_view);
-  completion = gtk_source_view_get_completion (source_view);
-
-  if (enable_word_completion != tab->priv->enable_word_completion)
-    {
-      if (!enable_word_completion)
-        gtk_source_completion_remove_provider (
-            completion,
-            GTK_SOURCE_COMPLETION_PROVIDER (tab->priv->words_provider),
-            NULL);
-      else
-        gtk_source_completion_add_provider (
-            completion,
-            GTK_SOURCE_COMPLETION_PROVIDER (tab->priv->words_provider),
-            NULL);
-      tab->priv->enable_word_completion = enable_word_completion;
-      g_object_notify_by_pspec (G_OBJECT (tab),
-                                gParamSpecs [PROP_ENABLE_WORD_COMPLETION]);
-    }
-}
-
 /**
  * gb_editor_tab_get_is_default:
  * @tab: A #GbEditorTab.
@@ -167,142 +126,6 @@ gb_editor_tab_get_file (GbEditorTab *tab)
 }
 
 static void
-gb_editor_tab_connect_settings (GbEditorTab      *tab,
-                                GbEditorSettings *settings)
-{
-  GbEditorTabPrivate *priv;
-
-  ENTRY;
-
-  g_return_if_fail (GB_IS_EDITOR_TAB (tab));
-  g_return_if_fail (GB_IS_EDITOR_SETTINGS (settings));
-
-  priv = tab->priv;
-
-#define ADD_BINDING(name, dst, prop, loc) \
-  G_STMT_START { \
-    (loc) = g_object_bind_property (settings, name, (dst), \
-                                    prop, G_BINDING_SYNC_CREATE); \
-    g_object_add_weak_pointer (G_OBJECT ((loc)), (gpointer *) &(loc)); \
-  } G_STMT_END
-
-  ADD_BINDING ("auto-indent", priv->source_view, "auto-indent",
-               priv->auto_indent_binding);
-  ADD_BINDING ("highlight-current-line", priv->source_view,
-               "highlight-current-line",
-               priv->highlight_current_line_binding);
-  ADD_BINDING ("highlight-matching-brackets", priv->document,
-               "highlight-matching-brackets",
-               priv->highlight_matching_brackets_binding);
-  ADD_BINDING ("insert-spaces-instead-of-tabs", priv->source_view,
-               "insert-spaces-instead-of-tabs",
-               priv->insert_spaces_instead_of_tabs_binding);
-  ADD_BINDING ("show-line-marks", priv->source_view, "show-line-marks",
-               priv->show_line_marks_binding);
-  ADD_BINDING ("show-line-numbers", priv->source_view, "show-line-numbers",
-               priv->show_line_numbers_binding);
-  ADD_BINDING ("show-right-margin", priv->source_view, "show-right-margin",
-               priv->show_right_margin_binding);
-  ADD_BINDING ("smart-home-end", priv->source_view, "smart-home-end",
-               priv->smart_home_end_binding);
-  ADD_BINDING ("tab-width", priv->source_view, "tab-width",
-               priv->tab_width_binding);
-  ADD_BINDING ("right-margin-position", priv->source_view,
-               "right-margin-position", priv->right_margin_position_binding);
-
-#undef ADD_BINDING
-
-  EXIT;
-}
-
-static void
-gb_editor_tab_disconnect_settings (GbEditorTab *tab)
-{
-  GbEditorTabPrivate *priv;
-
-  ENTRY;
-
-  g_assert (GB_IS_EDITOR_TAB (tab));
-
-  priv = tab->priv;
-
-#define REMOVE_BINDING(b) \
-  if (b) { \
-      g_binding_unbind (b); \
-      if (b) \
-        g_object_remove_weak_pointer (G_OBJECT (b), (gpointer *) &(b)); \
-      (b) = NULL; \
-    }
-
-  REMOVE_BINDING (priv->auto_indent_binding);
-  REMOVE_BINDING (priv->highlight_current_line_binding);
-  REMOVE_BINDING (priv->highlight_matching_brackets_binding);
-  REMOVE_BINDING (priv->insert_spaces_instead_of_tabs_binding);
-  REMOVE_BINDING (priv->show_line_marks_binding);
-  REMOVE_BINDING (priv->show_line_numbers_binding);
-  REMOVE_BINDING (priv->show_right_margin_binding);
-  REMOVE_BINDING (priv->smart_home_end_binding);
-  REMOVE_BINDING (priv->tab_width_binding);
-  REMOVE_BINDING (priv->right_margin_position_binding);
-
-#undef REMOVE_BINDING
-
-  EXIT;
-}
-
-/**
- * gb_editor_tab_get_settings:
- * @tab: A #GbEditorTab.
- *
- * Fetches the settings used on the editor tab.
- *
- * Returns: (transfer none): A #GbEditorSettings.
- */
-GbEditorSettings *
-gb_editor_tab_get_settings (GbEditorTab *tab)
-{
-  g_return_val_if_fail (GB_IS_EDITOR_TAB (tab), NULL);
-
-  return tab->priv->settings;
-}
-
-/**
- * gb_editor_tab_set_settings:
- * @tab: A #GbEditorTab.
- *
- * Sets the settings to use for this tab, including tab spacing and
- * style schemes.
- */
-void
-gb_editor_tab_set_settings (GbEditorTab      *tab,
-                            GbEditorSettings *settings)
-{
-  GbEditorTabPrivate *priv;
-
-  ENTRY;
-
-  g_return_if_fail (GB_IS_EDITOR_TAB (tab));
-  g_return_if_fail (!settings || GB_IS_EDITOR_SETTINGS (settings));
-
-  priv = tab->priv;
-
-  if (priv->settings)
-    {
-      gb_editor_tab_disconnect_settings (tab);
-      g_clear_object (&priv->settings);
-    }
-
-  if (settings)
-    priv->settings = g_object_ref (settings);
-  else
-    priv->settings = g_object_new (GB_TYPE_EDITOR_SETTINGS, NULL);
-
-  gb_editor_tab_connect_settings (tab, priv->settings);
-
-  EXIT;
-}
-
-static void
 set_search_position_label (GbEditorTab *tab,
                            const gchar *text)
 {
@@ -1066,28 +889,17 @@ transform_file_to_language (GBinding     *binding,
 
       /*
        * TODO: Load content_type using g_file_query_info().
+       *       Also, don't do this here, do it async.
        */
 
       manager = gtk_source_language_manager_get_default ();
       language = gtk_source_language_manager_guess_language (manager, filename,
                                                              content_type);
+      gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (tab->priv->document),
+                                      language);
 
       gb_editor_code_assistant_destroy (tab);
 
-      /* TODO: This shouldn't be set here, this function shouldn't have
-       *       side effects. But easy to plumb it until we clean this up.
-       */
-      if (language)
-        {
-          GbEditorSettings *settings;
-          const gchar *lang_id;
-
-          lang_id = gtk_source_language_get_id (language);
-          settings = gb_editor_settings_new_for_language (lang_id);
-          gb_editor_tab_set_settings (tab, settings);
-          g_object_unref (settings);
-        }
-
       g_free (filename);
       g_free (content_type);
     }
@@ -1131,7 +943,6 @@ gb_editor_tab_constructed (GObject *object)
   GbEditorTab *tab = (GbEditorTab *) object;
   GbSourceVim *vim;
   GtkSourceGutter *gutter;
-  GSettings *settings;
 
   ENTRY;
 
@@ -1139,24 +950,12 @@ gb_editor_tab_constructed (GObject *object)
 
   priv = tab->priv;
 
-  settings = g_settings_new ("org.gnome.builder.editor");
-
   if (!priv->document)
     priv->document = gb_editor_document_new ();
 
   gtk_text_view_set_buffer (GTK_TEXT_VIEW (priv->source_view),
                             GTK_TEXT_BUFFER (priv->document));
 
-  g_settings_bind (settings, "font-name",
-                   priv->source_view, "font-name",
-                   G_SETTINGS_BIND_GET);
-  g_settings_bind (settings, "style-scheme-name",
-                   priv->document, "style-scheme-name",
-                   G_SETTINGS_BIND_GET);
-
-  if (!priv->settings)
-    gb_editor_tab_set_settings (tab, NULL);
-
   if (!priv->file)
     priv->file = gtk_source_file_new ();
 
@@ -1183,12 +982,6 @@ gb_editor_tab_constructed (GObject *object)
                 "search-highlighter", priv->search_highlighter,
                 NULL);
 
-  priv->words_provider =
-    g_object_new (GTK_SOURCE_TYPE_COMPLETION_WORDS,
-                  "minimum-word-size", 5,
-                  NULL);
-
-
   g_signal_connect_swapped (priv->document,
                             "notify::language",
                             G_CALLBACK (gb_editor_tab_language_changed),
@@ -1234,19 +1027,14 @@ gb_editor_tab_constructed (GObject *object)
                            tab,
                            G_CONNECT_SWAPPED);
 
-  gtk_source_completion_words_register (
-      GTK_SOURCE_COMPLETION_WORDS (priv->words_provider),
-      GTK_TEXT_BUFFER (priv->document));
-
-  comp = gtk_source_view_get_completion (GTK_SOURCE_VIEW (priv->source_view));
-  gtk_source_completion_add_provider (comp, priv->words_provider, NULL);
 
   /*
    * WORKAROUND:
-
+   *
    * Once GtkSourceView exports this as an internal child, we can do this from
    * the gb-editor-tab.ui file.
    */
+  comp = gtk_source_view_get_completion (GTK_SOURCE_VIEW (priv->source_view));
   g_object_set (comp,
                 "show-headers", FALSE,
                 "select-on-show", TRUE,
@@ -1315,15 +1103,13 @@ gb_editor_tab_constructed (GObject *object)
                     G_CALLBACK (on_vim_notify_mode),
                     tab);
 
-  g_settings_bind (settings, "vim-mode", vim, "enabled",
-                   G_SETTINGS_BIND_DEFAULT);
+#if 0
   g_settings_bind (settings, "word-completion", tab, "enable-word-completion",
                    G_SETTINGS_BIND_DEFAULT);
+#endif
 
   gb_editor_tab_cursor_moved (tab, priv->document);
 
-  g_object_unref (settings);
-
   EXIT;
 }
 
@@ -1434,8 +1220,6 @@ gb_editor_tab_dispose (GObject *object)
 
   gb_editor_code_assistant_destroy (tab);
 
-  gb_editor_tab_disconnect_settings (tab);
-
   g_clear_object (&tab->priv->change_monitor);
   g_clear_object (&tab->priv->search_entry_tag);
   g_clear_object (&tab->priv->file);
@@ -1443,7 +1227,6 @@ gb_editor_tab_dispose (GObject *object)
   g_clear_object (&tab->priv->search_settings);
   g_clear_object (&tab->priv->search_context);
   g_clear_object (&tab->priv->settings);
-  g_clear_object (&tab->priv->words_provider);
   g_clear_object (&tab->priv->document);
 
   G_OBJECT_CLASS (gb_editor_tab_parent_class)->dispose (object);
@@ -1475,19 +1258,10 @@ gb_editor_tab_get_property (GObject    *object,
       g_value_set_object (value, gb_editor_tab_get_document (tab));
       break;
 
-    case PROP_ENABLE_WORD_COMPLETION:
-      g_value_set_boolean (value,
-                           gb_editor_tab_get_enable_word_completion (tab));
-      break;
-
     case PROP_FILE:
       g_value_set_object (value, gb_editor_tab_get_file (tab));
       break;
 
-    case PROP_SETTINGS:
-      g_value_set_object (value, gb_editor_tab_get_settings (tab));
-      break;
-
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -1499,19 +1273,12 @@ gb_editor_tab_set_property (GObject      *object,
                             const GValue *value,
                             GParamSpec   *pspec)
 {
+#if 0
   GbEditorTab *tab = GB_EDITOR_TAB (object);
+#endif
 
   switch (prop_id)
     {
-    case PROP_ENABLE_WORD_COMPLETION:
-      gb_editor_tab_set_enable_word_completion (tab,
-                                                g_value_get_boolean (value));
-      break;
-
-    case PROP_SETTINGS:
-      gb_editor_tab_set_settings (tab, g_value_get_object (value));
-      break;
-
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -1546,16 +1313,6 @@ gb_editor_tab_class_init (GbEditorTabClass *klass)
   g_object_class_install_property (object_class, PROP_DOCUMENT,
                                    gParamSpecs[PROP_DOCUMENT]);
 
-  gParamSpecs [PROP_ENABLE_WORD_COMPLETION] =
-    g_param_spec_boolean ("enable-word-completion",
-                          _("Enable Word Completion"),
-                          _("Enable Word Completion"),
-                          TRUE,
-                          (G_PARAM_READWRITE |
-                           G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (object_class, PROP_ENABLE_WORD_COMPLETION,
-                                   gParamSpecs [PROP_ENABLE_WORD_COMPLETION]);
-
   gParamSpecs [PROP_FILE] =
     g_param_spec_object ("file",
                          _("File"),
@@ -1566,15 +1323,6 @@ gb_editor_tab_class_init (GbEditorTabClass *klass)
   g_object_class_install_property (object_class, PROP_FILE,
                                    gParamSpecs [PROP_FILE]);
 
-  gParamSpecs [PROP_SETTINGS] =
-    g_param_spec_object ("settings",
-                         _("Settings"),
-                         _("The editor settings."),
-                         GB_TYPE_EDITOR_SETTINGS,
-                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (object_class, PROP_SETTINGS,
-                                   gParamSpecs[PROP_SETTINGS]);
-
   gtk_widget_class_set_template_from_resource (widget_class,
                                                GB_EDITOR_TAB_UI_RESOURCE);
 
@@ -1603,7 +1351,5 @@ gb_editor_tab_init (GbEditorTab *tab)
 {
   tab->priv = gb_editor_tab_get_instance_private (tab);
 
-  tab->priv->enable_word_completion = TRUE;
-
   gtk_widget_init_template (GTK_WIDGET (tab));
 }
diff --git a/src/editor/gb-source-view.c b/src/editor/gb-source-view.c
index 1bddc8e..2f4908f 100644
--- a/src/editor/gb-source-view.c
+++ b/src/editor/gb-source-view.c
@@ -20,6 +20,7 @@
 
 #include <glib/gi18n.h>
 #include <gtksourceview/gtksource.h>
+#include <gtksourceview/completion-providers/words/gtksourcecompletionwords.h>
 
 #include "gb-animation.h"
 #include "gb-source-auto-indenter.h"
@@ -48,8 +49,12 @@ struct _GbSourceViewPrivate
   GtkTextBuffer               *buffer;
   GbSourceAutoIndenter        *auto_indenter;
   GtkSourceCompletionProvider *snippets_provider;
+  GtkSourceCompletionProvider *words_provider;
   GbSourceVim                 *vim;
 
+  GSettings                   *language_settings;
+  GSettings                   *editor_settings;
+
   guint                        buffer_insert_text_handler;
   guint                        buffer_insert_text_after_handler;
   guint                        buffer_delete_range_handler;
@@ -57,8 +62,9 @@ struct _GbSourceViewPrivate
   guint                        buffer_mark_set_handler;
   guint                        buffer_notify_language_handler;
 
-  guint                        show_shadow : 1;
   guint                        auto_indent : 1;
+  guint                        enable_word_completion : 1;
+  guint                        show_shadow : 1;
 };
 
 typedef void (*GbSourceViewMatchFunc) (GbSourceView      *view,
@@ -71,9 +77,11 @@ G_DEFINE_TYPE_WITH_PRIVATE (GbSourceView, gb_source_view, GTK_SOURCE_TYPE_VIEW)
 enum {
   PROP_0,
   PROP_AUTO_INDENT,
+  PROP_ENABLE_WORD_COMPLETION,
   PROP_FONT_NAME,
   PROP_SEARCH_HIGHLIGHTER,
   PROP_SHOW_SHADOW,
+  PROP_SMART_HOME_END_SIMPLE,
   LAST_PROP
 };
 
@@ -96,6 +104,177 @@ gb_source_view_get_vim (GbSourceView *view)
   return view->priv->vim;
 }
 
+gboolean
+gb_source_view_get_enable_word_completion (GbSourceView *view)
+{
+  g_return_val_if_fail (GB_IS_SOURCE_VIEW (view), FALSE);
+
+  return view->priv->enable_word_completion;
+}
+
+void
+gb_source_view_set_enable_word_completion (GbSourceView *view,
+                                           gboolean      enable_word_completion)
+{
+  GbSourceViewPrivate *priv;
+
+  g_return_if_fail (GB_IS_SOURCE_VIEW (view));
+
+  priv = view->priv;
+
+  if (enable_word_completion != priv->enable_word_completion)
+    {
+      GtkSourceCompletion *completion;
+
+      completion = gtk_source_view_get_completion (GTK_SOURCE_VIEW (view));
+
+      if (!enable_word_completion)
+        gtk_source_completion_remove_provider (
+            completion,
+            GTK_SOURCE_COMPLETION_PROVIDER (priv->words_provider),
+            NULL);
+      else
+        gtk_source_completion_add_provider (
+            completion,
+            GTK_SOURCE_COMPLETION_PROVIDER (priv->words_provider),
+            NULL);
+
+      priv->enable_word_completion = enable_word_completion;
+      g_object_notify_by_pspec (G_OBJECT (view),
+                                gParamSpecs [PROP_ENABLE_WORD_COMPLETION]);
+    }
+}
+
+static void
+gb_source_view_disconnect_settings (GbSourceView *view)
+{
+  GtkTextBuffer *buffer;
+
+  g_return_if_fail (GB_IS_SOURCE_VIEW (view));
+
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+  g_settings_unbind (buffer, "highlight-matching-brackets");
+  g_settings_unbind (buffer, "style-scheme-name");
+
+  g_settings_unbind (view, "auto-indent");
+  g_settings_unbind (view, "highlight-current-line");
+  g_settings_unbind (view, "insert-spaces-instead-of-tabs");
+  g_settings_unbind (view, "right-margin-position");
+  g_settings_unbind (view, "show-line-marks");
+  g_settings_unbind (view, "show-line-numbers");
+  g_settings_unbind (view, "show-right-margin");
+  g_settings_unbind (view, "tab-width");
+  g_settings_unbind (view, "font-name");
+  g_settings_unbind (view->priv->vim, "enabled");
+
+  g_clear_object (&view->priv->language_settings);
+  g_clear_object (&view->priv->editor_settings);
+}
+
+static void
+gb_source_view_connect_settings (GbSourceView *view)
+{
+  GtkTextBuffer *buffer;
+  GtkSourceLanguage *language;
+
+  g_return_if_fail (GB_IS_SOURCE_VIEW (view));
+
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+  language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (buffer));
+
+  if (language)
+    {
+      GSettings *settings;
+      gchar *path;
+
+      path = g_strdup_printf ("/org/gnome/builder/editor/language/%s/",
+                              gtk_source_language_get_id (language));
+      settings = g_settings_new_with_path ("org.gnome.builder.editor.language",
+                                           path);
+      g_free (path);
+
+      g_settings_bind (settings, "auto-indent", view, "auto-indent",
+                       G_SETTINGS_BIND_GET);
+      g_settings_bind (settings, "auto-indent", view, "auto-indent",
+                       G_SETTINGS_BIND_GET);
+      g_settings_bind (settings, "highlight-current-line",
+                       view, "highlight-current-line",
+                       G_SETTINGS_BIND_GET);
+      g_settings_bind (settings, "highlight-matching-brackets",
+                       buffer, "highlight-matching-brackets",
+                       G_SETTINGS_BIND_GET);
+      g_settings_bind (settings, "insert-spaces-instead-of-tabs",
+                       view, "insert-spaces-instead-of-tabs",
+                       G_SETTINGS_BIND_GET);
+      g_settings_bind (settings, "right-margin-position",
+                       view, "right-margin-position",
+                       G_SETTINGS_BIND_GET);
+      g_settings_bind (settings, "show-line-marks",
+                       view, "show-line-marks",
+                       G_SETTINGS_BIND_GET);
+      g_settings_bind (settings, "show-line-numbers",
+                       view,"show-line-numbers",
+                       G_SETTINGS_BIND_GET);
+      g_settings_bind (settings, "show-right-margin",
+                       view, "show-right-margin",
+                       G_SETTINGS_BIND_GET);
+      g_settings_bind (settings, "tab-width", view, "tab-width",
+                       G_SETTINGS_BIND_GET);
+      g_settings_bind (settings, "smart-home-end",
+                       view, "smart-home-end-simple",
+                       G_SETTINGS_BIND_GET);
+
+      view->priv->language_settings = settings;
+    }
+
+  view->priv->editor_settings = g_settings_new ("org.gnome.builder.editor");
+
+  g_settings_bind (view->priv->editor_settings, "font-name",
+                   view, "font-name", G_SETTINGS_BIND_GET);
+  g_settings_bind (view->priv->editor_settings, "style-scheme-name",
+                   buffer, "style-scheme-name", G_SETTINGS_BIND_GET);
+  g_settings_bind (view->priv->editor_settings, "vim-mode",
+                   view->priv->vim, "enabled", G_SETTINGS_BIND_GET);
+  g_settings_bind (view->priv->editor_settings, "word-completion",
+                   view, "enable-word-completion", G_SETTINGS_BIND_GET);
+}
+
+static void
+gb_source_view_reload_settings (GbSourceView *view)
+{
+  GtkSourceLanguage *language;
+  GtkTextBuffer *buffer;
+  GSettings *settings = NULL;
+  gchar *path;
+
+  g_return_if_fail (GB_IS_SOURCE_VIEW (view));
+
+  if (view->priv->language_settings)
+    {
+      gb_source_view_disconnect_settings (view);
+      g_clear_object (&view->priv->language_settings);
+    }
+
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+  language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (buffer));
+
+  if (language)
+    {
+      path = g_strdup_printf ("/org/gnome/builder/editor/language/%s/",
+                              gtk_source_language_get_id (language));
+      settings = g_settings_new_with_path ("org.gnome.builder.editor.language",
+                                           path);
+      g_free (path);
+    }
+
+  if (settings)
+    {
+      view->priv->language_settings = settings;
+      gb_source_view_connect_settings (view);
+    }
+}
+
 void
 gb_source_view_begin_search (GbSourceView     *view,
                              GtkDirectionType  direction,
@@ -848,14 +1027,17 @@ on_mark_set (GtkTextBuffer *buffer,
 }
 
 static void
-gb_source_view_reload_snippets (GbSourceView      *source_view,
-                                GtkSourceLanguage *language)
+gb_source_view_reload_snippets (GbSourceView *source_view)
 {
   GbSourceSnippetsManager *mgr;
   GbSourceSnippets *snippets = NULL;
+  GtkSourceLanguage *language;
+  GtkTextBuffer *buffer;
 
   g_return_if_fail (GB_IS_SOURCE_VIEW (source_view));
-  g_return_if_fail (!language || GTK_SOURCE_IS_LANGUAGE (language));
+
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (source_view));
+  language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (buffer));
 
   if (language)
     {
@@ -869,19 +1051,16 @@ gb_source_view_reload_snippets (GbSourceView      *source_view,
 }
 
 static void
-on_language_set (GtkSourceBuffer *buffer,
-                 GParamSpec      *pspec,
-                 GbSourceView    *source_view)
+gb_source_view_reload_auto_indenter (GbSourceView *view)
 {
-  GtkSourceLanguage *language;
   GbSourceAutoIndenter *auto_indenter = NULL;
+  GtkTextBuffer *buffer;
+  GtkSourceLanguage *language;
 
-  g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
-  g_return_if_fail (GB_IS_SOURCE_VIEW (source_view));
-
-  g_clear_object (&source_view->priv->auto_indenter);
+  g_return_if_fail (GB_IS_SOURCE_VIEW (view));
 
-  language = gtk_source_buffer_get_language (buffer);
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+  language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (buffer));
 
   if (language)
     {
@@ -897,9 +1076,22 @@ on_language_set (GtkSourceBuffer *buffer,
         auto_indenter = gb_source_auto_indenter_xml_new ();
     }
 
-  source_view->priv->auto_indenter = auto_indenter;
+  g_clear_object (&view->priv->auto_indenter);
+
+  view->priv->auto_indenter = auto_indenter;
+}
+
+static void
+on_language_set (GtkSourceBuffer *buffer,
+                 GParamSpec      *pspec,
+                 GbSourceView    *source_view)
+{
+  g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
+  g_return_if_fail (GB_IS_SOURCE_VIEW (source_view));
 
-  gb_source_view_reload_snippets (source_view, language);
+  gb_source_view_reload_auto_indenter (source_view);
+  gb_source_view_reload_settings (source_view);
+  gb_source_view_reload_snippets (source_view);
 }
 
 static void
@@ -936,6 +1128,9 @@ gb_source_view_notify_buffer (GObject    *object,
       priv->buffer_delete_range_after_handler = 0;
       priv->buffer_mark_set_handler = 0;
       priv->buffer_notify_language_handler = 0;
+      gtk_source_completion_words_unregister (
+          GTK_SOURCE_COMPLETION_WORDS (priv->words_provider),
+          GTK_TEXT_BUFFER (priv->buffer));
       g_object_remove_weak_pointer (G_OBJECT (priv->buffer),
                                     (gpointer *) &priv->buffer);
       priv->buffer = NULL;
@@ -984,6 +1179,10 @@ gb_source_view_notify_buffer (GObject    *object,
                                  G_CALLBACK (on_language_set),
                                  object,
                                  0);
+
+      gtk_source_completion_words_register (
+          GTK_SOURCE_COMPLETION_WORDS (priv->words_provider),
+          GTK_TEXT_BUFFER (buffer));
     }
 }
 
@@ -1507,10 +1706,12 @@ gb_source_view_finalize (GObject *object)
       priv->buffer = NULL;
     }
 
+  gb_source_view_disconnect_settings (GB_SOURCE_VIEW (object));
   g_clear_pointer (&priv->snippets, g_queue_free);
   g_clear_object (&priv->search_highlighter);
   g_clear_object (&priv->auto_indenter);
   g_clear_object (&priv->snippets_provider);
+  g_clear_object (&priv->words_provider);
   g_clear_object (&priv->vim);
 
   G_OBJECT_CLASS (gb_source_view_parent_class)->finalize (object);
@@ -1529,6 +1730,10 @@ gb_source_view_get_property (GObject    *object,
     case PROP_AUTO_INDENT:
       g_value_set_boolean (value, view->priv->auto_indent);
       break;
+      
+    case PROP_ENABLE_WORD_COMPLETION:
+      g_value_set_boolean (value,
+                           gb_source_view_get_enable_word_completion (view));
 
     case PROP_SEARCH_HIGHLIGHTER:
       g_value_set_object (value, gb_source_view_get_search_highlighter (view));
@@ -1557,6 +1762,11 @@ gb_source_view_set_property (GObject      *object,
       view->priv->auto_indent = g_value_get_boolean (value);
       break;
 
+    case PROP_ENABLE_WORD_COMPLETION:
+      gb_source_view_set_enable_word_completion (view,
+                                                 g_value_get_boolean (value));
+      break;
+
     case PROP_FONT_NAME:
       gb_source_view_set_font_name (view, g_value_get_string (value));
       break;
@@ -1569,6 +1779,15 @@ gb_source_view_set_property (GObject      *object,
       gb_source_view_set_show_shadow (view, g_value_get_boolean (value));
       break;
 
+    case PROP_SMART_HOME_END_SIMPLE:
+      if (g_value_get_boolean (value))
+        gtk_source_view_set_smart_home_end (GTK_SOURCE_VIEW (view),
+                                            GTK_SOURCE_SMART_HOME_END_BEFORE);
+      else
+        gtk_source_view_set_smart_home_end (GTK_SOURCE_VIEW (view),
+                                            GTK_SOURCE_SMART_HOME_END_DISABLED);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -1593,6 +1812,15 @@ gb_source_view_class_init (GbSourceViewClass *klass)
 
   klass->draw_layer = gb_source_view_real_draw_layer;
 
+  gParamSpecs [PROP_ENABLE_WORD_COMPLETION] =
+    g_param_spec_boolean ("enable-word-completion",
+                          _("Enable Word Completion"),
+                          _("Enable Word Completion"),
+                          TRUE,
+                          (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_ENABLE_WORD_COMPLETION,
+                                   gParamSpecs [PROP_ENABLE_WORD_COMPLETION]);
+
   gParamSpecs [PROP_FONT_NAME] =
     g_param_spec_string ("font-name",
                          _("Font Name"),
@@ -1620,6 +1848,15 @@ gb_source_view_class_init (GbSourceViewClass *klass)
   g_object_class_install_property (object_class, PROP_SEARCH_HIGHLIGHTER,
                                    gParamSpecs[PROP_SEARCH_HIGHLIGHTER]);
 
+  gParamSpecs [PROP_SMART_HOME_END_SIMPLE] =
+    g_param_spec_boolean ("smart-home-end-simple",
+                          _("Smart Home End"),
+                          _("Enable smart home end in gtksourceview."),
+                          TRUE,
+                          (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_SMART_HOME_END_SIMPLE,
+                                   gParamSpecs [PROP_SMART_HOME_END_SIMPLE]);
+
   g_object_class_override_property (object_class,
                                     PROP_AUTO_INDENT,
                                     "auto-indent");
@@ -1694,6 +1931,11 @@ gb_source_view_init (GbSourceView *view)
                   "source-view", view,
                   NULL);
 
+  view->priv->words_provider =
+    g_object_new (GTK_SOURCE_TYPE_COMPLETION_WORDS,
+                  "minimum-word-size", 4,
+                  NULL);
+
   view->priv->vim = g_object_new (GB_TYPE_SOURCE_VIM,
                                   "enabled", FALSE,
                                   "text-view", view,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]