SF.net SVN: geany:[5322] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Mon Oct 25 16:58:13 UTC 2010


Revision: 5322
          http://geany.svn.sourceforge.net/geany/?rev=5322&view=rev
Author:   ntrel
Date:     2010-10-25 16:58:13 +0000 (Mon, 25 Oct 2010)

Log Message:
-----------
Auto-indent after an HTML/XML line with a missing closing tag (patch
by Eugene Arshinov, thanks).
Behaviour only applies if XML tag autoclosing is off.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/editor.c
    trunk/src/utils.c
    trunk/src/utils.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2010-10-25 16:24:55 UTC (rev 5321)
+++ trunk/ChangeLog	2010-10-25 16:58:13 UTC (rev 5322)
@@ -8,6 +8,10 @@
    src/document.c, src/document.h, THANKS, geany.glade:
    Add 'Ensure consistent line endings' file saving pref (patch by
    Manuel Bua, thanks).
+ * src/utils.c, src/utils.h, src/editor.c:
+   Auto-indent after an HTML/XML line with a missing closing tag (patch
+   by Eugene Arshinov, thanks).
+   Behaviour only applies if XML tag autoclosing is off.
 
 
 2010-10-22  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>

Modified: trunk/src/editor.c
===================================================================
--- trunk/src/editor.c	2010-10-25 16:24:55 UTC (rev 5321)
+++ trunk/src/editor.c	2010-10-25 16:58:13 UTC (rev 5322)
@@ -1304,6 +1304,37 @@
 }
 
 
+static gint get_xml_indent(ScintillaObject *sci, gint line)
+{
+	gboolean need_close = FALSE;
+	gint end = sci_get_line_end_position(sci, line) - 1;
+
+	if (sci_get_char_at(sci, end) == '>' &&
+		sci_get_char_at(sci, end - 1) != '/')
+	{
+		gint style = sci_get_style_at(sci, end);
+
+		if (style == SCE_H_TAG || style == SCE_H_TAGUNKNOWN)
+		{
+			gint start = sci_get_position_from_line(sci, line);
+			gchar *line_contents = sci_get_contents_range(sci, start, end + 1);
+			gchar *opened_tag_name = utils_find_open_xml_tag(line_contents, end + 1 - start);
+
+			if (NZV(opened_tag_name))
+			{
+				need_close = TRUE;
+				if (sci_get_lexer(sci) == SCLEX_HTML && utils_is_short_html_tag(opened_tag_name))
+					need_close = FALSE;
+			}
+			g_free(line_contents);
+			g_free(opened_tag_name);
+		}
+	}
+
+	return need_close ? 1 : 0;
+}
+
+
 static gint get_indent_size_after_line(GeanyEditor *editor, gint line)
 {
 	ScintillaObject *sci = editor->sci;
@@ -1316,11 +1347,25 @@
 
 	if (iprefs->auto_indent_mode > GEANY_AUTOINDENT_BASIC)
 	{
+		gint additional_indent = 0;
+
 		if (lexer_has_braces(sci))
-			size += iprefs->width * get_brace_indent(sci, line);
+			additional_indent = iprefs->width * get_brace_indent(sci, line);
 		else
 		if (FILETYPE_ID(editor->document->file_type) == GEANY_FILETYPES_PYTHON)
-			size += iprefs->width * get_python_indent(sci, line);
+			additional_indent = iprefs->width * get_python_indent(sci, line);
+
+		/* HTML lexer "has braces" because of PHP and JavaScript.  If get_brace_indent() did not
+		 * recommend us to insert additional indent, we are probably not in PHP/JavaScript chunk and
+		 * should make the XML-related check */
+		if (additional_indent == 0 && !editor_prefs.auto_close_xml_tags &&
+			(FILETYPE_ID(editor->document->file_type) == GEANY_FILETYPES_HTML ||
+			FILETYPE_ID(editor->document->file_type) == GEANY_FILETYPES_XML))
+		{
+			size += iprefs->width * get_xml_indent(sci, line);
+		}
+
+		size += additional_indent;
 	}
 	return size;
 }
@@ -2615,7 +2660,7 @@
 {
 	ScintillaObject *sci = editor->sci;
 	gint lexer = sci_get_lexer(sci);
-	gint min, style;
+	gint min, size, style;
 	gchar *str_found, sel[512];
 	gboolean result = FALSE;
 
@@ -2647,19 +2692,12 @@
 		/* User typed something like "<br/>" */
 		return FALSE;
 
-	str_found = utils_find_open_xml_tag(sel, pos - min, (ch == '/'));
+	size = pos - min;
+	if (ch == '/')
+		size -= 2; /* skip </ */
+	str_found = utils_find_open_xml_tag(sel, size);
 
-	/* when found string is something like br, img or another short tag, quit */
-	if (utils_str_equal(str_found, "br")
-	 || utils_str_equal(str_found, "hr")
-	 || utils_str_equal(str_found, "img")
-	 || utils_str_equal(str_found, "base")
-	 || utils_str_equal(str_found, "basefont")	/* < or not < */
-	 || utils_str_equal(str_found, "frame")
-	 || utils_str_equal(str_found, "input")
-	 || utils_str_equal(str_found, "link")
-	 || utils_str_equal(str_found, "area")
-	 || utils_str_equal(str_found, "meta"))
+	if (lexer == SCLEX_HTML && utils_is_short_html_tag(str_found))
 	{
 		/* ignore tag */
 	}

Modified: trunk/src/utils.c
===================================================================
--- trunk/src/utils.c	2010-10-25 16:24:55 UTC (rev 5321)
+++ trunk/src/utils.c	2010-10-25 16:58:13 UTC (rev 5322)
@@ -281,7 +281,7 @@
  * Search backward through size bytes looking for a '<', then return the tag, if any.
  * @return The tag name
  */
-gchar *utils_find_open_xml_tag(const gchar sel[], gint size, gboolean check_tag)
+gchar *utils_find_open_xml_tag(const gchar sel[], gint size)
 {
 	const gchar *begin, *cur;
 
@@ -290,10 +290,7 @@
 		return NULL;
 	}
 	begin = &sel[0];
-	if (check_tag)
-		cur = &sel[size - 3];
-	else
-		cur = &sel[size - 1];
+	cur = &sel[size-1];
 
 	/* Skip to the character before the closing brace */
 	while (cur > begin)
@@ -312,16 +309,18 @@
 	{
 		if (*cur == '<')
 			break;
-		else if (! check_tag && *cur == '>')
-			break;
 		--cur;
 	}
 
 	if (*cur == '<')
 	{
-		GString *result = g_string_sized_new(64);
+		GString *result;
 
 		cur++;
+		if (*cur == '/')
+			return NULL; /* we found a closing tag */
+
+		result = g_string_sized_new(64);
 		while (strchr(":_-.", *cur) || isalnum(*cur))
 		{
 			g_string_append_c(result, *cur);
@@ -334,6 +333,22 @@
 }
 
 
+/* Returns true if specified tag doesn't usually contain any content and can be left unclosed */
+gboolean utils_is_short_html_tag(const gchar *tag_name)
+{
+	return utils_str_equal(tag_name, "br")
+	 || utils_str_equal(tag_name, "hr")
+	 || utils_str_equal(tag_name, "img")
+	 || utils_str_equal(tag_name, "base")
+	 || utils_str_equal(tag_name, "basefont")	/* < or not < */
+	 || utils_str_equal(tag_name, "frame")
+	 || utils_str_equal(tag_name, "input")
+	 || utils_str_equal(tag_name, "link")
+	 || utils_str_equal(tag_name, "area")
+	 || utils_str_equal(tag_name, "meta");
+}
+
+
 const gchar *utils_get_eol_name(gint eol_mode)
 {
 	switch (eol_mode)
@@ -2063,5 +2078,3 @@
 	g_free(second);
 	return strv;
 }
-
-

Modified: trunk/src/utils.h
===================================================================
--- trunk/src/utils.h	2010-10-25 16:24:55 UTC (rev 5321)
+++ trunk/src/utils.h	2010-10-25 16:58:13 UTC (rev 5322)
@@ -140,8 +140,10 @@
 
 gint utils_write_file(const gchar *filename, const gchar *text);
 
-gchar *utils_find_open_xml_tag(const gchar sel[], gint size, gboolean check_tag);
+gchar *utils_find_open_xml_tag(const gchar sel[], gint size);
 
+gboolean utils_is_short_html_tag(const gchar *tag_name);
+
 void utils_ensure_same_eol_characters(GString *template, gint target_eol_mode);
 
 const gchar *utils_get_eol_char(gint eol_mode);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list