Use GRegex for snippet indentation replacement - fixes wrong
behaviour with Mac line endings. git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/branches/unstable@5973 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
parent
c6b38b861e
commit
9ca8db635a
@ -1,3 +1,10 @@
|
||||
2011-09-30 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
|
||||
|
||||
* src/utils.c, src/utils.h, src/editor.c:
|
||||
Use GRegex for snippet indentation replacement - fixes wrong
|
||||
behaviour with Mac line endings.
|
||||
|
||||
|
||||
2011-09-29 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
|
||||
|
||||
* src/build.c, doc/pluginsignals.c:
|
||||
|
61
src/editor.c
61
src/editor.c
@ -2272,63 +2272,18 @@ static void snippets_replace_specials(gpointer key, gpointer value, gpointer use
|
||||
}
|
||||
|
||||
|
||||
static gboolean utils_regex_find(regex_t *regex, const gchar *haystack, gsize start,
|
||||
gsize nmatches, regmatch_t *matches)
|
||||
{
|
||||
gint eflags = 0;
|
||||
|
||||
if (start > 0)
|
||||
{
|
||||
gchar c = haystack[start - 1];
|
||||
|
||||
if (c == '\n' || c == '\r')
|
||||
eflags = REG_NOTBOL;
|
||||
}
|
||||
return regexec(regex, haystack + start, nmatches, matches, eflags) == 0;
|
||||
}
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
gssize pos;
|
||||
regmatch_t matches[10];
|
||||
guint ret = 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))
|
||||
{
|
||||
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++;
|
||||
}
|
||||
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;
|
||||
GRegex *regex;
|
||||
gint cflags = G_REGEX_MULTILINE;
|
||||
|
||||
/* 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);
|
||||
regex = g_regex_new("^ *(\t)", cflags, 0, NULL);
|
||||
while (utils_string_regex_replace_all(buf, regex, 1, whitespace, TRUE));
|
||||
g_regex_unref(regex);
|
||||
|
||||
/* remaining tabs are for alignment */
|
||||
if (iprefs->type != GEANY_INDENT_TYPE_TABS)
|
||||
@ -2343,9 +2298,9 @@ static void fix_indentation(GeanyEditor *editor, GString *buf)
|
||||
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);
|
||||
regex = g_regex_new(str, cflags, 0, NULL);
|
||||
while (utils_string_regex_replace_all(buf, regex, 1, "\t", TRUE));
|
||||
g_regex_unref(regex);
|
||||
g_free(str);
|
||||
}
|
||||
g_free(whitespace);
|
||||
|
39
src/utils.c
39
src/utils.c
@ -1617,6 +1617,45 @@ guint utils_string_replace_first(GString *haystack, const gchar *needle, const g
|
||||
}
|
||||
|
||||
|
||||
/* Similar to g_regex_replace but allows matching a subgroup.
|
||||
* match_num: which match to replace, 0 for whole match.
|
||||
* literal: FALSE to interpret escape sequences in @a replace.
|
||||
* returns: number of replacements.
|
||||
* bug: replaced text can affect matching of ^ or \b */
|
||||
guint utils_string_regex_replace_all(GString *haystack, GRegex *regex,
|
||||
guint match_num, const gchar *replace, gboolean literal)
|
||||
{
|
||||
GMatchInfo *minfo;
|
||||
guint ret = 0;
|
||||
gint start = 0;
|
||||
|
||||
g_assert(literal); /* escapes not implemented yet */
|
||||
g_return_val_if_fail(replace, 0);
|
||||
|
||||
/* ensure haystack->str is not null */
|
||||
if (haystack->len == 0)
|
||||
return 0;
|
||||
|
||||
/* passing a start position makes G_REGEX_MATCH_NOTBOL automatic */
|
||||
while (g_regex_match_full(regex, haystack->str, -1, start, 0, &minfo, NULL))
|
||||
{
|
||||
gint end, len;
|
||||
|
||||
g_match_info_fetch_pos(minfo, match_num, &start, &end);
|
||||
len = end - start;
|
||||
utils_string_replace(haystack, start, len, replace);
|
||||
ret++;
|
||||
|
||||
/* skip past whole match */
|
||||
g_match_info_fetch_pos(minfo, 0, NULL, &end);
|
||||
start = end - len + strlen(replace);
|
||||
g_match_info_free(minfo);
|
||||
}
|
||||
g_match_info_free(minfo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Get project or default startup directory (if set), or NULL. */
|
||||
const gchar *utils_get_default_dir_utf8(void)
|
||||
{
|
||||
|
@ -178,6 +178,9 @@ guint utils_string_replace_all(GString *haystack, const gchar *needle, const gch
|
||||
|
||||
guint utils_string_replace_first(GString *haystack, const gchar *needle, const gchar *replace);
|
||||
|
||||
guint utils_string_regex_replace_all(GString *haystack, GRegex *regex,
|
||||
guint match_num, const gchar *replace, gboolean literal);
|
||||
|
||||
void utils_str_replace_all(gchar **haystack, const gchar *needle, const gchar *replacement);
|
||||
|
||||
gint utils_strpos(const gchar* haystack, const gchar *needle);
|
||||
|
Loading…
x
Reference in New Issue
Block a user