IdeSourceRange *
_ide_source_range_new (IdeSourceLocation *begin,
                       IdeSourceLocation *end)
{
  IdeSourceRange *ret;

  g_return_val_if_fail (begin, NULL);
  g_return_val_if_fail (end, NULL);
  g_return_val_if_fail (ide_file_equal (ide_source_location_get_file (begin),
                                        ide_source_location_get_file (end)),
                        NULL);

  ret = g_slice_new0 (IdeSourceRange);
  ret->ref_count = 1;
  ret->begin = ide_source_location_ref (begin);
  ret->end = ide_source_location_ref (end);

  return ret;
}
void
gb_view_stack_focus_location (GbViewStack       *self,
                              IdeSourceLocation *location)
{
  IdeBufferManager *buffer_manager;
  IdeBuffer *buffer;
  IdeFile *file;
  GFile *gfile;

  g_return_if_fail (GB_IS_VIEW_STACK (self));
  g_return_if_fail (location != NULL);

  if (self->context == NULL)
    return;

  file = ide_source_location_get_file (location);
  gfile = ide_file_get_file (file);

  g_assert (file != NULL);
  g_assert (IDE_IS_FILE (file));

  gfile = ide_file_get_file (file);

  buffer_manager = ide_context_get_buffer_manager (self->context);
  buffer = ide_buffer_manager_find_buffer (buffer_manager, gfile);

  if (buffer != NULL && GB_IS_DOCUMENT (buffer))
    {
      GtkWidget *active_view;

      gb_view_stack_focus_document (self, GB_DOCUMENT (buffer));
      active_view = gb_view_stack_get_active_view (self);
      g_assert (GB_DOCUMENT (buffer) == gb_view_get_document (GB_VIEW (active_view)));
      gb_view_navigate_to (GB_VIEW (active_view), location);
    }
  else
    {
      g_autoptr(GTask) task = NULL;

      task = g_task_new (self, NULL, NULL, NULL);
      g_task_set_task_data (task, ide_source_location_ref (location),
                            (GDestroyNotify)ide_source_location_unref);
      ide_buffer_manager_load_file_async (buffer_manager, file, FALSE, NULL, NULL,
                                          gb_view_stack__navigate_to_load_cb,
                                          g_object_ref (task));
    }
}
Exemple #3
0
static void
ide_editor_perspective_focus_location_full (IdeEditorPerspective *self,
                                            IdeSourceLocation    *location,
                                            gboolean              open_if_not_found)
{
  struct {
    IdeFile *file;
    IdeEditorView *view;
  } lookup = { 0 };
  GtkWidget *stack;
  guint line;
  guint line_offset;

  IDE_ENTRY;

  g_assert (IDE_IS_EDITOR_PERSPECTIVE (self));
  g_assert (location != NULL);

  lookup.file = ide_source_location_get_file (location);
  lookup.view = NULL;

  if (lookup.file == NULL)
    {
      g_warning ("IdeSourceLocation does not contain a file");
      IDE_EXIT;
    }

#ifdef IDE_ENABLE_TRACE
  {
    const gchar *path = ide_file_get_path (lookup.file);
    IDE_TRACE_MSG ("Locating %s, open_if_not_found=%d",
                   path, open_if_not_found);
  }
#endif

  ide_perspective_views_foreach (IDE_PERSPECTIVE (self),
                                 ide_editor_perspective_find_source_location,
                                 &lookup);

  if (!open_if_not_found && lookup.view == NULL)
    IDE_EXIT;

  if (lookup.view == NULL)
    {
      FocusLocation *state;
      IdeBufferManager *bufmgr;
      IdeWorkbench *workbench;
      IdeContext *context;

      workbench = ide_widget_get_workbench (GTK_WIDGET (self));
      context = ide_workbench_get_context (workbench);
      bufmgr = ide_context_get_buffer_manager (context);

      state = g_slice_new0 (FocusLocation);
      state->self = g_object_ref (self);
      state->location = ide_source_location_ref (location);

      ide_buffer_manager_load_file_async (bufmgr,
                                          lookup.file,
                                          FALSE,
                                          IDE_WORKBENCH_OPEN_FLAGS_NONE,
                                          NULL,
                                          NULL,
                                          ide_editor_perspective_focus_location_cb,
                                          state);
      IDE_EXIT;
    }

  line = ide_source_location_get_line (location);
  line_offset = ide_source_location_get_line_offset (location);

  stack = gtk_widget_get_ancestor (GTK_WIDGET (lookup.view), IDE_TYPE_LAYOUT_STACK);
  ide_layout_stack_set_visible_child (IDE_LAYOUT_STACK (stack), IDE_LAYOUT_VIEW (lookup.view));
  ide_editor_view_scroll_to_line_offset (lookup.view, line, line_offset);

  IDE_EXIT;
}
Exemple #4
0
static void
ide_langserv_rename_provider_rename_async (IdeRenameProvider   *provider,
                                           IdeSourceLocation   *location,
                                           const gchar         *new_name,
                                           GCancellable        *cancellable,
                                           GAsyncReadyCallback  callback,
                                           gpointer             user_data)
{
  IdeLangservRenameProvider *self = (IdeLangservRenameProvider *)provider;
  IdeLangservRenameProviderPrivate *priv = ide_langserv_rename_provider_get_instance_private (self);
  g_autoptr(GTask) task = NULL;
  g_autoptr(JsonNode) params = NULL;
  g_autofree gchar *uri = NULL;
  IdeFile *ifile;
  GFile *gfile;
  gint line;
  gint column;

  IDE_ENTRY;

  g_assert (IDE_IS_LANGSERV_RENAME_PROVIDER (self));
  g_assert (location != NULL);
  g_assert (new_name != NULL);
  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));

  task = g_task_new (self, cancellable, callback, user_data);
  g_task_set_source_tag (task, ide_langserv_rename_provider_rename_async);

  if (priv->client == NULL)
    {
      g_task_return_new_error (task,
                               G_IO_ERROR,
                               G_IO_ERROR_NOT_CONNECTED,
                               "No client set, cannot rename symbol");
      IDE_EXIT;
    }

  ifile = ide_source_location_get_file (location);
  gfile = ide_file_get_file (ifile);
  uri = g_file_get_uri (gfile);

  line = ide_source_location_get_line (location);
  column = ide_source_location_get_line_offset (location);

  params = JCON_NEW (
    "textDocument", "{",
      "uri", JCON_STRING (uri),
    "}",
    "position", "{",
      "line", JCON_INT (line),
      "character", JCON_INT (column),
    "}",
    "newName", JCON_STRING (new_name)
  );

  ide_langserv_client_call_async (priv->client,
                                  "textDocument/rename",
                                  g_steal_pointer (&params),
                                  cancellable,
                                  ide_langserv_rename_provider_rename_cb,
                                  g_steal_pointer (&task));

  IDE_EXIT;
}
Exemple #5
0
static void
ide_langserv_symbol_resolver_find_references_async (IdeSymbolResolver   *resolver,
                                                    IdeSourceLocation   *location,
                                                    GCancellable        *cancellable,
                                                    GAsyncReadyCallback  callback,
                                                    gpointer             user_data)
{
  IdeLangservSymbolResolver *self = (IdeLangservSymbolResolver *)resolver;
  IdeLangservSymbolResolverPrivate *priv = ide_langserv_symbol_resolver_get_instance_private (self);
  g_autoptr(GTask) task = NULL;
  g_autoptr(GVariant) params = NULL;
  g_autofree gchar *uri = NULL;
  const gchar *language_id;
  IdeFile *file;
  GFile *gfile;
  guint line;
  guint line_offset;

  IDE_ENTRY;

  g_assert (IDE_IS_LANGSERV_SYMBOL_RESOLVER (self));
  g_assert (location != NULL);
  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));

  task = g_task_new (self, cancellable, callback, user_data);
  g_task_set_source_tag (task, ide_langserv_symbol_resolver_find_references_async);

  file = ide_source_location_get_file (location);
  gfile = ide_file_get_file (file);
  uri = g_file_get_uri (gfile);

  line = ide_source_location_get_line (location);
  line_offset = ide_source_location_get_line_offset (location);

  language_id = ide_file_get_language_id (file);
  if (language_id == NULL)
    language_id = "plain";

  params = JSONRPC_MESSAGE_NEW (
    "textDocument", "{",
      "uri", JSONRPC_MESSAGE_PUT_STRING (uri),
      "languageId", JSONRPC_MESSAGE_PUT_STRING (language_id),
    "}",
    "position", "{",
      "line", JSONRPC_MESSAGE_PUT_INT32 (line),
      "character", JSONRPC_MESSAGE_PUT_INT32 (line_offset),
    "}",
    "context", "{",
      "includeDeclaration", JSONRPC_MESSAGE_PUT_BOOLEAN (TRUE),
    "}"
  );

  ide_langserv_client_call_async (priv->client,
                                  "textDocument/references",
                                  g_steal_pointer (&params),
                                  cancellable,
                                  ide_langserv_symbol_resolver_find_references_cb,
                                  g_steal_pointer (&task));

  IDE_EXIT;
}
Exemple #6
0
static void
ide_langserv_symbol_resolver_lookup_symbol_async (IdeSymbolResolver   *resolver,
                                                  IdeSourceLocation   *location,
                                                  GCancellable        *cancellable,
                                                  GAsyncReadyCallback  callback,
                                                  gpointer             user_data)
{
  IdeLangservSymbolResolver *self = (IdeLangservSymbolResolver *)resolver;
  IdeLangservSymbolResolverPrivate *priv = ide_langserv_symbol_resolver_get_instance_private (self);
  g_autoptr(GTask) task = NULL;
  g_autoptr(GVariant) params = NULL;
  g_autofree gchar *uri = NULL;
  IdeFile *ifile;
  GFile *gfile;
  gint line;
  gint column;

  IDE_ENTRY;

  g_assert (IDE_IS_LANGSERV_SYMBOL_RESOLVER (self));
  g_assert (location != NULL);
  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));

  task = g_task_new (self, cancellable, callback, user_data);
  g_task_set_source_tag (task, ide_langserv_symbol_resolver_lookup_symbol_async);

  if (priv->client == NULL)
    {
      g_task_return_new_error (task,
                               G_IO_ERROR,
                               G_IO_ERROR_NOT_CONNECTED,
                               "%s requires a client to resolve symbols",
                               G_OBJECT_TYPE_NAME (self));
      IDE_EXIT;
    }

  if (NULL == (ifile = ide_source_location_get_file (location)) ||
      NULL == (gfile = ide_file_get_file (ifile)))
    {
      g_task_return_new_error (task,
                               G_IO_ERROR,
                               G_IO_ERROR_NOT_SUPPORTED,
                               "Cannot resolve symbol, invalid source location");
      IDE_EXIT;
    }

  uri = g_file_get_uri (gfile);
  line = ide_source_location_get_line (location);
  column = ide_source_location_get_line_offset (location);

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

  ide_langserv_client_call_async (priv->client,
                                  "textDocument/definition",
                                  g_steal_pointer (&params),
                                  cancellable,
                                  ide_langserv_symbol_resolver_definition_cb,
                                  g_steal_pointer (&task));

  IDE_EXIT;
}