[gnome-builder/gnome-builder-3-18] indenter-c: respect indentation with tabs a bit better
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/gnome-builder-3-18] indenter-c: respect indentation with tabs a bit better
- Date: Tue, 13 Oct 2015 07:37:43 +0000 (UTC)
commit 5ed66cef5bb95f68408aa43a87ffd297b2d0f9de
Author: Christian Hergert <chergert redhat com>
Date: Sat Oct 10 00:26:43 2015 -0400
indenter-c: respect indentation with tabs a bit better
This tries to use the visual column instead of the line offset, which
would only be correct if we are using all spaces.
plugins/c-pack/ide-c-indenter.c | 219 +++++++++++++--------------------------
1 files changed, 72 insertions(+), 147 deletions(-)
---
diff --git a/plugins/c-pack/ide-c-indenter.c b/plugins/c-pack/ide-c-indenter.c
index 87103d4..dd866f3 100644
--- a/plugins/c-pack/ide-c-indenter.c
+++ b/plugins/c-pack/ide-c-indenter.c
@@ -42,8 +42,7 @@ struct _IdeCIndenter
gint scope_indent;
gint condition_indent;
gint directive_indent;
-
- guint space_before_paren : 1;
+ gint extra_label_indent;
};
static void indenter_iface_init (IdeIndenterInterface *iface);
@@ -161,34 +160,50 @@ line_is_whitespace_until (GtkTextIter *iter)
return TRUE;
}
+static gboolean is_special (const GtkTextIter *iter)
+{
+ GtkSourceBuffer *buffer;
+
+ buffer = GTK_SOURCE_BUFFER (gtk_text_iter_get_buffer (iter));
+ return (gtk_source_buffer_iter_has_context_class (buffer, iter, "string") ||
+ gtk_source_buffer_iter_has_context_class (buffer, iter, "comment"));
+}
+
static gboolean
-backward_find_keyword (GtkTextIter *iter,
- const gchar *keyword,
- GtkTextIter *limit)
+backward_find_keyword (GtkTextIter *iter,
+ const gchar *keyword,
+ const GtkTextIter *limit)
{
- GtkTextIter begin;
- GtkTextIter end;
+ GtkTextIter copy = *iter;
- /*
- * If we find the keyword, check to see that the character before it
- * is either a newline or some other space character. (ie, not part of a
- * function name like foo_do().
- */
- if (gtk_text_iter_backward_search (iter, keyword, GTK_TEXT_SEARCH_TEXT_ONLY,
- &begin, &end, limit))
+ while (gtk_text_iter_compare (©, limit) > 0)
{
- GtkTextIter copy;
- gunichar ch;
+ GtkTextIter begin;
+ GtkTextIter end;
- gtk_text_iter_assign (©, &begin);
+ if (!gtk_text_iter_backward_search (©, keyword, GTK_TEXT_SEARCH_TEXT_ONLY, &begin, &end, limit))
+ return FALSE;
- if (!gtk_text_iter_backward_char (©) ||
- !(ch = gtk_text_iter_get_char (©)) ||
- g_unichar_isspace (ch))
+ if (!is_special (&begin) &&
+ gtk_text_iter_starts_word (&begin) &&
+ gtk_text_iter_ends_word (&end))
{
- gtk_text_iter_assign (iter, &begin);
+ GtkTextIter prev = begin;
+ gunichar ch;
+
+ if (gtk_text_iter_backward_char (&prev) &&
+ (ch = gtk_text_iter_get_char (&prev)) &&
+ !g_unichar_isspace (ch))
+ {
+ goto again;
+ }
+
+ *iter = begin;
return TRUE;
}
+
+ again:
+ copy = begin;
}
return FALSE;
@@ -490,6 +505,9 @@ in_comment (const GtkTextIter *location,
IDE_RETURN (TRUE);
}
+#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,
@@ -533,7 +551,7 @@ c_indenter_indent (IdeCIndenter *c,
guint offset;
gtk_text_iter_assign (iter, &match_begin);
- offset = gtk_text_iter_get_line_offset (iter);
+ offset = GET_LINE_OFFSET (iter);
if (comment_type == COMMENT_C89)
{
build_indent (c, offset + 1, iter, str);
@@ -583,7 +601,7 @@ c_indenter_indent (IdeCIndenter *c,
!backward_find_matching_char (iter, '}'))
IDE_GOTO (cleanup);
- offset = gtk_text_iter_get_line_offset (iter);
+ offset = GET_LINE_OFFSET (iter);
if (gtk_text_iter_get_char (iter) == '(')
offset++;
@@ -594,7 +612,7 @@ c_indenter_indent (IdeCIndenter *c,
* like "enum {".
*/
if (backward_to_line_first_char (iter))
- offset = gtk_text_iter_get_line_offset (iter);
+ offset = GET_LINE_OFFSET (iter);
offset += c->scope_indent;
}
@@ -612,7 +630,7 @@ c_indenter_indent (IdeCIndenter *c,
if (backward_find_stmt_expr (iter))
{
- offset = gtk_text_iter_get_line_offset (iter);
+ offset = GET_LINE_OFFSET (iter);
build_indent (c, offset, iter, str);
IDE_GOTO (cleanup);
}
@@ -628,7 +646,7 @@ c_indenter_indent (IdeCIndenter *c,
{
guint offset;
- offset = gtk_text_iter_get_line_offset (iter);
+ offset = GET_LINE_OFFSET (iter);
build_indent (c, offset + 1, iter, str);
IDE_GOTO (cleanup);
}
@@ -645,11 +663,11 @@ c_indenter_indent (IdeCIndenter *c,
if (gtk_text_iter_forward_char (iter))
{
- guint offset = gtk_text_iter_get_line_offset (iter) - 1;
+ guint offset = GET_LINE_OFFSET (iter) - 1;
if (backward_find_matching_char (iter, '}'))
{
- offset = gtk_text_iter_get_line_offset (iter);
+ offset = GET_LINE_OFFSET (iter);
offset += c->scope_indent;
}
@@ -672,7 +690,7 @@ c_indenter_indent (IdeCIndenter *c,
if (backward_find_matching_char (iter, ')') &&
backward_find_condition_keyword (iter))
{
- guint offset = gtk_text_iter_get_line_offset (iter);
+ guint offset = GET_LINE_OFFSET (iter);
build_indent (c, offset + c->condition_indent, iter, str);
IDE_GOTO (cleanup);
}
@@ -694,7 +712,7 @@ c_indenter_indent (IdeCIndenter *c,
if (!line_is_whitespace_until (&match_begin))
backward_to_line_first_char (&match_begin);
- offset = gtk_text_iter_get_line_offset (&match_begin);
+ offset = GET_LINE_OFFSET (&match_begin);
build_indent (c, offset + c->scope_indent, iter, str);
IDE_GOTO (cleanup);
}
@@ -709,7 +727,7 @@ c_indenter_indent (IdeCIndenter *c,
{
guint offset;
- offset = gtk_text_iter_get_line_offset (iter);
+ offset = GET_LINE_OFFSET (iter);
build_indent (c, offset + c->scope_indent, iter, str);
IDE_GOTO (cleanup);
}
@@ -719,7 +737,7 @@ c_indenter_indent (IdeCIndenter *c,
{
guint offset;
- offset = gtk_text_iter_get_line_offset (iter);
+ offset = GET_LINE_OFFSET (iter);
build_indent (c, offset + c->scope_indent, iter, str);
IDE_GOTO (cleanup);
}
@@ -772,8 +790,9 @@ maybe_close_comment (IdeCIndenter *c,
static gchar *
maybe_unindent_brace (IdeCIndenter *c,
- GtkTextIter *begin,
- GtkTextIter *end)
+ GtkTextView *view,
+ GtkTextIter *begin,
+ GtkTextIter *end)
{
GtkTextIter saved;
gchar *ret = NULL;
@@ -803,7 +822,7 @@ maybe_unindent_brace (IdeCIndenter *c,
if (!starts_line_space_ok (begin))
backward_to_line_first_char (begin);
- offset = gtk_text_iter_get_line_offset (begin);
+ offset = GET_LINE_OFFSET (begin);
str = g_string_new (NULL);
build_indent (c, offset, begin, str);
g_string_append_c (str, '}');
@@ -828,8 +847,8 @@ maybe_unindent_brace (IdeCIndenter *c,
static gchar *
maybe_unindent_hash (IdeCIndenter *c,
- GtkTextIter *begin,
- GtkTextIter *end)
+ GtkTextIter *begin,
+ GtkTextIter *end)
{
GtkTextIter saved;
gchar *ret = NULL;
@@ -885,53 +904,6 @@ line_starts_with_fuzzy (const GtkTextIter *iter,
return ret;
}
-#if 0
-static gchar *
-maybe_space_before_paren (IdeCIndenter *c,
- GtkTextIter *begin,
- GtkTextIter *end)
-{
- GtkTextIter match_begin;
- GtkTextIter copy;
- gunichar ch;
-
- 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);
-
- if (!c->priv->space_before_paren)
- return NULL;
-
- if (in_c89_comment (begin, &match_begin))
- return NULL;
-
- /* ignore preprocessor #define */
- if (line_starts_with_fuzzy (begin, "#"))
- return NULL;
-
- gtk_text_iter_assign (©, begin);
-
- /*
- * Move back to the character just inserted.
- */
- if (gtk_text_iter_backward_char (begin) &&
- (ch = gtk_text_iter_get_char (begin)) &&
- (ch == '(') &&
- gtk_text_iter_backward_char (begin) &&
- (ch = gtk_text_iter_get_char (begin)) &&
- !g_unichar_isspace (ch) &&
- g_unichar_isalnum (ch))
- {
- gtk_text_iter_forward_char (begin);
- return g_strdup (" (");
- }
-
- gtk_text_iter_assign (begin, ©);
-
- return NULL;
-}
-#endif
-
static gchar *
format_parameter (const Parameter *param,
guint max_type,
@@ -1024,8 +996,8 @@ format_parameters (GtkTextIter *begin,
static gchar *
maybe_align_parameters (IdeCIndenter *c,
- GtkTextIter *begin,
- GtkTextIter *end)
+ GtkTextIter *begin,
+ GtkTextIter *end)
{
GtkTextIter match_begin;
GtkTextIter copy;
@@ -1068,55 +1040,6 @@ maybe_align_parameters (IdeCIndenter *c,
IDE_RETURN (ret);
}
-#if 0
-static gchar *
-maybe_add_brace (IdeCIndenter *c,
- GtkTextIter *begin,
- GtkTextIter *end,
- gint *cursor_offset)
-{
- GtkTextIter iter;
-
- gtk_text_iter_assign (&iter, begin);
-
- if (gtk_text_iter_backward_char (&iter) &&
- (gtk_text_iter_get_char (&iter) == '{') &&
- (gtk_text_iter_get_char (begin) != '}'))
- {
- GtkTextIter copy = iter;
-
- gtk_text_iter_assign (©, &iter);
-
- if (gtk_text_iter_backward_word_start (©))
- {
- GtkTextIter copy2 = copy;
-
- if (gtk_text_iter_forward_word_end (©2))
- {
- gchar *word;
-
- word = gtk_text_iter_get_slice (©, ©2);
-
- if ((g_strcmp0 (word, "enum") == 0) ||
- (g_strcmp0 (word, "struct") == 0))
- {
- *cursor_offset = -2;
- g_free (word);
- return g_strdup ("};");
- }
-
- g_free (word);
- }
- }
-
- *cursor_offset = -1;
- return g_strdup ("}");
- }
-
- return NULL;
-}
-#endif
-
static gboolean
line_is_case (const GtkTextIter *line)
{
@@ -1201,8 +1124,9 @@ line_is_label (const GtkTextIter *line)
static gchar *
maybe_unindent_case_label (IdeCIndenter *c,
- GtkTextIter *begin,
- GtkTextIter *end)
+ GtkTextView *view,
+ GtkTextIter *begin,
+ GtkTextIter *end)
{
GtkTextIter match_begin;
GtkTextIter iter;
@@ -1227,7 +1151,7 @@ maybe_unindent_case_label (IdeCIndenter *c,
guint offset;
str = g_string_new (NULL);
- offset = gtk_text_iter_get_line_offset (&iter);
+ offset = GET_LINE_OFFSET (&iter);
build_indent (c, offset, &iter, str);
while (!gtk_text_iter_starts_line (begin))
gtk_text_iter_backward_char (begin);
@@ -1250,9 +1174,7 @@ maybe_unindent_case_label (IdeCIndenter *c,
}
else if (line_is_label (&iter))
{
-#if 0
- TODO ("allow configurable label indent");
-#endif
+ GString *str = g_string_new (NULL);
ITER_INIT_LINE_START (begin, &iter);
ITER_INIT_LINE_START (end, &iter);
@@ -1261,7 +1183,11 @@ maybe_unindent_case_label (IdeCIndenter *c,
if (!gtk_text_iter_forward_char (end))
return NULL;
- return g_strdup ("");
+ 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);
}
IDE_RETURN (NULL);
@@ -1335,9 +1261,9 @@ ide_c_indenter_format (IdeIndenter *indenter,
if (backward_find_matching_char (&iter, '}'))
{
if (line_is_whitespace_until (&iter))
- offset = gtk_text_iter_get_line_offset (&iter);
+ offset = GET_LINE_OFFSET (&iter);
else if (backward_to_line_first_char (&iter))
- offset = gtk_text_iter_get_line_offset (&iter);
+ offset = GET_LINE_OFFSET (&iter);
build_indent (c, offset, &iter, str);
g_string_prepend (str, "\n");
g_string_prepend (str, ret);
@@ -1356,14 +1282,14 @@ ide_c_indenter_format (IdeIndenter *indenter,
* Probably need to unindent this line.
* TODO: Maybe overwrite character.
*/
- ret = maybe_unindent_brace (c, begin, end);
+ ret = maybe_unindent_brace (c, view, begin, end);
break;
case GDK_KEY_colon:
/*
* If this is a label or a case, adjust indentation.
*/
- ret = maybe_unindent_case_label (c, begin, end);
+ ret = maybe_unindent_case_label (c, view, begin, end);
break;
case GDK_KEY_numbersign:
@@ -1419,7 +1345,6 @@ ide_c_indenter_init (IdeCIndenter *self)
self->condition_indent = 2;
self->scope_indent = 2;
self->directive_indent = G_MININT;
- self->space_before_paren = TRUE;
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]