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@gmail.com\n" "Language-Team: Swedish geany-i18n@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(®ex, "^ *(\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(®ex, "^ *(\t)", cflags); + while (utils_string_regex_replace_all(buf, ®ex, 1, whitespace)); + regfree(®ex); + + /* 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(®ex, 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(®ex, str, cflags); + while (utils_string_regex_replace_all(buf, ®ex, 1, "\t")); + regfree(®ex); + g_free(str); } - regfree(®ex); + 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.