[geany/geany] 220ace: Fix uncommenting multi-line comments when cursor is on a delimiter

Colomban Wendling git-noreply at geany.org
Fri Oct 12 18:40:38 UTC 2012


Branch:      refs/heads/master
Author:      Colomban Wendling <ban at herbesfolles.org>
Committer:   Colomban Wendling <ban at herbesfolles.org>
Date:        Fri, 12 Oct 2012 18:40:38
Commit:      220ace841ca08baff629e2443df92540aa8fca62
             https://github.com/geany/geany/commit/220ace841ca08baff629e2443df92540aa8fca62

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).


More information about the Commits mailing list