Branch: refs/heads/master Author: Colomban Wendling ban@herbesfolles.org Committer: Colomban Wendling ban@herbesfolles.org Date: Fri, 12 Oct 2012 18:40:38 Commit: 220ace841ca08baff629e2443df92540aa8fca62 https://github.com/geany/geany/commit/220ace841ca08baff629e2443df92540aa8fca...
Log Message: ----------- Fix uncommenting multi-line comments when cursor is on a delimiter
If the cursor was inside one of the comment's delimiters, the code used to look for another delimiter, leading to removing previous comment's start. Moreover, the code assumed the delimiter will always be found, leading to improper deletions if a delimiter could not be found (either because of the above problem or because the comment wasn't terminated).
Also, the code used document_find_text() which, if the searched text cannot be found on the requested direction, either wraps or asks the user whether to wrap. Wrapping is wrong if there is more than one single comment in the file, and the dialog is confusing for the use since she didn't ask for it.
So, rework the code for it to correctly find the delimiters, and not to wrap search or ask the user. It is also simpler by reusing some already existing code.
Modified Paths: -------------- src/editor.c
Modified: src/editor.c 86 files changed, 54 insertions(+), 32 deletions(-) =================================================================== @@ -109,6 +109,7 @@ static void read_current_word(GeanyEditor *editor, gint pos, gchar *word, gsize static void snippets_make_replacements(GeanyEditor *editor, GString *pattern); static gssize replace_cursor_markers(GeanyEditor *editor, GString *pattern); static GeanyFiletype *editor_get_filetype_at_current_pos(GeanyEditor *editor); +static gboolean sci_is_blank_line(ScintillaObject *sci, gint line);
void editor_snippets_free(void) @@ -2820,47 +2821,68 @@ static void real_comment_multiline(GeanyEditor *editor, gint line_start, gint la }
-static void real_uncomment_multiline(GeanyEditor *editor) +/* find @p text inside the range of the current style */ +static gint find_in_current_style(ScintillaObject *sci, const gchar *text, gboolean backwards) +{ + gint start = sci_get_current_position(sci); + gint end = start; + gint len = sci_get_length(sci); + gint current_style = sci_get_style_at(sci, start); + struct Sci_TextToFind ttf; + + while (start > 0 && sci_get_style_at(sci, start - 1) == current_style) + start -= 1; + while (end < len && sci_get_style_at(sci, end + 1) == current_style) + end += 1; + + ttf.lpstrText = (gchar*) text; + ttf.chrg.cpMin = backwards ? end + 1 : start; + ttf.chrg.cpMax = backwards ? start : end + 1; + return sci_find_text(sci, 0, &ttf); +} + + +static void sci_delete_line(ScintillaObject *sci, gint line) +{ + gint start = sci_get_position_from_line(sci, line); + gint len = sci_get_line_length(sci, line); + SSM(sci, SCI_DELETERANGE, start, len); +} + + +static gboolean real_uncomment_multiline(GeanyEditor *editor) { /* find the beginning of the multi line comment */ - gint pos, line, len, x; - gchar *linebuf; - GeanyDocument *doc; + gint start, end, start_line, end_line; GeanyFiletype *ft; const gchar *co, *cc;
- g_return_if_fail(editor != NULL && editor->document->file_type != NULL); - doc = editor->document; + g_return_val_if_fail(editor != NULL && editor->document->file_type != NULL, FALSE);
ft = editor_get_filetype_at_current_pos(editor); if (! filetype_get_comment_open_close(ft, FALSE, &co, &cc)) - g_return_if_reached(); + g_return_val_if_reached(FALSE);
- /* remove comment open chars */ - pos = document_find_text(doc, co, NULL, 0, TRUE, FALSE, NULL); - SSM(editor->sci, SCI_DELETEBACK, 0, 0); + start = find_in_current_style(editor->sci, co, TRUE); + end = find_in_current_style(editor->sci, cc, FALSE);
- /* check whether the line is empty and can be deleted */ - line = sci_get_line_from_position(editor->sci, pos); - len = sci_get_line_length(editor->sci, line); - linebuf = sci_get_line(editor->sci, line); - x = 0; - while (linebuf[x] != '\0' && isspace(linebuf[x])) x++; - if (x == len) SSM(editor->sci, SCI_LINEDELETE, 0, 0); - g_free(linebuf); + if (start < 0 || end < 0 || start > end /* who knows */) + return FALSE; + + start_line = sci_get_line_from_position(editor->sci, start); + end_line = sci_get_line_from_position(editor->sci, end);
/* remove comment close chars */ - pos = document_find_text(doc, cc, NULL, 0, FALSE, FALSE, NULL); - SSM(editor->sci, SCI_DELETEBACK, 0, 0); + SSM(editor->sci, SCI_DELETERANGE, end, strlen(cc)); + if (sci_is_blank_line(editor->sci, end_line)) + sci_delete_line(editor->sci, end_line);
- /* check whether the line is empty and can be deleted */ - line = sci_get_line_from_position(editor->sci, pos); - len = sci_get_line_length(editor->sci, line); - linebuf = sci_get_line(editor->sci, line); - x = 0; - while (linebuf[x] != '\0' && isspace(linebuf[x])) x++; - if (x == len) SSM(editor->sci, SCI_LINEDELETE, 0, 0); - g_free(linebuf); + /* remove comment open chars (do it last since it would move the end position) */ + SSM(editor->sci, SCI_DELETERANGE, start, strlen(co)); + if (sci_is_blank_line(editor->sci, start_line)) + sci_delete_line(editor->sci, start_line); + + return TRUE; }
@@ -2993,8 +3015,8 @@ gint editor_do_uncomment(GeanyEditor *editor, gint line, gboolean toggle) style_comment = get_multiline_comment_style(editor, line_start); if (sci_get_style_at(editor->sci, line_start + x) == style_comment) { - real_uncomment_multiline(editor); - count = 1; + if (real_uncomment_multiline(editor)) + count = 1; }
/* break because we are already on the last line */ @@ -3116,8 +3138,8 @@ void editor_do_comment_toggle(GeanyEditor *editor) style_comment = get_multiline_comment_style(editor, line_start); if (sci_get_style_at(editor->sci, line_start + x) == style_comment) { - real_uncomment_multiline(editor); - count_uncommented++; + if (real_uncomment_multiline(editor)) + count_uncommented++; } else {
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: TBD).