[gnome-builder/wip/libide] libide: various completion work
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/libide] libide: various completion work
- Date: Mon, 16 Mar 2015 07:18:09 +0000 (UTC)
commit ebd3932c04fc660d27ecc1a84ff36d9a9e18697f
Author: Christian Hergert <christian hergert me>
Date: Mon Mar 16 00:17:25 2015 -0700
libide: various completion work
This progresses us towards using snippets when inserting completion
items. Still lots to do, of course.
libide/clang/ide-clang-completion-item.c | 432 +++++++++++++++++++-------
libide/clang/ide-clang-completion-item.h | 18 +-
libide/clang/ide-clang-completion-provider.c | 51 +++-
3 files changed, 384 insertions(+), 117 deletions(-)
---
diff --git a/libide/clang/ide-clang-completion-item.c b/libide/clang/ide-clang-completion-item.c
index 694632c..4543ae1 100644
--- a/libide/clang/ide-clang-completion-item.c
+++ b/libide/clang/ide-clang-completion-item.c
@@ -16,12 +16,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#define G_LOG_DOMAIN "ide-clang-completion"
+
#include <clang-c/Index.h>
#include <glib/gi18n.h>
-#include <gtksourceview/gtksourcecompletionproposal.h>
#include "ide-clang-completion-item.h"
+#include "ide-debug.h"
#include "ide-ref-ptr.h"
+#include "ide-source-snippet.h"
+#include "ide-source-snippet-chunk.h"
struct _IdeClangCompletionItemClass
{
@@ -30,39 +34,238 @@ struct _IdeClangCompletionItemClass
struct _IdeClangCompletionItem
{
- GObject parent_instance;
+ GObject parent_instance;
+
+ guint index;
+ gint typed_text_index;
+ guint initialized : 1;
- IdeRefPtr *results;
- guint index;
+ gchar *markup;
+ GdkPixbuf *icon;
+ IdeRefPtr *results;
+ IdeSourceSnippet *snippet;
};
-enum
-{
+static void completion_proposal_iface_init (GtkSourceCompletionProposalIface *);
+
+G_DEFINE_TYPE_WITH_CODE (IdeClangCompletionItem, ide_clang_completion_item, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GTK_SOURCE_TYPE_COMPLETION_PROPOSAL,
+ completion_proposal_iface_init))
+
+enum {
PROP_0,
PROP_INDEX,
PROP_RESULTS,
LAST_PROP
};
-static void completion_proposal_iface_init (GtkSourceCompletionProposalIface *);
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+static CXCompletionResult *
+ide_clang_completion_item_get_result (IdeClangCompletionItem *self)
+{
+ CXCodeCompleteResults *results;
-G_DEFINE_TYPE_EXTENDED (IdeClangCompletionItem, ide_clang_completion_item, G_TYPE_OBJECT, 0,
- G_IMPLEMENT_INTERFACE (GTK_SOURCE_TYPE_COMPLETION_PROPOSAL,
- completion_proposal_iface_init))
+ g_assert (IDE_IS_CLANG_COMPLETION_ITEM (self));
-static GParamSpec *gParamSpecs [LAST_PROP];
+ results = ide_ref_ptr_get (self->results);
+ return &results->Results [self->index];
+}
+
+static void
+ide_clang_completion_item_lazy_init (IdeClangCompletionItem *self)
+{
+ CXCompletionResult *result;
+ g_autoptr(IdeSourceSnippet) snippet = NULL;
+ GString *markup = NULL;
+ unsigned num_chunks;
+ unsigned i;
+ guint tab_stop = 0;
+
+ g_assert (IDE_IS_CLANG_COMPLETION_ITEM (self));
+
+ if (G_LIKELY (self->initialized))
+ return;
+
+ result = ide_clang_completion_item_get_result (self);
+ num_chunks = clang_getNumCompletionChunks (result);
+ snippet = ide_source_snippet_new (NULL, NULL);
+ markup = g_string_new (NULL);
+
+ g_assert (result);
+ g_assert (num_chunks);
+ g_assert (IDE_IS_SOURCE_SNIPPET (snippet));
+ g_assert (markup);
+
+ /*
+ * Walk the chunks, creating our snippet for insertion as well as our markup
+ * for the row in the completion window.
+ */
+ for (i = 0; i < num_chunks; i++)
+ {
+ enum CXCompletionChunkKind kind;
+ IdeSourceSnippetChunk *chunk;
+ const gchar *text;
+ g_autofree gchar *escaped = NULL;
+ CXString cxstr;
+
+ kind = clang_getCompletionChunkKind (result->CompletionString, i);
+ cxstr = clang_getCompletionChunkText (result->CompletionString, i);
+ text = clang_getCString (cxstr);
+
+ if (text)
+ escaped = g_markup_escape_text (text, -1);
+ else
+ escaped = g_strdup ("");
+
+ switch (kind)
+ {
+ case CXCompletionChunk_Optional:
+ break;
+
+ case CXCompletionChunk_TypedText:
+ g_string_append_printf (markup, "<b>%s</b>", escaped);
+ chunk = ide_source_snippet_chunk_new ();
+ ide_source_snippet_chunk_set_text (chunk, text);
+ ide_source_snippet_add_chunk (snippet, chunk);
+ g_clear_object (&chunk);
+ break;
+
+ case CXCompletionChunk_Text:
+ g_string_append (markup, escaped);
+ chunk = ide_source_snippet_chunk_new ();
+ ide_source_snippet_chunk_set_text (chunk, text);
+ ide_source_snippet_add_chunk (snippet, chunk);
+ g_clear_object (&chunk);
+ break;
+
+ case CXCompletionChunk_Placeholder:
+ g_string_append (markup, escaped);
+ chunk = ide_source_snippet_chunk_new ();
+ ide_source_snippet_chunk_set_text (chunk, text);
+ ide_source_snippet_chunk_set_tab_stop (chunk, tab_stop++);
+ ide_source_snippet_add_chunk (snippet, chunk);
+ g_clear_object (&chunk);
+ break;
+
+ case CXCompletionChunk_Informative:
+ if (0 == g_strcmp0 (text, "const "))
+ g_string_append (markup, text);
+ break;
+
+ case CXCompletionChunk_CurrentParameter:
+ break;
+
+ case CXCompletionChunk_LeftParen:
+ g_string_append (markup, " ");
+ /* fall through */
+ case CXCompletionChunk_RightParen:
+ case CXCompletionChunk_LeftBracket:
+ case CXCompletionChunk_RightBracket:
+ case CXCompletionChunk_LeftBrace:
+ case CXCompletionChunk_RightBrace:
+ case CXCompletionChunk_LeftAngle:
+ case CXCompletionChunk_RightAngle:
+ case CXCompletionChunk_Comma:
+ case CXCompletionChunk_Colon:
+ case CXCompletionChunk_SemiColon:
+ case CXCompletionChunk_Equal:
+ case CXCompletionChunk_HorizontalSpace:
+ g_string_append (markup, escaped);
+ chunk = ide_source_snippet_chunk_new ();
+ ide_source_snippet_chunk_set_text (chunk, text);
+ ide_source_snippet_add_chunk (snippet, chunk);
+ g_clear_object (&chunk);
+ break;
+
+ case CXCompletionChunk_VerticalSpace:
+ g_string_append (markup, escaped);
+ /* insert the vertical space */
+ chunk = ide_source_snippet_chunk_new ();
+ ide_source_snippet_chunk_set_text (chunk, text);
+ ide_source_snippet_add_chunk (snippet, chunk);
+ g_clear_object (&chunk);
+ /* now perform indentation */
+ chunk = ide_source_snippet_chunk_new ();
+ ide_source_snippet_chunk_set_text (chunk, "\t");
+ ide_source_snippet_add_chunk (snippet, chunk);
+ g_clear_object (&chunk);
+ break;
+
+ case CXCompletionChunk_ResultType:
+ g_string_append_printf (markup, "%s ", escaped);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ self->snippet = g_object_ref (snippet);
+ self->markup = g_string_free (markup, FALSE);
+}
+
+static gchar *
+ide_clang_completion_item_get_markup (GtkSourceCompletionProposal *proposal)
+{
+ IdeClangCompletionItem *self = (IdeClangCompletionItem *)proposal;
+
+ g_assert (IDE_IS_CLANG_COMPLETION_ITEM (self));
+
+ ide_clang_completion_item_lazy_init (self);
+
+ return g_strdup (self->markup);
+}
+
+static GdkPixbuf *
+ide_clang_completion_item_get_icon (GtkSourceCompletionProposal *proposal)
+{
+ IdeClangCompletionItem *self = (IdeClangCompletionItem *)proposal;
+
+ g_assert (IDE_IS_CLANG_COMPLETION_ITEM (self));
+
+ ide_clang_completion_item_lazy_init (self);
+
+ return self->icon ? g_object_ref (self->icon) : NULL;
+}
static void
ide_clang_completion_item_finalize (GObject *object)
{
IdeClangCompletionItem *self = (IdeClangCompletionItem *)object;
+ g_clear_object (&self->icon);
+ g_clear_object (&self->snippet);
+ g_clear_pointer (&self->markup, g_free);
g_clear_pointer (&self->results, ide_ref_ptr_unref);
G_OBJECT_CLASS (ide_clang_completion_item_parent_class)->finalize (object);
}
static void
+ide_clang_completion_item_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeClangCompletionItem *self = IDE_CLANG_COMPLETION_ITEM (object);
+
+ switch (prop_id)
+ {
+ case PROP_INDEX:
+ g_value_set_uint (value, self->index);
+ break;
+
+ case PROP_RESULTS:
+ g_value_set_boxed (value, self->results);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
ide_clang_completion_item_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -86,144 +289,163 @@ ide_clang_completion_item_set_property (GObject *object,
}
static void
+completion_proposal_iface_init (GtkSourceCompletionProposalIface *iface)
+{
+ iface->get_icon = ide_clang_completion_item_get_icon;
+ iface->get_markup = ide_clang_completion_item_get_markup;
+}
+
+static void
ide_clang_completion_item_class_init (IdeClangCompletionItemClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = ide_clang_completion_item_finalize;
+ object_class->get_property = ide_clang_completion_item_get_property;
object_class->set_property = ide_clang_completion_item_set_property;
gParamSpecs [PROP_INDEX] =
g_param_spec_uint ("index",
- "Index",
- "The index in the result structure.",
- 0,
- G_MAXUINT,
- 0,
- (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ _("Index"),
+ _("The index in the result set."),
+ 0,
+ G_MAXUINT-1,
+ 0,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_INDEX, gParamSpecs [PROP_INDEX]);
gParamSpecs [PROP_RESULTS] =
g_param_spec_boxed ("results",
- "Results",
- "The result set from clang.",
- IDE_TYPE_REF_PTR,
- (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ _("Results"),
+ _("The clang result set."),
+ IDE_TYPE_REF_PTR,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_RESULTS, gParamSpecs [PROP_RESULTS]);
}
static void
-ide_clang_completion_item_init (IdeClangCompletionItem *item)
+ide_clang_completion_item_init (IdeClangCompletionItem *self)
{
+ self->typed_text_index = -1;
}
-static CXCompletionResult *
-get_completion_result (GtkSourceCompletionProposal *proposal)
+/**
+ * ide_clang_completion_item_get_snippet:
+ * @self: A #IdeClangCompletionItem.
+ *
+ * Gets the #IdeSourceSnippet to be inserted when expanding this completion item.
+ *
+ * Returns: (transfer none): An #IdeSourceSnippet.
+ */
+IdeSourceSnippet *
+ide_clang_completion_item_get_snippet (IdeClangCompletionItem *self)
{
- IdeClangCompletionItem *self = (IdeClangCompletionItem *)proposal;
- CXCodeCompleteResults *results;
- CXCompletionResult *result;
-
- results = ide_ref_ptr_get (self->results);
- result = &results->Results [self->index];
+ g_return_val_if_fail (IDE_IS_CLANG_COMPLETION_ITEM (self), NULL);
- return result;
+ return self->snippet;
}
-static gchar *
-ide_clang_completion_item_get_label (GtkSourceCompletionProposal *proposal)
+/**
+ * ide_clang_completion_item_get_priority:
+ * @self: A #IdeClangCompletionItem.
+ *
+ * Gets the completion priority for sorting within the results.
+ *
+ * Returns: An unsigned integer.
+ */
+guint
+ide_clang_completion_item_get_priority (IdeClangCompletionItem *self)
{
- CXCompletionResult *result = get_completion_result (proposal);
- GString *str;
- unsigned num_chunks;
- unsigned i;
-
- str = g_string_new (NULL);
- num_chunks = clang_getNumCompletionChunks (result->CompletionString);
-
- for (i = 0; i < num_chunks; i++)
- {
- CXString cxstr;
+ CXCompletionResult *result;
- cxstr = clang_getCompletionChunkText (result->CompletionString, i);
+ g_return_val_if_fail (IDE_IS_CLANG_COMPLETION_ITEM (self), 0);
- if (str->len)
- g_string_append_printf (str, " %s", clang_getCString (cxstr));
- else
- g_string_append (str, clang_getCString (cxstr));
- }
+ result = ide_clang_completion_item_get_result (self);
- return g_string_free (str, FALSE);
+ return clang_getCompletionPriority (result);
}
-static void
-completion_proposal_iface_init (GtkSourceCompletionProposalIface *iface)
+/**
+ * ide_clang_completion_item_get_typed_text:
+ * @self: An #IdeClangCompletionItem.
+ *
+ * Gets the text that would be expected to be typed to insert this completion
+ * item into the text editor.
+ *
+ * Returns: A string which should not be modified or freed.
+ */
+const gchar *
+ide_clang_completion_item_get_typed_text (IdeClangCompletionItem *self)
{
- iface->get_label = ide_clang_completion_item_get_label;
-}
+ CXCompletionResult *result;
+ CXString cxstr;
-gint
-ide_clang_completion_item_sort (gconstpointer a,
- gconstpointer b)
-{
- CXCompletionResult *ar = get_completion_result ((gpointer)a);
- CXCompletionResult *br = get_completion_result ((gpointer)b);
- unsigned aprio;
- unsigned bprio;
+ g_return_val_if_fail (IDE_IS_CLANG_COMPLETION_ITEM (self), NULL);
- aprio = clang_getCompletionPriority (ar->CompletionString);
- bprio = clang_getCompletionPriority (br->CompletionString);
+ result = ide_clang_completion_item_get_result (self);
- /* TODO: check that this is safe */
+ /*
+ * Determine the index of the typed text. Each completion result should have
+ * exaction one of these.
+ */
+ if (self->typed_text_index == -1)
+ {
+ guint num_chunks;
+ guint i;
- return (gint)aprio - (gint)bprio;
-}
+ num_chunks = clang_getNumCompletionChunks (result);
-gboolean
-ide_clang_completion_item_matches (IdeClangCompletionItem *self,
- const gchar *text)
-{
- CXCompletionResult *result = get_completion_result ((GtkSourceCompletionProposal *)self);
- enum CXAvailabilityKind availability;
- unsigned chunks;
- unsigned i;
-
- g_return_val_if_fail (IDE_IS_CLANG_COMPLETION_ITEM (self), text);
+ for (i = 0; i < num_chunks; i++)
+ {
+ enum CXCompletionChunkKind kind;
- availability = clang_getCompletionAvailability (result->CompletionString);
+ kind = clang_getCompletionChunkKind (result->CompletionString, i);
+ if (kind == CXCompletionChunk_TypedText)
+ {
+ self->typed_text_index = i;
+ break;
+ }
+ }
+ }
- switch (availability)
- {
- case CXAvailability_NotAvailable:
- case CXAvailability_NotAccessible:
- return FALSE;
+#ifndef IDE_DISABLE_TRACE
+ {
+ enum CXCompletionChunkKind kind;
+ unsigned num_chunks;
- default:
- break;
- }
+ g_assert_cmpint (self->typed_text_index, >=, 0);
- chunks = clang_getNumCompletionChunks (result->CompletionString);
+ num_chunks = clang_getNumCompletionChunks (result->CompletionString);
+ g_assert_cmpint (num_chunks, >, self->typed_text_index);
- for (i = 0; i < chunks; i++)
- {
- enum CXCompletionChunkKind kind;
+ kind = clang_getCompletionChunkKind (result->CompletionString, self->typed_text_index);
+ g_assert_cmpint (kind, ==, CXCompletionChunk_TypedText);
+ }
+#endif
- kind = clang_getCompletionChunkKind (result->CompletionString, i);
+ cxstr = clang_getCompletionChunkText (result->CompletionString, self->typed_text_index);
- if (kind == CXCompletionChunk_TypedText)
- {
- CXString cxstr;
+ return clang_getCString (cxstr);
+}
- cxstr = clang_getCompletionChunkText(result->CompletionString, i);
- if (g_str_has_prefix (clang_getCString (cxstr), text))
- {
- clang_disposeString (cxstr);
- return TRUE;
- }
+/**
+ * ide_clang_completion_item_get_brief_comment:
+ * @self: An #IdeClangCompletionItem.
+ *
+ * Gets the brief comment that can be used to show extra information for the
+ * result.
+ *
+ * Returns: A string which should not be modified or freed.
+ */
+const gchar *
+ide_clang_completion_item_get_brief_comment (IdeClangCompletionItem *self)
+{
+ CXCompletionResult *result;
+ CXString cxstr;
- clang_disposeString (cxstr);
- }
- }
+ g_return_val_if_fail (IDE_IS_CLANG_COMPLETION_ITEM (self), NULL);
- return FALSE;
+ result = ide_clang_completion_item_get_result (self);
+ cxstr = clang_getCompletionBriefComment (result->CompletionString);
+ return clang_getCString (cxstr);
}
diff --git a/libide/clang/ide-clang-completion-item.h b/libide/clang/ide-clang-completion-item.h
index 60d458d..2299fe5 100644
--- a/libide/clang/ide-clang-completion-item.h
+++ b/libide/clang/ide-clang-completion-item.h
@@ -19,7 +19,9 @@
#ifndef IDE_CLANG_COMPLETION_ITEM_H
#define IDE_CLANG_COMPLETION_ITEM_H
-#include <glib-object.h>
+#include <gtksourceview/gtksourcecompletionproposal.h>
+
+#include "ide-source-snippet.h"
G_BEGIN_DECLS
@@ -31,14 +33,14 @@ G_BEGIN_DECLS
#define IDE_IS_CLANG_COMPLETION_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
IDE_TYPE_CLANG_COMPLETION_ITEM))
#define IDE_CLANG_COMPLETION_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
IDE_TYPE_CLANG_COMPLETION_ITEM, IdeClangCompletionItemClass))
-typedef struct _IdeClangCompletionItem IdeClangCompletionItem;
-typedef struct _IdeClangCompletionItemClass IdeClangCompletionItemClass;
+typedef struct _IdeClangCompletionItem IdeClangCompletionItem;
+typedef struct _IdeClangCompletionItemClass IdeClangCompletionItemClass;
-GType ide_clang_completion_item_get_type (void);
-gboolean ide_clang_completion_item_matches (IdeClangCompletionItem *self,
- const gchar *text);
-gint ide_clang_completion_item_sort (gconstpointer a,
- gconstpointer b);
+GType ide_clang_completion_item_get_type (void);
+IdeSourceSnippet *ide_clang_completion_item_get_snippet (IdeClangCompletionItem *self);
+const gchar *ide_clang_completion_item_get_typed_text (IdeClangCompletionItem *self);
+guint ide_clang_completion_item_get_priority (IdeClangCompletionItem *self);
+const gchar *ide_clang_completion_item_get_brief_comment (IdeClangCompletionItem *self);
G_END_DECLS
diff --git a/libide/clang/ide-clang-completion-provider.c b/libide/clang/ide-clang-completion-provider.c
index 2d8ff77..4a5f7d0 100644
--- a/libide/clang/ide-clang-completion-provider.c
+++ b/libide/clang/ide-clang-completion-provider.c
@@ -28,6 +28,8 @@
#include "ide-context.h"
#include "ide-debug.h"
#include "ide-file.h"
+#include "ide-source-snippet.h"
+#include "ide-source-view.h"
struct _IdeClangCompletionProviderClass
{
@@ -38,7 +40,8 @@ struct _IdeClangCompletionProvider
{
GObject parent_instance;
- GPtrArray *last_results;
+ IdeSourceView *view;
+ GPtrArray *last_results;
};
typedef struct
@@ -101,6 +104,16 @@ stop_on_predicate (gunichar ch,
}
}
+static gboolean
+matches (IdeClangCompletionItem *item,
+ const gchar *word)
+{
+ const gchar *typed_text;
+
+ typed_text = ide_clang_completion_item_get_typed_text (item);
+ return !!strstr (typed_text, word);
+}
+
static gchar *
get_word (const GtkTextIter *location)
{
@@ -134,7 +147,7 @@ filter_list (GPtrArray *ar,
IdeClangCompletionItem *item;
item = g_ptr_array_index (ar, i);
- if (ide_clang_completion_item_matches (item, word))
+ if (matches (item, word))
g_ptr_array_add (matched, item);
}
@@ -252,22 +265,35 @@ static void
ide_clang_completion_provider_populate (GtkSourceCompletionProvider *provider,
GtkSourceCompletionContext *context)
{
+ IdeClangCompletionProvider *self = (IdeClangCompletionProvider *)provider;
AddProposalsState *state;
IdeClangService *service;
+ GtkSourceCompletion *completion;
+ GtkSourceView *view;
GtkTextBuffer *buffer;
IdeContext *icontext;
GtkTextIter iter;
IdeFile *file;
+ g_assert (IDE_IS_CLANG_COMPLETION_PROVIDER (self));
+
if (!gtk_source_completion_context_get_iter (context, &iter))
goto failure;
buffer = gtk_text_iter_get_buffer (&iter);
if (buffer == NULL)
goto failure;
-
g_assert (IDE_IS_BUFFER (buffer));
+ /* stash the view for later */
+ g_object_get (context, "completion", &completion, NULL);
+ g_assert (GTK_SOURCE_IS_COMPLETION (completion));
+ view = gtk_source_completion_get_view (completion);
+ g_assert (IDE_IS_SOURCE_VIEW (view));
+ g_assert ((self->view == NULL) || (self->view == (IdeSourceView *)view));
+ self->view = IDE_SOURCE_VIEW (view);
+ g_clear_object (&completion);
+
file = ide_buffer_get_file (IDE_BUFFER (buffer));
if (file == NULL)
goto failure;
@@ -321,7 +347,24 @@ ide_clang_completion_provider_activate_proposal (GtkSourceCompletionProvider *pr
GtkSourceCompletionProposal *proposal,
GtkTextIter *iter)
{
- return FALSE;
+ IdeClangCompletionProvider *self = (IdeClangCompletionProvider *)provider;
+ IdeClangCompletionItem *item = (IdeClangCompletionItem *)proposal;
+ IdeSourceSnippet *snippet;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_CLANG_COMPLETION_PROVIDER (self));
+ g_assert (IDE_IS_CLANG_COMPLETION_ITEM (item));
+
+ snippet = ide_clang_completion_item_get_snippet (item);
+
+ g_assert (snippet != NULL);
+ g_assert (IDE_IS_SOURCE_SNIPPET (snippet));
+ g_assert (IDE_IS_SOURCE_VIEW (self->view));
+
+ ide_source_view_push_snippet (self->view, snippet);
+
+ IDE_RETURN (TRUE);
}
static gint
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]