static gboolean
ide_ctags_completion_provider_match (GtkSourceCompletionProvider *provider,
                                     GtkSourceCompletionContext  *context)
{
  IdeCtagsCompletionProvider *self = (IdeCtagsCompletionProvider *)provider;
  GtkSourceCompletionActivation activation;
  GtkTextIter iter;

  g_assert (IDE_IS_CTAGS_COMPLETION_PROVIDER (self));
  g_assert (GTK_SOURCE_IS_COMPLETION_CONTEXT (context));

  if (!gtk_source_completion_context_get_iter (context, &iter))
    return FALSE;

  activation = gtk_source_completion_context_get_activation (context);

  if (activation == GTK_SOURCE_COMPLETION_ACTIVATION_INTERACTIVE)
    {
      if (gtk_text_iter_starts_line (&iter) ||
          !gtk_text_iter_backward_char (&iter) ||
          g_unichar_isspace (gtk_text_iter_get_char (&iter)))
        return FALSE;
    }

  if (!g_settings_get_boolean (self->settings, "ctags-autocompletion"))
    return FALSE;

  if (ide_completion_provider_context_in_comment (context))
    return FALSE;

  return TRUE;
}
Example #2
0
static gboolean
ide_langserv_completion_provider_match (GtkSourceCompletionProvider *provider,
                                        GtkSourceCompletionContext  *context)
{
  GtkSourceCompletionActivation activation;
  GtkTextIter iter;

  g_assert (IDE_IS_LANGSERV_COMPLETION_PROVIDER (provider));
  g_assert (GTK_SOURCE_IS_COMPLETION_CONTEXT (context));

  if (!gtk_source_completion_context_get_iter (context, &iter))
    return FALSE;

  activation = gtk_source_completion_context_get_activation (context);

  if (activation == GTK_SOURCE_COMPLETION_ACTIVATION_INTERACTIVE)
    {
      if (gtk_text_iter_starts_line (&iter) ||
          !gtk_text_iter_backward_char (&iter) ||
          g_unichar_isspace (gtk_text_iter_get_char (&iter)))
        return FALSE;
    }

  if (ide_completion_provider_context_in_comment (context))
    return FALSE;

  return TRUE;
}
Example #3
0
static void
gsc_provider_devhelp_populate (GtkSourceCompletionProvider *provider,
                               GtkSourceCompletionContext  *context)
{
	GscProviderDevhelp *devhelp = GSC_PROVIDER_DEVHELP (provider);
	GtkTextIter iter;
	gchar *word;

	devhelp->priv->cancel_id = 
		g_signal_connect_swapped (context,
			                  "cancelled",
			                  G_CALLBACK (population_finished),
			                  provider);
	
	devhelp->priv->counter = 0;
	devhelp->priv->populate_iter = NULL;
	devhelp->priv->context = g_object_ref (context);

	gtk_source_completion_context_get_iter (context, &iter);
	
	g_free (devhelp->priv->word);

	word = get_word_at_iter (devhelp, &iter);
	
	if (word != NULL)
	{
		devhelp->priv->word = string_for_compare (word);
		devhelp->priv->word_len = strlen (devhelp->priv->word);
	}
	else
	{
		devhelp->priv->word_len = 0;
	}
	
	g_free (word);
	
	/* Make sure we are finished populating the proposals from devhelp */
	if (devhelp->priv->idle_populate_id != 0)
	{
		g_source_remove (devhelp->priv->idle_populate_id);
		devhelp->priv->idle_populate_id = 0;
		
		while (idle_populate_proposals (devhelp))
		;
	}
	
	/* Do first right now */
	if (add_in_idle (devhelp))
	{
		devhelp->priv->idle_id = g_idle_add ((GSourceFunc)add_in_idle,
		                                     devhelp);
	}
}
Example #4
0
static void
sourceview_provider_populate (GtkSourceCompletionProvider* provider, GtkSourceCompletionContext* context)
{
	SourceviewProvider* prov = SOURCEVIEW_PROVIDER(provider);
	GtkTextIter iter;
	SourceviewCell* cell;
	gtk_source_completion_context_get_iter(context, &iter);
	cell = sourceview_cell_new (&iter, GTK_TEXT_VIEW(prov->sv->priv->view));
	prov->context = context;
	prov->cancelled = FALSE;
	g_signal_connect (context, "cancelled", G_CALLBACK(on_context_cancelled), prov);
	ianjuta_provider_populate(prov->iprov, IANJUTA_ITERABLE(cell), NULL);
	g_object_unref (cell);
}
Example #5
0
static gboolean
gsc_provider_devhelp_match (GtkSourceCompletionProvider *provider,
                            GtkSourceCompletionContext  *context)
{
	GtkTextIter iter;
	gchar *word;
	gboolean match = FALSE;

	gtk_source_completion_context_get_iter (context, &iter);

	word = get_word_at_iter (GSC_PROVIDER_DEVHELP (provider), &iter);

	/* FIXME: If MIN_WORD_LEN >= 4 only the doc completion is loaded,
	 * also because if the doc provider is loader before this one the icon
	 * is not shown. We should fix this before 2.30
	 */
	match = word != NULL && g_utf8_strlen (word, -1) >= MIN_WORD_LEN;

	g_free (word);

	return match;
}
Example #6
0
static gboolean
gsc_provider_devhelp_get_start_iter (GtkSourceCompletionProvider *provider,
                                     GtkSourceCompletionContext  *context,
                                     GtkSourceCompletionProposal *proposal,
                                     GtkTextIter                 *iter)
{
	GscProviderDevhelp *devhelp = GSC_PROVIDER_DEVHELP (provider);
	GtkTextBuffer *buf;
	GtkTextMark *mark;
	GtkTextIter context_iter;

	gtk_source_completion_context_get_iter (context, &context_iter);
	buf = gtk_text_iter_get_buffer (&context_iter);
	mark = gtk_text_buffer_get_mark (buf, MARK_NAME);
	
	if (!mark)
	{
		return FALSE;
	}
	
	gtk_text_buffer_get_iter_at_mark (buf, iter, mark);

	return TRUE;
}
static void
provider_populate (GtkSourceCompletionProvider *provider,
                   GtkSourceCompletionContext  *context)
{
   GbDBusTypelib *proxy;
   GCancellable *cancellable;
   GtkTextIter iter;
   GError *error = NULL;
   GVariant *matches = NULL;
   gpointer *closure;
   //gchar **words = NULL;
   gchar *word;
   GList *list = NULL;
   gint len;
   gint i;

   proxy = get_proxy(GB_SOURCE_TYPELIB_COMPLETION_PROVIDER(provider));
   if (!proxy) {
      g_warning("No dbus proxy.");
      return;
   }

   gtk_source_completion_context_get_iter(context, &iter);
   word = get_word(provider, &iter);
   len = strlen(word);

   closure = g_new0(gpointer, 2);
   closure[0] = g_object_ref(provider);
   closure[1] = g_object_ref(context);
   closure[2] = g_strdup(word);

   cancellable = g_cancellable_new();
   g_signal_connect_object(context,
                           "cancelled",
                           G_CALLBACK(g_cancellable_cancel),
                           cancellable,
                           G_CONNECT_SWAPPED);

   gb_dbus_typelib_call_get_methods(proxy,
                                    word,
                                    cancellable,
                                    get_methods_cb,
                                    closure);

   g_object_unref(cancellable);

#if 0
   if (!gb_dbus_typelib_call_get_objects_sync(proxy,
                                              word,
                                              &words,
                                              NULL,
                                              &error)) {
      g_warning("%s\n", error->message);
      g_error_free(error);
   }

   if (words) {
      for (i = 0; words[i]; i++) {
         GtkSourceCompletionItem *item;

         item = gtk_source_completion_item_new(words[i], words[i], gClassPixbuf, NULL);
         list = g_list_prepend(list, item);
      }
   }

   list = g_list_reverse(list);
   gtk_source_completion_context_add_proposals(context, provider, list, TRUE);

   g_strfreev(words);

   words = NULL;

   g_free(word);
#endif
}
Example #8
0
static void
ide_langserv_completion_provider_populate (GtkSourceCompletionProvider *provider,
                                           GtkSourceCompletionContext  *context)
{
  IdeLangservCompletionProvider *self = (IdeLangservCompletionProvider *)provider;
  IdeLangservCompletionProviderPrivate *priv = ide_langserv_completion_provider_get_instance_private (self);
  g_autoptr(GVariant) params = NULL;
  g_autoptr(GCancellable) cancellable = NULL;
  g_autoptr(CompletionState) state = NULL;
  g_autofree gchar *uri = NULL;
  GtkTextIter iter;
  IdeBuffer *buffer;
  gint line;
  gint column;

  IDE_ENTRY;

  g_assert (IDE_IS_LANGSERV_COMPLETION_PROVIDER (self));
  g_assert (GTK_SOURCE_IS_COMPLETION_CONTEXT (context));

  if (priv->client == NULL)
    {
      IDE_TRACE_MSG ("No client set, cannot provide proposals");
      gtk_source_completion_context_add_proposals (context, provider, NULL, TRUE);
      IDE_EXIT;
    }

  gtk_source_completion_context_get_iter (context, &iter);

  buffer = IDE_BUFFER (gtk_text_iter_get_buffer (&iter));
  uri = ide_buffer_get_uri (buffer);

  line = gtk_text_iter_get_line (&iter);
  column = gtk_text_iter_get_line_offset (&iter);

  params = JSONRPC_MESSAGE_NEW (
    "textDocument", "{",
      "uri", JSONRPC_MESSAGE_PUT_STRING (uri),
    "}",
    "position", "{",
      "line", JSONRPC_MESSAGE_PUT_INT32 (line),
      "character", JSONRPC_MESSAGE_PUT_INT32 (column),
    "}"
  );

  cancellable = g_cancellable_new ();

  g_signal_connect_data (context,
                         "cancelled",
                         G_CALLBACK (g_cancellable_cancel),
                         g_object_ref (cancellable),
                         (GClosureNotify)g_object_unref,
                         G_CONNECT_SWAPPED);

  state = completion_state_new (self, context);

  ide_langserv_client_call_async (priv->client,
                                  "textDocument/completion",
                                  g_steal_pointer (&params),
                                  g_steal_pointer (&cancellable),
                                  ide_langserv_completion_provider_complete_cb,
                                  g_steal_pointer (&state));

  IDE_EXIT;
}
static void
ide_ctags_completion_provider_populate (GtkSourceCompletionProvider *provider,
                                        GtkSourceCompletionContext  *context)
{
  IdeCtagsCompletionProvider *self = (IdeCtagsCompletionProvider *)provider;
  g_autofree gchar *word = NULL;
  const IdeCtagsIndexEntry *entries;
  const gchar * const *allowed;
  g_autoptr(GPtrArray) ar = NULL;
  IdeCtagsIndexEntry *last = NULL;
  GtkSourceBuffer *buffer;
  gsize n_entries;
  GtkTextIter iter;
  GList *list = NULL;
  gsize i;
  gsize j;

  IDE_ENTRY;

  g_assert (IDE_IS_CTAGS_COMPLETION_PROVIDER (self));
  g_assert (GTK_SOURCE_IS_COMPLETION_CONTEXT (context));

  if (self->indexes->len == 0)
    IDE_GOTO (failure);

  if (!g_settings_get_boolean (self->settings, "ctags-autocompletion"))
    IDE_GOTO (failure);

  if (!gtk_source_completion_context_get_iter (context, &iter))
    IDE_GOTO (failure);

  buffer = GTK_SOURCE_BUFFER (gtk_text_iter_get_buffer (&iter));
  allowed = get_allowed_suffixes (buffer);

  word = get_word_to_cursor (&iter);
  if (ide_str_empty0 (word) || strlen (word) < self->minimum_word_size)
    IDE_GOTO (failure);

  if (strlen (word) < 3)
    IDE_GOTO (failure);

  ar = g_ptr_array_new ();

  IDE_TRACE_MSG ("Searching for %s", word);

  for (j = 0; j < self->indexes->len; j++)
    {
      IdeCtagsIndex *index = g_ptr_array_index (self->indexes, j);

      entries = ide_ctags_index_lookup_prefix (index, word, &n_entries);
      if ((entries == NULL) || (n_entries == 0))
        continue;

      for (i = 0; i < n_entries; i++)
        {
          const IdeCtagsIndexEntry *entry = &entries [i];

          if (is_allowed (entry, allowed))
            g_ptr_array_add (ar, (gpointer)entry);
        }
    }

  g_ptr_array_sort (ar, sort_wrapper);

  for (i = ar->len; i > 0; i--)
    {
      GtkSourceCompletionProposal *item;
      IdeCtagsIndexEntry *entry = g_ptr_array_index (ar, i - 1);

      /*
       * NOTE:
       *
       * We walk backwards in this ptrarray so that we can use g_list_prepend() for O(1) access.
       * I think everyone agrees that using GList for passing completion data around was not
       * a great choice, but it is what we have to work with.
       */

      /*
       * Ignore this item if the previous one looks really similar.
       * We take the first item instead of the last since the first item (when walking backwards)
       * tends to be more likely to be the one we care about (based on lexicographical
       * ordering. For example, something in "gtk-2.0" is less useful than "gtk-3.0".
       *
       * This is done here instead of during our initial object creation so that
       * we can merge items between different indexes. It often happens that the
       * same headers are included in multiple tags files.
       */
      if ((last != NULL) && too_similar (entry, last))
        continue;

      /*
       * NOTE:
       *
       * Autocompletion is very performance sensitive code. The smallest amount of
       * extra work has a very negative impact on interactivity. We are trying to
       * avoid a couple things here based on how completion works.
       *
       * 1) Avoiding referencing or copying things.
       *    Since the provider will always outlive the completion item, we use
       *    borrowed references for as much as we can.
       * 2) We delay the work of looking up icons until they are requested.
       *    No sense in doing that work before hand.
       */
      item = ide_ctags_completion_item_new (entry, self, context);
      list = g_list_prepend (list, item);

      last = entry;
    }

failure:
  gtk_source_completion_context_add_proposals (context, provider, list, TRUE);
  g_list_free_full (list, g_object_unref);

  IDE_EXIT;
}