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. git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@5322 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
parent
c25d9856fe
commit
3c6212544c
@ -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>
|
||||
|
68
src/editor.c
68
src/editor.c
@ -1304,6 +1304,37 @@ static gint get_python_indent(ScintillaObject *sci, gint line)
|
||||
}
|
||||
|
||||
|
||||
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 @@ static gint get_indent_size_after_line(GeanyEditor *editor, gint line)
|
||||
|
||||
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 @@ static gboolean handle_xml(GeanyEditor *editor, gint pos, gchar ch)
|
||||
{
|
||||
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 @@ static gboolean handle_xml(GeanyEditor *editor, gint pos, gchar ch)
|
||||
/* 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 */
|
||||
}
|
||||
|
33
src/utils.c
33
src/utils.c
@ -281,7 +281,7 @@ gint utils_write_file(const gchar *filename, const gchar *text)
|
||||
* 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 @@ gchar *utils_find_open_xml_tag(const gchar sel[], gint size, gboolean check_tag)
|
||||
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 @@ gchar *utils_find_open_xml_tag(const gchar sel[], gint size, gboolean check_tag)
|
||||
{
|
||||
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 @@ gchar *utils_find_open_xml_tag(const gchar sel[], gint size, gboolean check_tag)
|
||||
}
|
||||
|
||||
|
||||
/* 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 @@ gchar **utils_strv_join(gchar **first, gchar **second)
|
||||
g_free(second);
|
||||
return strv;
|
||||
}
|
||||
|
||||
|
||||
|
@ -140,7 +140,9 @@ gboolean utils_is_opening_brace(gchar c, gboolean include_angles);
|
||||
|
||||
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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user