SF.net SVN: geany:[5408] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Tue Nov 16 13:26:05 UTC 2010


Revision: 5408
          http://geany.svn.sourceforge.net/geany/?rev=5408&view=rev
Author:   ntrel
Date:     2010-11-16 13:26:04 +0000 (Tue, 16 Nov 2010)

Log Message:
-----------
Make Reflow Lines/Block command use the current indented block, not
the whole paragraph, which could have mixed indentation.
Fix memory leak and off-by-one bug on first line when using Select
Paragraph command.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/editor.c
    trunk/src/editor.h
    trunk/src/keybindings.c

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2010-11-15 15:16:00 UTC (rev 5407)
+++ trunk/ChangeLog	2010-11-16 13:26:04 UTC (rev 5408)
@@ -1,3 +1,12 @@
+2010-11-16  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
+
+ * src/keybindings.c, src/editor.c, src/editor.h:
+   Make Reflow Lines/Block command use the current indented block, not
+   the whole paragraph, which could have mixed indentation.
+   Fix memory leak and off-by-one bug on first line when using Select
+   Paragraph command.
+
+
 2010-11-15  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
 
  * src/editor.c, doc/geany.txt, doc/geany.html:

Modified: trunk/src/editor.c
===================================================================
--- trunk/src/editor.c	2010-11-15 15:16:00 UTC (rev 5407)
+++ trunk/src/editor.c	2010-11-16 13:26:04 UTC (rev 5408)
@@ -3931,50 +3931,48 @@
 }
 
 
-/* find the start or end of a paragraph by searching all lines in direction (UP or DOWN)
- * starting at the given line and return the found line or return -1 if called on an empty line */
+static gboolean sci_is_blank_line(ScintillaObject *sci, gint line)
+{
+	return sci_get_line_indent_position(sci, line) ==
+		sci_get_line_end_position(sci, line);
+}
+
+
+/* Returns first line of paragraph for GTK_DIR_UP, line after paragraph
+ * ends for GTK_DIR_DOWN or -1 if called on an empty line. */
 static gint find_paragraph_stop(GeanyEditor *editor, gint line, gint direction)
 {
-	gboolean found_end = FALSE;
 	gint step;
-	gchar *line_buf, *x;
 	ScintillaObject *sci = editor->sci;
 
 	/* first check current line and return -1 if it is empty to skip creating of a selection */
-	line_buf = x = sci_get_line(sci, line);
-	while (isspace(*x))
-		x++;
-	if (*x == '\0')
-	{
-		g_free(line_buf);
+	if (sci_is_blank_line(sci, line))
 		return -1;
-	}
 
 	if (direction == GTK_DIR_UP)
 		step = -1;
 	else
 		step = 1;
 
-	while (! found_end)
+	while (TRUE)
 	{
 		line += step;
+		if (line == -1)
+		{
+			/* start of document */
+			line = 0;
+			break;
+		}
+		if (line == sci_get_line_count(sci))
+			break;
 
-		/* sci_get_line checks for sanity of the given line, sci_get_line always return a string
-		 * containing at least '\0' so no need to check for NULL */
-		line_buf = x = sci_get_line(sci, line);
-
-		/* check whether after skipping all whitespace we are at end of line and if so, assume
-		 * this line as end of paragraph */
-		while (isspace(*x))
-			x++;
-		if (*x == '\0')
+		if (sci_is_blank_line(sci, line))
 		{
-			found_end = TRUE;
-			if (line == -1)
-				/* called on the first line but there is no previous line so return line 0 */
-				line = 0;
+			/* return line paragraph starts on */
+			if (direction == GTK_DIR_UP)
+				line++;
+			break;
 		}
-		g_free(line_buf);
 	}
 	return line;
 }
@@ -3986,18 +3984,12 @@
 
 	g_return_if_fail(editor != NULL);
 
-	line_start = SSM(editor->sci, SCI_LINEFROMPOSITION,
-						SSM(editor->sci, SCI_GETCURRENTPOS, 0, 0), 0);
+	line_start = sci_get_current_line(editor->sci);
 
 	line_found = find_paragraph_stop(editor, line_start, GTK_DIR_UP);
 	if (line_found == -1)
 		return;
 
-	/* find_paragraph_stop returns the emtpy line(previous to the real start of the paragraph),
-	 * so use the next line for selection start */
-	if (line_found > 0)
-		line_found++;
-
 	pos_start = SSM(editor->sci, SCI_POSITIONFROMLINE, line_found, 0);
 
 	line_found = find_paragraph_stop(editor, line_start, GTK_DIR_DOWN);
@@ -4007,6 +3999,69 @@
 }
 
 
+/* Returns first line of block for GTK_DIR_UP, line after block
+ * ends for GTK_DIR_DOWN or -1 if called on an empty line. */
+static gint find_block_stop(GeanyEditor *editor, gint line, gint direction)
+{
+	gint step, ind;
+	ScintillaObject *sci = editor->sci;
+
+	/* first check current line and return -1 if it is empty to skip creating of a selection */
+	if (sci_is_blank_line(sci, line))
+		return -1;
+
+	if (direction == GTK_DIR_UP)
+		step = -1;
+	else
+		step = 1;
+
+	ind = sci_get_line_indentation(sci, line);
+	while (TRUE)
+	{
+		line += step;
+		if (line == -1)
+		{
+			/* start of document */
+			line = 0;
+			break;
+		}
+		if (line == sci_get_line_count(sci))
+			break;
+
+		if (sci_get_line_indentation(sci, line) != ind ||
+			sci_is_blank_line(sci, line))
+		{
+			/* return line block starts on */
+			if (direction == GTK_DIR_UP)
+				line++;
+			break;
+		}
+	}
+	return line;
+}
+
+
+void editor_select_indent_block(GeanyEditor *editor)
+{
+	gint pos_start, pos_end, line_start, line_found;
+
+	g_return_if_fail(editor != NULL);
+
+	line_start = sci_get_current_line(editor->sci);
+
+	line_found = find_block_stop(editor, line_start, GTK_DIR_UP);
+	if (line_found == -1)
+		return;
+
+	pos_start = SSM(editor->sci, SCI_POSITIONFROMLINE, line_found, 0);
+
+	line_found = find_block_stop(editor, line_start, GTK_DIR_DOWN);
+	pos_end = SSM(editor->sci, SCI_POSITIONFROMLINE, line_found, 0);
+
+	sci_set_selection(editor->sci, pos_start, pos_end);
+}
+
+
 /* simple indentation to indent the current line with the same indent as the previous one */
 static void smart_line_indentation(GeanyEditor *editor, gint first_line, gint last_line)
 {

Modified: trunk/src/editor.h
===================================================================
--- trunk/src/editor.h	2010-11-15 15:16:00 UTC (rev 5407)
+++ trunk/src/editor.h	2010-11-16 13:26:04 UTC (rev 5408)
@@ -243,12 +243,16 @@
 
 gchar *editor_get_default_selection(GeanyEditor *editor, gboolean use_current_word, const gchar *wordchars);
 
+
 void editor_select_word(GeanyEditor *editor);
 
 void editor_select_lines(GeanyEditor *editor, gboolean extra_line);
 
 void editor_select_paragraph(GeanyEditor *editor);
 
+void editor_select_indent_block(GeanyEditor *editor);
+
+
 void editor_set_font(GeanyEditor *editor, const gchar *font);
 
 void editor_indicator_set_on_line(GeanyEditor *editor, gint indic, gint line);

Modified: trunk/src/keybindings.c
===================================================================
--- trunk/src/keybindings.c	2010-11-15 15:16:00 UTC (rev 5407)
+++ trunk/src/keybindings.c	2010-11-16 13:26:04 UTC (rev 5408)
@@ -2344,7 +2344,8 @@
 	{
 		gint line, pos;
 
-		keybindings_send_command(GEANY_KEY_GROUP_SELECT, GEANY_KEYS_SELECT_PARAGRAPH);
+		editor_select_indent_block(editor);
+
 		/* deselect last line break */
 		pos = sci_get_selection_end(sci);
 		line = sci_get_line_from_position(sci, pos);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list