[gnome-builder] cindent: improve our comment discover for c89/c99
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] cindent: improve our comment discover for c89/c99
- Date: Sun, 13 Sep 2015 02:16:29 +0000 (UTC)
commit 846b8c0c90e3823c1d88985d6ed9ce1019a697a3
Author: Christian Hergert <christian hergert me>
Date: Sat Sep 12 19:15:55 2015 -0700
cindent: improve our comment discover for c89/c99
plugins/c-pack/ide-c-indenter.c | 205 ++++++++++++++++++---------------------
1 files changed, 96 insertions(+), 109 deletions(-)
---
diff --git a/plugins/c-pack/ide-c-indenter.c b/plugins/c-pack/ide-c-indenter.c
index 47bad11..dc302a7 100644
--- a/plugins/c-pack/ide-c-indenter.c
+++ b/plugins/c-pack/ide-c-indenter.c
@@ -16,6 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#define G_LOG_DOMAIN "cindent"
+
#include <glib/gi18n.h>
#include <libpeas/peas.h>
@@ -49,27 +51,11 @@ static void indenter_iface_init (IdeIndenterInterface *iface);
G_DEFINE_DYNAMIC_TYPE_EXTENDED (IdeCIndenter, ide_c_indenter, IDE_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (IDE_TYPE_INDENTER, indenter_iface_init))
-static gunichar
-text_iter_peek_next_char (const GtkTextIter *location)
-{
- GtkTextIter iter = *location;
-
- if (gtk_text_iter_forward_char (&iter))
- return gtk_text_iter_get_char (&iter);
-
- return 0;
-}
-
-static gunichar
-text_iter_peek_prev_char (const GtkTextIter *location)
-{
- GtkTextIter iter = *location;
-
- if (gtk_text_iter_backward_char (&iter))
- return gtk_text_iter_get_char (&iter);
-
- return 0;
-}
+enum {
+ COMMENT_NONE,
+ COMMENT_C89,
+ COMMENT_C99
+};
static inline void
build_indent (IdeCIndenter *c,
@@ -141,8 +127,7 @@ iter_ends_c89_comment (const GtkTextIter *iter)
tmp = *iter;
- if (gtk_text_iter_backward_char (&tmp) &&
- ('*' == gtk_text_iter_get_char (&tmp)))
+ if (gtk_text_iter_backward_char (&tmp) && ('*' == gtk_text_iter_get_char (&tmp)))
return TRUE;
}
@@ -434,93 +419,85 @@ backward_to_line_first_char (GtkTextIter *iter)
return FALSE;
}
-/**
- * text_iter_in_c89_comment:
- * @location: (in): A #GtkTextIter containing the target location.
- *
- * The algorith for this is unfortunately trickier than one would expect.
- * Because we could always still have context if we walk backwards that
- * would let us know if we are in a string, we just start from the beginning
- * of the buffer and try to skip forward until we get to our target
- * position.
- *
- * Returns: %TRUE if we think we are in a c89 comment, otherwise %FALSE.
- */
static gboolean
-in_c89_comment (const GtkTextIter *location,
- GtkTextIter *match_begin)
+in_comment (const GtkTextIter *location,
+ GtkTextIter *match_begin,
+ gint *comment_type)
{
- GtkTextBuffer *buffer;
- GtkTextIter iter;
- GtkTextIter after_location;
+ GtkSourceBuffer *buffer = GTK_SOURCE_BUFFER (gtk_text_iter_get_buffer (location));
+ GtkTextIter iter = *location;
+ GtkTextIter copy;
+ gint type = COMMENT_NONE;
- buffer = gtk_text_iter_get_buffer (location);
- gtk_text_buffer_get_start_iter (buffer, &iter);
+ IDE_ENTRY;
- after_location = *location;
- gtk_text_iter_forward_char (&after_location);
+ if (comment_type)
+ *comment_type = COMMENT_NONE;
- do
+ /*
+ * A rather esoteric set of heuristics to be able to determine if we are
+ * actually in a GtkSourceView comment context.
+ */
+ if (gtk_text_iter_ends_line (&iter))
{
- gunichar ch;
+ if (gtk_text_iter_is_end (&iter))
+ gtk_text_iter_backward_char (&iter);
+ gtk_text_iter_backward_char (&iter);
+ }
- if (gtk_text_iter_compare (&iter, location) > 0)
- break;
+ /*
+ * But make sure that our new position isn't the end of a C89 block.
+ */
+ if (gtk_text_iter_get_char (&iter) == '/')
+ {
+ GtkTextIter star = iter;
- ch = gtk_text_iter_get_char (&iter);
+ if (gtk_text_iter_backward_char (&star) && (gtk_text_iter_get_char (&star) == '*'))
+ IDE_RETURN (FALSE);
+ }
- /* skip past the c89 comment */
- if ((ch == '/') && (text_iter_peek_next_char (&iter) == '*'))
- {
- GtkTextIter saved = iter;
+ g_print ("%d:%d (%02x)\n", gtk_text_iter_get_line (&iter), gtk_text_iter_get_line_offset (&iter),
gtk_text_iter_get_char (&iter));
- if (!gtk_text_iter_forward_chars (&iter, 2) ||
- !gtk_text_iter_forward_search (&iter, "*/",
- GTK_TEXT_SEARCH_TEXT_ONLY,
- NULL, &iter, &after_location))
- {
- *match_begin = saved;
- IDE_RETURN (TRUE);
- }
- }
+ if (!gtk_source_buffer_iter_has_context_class (buffer, &iter, "comment"))
+ IDE_RETURN (FALSE);
- /* skip past a string or character */
- if ((ch == '\'') || (ch == '"'))
- {
- const gchar *match = (ch == '\'') ? "'" : "\"";
+g_print ("looks like we are in a comment, find start.\n");
- again:
- if (!gtk_text_iter_forward_search (&iter, match,
- GTK_TEXT_SEARCH_TEXT_ONLY,
- NULL, NULL, NULL))
- return FALSE;
+ copy = iter;
- /* this one is escaped, keep looking */
- if (text_iter_peek_prev_char (&iter) == '\\')
- {
- if (!gtk_text_iter_forward_char (&iter))
- return FALSE;
- goto again;
- }
- }
+ while (gtk_source_buffer_iter_has_context_class (buffer, &iter, "comment"))
+ {
+ copy = iter;
- /* skip past escaped character */
- if (ch == '\\')
- {
- if (!gtk_text_iter_forward_char (&iter))
- return FALSE;
- }
+ gtk_text_iter_backward_char (&iter);
}
- while (gtk_text_iter_forward_char (&iter));
- return FALSE;
+ *match_begin = copy;
+
+ if ((gtk_text_iter_get_char (©) == '/') &&
+ !gtk_text_iter_is_end (©) &&
+ gtk_text_iter_forward_char (©))
+ {
+ if (gtk_text_iter_get_char (©) == '/')
+ type = COMMENT_C99;
+ else if (gtk_text_iter_get_char (©) == '*')
+ type = COMMENT_C89;
+ }
+
+ if ((type == COMMENT_C99) && (gtk_text_iter_get_line (©) != gtk_text_iter_get_line (location)))
+ IDE_RETURN (FALSE);
+
+ if (comment_type)
+ *comment_type = type;
+
+ IDE_RETURN (TRUE);
}
static gchar *
-c_indenter_indent (IdeCIndenter *c,
- GtkTextView *view,
- GtkTextBuffer *buffer,
- GtkTextIter *iter)
+c_indenter_indent (IdeCIndenter *c,
+ GtkTextView *view,
+ GtkTextBuffer *buffer,
+ GtkTextIter *iter)
{
GtkTextIter cur;
GtkTextIter match_begin;
@@ -528,6 +505,7 @@ c_indenter_indent (IdeCIndenter *c,
GString *str;
gchar *ret = NULL;
gchar *last_word = NULL;
+ gint comment_type;
IDE_ENTRY;
@@ -536,7 +514,7 @@ c_indenter_indent (IdeCIndenter *c,
/*
* Save our current iter position to restore it later.
*/
- gtk_text_iter_assign (&cur, iter);
+ cur = *iter;
/*
* Move to before the character just inserted.
@@ -549,27 +527,26 @@ c_indenter_indent (IdeCIndenter *c,
str = g_string_new (NULL);
/*
- * Move backwards to the last non-space character inserted. We need to
- * start by moving back one character to get to the pre-newline insertion
- * point.
- */
- if (g_unichar_isspace (gtk_text_iter_get_char (iter)))
- if (!gtk_text_iter_backward_find_char (iter, non_space_predicate, NULL, NULL))
- IDE_GOTO (cleanup);
-
- /*
* If we are in a c89 multi-line comment, try to match the previous comment
* line. Function will leave iter at original position unless it matched.
* If so, it will be at the beginning of the comment.
*/
- if (in_c89_comment (iter, &match_begin))
+ if (in_comment (iter, &match_begin, &comment_type))
{
guint offset;
gtk_text_iter_assign (iter, &match_begin);
offset = gtk_text_iter_get_line_offset (iter);
- build_indent (c, offset + 1, iter, str);
- g_string_append (str, "* ");
+ if (comment_type == COMMENT_C89)
+ {
+ build_indent (c, offset + 1, iter, str);
+ g_string_append (str, "* ");
+ }
+ else if (comment_type == COMMENT_C99)
+ {
+ build_indent (c, offset, iter, str);
+ g_string_append (str, "// ");
+ }
IDE_GOTO (cleanup);
}
@@ -582,6 +559,14 @@ c_indenter_indent (IdeCIndenter *c,
gtk_text_iter_assign (&cur, iter);
/*
+ * Move backwards to the last non-space character inserted. This helps us
+ * more accurately locate the type of syntax block we are in.
+ */
+ if (g_unichar_isspace (gtk_text_iter_get_char (iter)))
+ if (!gtk_text_iter_backward_find_char (iter, non_space_predicate, NULL, NULL))
+ IDE_GOTO (cleanup);
+
+ /*
* Get our new character as we possibely moved.
*/
ch = gtk_text_iter_get_char (iter);
@@ -755,12 +740,13 @@ cleanup:
static gchar *
maybe_close_comment (IdeCIndenter *c,
- GtkTextIter *begin,
- GtkTextIter *end)
+ GtkTextIter *begin,
+ GtkTextIter *end)
{
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);
@@ -772,7 +758,8 @@ maybe_close_comment (IdeCIndenter *c,
* Walk backwards ensuring we just inserted a '/' and that it was after
* a '* ' sequence.
*/
- if (in_c89_comment (begin, &begin_comment) &&
+ if (in_comment (begin, &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) &&
@@ -1055,7 +1042,7 @@ maybe_align_parameters (IdeCIndenter *c,
g_return_val_if_fail (begin, NULL);
g_return_val_if_fail (end, NULL);
- if (in_c89_comment (begin, &match_begin))
+ if (in_comment (begin, &match_begin, NULL))
IDE_RETURN (NULL);
gtk_text_iter_assign (©, begin);
@@ -1227,7 +1214,7 @@ maybe_unindent_case_label (IdeCIndenter *c,
gtk_text_iter_assign (&iter, begin);
- if (in_c89_comment (begin, &match_begin))
+ if (in_comment (begin, &match_begin, NULL))
IDE_RETURN (NULL);
if (!gtk_text_iter_backward_char (&iter))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]