Revision: 5725 http://geany.svn.sourceforge.net/geany/?rev=5725&view=rev Author: ntrel Date: 2011-04-14 17:37:46 +0000 (Thu, 14 Apr 2011)
Log Message: ----------- Fix snippets bug: {ob}pc{cb} replaced by '%' instead of {pc}. Refactor snippets_make_replacements() using geany_cursor_marker.
Modified Paths: -------------- trunk/ChangeLog trunk/src/editor.c
Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2011-04-13 21:55:31 UTC (rev 5724) +++ trunk/ChangeLog 2011-04-14 17:37:46 UTC (rev 5725) @@ -1,3 +1,10 @@ +2011-04-14 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com> + + * src/editor.c: + Fix snippets bug: {ob}pc{cb} replaced by '%' instead of {pc}. + Refactor snippets_make_replacements() using geany_cursor_marker. + + 2011-04-13 Colomban Wendling <colomban(at)geany(dot)org>
* src/editor.c:
Modified: trunk/src/editor.c =================================================================== --- trunk/src/editor.c 2011-04-13 21:55:31 UTC (rev 5724) +++ trunk/src/editor.c 2011-04-14 17:37:46 UTC (rev 5725) @@ -80,6 +80,8 @@ static gint snippet_cursor_insert_pos; static GtkAccelGroup *snippet_accel_group = NULL;
+static const gchar geany_cursor_marker[] = "__GEANY_CURSOR_MARKER__"; + /* holds word under the mouse or keyboard cursor */ static gchar current_word[GEANY_MAX_WORD_LENGTH];
@@ -2386,7 +2388,6 @@ gint line_end; gchar *whitespace; GString *buf; - const gchar cur_marker[] = "__GEANY_CURSOR_MARKER__"; const gchar *eol = editor_get_eol_char(editor); const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor);
@@ -2397,7 +2398,7 @@ buf = g_string_new(text);
if (cursor_index >= 0) - g_string_insert(buf, cursor_index, cur_marker); /* remember cursor pos */ + g_string_insert(buf, cursor_index, geany_cursor_marker); /* remember cursor pos */
if (newline_indent_size == -1) { @@ -2435,9 +2436,9 @@
if (cursor_index >= 0) { - gint idx = utils_strpos(buf->str, cur_marker); + gint idx = utils_strpos(buf->str, geany_cursor_marker);
- g_string_erase(buf, idx, strlen(cur_marker)); + g_string_erase(buf, idx, strlen(geany_cursor_marker));
sci_insert_text(sci, insert_pos, buf->str); sci_set_current_position(sci, insert_pos + idx, FALSE); @@ -2481,16 +2482,13 @@ }
-static gssize snippets_make_replacements(GeanyEditor *editor, GString *pattern, - gsize indent_size) +static gssize replace_cursor_markers(GeanyEditor *editor, GString *pattern, gsize indent_size); + +static gssize snippets_make_replacements(GeanyEditor *editor, GString *pattern, gsize indent_size) { - gssize cur_index = -1; gchar *whitespace; - gint i, tmp_pos, whitespace_len, nl_count = 0; GHashTable *specials; - GList *temp_list = NULL; const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor); - gint cursor_steps, old_cursor = 0;
/* replace 'special' completions */ specials = g_hash_table_lookup(snippet_hash, "Special"); @@ -2501,72 +2499,87 @@ g_hash_table_foreach(specials, snippets_replace_specials, NULL); }
- /* replace any template {foo} wildcards */ - templates_replace_common(pattern, editor->document->file_name, editor->document->file_type, NULL); + /* now transform other wildcards */
- /* transform other wildcards */ - /* convert to %newlines%, else we get endless loops */ - utils_string_replace_all(pattern, "\n", "%newline%"); + utils_string_replace_all(pattern, "%newline%", "\n");
- /* if spaces are used, replaces all tabs with %ws%, which is later replaced - * by real whitespace characters - * otherwise replace all %ws% by \t, which will be replaced later by tab - * characters, - * this makes seperating between tab and spaces intentation pretty easy */ + /* 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 */ - whitespace_len = strlen(whitespace); + 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); + + /* unescape '%' after all %wildcards% */ + templates_replace_valist(pattern, "{pc}", "%", NULL); + + /* 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) +{ + gssize cur_index = -1; + gint i, pos, idx, nl_count = 0; + GList *temp_list = NULL; + gint cursor_steps, old_cursor = 0; + i = 0; - while ((cursor_steps = utils_strpos(pattern->str, "%cursor%")) >= 0) + idx = 0; + while ((cursor_steps = utils_strpos(pattern->str, geany_cursor_marker)) >= 0) { - /* replace every %newline% (up to next %cursor%) with EOL, - * and update cursor_steps after */ - while ((tmp_pos = utils_strpos(pattern->str, "%newline%")) < cursor_steps && tmp_pos != -1) + /* replace every newline (up to next cursor) with EOL, + * count newlines and update cursor_steps after */ + while ((pos = utils_strpos(pattern->str + idx, "\n")) != -1) { + idx += pos; + if (idx >= cursor_steps) + break; + nl_count++; - utils_string_replace_first(pattern, "%newline%", editor_get_eol_char(editor)); - cursor_steps = utils_strpos(pattern->str, "%cursor%"); + g_string_erase(pattern, idx, 1); + g_string_insert(pattern, idx, editor_get_eol_char(editor)); + idx += editor_get_eol_char_len(editor); + + cursor_steps = utils_strpos(pattern->str, geany_cursor_marker); } - /* replace every %ws% (up to next %cursor%) with whitespaces, - * and update cursor_steps after */ - while ((tmp_pos = utils_strpos(pattern->str, "%ws%")) < cursor_steps && tmp_pos != -1) - { - utils_string_replace_first(pattern, "%ws%", whitespace); - cursor_steps = utils_strpos(pattern->str, "%cursor%"); - } - /* finally replace the next %cursor% */ - utils_string_replace_first(pattern, "%cursor%", ""); + utils_string_replace_first(pattern, geany_cursor_marker, ""); + idx = cursor_steps;
- /* modify cursor_steps to take indentation count and type into account */ - - /* We're saving the relative offset to each cursor position in a simple - * linked list, including indentations between them. */ 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 %ws% and %newline% which may occur after the last %cursor% */ - utils_string_replace_all(pattern, "%newline%", editor_get_eol_char(editor)); - utils_string_replace_all(pattern, "%ws%", whitespace); - g_free(whitespace); + /* replace remaining \n which may occur after the last cursor */ + while ((pos = utils_strpos(pattern->str + idx, "\n")) != -1) + { + idx += pos; + g_string_erase(pattern, idx, 1); + g_string_insert(pattern, idx, editor_get_eol_char(editor)); + idx += editor_get_eol_char_len(editor); + }
- /* escape % last */ - /* Bug: {ob}pc{cb} will be replaced by % too */ - templates_replace_valist(pattern, "{pc}", "%", NULL); - - /* We put the cursor positions for the most recent + /* put the cursor positions for the most recent * parsed snippet first, followed by any remaining positions */ i = 0; if (temp_list) @@ -2583,6 +2596,7 @@
g_list_free(temp_list); } + /* if there's no first cursor, skip whole snippet */ if (cur_index < 0) cur_index = pattern->len;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.