[gnome-builder/editor-layout] editor: add reformat command for editor tab.
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/editor-layout] editor: add reformat command for editor tab.
- Date: Mon, 1 Dec 2014 09:41:33 +0000 (UTC)
commit 6aa4b4b09770339164046fa0f5535762552acafe
Author: Christian Hergert <christian hergert me>
Date: Mon Dec 1 01:41:26 2014 -0800
editor: add reformat command for editor tab.
src/editor/gb-editor-document.h | 1 +
src/editor/gb-editor-frame.c | 97 ++++++++++++++++++++++++++++++++++++++
src/editor/gb-editor-frame.h | 1 +
src/editor/gb-editor-tab.c | 11 ++++
src/editor/gb-editor-tab.h | 1 +
src/editor/gb-editor-workspace.c | 14 ++++++
6 files changed, 125 insertions(+), 0 deletions(-)
---
diff --git a/src/editor/gb-editor-document.h b/src/editor/gb-editor-document.h
index f0e556b..b7fd268 100644
--- a/src/editor/gb-editor-document.h
+++ b/src/editor/gb-editor-document.h
@@ -84,6 +84,7 @@ void gb_editor_document_save_async (GbEditorDocument
gboolean gb_editor_document_save_finish (GbEditorDocument *document,
GAsyncResult *result,
GError **error);
+void gb_editor_document_reformat (GbEditorDocument *document);
G_END_DECLS
diff --git a/src/editor/gb-editor-frame.c b/src/editor/gb-editor-frame.c
index 4b05ef9..833f24d 100644
--- a/src/editor/gb-editor-frame.c
+++ b/src/editor/gb-editor-frame.c
@@ -23,6 +23,7 @@
#include "gb-editor-frame.h"
#include "gb-editor-frame-private.h"
#include "gb-log.h"
+#include "gb-source-formatter.h"
#include "gb-string.h"
#include "gb-widget.h"
#include "gb-workbench.h"
@@ -267,6 +268,102 @@ gb_editor_frame_on_search_occurrences_notify (GbEditorFrame *frame,
gb_editor_frame_update_search_position_label (frame);
}
+void
+gb_editor_frame_reformat (GbEditorFrame *frame)
+{
+ GbEditorFramePrivate *priv;
+ GbSourceFormatter *formatter;
+ GtkSourceLanguage *language;
+ GtkTextBuffer *buffer;
+ GtkTextIter begin;
+ GtkTextIter end;
+ GtkTextIter iter;
+ GtkTextMark *insert;
+ gboolean fragment = TRUE;
+ GError *error = NULL;
+ gchar *input = NULL;
+ gchar *output = NULL;
+ guint line_number;
+ guint char_offset;
+
+ ENTRY;
+
+ /*
+ * TODO: Do this asynchronously, add tab state, propagate errors.
+ */
+
+ g_return_if_fail (GB_IS_EDITOR_FRAME (frame));
+
+ priv = frame->priv;
+
+ buffer = GTK_TEXT_BUFFER (priv->document);
+
+ gtk_text_buffer_get_selection_bounds (buffer, &begin, &end);
+
+ if (gtk_text_iter_compare (&begin, &end) == 0)
+ {
+ gtk_text_buffer_get_bounds (buffer, &begin, &end);
+ fragment = FALSE;
+ }
+
+ input = gtk_text_buffer_get_text (buffer, &begin, &end, TRUE);
+
+ insert = gtk_text_buffer_get_insert (buffer);
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
+ char_offset = gtk_text_iter_get_line_offset (&iter);
+ line_number = gtk_text_iter_get_line (&iter);
+
+ language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (buffer));
+ formatter = gb_source_formatter_new_from_language (language);
+
+ if (!gb_source_formatter_format (formatter, input, fragment, NULL, &output,
+ &error))
+ {
+ g_warning ("%s", error->message);
+ g_clear_error (&error);
+ GOTO (cleanup);
+ }
+
+ gtk_text_buffer_begin_user_action (buffer);
+
+ /* TODO: Keep the cursor on same CXCursor from Clang instead of the
+ * same character offset within the buffer. We probably want
+ * to defer this to the formatter API since it will be language
+ * specific.
+ */
+
+ gtk_text_buffer_delete (buffer, &begin, &end);
+ gtk_text_buffer_insert (buffer, &begin, output, -1);
+
+ if (line_number >= gtk_text_buffer_get_line_count (buffer))
+ {
+ gtk_text_buffer_get_bounds (buffer, &begin, &iter);
+ goto select_range;
+ }
+
+ gtk_text_buffer_get_iter_at_line (buffer, &iter, line_number);
+ gtk_text_iter_forward_to_line_end (&iter);
+
+ if (gtk_text_iter_get_line (&iter) != line_number)
+ gtk_text_iter_backward_char (&iter);
+ else if (gtk_text_iter_get_line_offset (&iter) > char_offset)
+ gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, line_number, char_offset);
+
+select_range:
+ gtk_text_buffer_select_range (buffer, &iter, &iter);
+ gtk_text_buffer_end_user_action (buffer);
+
+ gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->source_view), &iter,
+ 0.25, TRUE, 0.5, 0.5);
+
+cleanup:
+ g_free (input);
+ g_free (output);
+ g_clear_object (&formatter);
+
+ EXIT;
+}
+
/**
* gb_editor_frame_on_cursor_moved:
*
diff --git a/src/editor/gb-editor-frame.h b/src/editor/gb-editor-frame.h
index 2c006ba..03722f3 100644
--- a/src/editor/gb-editor-frame.h
+++ b/src/editor/gb-editor-frame.h
@@ -59,6 +59,7 @@ void gb_editor_frame_set_document (GbEditorFrame *frame,
GbEditorDocument *document);
void gb_editor_frame_find (GbEditorFrame *frame,
const gchar *search_text);
+void gb_editor_frame_reformat (GbEditorFrame *frame);
G_END_DECLS
diff --git a/src/editor/gb-editor-tab.c b/src/editor/gb-editor-tab.c
index 8b7c25e..91229cc 100644
--- a/src/editor/gb-editor-tab.c
+++ b/src/editor/gb-editor-tab.c
@@ -504,6 +504,17 @@ gb_editor_tab_find (GbEditorTab *tab)
gb_editor_frame_find (frame, NULL);
}
+void
+gb_editor_tab_reformat (GbEditorTab *tab)
+{
+ GbEditorFrame *frame;
+
+ g_return_if_fail (GB_IS_EDITOR_TAB (tab));
+
+ frame = gb_editor_tab_get_last_frame (tab);
+ gb_editor_frame_reformat (frame);
+}
+
static void
gb_editor_tab_constructed (GObject *object)
{
diff --git a/src/editor/gb-editor-tab.h b/src/editor/gb-editor-tab.h
index f35627f..bd769f9 100644
--- a/src/editor/gb-editor-tab.h
+++ b/src/editor/gb-editor-tab.h
@@ -61,6 +61,7 @@ void gb_editor_tab_scroll_up (GbEditorTab *tab);
void gb_editor_tab_scroll_down (GbEditorTab *tab);
void gb_editor_tab_toggle_split (GbEditorTab *tab);
void gb_editor_tab_find (GbEditorTab *tab);
+void gb_editor_tab_reformat (GbEditorTab *tab);
void gb_editor_tab_scroll_to_line (GbEditorTab *tab,
guint line,
guint line_offset);
diff --git a/src/editor/gb-editor-workspace.c b/src/editor/gb-editor-workspace.c
index e1b07e3..c40a90e 100644
--- a/src/editor/gb-editor-workspace.c
+++ b/src/editor/gb-editor-workspace.c
@@ -128,6 +128,19 @@ find_tab (GSimpleAction *action,
}
static void
+reformat_tab (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GbEditorWorkspace *workspace = user_data;
+ GbTab *tab;
+
+ tab = gb_tab_grid_get_active (workspace->priv->tab_grid);
+ if (GB_IS_EDITOR_TAB (tab))
+ gb_editor_tab_reformat (GB_EDITOR_TAB (tab));
+}
+
+static void
close_tab (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
@@ -284,6 +297,7 @@ gb_editor_workspace_init (GbEditorWorkspace *workspace)
{ "scroll-down", scroll_down_tab },
{ "toggle-split", toggle_split_tab },
{ "find", find_tab },
+ { "reformat", reformat_tab },
};
workspace->priv = gb_editor_workspace_get_instance_private (workspace);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]