[gnome-builder/wip/code-assistance: 5/5] code-assistance: highlight error regions from code assistance
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/code-assistance: 5/5] code-assistance: highlight error regions from code assistance
- Date: Mon, 20 Oct 2014 22:34:32 +0000 (UTC)
commit 33d6e83f026db80f96971ccae3b4c8cad9f6b2da
Author: Christian Hergert <christian hergert me>
Date: Sun Oct 19 22:18:17 2014 -0700
code-assistance: highlight error regions from code assistance
Still *tons* to do here, but at least you see squiggly lines now!
src/editor/gb-editor-code-assistant.c | 138 +++++++++++++++++++++++++++++----
src/editor/gb-editor-tab.c | 3 -
src/gca/gca-structs.c | 105 +++++++++++++++++++++++++
src/gca/gca-structs.h | 67 ++++++++++++++++
src/gnome-builder.mk | 2 +
5 files changed, 295 insertions(+), 20 deletions(-)
---
diff --git a/src/editor/gb-editor-code-assistant.c b/src/editor/gb-editor-code-assistant.c
index f4adb8d..1ff5081 100644
--- a/src/editor/gb-editor-code-assistant.c
+++ b/src/editor/gb-editor-code-assistant.c
@@ -25,35 +25,142 @@
#include "gb-log.h"
#include "gca-diagnostics.h"
#include "gca-service.h"
+#include "gca-structs.h"
#define PARSE_TIMEOUT_MSEC 250
static void
+add_diagnostic_range (GbEditorTab *tab,
+ GcaDiagnostic *diag,
+ GcaSourceRange *range)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter begin;
+ GtkTextIter end;
+ guint column;
+
+ g_assert (GB_IS_EDITOR_TAB (tab));
+ g_assert (diag);
+ g_assert (range);
+
+ buffer = GTK_TEXT_BUFFER (tab->priv->document);
+
+ gtk_text_buffer_get_iter_at_line (buffer, &begin, range->begin.line);
+ for (column = range->begin.column; column; column--)
+ if (gtk_text_iter_ends_line (&begin) || !gtk_text_iter_forward_char (&begin))
+ break;
+
+ gtk_text_buffer_get_iter_at_line (buffer, &end, range->end.line);
+ for (column = range->end.column; column; column--)
+ if (gtk_text_iter_ends_line (&end) || !gtk_text_iter_forward_char (&end))
+ break;
+
+ if (gtk_text_iter_equal (&begin, &end))
+ gtk_text_iter_forward_to_line_end (&end);
+
+ gtk_text_buffer_apply_tag_by_name (buffer, "ErrorTag", &begin, &end);
+}
+
+static void
+add_diagnostic (GbEditorTab *tab,
+ GcaDiagnostic *diag)
+{
+ guint i;
+
+ g_return_if_fail (GB_IS_EDITOR_TAB (tab));
+ g_return_if_fail (diag);
+
+#if 0
+ g_print ("DIAG: %s\n", diag->message);
+#endif
+
+ for (i = 0; i < diag->locations->len; i++)
+ {
+ GcaSourceRange *range;
+
+ range = &g_array_index (diag->locations, GcaSourceRange, i);
+ add_diagnostic_range (tab, diag, range);
+ }
+}
+
+static const gchar *
+get_language (GbSourceView *view)
+{
+ GtkTextBuffer *buffer;
+ GtkSourceLanguage *lang;
+ const gchar *lang_id;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+ if (!GTK_SOURCE_IS_BUFFER (buffer))
+ return NULL;
+
+ lang = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (buffer));
+ if (!lang)
+ return NULL;
+
+ /* TODO: probably should get the mapping from GCA service for this */
+ lang_id = gtk_source_language_get_id (lang);
+ if (g_str_equal (lang_id, "chdr") || g_str_equal (lang_id, "objc"))
+ return "c";
+
+ return lang_id;
+}
+
+static void
gb_editor_code_assistant_diag_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
GbEditorTab *tab = user_data;
- GcaDiagnostics *diag = (GcaDiagnostics *)source_object;
+ GtkTextBuffer *buffer;
+ GtkTextTagTable *tag_table;
+ GtkTextIter begin;
+ GtkTextIter end;
+ GtkTextTag *tag;
+ GcaDiagnostics *proxy = (GcaDiagnostics *)source_object;
GVariant *diags = NULL;
+ GArray *ar;
GError *error = NULL;
+ guint i;
- if (!gca_diagnostics_call_diagnostics_finish (diag, &diags, result, &error))
+ ENTRY;
+
+ if (!gca_diagnostics_call_diagnostics_finish (proxy, &diags, result, &error))
{
g_warning ("%s", error->message);
g_clear_error (&error);
GOTO (cleanup);
}
- {
- gchar *str = g_variant_print (diags, TRUE);
- g_print (">> %s\n", str);
- g_free (str);
- }
+ buffer = GTK_TEXT_BUFFER (tab->priv->document);
+ tag_table = gtk_text_buffer_get_tag_table (buffer);
+ tag = gtk_text_tag_table_lookup (tag_table, "ErrorTag");
+
+ if (!tag)
+ tag = gtk_text_buffer_create_tag (buffer, "ErrorTag",
+ "underline", PANGO_UNDERLINE_ERROR,
+ NULL);
+
+ gtk_text_buffer_get_bounds (buffer, &begin, &end);
+ gtk_text_buffer_remove_tag (buffer, tag, &begin, &end);
+
+ ar = gca_diagnostics_from_variant (diags);
+
+ for (i = 0; i < ar->len; i++)
+ {
+ GcaDiagnostic *diag;
+
+ diag = &g_array_index (ar, GcaDiagnostic, i);
+ add_diagnostic (tab, diag);
+ }
+
+ g_array_unref (ar);
cleanup:
g_clear_pointer (&diags, g_variant_unref);
g_object_unref (tab);
+
+ EXIT;
}
static void
@@ -64,7 +171,6 @@ gb_editor_code_assistant_parse_cb (GObject *source_object,
GbEditorTab *tab = user_data;
GcaService *service = (GcaService *)source_object;
GcaDiagnostics *diag_proxy = NULL;
- GtkSourceLanguage *language;
const gchar *lang_id;
GError *error = NULL;
gchar *document_path = NULL;
@@ -82,12 +188,10 @@ gb_editor_code_assistant_parse_cb (GObject *source_object,
GOTO (cleanup);
}
- language =
- gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (tab->priv->document));
- if (!language)
+ lang_id = get_language (tab->priv->source_view);
+ if (!lang_id)
GOTO (cleanup);
- lang_id = gtk_source_language_get_id (language);
name = g_strdup_printf ("org.gnome.CodeAssist.v1.%s", lang_id);
diag_proxy =
@@ -129,6 +233,8 @@ gb_editor_code_assistant_parse (gpointer user_data)
gchar *path;
gchar *text;
+ ENTRY;
+
g_return_val_if_fail (GB_IS_EDITOR_TAB (tab), G_SOURCE_REMOVE);
priv = tab->priv;
@@ -163,7 +269,7 @@ gb_editor_code_assistant_parse (gpointer user_data)
g_free (path);
g_free (text);
- return G_SOURCE_REMOVE;
+ RETURN (G_SOURCE_REMOVE);
}
static void
@@ -198,7 +304,6 @@ void
gb_editor_code_assistant_init (GbEditorTab *tab)
{
GbEditorTabPrivate *priv;
- GtkSourceLanguage *language;
const gchar *lang_id;
gchar *name;
gchar *path;
@@ -210,11 +315,10 @@ gb_editor_code_assistant_init (GbEditorTab *tab)
priv = tab->priv;
- language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (priv->document));
- if (!language)
+ lang_id = get_language (tab->priv->source_view);
+ if (!lang_id)
EXIT;
- lang_id = gtk_source_language_get_id (language);
name = g_strdup_printf ("org.gnome.CodeAssist.v1.%s", lang_id);
path = g_strdup_printf ("/org/gnome/CodeAssist/v1/%s", lang_id);
diff --git a/src/editor/gb-editor-tab.c b/src/editor/gb-editor-tab.c
index c6541ee..d077428 100644
--- a/src/editor/gb-editor-tab.c
+++ b/src/editor/gb-editor-tab.c
@@ -1086,9 +1086,6 @@ transform_file_to_language (GBinding *binding,
settings = gb_editor_settings_new_for_language (lang_id);
gb_editor_tab_set_settings (tab, settings);
g_object_unref (settings);
-
-
- gb_editor_code_assistant_init (tab);
}
g_free (filename);
diff --git a/src/gca/gca-structs.c b/src/gca/gca-structs.c
new file mode 100644
index 0000000..c8ab4b7
--- /dev/null
+++ b/src/gca/gca-structs.c
@@ -0,0 +1,105 @@
+/* gca-structs.c
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 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 "gb-log.h"
+#include "gca-structs.h"
+
+static void
+gca_diagnostic_destroy (gpointer data)
+{
+ GcaDiagnostic *diag = data;
+
+ if (diag)
+ {
+ g_array_unref (diag->fixits);
+ g_array_unref (diag->locations);
+ g_free (diag->message);
+ }
+}
+
+static void
+gca_fixit_destroy (gpointer data)
+{
+ GcaFixit *fixit = data;
+
+ if (fixit)
+ g_free (fixit->value);
+}
+
+GArray *
+gca_diagnostics_from_variant (GVariant *variant)
+{
+ GVariantIter iter;
+ GArray *ret;
+ GVariantIter *b;
+ GVariantIter *c;
+ gchar *d;
+ guint a;
+
+ ret = g_array_new (FALSE, FALSE, sizeof (GcaDiagnostic));
+
+ g_array_set_clear_func (ret, gca_diagnostic_destroy);
+
+ g_variant_iter_init (&iter, variant);
+
+ while (g_variant_iter_loop (&iter, "(ua((x(xx)(xx))s)a(x(xx)(xx))s)",
+ &a, &b, &c, &d))
+ {
+ GcaDiagnostic diag = { 0 };
+ gint64 x1, x2, x3, x4, x5;
+ gchar *e;
+
+ diag.severity = a;
+ diag.fixits = g_array_new (FALSE, FALSE, sizeof (GcaFixit));
+ diag.locations = g_array_new (FALSE, FALSE, sizeof (GcaSourceRange));
+ diag.message = g_strdup (d);
+
+ g_array_set_clear_func (diag.fixits, gca_fixit_destroy);
+
+ while (g_variant_iter_next (b, "((x(xx)(xx))s)", &x1, &x2, &x3, &x4, &x5, &e))
+ {
+ GcaFixit fixit = {{ 0 }};
+
+ fixit.range.file = x1;
+ fixit.range.begin.line = x2 - 1;
+ fixit.range.begin.column = x3 - 1;
+ fixit.range.end.line = x4 - 1;
+ fixit.range.end.column = x5 - 1;
+ fixit.value = g_strdup (e);
+
+ g_array_append_val (diag.fixits, fixit);
+ }
+
+ while (g_variant_iter_next (c, "(x(xx)(xx))", &x1, &x2, &x3, &x4, &x5))
+ {
+ GcaSourceRange range = { 0 };
+
+ range.file = x1;
+ range.begin.line = x2 - 1;
+ range.begin.column = x3 - 1;
+ range.end.line = x4 - 1;
+ range.end.column = x5 - 1;
+
+ g_array_append_val (diag.locations, range);
+ }
+
+ g_array_append_val (ret, diag);
+ }
+
+ return ret;
+}
diff --git a/src/gca/gca-structs.h b/src/gca/gca-structs.h
new file mode 100644
index 0000000..57b8219
--- /dev/null
+++ b/src/gca/gca-structs.h
@@ -0,0 +1,67 @@
+/* gca-structs.h
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 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 GCA_STRUCTS_H
+#define GCA_STRUCTS_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+ GCA_SEVERITY_NONE,
+ GCA_SEVERITY_INFO,
+ GCA_SEVERITY_WARNING,
+ GCA_SEVERITY_DEPRECATED,
+ GCA_SEVERITY_ERROR,
+ GCA_SEVERITY_FATAL,
+} GcaSeverity;
+
+typedef struct
+{
+ guint64 line;
+ guint64 column;
+} GcaSourceLocation;
+
+typedef struct
+{
+ gint64 file;
+ GcaSourceLocation begin;
+ GcaSourceLocation end;
+} GcaSourceRange;
+
+typedef struct
+{
+ GcaSourceRange range;
+ gchar *value;
+} GcaFixit;
+
+typedef struct
+{
+ GcaSeverity severity;
+ GArray *fixits;
+ GArray *locations;
+ gchar *message;
+} GcaDiagnostic;
+
+GArray *gca_diagnostics_from_variant (GVariant *variant);
+
+G_END_DECLS
+
+#endif /* GCA_STRUCTS_H */
diff --git a/src/gnome-builder.mk b/src/gnome-builder.mk
index 756a0e6..c14c415 100644
--- a/src/gnome-builder.mk
+++ b/src/gnome-builder.mk
@@ -81,6 +81,8 @@ libgnome_builder_la_SOURCES = \
src/gca/gca-diagnostics.h \
src/gca/gca-service.c \
src/gca/gca-service.h \
+ src/gca/gca-structs.c \
+ src/gca/gca-structs.h \
src/markdown/gs-markdown.c \
src/markdown/gs-markdown.h \
src/markdown/gb-markdown-preview.c \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]