[gnome-builder] plugins/c-pack: Re-enable C indenter
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] plugins/c-pack: Re-enable C indenter
- Date: Thu, 28 Jul 2022 21:09:44 +0000 (UTC)
commit 1ac0e2027edc7dde48aa6e9dc4768346e60a4083
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Thu Jul 28 09:00:04 2022 -0300
plugins/c-pack: Re-enable C indenter
Rewrite a good chunk of the C indenter to work with GSV5 APIs, and
re-enable it. Most of the diff is composed or shuffling functions
around, and replacing `GtkTextIter *begin, *end` to simply `*iter`.
Other than that, the core logic is about the same, so it shouldn't
require re-learning how the indenter works entirely.
src/plugins/c-pack/c-pack-plugin.c | 6 +-
src/plugins/c-pack/ide-c-indenter.c | 641 +++++++++++++++++++-----------------
src/plugins/c-pack/meson.build | 4 +-
3 files changed, 339 insertions(+), 312 deletions(-)
---
diff --git a/src/plugins/c-pack/c-pack-plugin.c b/src/plugins/c-pack/c-pack-plugin.c
index a0e03e4b2..e95747e1e 100644
--- a/src/plugins/c-pack/c-pack-plugin.c
+++ b/src/plugins/c-pack/c-pack-plugin.c
@@ -25,20 +25,16 @@
#include <libide-editor.h>
#include <libide-sourceview.h>
-#if 0
#include "ide-c-indenter.h"
-#endif
#include "cpack-completion-provider.h"
#include "cpack-editor-page-addin.h"
_IDE_EXTERN void
_ide_c_pack_register_types (PeasObjectModule *module)
{
-#if 0
peas_object_module_register_extension_type (module,
- IDE_TYPE_INDENTER,
+ GTK_SOURCE_TYPE_INDENTER,
IDE_TYPE_C_INDENTER);
-#endif
peas_object_module_register_extension_type (module,
IDE_TYPE_EDITOR_PAGE_ADDIN,
CPACK_TYPE_EDITOR_PAGE_ADDIN);
diff --git a/src/plugins/c-pack/ide-c-indenter.c b/src/plugins/c-pack/ide-c-indenter.c
index d9725fe2a..dfa236271 100644
--- a/src/plugins/c-pack/ide-c-indenter.c
+++ b/src/plugins/c-pack/ide-c-indenter.c
@@ -33,6 +33,17 @@
(iter), \
gtk_text_iter_get_line(other))
+typedef enum
+{
+ IDE_C_INDENT_ACTION_ALIGN_PARAMETERS,
+ IDE_C_INDENT_ACTION_CLOSE_COMMENT,
+ IDE_C_INDENT_ACTION_INDENT_LINE,
+ IDE_C_INDENT_ACTION_UNINDENT_CASE_OR_LABEL,
+ IDE_C_INDENT_ACTION_UNINDENT_CLOSING_BRACE,
+ IDE_C_INDENT_ACTION_UNINDENT_HASH,
+ IDE_C_INDENT_ACTION_UNINDENT_OPENING_BRACE,
+} IdeCIndentAction;
+
struct _IdeCIndenter
{
IdeObject parent_instance;
@@ -47,15 +58,17 @@ struct _IdeCIndenter
gint extra_label_indent;
gint case_indent;
+ IdeCIndentAction indent_action;
+
guint tab_width;
guint indent_width;
guint use_tabs : 1;
};
-static void indenter_iface_init (IdeIndenterInterface *iface);
+static void indenter_iface_init (GtkSourceIndenterInterface *iface);
G_DEFINE_FINAL_TYPE_WITH_CODE (IdeCIndenter, ide_c_indenter, IDE_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (IDE_TYPE_INDENTER, indenter_iface_init))
+ G_IMPLEMENT_INTERFACE (GTK_SOURCE_TYPE_INDENTER, indenter_iface_init))
enum {
COMMENT_NONE,
@@ -546,29 +559,30 @@ in_comment (const GtkTextIter *location,
#define GET_LINE_OFFSET(_iter) \
gtk_source_view_get_visual_column(GTK_SOURCE_VIEW(view), _iter)
-static gchar *
-c_indenter_indent (IdeCIndenter *c,
- GtkTextView *view,
- GtkTextBuffer *buffer,
- GtkTextIter *iter)
+static void
+c_indenter_indent_line (IdeCIndenter *c,
+ GtkSourceView *view,
+ GtkTextBuffer *buffer,
+ GtkTextIter *iter)
{
+ g_autoptr(GString) str = NULL;
+ GtkTextIter original_iter;
GtkTextIter cur;
GtkTextIter match_begin;
GtkTextIter copy;
gunichar ch;
- GString *str;
- gchar *ret = NULL;
gchar *last_word = NULL;
+ gint cursor_offset = 0;
gint comment_type;
IDE_ENTRY;
- g_return_val_if_fail (IDE_IS_C_INDENTER (c), NULL);
+ g_return_if_fail (IDE_IS_C_INDENTER (c));
/*
* Save our current iter position to restore it later.
*/
- cur = *iter;
+ original_iter = cur = *iter;
/*
* Move to before the character just inserted.
@@ -779,63 +793,114 @@ c_indenter_indent (IdeCIndenter *c,
}
cleanup:
- gtk_text_iter_assign (iter, &cur);
- g_free (last_word);
- ret = g_string_free (str, FALSE);
+ if (str->len > 0)
+ {
+ /*
+ * If we have additional space after where our new indentation
+ * will occur, we should chomp it up so that the text starts
+ * immediately after our new indentation.
+ *
+ * GNOME/gnome-builder#545
+ */
+ while (text_iter_isspace (iter) && !gtk_text_iter_ends_line (iter))
+ gtk_text_iter_forward_char (iter);
+ }
+
+ /*
+ * If we are inserting a newline right before a closing brace (for example
+ * after {<cursor>}, we need to indent and then maybe unindent the }.
+ */
+ if (gtk_text_iter_get_char (&original_iter) == '}')
+ {
+ GtkTextIter iter2;
+ guint offset = 0;
+
+ gtk_text_iter_assign (&iter2, &original_iter);
+ if (backward_find_matching_char (&iter2, '}'))
+ {
+ g_autoptr(GString) str2 = g_string_new (NULL);
+
+ if (line_is_whitespace_until (&iter2))
+ offset = GET_LINE_OFFSET (&iter2);
+ else if (backward_to_line_first_char (&iter2))
+ offset = GET_LINE_OFFSET (&iter2);
+ build_indent (c, offset, &iter2, str2);
+ g_string_prepend (str2, "\n");
+ g_string_prepend (str2, str->str);
+
+ cursor_offset = -(str2->len - str->len);
+
+ g_string_free (str, TRUE);
+ str = g_steal_pointer (&str2);
+ }
+ }
+
+ if (str->len > 0)
+ {
+ gtk_text_iter_assign (iter, &cur);
+ gtk_text_buffer_insert (buffer, iter, str->str, str->len);
+ gtk_text_iter_forward_chars (iter, cursor_offset);
+ gtk_text_buffer_place_cursor (buffer, iter);
+ }
- IDE_RETURN (ret);
+ IDE_EXIT;
}
-static gchar *
-maybe_close_comment (IdeCIndenter *c,
- GtkTextIter *begin,
- GtkTextIter *end)
+static void
+maybe_close_comment (IdeCIndenter *c,
+ GtkTextBuffer *buffer,
+ GtkTextIter *iter)
{
GtkTextIter copy;
GtkTextIter begin_comment;
- gchar *ret = NULL;
gint comment_type;
- g_return_val_if_fail (IDE_IS_C_INDENTER (c), NULL);
- g_return_val_if_fail (begin, NULL);
- g_return_val_if_fail (end, NULL);
+ g_assert (IDE_IS_C_INDENTER (c));
+ g_assert (GTK_IS_TEXT_BUFFER (buffer));
+ g_assert (iter);
- gtk_text_iter_assign (©, begin);
+ copy = *iter;
+
+ if (!gtk_text_iter_backward_char (©))
+ return;
/*
* Walk backwards ensuring we just inserted a '/' and that it was after
* a '* ' sequence.
*/
- if (in_comment (begin, &begin_comment, &comment_type) &&
+ if (in_comment (©, &begin_comment, &comment_type) &&
(comment_type == COMMENT_C89) &&
- gtk_text_iter_backward_char (begin) &&
- ('/' == gtk_text_iter_get_char (begin)) &&
- gtk_text_iter_backward_char (begin) &&
- (' ' == gtk_text_iter_get_char (begin)) &&
- gtk_text_iter_backward_char (begin) &&
- ('*' == gtk_text_iter_get_char (begin)))
- ret = g_strdup ("*/");
- else
- gtk_text_iter_assign (begin, ©);
-
- return ret;
+ gtk_text_iter_backward_char (©) &&
+ ('/' == gtk_text_iter_get_char (©)) &&
+ gtk_text_iter_backward_char (©) &&
+ (' ' == gtk_text_iter_get_char (©)) &&
+ gtk_text_iter_backward_char (©) &&
+ ('*' == gtk_text_iter_get_char (©)))
+ {
+ gtk_text_buffer_delete (buffer, ©, iter);
+ gtk_text_buffer_insert (buffer, iter, "*/", 2);
+ gtk_text_buffer_place_cursor (buffer, iter);
+ }
}
-static gchar *
-maybe_unindent_opening_brace (IdeCIndenter *c,
- GtkTextView *view,
- GtkTextIter *begin,
- GtkTextIter *end,
- gint *cursor_offset)
+static void
+maybe_unindent_opening_brace (IdeCIndenter *c,
+ GtkTextView *view,
+ GtkTextBuffer *buffer,
+ IdeFileSettings *file_settings,
+ GtkTextIter *iter)
{
GtkTextIter copy;
+ gboolean insert_matching_brace;
g_assert (IDE_IS_C_INDENTER (c));
- g_assert (begin);
- g_assert (end);
+ g_assert (GTK_IS_TEXT_VIEW (view));
+ g_assert (GTK_IS_TEXT_BUFFER (buffer));
+ g_assert (IDE_IS_FILE_SETTINGS (file_settings));
+ g_assert (iter);
- copy = *begin;
+ copy = *iter;
/*
* Make sure we just inserted a { and then move before it.
@@ -844,7 +909,9 @@ maybe_unindent_opening_brace (IdeCIndenter *c,
if (!gtk_text_iter_backward_char (©) ||
('{' != gtk_text_iter_get_char (©)) ||
!gtk_text_iter_backward_char (©))
- return NULL;
+ return;
+
+ insert_matching_brace = ide_file_settings_get_insert_matching_brace (file_settings);
/*
* Find the opening of the parent scope.
@@ -853,8 +920,9 @@ maybe_unindent_opening_brace (IdeCIndenter *c,
*/
if (line_is_whitespace_until (©) && backward_find_matching_char (©, '}'))
{
+ g_autoptr(GString) str = NULL;
+ GtkTextIter line_start;
guint offset;
- GString *str;
backward_to_line_first_char (©);
@@ -863,140 +931,116 @@ maybe_unindent_opening_brace (IdeCIndenter *c,
build_indent (c, offset + get_post_scope_indent(c) + get_pre_scope_indent (c), ©, str);
g_string_append_c (str, '{');
- if (ide_source_view_get_insert_matching_brace (IDE_SOURCE_VIEW (view)))
- {
- g_string_append_c (str, '}');
- *cursor_offset = -1;
- }
+ if (insert_matching_brace)
+ g_string_append_c (str, '}');
- gtk_text_iter_set_line_offset (begin, 0);
+ line_start = *iter;
+ gtk_text_iter_set_line_offset (&line_start, 0);
+ gtk_text_buffer_delete (buffer, &line_start, iter);
+ gtk_text_buffer_insert (buffer, iter, str->str, str->len);
- return g_string_free (str, FALSE);
- }
+ if (insert_matching_brace)
+ gtk_text_iter_backward_chars (iter, 1);
- if (ide_source_view_get_insert_matching_brace (IDE_SOURCE_VIEW (view)))
+ gtk_text_buffer_place_cursor (buffer, iter);
+ }
+ else if (insert_matching_brace)
{
- *cursor_offset = -1;
- return g_strdup ("}");
+ gtk_text_buffer_insert (buffer, iter, "}", 1);
+ gtk_text_iter_backward_chars (iter, 1);
+ gtk_text_buffer_place_cursor (buffer, iter);
}
-
- return NULL;
}
-static gchar *
-maybe_unindent_closing_brace (IdeCIndenter *c,
- GtkTextView *view,
- GtkTextIter *begin,
- GtkTextIter *end)
+static void
+maybe_unindent_closing_brace (IdeCIndenter *c,
+ GtkTextView *view,
+ GtkTextBuffer *buffer,
+ GtkTextIter *iter)
{
- GtkTextIter saved;
- gchar *ret = NULL;
+ GtkTextIter start;
+ GtkTextIter end;
IDE_ENTRY;
- g_return_val_if_fail (IDE_IS_C_INDENTER (c), NULL);
- g_return_val_if_fail (begin, NULL);
- g_return_val_if_fail (end, NULL);
+ g_assert (IDE_IS_C_INDENTER (c));
+ g_assert (GTK_IS_TEXT_VIEW (view));
+ g_assert (GTK_IS_TEXT_BUFFER (buffer));
+ g_assert (iter);
- gtk_text_iter_assign (&saved, begin);
+ start = end = *iter;
- if (gtk_text_iter_backward_char (begin) &&
- gtk_text_iter_backward_char (end) &&
- backward_find_matching_char (begin, '}') &&
- line_is_whitespace_until (end) &&
- ((gtk_text_iter_get_offset (begin) + 1) !=
- gtk_text_iter_get_offset (end)))
+ if (gtk_text_iter_backward_char (&start) &&
+ gtk_text_iter_backward_char (&end) &&
+ backward_find_matching_char (&start, '}') &&
+ line_is_whitespace_until (&end) &&
+ (gtk_text_iter_get_offset (&start) + 1) != gtk_text_iter_get_offset (&end))
{
- GString *str;
+ g_autoptr(GString) str = NULL;
guint offset;
/*
* Handle the case where { is not the first non-whitespace
* character on the line.
*/
- if (!starts_line_space_ok (begin))
- backward_to_line_first_char (begin);
+ if (!starts_line_space_ok (&start))
+ backward_to_line_first_char (&start);
- offset = GET_LINE_OFFSET (begin);
+ offset = GET_LINE_OFFSET (&start);
str = g_string_new (NULL);
- build_indent (c, offset, begin, str);
+ build_indent (c, offset, &start, str);
g_string_append_c (str, '}');
- gtk_text_iter_assign (begin, &saved);
- while (!gtk_text_iter_starts_line (begin))
- gtk_text_iter_backward_char (begin);
+ start = *iter;
+ while (!gtk_text_iter_starts_line (&start))
+ gtk_text_iter_backward_char (&start);
- gtk_text_iter_assign (end, &saved);
+ end = *iter;
- ret = g_string_free (str, FALSE);
- }
+ gtk_text_buffer_delete (buffer, &start, &end);
+ gtk_text_buffer_insert (buffer, &start, str->str, str->len);
- if (!ret)
- {
- gtk_text_iter_assign (begin, &saved);
- gtk_text_iter_assign (end, &saved);
+ *iter = start;
}
- IDE_RETURN (ret);
+ IDE_EXIT;
}
-static gchar *
-maybe_unindent_hash (IdeCIndenter *c,
- GtkTextIter *begin,
- GtkTextIter *end)
+static void
+maybe_unindent_hash (IdeCIndenter *c,
+ GtkTextBuffer *buffer,
+ GtkTextIter *iter)
{
- GtkTextIter saved;
- gchar *ret = NULL;
+ GtkTextIter start;
- g_return_val_if_fail (IDE_IS_C_INDENTER (c), NULL);
- g_return_val_if_fail (begin, NULL);
- g_return_val_if_fail (end, NULL);
+ g_assert (IDE_IS_C_INDENTER (c));
+ g_assert (GTK_IS_TEXT_BUFFER (buffer));
+ g_assert (iter);
- gtk_text_iter_assign (&saved, begin);
+ start = *iter;
- if (gtk_text_iter_backward_char (begin) &&
- ('#' == gtk_text_iter_get_char (begin)) &&
- line_is_whitespace_until (begin))
+ if (gtk_text_iter_backward_char (&start) &&
+ ('#' == gtk_text_iter_get_char (&start)) &&
+ line_is_whitespace_until (&start))
{
if (c->directive_indent == G_MININT)
{
- while (!gtk_text_iter_starts_line (begin))
- gtk_text_iter_backward_char (begin);
- ret = g_strdup ("#");
+ while (!gtk_text_iter_starts_line (&start))
+ gtk_text_iter_backward_char (&start);
+
+ /* Delete whitespace before the hash character */
+ gtk_text_iter_backward_char (iter);
+ gtk_text_buffer_delete (buffer, &start, iter);
+
+ /* Return cursor to after the hash character */
+ gtk_text_iter_forward_char (iter);
+ gtk_text_buffer_place_cursor (buffer, iter);
}
else
{
/* TODO: Handle indent when not fully unindenting. */
}
}
-
- if (!ret)
- gtk_text_iter_assign (begin, &saved);
-
- return ret;
-}
-
-static gboolean
-line_starts_with_fuzzy (const GtkTextIter *iter,
- const gchar *prefix)
-{
- GtkTextIter begin;
- GtkTextIter end;
- gboolean ret;
- gchar *line;
-
- ITER_INIT_LINE_START (&begin, iter);
- ITER_INIT_LINE_START (&end, iter);
-
- while (!gtk_text_iter_ends_line (&end))
- if (!gtk_text_iter_forward_char (&end))
- return FALSE;
-
- line = g_strstrip (gtk_text_iter_get_slice (&begin, &end));
- ret = g_str_has_prefix (line, prefix);
- g_free (line);
-
- return ret;
}
static gchar *
@@ -1030,13 +1074,15 @@ format_parameter (const Parameter *param,
return g_string_free (str, FALSE);
}
-static gchar *
-format_parameters (GtkTextIter *begin,
- GSList *params)
+static void
+format_parameters (GSList *params,
+ GtkTextBuffer *buffer,
+ GtkTextIter *begin,
+ GtkTextIter *end)
{
+ g_autoptr(GString) str = NULL;
GtkTextIter line_start;
GtkTextIter first_char;
- GString *str;
GSList *iter;
gchar *slice;
gchar *join_str;
@@ -1086,53 +1132,71 @@ format_parameters (GtkTextIter *begin,
g_free (join_str);
- return g_string_free (str, FALSE);
+ gtk_text_buffer_delete (buffer, begin, end);
+ gtk_text_buffer_insert (buffer, begin, str->str, str->len);
}
-static gchar *
-maybe_align_parameters (IdeCIndenter *c,
- GtkTextIter *begin,
- GtkTextIter *end)
+static void
+maybe_align_parameters (IdeCIndenter *c,
+ GtkTextBuffer *buffer,
+ GtkTextIter *iter)
{
+ g_autofree gchar *text = NULL;
GtkTextIter match_begin;
- GtkTextIter copy;
+ GtkTextIter start, end;
GSList *params = NULL;
- gchar *ret = NULL;
- gchar *text = NULL;
IDE_ENTRY;
- g_return_val_if_fail (IDE_IS_C_INDENTER (c), NULL);
- g_return_val_if_fail (begin, NULL);
- g_return_val_if_fail (end, NULL);
+ g_assert (IDE_IS_C_INDENTER (c));
+ g_assert (GTK_IS_TEXT_BUFFER (buffer));
+ g_assert (iter);
+
+ if (in_comment (iter, &match_begin, NULL))
+ IDE_RETURN ();
- if (in_comment (begin, &match_begin, NULL))
- IDE_RETURN (NULL);
+ start = end = *iter;
- gtk_text_iter_assign (©, begin);
+ if (!gtk_text_iter_backward_char (&start))
+ IDE_RETURN ();
- if (gtk_text_iter_backward_char (begin) &&
- backward_find_matching_char (begin, ')') &&
- gtk_text_iter_forward_char (begin) &&
- gtk_text_iter_backward_char (end) &&
- (gtk_text_iter_compare (begin, end) < 0) &&
- (text = gtk_text_iter_get_slice (begin, end)) &&
+ if (gtk_text_iter_backward_char (&start) &&
+ backward_find_matching_char (&start, ')') &&
+ gtk_text_iter_forward_char (&start) &&
+ gtk_text_iter_backward_char (&end) &&
+ (gtk_text_iter_compare (&start, &end) < 0) &&
+ (text = gtk_text_iter_get_slice (&start, &end)) &&
(params = parse_parameters (text)) &&
(params->next != NULL))
- ret = format_parameters (begin, params);
+ format_parameters (params, buffer, &start, &end);
g_slist_foreach (params, (GFunc)parameter_free, NULL);
g_slist_free (params);
- if (!ret)
- {
- gtk_text_iter_assign (begin, ©);
- gtk_text_iter_assign (end, ©);
- }
+ IDE_EXIT;
+}
- g_free (text);
+static gboolean
+line_starts_with_fuzzy (const GtkTextIter *iter,
+ const gchar *prefix)
+{
+ GtkTextIter begin;
+ GtkTextIter end;
+ gboolean ret;
+ gchar *line;
+
+ ITER_INIT_LINE_START (&begin, iter);
+ ITER_INIT_LINE_START (&end, iter);
- IDE_RETURN (ret);
+ while (!gtk_text_iter_ends_line (&end))
+ if (!gtk_text_iter_forward_char (&end))
+ return FALSE;
+
+ line = g_strstrip (gtk_text_iter_get_slice (&begin, &end));
+ ret = g_str_has_prefix (line, prefix);
+ g_free (line);
+
+ return ret;
}
static gboolean
@@ -1214,86 +1278,112 @@ line_is_label (const GtkTextIter *line)
return (count == 1);
}
-static gchar *
-maybe_unindent_case_label (IdeCIndenter *c,
- GtkTextView *view,
- GtkTextIter *begin,
- GtkTextIter *end)
+static void
+maybe_unindent_case_label (IdeCIndenter *c,
+ GtkTextView *view,
+ GtkTextBuffer *buffer,
+ GtkTextIter *iter)
{
GtkTextIter match_begin;
- GtkTextIter iter;
+ GtkTextIter start, end;
+ GtkTextIter aux;
IDE_ENTRY;
- gtk_text_iter_assign (&iter, begin);
+ g_assert (IDE_IS_C_INDENTER (c));
+ g_assert (GTK_IS_TEXT_VIEW (view));
+ g_assert (GTK_IS_TEXT_BUFFER (buffer));
+ g_assert (iter);
+
+ aux = *iter;
- if (in_comment (begin, &match_begin, NULL))
- IDE_RETURN (NULL);
+ if (in_comment (&aux, &match_begin, NULL))
+ IDE_RETURN ();
- if (!gtk_text_iter_backward_char (&iter))
- IDE_RETURN (NULL);
+ if (!gtk_text_iter_backward_char (&aux))
+ IDE_RETURN ();
- if (line_is_case (&iter))
+ if (line_is_case (&aux))
{
- if (backward_find_matching_char (&iter, '}'))
+ if (backward_find_matching_char (&aux, '}'))
{
- GString *str;
+ g_autoptr(GString) str = NULL;
guint offset;
- if (!line_is_whitespace_until (&iter))
- backward_to_line_first_char (&iter);
+ if (!line_is_whitespace_until (&aux))
+ backward_to_line_first_char (&aux);
str = g_string_new (NULL);
- offset = GET_LINE_OFFSET (&iter);
- build_indent (c, offset + c->case_indent, &iter, str);
- while (!gtk_text_iter_starts_line (begin))
- gtk_text_iter_backward_char (begin);
- gtk_text_iter_assign (end, begin);
- while (g_unichar_isspace (gtk_text_iter_get_char (end)))
- if (!gtk_text_iter_forward_char (end))
- IDE_RETURN (NULL);
- return g_string_free (str, FALSE);
+ offset = GET_LINE_OFFSET (&aux);
+ build_indent (c, offset + c->case_indent, &aux, str);
+
+ start = *iter;
+ gtk_text_iter_set_line_offset (&start, 0);
+
+ end = start;
+ while (g_unichar_isspace (gtk_text_iter_get_char (&end)))
+ if (!gtk_text_iter_forward_char (&end))
+ IDE_RETURN ();
+
+ gtk_text_buffer_delete (buffer, &start, &end);
+ gtk_text_buffer_insert (buffer, &start, str->str, str->len);
}
}
- else if (line_is_label (&iter))
+ else if (line_is_label (&aux))
{
- GString *str = g_string_new (NULL);
-
- ITER_INIT_LINE_START (begin, &iter);
- ITER_INIT_LINE_START (end, &iter);
+ ITER_INIT_LINE_START (&start, iter);
+ ITER_INIT_LINE_START (&end, iter);
- while (g_unichar_isspace (gtk_text_iter_get_char (end)))
- if (!gtk_text_iter_forward_char (end))
- return NULL;
+ while (g_unichar_isspace (gtk_text_iter_get_char (&end)))
+ if (!gtk_text_iter_forward_char (&end))
+ IDE_RETURN ();
- if (c->extra_label_indent)
- for (int i = 0; i < c->extra_label_indent; i++)
- g_string_append_c (str, ' ');
-
- return g_string_free (str, FALSE);
+ gtk_text_buffer_delete (buffer, &start, &end);
}
- IDE_RETURN (NULL);
+ IDE_EXIT;
}
static gboolean
-ide_c_indenter_is_trigger (IdeIndenter *indenter,
- GdkEventKey *event)
+ide_c_indenter_is_trigger (GtkSourceIndenter *indenter,
+ GtkSourceView *view,
+ const GtkTextIter *location,
+ GdkModifierType state,
+ guint keyval)
{
- switch (event->keyval)
+ IdeCIndenter *c = (IdeCIndenter *)indenter;
+
+ switch (keyval)
{
case GDK_KEY_KP_Enter:
case GDK_KEY_Return:
- if ((event->state & GDK_SHIFT_MASK) != 0)
+ if ((state & GDK_SHIFT_MASK) != 0)
return FALSE;
- /* Fall through */
+ c->indent_action = IDE_C_INDENT_ACTION_INDENT_LINE;
+ return TRUE;
case GDK_KEY_braceleft:
+ c->indent_action = IDE_C_INDENT_ACTION_UNINDENT_OPENING_BRACE;
+ return TRUE;
+
case GDK_KEY_braceright:
+ c->indent_action = IDE_C_INDENT_ACTION_UNINDENT_CLOSING_BRACE;
+ return TRUE;
+
case GDK_KEY_colon:
+ c->indent_action = IDE_C_INDENT_ACTION_UNINDENT_CASE_OR_LABEL;
+ return TRUE;
+
case GDK_KEY_numbersign:
+ c->indent_action = IDE_C_INDENT_ACTION_UNINDENT_HASH;
+ return TRUE;
+
case GDK_KEY_parenright:
+ c->indent_action = IDE_C_INDENT_ACTION_ALIGN_PARAMETERS;
+ return TRUE;
+
case GDK_KEY_slash:
+ c->indent_action = IDE_C_INDENT_ACTION_CLOSE_COMMENT;
return TRUE;
default:
@@ -1301,27 +1391,24 @@ ide_c_indenter_is_trigger (IdeIndenter *indenter,
}
}
-static gchar *
-ide_c_indenter_format (IdeIndenter *indenter,
- GtkTextView *view,
- GtkTextIter *begin,
- GtkTextIter *end,
- gint *cursor_offset,
- GdkEventKey *event)
+static void
+ide_c_indenter_indent (GtkSourceIndenter *indenter,
+ GtkSourceView *view,
+ GtkTextIter *iter)
{
IdeCIndenter *c = (IdeCIndenter *)indenter;
- GtkTextIter begin_copy;
- gchar *ret = NULL;
+ GtkTextView *text_view;
GtkTextBuffer *buffer;
IdeFileSettings *file_settings;
IdeIndentStyle indent_style = IDE_INDENT_STYLE_SPACES;
guint tab_width = 2;
gint indent_width = -1;
- g_return_val_if_fail (IDE_IS_C_INDENTER (c), NULL);
- g_return_val_if_fail (IDE_IS_SOURCE_VIEW (view), NULL);
+ g_return_if_fail (IDE_IS_C_INDENTER (c));
+ g_return_if_fail (IDE_IS_SOURCE_VIEW (view));
- buffer = gtk_text_view_get_buffer (view);
+ text_view = GTK_TEXT_VIEW (view);
+ buffer = gtk_text_view_get_buffer (text_view);
c->view = IDE_SOURCE_VIEW (view);
@@ -1348,118 +1435,64 @@ ide_c_indenter_format (IdeIndenter *indenter,
!gtk_source_view_get_insert_spaces_instead_of_tabs (GTK_SOURCE_VIEW (view)) ||
indent_style == IDE_INDENT_STYLE_TABS;
- switch (event->keyval) {
- case GDK_KEY_Return:
- case GDK_KEY_KP_Enter:
- begin_copy = *begin;
- ret = c_indenter_indent (c, view, buffer, begin);
- *begin = begin_copy;
-
- if (!ide_str_empty0 (ret))
- {
- /*
- * If we have additional space after where our new indentation
- * will occur, we should chomp it up so that the text starts
- * immediately after our new indentation.
- *
- * GNOME/gnome-builder#545
- */
- while (text_iter_isspace (end) && !gtk_text_iter_ends_line (end))
- gtk_text_iter_forward_char (end);
- }
-
+ switch (c->indent_action) {
+ case IDE_C_INDENT_ACTION_ALIGN_PARAMETERS:
/*
- * If we are inserting a newline right before a closing brace (for example
- * after {<cursor>}, we need to indent and then maybe unindent the }.
+ * If we are closing a function declaration, adjust the spacing of
+ * parameters so that *'s are aligned.
*/
- if (gtk_text_iter_get_char (begin) == '}')
- {
- GtkTextIter iter;
- GString *str;
- gchar *tmp = ret;
- guint offset = 0;
-
- str = g_string_new (NULL);
-
- gtk_text_iter_assign (&iter, begin);
- if (backward_find_matching_char (&iter, '}'))
- {
- if (line_is_whitespace_until (&iter))
- offset = GET_LINE_OFFSET (&iter);
- else if (backward_to_line_first_char (&iter))
- offset = GET_LINE_OFFSET (&iter);
- build_indent (c, offset, &iter, str);
- g_string_prepend (str, "\n");
- g_string_prepend (str, ret);
-
- *cursor_offset = -(str->len - strlen (ret));
-
- ret = g_string_free (str, FALSE);
- g_free (tmp);
- }
- }
-
+ maybe_align_parameters (c, buffer, iter);
break;
- case GDK_KEY_braceright:
- /*
- * Possibly need to unindent this line.
- */
- ret = maybe_unindent_closing_brace (c, view, begin, end);
+ case IDE_C_INDENT_ACTION_CLOSE_COMMENT:
+ maybe_close_comment (c, buffer, iter);
break;
- case GDK_KEY_braceleft:
- /*
- * Maybe unindent the opening brace to match the conditional.
- * This could happen if we are doing k&r/linux/etc where the open
- * brace has less indentation than the natural single line conditional
- * child statement.
- */
- ret = maybe_unindent_opening_brace (c, view, begin, end, cursor_offset);
+ case IDE_C_INDENT_ACTION_INDENT_LINE:
+ c_indenter_indent_line (c, view, buffer, iter);
break;
- case GDK_KEY_colon:
+ case IDE_C_INDENT_ACTION_UNINDENT_CASE_OR_LABEL:
/*
* If this is a label or a case, adjust indentation.
*/
- ret = maybe_unindent_case_label (c, view, begin, end);
+ maybe_unindent_case_label (c, text_view, buffer, iter);
break;
- case GDK_KEY_numbersign:
+ case IDE_C_INDENT_ACTION_UNINDENT_CLOSING_BRACE:
/*
- * If this is a preprocessor directive, adjust indentation.
+ * Possibly need to unindent this line.
*/
- ret = maybe_unindent_hash (c, begin, end);
+ maybe_unindent_closing_brace (c, text_view, buffer, iter);
break;
- case GDK_KEY_parenright:
+ case IDE_C_INDENT_ACTION_UNINDENT_HASH:
/*
- * If we are closing a function declaration, adjust the spacing of
- * parameters so that *'s are aligned.
+ * If this is a preprocessor directive, adjust indentation.
*/
- ret = maybe_align_parameters (c, begin, end);
+ maybe_unindent_hash (c, buffer, iter);
break;
- case GDK_KEY_slash:
+ case IDE_C_INDENT_ACTION_UNINDENT_OPENING_BRACE:
/*
- * Check to see if we are right after a "* " and typing "/" while inside
- * of a multi-line comment. Probably just want to close the comment.
+ * Maybe unindent the opening brace to match the conditional.
+ * This could happen if we are doing k&r/linux/etc where the open
+ * brace has less indentation than the natural single line conditional
+ * child statement.
*/
- ret = maybe_close_comment (c, begin, end);
+ maybe_unindent_opening_brace (c, text_view, buffer, file_settings, iter);
break;
default:
break;
}
-
- return ret;
}
static void
-indenter_iface_init (IdeIndenterInterface *iface)
+indenter_iface_init (GtkSourceIndenterInterface *iface)
{
iface->is_trigger = ide_c_indenter_is_trigger;
- iface->format = ide_c_indenter_format;
+ iface->indent = ide_c_indenter_indent;
}
static void
diff --git a/src/plugins/c-pack/meson.build b/src/plugins/c-pack/meson.build
index 676dd1e98..04e83cdab 100644
--- a/src/plugins/c-pack/meson.build
+++ b/src/plugins/c-pack/meson.build
@@ -7,12 +7,10 @@ plugins_sources += files([
'cpack-completion-provider.c',
'cpack-completion-results.c',
'cpack-editor-page-addin.c',
+ 'ide-c-indenter.c',
'hdr-format.c',
])
-# needs to be ported to GtkSourceView 5 and moved there
-# 'ide-c-indenter.c',
-
plugin_c_pack_resources = gnome.compile_resources(
'c-pack-resources',
'c-pack.gresource.xml',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]