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.