[gnome-builder] GbEditorFrame: move next/previous diagnostic with ctrl+shift+(n/p)



commit e060ce93f257e1da6437e272371154bf765b5f30
Author: Christian Hergert <christian hergert me>
Date:   Sun Jan 11 19:08:03 2015 -0800

    GbEditorFrame: move next/previous diagnostic with ctrl+shift+(n/p)
    
    For languages that support diagnostics, this will allow you to move to
    the next or previous diagnostic as reported from code-assistance.

 src/editor/gb-editor-frame.c          |  173 +++++++++++++++++++++++++++++++++
 src/resources/keybindings/default.ini |    2 +
 src/resources/keybindings/vim.ini     |    2 +
 3 files changed, 177 insertions(+), 0 deletions(-)
---
diff --git a/src/editor/gb-editor-frame.c b/src/editor/gb-editor-frame.c
index 5d5cf3c..74d0737 100644
--- a/src/editor/gb-editor-frame.c
+++ b/src/editor/gb-editor-frame.c
@@ -1087,6 +1087,157 @@ gb_editor_frame_grab_focus (GtkWidget *widget)
 }
 
 static void
+gb_editor_frame_scroll_to_line (GbEditorFrame *self,
+                                guint          line,
+                                guint          offset)
+{
+  GtkTextBuffer *buffer;
+  GtkTextView *text_view;
+  GtkTextIter iter;
+
+  g_return_if_fail (GB_IS_EDITOR_FRAME (self));
+
+  buffer = GTK_TEXT_BUFFER (self->priv->document);
+  text_view = GTK_TEXT_VIEW (self->priv->source_view);
+
+  gb_gtk_text_buffer_get_iter_at_line_and_offset (buffer, &iter, line, offset);
+  gtk_text_buffer_select_range (buffer, &iter, &iter);
+  gb_gtk_text_view_scroll_to_iter (text_view, &iter, 0.0, TRUE, 0.0, 0.5);
+}
+
+static void
+gb_editor_frame_next_diagnostic (GbEditorFrame *self)
+{
+  GbSourceCodeAssistant *assistant;
+  GtkTextMark *mark;
+  GtkTextIter iter;
+  guint current_line;
+  GArray *ar;
+  guint i;
+
+  g_return_if_fail (GB_IS_EDITOR_FRAME (self));
+
+  assistant = gb_editor_document_get_code_assistant (self->priv->document);
+  ar = gb_source_code_assistant_get_diagnostics (assistant);
+  mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (self->priv->document));
+  gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (self->priv->document),
+                                    &iter, mark);
+  current_line = gtk_text_iter_get_line (&iter);
+
+  if (ar)
+    {
+      for (i = 0; i < ar->len; i++)
+        {
+          GcaDiagnostic *diag;
+          guint j;
+
+          diag = &g_array_index (ar, GcaDiagnostic, i);
+
+          for (j = 0; j < diag->locations->len; j++)
+            {
+              GcaSourceRange *range;
+
+              range = &g_array_index (diag->locations, GcaSourceRange, j);
+
+              if (range->begin.line > current_line)
+                {
+                  gb_editor_frame_scroll_to_line (self,
+                                                  range->begin.line,
+                                                  range->begin.column);
+                  goto cleanup;
+                }
+            }
+        }
+
+      /* wrap around to first diagnostic */
+      if (ar->len > 0)
+        {
+          GcaDiagnostic *diag;
+
+          diag = &g_array_index (ar, GcaDiagnostic, 0);
+
+          if (diag->locations->len > 0)
+            {
+              GcaSourceRange *range;
+
+              range = &g_array_index (diag->locations, GcaSourceRange, 0);
+              gb_editor_frame_scroll_to_line (self, range->begin.line,
+                                              range->begin.column);
+            }
+        }
+
+cleanup:
+      g_array_unref (ar);
+    }
+}
+
+static void
+gb_editor_frame_previous_diagnostic (GbEditorFrame *self)
+{
+  GbSourceCodeAssistant *assistant;
+  GtkTextMark *mark;
+  GtkTextIter iter;
+  guint current_line;
+  GArray *ar;
+  gint i;
+
+  g_return_if_fail (GB_IS_EDITOR_FRAME (self));
+
+  assistant = gb_editor_document_get_code_assistant (self->priv->document);
+  ar = gb_source_code_assistant_get_diagnostics (assistant);
+  mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (self->priv->document));
+  gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (self->priv->document),
+                                    &iter, mark);
+  current_line = gtk_text_iter_get_line (&iter);
+
+  if (ar)
+    {
+      for (i = 0; i < ar->len; i++)
+        {
+          GcaDiagnostic *diag;
+          guint j;
+
+          diag = &g_array_index (ar, GcaDiagnostic, ar->len-i-1);
+
+          for (j = 0; j < diag->locations->len; j++)
+            {
+              GcaSourceRange *range;
+
+              range = &g_array_index (diag->locations, GcaSourceRange, j);
+
+              if (range->begin.line < current_line)
+                {
+                  gb_editor_frame_scroll_to_line (self,
+                                                  range->begin.line,
+                                                  range->begin.column);
+                  goto cleanup;
+                }
+            }
+        }
+
+      /* wrap around to last diagnostic */
+      if (ar->len > 0)
+        {
+          GcaDiagnostic *diag;
+
+          diag = &g_array_index (ar, GcaDiagnostic, ar->len-1);
+
+          if (diag->locations->len > 0)
+            {
+              GcaSourceRange *range;
+
+              range = &g_array_index (diag->locations, GcaSourceRange, 0);
+              gb_editor_frame_scroll_to_line (self, range->begin.line,
+                                              range->begin.column);
+            }
+        }
+    }
+
+cleanup:
+  g_clear_pointer (&ar, g_array_unref);
+}
+
+static void
 gb_editor_frame_reformat_activate (GSimpleAction *action,
                                    GVariant      *parameter,
                                    gpointer       user_data)
@@ -1099,6 +1250,26 @@ gb_editor_frame_reformat_activate (GSimpleAction *action,
 }
 
 static void
+gb_editor_frame_next_diagnostic_activate (GSimpleAction *action,
+                                          GVariant      *parameter,
+                                          gpointer       user_data)
+{
+  GbEditorFrame *self = user_data;
+  g_return_if_fail (GB_IS_EDITOR_FRAME (self));
+  gb_editor_frame_next_diagnostic (self);
+}
+
+static void
+gb_editor_frame_previous_diagnostic_activate (GSimpleAction *action,
+                                              GVariant      *parameter,
+                                              gpointer       user_data)
+{
+  GbEditorFrame *self = user_data;
+  g_return_if_fail (GB_IS_EDITOR_FRAME (self));
+  gb_editor_frame_previous_diagnostic (self);
+}
+
+static void
 gb_editor_frame_scroll (GbEditorFrame    *self,
                         GtkDirectionType  dir)
 {
@@ -1406,6 +1577,8 @@ gb_editor_frame_init (GbEditorFrame *self)
     { "reformat", gb_editor_frame_reformat_activate },
     { "scroll-up", gb_editor_frame_scroll_up },
     { "scroll-down", gb_editor_frame_scroll_down },
+    { "next-diagnostic", gb_editor_frame_next_diagnostic_activate },
+    { "previous-diagnostic", gb_editor_frame_previous_diagnostic_activate },
   };
   GSimpleActionGroup *actions;
 
diff --git a/src/resources/keybindings/default.ini b/src/resources/keybindings/default.ini
index fe4b989..40a5d5f 100644
--- a/src/resources/keybindings/default.ini
+++ b/src/resources/keybindings/default.ini
@@ -18,6 +18,8 @@ find = <Control>F
 reformat = <Control><Shift>R
 scroll-down = <Control>E
 scroll-up = <Control>Y
+next-diagnostic = <Control><Shift>N
+previous-diagnostic = <Control><Shift>P
 
 [editor-view]
 toggle-split = <Control><Shift>J
diff --git a/src/resources/keybindings/vim.ini b/src/resources/keybindings/vim.ini
index 34f6b4a..8ea77db 100644
--- a/src/resources/keybindings/vim.ini
+++ b/src/resources/keybindings/vim.ini
@@ -17,6 +17,8 @@ open = <Control><Shift>O
 reformat = <Control><Shift>R
 scroll-down = <Control>E
 scroll-up = <Control>Y
+next-diagnostic = <Control><Shift>N
+previous-diagnostic = <Control><Shift>P
 
 [editor-view]
 toggle-split = <Control><Shift>J


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]