[anjuta] language-support-cpp-java: Move indentation code to it's own file



commit 89443c06f0d142ba7a910e52b35184e07b943075
Author: Johannes Schmid <jhs gnome org>
Date:   Tue Jan 25 15:08:13 2011 +0100

    language-support-cpp-java: Move indentation code to it's own file

 plugins/language-support-cpp-java/Makefile.am      |    4 +-
 .../cpp-java-indentation.c                         | 1356 +++++++++++++++++
 .../cpp-java-indentation.h                         |   37 +
 plugins/language-support-cpp-java/plugin.c         | 1591 ++------------------
 plugins/language-support-cpp-java/plugin.h         |    5 +
 5 files changed, 1541 insertions(+), 1452 deletions(-)
---
diff --git a/plugins/language-support-cpp-java/Makefile.am b/plugins/language-support-cpp-java/Makefile.am
index 24fe48a..fe7eb86 100644
--- a/plugins/language-support-cpp-java/Makefile.am
+++ b/plugins/language-support-cpp-java/Makefile.am
@@ -51,7 +51,9 @@ libanjuta_language_cpp_java_la_SOURCES = \
 	cpp-java-assist.h \
 	cpp-java-assist.c \
 	cpp-java-utils.c \
-	cpp-java-utils.h 
+	cpp-java-utils.h \
+	cpp-java-indentation.c \
+	cpp-java-indentation.h 
 
 libanjuta_language_cpp_java_la_LDFLAGS = $(ANJUTA_PLUGIN_LDFLAGS)
 
diff --git a/plugins/language-support-cpp-java/cpp-java-indentation.c b/plugins/language-support-cpp-java/cpp-java-indentation.c
new file mode 100644
index 0000000..6408972
--- /dev/null
+++ b/plugins/language-support-cpp-java/cpp-java-indentation.c
@@ -0,0 +1,1356 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * cpp-java-indentation.c
+ *
+ * Copyright (C) 2011 - Johannes Schmid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <libanjuta/anjuta-debug.h>
+#include <libanjuta/interfaces/ianjuta-iterable.h>
+#include <libanjuta/interfaces/ianjuta-document.h>
+#include <libanjuta/interfaces/ianjuta-editor.h>
+#include <libanjuta/interfaces/ianjuta-file.h>
+#include <libanjuta/interfaces/ianjuta-editor-language.h>
+#include <libanjuta/interfaces/ianjuta-editor-selection.h>
+#include <libanjuta/interfaces/ianjuta-preferences.h>
+#include <libanjuta/interfaces/ianjuta-language.h>
+
+#include "cpp-java-indentation.h"
+#include "cpp-java-utils.h"
+
+#define PREF_INDENT_STATEMENT_SIZE "cpp-indent-statement-size"
+#define PREF_INDENT_BRACE_SIZE "cpp-indent-brace-size"
+#define PREF_INDENT_PARANTHESE_LINEUP "cpp-indent-paranthese-lineup"
+#define PREF_INDENT_PARANTHESE_SIZE "cpp-indent-paranthese-size"
+#define PREF_BRACE_AUTOCOMPLETION "cpp-brace-autocompletion"
+#define PREF_COMMENT_LEADING_ASTERISK "cpp-multiline-leading-asterisk"
+
+#define TAB_SIZE (ianjuta_editor_get_tabsize (editor, NULL))
+#define USE_SPACES_FOR_INDENTATION (ianjuta_editor_get_use_spaces (editor, NULL))
+
+#define INDENT_SIZE \
+	(plugin->param_statement_indentation >= 0? \
+		plugin->param_statement_indentation : \
+		g_settings_get_int (plugin->settings, PREF_INDENT_STATEMENT_SIZE))
+
+#define BRACE_INDENT \
+	(plugin->param_brace_indentation >= 0? \
+		plugin->param_brace_indentation : \
+		g_settings_get_int (plugin->settings, PREF_INDENT_BRACE_SIZE))
+
+#define CASE_INDENT (INDENT_SIZE)
+#define LABEL_INDENT (INDENT_SIZE)
+
+static gboolean
+iter_is_newline (IAnjutaIterable *iter, gchar ch)
+{
+	if (ch == '\n' || ch == '\r')
+		return TRUE;
+	return FALSE;
+}
+
+/* Returns TRUE if iter was moved */
+static gboolean
+skip_iter_to_newline_head (IAnjutaIterable *iter, gchar ch)
+{
+	gboolean ret_val = FALSE;
+	
+	if (ch == '\n')
+	{
+		/* Possibly at tail */
+		if (ianjuta_iterable_previous (iter, NULL))
+		{
+			ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter),
+											0, NULL);
+			if (ch != '\r')
+				/* Already at head, undo iter */
+				ianjuta_iterable_next (iter, NULL);
+			else
+				/* Correctly at head */
+				ret_val = TRUE;
+		}
+	}
+	return ret_val;
+}
+
+/* Returns TRUE if iter was moved */
+static gboolean
+skip_iter_to_newline_tail (IAnjutaIterable *iter, gchar ch)
+{
+	gboolean ret_val = FALSE;
+	
+	if (ch == '\r')
+	{
+		/* Possibly at head */
+		if (ianjuta_iterable_previous (iter, NULL))
+		{
+			ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter),
+											0, NULL);
+			if (ch != '\n')
+				/* Already at tail, undo iter */
+				ianjuta_iterable_next (iter, NULL);
+			else
+				/* Correctly at tail */
+				ret_val = TRUE;
+		}
+	}
+	return ret_val;
+}
+
+/* Jumps to the reverse matching brace of the given brace character */
+
+static gint
+get_line_indentation (IAnjutaEditor *editor, gint line_num)
+{
+	IAnjutaIterable *line_begin, *line_end;
+	gchar *line_string, *idx;
+	gint line_indent = 0;
+	
+	line_begin = ianjuta_editor_get_line_begin_position (editor, line_num, NULL);
+	line_end = ianjuta_editor_get_line_end_position (editor, line_num, NULL);
+	/*
+	DEBUG_PRINT ("%s: line begin = %d, line end = %d", __FUNCTION__,
+				 line_begin, line_end);
+	*/
+	if (ianjuta_iterable_compare (line_begin, line_end, NULL) == 0)
+	{
+		g_object_unref (line_begin);
+		g_object_unref (line_end);
+		return 0;
+	}
+	
+	line_string = ianjuta_editor_get_text (editor, line_begin, line_end,
+												NULL);
+	g_object_unref (line_begin);
+	g_object_unref (line_end);
+	
+	/* DEBUG_PRINT ("line_string = '%s'", line_string); */
+	
+	if (!line_string)
+		return 0;
+	
+	idx = line_string;
+	
+	/* Find first non-white space */
+	while (*idx != '\0' && isspace (*idx))
+	{
+		if (*idx == '\t')
+			line_indent += TAB_SIZE;
+		else
+			line_indent++;
+		idx++; /* Since we are looking for first non-space char, simple
+				* increment of the utf8 chars would do */
+	}
+	g_free (line_string);
+	return line_indent;
+}
+
+static gchar *
+get_line_indentation_string (IAnjutaEditor *editor, gint spaces, gint line_indent_spaces)
+{
+	gint i;
+	gchar *indent_string;
+		
+	if ((spaces + line_indent_spaces) <= 0)
+		return NULL;
+	
+	if (USE_SPACES_FOR_INDENTATION)
+	{
+		indent_string = g_new0 (gchar, spaces + line_indent_spaces + 1);
+		for (i = 0; i < (spaces + line_indent_spaces); i++)
+			indent_string[i] = ' ';
+	}
+	else
+	{
+		gint num_tabs = spaces / TAB_SIZE;
+		gint num_spaces = spaces % TAB_SIZE;
+		indent_string = g_new0 (gchar, num_tabs + num_spaces + line_indent_spaces + 1);
+		
+		for (i = 0; i < num_tabs; i++)
+			indent_string[i] = '\t';
+		for (; i < num_tabs + (num_spaces + line_indent_spaces); i++)
+			indent_string[i] = ' ';
+	}
+	return indent_string;
+}
+
+/* Sets the iter to line end of previous line and TRUE is returned.
+ * If there is no previous line, iter is set to first character in the
+ * buffer and FALSE is returned.
+ */
+static gboolean
+skip_iter_to_previous_line (IAnjutaEditor *editor, IAnjutaIterable *iter)
+{
+	gboolean found = FALSE;
+	gchar ch;
+	
+	while (ianjuta_iterable_previous (iter, NULL))
+	{
+		ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
+		if (iter_is_newline (iter, ch))
+		{
+			skip_iter_to_newline_head (iter, ch);
+			found = TRUE;
+			break;
+		}
+	}
+	return found;
+}
+
+/* Returns TRUE if the line is continuation of previous line (that is, it is
+ * part of the same logical line).
+ */
+static gboolean
+line_is_continuation (IAnjutaEditor *editor, IAnjutaIterable *iter)
+{
+	int is_continuation = FALSE;
+	
+	IAnjutaIterable *new_iter = ianjuta_iterable_clone (iter, NULL);
+	if (skip_iter_to_previous_line (editor, new_iter))
+	{
+		while (ianjuta_iterable_previous (new_iter, NULL))
+		{
+			gchar ch = ianjuta_editor_cell_get_char
+				(IANJUTA_EDITOR_CELL (new_iter), 0, NULL);
+			if (ch == ' ' || ch == '\t')
+				continue;
+			
+			if (ch == '\\')
+			{
+				is_continuation = TRUE;
+				break;
+			}
+			
+			if (iter_is_newline (new_iter, ch))
+				break;
+		}
+	}
+	g_object_unref (new_iter);
+	return is_continuation;
+}
+
+/* Sets the iter to line end of previous logical line and TRUE is returned.
+ * If there is no previous logical line, iter is set to first character in the
+ * buffer and FALSE is returned. logical line is defined as one or more
+ * real lines that are joined with line escapes ('\' at the end of real
+ * lines.
+ */
+static gboolean
+skip_iter_to_previous_logical_line (IAnjutaEditor *editor,
+									IAnjutaIterable *iter)
+{
+	gboolean found = TRUE;
+	
+	while (line_is_continuation (editor, iter))
+	{
+		/*
+		DEBUG_PRINT ("Line %d is continuation line .. Skipping",
+					 ianjuta_editor_get_line_from_position (editor, iter, NULL));
+		*/
+		found = skip_iter_to_previous_line (editor, iter);
+		if (!found)
+			break;
+	}
+	/*
+	DEBUG_PRINT ("Line %d is *not* continuation line .. Breaking",
+				 ianjuta_editor_get_line_from_position (editor, iter, NULL));
+	*/
+	if (found)
+		found = skip_iter_to_previous_line (editor, iter);
+	/*
+	DEBUG_PRINT ("Line %d is next logical line",
+				 ianjuta_editor_get_line_from_position (editor, iter, NULL));
+	*/
+	return found;
+}
+
+static gboolean
+line_is_preprocessor (IAnjutaEditor *editor, IAnjutaIterable *iter)
+{
+	gboolean is_preprocessor = FALSE;
+	IAnjutaIterable *new_iter = ianjuta_iterable_clone (iter, NULL);
+	
+	if (skip_iter_to_previous_logical_line (editor, new_iter))
+	{
+		/* Forward the newline char and point to line begin of next line */
+		gchar ch;
+		ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter),
+										   0, NULL);
+		skip_iter_to_newline_tail (new_iter, ch);
+		ianjuta_iterable_next (new_iter, NULL);
+	}
+	/* else, line is already pointed at first char of the line */
+	
+	do
+	{
+		gchar ch;
+		ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter),
+										   0, NULL);
+		if (ch == '#')
+		{
+			is_preprocessor = TRUE;
+			break;
+		}
+		if (iter_is_newline (new_iter, ch) || !isspace (ch))
+			break;
+	}
+	while (ianjuta_iterable_next (new_iter, NULL));
+	
+	g_object_unref (new_iter);
+	
+	return is_preprocessor;
+}
+
+/* Skips to the end-of-line of previous non-preprocessor line. Any multiple
+ * preprocessor lines are skipped. If current
+ * line is not preprocessor line, nothing happens. If there is no previous
+ * non-preprocessor line (we are at first line of the document which happens
+ * to be preprocessor line), iter is set to the first character in the
+ * document. It returns TRUE if the line is preprocessor line, otherwise
+ * FALSE.
+ */
+static gboolean
+skip_preprocessor_lines (IAnjutaEditor *editor, IAnjutaIterable *iter)
+{
+	gboolean line_found = FALSE;
+	gboolean preprocessor_found = FALSE;
+	IAnjutaIterable *new_iter = ianjuta_iterable_clone (iter, NULL);
+	
+	do
+	{
+		gboolean is_preprocessor = FALSE;
+		if (skip_iter_to_previous_logical_line (editor, new_iter))
+		{
+			gchar ch;
+			ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter),
+											   0, NULL);
+			skip_iter_to_newline_tail (new_iter, ch);
+			ianjuta_iterable_next (new_iter, NULL);
+		}
+		do
+		{
+			gchar ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter),
+													 0, NULL);
+			if (ch == '#')
+			{
+				is_preprocessor = TRUE;
+				/*
+				DEBUG_PRINT ("Line %d is preprocessor line .. Skipping",
+							 ianjuta_editor_get_line_from_position
+							 (editor, new_iter, NULL));
+				*/
+				break;
+			}
+			if (iter_is_newline (new_iter, ch) || !isspace (ch))
+			{
+				skip_iter_to_newline_tail (new_iter, ch);
+				break;
+			}
+		}
+		while (ianjuta_iterable_next (new_iter, NULL));
+		
+		if (is_preprocessor)
+		{
+			line_found = skip_iter_to_previous_line (editor, new_iter);
+			ianjuta_iterable_assign (iter, new_iter, NULL);
+			preprocessor_found = TRUE;
+		}
+		else
+		{
+			/*
+			DEBUG_PRINT ("Line %d is *not* preprocessor line .. Breaking",
+						 ianjuta_editor_get_line_from_position
+							(editor, new_iter, NULL));
+			*/
+			break;
+		}
+	}
+	while (line_found);
+	
+	g_object_unref (new_iter);
+	return preprocessor_found;
+}
+
+static gint
+set_line_indentation (IAnjutaEditor *editor, gint line_num, gint indentation, gint line_indent_spaces)
+{
+	IAnjutaIterable *line_begin, *line_end, *indent_position;
+	IAnjutaIterable *current_pos;
+	gint carat_offset, nchars = 0, nchars_removed = 0;
+	gchar *old_indent_string = NULL, *indent_string = NULL;
+	
+	/* DEBUG_PRINT ("In %s()", __FUNCTION__); */
+	line_begin = ianjuta_editor_get_line_begin_position (editor, line_num, NULL);
+	line_end = ianjuta_editor_get_line_end_position (editor, line_num, NULL);
+	
+	/*
+	DEBUG_PRINT ("line begin = %d, line end = %d, current_pos = %d",
+				 line_begin, line_end, current_pos);
+	*/
+	indent_position = ianjuta_iterable_clone (line_begin, NULL);
+	
+	if (ianjuta_iterable_compare (line_end, line_begin, NULL) > 0)
+	{
+		gchar *idx;
+		gchar *line_string = ianjuta_editor_get_text (editor, line_begin,
+														   line_end, NULL);
+		
+		//DEBUG_PRINT ("line_string = '%s'", line_string);
+		if (line_string)
+		{
+			idx = line_string;
+			
+			/* Find first non-white space */
+			while (*idx != '\0' && isspace (*idx))
+			{
+				idx = g_utf8_find_next_char (idx, NULL);
+				ianjuta_iterable_next (indent_position, NULL);
+			}
+			g_free (line_string);
+		}
+	}
+	/* Indent iter defined at this point, Identify how much is current
+	 * position is beyound this point. We need to restore it later after
+	 * indentation
+	*/
+	current_pos = ianjuta_editor_get_position (editor, NULL);
+	carat_offset = ianjuta_iterable_diff (indent_position, current_pos, NULL);
+	//DEBUG_PRINT ("carat offset is = %d", carat_offset);
+	
+	/* Set new indentation */
+	if ((indentation + line_indent_spaces) > 0)
+	{
+		indent_string = get_line_indentation_string (editor, indentation, line_indent_spaces);
+		nchars = indent_string ? g_utf8_strlen (indent_string, -1) : 0;
+		
+		/* Only indent if there is something to indent with */
+		if (indent_string)
+		{
+			/* Get existing indentation */
+			if (ianjuta_iterable_compare (indent_position, line_begin, NULL) > 0)
+			{
+				old_indent_string =
+					ianjuta_editor_get_text (editor, line_begin,
+												  indent_position, NULL);
+				
+				//DEBUG_PRINT ("old_indent_string = '%s'", old_indent_string);
+				nchars_removed = g_utf8_strlen (old_indent_string, -1);
+			}
+			
+			/* Only indent if there was no indentation before or old
+			 * indentation string was different from the new indent string
+			 */
+			if (old_indent_string == NULL ||
+				strcmp (old_indent_string, indent_string) != 0)
+			{
+				/* Remove the old indentation string, if there is any */
+				if (old_indent_string)
+					ianjuta_editor_erase (editor, line_begin,
+										  indent_position, NULL);
+				
+				/* Insert the new indentation string */
+				ianjuta_editor_insert (editor, line_begin,
+									   indent_string, -1, NULL);
+			}
+		}
+	}
+	
+	/* If indentation == 0, we really didn't enter the previous code block,
+	 * but we may need to clear existing indentation.
+	 */
+	if ((indentation + line_indent_spaces) == 0)
+	{
+		/* Get existing indentation */
+		if (ianjuta_iterable_compare (indent_position, line_begin, NULL) > 0)
+		{
+			old_indent_string =
+				ianjuta_editor_get_text (editor, line_begin,
+											  indent_position, NULL);
+			nchars_removed = g_utf8_strlen (old_indent_string, -1);
+		}
+		if (old_indent_string)
+			ianjuta_editor_erase (editor, line_begin, indent_position, NULL);
+	}
+	
+	/* Restore current position */
+	if (carat_offset >= 0)
+	{
+		/* If the cursor was not before the first non-space character in
+		 * the line, restore it's position after indentation.
+		 */
+		gint i;
+		IAnjutaIterable *pos = ianjuta_editor_get_line_begin_position (editor, line_num, NULL);
+		for (i = 0; i < nchars + carat_offset; i++)
+			ianjuta_iterable_next (pos, NULL);
+		ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor), NULL);
+		ianjuta_editor_goto_position (editor, pos, NULL);
+		ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor), NULL);
+		g_object_unref (pos);
+	}
+	else /* cursor_offset < 0 */
+	{
+		/* If the cursor was somewhere in the old indentation spaces,
+		 * home the cursor to first non-space character in the line (or
+		 * end of line if there is no non-space characters in the line.
+		 */
+		gint i;
+		IAnjutaIterable *pos = ianjuta_editor_get_line_begin_position (editor, line_num, NULL);
+		for (i = 0; i < nchars; i++)
+			ianjuta_iterable_next (pos, NULL);
+		ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor), NULL);
+		ianjuta_editor_goto_position (editor, pos, NULL);
+		ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor), NULL);
+		g_object_unref (pos);
+	}
+
+	g_object_unref (current_pos);
+	g_object_unref (indent_position);
+	g_object_unref (line_begin);
+	g_object_unref (line_end);
+	
+	g_free (old_indent_string);
+	g_free (indent_string);
+	return nchars;
+}
+
+/*  incomplete_statement:
+ *  1 == COMPLETE STATEMENT
+ *  0 == INCOMPLETE STATEMENT
+ * -1 == UNKNOWN
+ */
+static gint
+get_line_indentation_base (CppJavaPlugin *plugin,
+						   IAnjutaEditor *editor,
+						   gint line_num,
+						   gint *incomplete_statement,
+						   gint *line_indent_spaces,
+						   gboolean *colon_indent)
+{
+	IAnjutaIterable *iter;
+	gchar point_ch;
+	gint line_indent = 0;
+	gint extra_indent = 0;
+	gboolean looking_at_just_next_line = TRUE;
+	gboolean current_line_is_preprocessor = FALSE;
+	gboolean current_line_is_continuation = FALSE;
+	gboolean line_checked_for_comment = FALSE;
+
+    /* Determine whether or not to add multi-line comment asterisks */
+	const gchar *comment_continued = " * ";
+	IAnjutaIterable *line_begin = ianjuta_editor_get_line_begin_position (editor, line_num, NULL);
+	IAnjutaIterable  *line_end = ianjuta_editor_get_line_end_position (editor, line_num, NULL);
+
+	*incomplete_statement = -1;
+	*line_indent_spaces = 0;
+	
+	if (line_num <= 1)
+		return 0;
+	
+	/* DEBUG_PRINT ("In %s()", __FUNCTION__); */
+	
+	iter = ianjuta_editor_get_line_begin_position (editor, line_num, NULL);
+	
+	current_line_is_preprocessor = line_is_preprocessor (editor, iter);
+	current_line_is_continuation = 
+		line_is_continuation (editor, iter);
+	/*
+	DEBUG_PRINT ("Current line is preprocessor = %d",
+				 current_line_is_preprocessor);
+	DEBUG_PRINT ("Current line is continuation = %d",
+				 current_line_is_continuation);
+	*/
+	/* line_indent = get_line_indentation (editor, line_num - 1); */
+	
+	if (current_line_is_preprocessor && current_line_is_continuation)
+	{
+		/* Continuation of preprocessor line -- just maintain indentation */
+		g_object_unref (iter);
+		return get_line_indentation (editor, line_num - 1);
+	}
+	else if (current_line_is_preprocessor)
+	{
+		/* Preprocessor line -- indentation should be 0 */
+		g_object_unref (iter);
+		return 0;
+	}
+	
+	while (ianjuta_iterable_previous (iter, NULL))
+	{
+		/* Skip strings */
+		IAnjutaEditorAttribute attrib =
+			ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL (iter), NULL);
+		if (attrib == IANJUTA_EDITOR_STRING)
+			continue;
+		
+		point_ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0,
+												 NULL);
+
+		/* DEBUG_PRINT("point_ch = %c", point_ch); */
+		
+		/* Check for line comment comment */
+		if (!line_checked_for_comment && !isspace(point_ch))
+		{
+			gboolean comment = FALSE;
+			IAnjutaIterable* new_iter = ianjuta_iterable_clone (iter, NULL);
+			do
+			{
+				gchar c;
+				c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter), 0,
+												  NULL);
+				if (iter_is_newline (new_iter, c))
+				{
+					line_checked_for_comment = TRUE;
+					break;
+				}
+				if (c == '/')
+				{
+					IAnjutaIterable* tmp_iter = ianjuta_iterable_clone (new_iter, NULL);
+					if (!ianjuta_iterable_previous (tmp_iter, NULL))
+					{
+						g_object_unref (tmp_iter);
+						break;
+					}
+					c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (tmp_iter), 0,
+													  NULL);
+					if (c == '/')
+					{
+						/* is a line comment, skip until begin of comment */
+						comment = TRUE;
+						g_object_unref (tmp_iter);
+						break;
+					}
+					g_object_unref (tmp_iter);
+				}
+			} while (ianjuta_iterable_previous (new_iter, NULL));
+			if (comment)
+			{
+				ianjuta_iterable_assign (iter, new_iter, NULL);
+				ianjuta_iterable_previous (iter, NULL);
+				g_object_unref (new_iter);
+				continue;
+			}
+			g_object_unref (new_iter);
+		}
+		/* Check if we are inside a comment */
+		if (point_ch == '/' || point_ch == '*')
+		{
+			gboolean comment = FALSE;
+			gboolean comment_end = FALSE;
+			IAnjutaIterable* new_iter = ianjuta_iterable_clone (iter, NULL);
+			do
+			{
+				gchar c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL(new_iter),
+												  0, NULL);
+				if (!comment_end && iter_is_newline (new_iter, c))
+				{
+					break;
+				}
+				if (c == '*')
+				{
+					IAnjutaIterable* prev = ianjuta_iterable_clone (new_iter, NULL);
+					IAnjutaIterable* next = ianjuta_iterable_clone (new_iter, NULL);					
+					ianjuta_iterable_previous (prev, NULL);
+					ianjuta_iterable_next (next, NULL);
+					gchar prev_c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (prev), 0,
+													  NULL);
+					gchar next_c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (next), 0,
+													  NULL);					
+					if (prev_c == '/')
+					{		 
+						/* starts comment */
+						comment = TRUE;
+						if (!comment_end)
+						{
+							extra_indent++;
+
+							/* If a multiline comment is continuing, check the next line and insert " * " 
+							 * only if it does not already exist there. The purpose of this fix is to avoid
+							 * extra " * " on auto-indent. */
+
+							if ((g_settings_get_boolean (plugin->settings, PREF_COMMENT_LEADING_ASTERISK)) &&
+								(ianjuta_iterable_compare (line_end, line_begin, NULL)) == 0)
+							{
+								ianjuta_editor_insert (editor, line_begin, comment_continued, -1, NULL);
+							}
+
+							/* In the middle of a comment we can't know
+						     * if the statement is incomplete
+							 */
+							*incomplete_statement = -1;
+							
+							/* ":" have to be ignored inside comments */
+							if (*colon_indent)
+							{
+								*colon_indent = FALSE;
+								extra_indent -= INDENT_SIZE;
+							}
+						}
+						g_object_unref (prev);
+						g_object_unref (next);
+						break;
+						
+					}
+					else if (next_c == '/')
+					{
+						/* ends comment: */
+						comment_end = TRUE;
+						g_object_unref (prev);
+						g_object_unref (next);
+						continue;
+					}
+					/* Possibly continued comment */
+					else if (isspace(prev_c))
+					{
+						gboolean possible_comment = FALSE;
+						while (ianjuta_iterable_previous (prev, NULL))
+						{
+							prev_c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (prev), 0,
+															  	   NULL);
+							if (!isspace(prev_c))
+								break;
+							if (iter_is_newline (prev, prev_c))
+							{
+								possible_comment = TRUE;
+								break;
+							}
+						}
+						if (possible_comment)
+						{
+							ianjuta_iterable_assign (new_iter, prev, NULL);
+							g_object_unref (prev);
+							g_object_unref (next);
+							continue;
+						}
+					}
+					g_object_unref (prev);
+					g_object_unref (next);
+				}
+			} while (ianjuta_iterable_previous (new_iter, NULL));
+			if (comment)
+			{
+				ianjuta_iterable_assign (iter, new_iter, NULL);
+				ianjuta_iterable_previous (iter, NULL);
+				g_object_unref (new_iter);
+				continue;
+			}
+			g_object_unref (new_iter);
+		}
+		if (point_ch == ')' || point_ch == ']' || point_ch == '}')
+		{
+			gint line_saved;
+			
+			line_saved = ianjuta_editor_get_line_from_position (editor, iter,
+																NULL);
+			
+			/* If we encounter a block-end before anything else, the
+			 * statement could hardly be incomplte.
+			 */
+			if (point_ch == '}' && *incomplete_statement == -1)
+				*incomplete_statement = 0;
+			
+			/* If at level 0 indentation, encoutered a
+			 * block end, don't bother going further
+			 */
+			if (point_ch == '}' && get_line_indentation (editor, line_saved) <= 0)
+			{
+				line_indent = 0;
+				line_indent += extra_indent;
+				break;
+			}
+			
+			/* Find matching brace and continue */
+			if (!cpp_java_util_jump_to_matching_brace (iter, point_ch, -1))
+			{
+				line_indent = get_line_indentation (editor, line_saved);
+				line_indent += extra_indent;
+				break;
+			}
+		}
+		else if (point_ch == '{')
+		{
+			gint line_for_indent =
+				ianjuta_editor_get_line_from_position (editor, iter, NULL);
+			line_indent = get_line_indentation (editor, line_for_indent);
+			/* Increase line indentation */
+			line_indent += INDENT_SIZE;
+			line_indent += extra_indent;
+			
+			/* If we encounter a block-start before anything else, the
+			 * statement could hardly be incomplte.
+			 */
+			if (point_ch == '{' && *incomplete_statement == -1)
+				*incomplete_statement = 0;
+			
+			break;
+		}
+		else if (point_ch == '(' || point_ch == '[')
+		{
+			line_indent = 0;
+			if (g_settings_get_boolean (plugin->settings,
+			                            PREF_INDENT_PARANTHESE_LINEUP))
+			{
+				while (ianjuta_iterable_previous (iter, NULL))
+				{
+					gchar dummy_ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0,
+					                                               NULL);
+					if (iter_is_newline (iter, dummy_ch))
+					{
+						skip_iter_to_newline_head (iter, dummy_ch);
+						break;
+					}
+					if (dummy_ch == '\t')
+						line_indent += TAB_SIZE;
+					else
+						(*line_indent_spaces)++;
+				}
+				(*line_indent_spaces)++;
+				line_indent += extra_indent;
+			}
+			else
+			{
+				gint line_for_indent =
+					ianjuta_editor_get_line_from_position (editor, iter, NULL);
+				line_indent = get_line_indentation (editor, line_for_indent);
+				line_indent += extra_indent;
+
+				(*line_indent_spaces) += g_settings_get_int (plugin->settings,
+				                                             PREF_INDENT_PARANTHESE_SIZE);
+			}
+			
+			/* Although statement is incomplete at this point, we don't
+			 * set it to incomplete and just leave it to unknown to avaoid
+			 * increating indentation for it, because incomplete braces,
+			 * overrides any existing indentation
+			 */
+			*incomplete_statement = -1;
+			break;
+		}
+		else if (point_ch == ';' || point_ch == ',')
+		{
+			/* If we encounter statement-end before any non-whitespace
+			 * char, the statement is complete.
+			 */
+			if (*incomplete_statement == -1)
+				*incomplete_statement = 0;
+		}
+		else if (point_ch == ':' && *colon_indent == FALSE)
+		{
+			/* This is a forward reference, all lines below should have
+			 * increased indentation until the next statement has
+			 * a ':'
+			 * If current line indentation is zero, that we don't indent
+			 */
+			IAnjutaIterable* new_iter = ianjuta_iterable_clone (iter, NULL);
+			IAnjutaIterable* line_begin;
+			gboolean indent = FALSE;
+			gchar c;
+			
+			/* Is the last non-whitespace in line */
+			while (ianjuta_iterable_next (new_iter, NULL))
+			{
+				c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter),
+													   0, NULL);
+				if (!isspace(c))
+					break;
+				if (iter_is_newline (new_iter, c))
+				{
+					indent = TRUE;
+					break;
+				}
+			}
+			line_begin = ianjuta_editor_get_line_begin_position(editor,
+																ianjuta_editor_get_line_from_position(editor, iter, NULL),
+																NULL);
+			c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (line_begin),
+														0, NULL);
+			if (indent)
+			{
+				*colon_indent = TRUE;
+				if (*incomplete_statement == -1)
+					*incomplete_statement = 0;
+			}
+			if (indent && isspace(c))
+			{
+				extra_indent += INDENT_SIZE;
+			}
+			g_object_unref (new_iter);
+			g_object_unref (line_begin);
+		}	
+		else if (iter_is_newline (iter, point_ch))
+		{
+			skip_iter_to_newline_head (iter, point_ch);
+			
+			/* We just crossed a line boundary. Skip any preprocessor lines,
+			 * and ensure that line_indent is updated with correct real
+			 * previous non-preprocessor line.
+			 */
+			if (skip_preprocessor_lines (editor, iter) &&
+				looking_at_just_next_line)
+			{
+				/*
+				gint line = ianjuta_editor_get_line_from_position (editor, iter, NULL);
+				line_indent = get_line_indentation (editor, line);
+				*/
+			}
+			looking_at_just_next_line = FALSE;
+			line_checked_for_comment = FALSE;
+		}		 
+		else if (!isspace (point_ch))
+		{			
+			/* If we encounter any non-whitespace char before any of the
+			 * statement-complete indicators, the statement is basically
+			 * incomplete
+			 */
+			if (*incomplete_statement == -1)
+				*incomplete_statement = 1;
+		}
+	}
+	if (!line_indent && extra_indent)
+	{
+		line_indent += extra_indent;
+	}
+	g_object_unref (iter);
+		
+	return line_indent;
+}
+
+/* Check if iter is inside string. Begining of string
+ * is not counted as inside.
+ */
+static gboolean
+is_iter_inside_string (IAnjutaIterable *iter)
+{
+	IAnjutaEditorAttribute attrib;
+	
+	attrib = ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL (iter),
+												NULL);
+	/* Check if we are *inside* string. Begining
+	 * of string does not count as inside.
+	 */
+	if (attrib == IANJUTA_EDITOR_STRING)
+	{
+		/* Peek previous attrib and see what it was */
+		if (ianjuta_iterable_previous (iter, NULL))
+		{
+			attrib = ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL
+														(iter),	NULL);
+			if (attrib == IANJUTA_EDITOR_STRING)
+			{
+				/* We are inside string */
+				return TRUE;
+			}
+			else
+			{
+				/* The string just began, not inside.
+				 * Restore iter from the peek
+				 */
+				ianjuta_iterable_next (iter, NULL);
+			}
+		}
+		/* else, there is no previous and so we can't be inside string
+		 */
+	}
+	return FALSE;
+}
+
+static gboolean
+spaces_only (IAnjutaEditor* editor, IAnjutaIterable* begin, IAnjutaIterable* end)
+{
+	gboolean empty = TRUE;
+	gchar* idx;
+	gchar* text = ianjuta_editor_get_text (editor, begin, end, NULL);
+
+	if (text == NULL)
+		return TRUE;
+	
+
+	for (idx = text; *idx != '\0'; idx++)
+	{
+		if (!isspace(*idx))
+		{
+			empty = FALSE;
+			break;
+		}
+	}
+	g_free(text);
+	return empty;
+}
+
+static gint
+get_line_auto_indentation (CppJavaPlugin *plugin, IAnjutaEditor *editor,
+						   gint line, gint *line_indent_spaces)
+{
+	IAnjutaIterable *iter;
+	IAnjutaIterable *end_iter;
+	gint line_indent = 0;
+	gint incomplete_statement = -1;
+	gboolean colon_indent = FALSE;
+	
+	g_return_val_if_fail (line > 0, 0);
+
+	/* be sure to set a default if we're in the first line otherwise
+	 * the pointer'll be left hanging with no value.
+	 */
+	*line_indent_spaces = 0;
+	
+	if (line == 1) /* First line */
+	{
+		return 0;
+	}
+	else
+	{
+		IAnjutaIterable* begin = ianjuta_editor_get_line_begin_position (editor, line -1 , NULL);
+		IAnjutaIterable* end = ianjuta_editor_get_line_end_position (editor, line -1 , NULL);
+
+		if (spaces_only (editor, begin, end))
+		{
+			set_line_indentation (editor, line -1, 0, 0);
+		}
+		g_object_unref (begin);
+		g_object_unref (end);
+	}
+	
+	iter = ianjuta_editor_get_line_begin_position (editor, line, NULL);
+
+	if (is_iter_inside_string (iter))
+	{
+		line_indent = get_line_indentation (editor, line - 1);
+	}
+	else
+	{
+		line_indent = get_line_indentation_base (plugin, editor, line,
+												 &incomplete_statement, 
+												 line_indent_spaces,
+												 &colon_indent);
+	}
+
+	if (colon_indent)
+	{
+		/* If the last non-whitespace character in the line is ":" then
+		 * we remove the extra colon_indent
+		 */
+		end_iter = ianjuta_editor_get_line_end_position (editor, line, NULL);
+		gchar ch;
+		while (ianjuta_iterable_previous (end_iter, NULL))
+		{
+			ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (end_iter),
+			                                   0, NULL);
+			if (ch == ':')
+			{
+				line_indent -= INDENT_SIZE;
+				break;
+			}
+			if (!isspace(ch) || iter_is_newline (end_iter, ch))
+				break;
+		}
+		g_object_unref (end_iter);
+	}
+	
+	/* Determine what the first non-white char in the line is */
+	do
+	{
+		gchar ch;
+		/* Check if we are *inside* comment or string. Begining of comment
+		 * or string does not count as inside. If inside, just align with
+		 * previous indentation.
+		 */
+		if (is_iter_inside_string (iter))
+		{
+			line_indent = get_line_indentation (editor, line - 1);
+			break;
+		}
+		ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter),
+										   0, NULL);
+		if (iter_is_newline (iter, ch))
+		{
+			skip_iter_to_newline_tail (iter, ch);
+			
+			/* First levels are excused from incomplete statement indent */
+			if (incomplete_statement == 1 && line_indent > 0)
+				line_indent += INDENT_SIZE;
+			break;
+		}
+		
+		if (ch == '{')
+		{
+			if (line_indent > 0)
+			{
+				/* The first level braces are excused from brace indentation */
+				/*
+				DEBUG_PRINT ("Increasing indent level from %d to %d",
+							 line_indent,
+							 line_indent + BRACE_INDENT);
+				*/
+				line_indent += BRACE_INDENT;
+				/* It looks ugly to add extra indent after case: so remove that */
+				if (colon_indent)
+					line_indent -= INDENT_SIZE;
+			}
+			break;
+		}
+		else if (ch == '}')
+		{
+			ianjuta_iterable_previous (iter, NULL);
+			if (cpp_java_util_jump_to_matching_brace (iter, ch, -1))
+			{
+				gint line = ianjuta_editor_get_line_from_position (editor,
+																   iter,
+																   NULL);
+				line_indent = get_line_indentation (editor, line);
+			}
+			break;
+		}
+		else if (ch == '#')
+		{
+			line_indent = 0;
+			*line_indent_spaces = 0;
+		}
+		else if (!isspace (ch))
+		{
+			/* First levels are excused from incomplete statement indent */
+			if (incomplete_statement == 1 && line_indent > 0)
+				line_indent += INDENT_SIZE;
+			break;
+		}
+	}
+	while (ianjuta_iterable_next (iter, NULL));
+	g_object_unref (iter);
+	
+	return line_indent;
+}
+
+static void
+insert_editor_blocked (IAnjutaEditor* editor,
+                       IAnjutaIterable* iter,
+                       gchar* text,
+                       CppJavaPlugin* plugin)
+{
+	g_signal_handlers_block_by_func (editor, cpp_indentation, plugin);
+	ianjuta_editor_insert (editor, iter, text, -1, NULL);
+	g_signal_handlers_unblock_by_func (editor, cpp_indentation, plugin);
+}
+
+void
+cpp_indentation (IAnjutaEditor *editor,
+                 IAnjutaIterable *insert_pos,
+                 gchar ch,
+                 CppJavaPlugin *plugin)
+{
+	IAnjutaEditorAttribute attrib;
+	IAnjutaIterable *iter;
+	gboolean should_auto_indent = FALSE;
+
+	iter = ianjuta_iterable_clone (insert_pos, NULL);
+
+	/* If autoindent is enabled*/
+	if (plugin->smart_indentation)
+	{
+
+		/* DEBUG_PRINT ("Char added at position %d: '%c'", insert_pos, ch); */	
+
+		if (iter_is_newline (iter, ch))
+		{
+			skip_iter_to_newline_head (iter, ch);
+			/* All newline entries means enable indenting */
+			should_auto_indent = TRUE;
+		}
+		else if (ch == '{' || ch == '}' || ch == '#')
+		{
+			/* Indent only when it's the first non-white space char in the line */
+
+			/* Don't bother if we are inside string */
+			attrib = ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL (iter),
+			                                            NULL);
+			if (attrib != IANJUTA_EDITOR_STRING)
+			{
+				/* Iterate backwards till the begining of the line and disable
+				 * indenting if any non-white space char is encountered
+				 */
+
+				/* Begin by assuming it should be indented */
+				should_auto_indent = TRUE;
+
+				while (ianjuta_iterable_previous (iter, NULL))
+				{
+					ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter),
+					                                   0, NULL);
+
+					//DEBUG_PRINT ("Looking at char '%c'", ch);
+
+					/* Break on begining of line (== end of previous line) */
+					if (iter_is_newline (iter, ch))
+					{
+						skip_iter_to_newline_head (iter, ch);
+						break;
+					}
+					/* If a non-white space char is encountered, disabled indenting */
+					if (!isspace (ch))
+					{
+						should_auto_indent = FALSE;
+						break;
+					}
+				}
+			}
+		}
+		if (should_auto_indent)
+		{
+			gint insert_line;
+			gint line_indent;
+			gint line_indent_spaces;
+
+			ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor), NULL);
+
+			insert_line = ianjuta_editor_get_lineno (editor, NULL);
+			line_indent = get_line_auto_indentation (plugin, editor, insert_line, &line_indent_spaces);
+			set_line_indentation (editor, insert_line, line_indent, line_indent_spaces);
+			ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor), NULL);
+		}
+	}
+
+	if (g_settings_get_boolean (plugin->settings, PREF_BRACE_AUTOCOMPLETION))
+	{
+		if (ch == '[' || ch == '(')
+		            {
+						gchar *prev_char;
+						IAnjutaIterable *previous;
+
+						previous = ianjuta_iterable_clone (iter, NULL);
+						ianjuta_iterable_previous (previous, NULL);
+						prev_char = ianjuta_editor_get_text (editor, previous, iter, NULL);
+
+						/* If the previous char is a ' we don't have to autocomplete */
+						if (*prev_char != '\'')
+						{
+							ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT (editor), NULL);
+							ianjuta_iterable_next (iter, NULL);
+							switch (ch)
+							{
+								case '[': 
+									       insert_editor_blocked (editor, iter,
+									                              "]", plugin);
+									       break;
+								       case '(': 
+									              insert_editor_blocked (editor, iter,
+									                                     ")", plugin);
+									              break;
+								              default: 
+									              break;
+							              }
+							ianjuta_editor_goto_position (editor, iter, NULL);
+							ianjuta_document_end_undo_action (IANJUTA_DOCUMENT (editor), NULL);
+						}
+						g_object_unref (previous);
+					}
+		            else if (ch == '"' || ch == '\'')
+		            {
+						gchar *prev_char;
+						IAnjutaIterable *previous;
+
+						previous = ianjuta_iterable_clone (iter, NULL);
+						ianjuta_iterable_previous (previous, NULL);
+						prev_char = ianjuta_editor_get_text (editor, previous, iter, NULL);
+
+						/* First iter*/
+						ianjuta_iterable_next (iter, NULL);
+
+						/*
+						 * If the character is " we have to decide if we need insert
+						 * another " or we have to skip the character
+						 */
+						if (ch == '"' || ch == '\'')
+						{
+							/*
+							 * Now we have to detect if we want to manage " as a char
+							 */
+							if (*prev_char != '\'' && *prev_char != '\\')
+							{
+								gchar *c;
+
+								if (ch == '"')
+									c = g_strdup ("\"");
+								else c = g_strdup ("'");
+
+								ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT (editor), NULL);
+								insert_editor_blocked (editor, iter, c, plugin);
+								ianjuta_editor_goto_position (editor, iter, NULL);
+								ianjuta_document_end_undo_action (IANJUTA_DOCUMENT (editor), NULL);	
+
+								g_free (c);
+							}
+							g_object_unref (previous);
+							g_object_unref (iter);
+							return;
+						}
+						g_object_unref (previous);
+					}
+	            }
+	g_object_unref (iter);
+}
+
+void
+cpp_auto_indentation (IAnjutaEditor *editor,
+                      CppJavaPlugin *lang_plugin)
+{
+	gint line_start, line_end;
+	gint insert_line;
+	gint line_indent;
+	gboolean has_selection;
+
+	has_selection = ianjuta_editor_selection_has_selection
+		(IANJUTA_EDITOR_SELECTION (editor), NULL);
+	if (has_selection)
+	{
+		IAnjutaIterable *sel_start, *sel_end;
+		sel_start = ianjuta_editor_selection_get_start (IANJUTA_EDITOR_SELECTION (editor),
+		                                                NULL);
+		sel_end = ianjuta_editor_selection_get_end (IANJUTA_EDITOR_SELECTION (editor),
+		                                            NULL);
+		line_start = ianjuta_editor_get_line_from_position (editor, sel_start, NULL);
+		line_end = ianjuta_editor_get_line_from_position (editor, sel_end, NULL);
+		g_object_unref (sel_start);
+		g_object_unref (sel_end);
+	}
+	else
+	{
+		line_start = ianjuta_editor_get_lineno (IANJUTA_EDITOR(editor), NULL);
+		line_end = line_start;
+	}
+	ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor), NULL);
+
+	for (insert_line = line_start; insert_line <= line_end; insert_line++)
+	{
+		gint line_indent_spaces = 0;
+		line_indent = get_line_auto_indentation (lang_plugin, editor,
+		                                         insert_line,
+		                                         &line_indent_spaces);
+		/* DEBUG_PRINT ("Line indent for line %d = %d", insert_line, line_indent); */
+		set_line_indentation (editor, insert_line, line_indent, line_indent_spaces);
+	}
+	ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor), NULL);
+}
+
+
+void
+java_indentation (IAnjutaEditor *editor,
+                  IAnjutaIterable *insert_pos,
+                  gchar ch,
+                  CppJavaPlugin *plugin)
+{
+	cpp_indentation (editor, insert_pos, ch, plugin);
+}
\ No newline at end of file
diff --git a/plugins/language-support-cpp-java/cpp-java-indentation.h b/plugins/language-support-cpp-java/cpp-java-indentation.h
new file mode 100644
index 0000000..b68d16f
--- /dev/null
+++ b/plugins/language-support-cpp-java/cpp-java-indentation.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * cpp-java-indentation.h
+ *
+ * Copyright (C) 2011 - Johannes Schmid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "plugin.h"
+
+void
+cpp_indentation (IAnjutaEditor *editor,
+                 IAnjutaIterable *insert_pos,
+                 gchar ch,
+                 CppJavaPlugin *plugin);
+
+void
+cpp_auto_indentation (IAnjutaEditor *editor,
+                      CppJavaPlugin *plugin);
+
+void
+java_indentation (IAnjutaEditor *editor,
+                  IAnjutaIterable *insert_pos,
+                  gchar ch,
+                  CppJavaPlugin *plugin);
diff --git a/plugins/language-support-cpp-java/plugin.c b/plugins/language-support-cpp-java/plugin.c
index c0edbca..fbb2a8e 100644
--- a/plugins/language-support-cpp-java/plugin.c
+++ b/plugins/language-support-cpp-java/plugin.c
@@ -41,6 +41,7 @@
 
 #include "plugin.h"
 #include "cpp-java-utils.h"
+#include "cpp-java-indentation.h"
 
 /* Pixmaps */
 #define ANJUTA_PIXMAP_SWAP                "anjuta-swap"
@@ -61,362 +62,9 @@
 #define PREF_SCHEMA "org.gnome.anjuta.cpp"
 #define PREF_INDENT_AUTOMATIC "cpp-indent-automatic"
 #define PREF_INDENT_MODELINE "cpp-indent-modeline"
-#define PREF_INDENT_STATEMENT_SIZE "cpp-indent-statement-size"
-#define PREF_INDENT_BRACE_SIZE "cpp-indent-brace-size"
-#define PREF_INDENT_PARANTHESE_LINEUP "cpp-indent-paranthese-lineup"
-#define PREF_INDENT_PARANTHESE_SIZE "cpp-indent-paranthese-size"
-#define PREF_BRACE_AUTOCOMPLETION "cpp-brace-autocompletion"
-#define PREF_COMMENT_LEADING_ASTERISK "cpp-multiline-leading-asterisk"
-
-#define TAB_SIZE (ianjuta_editor_get_tabsize (editor, NULL))
-
-#define USE_SPACES_FOR_INDENTATION (ianjuta_editor_get_use_spaces (editor, NULL))
-
-#define INDENT_SIZE \
-	(plugin->param_statement_indentation >= 0? \
-		plugin->param_statement_indentation : \
-		g_settings_get_int (plugin->settings, PREF_INDENT_STATEMENT_SIZE))
-
-#define BRACE_INDENT \
-	(plugin->param_brace_indentation >= 0? \
-		plugin->param_brace_indentation : \
-		g_settings_get_int (plugin->settings, PREF_INDENT_BRACE_SIZE))
-
-#define CASE_INDENT (INDENT_SIZE)
-#define LABEL_INDENT (INDENT_SIZE)
 
 static gpointer parent_class;
 
-static gboolean
-iter_is_newline (IAnjutaIterable *iter, gchar ch)
-{
-	if (ch == '\n' || ch == '\r')
-		return TRUE;
-	return FALSE;
-}
-
-/* Returns TRUE if iter was moved */
-static gboolean
-skip_iter_to_newline_head (IAnjutaIterable *iter, gchar ch)
-{
-	gboolean ret_val = FALSE;
-	
-	if (ch == '\n')
-	{
-		/* Possibly at tail */
-		if (ianjuta_iterable_previous (iter, NULL))
-		{
-			ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter),
-											0, NULL);
-			if (ch != '\r')
-				/* Already at head, undo iter */
-				ianjuta_iterable_next (iter, NULL);
-			else
-				/* Correctly at head */
-				ret_val = TRUE;
-		}
-	}
-	return ret_val;
-}
-
-/* Returns TRUE if iter was moved */
-static gboolean
-skip_iter_to_newline_tail (IAnjutaIterable *iter, gchar ch)
-{
-	gboolean ret_val = FALSE;
-	
-	if (ch == '\r')
-	{
-		/* Possibly at head */
-		if (ianjuta_iterable_previous (iter, NULL))
-		{
-			ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter),
-											0, NULL);
-			if (ch != '\n')
-				/* Already at tail, undo iter */
-				ianjuta_iterable_next (iter, NULL);
-			else
-				/* Correctly at tail */
-				ret_val = TRUE;
-		}
-	}
-	return ret_val;
-}
-
-/* Jumps to the reverse matching brace of the given brace character */
-
-static gint
-get_line_indentation (IAnjutaEditor *editor, gint line_num)
-{
-	IAnjutaIterable *line_begin, *line_end;
-	gchar *line_string, *idx;
-	gint line_indent = 0;
-	
-	line_begin = ianjuta_editor_get_line_begin_position (editor, line_num, NULL);
-	line_end = ianjuta_editor_get_line_end_position (editor, line_num, NULL);
-	/*
-	DEBUG_PRINT ("%s: line begin = %d, line end = %d", __FUNCTION__,
-				 line_begin, line_end);
-	*/
-	if (ianjuta_iterable_compare (line_begin, line_end, NULL) == 0)
-	{
-		g_object_unref (line_begin);
-		g_object_unref (line_end);
-		return 0;
-	}
-	
-	line_string = ianjuta_editor_get_text (editor, line_begin, line_end,
-												NULL);
-	g_object_unref (line_begin);
-	g_object_unref (line_end);
-	
-	/* DEBUG_PRINT ("line_string = '%s'", line_string); */
-	
-	if (!line_string)
-		return 0;
-	
-	idx = line_string;
-	
-	/* Find first non-white space */
-	while (*idx != '\0' && isspace (*idx))
-	{
-		if (*idx == '\t')
-			line_indent += TAB_SIZE;
-		else
-			line_indent++;
-		idx++; /* Since we are looking for first non-space char, simple
-				* increment of the utf8 chars would do */
-	}
-	g_free (line_string);
-	return line_indent;
-}
-
-static gchar *
-get_line_indentation_string (IAnjutaEditor *editor, gint spaces, gint line_indent_spaces)
-{
-	gint i;
-	gchar *indent_string;
-		
-	if ((spaces + line_indent_spaces) <= 0)
-		return NULL;
-	
-	if (USE_SPACES_FOR_INDENTATION)
-	{
-		indent_string = g_new0 (gchar, spaces + line_indent_spaces + 1);
-		for (i = 0; i < (spaces + line_indent_spaces); i++)
-			indent_string[i] = ' ';
-	}
-	else
-	{
-		gint num_tabs = spaces / TAB_SIZE;
-		gint num_spaces = spaces % TAB_SIZE;
-		indent_string = g_new0 (gchar, num_tabs + num_spaces + line_indent_spaces + 1);
-		
-		for (i = 0; i < num_tabs; i++)
-			indent_string[i] = '\t';
-		for (; i < num_tabs + (num_spaces + line_indent_spaces); i++)
-			indent_string[i] = ' ';
-	}
-	return indent_string;
-}
-
-/* Sets the iter to line end of previous line and TRUE is returned.
- * If there is no previous line, iter is set to first character in the
- * buffer and FALSE is returned.
- */
-static gboolean
-skip_iter_to_previous_line (IAnjutaEditor *editor, IAnjutaIterable *iter)
-{
-	gboolean found = FALSE;
-	gchar ch;
-	
-	while (ianjuta_iterable_previous (iter, NULL))
-	{
-		ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL);
-		if (iter_is_newline (iter, ch))
-		{
-			skip_iter_to_newline_head (iter, ch);
-			found = TRUE;
-			break;
-		}
-	}
-	return found;
-}
-
-/* Returns TRUE if the line is continuation of previous line (that is, it is
- * part of the same logical line).
- */
-static gboolean
-line_is_continuation (IAnjutaEditor *editor, IAnjutaIterable *iter)
-{
-	int is_continuation = FALSE;
-	
-	IAnjutaIterable *new_iter = ianjuta_iterable_clone (iter, NULL);
-	if (skip_iter_to_previous_line (editor, new_iter))
-	{
-		while (ianjuta_iterable_previous (new_iter, NULL))
-		{
-			gchar ch = ianjuta_editor_cell_get_char
-				(IANJUTA_EDITOR_CELL (new_iter), 0, NULL);
-			if (ch == ' ' || ch == '\t')
-				continue;
-			
-			if (ch == '\\')
-			{
-				is_continuation = TRUE;
-				break;
-			}
-			
-			if (iter_is_newline (new_iter, ch))
-				break;
-		}
-	}
-	g_object_unref (new_iter);
-	return is_continuation;
-}
-
-/* Sets the iter to line end of previous logical line and TRUE is returned.
- * If there is no previous logical line, iter is set to first character in the
- * buffer and FALSE is returned. logical line is defined as one or more
- * real lines that are joined with line escapes ('\' at the end of real
- * lines.
- */
-static gboolean
-skip_iter_to_previous_logical_line (IAnjutaEditor *editor,
-									IAnjutaIterable *iter)
-{
-	gboolean found = TRUE;
-	
-	while (line_is_continuation (editor, iter))
-	{
-		/*
-		DEBUG_PRINT ("Line %d is continuation line .. Skipping",
-					 ianjuta_editor_get_line_from_position (editor, iter, NULL));
-		*/
-		found = skip_iter_to_previous_line (editor, iter);
-		if (!found)
-			break;
-	}
-	/*
-	DEBUG_PRINT ("Line %d is *not* continuation line .. Breaking",
-				 ianjuta_editor_get_line_from_position (editor, iter, NULL));
-	*/
-	if (found)
-		found = skip_iter_to_previous_line (editor, iter);
-	/*
-	DEBUG_PRINT ("Line %d is next logical line",
-				 ianjuta_editor_get_line_from_position (editor, iter, NULL));
-	*/
-	return found;
-}
-
-static gboolean
-line_is_preprocessor (IAnjutaEditor *editor, IAnjutaIterable *iter)
-{
-	gboolean is_preprocessor = FALSE;
-	IAnjutaIterable *new_iter = ianjuta_iterable_clone (iter, NULL);
-	
-	if (skip_iter_to_previous_logical_line (editor, new_iter))
-	{
-		/* Forward the newline char and point to line begin of next line */
-		gchar ch;
-		ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter),
-										   0, NULL);
-		skip_iter_to_newline_tail (new_iter, ch);
-		ianjuta_iterable_next (new_iter, NULL);
-	}
-	/* else, line is already pointed at first char of the line */
-	
-	do
-	{
-		gchar ch;
-		ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter),
-										   0, NULL);
-		if (ch == '#')
-		{
-			is_preprocessor = TRUE;
-			break;
-		}
-		if (iter_is_newline (new_iter, ch) || !isspace (ch))
-			break;
-	}
-	while (ianjuta_iterable_next (new_iter, NULL));
-	
-	g_object_unref (new_iter);
-	
-	return is_preprocessor;
-}
-
-/* Skips to the end-of-line of previous non-preprocessor line. Any multiple
- * preprocessor lines are skipped. If current
- * line is not preprocessor line, nothing happens. If there is no previous
- * non-preprocessor line (we are at first line of the document which happens
- * to be preprocessor line), iter is set to the first character in the
- * document. It returns TRUE if the line is preprocessor line, otherwise
- * FALSE.
- */
-static gboolean
-skip_preprocessor_lines (IAnjutaEditor *editor, IAnjutaIterable *iter)
-{
-	gboolean line_found = FALSE;
-	gboolean preprocessor_found = FALSE;
-	IAnjutaIterable *new_iter = ianjuta_iterable_clone (iter, NULL);
-	
-	do
-	{
-		gboolean is_preprocessor = FALSE;
-		if (skip_iter_to_previous_logical_line (editor, new_iter))
-		{
-			gchar ch;
-			ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter),
-											   0, NULL);
-			skip_iter_to_newline_tail (new_iter, ch);
-			ianjuta_iterable_next (new_iter, NULL);
-		}
-		do
-		{
-			gchar ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter),
-													 0, NULL);
-			if (ch == '#')
-			{
-				is_preprocessor = TRUE;
-				/*
-				DEBUG_PRINT ("Line %d is preprocessor line .. Skipping",
-							 ianjuta_editor_get_line_from_position
-							 (editor, new_iter, NULL));
-				*/
-				break;
-			}
-			if (iter_is_newline (new_iter, ch) || !isspace (ch))
-			{
-				skip_iter_to_newline_tail (new_iter, ch);
-				break;
-			}
-		}
-		while (ianjuta_iterable_next (new_iter, NULL));
-		
-		if (is_preprocessor)
-		{
-			line_found = skip_iter_to_previous_line (editor, new_iter);
-			ianjuta_iterable_assign (iter, new_iter, NULL);
-			preprocessor_found = TRUE;
-		}
-		else
-		{
-			/*
-			DEBUG_PRINT ("Line %d is *not* preprocessor line .. Breaking",
-						 ianjuta_editor_get_line_from_position
-							(editor, new_iter, NULL));
-			*/
-			break;
-		}
-	}
-	while (line_found);
-	
-	g_object_unref (new_iter);
-	return preprocessor_found;
-}
-
 static void
 set_indentation_param_emacs (CppJavaPlugin* plugin, const gchar *param,
 					   const gchar *value)
@@ -581,7 +229,6 @@ extract_mode_line (const gchar *comment_text, gboolean* vim)
 }
 
 #define MINI_BUFFER_SIZE 3
-
 static void
 initialize_indentation_params (CppJavaPlugin *plugin)
 {
@@ -687,1067 +334,7 @@ initialize_indentation_params (CppJavaPlugin *plugin)
 	}
 }
 
-static gint
-set_line_indentation (IAnjutaEditor *editor, gint line_num, gint indentation, gint line_indent_spaces)
-{
-	IAnjutaIterable *line_begin, *line_end, *indent_position;
-	IAnjutaIterable *current_pos;
-	gint carat_offset, nchars = 0, nchars_removed = 0;
-	gchar *old_indent_string = NULL, *indent_string = NULL;
-	
-	/* DEBUG_PRINT ("In %s()", __FUNCTION__); */
-	line_begin = ianjuta_editor_get_line_begin_position (editor, line_num, NULL);
-	line_end = ianjuta_editor_get_line_end_position (editor, line_num, NULL);
-	
-	/*
-	DEBUG_PRINT ("line begin = %d, line end = %d, current_pos = %d",
-				 line_begin, line_end, current_pos);
-	*/
-	indent_position = ianjuta_iterable_clone (line_begin, NULL);
-	
-	if (ianjuta_iterable_compare (line_end, line_begin, NULL) > 0)
-	{
-		gchar *idx;
-		gchar *line_string = ianjuta_editor_get_text (editor, line_begin,
-														   line_end, NULL);
-		
-		//DEBUG_PRINT ("line_string = '%s'", line_string);
-		if (line_string)
-		{
-			idx = line_string;
-			
-			/* Find first non-white space */
-			while (*idx != '\0' && isspace (*idx))
-			{
-				idx = g_utf8_find_next_char (idx, NULL);
-				ianjuta_iterable_next (indent_position, NULL);
-			}
-			g_free (line_string);
-		}
-	}
-	/* Indent iter defined at this point, Identify how much is current
-	 * position is beyound this point. We need to restore it later after
-	 * indentation
-	*/
-	current_pos = ianjuta_editor_get_position (editor, NULL);
-	carat_offset = ianjuta_iterable_diff (indent_position, current_pos, NULL);
-	//DEBUG_PRINT ("carat offset is = %d", carat_offset);
-	
-	/* Set new indentation */
-	if ((indentation + line_indent_spaces) > 0)
-	{
-		indent_string = get_line_indentation_string (editor, indentation, line_indent_spaces);
-		nchars = indent_string ? g_utf8_strlen (indent_string, -1) : 0;
-		
-		/* Only indent if there is something to indent with */
-		if (indent_string)
-		{
-			/* Get existing indentation */
-			if (ianjuta_iterable_compare (indent_position, line_begin, NULL) > 0)
-			{
-				old_indent_string =
-					ianjuta_editor_get_text (editor, line_begin,
-												  indent_position, NULL);
-				
-				//DEBUG_PRINT ("old_indent_string = '%s'", old_indent_string);
-				nchars_removed = g_utf8_strlen (old_indent_string, -1);
-			}
-			
-			/* Only indent if there was no indentation before or old
-			 * indentation string was different from the new indent string
-			 */
-			if (old_indent_string == NULL ||
-				strcmp (old_indent_string, indent_string) != 0)
-			{
-				/* Remove the old indentation string, if there is any */
-				if (old_indent_string)
-					ianjuta_editor_erase (editor, line_begin,
-										  indent_position, NULL);
-				
-				/* Insert the new indentation string */
-				ianjuta_editor_insert (editor, line_begin,
-									   indent_string, -1, NULL);
-			}
-		}
-	}
-	
-	/* If indentation == 0, we really didn't enter the previous code block,
-	 * but we may need to clear existing indentation.
-	 */
-	if ((indentation + line_indent_spaces) == 0)
-	{
-		/* Get existing indentation */
-		if (ianjuta_iterable_compare (indent_position, line_begin, NULL) > 0)
-		{
-			old_indent_string =
-				ianjuta_editor_get_text (editor, line_begin,
-											  indent_position, NULL);
-			nchars_removed = g_utf8_strlen (old_indent_string, -1);
-		}
-		if (old_indent_string)
-			ianjuta_editor_erase (editor, line_begin, indent_position, NULL);
-	}
-	
-	/* Restore current position */
-	if (carat_offset >= 0)
-	{
-		/* If the cursor was not before the first non-space character in
-		 * the line, restore it's position after indentation.
-		 */
-		gint i;
-		IAnjutaIterable *pos = ianjuta_editor_get_line_begin_position (editor, line_num, NULL);
-		for (i = 0; i < nchars + carat_offset; i++)
-			ianjuta_iterable_next (pos, NULL);
-		ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor), NULL);
-		ianjuta_editor_goto_position (editor, pos, NULL);
-		ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor), NULL);
-		g_object_unref (pos);
-	}
-	else /* cursor_offset < 0 */
-	{
-		/* If the cursor was somewhere in the old indentation spaces,
-		 * home the cursor to first non-space character in the line (or
-		 * end of line if there is no non-space characters in the line.
-		 */
-		gint i;
-		IAnjutaIterable *pos = ianjuta_editor_get_line_begin_position (editor, line_num, NULL);
-		for (i = 0; i < nchars; i++)
-			ianjuta_iterable_next (pos, NULL);
-		ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor), NULL);
-		ianjuta_editor_goto_position (editor, pos, NULL);
-		ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor), NULL);
-		g_object_unref (pos);
-	}
-
-	g_object_unref (current_pos);
-	g_object_unref (indent_position);
-	g_object_unref (line_begin);
-	g_object_unref (line_end);
-	
-	g_free (old_indent_string);
-	g_free (indent_string);
-	return nchars;
-}
-
-/*  incomplete_statement:
- *  1 == COMPLETE STATEMENT
- *  0 == INCOMPLETE STATEMENT
- * -1 == UNKNOWN
- */
-static gint
-get_line_indentation_base (CppJavaPlugin *plugin,
-						   IAnjutaEditor *editor,
-						   gint line_num,
-						   gint *incomplete_statement,
-						   gint *line_indent_spaces,
-						   gboolean *colon_indent)
-{
-	IAnjutaIterable *iter;
-	gchar point_ch;
-	gint line_indent = 0;
-	gint extra_indent = 0;
-	gboolean looking_at_just_next_line = TRUE;
-	gboolean current_line_is_preprocessor = FALSE;
-	gboolean current_line_is_continuation = FALSE;
-	gboolean line_checked_for_comment = FALSE;
-
-    /* Determine whether or not to add multi-line comment asterisks */
-	const gchar *comment_continued = " * ";
-	IAnjutaIterable *line_begin = ianjuta_editor_get_line_begin_position (editor, line_num, NULL);
-	IAnjutaIterable  *line_end = ianjuta_editor_get_line_end_position (editor, line_num, NULL);
-
-	*incomplete_statement = -1;
-	*line_indent_spaces = 0;
-	
-	if (line_num <= 1)
-		return 0;
-	
-	/* DEBUG_PRINT ("In %s()", __FUNCTION__); */
-	
-	iter = ianjuta_editor_get_line_begin_position (editor, line_num, NULL);
-	
-	current_line_is_preprocessor = line_is_preprocessor (editor, iter);
-	current_line_is_continuation = 
-		line_is_continuation (editor, iter);
-	/*
-	DEBUG_PRINT ("Current line is preprocessor = %d",
-				 current_line_is_preprocessor);
-	DEBUG_PRINT ("Current line is continuation = %d",
-				 current_line_is_continuation);
-	*/
-	/* line_indent = get_line_indentation (editor, line_num - 1); */
-	
-	if (current_line_is_preprocessor && current_line_is_continuation)
-	{
-		/* Continuation of preprocessor line -- just maintain indentation */
-		g_object_unref (iter);
-		return get_line_indentation (editor, line_num - 1);
-	}
-	else if (current_line_is_preprocessor)
-	{
-		/* Preprocessor line -- indentation should be 0 */
-		g_object_unref (iter);
-		return 0;
-	}
-	
-	while (ianjuta_iterable_previous (iter, NULL))
-	{
-		/* Skip strings */
-		IAnjutaEditorAttribute attrib =
-			ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL (iter), NULL);
-		if (attrib == IANJUTA_EDITOR_STRING)
-			continue;
-		
-		point_ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0,
-												 NULL);
-
-		/* DEBUG_PRINT("point_ch = %c", point_ch); */
-		
-		/* Check for line comment comment */
-		if (!line_checked_for_comment && !isspace(point_ch))
-		{
-			gboolean comment = FALSE;
-			IAnjutaIterable* new_iter = ianjuta_iterable_clone (iter, NULL);
-			do
-			{
-				gchar c;
-				c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter), 0,
-												  NULL);
-				if (iter_is_newline (new_iter, c))
-				{
-					line_checked_for_comment = TRUE;
-					break;
-				}
-				if (c == '/')
-				{
-					IAnjutaIterable* tmp_iter = ianjuta_iterable_clone (new_iter, NULL);
-					if (!ianjuta_iterable_previous (tmp_iter, NULL))
-					{
-						g_object_unref (tmp_iter);
-						break;
-					}
-					c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (tmp_iter), 0,
-													  NULL);
-					if (c == '/')
-					{
-						/* is a line comment, skip until begin of comment */
-						comment = TRUE;
-						g_object_unref (tmp_iter);
-						break;
-					}
-					g_object_unref (tmp_iter);
-				}
-			} while (ianjuta_iterable_previous (new_iter, NULL));
-			if (comment)
-			{
-				ianjuta_iterable_assign (iter, new_iter, NULL);
-				ianjuta_iterable_previous (iter, NULL);
-				g_object_unref (new_iter);
-				continue;
-			}
-			g_object_unref (new_iter);
-		}
-		/* Check if we are inside a comment */
-		if (point_ch == '/' || point_ch == '*')
-		{
-			gboolean comment = FALSE;
-			gboolean comment_end = FALSE;
-			IAnjutaIterable* new_iter = ianjuta_iterable_clone (iter, NULL);
-			do
-			{
-				gchar c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL(new_iter),
-												  0, NULL);
-				if (!comment_end && iter_is_newline (new_iter, c))
-				{
-					break;
-				}
-				if (c == '*')
-				{
-					IAnjutaIterable* prev = ianjuta_iterable_clone (new_iter, NULL);
-					IAnjutaIterable* next = ianjuta_iterable_clone (new_iter, NULL);					
-					ianjuta_iterable_previous (prev, NULL);
-					ianjuta_iterable_next (next, NULL);
-					gchar prev_c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (prev), 0,
-													  NULL);
-					gchar next_c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (next), 0,
-													  NULL);					
-					if (prev_c == '/')
-					{		 
-						/* starts comment */
-						comment = TRUE;
-						if (!comment_end)
-						{
-							extra_indent++;
-
-							/* If a multiline comment is continuing, check the next line and insert " * " 
-							 * only if it does not already exist there. The purpose of this fix is to avoid
-							 * extra " * " on auto-indent. */
-
-							if ((g_settings_get_boolean (plugin->settings, PREF_COMMENT_LEADING_ASTERISK)) &&
-								(ianjuta_iterable_compare (line_end, line_begin, NULL)) == 0)
-							{
-								ianjuta_editor_insert (editor, line_begin, comment_continued, -1, NULL);
-							}
-
-							/* In the middle of a comment we can't know
-						     * if the statement is incomplete
-							 */
-							*incomplete_statement = -1;
-							
-							/* ":" have to be ignored inside comments */
-							if (*colon_indent)
-							{
-								*colon_indent = FALSE;
-								extra_indent -= INDENT_SIZE;
-							}
-						}
-						g_object_unref (prev);
-						g_object_unref (next);
-						break;
-						
-					}
-					else if (next_c == '/')
-					{
-						/* ends comment: */
-						comment_end = TRUE;
-						g_object_unref (prev);
-						g_object_unref (next);
-						continue;
-					}
-					/* Possibly continued comment */
-					else if (isspace(prev_c))
-					{
-						gboolean possible_comment = FALSE;
-						while (ianjuta_iterable_previous (prev, NULL))
-						{
-							prev_c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (prev), 0,
-															  	   NULL);
-							if (!isspace(prev_c))
-								break;
-							if (iter_is_newline (prev, prev_c))
-							{
-								possible_comment = TRUE;
-								break;
-							}
-						}
-						if (possible_comment)
-						{
-							ianjuta_iterable_assign (new_iter, prev, NULL);
-							g_object_unref (prev);
-							g_object_unref (next);
-							continue;
-						}
-					}
-					g_object_unref (prev);
-					g_object_unref (next);
-				}
-			} while (ianjuta_iterable_previous (new_iter, NULL));
-			if (comment)
-			{
-				ianjuta_iterable_assign (iter, new_iter, NULL);
-				ianjuta_iterable_previous (iter, NULL);
-				g_object_unref (new_iter);
-				continue;
-			}
-			g_object_unref (new_iter);
-		}
-		if (point_ch == ')' || point_ch == ']' || point_ch == '}')
-		{
-			gint line_saved;
-			
-			line_saved = ianjuta_editor_get_line_from_position (editor, iter,
-																NULL);
-			
-			/* If we encounter a block-end before anything else, the
-			 * statement could hardly be incomplte.
-			 */
-			if (point_ch == '}' && *incomplete_statement == -1)
-				*incomplete_statement = 0;
-			
-			/* If at level 0 indentation, encoutered a
-			 * block end, don't bother going further
-			 */
-			if (point_ch == '}' && get_line_indentation (editor, line_saved) <= 0)
-			{
-				line_indent = 0;
-				line_indent += extra_indent;
-				break;
-			}
-			
-			/* Find matching brace and continue */
-			if (!cpp_java_util_jump_to_matching_brace (iter, point_ch, -1))
-			{
-				line_indent = get_line_indentation (editor, line_saved);
-				line_indent += extra_indent;
-				break;
-			}
-		}
-		else if (point_ch == '{')
-		{
-			gint line_for_indent =
-				ianjuta_editor_get_line_from_position (editor, iter, NULL);
-			line_indent = get_line_indentation (editor, line_for_indent);
-			/* Increase line indentation */
-			line_indent += INDENT_SIZE;
-			line_indent += extra_indent;
-			
-			/* If we encounter a block-start before anything else, the
-			 * statement could hardly be incomplte.
-			 */
-			if (point_ch == '{' && *incomplete_statement == -1)
-				*incomplete_statement = 0;
-			
-			break;
-		}
-		else if (point_ch == '(' || point_ch == '[')
-		{
-			line_indent = 0;
-			if (g_settings_get_boolean (plugin->settings,
-			                            PREF_INDENT_PARANTHESE_LINEUP))
-			{
-				while (ianjuta_iterable_previous (iter, NULL))
-				{
-					gchar dummy_ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0,
-					                                               NULL);
-					if (iter_is_newline (iter, dummy_ch))
-					{
-						skip_iter_to_newline_head (iter, dummy_ch);
-						break;
-					}
-					if (dummy_ch == '\t')
-						line_indent += TAB_SIZE;
-					else
-						(*line_indent_spaces)++;
-				}
-				(*line_indent_spaces)++;
-				line_indent += extra_indent;
-			}
-			else
-			{
-				gint line_for_indent =
-					ianjuta_editor_get_line_from_position (editor, iter, NULL);
-				line_indent = get_line_indentation (editor, line_for_indent);
-				line_indent += extra_indent;
-
-				(*line_indent_spaces) += g_settings_get_int (plugin->settings,
-				                                             PREF_INDENT_PARANTHESE_SIZE);
-			}
-			
-			/* Although statement is incomplete at this point, we don't
-			 * set it to incomplete and just leave it to unknown to avaoid
-			 * increating indentation for it, because incomplete braces,
-			 * overrides any existing indentation
-			 */
-			*incomplete_statement = -1;
-			break;
-		}
-		else if (point_ch == ';' || point_ch == ',')
-		{
-			/* If we encounter statement-end before any non-whitespace
-			 * char, the statement is complete.
-			 */
-			if (*incomplete_statement == -1)
-				*incomplete_statement = 0;
-		}
-		else if (point_ch == ':' && *colon_indent == FALSE)
-		{
-			/* This is a forward reference, all lines below should have
-			 * increased indentation until the next statement has
-			 * a ':'
-			 * If current line indentation is zero, that we don't indent
-			 */
-			IAnjutaIterable* new_iter = ianjuta_iterable_clone (iter, NULL);
-			IAnjutaIterable* line_begin;
-			gboolean indent = FALSE;
-			gchar c;
-			
-			/* Is the last non-whitespace in line */
-			while (ianjuta_iterable_next (new_iter, NULL))
-			{
-				c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter),
-													   0, NULL);
-				if (!isspace(c))
-					break;
-				if (iter_is_newline (new_iter, c))
-				{
-					indent = TRUE;
-					break;
-				}
-			}
-			line_begin = ianjuta_editor_get_line_begin_position(editor,
-																ianjuta_editor_get_line_from_position(editor, iter, NULL),
-																NULL);
-			c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (line_begin),
-														0, NULL);
-			if (indent)
-			{
-				*colon_indent = TRUE;
-				if (*incomplete_statement == -1)
-					*incomplete_statement = 0;
-			}
-			if (indent && isspace(c))
-			{
-				extra_indent += INDENT_SIZE;
-			}
-			g_object_unref (new_iter);
-			g_object_unref (line_begin);
-		}	
-		else if (iter_is_newline (iter, point_ch))
-		{
-			skip_iter_to_newline_head (iter, point_ch);
-			
-			/* We just crossed a line boundary. Skip any preprocessor lines,
-			 * and ensure that line_indent is updated with correct real
-			 * previous non-preprocessor line.
-			 */
-			if (skip_preprocessor_lines (editor, iter) &&
-				looking_at_just_next_line)
-			{
-				/*
-				gint line = ianjuta_editor_get_line_from_position (editor, iter, NULL);
-				line_indent = get_line_indentation (editor, line);
-				*/
-			}
-			looking_at_just_next_line = FALSE;
-			line_checked_for_comment = FALSE;
-		}		 
-		else if (!isspace (point_ch))
-		{			
-			/* If we encounter any non-whitespace char before any of the
-			 * statement-complete indicators, the statement is basically
-			 * incomplete
-			 */
-			if (*incomplete_statement == -1)
-				*incomplete_statement = 1;
-		}
-	}
-	if (!line_indent && extra_indent)
-	{
-		line_indent += extra_indent;
-	}
-	g_object_unref (iter);
-		
-	return line_indent;
-}
-
-/* Check if iter is inside string. Begining of string
- * is not counted as inside.
- */
-static gboolean
-is_iter_inside_string (IAnjutaIterable *iter)
-{
-	IAnjutaEditorAttribute attrib;
-	
-	attrib = ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL (iter),
-												NULL);
-	/* Check if we are *inside* string. Begining
-	 * of string does not count as inside.
-	 */
-	if (attrib == IANJUTA_EDITOR_STRING)
-	{
-		/* Peek previous attrib and see what it was */
-		if (ianjuta_iterable_previous (iter, NULL))
-		{
-			attrib = ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL
-														(iter),	NULL);
-			if (attrib == IANJUTA_EDITOR_STRING)
-			{
-				/* We are inside string */
-				return TRUE;
-			}
-			else
-			{
-				/* The string just began, not inside.
-				 * Restore iter from the peek
-				 */
-				ianjuta_iterable_next (iter, NULL);
-			}
-		}
-		/* else, there is no previous and so we can't be inside string
-		 */
-	}
-	return FALSE;
-}
-
-static gboolean
-spaces_only (IAnjutaEditor* editor, IAnjutaIterable* begin, IAnjutaIterable* end)
-{
-	gboolean empty = TRUE;
-	gchar* idx;
-	gchar* text = ianjuta_editor_get_text (editor, begin, end, NULL);
-
-	if (text == NULL)
-		return TRUE;
-	
-
-	for (idx = text; *idx != '\0'; idx++)
-	{
-		if (!isspace(*idx))
-		{
-			empty = FALSE;
-			break;
-		}
-	}
-	g_free(text);
-	return empty;
-}
-
-static gint
-get_line_auto_indentation (CppJavaPlugin *plugin, IAnjutaEditor *editor,
-						   gint line, gint *line_indent_spaces)
-{
-	IAnjutaIterable *iter;
-	IAnjutaIterable *end_iter;
-	gint line_indent = 0;
-	gint incomplete_statement = -1;
-	gboolean colon_indent = FALSE;
-	
-	g_return_val_if_fail (line > 0, 0);
-
-	/* be sure to set a default if we're in the first line otherwise
-	 * the pointer'll be left hanging with no value.
-	 */
-	*line_indent_spaces = 0;
-	
-	if (line == 1) /* First line */
-	{
-		return 0;
-	}
-	else
-	{
-		IAnjutaIterable* begin = ianjuta_editor_get_line_begin_position (editor, line -1 , NULL);
-		IAnjutaIterable* end = ianjuta_editor_get_line_end_position (editor, line -1 , NULL);
-
-		if (spaces_only (editor, begin, end))
-		{
-			set_line_indentation (editor, line -1, 0, 0);
-		}
-		g_object_unref (begin);
-		g_object_unref (end);
-	}
-	
-	iter = ianjuta_editor_get_line_begin_position (editor, line, NULL);
-
-	if (is_iter_inside_string (iter))
-	{
-		line_indent = get_line_indentation (editor, line - 1);
-	}
-	else
-	{
-		line_indent = get_line_indentation_base (plugin, editor, line,
-												 &incomplete_statement, 
-												 line_indent_spaces,
-												 &colon_indent);
-	}
-
-	if (colon_indent)
-	{
-		/* If the last non-whitespace character in the line is ":" then
-		 * we remove the extra colon_indent
-		 */
-		end_iter = ianjuta_editor_get_line_end_position (editor, line, NULL);
-		gchar ch;
-		while (ianjuta_iterable_previous (end_iter, NULL))
-		{
-			ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (end_iter),
-			                                   0, NULL);
-			if (ch == ':')
-			{
-				line_indent -= INDENT_SIZE;
-				break;
-			}
-			if (!isspace(ch) || iter_is_newline (end_iter, ch))
-				break;
-		}
-		g_object_unref (end_iter);
-	}
-	
-	/* Determine what the first non-white char in the line is */
-	do
-	{
-		gchar ch;
-		/* Check if we are *inside* comment or string. Begining of comment
-		 * or string does not count as inside. If inside, just align with
-		 * previous indentation.
-		 */
-		if (is_iter_inside_string (iter))
-		{
-			line_indent = get_line_indentation (editor, line - 1);
-			break;
-		}
-		ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter),
-										   0, NULL);
-		if (iter_is_newline (iter, ch))
-		{
-			skip_iter_to_newline_tail (iter, ch);
-			
-			/* First levels are excused from incomplete statement indent */
-			if (incomplete_statement == 1 && line_indent > 0)
-				line_indent += INDENT_SIZE;
-			break;
-		}
-		
-		if (ch == '{')
-		{
-			if (line_indent > 0)
-			{
-				/* The first level braces are excused from brace indentation */
-				/*
-				DEBUG_PRINT ("Increasing indent level from %d to %d",
-							 line_indent,
-							 line_indent + BRACE_INDENT);
-				*/
-				line_indent += BRACE_INDENT;
-				/* It looks ugly to add extra indent after case: so remove that */
-				if (colon_indent)
-					line_indent -= INDENT_SIZE;
-			}
-			break;
-		}
-		else if (ch == '}')
-		{
-			ianjuta_iterable_previous (iter, NULL);
-			if (cpp_java_util_jump_to_matching_brace (iter, ch, -1))
-			{
-				gint line = ianjuta_editor_get_line_from_position (editor,
-																   iter,
-																   NULL);
-				line_indent = get_line_indentation (editor, line);
-			}
-			break;
-		}
-		else if (ch == '#')
-		{
-			line_indent = 0;
-			*line_indent_spaces = 0;
-		}
-		else if (!isspace (ch))
-		{
-			/* First levels are excused from incomplete statement indent */
-			if (incomplete_statement == 1 && line_indent > 0)
-				line_indent += INDENT_SIZE;
-			break;
-		}
-	}
-	while (ianjuta_iterable_next (iter, NULL));
-	g_object_unref (iter);
-	
-	return line_indent;
-}
-
-static gboolean
-is_commented_multiline (IAnjutaEditor *editor,
-						IAnjutaIterable *start,
-						IAnjutaIterable *end)
-{
-	gchar *text;
-	gboolean is_commented = TRUE;
-
-	text = ianjuta_editor_get_text (editor, start, end, NULL);
-	while (is_commented && !g_str_has_prefix (text, "/*"))
-	{
-		if (!ianjuta_iterable_previous (start, NULL))
-			is_commented = FALSE;
-		g_free (text);
-		text = ianjuta_editor_get_text (editor, start, end, NULL);
-		if (g_str_has_prefix (text, "*/"))
-			is_commented = FALSE;
-	}
-	while (is_commented && !g_str_has_suffix (text, "*/"))
-	{
-		if (!ianjuta_iterable_next (end, NULL))
-			is_commented = FALSE;
-		g_free (text);
-		text = ianjuta_editor_get_text (editor, start, end, NULL);
-		if (g_str_has_suffix (text, "/*"))
-			is_commented = FALSE;
-	}
-
-	g_free (text);
-	return is_commented;
-}
-
-static void
-toggle_comment_multiline (IAnjutaEditor *editor,
-					      IAnjutaIterable *start,
-					      IAnjutaIterable *end)
-{
-	IAnjutaIterable *start_copy, *end_copy;
-	gchar *text;
-	gboolean is_commented;
-
-	start_copy = ianjuta_iterable_clone (start, NULL);
-	end_copy = ianjuta_iterable_clone (end, NULL);
-	is_commented = is_commented_multiline (editor, start_copy, end_copy);
-	text = ianjuta_editor_get_text (editor, start_copy, end_copy, NULL);	
-
-	if (is_commented)
-	{
-		ianjuta_editor_erase (editor, start_copy, end_copy, NULL);
-		ianjuta_editor_insert (editor, start_copy, text + 2,
-							   (strlen (text) - 4), NULL);
-	}
-	else
-	{
-		ianjuta_editor_insert (editor, end, "*/", -1, NULL);
-		ianjuta_editor_insert (editor, start, "/*", -1, NULL);
-	}
-
-	g_object_unref (start_copy);
-	g_object_unref (end_copy);
-	g_free (text);
-}
-
-static void
-toggle_comment_singleline (CppJavaPlugin *plugin, IAnjutaEditor *editor,
-						   gint line)
-{
-	IAnjutaIterable *begin, *end, *begin_copy, *end_copy;
-	gchar *text, *text_stripped, **text_diff = NULL;
-
-	begin = ianjuta_editor_get_line_begin_position (editor, line, NULL);
-	end = ianjuta_editor_get_line_end_position (editor, line, NULL);
-	begin_copy = ianjuta_iterable_clone (begin, NULL);
-	end_copy = ianjuta_iterable_clone (end, NULL);
-
-	if (is_commented_multiline (editor, begin_copy, end_copy))
-	{
-		toggle_comment_multiline (editor, begin_copy, end_copy);
-		g_object_unref (begin);
-		g_object_unref (end);
-		g_object_unref (begin_copy);
-		g_object_unref (end_copy);
-		return;
-	}
-	g_object_unref (begin_copy);
-	g_object_unref (end_copy);
-
-	text = ianjuta_editor_get_text (editor, begin, end, NULL);
-	text_stripped = g_strstrip (g_strdup (text));
-	text_diff = g_strsplit (text, text_stripped, 2);
-
-	if (plugin->current_language &&
-		(g_str_equal (plugin->current_language, "C")))
-	{
-		if (g_str_has_prefix (text_stripped, "/*") &&
-			g_str_has_suffix (text_stripped, "*/"))
-		{
-			ianjuta_editor_erase (editor, begin, end, NULL);
-			ianjuta_editor_insert (editor, begin, text_stripped + 2,
-								   (strlen (text_stripped) - 4), NULL);
-			if (text_diff != NULL)
-				ianjuta_editor_insert (editor, begin, *text_diff, -1, NULL);
-		}
-		else
-		{
-			ianjuta_editor_insert (editor, end, "*/", -1, NULL);
-			ianjuta_editor_insert (editor, begin, "/*", -1, NULL);
-		}
-	}
-	else
-	{
-		if (g_str_has_prefix (text_stripped, "//"))
-		{
-			ianjuta_editor_erase (editor, begin, end, NULL);
-			ianjuta_editor_insert (editor, begin, text_stripped + 2, -1, NULL);
-			if (text_diff != NULL)
-				ianjuta_editor_insert (editor, begin, *text_diff, -1, NULL);
-		}
-		else
-		{
-			ianjuta_editor_insert (editor, begin, "//", -1, NULL);
-		}
-	}
-
-	g_object_unref (begin);
-	g_object_unref (end);
-	g_free (text);
-	g_free (text_stripped);
-	g_strfreev (text_diff);
-}
-
-static void on_editor_char_inserted_cpp (IAnjutaEditor *editor,
-                                         IAnjutaIterable *insert_pos,
-                                         gchar ch,
-                                         CppJavaPlugin *plugin);
-
-static void
-insert_editor_blocked (IAnjutaEditor* editor,
-                       IAnjutaIterable* iter,
-                       gchar* text,
-                       CppJavaPlugin* plugin)
-{
-	g_signal_handlers_block_by_func (editor, on_editor_char_inserted_cpp, plugin);
-	ianjuta_editor_insert (editor, iter, text, -1, NULL);
-	g_signal_handlers_unblock_by_func (editor, on_editor_char_inserted_cpp, plugin);
-}
-
-static void
-on_editor_char_inserted_cpp (IAnjutaEditor *editor,
-							 IAnjutaIterable *insert_pos,
-							 gchar ch,
-							 CppJavaPlugin *plugin)
-{
-	IAnjutaEditorAttribute attrib;
-	IAnjutaIterable *iter;
-	gboolean should_auto_indent = FALSE;
-
-	iter = ianjuta_iterable_clone (insert_pos, NULL);
-	
-	/* If autoindent is enabled*/
-	if (plugin->smart_indentation)
-	{
-	
-		/* DEBUG_PRINT ("Char added at position %d: '%c'", insert_pos, ch); */	
-	
-		if (iter_is_newline (iter, ch))
-		{
-			skip_iter_to_newline_head (iter, ch);
-			/* All newline entries means enable indenting */
-			should_auto_indent = TRUE;
-		}
-		else if (ch == '{' || ch == '}' || ch == '#')
-		{
-			/* Indent only when it's the first non-white space char in the line */
-		
-			/* Don't bother if we are inside string */
-			attrib = ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL (iter),
-														NULL);
-			if (attrib != IANJUTA_EDITOR_STRING)
-			{
-				/* Iterate backwards till the begining of the line and disable
-				 * indenting if any non-white space char is encountered
-				 */
-
-				/* Begin by assuming it should be indented */
-				should_auto_indent = TRUE;
-
-				while (ianjuta_iterable_previous (iter, NULL))
-				{
-					ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter),
-					                                   0, NULL);
-
-					//DEBUG_PRINT ("Looking at char '%c'", ch);
-
-					/* Break on begining of line (== end of previous line) */
-					if (iter_is_newline (iter, ch))
-					{
-						skip_iter_to_newline_head (iter, ch);
-						break;
-					}
-					/* If a non-white space char is encountered, disabled indenting */
-					if (!isspace (ch))
-					{
-						should_auto_indent = FALSE;
-						break;
-					}
-				}
-			}
-		}
-		if (should_auto_indent)
-		{
-			gint insert_line;
-			gint line_indent;
-			gint line_indent_spaces;
-		
-			ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor), NULL);
-			initialize_indentation_params (plugin);
-			
-			insert_line = ianjuta_editor_get_lineno (editor, NULL);
-			line_indent = get_line_auto_indentation (plugin, editor, insert_line, &line_indent_spaces);
-			set_line_indentation (editor, insert_line, line_indent, line_indent_spaces);
-			ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor), NULL);
-		}
-	}
-	
-	if (g_settings_get_boolean (plugin->settings, PREF_BRACE_AUTOCOMPLETION))
-	{
-		if (ch == '[' || ch == '(')
-		{
-			gchar *prev_char;
-			IAnjutaIterable *previous;
-			
-			previous = ianjuta_iterable_clone (iter, NULL);
-			ianjuta_iterable_previous (previous, NULL);
-			prev_char = ianjuta_editor_get_text (editor, previous, iter, NULL);
-			
-			/* If the previous char is a ' we don't have to autocomplete */
-			if (*prev_char != '\'')
-			{
-				ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT (editor), NULL);
-				ianjuta_iterable_next (iter, NULL);
-				switch (ch)
-				{
-					case '[': 
-							  insert_editor_blocked (editor, iter,
-													 "]", plugin);
-							  break;
-					case '(': 
-							  insert_editor_blocked (editor, iter,
-													 ")", plugin);
-							  break;
-					default: 
-						       break;
-				}
-				ianjuta_editor_goto_position (editor, iter, NULL);
-				ianjuta_document_end_undo_action (IANJUTA_DOCUMENT (editor), NULL);
-			}
-			g_object_unref (previous);
-		}
-		else if (ch == '"' || ch == '\'')
-		{
-			gchar *prev_char;
-			IAnjutaIterable *previous;
-
-			previous = ianjuta_iterable_clone (iter, NULL);
-			ianjuta_iterable_previous (previous, NULL);
-			prev_char = ianjuta_editor_get_text (editor, previous, iter, NULL);
-
-			/* First iter*/
-			ianjuta_iterable_next (iter, NULL);
-
-			/*
-			 * If the character is " we have to decide if we need insert
-			 * another " or we have to skip the character
-			 */
-			if (ch == '"' || ch == '\'')
-			{
-				/*
-				 * Now we have to detect if we want to manage " as a char
-				 */
-				if (*prev_char != '\'' && *prev_char != '\\')
-				{
-					gchar *c;
-					
-					if (ch == '"')
-						c = g_strdup ("\"");
-					else c = g_strdup ("'");
-					
-					ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT (editor), NULL);
-					insert_editor_blocked (editor, iter, c, plugin);
-					ianjuta_editor_goto_position (editor, iter, NULL);
-					ianjuta_document_end_undo_action (IANJUTA_DOCUMENT (editor), NULL);	
-					
-					g_free (c);
-				}
-				g_object_unref (previous);
-				g_object_unref (iter);
-				return;
-			}
-			g_object_unref (previous);
-		}
-	}
-	g_object_unref (iter);
-}
-
-static void
-on_editor_char_inserted_java (IAnjutaEditor *editor,
-							  IAnjutaIterable *insert_pos,
-							  gchar ch,
-							  CppJavaPlugin *plugin)
-{
-	on_editor_char_inserted_cpp (editor, insert_pos, ch, plugin);
-}
+/* Glade support */
 
 static void
 init_file_type (CppJavaPlugin* lang_plugin)
@@ -1915,6 +502,8 @@ on_glade_drop (IAnjutaEditor* editor,
 	g_strfreev (data);
 }
 
+/* Enable/Disable language-support */
+
 static void
 install_support (CppJavaPlugin *lang_plugin)
 {	
@@ -1942,7 +531,7 @@ install_support (CppJavaPlugin *lang_plugin)
 	{
 		g_signal_connect (lang_plugin->current_editor,
 						  "char-added",
-						  G_CALLBACK (on_editor_char_inserted_cpp),
+						  G_CALLBACK (cpp_indentation),
 						  lang_plugin);
 	}
 	else if (lang_plugin->current_language &&
@@ -1950,7 +539,7 @@ install_support (CppJavaPlugin *lang_plugin)
 	{
 		g_signal_connect (lang_plugin->current_editor,
 						  "char-added",
-						  G_CALLBACK (on_editor_char_inserted_java),
+						  G_CALLBACK (java_indentation),
 						  lang_plugin);
 	}
 	else
@@ -2002,14 +591,14 @@ uninstall_support (CppJavaPlugin *lang_plugin)
 		|| g_str_equal (lang_plugin->current_language, "Vala")))
 	{
 		g_signal_handlers_disconnect_by_func (lang_plugin->current_editor,
-									G_CALLBACK (on_editor_char_inserted_cpp),
+									G_CALLBACK (cpp_indentation),
 									lang_plugin);
 	}
 	else if (lang_plugin->current_language &&
 		(g_str_equal (lang_plugin->current_language, "Java")))
 	{
 		g_signal_handlers_disconnect_by_func (lang_plugin->current_editor,
-									G_CALLBACK (on_editor_char_inserted_java),
+									G_CALLBACK (java_indentation),
 									lang_plugin);
 	}
 	
@@ -2186,51 +775,149 @@ on_swap_activate (GtkAction* action, gpointer data)
 
 static void
 on_auto_indent (GtkAction *action, gpointer data)
-{
-	gint line_start, line_end;
-	gint insert_line;
-	gint line_indent;
-	gboolean has_selection;
-	
+{	
 	CppJavaPlugin *lang_plugin;
 	IAnjutaEditor *editor;
 	lang_plugin = ANJUTA_PLUGIN_CPP_JAVA (data);
 	editor = IANJUTA_EDITOR (lang_plugin->current_editor);
-	
-	has_selection = ianjuta_editor_selection_has_selection
-						(IANJUTA_EDITOR_SELECTION (editor), NULL);
-	if (has_selection)
+
+	cpp_auto_indentation (editor, lang_plugin);
+}
+
+/* Automatic comments */
+
+static gboolean
+is_commented_multiline (IAnjutaEditor *editor,
+						IAnjutaIterable *start,
+						IAnjutaIterable *end)
+{
+	gchar *text;
+	gboolean is_commented = TRUE;
+
+	text = ianjuta_editor_get_text (editor, start, end, NULL);
+	while (is_commented && !g_str_has_prefix (text, "/*"))
 	{
-		IAnjutaIterable *sel_start, *sel_end;
-		sel_start = ianjuta_editor_selection_get_start (IANJUTA_EDITOR_SELECTION (editor),
-														NULL);
-		sel_end = ianjuta_editor_selection_get_end (IANJUTA_EDITOR_SELECTION (editor),
-													NULL);
-		line_start = ianjuta_editor_get_line_from_position (editor, sel_start, NULL);
-		line_end = ianjuta_editor_get_line_from_position (editor, sel_end, NULL);
-		g_object_unref (sel_start);
-		g_object_unref (sel_end);
+		if (!ianjuta_iterable_previous (start, NULL))
+			is_commented = FALSE;
+		g_free (text);
+		text = ianjuta_editor_get_text (editor, start, end, NULL);
+		if (g_str_has_prefix (text, "*/"))
+			is_commented = FALSE;
+	}
+	while (is_commented && !g_str_has_suffix (text, "*/"))
+	{
+		if (!ianjuta_iterable_next (end, NULL))
+			is_commented = FALSE;
+		g_free (text);
+		text = ianjuta_editor_get_text (editor, start, end, NULL);
+		if (g_str_has_suffix (text, "/*"))
+			is_commented = FALSE;
+	}
+
+	g_free (text);
+	return is_commented;
+}
+
+static void
+toggle_comment_multiline (IAnjutaEditor *editor,
+					      IAnjutaIterable *start,
+					      IAnjutaIterable *end)
+{
+	IAnjutaIterable *start_copy, *end_copy;
+	gchar *text;
+	gboolean is_commented;
+
+	start_copy = ianjuta_iterable_clone (start, NULL);
+	end_copy = ianjuta_iterable_clone (end, NULL);
+	is_commented = is_commented_multiline (editor, start_copy, end_copy);
+	text = ianjuta_editor_get_text (editor, start_copy, end_copy, NULL);	
+
+	if (is_commented)
+	{
+		ianjuta_editor_erase (editor, start_copy, end_copy, NULL);
+		ianjuta_editor_insert (editor, start_copy, text + 2,
+							   (strlen (text) - 4), NULL);
 	}
 	else
 	{
-		line_start = ianjuta_editor_get_lineno (IANJUTA_EDITOR(editor), NULL);
-		line_end = line_start;
+		ianjuta_editor_insert (editor, end, "*/", -1, NULL);
+		ianjuta_editor_insert (editor, start, "/*", -1, NULL);
 	}
-	ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor), NULL);
-	initialize_indentation_params (lang_plugin);
-	
-	for (insert_line = line_start; insert_line <= line_end; insert_line++)
+
+	g_object_unref (start_copy);
+	g_object_unref (end_copy);
+	g_free (text);
+}
+
+static void
+toggle_comment_singleline (CppJavaPlugin *plugin, IAnjutaEditor *editor,
+						   gint line)
+{
+	IAnjutaIterable *begin, *end, *begin_copy, *end_copy;
+	gchar *text, *text_stripped, **text_diff = NULL;
+
+	begin = ianjuta_editor_get_line_begin_position (editor, line, NULL);
+	end = ianjuta_editor_get_line_end_position (editor, line, NULL);
+	begin_copy = ianjuta_iterable_clone (begin, NULL);
+	end_copy = ianjuta_iterable_clone (end, NULL);
+
+	if (is_commented_multiline (editor, begin_copy, end_copy))
 	{
-		gint line_indent_spaces = 0;
-		line_indent = get_line_auto_indentation (lang_plugin, editor,
-												 insert_line,
-												 &line_indent_spaces);
-		/* DEBUG_PRINT ("Line indent for line %d = %d", insert_line, line_indent); */
-		set_line_indentation (editor, insert_line, line_indent, line_indent_spaces);
+		toggle_comment_multiline (editor, begin_copy, end_copy);
+		g_object_unref (begin);
+		g_object_unref (end);
+		g_object_unref (begin_copy);
+		g_object_unref (end_copy);
+		return;
 	}
-	ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor), NULL);
+	g_object_unref (begin_copy);
+	g_object_unref (end_copy);
+
+	text = ianjuta_editor_get_text (editor, begin, end, NULL);
+	text_stripped = g_strstrip (g_strdup (text));
+	text_diff = g_strsplit (text, text_stripped, 2);
+
+	if (plugin->current_language &&
+		(g_str_equal (plugin->current_language, "C")))
+	{
+		if (g_str_has_prefix (text_stripped, "/*") &&
+			g_str_has_suffix (text_stripped, "*/"))
+		{
+			ianjuta_editor_erase (editor, begin, end, NULL);
+			ianjuta_editor_insert (editor, begin, text_stripped + 2,
+								   (strlen (text_stripped) - 4), NULL);
+			if (text_diff != NULL)
+				ianjuta_editor_insert (editor, begin, *text_diff, -1, NULL);
+		}
+		else
+		{
+			ianjuta_editor_insert (editor, end, "*/", -1, NULL);
+			ianjuta_editor_insert (editor, begin, "/*", -1, NULL);
+		}
+	}
+	else
+	{
+		if (g_str_has_prefix (text_stripped, "//"))
+		{
+			ianjuta_editor_erase (editor, begin, end, NULL);
+			ianjuta_editor_insert (editor, begin, text_stripped + 2, -1, NULL);
+			if (text_diff != NULL)
+				ianjuta_editor_insert (editor, begin, *text_diff, -1, NULL);
+		}
+		else
+		{
+			ianjuta_editor_insert (editor, begin, "//", -1, NULL);
+		}
+	}
+
+	g_object_unref (begin);
+	g_object_unref (end);
+	g_free (text);
+	g_free (text_stripped);
+	g_strfreev (text_diff);
 }
 
+
 static void
 on_toggle_comment (GtkAction *action, gpointer data)
 {
@@ -2265,6 +952,8 @@ on_toggle_comment (GtkAction *action, gpointer data)
 	ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor), NULL);
 }
 
+/* Plugin */
+
 static GtkActionEntry actions[] = {
 	{
 		"ActionMenuEdit",
diff --git a/plugins/language-support-cpp-java/plugin.h b/plugins/language-support-cpp-java/plugin.h
index 7c67b6c..ed9ac3c 100644
--- a/plugins/language-support-cpp-java/plugin.h
+++ b/plugins/language-support-cpp-java/plugin.h
@@ -18,6 +18,9 @@
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
+#ifndef _PLUGIN_H_
+#define _PLUGIN_H_
+
 #include <libanjuta/anjuta-plugin.h>
 #include <libanjuta/interfaces/ianjuta-editor.h>
 #include <libanjuta/interfaces/ianjuta-symbol-manager.h>
@@ -75,3 +78,5 @@ struct _CppJavaPlugin {
 struct _CppJavaPluginClass {
 	AnjutaPluginClass parent_class;
 };
+
+#endif
\ No newline at end of file



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