SF.net SVN: geany:[5811] branches/sm

statc at users.sourceforge.net statc at xxxxx
Sat May 21 09:01:55 UTC 2011


Revision: 5811
          http://geany.svn.sourceforge.net/geany/?rev=5811&view=rev
Author:   statc
Date:     2011-05-21 09:01:55 +0000 (Sat, 21 May 2011)

Log Message:
-----------
Merge trunk (revisions 5727..5737)

Modified Paths:
--------------
    branches/sm/ChangeLog
    branches/sm/plugins/geanyfunctions.h
    branches/sm/po/ChangeLog
    branches/sm/po/sv.po
    branches/sm/src/document.c
    branches/sm/src/document.h
    branches/sm/src/editor.c
    branches/sm/src/filetypes.c
    branches/sm/src/plugindata.h
    branches/sm/src/plugins.c
    branches/sm/src/templates.c
    branches/sm/src/ui_utils.c
    branches/sm/src/utils.c
    branches/sm/src/utils.h

Modified: branches/sm/ChangeLog
===================================================================
--- branches/sm/ChangeLog	2011-05-21 09:00:53 UTC (rev 5810)
+++ branches/sm/ChangeLog	2011-05-21 09:01:55 UTC (rev 5811)
@@ -1,3 +1,44 @@
+2011-04-25  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
+
+ * src/utils.c:
+   Fix warning in utils_find_open_xml_tag() with malformed tags like
+   <~foo> (oops).
+
+
+2011-04-23  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
+
+ * src/utils.c, src/utils.h, src/plugindata.h, src/plugins.c,
+   plugins/geanyfunctions.h:
+   Add utils_find_open_xml_tag_pos() API function (patch by Eugene
+   Arshinov, thanks).
+ * src/templates.c:
+   Replace dates on template insertion, not when loading templates.
+
+
+2011-04-19  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
+
+ * src/editor.c:
+   Fix multiple snippet cursor positions for Tabs + Spaces mode.
+   Simplify editor_insert_snippet() code now we use cursor marker
+   strings.
+ * src/utils.c, src/utils.h, src/editor.c:
+   Add utils_string_find() to search in a fixed range.
+   Change utils_string_replace() to just replace a fixed number of
+   characters.
+
+
+2011-04-17  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>
+
+ * src/plugindata.h, src/document.c, src/plugins.c, src/document.h,
+   plugins/geanyfunctions.h:
+   Add document_compare_by_tab_order() and
+   document_compare_by_tab_order_reverse() to the plugin API.
+ * src/ui_utils.c:
+   Use document_compare_by_tab_order() as default compare function
+   to sort the document list in the document notebook tab menu, this
+   fixes the currently broken default ordering.
+
+
 2011-04-15  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
 
  * src/utils.c, src/utils.h, src/editor.c:

Modified: branches/sm/plugins/geanyfunctions.h
===================================================================
--- branches/sm/plugins/geanyfunctions.h	2011-05-21 09:00:53 UTC (rev 5810)
+++ branches/sm/plugins/geanyfunctions.h	2011-05-21 09:01:55 UTC (rev 5811)
@@ -74,6 +74,10 @@
 	geany_functions->p_document->document_get_notebook_page
 #define document_compare_by_display_name \
 	geany_functions->p_document->document_compare_by_display_name
+#define document_compare_by_tab_order \
+	geany_functions->p_document->document_compare_by_tab_order
+#define document_compare_by_tab_order_reverse \
+	geany_functions->p_document->document_compare_by_tab_order_reverse
 #define editor_get_indent_prefs \
 	geany_functions->p_editor->editor_get_indent_prefs
 #define editor_create_widget \
@@ -258,6 +262,8 @@
 	geany_functions->p_utils->utils_copy_environment
 #define utils_find_open_xml_tag \
 	geany_functions->p_utils->utils_find_open_xml_tag
+#define utils_find_open_xml_tag_pos \
+	geany_functions->p_utils->utils_find_open_xml_tag_pos
 #define ui_dialog_vbox_new \
 	geany_functions->p_ui->ui_dialog_vbox_new
 #define ui_frame_new_with_alignment \

Modified: branches/sm/po/ChangeLog
===================================================================
--- branches/sm/po/ChangeLog	2011-05-21 09:00:53 UTC (rev 5810)
+++ branches/sm/po/ChangeLog	2011-05-21 09:01:55 UTC (rev 5811)
@@ -1,3 +1,9 @@
+2011-04-20  Frank Lanitz  <frank(at)frank(dot)uvena(dot)de>
+
+ * sv.po: Update of Swedish translation. Thanks to Tony Mattsson for
+          providing the update.
+
+
 2011-04-12  Frank Lanitz  <frank(at)frank(dot)uvena(dot)de>
 
  * de.po: Update of German translation.

Modified: branches/sm/po/sv.po
===================================================================
--- branches/sm/po/sv.po	2011-05-21 09:00:53 UTC (rev 5810)
+++ branches/sm/po/sv.po	2011-05-21 09:01:55 UTC (rev 5811)
@@ -8,7 +8,7 @@
 "Project-Id-Version: Geany 0.20\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2010-11-01 10:53+0100\n"
-"PO-Revision-Date: 2010-12-08 08:05+0100\n"
+"PO-Revision-Date: 2011-04-20 12:21+0100\n"
 "Last-Translator: Tony Mattsson <superxorn at gmail.com>\n"
 "Language-Team: Swedish <geany-i18n at uvena.de>\n"
 "MIME-Version: 1.0\n"
@@ -236,7 +236,7 @@
 #: ../src/build.c:1980
 #: ../src/build.c:2015
 msgid "Error Regular Expression:"
-msgstr "Fel på \"Regular Expression\""
+msgstr "Fel på reguljärt uttryck"
 
 #: ../src/build.c:2008
 msgid "Non-Filetype Commands"
@@ -1344,7 +1344,7 @@
 
 #: ../src/interface.c:805
 msgid "_More"
-msgstr "_More"
+msgstr "_Mer"
 
 #: ../src/interface.c:812
 #: ../src/keybindings.c:398
@@ -3820,11 +3820,11 @@
 #: ../src/search.c:227
 #: ../src/search.c:826
 msgid "_Use regular expressions"
-msgstr "Använd regular expressions"
+msgstr "Använd reguljära uttryck"
 
 #: ../src/search.c:230
 msgid "Use POSIX-like regular expressions. For detailed information about using regular expressions, please read the documentation."
-msgstr "Använd POSIX Regular Expressions. För mer information, se dokumentationen."
+msgstr "Använd POSIX Reguljära uttryck. För mer information, se dokumentationen."
 
 #: ../src/search.c:237
 msgid "Search _backwards"
@@ -3854,7 +3854,7 @@
 
 #: ../src/search.c:271
 msgid "Match from s_tart of word"
-msgstr "Sök från början av ord"
+msgstr "Sök i början av ord"
 
 #: ../src/search.c:405
 msgid "_Previous"
@@ -3886,7 +3886,7 @@
 #: ../src/search.c:455
 #: ../src/search.c:632
 msgid "In Sessi_on"
-msgstr "I Session"
+msgstr "I öppna dokument"
 
 #: ../src/search.c:460
 #: ../src/search.c:637

Modified: branches/sm/src/document.c
===================================================================
--- branches/sm/src/document.c	2011-05-21 09:00:53 UTC (rev 5810)
+++ branches/sm/src/document.c	2011-05-21 09:01:55 UTC (rev 5811)
@@ -3055,3 +3055,63 @@
 
 	return result;
 }
+
+
+/** Compares documents by their tab order.
+ * This matches @c GCompareFunc for use with e.g. @c g_ptr_array_sort().
+ *
+ * @param a @c GeanyDocument**.
+ * @param b @c GeanyDocument**.
+ * @warning The arguments take the address of each document pointer.
+ * @return Negative value if a < b; zero if a = b; positive value if a > b.
+ *
+ * @since 0.21 (GEANY_API_VERSION 209)
+ */
+gint document_compare_by_tab_order(gconstpointer a, gconstpointer b)
+{
+	GeanyDocument *doc_a = *((GeanyDocument**) a);
+	GeanyDocument *doc_b = *((GeanyDocument**) b);
+	gint notebook_position_doc_a;
+	gint notebook_position_doc_b;
+
+	notebook_position_doc_a = document_get_notebook_page(doc_a);
+	notebook_position_doc_b = document_get_notebook_page(doc_b);
+
+	if (notebook_position_doc_a < notebook_position_doc_b)
+		return -1;
+	if (notebook_position_doc_a > notebook_position_doc_b)
+		return 1;
+	/* equality */
+	return 0;
+}
+
+
+/** Compares documents by their tab order, in reverse order.
+ * This matches @c GCompareFunc for use with e.g. @c g_ptr_array_sort().
+ *
+ * @param a @c GeanyDocument**.
+ * @param b @c GeanyDocument**.
+ * @warning The arguments take the address of each document pointer.
+ * @return Negative value if a < b; zero if a = b; positive value if a > b.
+ *
+ * @since 0.21 (GEANY_API_VERSION 209)
+ */
+gint document_compare_by_tab_order_reverse(gconstpointer a, gconstpointer b)
+{
+	GeanyDocument *doc_a = *((GeanyDocument**) a);
+	GeanyDocument *doc_b = *((GeanyDocument**) b);
+	gint notebook_position_doc_a;
+	gint notebook_position_doc_b;
+
+	notebook_position_doc_a = document_get_notebook_page(doc_a);
+	notebook_position_doc_b = document_get_notebook_page(doc_b);
+
+	if (notebook_position_doc_a < notebook_position_doc_b)
+		return 1;
+	if (notebook_position_doc_a > notebook_position_doc_b)
+		return -1;
+	/* equality */
+	return 0;
+}
+
+

Modified: branches/sm/src/document.h
===================================================================
--- branches/sm/src/document.h	2011-05-21 09:00:53 UTC (rev 5810)
+++ branches/sm/src/document.h	2011-05-21 09:01:55 UTC (rev 5811)
@@ -264,4 +264,8 @@
 
 gint document_compare_by_display_name(gconstpointer a, gconstpointer b);
 
+gint document_compare_by_tab_order(gconstpointer a, gconstpointer b);
+
+gint document_compare_by_tab_order_reverse(gconstpointer a, gconstpointer b);
+
 #endif

Modified: branches/sm/src/editor.c
===================================================================
--- branches/sm/src/editor.c	2011-05-21 09:00:53 UTC (rev 5810)
+++ branches/sm/src/editor.c	2011-05-21 09:01:55 UTC (rev 5811)
@@ -86,7 +86,7 @@
 static gchar current_word[GEANY_MAX_WORD_LENGTH];
 
 /* whether there is a tag list update pending */
-static gboolean document_tags_update_pending = FALSE;
+static guint document_tags_update_source = 0;
 
 /* Initialised in keyfile.c. */
 GeanyEditorPrefs editor_prefs;
@@ -117,8 +117,8 @@
 		const gchar *wc, gboolean stem);
 static gsize count_indent_size(GeanyEditor *editor, const gchar *base_indent);
 static const gchar *snippets_find_completion_by_name(const gchar *type, const gchar *name);
-static gssize snippets_make_replacements(GeanyEditor *editor, GString *pattern,
-		gsize indent_size);
+static void snippets_make_replacements(GeanyEditor *editor, GString *pattern);
+static gssize replace_cursor_markers(GeanyEditor *editor, GString *pattern);
 
 
 void editor_snippets_free(void)
@@ -1008,19 +1008,17 @@
 	if (!main_status.quitting && DOC_VALID(doc))
 		document_update_tag_list(doc, TRUE);
 
-	document_tags_update_pending = FALSE;
+	document_tags_update_source = 0;
 	return FALSE;
 }
 
 
 static void request_tag_list_update(GeanyDocument *doc)
 {
-	if (!document_tags_update_pending)
-	{
-		document_tags_update_pending = TRUE;
-		g_timeout_add_full(G_PRIORITY_LOW, editor_prefs.autocompletion_update_freq,
-				on_document_update_tags_idle, doc, NULL);
-	}
+	if (document_tags_update_source)
+		g_source_remove(document_tags_update_source);
+	document_tags_update_source = g_timeout_add_full(G_PRIORITY_LOW,
+		editor_prefs.autocompletion_update_freq, on_document_update_tags_idle, doc, NULL);
 }
 
 
@@ -2289,76 +2287,98 @@
 }
 
 
-/* This is very ugly but passing the pattern to ac_replace_specials() doesn't work because it is
- * modified when replacing a completion but the foreach function still passes the old pointer
- * to ac_replace_specials, so we use a global pointer outside of ac_replace_specials and
- * ac_complete_constructs. Any hints to improve this are welcome. */
-static GString *snippets_global_pattern = NULL;
-
 static void snippets_replace_specials(gpointer key, gpointer value, gpointer user_data)
 {
 	gchar *needle;
+	GString *pattern = user_data;
 
 	g_return_if_fail(key != NULL);
 	g_return_if_fail(value != NULL);
 
 	needle = g_strconcat("%", (gchar*) key, "%", NULL);
 
-	utils_string_replace_all(snippets_global_pattern, needle, (gchar*) value);
+	utils_string_replace_all(pattern, needle, (gchar*) value);
 	g_free(needle);
 }
 
 
-/* this only works with spaces only indentation on the lines */
-static void fix_line_indents(GeanyEditor *editor, gint line_start, gint line_end)
+static gboolean utils_regex_find(regex_t *regex, const gchar *haystack, gsize start,
+		gsize nmatches, regmatch_t *matches)
 {
-	ScintillaObject *sci = editor->sci;
-	gint line, cur_line, cur_col, pos;
+	gint eflags = 0;
 
-	/* get the line, col position as fixing indentation will move cursor to start of line */
-	pos = sci_get_current_position(sci);
-	cur_col = sci_get_col_from_position(sci, pos);
-	cur_line = sci_get_current_line(sci);
-
-	for (line = line_start; line <= line_end; line++)
+	if (start > 0)
 	{
-		gint size = sci_get_line_indentation(sci, line);
+		gchar c = haystack[start - 1];
 
-		/* set to 0 first to trigger proper indent creation */
-		sci_set_line_indentation(sci, line, 0);
-		sci_set_line_indentation(sci, line, size);
+		if (c == '\n' || c == '\r')
+			eflags = REG_NOTBOL;
 	}
-	pos = scintilla_send_message(sci, SCI_FINDCOLUMN, cur_line, cur_col);
-	sci_set_current_position(sci, pos, FALSE);
+	return regexec(regex, haystack + start, nmatches, matches, eflags) == 0;
 }
 
 
-static void replace_leading_tabs(GString *str, const gchar *whitespace)
+/* match_index: which match to replace, 0 for whole regex.
+ * note: this doesn't support backreferences in replacements */
+static guint utils_string_regex_replace_all(GString *haystack,
+		regex_t *regex, guint match_index, const gchar *replace)
 {
-	regex_t regex;
 	gssize pos;
-	regmatch_t matches[2];
-	gchar *ptr;
+	regmatch_t matches[10];
+	guint ret = 0;
 
-	if (regcomp(&regex, "^ *(\t)", 0) != 0)
+	g_return_val_if_fail(match_index < 10, 0);
+
+	/* ensure haystack->str is not null */
+	if (haystack->len == 0)
+		return 0;
+
+	pos = 0;
+	while (utils_regex_find(regex, haystack->str, pos, G_N_ELEMENTS(matches), matches))
 	{
-		g_return_if_fail(FALSE);
+		regmatch_t *match = &matches[match_index];
+
+		g_return_val_if_fail(match->rm_so >= 0, FALSE);
+		pos += match->rm_so;
+		pos = utils_string_replace(haystack, pos, match->rm_eo - match->rm_so, replace);
+		ret++;
 	}
-	ptr = str->str;
-	while (ptr)
+	return ret;
+}
+
+
+static void fix_indentation(GeanyEditor *editor, GString *buf)
+{
+	const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor);
+	gchar *whitespace;
+	regex_t regex;
+	gint cflags = REG_EXTENDED | REG_NEWLINE;
+
+	/* transform leading tabs into indent widths (in spaces) */
+	whitespace = g_strnfill(iprefs->width, ' ');
+	regcomp(&regex, "^ *(\t)", cflags);
+	while (utils_string_regex_replace_all(buf, &regex, 1, whitespace));
+	regfree(&regex);
+
+	/* remaining tabs are for alignment */
+	if (iprefs->type != GEANY_INDENT_TYPE_TABS)
+		utils_string_replace_all(buf, "\t", whitespace);
+
+	/* use leading tabs */
+	if (iprefs->type != GEANY_INDENT_TYPE_SPACES)
 	{
-		if (regexec(&regex, ptr,
-			G_N_ELEMENTS(matches), matches, 0) != 0)
-			break;
+		gchar *str;
 
-		pos = matches[1].rm_so;
-		g_return_if_fail(pos >= 0);
-		pos += ptr - str->str;
-		g_string_erase(str, pos, 1);
-		g_string_insert(str, pos, whitespace);
-		ptr = str->str + pos + strlen(whitespace);
+		/* for tabs+spaces mode we want the real tab width, not indent width */
+		setptr(whitespace, g_strnfill(sci_get_tab_width(editor->sci), ' '));
+		str = g_strdup_printf("^\t*(%s)", whitespace);
+
+		regcomp(&regex, str, cflags);
+		while (utils_string_regex_replace_all(buf, &regex, 1, "\t"));
+		regfree(&regex);
+		g_free(str);
 	}
-	regfree(&regex);
+	g_free(whitespace);
 }
 
 
@@ -2385,11 +2405,10 @@
 {
 	ScintillaObject *sci = editor->sci;
 	gint line_start = sci_get_line_from_position(sci, insert_pos);
-	gint line_end;
 	gchar *whitespace;
 	GString *buf;
 	const gchar *eol = editor_get_eol_char(editor);
-	const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor);
+	gint idx;
 
 	g_return_if_fail(text);
 	g_return_if_fail(editor != NULL);
@@ -2405,7 +2424,8 @@
 		/* count indent size up to insert_pos instead of asking sci
 		 * because there may be spaces after it */
 		gchar *tmp = sci_get_line(sci, line_start);
-		gint idx = insert_pos - sci_get_position_from_line(sci, line_start);
+
+		idx = insert_pos - sci_get_position_from_line(sci, line_start);
 		tmp[idx] = '\0';
 		newline_indent_size = count_indent_size(editor, tmp);
 		g_free(tmp);
@@ -2424,32 +2444,19 @@
 	if (replace_newlines)
 		utils_string_replace_all(buf, "\n", eol);
 
-	/* transform leading tabs into indent widths (in spaces) */
-	whitespace = g_strnfill(iprefs->width, ' ');
-	replace_leading_tabs(buf, whitespace);
-	/* remaining tabs are for alignment */
-	if (iprefs->type != GEANY_INDENT_TYPE_TABS)
-		utils_string_replace_all(buf, "\t", whitespace);
-	g_free(whitespace);
+	fix_indentation(editor, buf);
 
-	sci_start_undo_action(sci);
-
-	if (cursor_index >= 0)
+	idx = replace_cursor_markers(editor, buf);
+	if (idx >= 0)
 	{
-		gint idx = utils_string_replace(buf, 0, -1, geany_cursor_marker, NULL);
-
 		sci_insert_text(sci, insert_pos, buf->str);
 		sci_set_current_position(sci, insert_pos + idx, FALSE);
 	}
 	else
 		sci_insert_text(sci, insert_pos, buf->str);
 
-	/* fixup indentation (very useful for Tabs & Spaces indent type) */
-	line_end = sci_get_line_from_position(sci, insert_pos + buf->len);
-	fix_line_indents(editor, line_start, line_end);
 	snippet_cursor_insert_pos = sci_get_current_position(sci);
 
-	sci_end_undo_action(sci);
 	g_string_free(buf, TRUE);
 }
 
@@ -2480,38 +2487,21 @@
 }
 
 
-static gssize replace_cursor_markers(GeanyEditor *editor, GString *pattern, gsize indent_size);
-
-static gssize snippets_make_replacements(GeanyEditor *editor, GString *pattern, gsize indent_size)
+static void snippets_make_replacements(GeanyEditor *editor, GString *pattern)
 {
-	gchar *whitespace;
 	GHashTable *specials;
-	const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor);
 
 	/* replace 'special' completions */
 	specials = g_hash_table_lookup(snippet_hash, "Special");
 	if (G_LIKELY(specials != NULL))
 	{
-		/* ugly hack using global_pattern */
-		snippets_global_pattern = pattern;
-		g_hash_table_foreach(specials, snippets_replace_specials, NULL);
+		g_hash_table_foreach(specials, snippets_replace_specials, pattern);
 	}
 
 	/* now transform other wildcards */
-
 	utils_string_replace_all(pattern, "%newline%", "\n");
+	utils_string_replace_all(pattern, "%ws%", "\t");
 
-	/* if spaces are used, replace tabs with spaces
-	 * otherwise replace all %ws% by \t */
-	if (iprefs->type == GEANY_INDENT_TYPE_SPACES)
-		utils_string_replace_all(pattern, "\t", "%ws%");
-	else
-		utils_string_replace_all(pattern, "%ws%", "\t");
-
-	whitespace = g_strnfill(iprefs->width, ' '); /* use spaces for indentation, will be fixed up */
-	utils_string_replace_all(pattern, "%ws%", whitespace);
-	g_free(whitespace);
-
 	/* replace %cursor% by a very unlikely string marker */
 	utils_string_replace_all(pattern, "%cursor%", geany_cursor_marker);
 
@@ -2520,62 +2510,38 @@
 
 	/* replace any template {foo} wildcards */
 	templates_replace_common(pattern, editor->document->file_name, editor->document->file_type, NULL);
-
-	return replace_cursor_markers(editor, pattern, indent_size);
 }
 
 
-static gssize replace_cursor_markers(GeanyEditor *editor, GString *pattern, gsize indent_size)
+static gssize replace_cursor_markers(GeanyEditor *editor, GString *pattern)
 {
 	gssize cur_index = -1;
-	gint i, idx, nl_count = 0;
+	gint i;
 	GList *temp_list = NULL;
-	gint cursor_steps, old_cursor = 0;
+	gint cursor_steps = 0, old_cursor = 0;
 
 	i = 0;
-	idx = 0;
-	while ((cursor_steps = utils_strpos(pattern->str, geany_cursor_marker)) >= 0)
+	while (1)
 	{
-		/* replace every newline (up to next cursor) with EOL,
-		 * count newlines and update cursor_steps after */
-		while (1)
-		{
-			idx = utils_string_replace(pattern, idx, cursor_steps, "\n", editor_get_eol_char(editor));
-			if (idx == -1)
-				break;
+		cursor_steps = utils_string_find(pattern, cursor_steps, -1, geany_cursor_marker);
+		if (cursor_steps == -1)
+			break;
 
-			nl_count++;
-			idx += editor_get_eol_char_len(editor);
+		g_string_erase(pattern, cursor_steps, strlen(geany_cursor_marker));
 
-			cursor_steps = utils_strpos(pattern->str, geany_cursor_marker);
-		}
-		utils_string_replace_first(pattern, geany_cursor_marker, "");
-		idx = cursor_steps;
-
 		if (i++ > 0)
 		{
 			/* save the relative offset to each cursor position */
-			cursor_steps += (nl_count * indent_size);
 			temp_list = g_list_prepend(temp_list, GINT_TO_POINTER(cursor_steps - old_cursor));
 		}
 		else
 		{
 			/* first cursor already includes newline positions */
-			nl_count = 0;
 			cur_index = cursor_steps;
 		}
 		old_cursor = cursor_steps;
 	}
-	/* replace remaining \n which may occur after the last cursor */
-	while (1)
-	{
-		idx = utils_string_replace(pattern, idx, -1, "\n", editor_get_eol_char(editor));
-		if (idx == -1)
-			break;
 
-		idx += editor_get_eol_char_len(editor);
-	}
-
 	/* put the cursor positions for the most recent
 	 * parsed snippet first, followed by any remaining positions */
 	i = 0;
@@ -5110,12 +5076,10 @@
  */
 void editor_insert_snippet(GeanyEditor *editor, gint pos, const gchar *snippet)
 {
-	gint cursor_pos;
 	GString *pattern;
 
 	pattern = g_string_new(snippet);
-	read_indent(editor, pos);
-	cursor_pos = snippets_make_replacements(editor, pattern, strlen(indent));
-	editor_insert_text_block(editor, pattern->str, pos, cursor_pos, -1, FALSE);
+	snippets_make_replacements(editor, pattern);
+	editor_insert_text_block(editor, pattern->str, pos, -1, -1, FALSE);
 	g_string_free(pattern, TRUE);
 }

Modified: branches/sm/src/filetypes.c
===================================================================
--- branches/sm/src/filetypes.c	2011-05-21 09:00:53 UTC (rev 5810)
+++ branches/sm/src/filetypes.c	2011-05-21 09:01:55 UTC (rev 5811)
@@ -1248,22 +1248,30 @@
 
 static void add_group_keys(GKeyFile *kf, const gchar *group, GeanyFiletype *ft)
 {
-	GKeyFile *src = g_key_file_new();
-	gchar *f;
+	gchar *files[2];
+	gboolean loaded = FALSE;
+	guint i;
 
-	f = filetypes_get_filename(ft, FALSE);
-	if (!g_file_test(f, G_FILE_TEST_EXISTS))
-		f = filetypes_get_filename(ft, TRUE);
+	files[0] = filetypes_get_filename(ft, FALSE);
+	files[1] = filetypes_get_filename(ft, TRUE);
 
-	if (!g_key_file_load_from_file(src, f, G_KEY_FILE_NONE, NULL))
+	for (i = 0; i < G_N_ELEMENTS(files); i++)
 	{
-		geany_debug("Could not read config file %s for [%s=%s]!", f, group, ft->name);
-		g_free(f);
-		return;
+		GKeyFile *src = g_key_file_new();
+
+		if (g_key_file_load_from_file(src, files[i], G_KEY_FILE_NONE, NULL))
+		{
+			add_keys(kf, group, src);
+			loaded = TRUE;
+		}
+		g_key_file_free(src);
 	}
-	g_free(f);
 
-	add_keys(kf, group, src);
+	if (!loaded)
+		geany_debug("Could not read config file %s for [%s=%s]!", files[0], group, ft->name);
+
+	g_free(files[0]);
+	g_free(files[1]);
 }
 
 

Modified: branches/sm/src/plugindata.h
===================================================================
--- branches/sm/src/plugindata.h	2011-05-21 09:00:53 UTC (rev 5810)
+++ branches/sm/src/plugindata.h	2011-05-21 09:01:55 UTC (rev 5811)
@@ -54,7 +54,7 @@
  * @warning You should not test for values below 200 as previously
  * @c GEANY_API_VERSION was defined as an enum value, not a macro.
  */
-#define GEANY_API_VERSION 208
+#define GEANY_API_VERSION 210
 
 /** The Application Binary Interface (ABI) version, incremented whenever
  * existing fields in the plugin data types have to be changed or reordered.
@@ -311,6 +311,8 @@
 	gchar*		(*document_get_basename_for_display) (struct GeanyDocument *doc, gint length);
 	gint		(*document_get_notebook_page) (struct GeanyDocument *doc);
 	gint		(*document_compare_by_display_name) (gconstpointer a, gconstpointer b);
+	gint		(*document_compare_by_tab_order) (gconstpointer a, gconstpointer b);
+	gint		(*document_compare_by_tab_order_reverse) (gconstpointer a, gconstpointer b);
 }
 DocumentFuncs;
 
@@ -437,6 +439,7 @@
 				GError **error);
 	gchar**		(*utils_copy_environment)(const gchar **exclude_vars, const gchar *first_varname, ...);
 	gchar*		(*utils_find_open_xml_tag) (const gchar sel[], gint size);
+	const gchar*	(*utils_find_open_xml_tag_pos) (const gchar sel[], gint size);
 }
 UtilsFuncs;
 

Modified: branches/sm/src/plugins.c
===================================================================
--- branches/sm/src/plugins.c	2011-05-21 09:00:53 UTC (rev 5810)
+++ branches/sm/src/plugins.c	2011-05-21 09:01:55 UTC (rev 5811)
@@ -112,7 +112,9 @@
 	&document_get_status_color,
 	&document_get_basename_for_display,
 	&document_get_notebook_page,
-	&document_compare_by_display_name
+	&document_compare_by_display_name,
+	&document_compare_by_tab_order,
+	&document_compare_by_tab_order_reverse
 };
 
 static EditorFuncs editor_funcs = {
@@ -223,7 +225,8 @@
 	&utils_str_remove_chars,
 	&utils_get_file_list_full,
 	&utils_copy_environment,
-	&utils_find_open_xml_tag
+	&utils_find_open_xml_tag,
+	&utils_find_open_xml_tag_pos
 };
 
 static UIUtilsFuncs uiutils_funcs = {

Modified: branches/sm/src/templates.c
===================================================================
--- branches/sm/src/templates.c	2011-05-21 09:00:53 UTC (rev 5810)
+++ branches/sm/src/templates.c	2011-05-21 09:01:55 UTC (rev 5811)
@@ -104,27 +104,6 @@
 }
 
 
-/* TODO the callers should use GStrings instead of char arrays */
-static gchar *replace_all(gchar *text, const gchar *year, const gchar *date, const gchar *datetime)
-{
-	GString *str;
-
-	if (text == NULL)
-		return NULL;
-
-	str = g_string_new(text);
-
-	g_free(text);
-	templates_replace_valist(str,
-		"{year}", year,
-		"{date}", date,
-		"{datetime}", datetime,
-		NULL);
-
-	return g_string_free(str, FALSE);
-}
-
-
 /* called when inserting templates into an existing document */
 static void convert_eol_characters(GString *template, GeanyDocument *doc)
 {
@@ -140,20 +119,14 @@
 }
 
 
-static void init_general_templates(const gchar *year, const gchar *date, const gchar *datetime)
+static void init_general_templates(void)
 {
-	guint id;
-
 	/* read the contents */
 	read_template("fileheader", GEANY_TEMPLATE_FILEHEADER);
 	read_template("gpl", GEANY_TEMPLATE_GPL);
 	read_template("bsd", GEANY_TEMPLATE_BSD);
 	read_template("function", GEANY_TEMPLATE_FUNCTION);
 	read_template("changelog", GEANY_TEMPLATE_CHANGELOG);
-
-	/* FIXME: we should replace the dates on insertion, not on loading */
-	for (id = 0; id < GEANY_MAX_TEMPLATES; id++)
-		templates[id] = replace_all(templates[id], year, date, datetime);
 }
 
 
@@ -344,17 +317,10 @@
 /* warning: also called when reloading template settings */
 void templates_init(void)
 {
-	gchar *year = utils_get_date_time(template_prefs.year_format, NULL);
-	gchar *date = utils_get_date_time(template_prefs.date_format, NULL);
-	gchar *datetime = utils_get_date_time(template_prefs.datetime_format, NULL);
 	static gboolean init_done = FALSE;
 
-	init_general_templates(year, date, datetime);
+	init_general_templates();
 
-	g_free(date);
-	g_free(datetime);
-	g_free(year);
-
 	create_file_template_menu();
 	/* we hold our own ref for the menu as it has no parent whilst being moved */
 	g_object_ref(new_with_template_menu);

Modified: branches/sm/src/ui_utils.c
===================================================================
--- branches/sm/src/ui_utils.c	2011-05-21 09:00:53 UTC (rev 5810)
+++ branches/sm/src/ui_utils.c	2011-05-21 09:01:55 UTC (rev 5811)
@@ -2482,9 +2482,11 @@
 	{
 		g_ptr_array_add(sorted_documents, documents[i]);
 	}
+	if (compare_func == NULL)
+		compare_func = document_compare_by_tab_order;
+
 	/* and now sort it */
-	if (compare_func != NULL)
-		g_ptr_array_sort(sorted_documents, compare_func);
+	g_ptr_array_sort(sorted_documents, compare_func);
 
 	for (i = 0; i < sorted_documents->len; i++)
 	{

Modified: branches/sm/src/utils.c
===================================================================
--- branches/sm/src/utils.c	2011-05-21 09:00:53 UTC (rev 5810)
+++ branches/sm/src/utils.c	2011-05-21 09:01:55 UTC (rev 5811)
@@ -288,13 +288,37 @@
 }
 
 
-/** Searches backward through @a size bytes looking for a '<', then returns the tag, if any.
+/** Searches backward through @a size bytes looking for a '<'.
  * @param sel .
  * @param size .
- * @return The tag name.
+ * @return The tag name (newly allocated) or @c NULL if no opening tag was found.
  */
 gchar *utils_find_open_xml_tag(const gchar sel[], gint size)
 {
+	const gchar *cur, *begin;
+	gint len;
+
+	cur = utils_find_open_xml_tag_pos(sel, size);
+	if (cur == NULL)
+		return NULL;
+
+	cur++; /* skip the bracket */
+	begin = cur;
+	while (strchr(":_-.", *cur) || isalnum(*cur))
+		cur++;
+
+	len = cur - begin;
+	return len ? g_strndup(begin, len) : NULL;
+}
+
+
+/** Searches backward through @a size bytes looking for a '<'.
+ * @param sel .
+ * @param size .
+ * @return pointer to '<' of the found opening tag within @a sel, or @c NULL if no opening tag was found.
+ */
+const gchar *utils_find_open_xml_tag_pos(const gchar sel[], gint size)
+{
 	/* stolen from anjuta and modified */
 	const gchar *begin, *cur;
 
@@ -322,28 +346,16 @@
 	{
 		if (*cur == '<')
 			break;
+		/* exit immediately if such non-valid XML/HTML is detected, e.g. "<script>if a >" */
 		else if (*cur == '>')
 			break;
 		--cur;
 	}
 
-	if (*cur == '<')
-	{
-		GString *result;
+	/* if the found tag is an opening, not a closing tag or empty <> */
+	if (*cur == '<' && *(cur + 1) != '/' && *(cur + 1) != '>')
+		return cur;
 
-		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);
-			cur++;
-		}
-		return g_string_free(result, FALSE);
-	}
-
 	return NULL;
 }
 
@@ -1533,11 +1545,9 @@
 }
 
 
-/* Replaces needle if in range.
- * end can be -1 for haystack->len.
- * returns: position of replaced text or -1. */
-gint utils_string_replace(GString *haystack, gint start, gint end,
-		const gchar *needle, const gchar *replace)
+/* end can be -1 for haystack->len.
+ * returns: position of found text or -1. */
+gint utils_string_find(GString *haystack, gint start, gint end, const gchar *needle)
 {
 	gint pos;
 
@@ -1561,14 +1571,22 @@
 	pos += start;
 	if (pos >= end)
 		return -1;
-
-	g_string_erase(haystack, pos, strlen(needle));
-	if (G_LIKELY(replace))
-		g_string_insert(haystack, pos, replace);
 	return pos;
 }
 
 
+/* Replaces @len characters from offset @a pos.
+ * len can be -1 for str->len.
+ * returns: pos + strlen(replace). */
+gint utils_string_replace(GString *str, gint pos, gint len, const gchar *replace)
+{
+	g_string_erase(str, pos, len);
+	g_string_insert(str, pos, replace);
+
+	return pos + strlen(replace);
+}
+
+
 /**
  * Replaces all occurrences of @a needle in @a haystack with @a replace.
  * As of Geany 0.16, @a replace can match @a needle, so the following will work:
@@ -1587,13 +1605,12 @@
 
 	while (1)
 	{
-		pos = utils_string_replace(haystack, pos, -1, needle, replace);
+		pos = utils_string_find(haystack, pos, -1, needle);
 
 		if (pos == -1)
 			break;
 
-		if (replace)
-			pos += strlen(replace);
+		pos = utils_string_replace(haystack, pos, strlen(needle), replace);
 		count++;
 	}
 	return count;
@@ -1615,7 +1632,13 @@
  */
 guint utils_string_replace_first(GString *haystack, const gchar *needle, const gchar *replace)
 {
-	return utils_string_replace(haystack, 0, -1, needle, replace) == -1 ? 0 : 1;
+	gint pos = utils_string_find(haystack, 0, -1, needle);
+
+	if (pos == -1)
+		return 0;
+
+	utils_string_replace(haystack, pos, strlen(needle), replace);
+	return 1;
 }
 
 

Modified: branches/sm/src/utils.h
===================================================================
--- branches/sm/src/utils.h	2011-05-21 09:00:53 UTC (rev 5810)
+++ branches/sm/src/utils.h	2011-05-21 09:01:55 UTC (rev 5811)
@@ -146,6 +146,8 @@
 
 gchar *utils_find_open_xml_tag(const gchar sel[], gint size);
 
+const gchar *utils_find_open_xml_tag_pos(const gchar sel[], gint size);
+
 gboolean utils_is_short_html_tag(const gchar *tag_name);
 
 void utils_ensure_same_eol_characters(GString *string, gint target_eol_mode);
@@ -172,9 +174,10 @@
 
 gchar *utils_get_hostname(void);
 
-gint utils_string_replace(GString *haystack, gint start, gint end,
-		const gchar *needle, const gchar *replace);
+gint utils_string_find(GString *haystack, gint start, gint end, const gchar *needle);
 
+gint utils_string_replace(GString *str, gint pos, gint len, const gchar *replace);
+
 guint utils_string_replace_all(GString *haystack, const gchar *needle, const gchar *replace);
 
 guint utils_string_replace_first(GString *haystack, const gchar *needle, const gchar *replace);


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