[gnome-builder] libide: add search provider for git filenames
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] libide: add search provider for git filenames
- Date: Mon, 23 Mar 2015 23:36:34 +0000 (UTC)
commit dc6e0cedcbb1541b73365278fe65939301f272fe
Author: Christian Hergert <christian hergert me>
Date: Mon Feb 16 21:24:53 2015 -0800
libide: add search provider for git filenames
libide/Makefile.am | 4 +
libide/git/ide-git-search-index.c | 469 ++++++++++++++++++++++++++++++++++
libide/git/ide-git-search-index.h | 39 +++
libide/git/ide-git-search-provider.c | 215 ++++++++++++++++
libide/git/ide-git-search-provider.h | 35 +++
libide/ide.c | 6 +
6 files changed, 768 insertions(+), 0 deletions(-)
---
diff --git a/libide/Makefile.am b/libide/Makefile.am
index d89293e..ad64a95 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -30,6 +30,8 @@ libide_1_0_la_public_sources = \
libide/directory/ide-directory-vcs.h \
libide/editorconfig/ide-editorconfig-file-settings.c \
libide/editorconfig/ide-editorconfig-file-settings.h \
+ libide/git/ide-git-search-provider.c \
+ libide/git/ide-git-search-provider.h \
libide/git/ide-git-vcs.c \
libide/git/ide-git-vcs.h \
libide/gjs/ide-gjs-script.cpp \
@@ -156,6 +158,8 @@ libide_1_0_la_SOURCES = \
libide/gca/ide-gca-service.h \
libide/gca/ide-gca-service.h \
libide/gconstructor.h \
+ libide/git/ide-git-search-index.c \
+ libide/git/ide-git-search-index.h \
libide/ide-async-helper.c \
libide/ide-async-helper.h \
libide/ide-search-reducer.c \
diff --git a/libide/git/ide-git-search-index.c b/libide/git/ide-git-search-index.c
new file mode 100644
index 0000000..884793b
--- /dev/null
+++ b/libide/git/ide-git-search-index.c
@@ -0,0 +1,469 @@
+/* ide-git-search-index.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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
+ * Lesser 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/>.
+ */
+
+#include <ctype.h>
+#include <fuzzy.h>
+#include <glib/gi18n.h>
+#include <libgit2-glib/ggit.h>
+
+#include "ide-context.h"
+#include "ide-git-search-index.h"
+#include "ide-project.h"
+#include "ide-search-context.h"
+#include "ide-search-provider.h"
+#include "ide-search-reducer.h"
+#include "ide-search-result.h"
+
+struct _IdeGitSearchIndex
+{
+ IdeObject parent_instance;
+
+ GFile *location;
+ gchar *shorthand;
+ Fuzzy *fuzzy;
+};
+
+static GQuark gPathQuark;
+
+static void async_initable_iface_init (GAsyncInitableIface *iface);
+
+G_DEFINE_TYPE_EXTENDED (IdeGitSearchIndex,
+ ide_git_search_index,
+ IDE_TYPE_OBJECT,
+ 0,
+ G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
+ async_initable_iface_init))
+
+enum {
+ PROP_0,
+ PROP_LOCATION,
+ LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+static void
+activate_cb (IdeSearchResult *result,
+ gpointer user_data)
+{
+ g_assert (IDE_IS_SEARCH_RESULT (result));
+
+ /* TODO: Hook up document manager in LibIDE */
+}
+
+/**
+ * ide_git_search_index_get_location:
+ *
+ * Returns the location of the .git directory.
+ *
+ * Returns: (transfer none): A #GFile.
+ */
+GFile *
+ide_git_search_index_get_location (IdeGitSearchIndex *self)
+{
+ g_return_val_if_fail (IDE_IS_GIT_SEARCH_INDEX (self), NULL);
+
+ return self->location;
+}
+
+static void
+ide_git_search_index_set_location (IdeGitSearchIndex *self,
+ GFile *location)
+{
+ g_return_if_fail (IDE_IS_GIT_SEARCH_INDEX (self));
+ g_return_if_fail (G_IS_FILE (location));
+
+ if (g_set_object (&self->location, location))
+ g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_LOCATION]);
+}
+
+static gchar *
+str_highlight (const gchar *str,
+ const gchar *match)
+{
+ GString *ret;
+ gunichar str_ch;
+ gunichar match_ch;
+
+ g_return_val_if_fail (str, NULL);
+ g_return_val_if_fail (match, NULL);
+
+ ret = g_string_new (NULL);
+
+ for (; *str; str = g_utf8_next_char (str))
+ {
+ str_ch = g_utf8_get_char (str);
+ match_ch = g_utf8_get_char (match);
+
+ if (str_ch == match_ch)
+ {
+ g_string_append (ret, "<u>");
+ g_string_append_unichar (ret, str_ch);
+ g_string_append (ret, "</u>");
+
+ match = g_utf8_next_char (match);
+ }
+ else
+ {
+ g_string_append_unichar (ret, str_ch);
+ }
+ }
+
+ return g_string_free (ret, FALSE);
+}
+
+static gchar *
+filter_search_terms (const gchar *search_terms)
+{
+ GString *str;
+
+ str = g_string_new (NULL);
+
+ for (; *search_terms; search_terms = g_utf8_next_char (search_terms))
+ {
+ gunichar ch = g_utf8_get_char (search_terms);
+
+ if ((isascii (ch) != 0) && !g_unichar_isspace (ch))
+ g_string_append_unichar (str, ch);
+ }
+
+ return g_string_free (str, FALSE);
+}
+
+static gchar **
+split_path (const gchar *path,
+ gchar **shortname)
+{
+ gchar **parts;
+ gsize len;
+
+ g_return_val_if_fail (path, NULL);
+ g_return_val_if_fail (shortname, NULL);
+
+ *shortname = NULL;
+
+ parts = g_strsplit (path, "/", 0);
+ len = g_strv_length (parts);
+
+ if (len)
+ {
+ *shortname = parts [len-1];
+ parts [len-1] = 0;
+ }
+
+ return parts;
+}
+
+void
+ide_git_search_index_populate (IdeGitSearchIndex *self,
+ IdeSearchProvider *provider,
+ IdeSearchContext *search_context,
+ gsize max_results,
+ const gchar *search_terms)
+{
+ g_auto(IdeSearchReducer) reducer = { 0 };
+ g_autoptr(gchar) delimited = NULL;
+ IdeContext *context;
+ IdeProject *project;
+ const gchar *project_name;
+ GArray *matches = NULL;
+ GString *str = NULL;
+ gsize truncate_len = 0;
+ gsize i;
+
+ g_return_if_fail (IDE_IS_GIT_SEARCH_INDEX (self));
+ g_return_if_fail (IDE_IS_SEARCH_PROVIDER (provider));
+ g_return_if_fail (IDE_IS_SEARCH_CONTEXT (search_context));
+ g_return_if_fail (search_terms);
+
+ context = ide_object_get_context (IDE_OBJECT (self));
+
+ /* Filter space and non-ascii from the search terms */
+ delimited = filter_search_terms (search_terms);
+
+ /* Execute the search against the fuzzy index */
+ matches = fuzzy_match (self->fuzzy, delimited, max_results);
+
+ /* Generate the prefix for the secondary text */
+ project = ide_context_get_project (context);
+ project_name = ide_project_get_name (project);
+ str = g_string_new (project_name);
+ if (self->shorthand)
+ g_string_append_printf (str, "[%s]", self->shorthand);
+ truncate_len = str->len;
+
+ /* initialize our reducer, which helps us prevent creating unnecessary
+ * objects that will simply be discarded */
+ ide_search_reducer_init (&reducer, search_context, provider);
+
+ for (i = 0; i < matches->len; i++)
+ {
+ FuzzyMatch *match = &g_array_index (matches, FuzzyMatch, i);
+
+ if (ide_search_reducer_accepts (&reducer, match->score))
+ {
+ g_autoptr(gchar) shortname = NULL;
+ g_autoptr(gchar) markup = NULL;
+ g_autoptr(IdeSearchResult) result = NULL;
+ gchar **parts;
+ gsize j;
+
+ /* truncate the secondary text to the shared info */
+ g_string_truncate (str, truncate_len);
+
+ /* Generate pretty path to the directory */
+ parts = split_path (match->value, &shortname);
+ for (j = 0; parts [j]; j++)
+ g_string_append_printf (str, " / %s", parts [j]);
+ g_strfreev (parts);
+
+ /* highlight the title string with underlines */
+ markup = str_highlight (shortname, search_terms);
+
+ /* create our search result and connect to signals */
+ result = ide_search_result_new (context,
+ markup,
+ str->str,
+ match->score);
+ g_object_set_qdata_full (G_OBJECT (result), gPathQuark,
+ g_strdup (match->value), g_free);
+#if 0
+ /* I think we might want to leave this signal on the provider */
+ g_signal_connect (result, "activate", G_CALLBACK (activate_cb), NULL);
+#endif
+
+ /* push the result through the search reducer */
+ ide_search_reducer_push (&reducer, result);
+ }
+ }
+
+cleanup:
+ g_clear_pointer (&matches, g_array_unref);
+ g_string_free (str, TRUE);
+}
+
+static void
+ide_git_search_index_finalize (GObject *object)
+{
+ IdeGitSearchIndex *self = (IdeGitSearchIndex *)object;
+
+ g_clear_object (&self->location);
+ g_clear_pointer (&self->shorthand, g_free);
+ g_clear_pointer (&self->fuzzy, fuzzy_unref);
+
+ G_OBJECT_CLASS (ide_git_search_index_parent_class)->finalize (object);
+}
+
+static void
+ide_git_search_index_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeGitSearchIndex *self = IDE_GIT_SEARCH_INDEX (object);
+
+ switch (prop_id)
+ {
+ case PROP_LOCATION:
+ g_value_set_object (value, ide_git_search_index_get_location (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_git_search_index_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdeGitSearchIndex *self = IDE_GIT_SEARCH_INDEX (object);
+
+ switch (prop_id)
+ {
+ case PROP_LOCATION:
+ ide_git_search_index_set_location (self, g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_git_search_index_class_init (IdeGitSearchIndexClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = ide_git_search_index_finalize;
+ object_class->get_property = ide_git_search_index_get_property;
+ object_class->set_property = ide_git_search_index_set_property;
+
+ gPathQuark = g_quark_from_static_string ("IDE_GIT_SEARCH_INDEX_PATH");
+
+ gParamSpecs [PROP_LOCATION] =
+ g_param_spec_object ("location",
+ _("Location"),
+ _("The location of the .git index."),
+ G_TYPE_FILE,
+ (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_LOCATION,
+ gParamSpecs [PROP_LOCATION]);
+}
+
+static void
+ide_git_search_index_init (IdeGitSearchIndex *self)
+{
+}
+
+static void
+ide_git_search_index_init_worker (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ IdeGitSearchIndex *self = source_object;
+ GgitRepository *repository = NULL;
+ GgitIndexEntries *entries = NULL;
+ GgitIndex *index = NULL;
+ GgitRef *ref;
+ GError *error = NULL;
+ GFile *repository_dir = task_data;
+ guint count;
+ guint i;
+
+ g_assert (G_IS_TASK (task));
+ g_assert (IDE_IS_GIT_SEARCH_INDEX (self));
+
+ if (!self->location)
+ {
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_INVALID_FILENAME,
+ _("Location must be set to .git directory."));
+ goto cleanup;
+ }
+
+ repository = ggit_repository_open (self->location, &error);
+
+ if (!repository)
+ {
+ g_task_return_error (task, error);
+ goto cleanup;
+ }
+
+ ref = ggit_repository_get_head (repository, NULL);
+
+ if (ref)
+ {
+ self->shorthand = g_strdup (ggit_ref_get_shorthand (ref));
+ g_clear_object (&ref);
+ }
+
+ index = ggit_repository_get_index (repository, &error);
+
+ if (!index)
+ {
+ g_task_return_error (task, error);
+ goto cleanup;
+ }
+
+ entries = ggit_index_get_entries (index);
+
+ self->fuzzy = fuzzy_new_with_free_func (FALSE, g_free);
+ count = ggit_index_entries_size (entries);
+
+ fuzzy_begin_bulk_insert (self->fuzzy);
+
+ for (i = 0; i < count; i++)
+ {
+ GgitIndexEntry *entry;
+ const gchar *path;
+
+ entry = ggit_index_entries_get_by_index (entries, i);
+ path = ggit_index_entry_get_path (entry);
+
+ /* FIXME:
+ *
+ * fuzzy does not yet support UTF-8, which is the native format
+ * for the filesystem. It wont be as fast, but we can just take
+ * the cost of gunichar most likely.
+ */
+ if (g_str_is_ascii (path))
+ {
+ const gchar *shortname = strrchr (path, '/');
+
+ if (shortname)
+ fuzzy_insert (self->fuzzy, shortname, g_strdup (path));
+ else
+ fuzzy_insert (self->fuzzy, path, g_strdup (path));
+ }
+
+ ggit_index_entry_unref (entry);
+ }
+
+ fuzzy_end_bulk_insert (self->fuzzy);
+
+ g_task_return_boolean (task, TRUE);
+
+cleanup:
+ g_clear_pointer (&entries, ggit_index_entries_unref);
+ g_clear_object (&index);
+ g_clear_object (&repository);
+}
+
+static void
+ide_git_search_index_init_async (GAsyncInitable *initable,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ IdeGitSearchIndex *self = (IdeGitSearchIndex *)initable;
+ g_autoptr(GTask) task = NULL;
+
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (IDE_IS_GIT_SEARCH_INDEX (self));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_run_in_thread (task, ide_git_search_index_init_worker);
+}
+
+static gboolean
+ide_git_search_index_init_finish (GAsyncInitable *initable,
+ GAsyncResult *result,
+ GError **error)
+{
+ GTask *task = (GTask *)result;
+
+ g_return_val_if_fail (IDE_IS_GIT_SEARCH_INDEX (initable), FALSE);
+ g_return_val_if_fail (G_IS_TASK (task), FALSE);
+
+ return g_task_propagate_boolean (task, error);
+}
+
+static void
+async_initable_iface_init (GAsyncInitableIface *iface)
+{
+ iface->init_async = ide_git_search_index_init_async;
+ iface->init_finish = ide_git_search_index_init_finish;
+}
diff --git a/libide/git/ide-git-search-index.h b/libide/git/ide-git-search-index.h
new file mode 100644
index 0000000..28820f1
--- /dev/null
+++ b/libide/git/ide-git-search-index.h
@@ -0,0 +1,39 @@
+/* ide-git-search-index.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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
+ * Lesser 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 IDE_GIT_SEARCH_INDEX_H
+#define IDE_GIT_SEARCH_INDEX_H
+
+#include "ide-object.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_GIT_SEARCH_INDEX (ide_git_search_index_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeGitSearchIndex, ide_git_search_index,
+ IDE, GIT_SEARCH_INDEX, IdeObject)
+
+void ide_git_search_index_populate (IdeGitSearchIndex *self,
+ IdeSearchProvider *provider,
+ IdeSearchContext *context,
+ gsize max_results,
+ const gchar *search_terms);
+
+G_END_DECLS
+
+#endif /* IDE_GIT_SEARCH_INDEX_H */
diff --git a/libide/git/ide-git-search-provider.c b/libide/git/ide-git-search-provider.c
new file mode 100644
index 0000000..8778b31
--- /dev/null
+++ b/libide/git/ide-git-search-provider.c
@@ -0,0 +1,215 @@
+/* ide-git-search-provider.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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
+ * Lesser 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/>.
+ */
+
+#include <glib/gi18n.h>
+
+#include "ide-context.h"
+#include "ide-git-search-index.h"
+#include "ide-git-search-provider.h"
+#include "ide-git-vcs.h"
+#include "ide-search-context.h"
+
+struct _IdeGitSearchProvider
+{
+ IdeSearchProvider parent_instance;
+
+ IdeGitSearchIndex *index;
+};
+
+typedef struct
+{
+ IdeSearchContext *context;
+ gchar *search_terms;
+ gsize max_results;
+} PopulateState;
+
+G_DEFINE_TYPE (IdeGitSearchProvider, ide_git_search_provider,
+ IDE_TYPE_SEARCH_PROVIDER)
+
+static void
+ide_git_search_provider_get_index_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ g_autoptr(GTask) task = user_data;
+ GAsyncInitable *initable = (GAsyncInitable *)object;
+ IdeGitSearchProvider *self;
+ g_autoptr(GObject) res = NULL;
+ GError *error = NULL;
+
+ g_assert (G_IS_TASK (task));
+ g_assert (G_IS_ASYNC_RESULT (result));
+
+ self = g_task_get_source_object (task);
+
+ res = g_async_initable_new_finish (initable, result, &error);
+
+ if (!res)
+ {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ g_clear_object (&self->index);
+ self->index = g_object_ref (res);
+
+ g_task_return_pointer (task, g_object_ref (self->index), g_object_unref);
+}
+
+static void
+ide_git_search_provider_get_index_async (IdeGitSearchProvider *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(GTask) task = NULL;
+ g_autoptr(GFile) location = NULL;
+ GgitRepository *repository;
+ IdeContext *context;
+ IdeVcs *vcs;
+
+ g_return_if_fail (IDE_IS_GIT_SEARCH_PROVIDER (self));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+
+ if (self->index)
+ {
+ g_task_return_pointer (task, g_object_ref (self->index), g_object_unref);
+ return;
+ }
+
+ context = ide_object_get_context (IDE_OBJECT (self));
+ vcs = ide_context_get_vcs (context);
+
+ if (!IDE_IS_GIT_VCS (vcs))
+ {
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("Git search provider requires the Git VCS"));
+ return;
+ }
+
+ repository = ide_git_vcs_get_repository (IDE_GIT_VCS (vcs));
+ location = ggit_repository_get_location (repository);
+
+ g_async_initable_new_async (IDE_TYPE_GIT_SEARCH_INDEX,
+ G_PRIORITY_DEFAULT,
+ cancellable,
+ ide_git_search_provider_get_index_cb,
+ g_object_ref (task),
+ "context", context,
+ "location", location,
+ NULL);
+}
+
+static IdeGitSearchIndex *
+ide_git_search_provider_get_index_finish (IdeGitSearchProvider *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GTask *task = (GTask *)result;
+
+ g_return_val_if_fail (IDE_IS_GIT_SEARCH_PROVIDER (self), NULL);
+ g_return_val_if_fail (G_IS_TASK (task), NULL);
+
+ return g_task_propagate_pointer (task, error);
+}
+
+static void
+populate_get_index_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeGitSearchProvider *self = (IdeGitSearchProvider *)object;
+ PopulateState *state = user_data;
+ g_autoptr(IdeGitSearchIndex) index = NULL;
+ GError *error = NULL;
+
+ index = ide_git_search_provider_get_index_finish (self, result, &error);
+
+ if (index)
+ {
+ ide_git_search_index_populate (index,
+ IDE_SEARCH_PROVIDER (self),
+ state->context,
+ state->max_results,
+ state->search_terms);
+ }
+
+cleanup:
+ ide_search_context_provider_completed (state->context,
+ IDE_SEARCH_PROVIDER (self));
+
+ g_free (state->search_terms);
+ g_object_unref (state->context);
+ g_slice_free (PopulateState, state);
+}
+
+static void
+ide_git_search_provider_populate (IdeSearchProvider *provider,
+ IdeSearchContext *context,
+ const gchar *search_terms,
+ gsize max_results,
+ GCancellable *cancellable)
+{
+ IdeGitSearchProvider *self = (IdeGitSearchProvider *)provider;
+ PopulateState *state;
+
+ g_return_if_fail (IDE_IS_GIT_SEARCH_PROVIDER (self));
+ g_return_if_fail (IDE_IS_SEARCH_CONTEXT (context));
+ g_return_if_fail (search_terms);
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ state = g_slice_new0 (PopulateState);
+ state->context = g_object_ref (context);
+ state->search_terms = g_strdup (search_terms);
+ state->max_results = max_results;
+
+ ide_git_search_provider_get_index_async (self,
+ cancellable,
+ populate_get_index_cb,
+ state);
+}
+
+static void
+ide_git_search_provider_finalize (GObject *object)
+{
+ IdeGitSearchProvider *self = (IdeGitSearchProvider *)object;
+
+ g_clear_object (&self->index);
+
+ G_OBJECT_CLASS (ide_git_search_provider_parent_class)->finalize (object);
+}
+
+static void
+ide_git_search_provider_class_init (IdeGitSearchProviderClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ IdeSearchProviderClass *provider_class = IDE_SEARCH_PROVIDER_CLASS (klass);
+
+ object_class->finalize = ide_git_search_provider_finalize;
+
+ provider_class->populate = ide_git_search_provider_populate;
+}
+
+static void
+ide_git_search_provider_init (IdeGitSearchProvider *self)
+{
+}
diff --git a/libide/git/ide-git-search-provider.h b/libide/git/ide-git-search-provider.h
new file mode 100644
index 0000000..0b6cc8e
--- /dev/null
+++ b/libide/git/ide-git-search-provider.h
@@ -0,0 +1,35 @@
+/* ide-git-search-provider.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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
+ * Lesser 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 IDE_GIT_SEARCH_PROVIDER_H
+#define IDE_GIT_SEARCH_PROVIDER_H
+
+#include "ide-search-provider.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_GIT_SEARCH_PROVIDER (ide_git_search_provider_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeGitSearchProvider,
+ ide_git_search_provider,
+ IDE, GIT_SEARCH_PROVIDER,
+ IdeSearchProvider)
+
+G_END_DECLS
+
+#endif /* IDE_GIT_SEARCH_PROVIDER_H */
diff --git a/libide/ide.c b/libide/ide.c
index ea360d5..dd12183 100644
--- a/libide/ide.c
+++ b/libide/ide.c
@@ -30,6 +30,7 @@
#include "ide-editorconfig-file-settings.h"
#include "ide-file-settings.h"
#include "ide-gca-service.h"
+#include "ide-git-search-provider.h"
#include "ide-git-vcs.h"
#include "ide-gjs-script.h"
#include "ide-gsettings-file-settings.h"
@@ -101,6 +102,11 @@ ide_init_ctor (void)
IDE_SCRIPT_EXTENSION_POINT".gjs",
-100);
+ g_io_extension_point_implement (IDE_SEARCH_PROVIDER_EXTENSION_POINT,
+ IDE_TYPE_GIT_SEARCH_PROVIDER,
+ IDE_SEARCH_PROVIDER_EXTENSION_POINT".git",
+ -100);
+
g_io_extension_point_implement (IDE_SERVICE_EXTENSION_POINT,
IDE_TYPE_CLANG_SERVICE,
IDE_SERVICE_EXTENSION_POINT".clang",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]