[geany/geany-plugins] c563b2: Merge pull request #378 from smostertdev/lineoperations_v2
Frank Lanitz
git-noreply at xxxxx
Tue Jan 3 21:45:58 UTC 2017
Branch: refs/heads/master
Author: Frank Lanitz <frank at frank.uvena.de>
Committer: GitHub <noreply at github.com>
Date: Tue, 03 Jan 2017 21:45:58 UTC
Commit: c563b20ceeac9d91d2fa77b1783262317b4b49ef
https://github.com/geany/geany-plugins/commit/c563b20ceeac9d91d2fa77b1783262317b4b49ef
Log Message:
-----------
Merge pull request #378 from smostertdev/lineoperations_v2
lineoperations: added selection support
Modified Paths:
--------------
lineoperations/ChangeLog
lineoperations/README
lineoperations/src/linefunctions.c
lineoperations/src/linefunctions.h
lineoperations/src/lineoperations.c
Modified: lineoperations/ChangeLog
6 lines changed, 6 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,6 @@
+2016-02-27 Sylvan Mostert <smostert.dev at gmail.com>
+
+ * added selection support
+
+
+
Modified: lineoperations/README
14 lines changed, 11 insertions(+), 3 deletions(-)
===================================================================
@@ -8,7 +8,7 @@ About
=====
Line Operations is an assortment of simple line functions that can be
-applied to an open file.
+applied to an open file, or selection.
Features
========
@@ -26,8 +26,16 @@ Usage
After the plugins has been installed successfully, load the plugin via
Geany's plugin manager and a new menu item in the Tools menu will
-appear. Click on each menu item to apply the operation on whole file.
-See descriptions below to see operations for each menu item.
+appear. Click on each menu item to apply the operation on whole file, or
+selection. See descriptions below to see operations for each menu item.
+
+Selection
+---------
+
+If a selection is made in the file, the line operation will be applied to the
+lines within the selection. The beginning of the selection will expand to the
+beginning of its line, and the end of the selection will expand to the end of
+its line. If the end of the selection is on col 0, that line will be included.
Notes
-----
Modified: lineoperations/src/linefunctions.c
336 lines changed, 136 insertions(+), 200 deletions(-)
===================================================================
@@ -1,5 +1,6 @@
/*
- * linefunctions.c - Line operations, remove duplicate lines, empty lines, lines with only whitespace, sort lines.
+ * linefunctions.c - Line operations, remove duplicate lines, empty lines,
+ * lines with only whitespace, sort lines.
*
* Copyright 2015 Sylvan Mostert <smostert.dev at gmail.com>
*
@@ -22,302 +23,237 @@
#include "linefunctions.h"
-/* altered from geany/src/editor.c, ensure new line at file end */
-static void ensure_final_newline(GeanyEditor *editor, gint max_lines)
-{
- gint end_document = sci_get_position_from_line(editor->sci, max_lines);
- gboolean append_newline = end_document >
- sci_get_position_from_line(editor->sci, max_lines - 1);
-
- if (append_newline)
- {
- const gchar *eol = editor_get_eol_char(editor);
- sci_insert_text(editor->sci, end_document, eol);
- }
-}
-
-
/* comparison function to be used in qsort */
-static gint compare_asc(const void * a, const void * b)
+static gint
+compare_asc(const void * a, const void * b)
{
return strcmp(*(const gchar **) a, *(const gchar **) b);
}
/* comparison function to be used in qsort */
-static gint compare_desc(const void * a, const void * b)
+static gint
+compare_desc(const void * a, const void * b)
{
return strcmp(*(const gchar **) b, *(const gchar **) a);
}
/* Remove Duplicate Lines, sorted */
-void rmdupst(GeanyDocument *doc) {
- gint total_num_chars; /* number of characters in the document */
- gint total_num_lines; /* number of lines in the document */
- gchar **lines; /* array to hold all lines in the document */
- gchar *new_file; /* *final* string to replace current document */
- gchar *nf_end; /* points to end of new_file */
- gchar *lineptr; /* temporary line pointer */
- gint i; /* iterator */
-
- total_num_chars = sci_get_length(doc->editor->sci);
- total_num_lines = sci_get_line_count(doc->editor->sci);
- lines = g_malloc(sizeof(gchar *) * total_num_lines);
- new_file = g_malloc(sizeof(gchar) * (total_num_chars+1));
- new_file[0] = '\0';
- nf_end = new_file;
- lineptr = (gchar *)"";
-
-
- /* if file is not empty, ensure that the file ends with newline */
- if(total_num_lines != 1)
- ensure_final_newline(doc->editor, total_num_lines);
-
- /* copy *all* lines into **lines array */
- for(i = 0; i < total_num_lines; i++)
- lines[i] = sci_get_line(doc->editor->sci, i);
+gint
+rmdupst(gchar **lines, gint num_lines, gchar *new_file)
+{
+ gchar *nf_end = new_file; /* points to last char of new_file */
+ gchar *lineptr = (gchar *)" "; /* temporary line pointer */
+ gint i = 0; /* iterator */
+ gint changed = 0; /* number of lines removed */
/* sort **lines ascending */
- qsort(lines, total_num_lines, sizeof(gchar *), compare_asc);
+ qsort(lines, num_lines, sizeof(gchar *), compare_asc);
/* loop through **lines, join first occurances into one str (new_file) */
- for(i = 0; i < total_num_lines; i++)
+ for(i = 0; i < num_lines; i++)
+ {
if(strcmp(lines[i], lineptr) != 0)
{
- lineptr = lines[i];
- nf_end = g_stpcpy(nf_end, lines[i]);
+ changed++; /* number of lines kept */
+ lineptr = lines[i];
+ nf_end = g_stpcpy(nf_end, lines[i]);
}
+ }
- /* set new document */
- sci_set_text(doc->editor->sci, new_file);
-
- /* free used memory */
- for(i = 0; i < total_num_lines; i++)
- g_free(lines[i]);
- g_free(lines);
- g_free(new_file);
+ /* return the number of lines deleted */
+ return -(num_lines - changed);
}
/* Remove Duplicate Lines, ordered */
-void rmdupln(GeanyDocument *doc) {
- gint total_num_chars; /* number of characters in the document */
- gint total_num_lines; /* number of lines in the document */
- gchar **lines; /* array to hold all lines in the document */
- gchar *new_file; /* *final* string to replace current document */
- gchar *nf_end; /* points to end of new_file */
- gint i; /* iterator */
- gint j; /* iterator */
- gboolean *to_remove; /* flag to 'mark' which lines to remove */
-
- total_num_chars = sci_get_length(doc->editor->sci);
- total_num_lines = sci_get_line_count(doc->editor->sci);
- lines = g_malloc(sizeof(gchar *) * total_num_lines);
- new_file = g_malloc(sizeof(gchar) * (total_num_chars+1));
- new_file[0] = '\0';
- nf_end = new_file;
-
-
- /* if file is not empty, ensure that the file ends with newline */
- if(total_num_lines != 1)
- ensure_final_newline(doc->editor, total_num_lines);
-
- /* copy *all* lines into **lines array */
- for(i = 0; i < total_num_lines; i++)
- lines[i] = sci_get_line(doc->editor->sci, i);
+gint
+rmdupln(gchar **lines, gint num_lines, gchar *new_file)
+{
+ gchar *nf_end = new_file; /* points to last char of new_file */
+ gint i = 0; /* iterator */
+ gint j = 0; /* iterator */
+ gboolean *to_remove = NULL; /* flag to 'mark' which lines to remove */
+ gint changed = 0; /* number of lines removed */
+
/* allocate and set *to_remove to all FALSE
* to_remove[i] represents whether lines[i] should be removed */
- to_remove = g_malloc(sizeof(gboolean) * total_num_lines);
- for(i = 0; i < (total_num_lines); i++)
+ to_remove = g_malloc(sizeof(gboolean) * num_lines);
+ for(i = 0; i < (num_lines); i++)
to_remove[i] = FALSE;
/* find which **lines are duplicate, and mark them as duplicate */
- for(i = 0; i < total_num_lines; i++) /* loop through **lines */
+ for(i = 0; i < num_lines; i++) /* loop through **lines */
+ {
/* make sure that the line is not already duplicate */
if(!to_remove[i])
+ {
/* find the rest of same lines */
- for(j = (i+1); j < total_num_lines; j++)
+ for(j = (i+1); j < num_lines; j++)
+ {
if(!to_remove[j] && strcmp(lines[i], lines[j]) == 0)
- to_remove[j] = TRUE; /* line is duplicate, mark to remove */
+ to_remove[j] = TRUE; /* line is duplicate, mark to remove */
+ }
+ }
+ }
- /* copy **lines into 'new_file' if it is not FALSE(not duplicate) */
- for(i = 0; i < total_num_lines; i++)
+ /* copy **lines into 'new_file' if it is not FALSE (not duplicate) */
+ for(i = 0; i < num_lines; i++)
if(!to_remove[i])
- nf_end = g_stpcpy(nf_end, lines[i]);
-
- /* set new document */
- sci_set_text(doc->editor->sci, new_file);
+ {
+ changed++; /* number of lines kept */
+ nf_end = g_stpcpy(nf_end, lines[i]);
+ }
/* free used memory */
- for(i = 0; i < total_num_lines; i++)
- g_free(lines[i]);
- g_free(lines);
- g_free(new_file);
g_free(to_remove);
+
+ /* return the number of lines deleted */
+ return -(num_lines - changed);
}
/* Remove Unique Lines */
-void rmunqln(GeanyDocument *doc) {
- gint total_num_chars; /* number of characters in the document */
- gint total_num_lines; /* number of lines in the document */
- gchar **lines; /* array to hold all lines in the document */
- gchar *new_file; /* *final* string to replace current document */
- gchar *nf_end; /* points to end of new_file */
- gint i; /* iterator */
- gint j; /* iterator */
- gboolean *to_remove; /* to 'mark' which lines to remove */
-
- total_num_chars = sci_get_length(doc->editor->sci);
- total_num_lines = sci_get_line_count(doc->editor->sci);
- lines = g_malloc(sizeof(gchar *) * total_num_lines);
- new_file = g_malloc(sizeof(gchar) * (total_num_chars+1));
- new_file[0] = '\0';
- nf_end = new_file;
-
-
- /* if file is not empty, ensure that the file ends with newline */
- if(total_num_lines != 1)
- ensure_final_newline(doc->editor, total_num_lines);
-
- /* copy *all* lines into **lines array */
- for(i = 0; i < total_num_lines; i++)
- lines[i] = sci_get_line(doc->editor->sci, i);
+gint
+rmunqln(gchar **lines, gint num_lines, gchar *new_file)
+{
+ gchar *nf_end = new_file; /* points to last char of new_file */
+ gint i = 0; /* iterator */
+ gint j = 0; /* iterator */
+ gboolean *to_remove = NULL; /* to 'mark' which lines to remove */
+ gint changed = 0; /* number of lines removed */
/* allocate and set *to_remove to all TRUE
* to_remove[i] represents whether lines[i] should be removed */
- to_remove = g_malloc(sizeof(gboolean) * total_num_lines);
- for(i = 0; i < total_num_lines; i++)
+ to_remove = g_malloc(sizeof(gboolean) * num_lines);
+ for(i = 0; i < num_lines; i++)
to_remove[i] = TRUE;
/* find all unique lines and set them to FALSE (not to be removed) */
- for(i = 0; i < total_num_lines; i++)
+ for(i = 0; i < num_lines; i++)
/* make sure that the line is not already determined to be unique */
if(to_remove[i])
- for(j = (i+1); j < total_num_lines; j++)
+ for(j = (i+1); j < num_lines; j++)
if(to_remove[j] && strcmp(lines[i], lines[j]) == 0)
{
to_remove[i] = FALSE;
to_remove[j] = FALSE;
}
/* copy **lines into 'new_file' if it is not FALSE(not duplicate) */
- for(i = 0; i < total_num_lines; i++)
+ for(i = 0; i < num_lines; i++)
if(!to_remove[i])
+ {
+ changed++; /* number of lines kept */
nf_end = g_stpcpy(nf_end, lines[i]);
-
- /* set new document */
- sci_set_text(doc->editor->sci, new_file);
+ }
/* free used memory */
- for(i = 0; i < total_num_lines; i++)
- g_free(lines[i]);
- g_free(lines);
- g_free(new_file);
g_free(to_remove);
+
+ /* return the number of lines deleted */
+ return -(num_lines - changed);
}
/* Remove Empty Lines */
-void rmemtyln(GeanyDocument *doc) {
- gint total_num_lines; /* number of lines in the document */
- gint i; /* iterator */
-
- total_num_lines = sci_get_line_count(doc->editor->sci);
-
- sci_start_undo_action(doc->editor->sci);
+gint
+rmemtyln(ScintillaObject *sci, gint line_num, gint end_line_num)
+{
+ gint changed = 0; /* number of lines removed */
- for(i = 0; i < total_num_lines; i++) /* loop through opened doc */
+ while(line_num <= end_line_num) /* loop through lines */
{
- if(sci_get_position_from_line(doc->editor->sci, i) ==
- sci_get_line_end_position(doc->editor->sci, i))
+ /* check if the first posn of the line is also the end of line posn */
+ if(sci_get_position_from_line(sci, line_num) ==
+ sci_get_line_end_position (sci, line_num))
{
- scintilla_send_message(doc->editor->sci,
- SCI_DELETERANGE,
- sci_get_position_from_line(doc->editor->sci, i),
- sci_get_line_length(doc->editor->sci, i));
- total_num_lines--;
- i--;
+ scintilla_send_message(sci,
+ SCI_DELETERANGE,
+ sci_get_position_from_line(sci, line_num),
+ sci_get_line_length(sci, line_num));
+
+ line_num--;
+ end_line_num--;
+ changed++;
}
+ line_num++;
}
- sci_end_undo_action(doc->editor->sci);
+ /* return the number of lines deleted */
+ return -changed;
}
/* Remove Whitespace Lines */
-void rmwhspln(GeanyDocument *doc) {
- gint total_num_lines; /* number of lines in the document */
- gint indent;
- gint i; /* iterator */
-
- total_num_lines = sci_get_line_count(doc->editor->sci);
-
- sci_start_undo_action(doc->editor->sci);
+gint
+rmwhspln(ScintillaObject *sci, gint line_num, gint end_line_num)
+{
+ gint indent; /* indent position */
+ gint changed = 0; /* number of lines removed */
- for(i = 0; i < total_num_lines; i++) /* loop through opened doc */
+ while(line_num <= end_line_num) /* loop through lines */
{
- indent = scintilla_send_message(doc->editor->sci,
+ indent = scintilla_send_message(sci,
SCI_GETLINEINDENTPOSITION,
- i, 0);
+ line_num, 0);
+ /* check if the posn of indentation is also the end of line posn */
if(indent -
- sci_get_position_from_line(doc->editor->sci, i) ==
- sci_get_line_end_position(doc->editor->sci, i)-
- sci_get_position_from_line(doc->editor->sci, i))
+ sci_get_position_from_line(sci, line_num) ==
+ sci_get_line_end_position (sci, line_num) -
+ sci_get_position_from_line(sci, line_num))
{
- scintilla_send_message(doc->editor->sci,
- SCI_DELETERANGE,
- sci_get_position_from_line(doc->editor->sci, i),
- sci_get_line_length(doc->editor->sci, i));
- total_num_lines--;
- i--;
+ scintilla_send_message(sci,
+ SCI_DELETERANGE,
+ sci_get_position_from_line(sci, line_num),
+ sci_get_line_length(sci, line_num));
+
+ line_num--;
+ end_line_num--;
+ changed++;
}
+ line_num++;
}
-
- sci_end_undo_action(doc->editor->sci);
+ /* return the number of lines deleted */
+ return -changed;
}
-/* Sort Lines Ascending and Descending */
-void sortlines(GeanyDocument *doc, gboolean asc) {
- gint total_num_lines; /* number of lines in the document */
- gchar **lines; /* array to hold all lines in the document */
- gchar *new_file; /* *final* string to replace current document */
- gint i; /* iterator */
+/* Sort Lines Ascending */
+gint
+sortlnsasc(gchar **lines, gint num_lines, gchar *new_file)
+{
+ gchar *nf_end = new_file; /* points to last char of new_file */
+ gint i;
+
+ qsort(lines, num_lines, sizeof(gchar *), compare_asc);
+
+ /* join **lines into one string (new_file) */
+ for(i = 0; i < num_lines; i++)
+ nf_end = g_stpcpy(nf_end, lines[i]);
- total_num_lines = sci_get_line_count(doc->editor->sci);
- lines = g_malloc(sizeof(gchar *) * (total_num_lines+1));
+ return num_lines;
+}
- /* if file is not empty, ensure that the file ends with newline */
- if(total_num_lines != 1)
- ensure_final_newline(doc->editor, total_num_lines);
- /* copy *all* lines into **lines array */
- for(i = 0; i < total_num_lines; i++)
- lines[i] = sci_get_line(doc->editor->sci, i);
+/* Sort Lines Descending */
+gint
+sortlndesc(gchar **lines, gint num_lines, gchar *new_file)
+{
+ gchar *nf_end = new_file; /* points to last char of new_file */
+ gint i;
- /* sort **lines array */
- if(asc)
- qsort(lines, total_num_lines, sizeof(gchar *), compare_asc);
- else
- qsort(lines, total_num_lines, sizeof(gchar *), compare_desc);
+ qsort(lines, num_lines, sizeof(gchar *), compare_desc);
/* join **lines into one string (new_file) */
- lines[total_num_lines] = NULL;
- new_file = g_strjoinv("", lines);
-
- /* set new document */
- sci_set_text(doc->editor->sci, new_file);
+ for(i = 0; i < num_lines; i++)
+ nf_end = g_stpcpy(nf_end, lines[i]);
- /* free used memory */
- for(i = 0; i < total_num_lines; i++)
- g_free(lines[i]);
- g_free(lines);
- g_free(new_file);
+ return num_lines;
}
Modified: lineoperations/src/linefunctions.h
28 lines changed, 20 insertions(+), 8 deletions(-)
===================================================================
@@ -1,5 +1,6 @@
/*
- * linefunctions.h - Line operations, remove duplicate lines, empty lines, lines with only whitespace, sort lines.
+ * linefunctions.h - Line operations, remove duplicate lines, empty lines,
+ * lines with only whitespace, sort lines.
*
* Copyright 2015 Sylvan Mostert <smostert.dev at gmail.com>
*
@@ -30,26 +31,37 @@
/* Remove Duplicate Lines, sorted */
-void rmdupst(GeanyDocument *doc);
+gint
+rmdupst(gchar **lines, gint num_lines, gchar *new_file);
/* Remove Duplicate Lines, ordered */
-void rmdupln(GeanyDocument *doc);
+gint
+rmdupln(gchar **lines, gint num_lines, gchar *new_file);
/* Remove Unique Lines */
-void rmunqln(GeanyDocument *doc);
+gint
+rmunqln(gchar **lines, gint num_lines, gchar *new_file);
/* Remove Empty Lines */
-void rmemtyln(GeanyDocument *doc);
+gint
+rmemtyln(ScintillaObject *sci, gint line_num, gint end_line_num);
/* Remove Whitespace Lines */
-void rmwhspln(GeanyDocument *doc);
+gint
+rmwhspln(ScintillaObject *sci, gint line_num, gint end_line_num);
-/* Sort Lines Ascending and Descending */
-void sortlines(GeanyDocument *doc, gboolean asc);
+/* Sort Lines Ascending */
+gint
+sortlnsasc(gchar **lines, gint num_lines, gchar *new_file);
+
+
+/* Sort Lines Descending */
+gint
+sortlndesc(gchar **lines, gint num_lines, gchar *new_file);
#endif
Modified: lineoperations/src/lineoperations.c
237 lines changed, 214 insertions(+), 23 deletions(-)
===================================================================
@@ -1,5 +1,6 @@
/*
- * lineoperations.c - Line operations, remove duplicate lines, empty lines, lines with only whitespace, sort lines.
+ * lineoperations.c - Line operations, remove duplicate lines, empty lines,
+ * lines with only whitespace, sort lines.
*
* Copyright 2015 Sylvan Mostert <smostert.dev at gmail.com>
*
@@ -29,26 +30,212 @@
static GtkWidget *main_menu_item = NULL;
-/* call custom func */
+
+/* represents a selection of lines that will have Operation applied to */
+struct lo_lines {
+ gboolean is_selection;
+ gint start_line;
+ gint end_line;
+};
+
+
+/* selects lines in document (based off of lo_lines struct parameter) */
static void
-action_func_item(GtkMenuItem *menuitem, gpointer gdata)
+select_lines(GeanyEditor *editor, struct lo_lines sel)
{
- void (*func)(GeanyDocument *) = gdata;
- GeanyDocument *doc = NULL;
- doc = document_get_current();
+ /* set the selection to beginning of first line */
+ sci_set_selection_start(editor->sci,
+ sci_get_position_from_line(editor->sci, sel.start_line));
- if(doc) func(doc);
+ /* set the selection to end of last line */
+ sci_set_selection_end(editor->sci,
+ sci_get_line_end_position(editor->sci, sel.end_line) +
+ editor_get_eol_char_len(editor));
}
-/* Sort Lines */
+/* get lo_lines struct based off of document */
+static struct lo_lines
+get_current_sel_lines(ScintillaObject *sci)
+{
+ struct lo_lines sel = { FALSE, 0, 0 };
+ gint start_posn = 0; /* position of selection start */
+ gint end_posn = 0; /* position of selection end */
+
+ /* check for selection */
+ if(sci_has_selection(sci))
+ {
+ /* get the start and end *positions* */
+ start_posn = sci_get_selection_start(sci);
+ end_posn = sci_get_selection_end (sci);
+
+ /* get the *line number* of those positions */
+ sel.start_line = scintilla_send_message(sci,
+ SCI_LINEFROMPOSITION,
+ start_posn, 0);
+
+ sel.end_line = scintilla_send_message(sci,
+ SCI_LINEFROMPOSITION,
+ end_posn, 0);
+
+ sel.is_selection = TRUE;
+ }
+ else
+ {
+ /* if there is no selection, start at first line */
+ sel.start_line = 0;
+ /* and end at last one */
+ sel.end_line = (sci_get_line_count(sci) - 1);
+
+ sel.is_selection = FALSE;
+ }
+
+ return sel;
+}
+
+
+/* altered from geany/src/editor.c, ensure new line at file end */
static void
-action_sort_item(GtkMenuItem *menuitem, gpointer gdata)
+ensure_final_newline(GeanyEditor *editor, gint *num_lines, struct lo_lines *sel)
{
- GeanyDocument *doc = NULL;
- doc = document_get_current();
+ gint end_document = sci_get_position_from_line(editor->sci, (*num_lines));
+ gboolean append_newline = end_document >
+ sci_get_position_from_line(editor->sci, ((*num_lines) - 1));
+
+ if (append_newline)
+ {
+ const gchar *eol = editor_get_eol_char(editor);
+ sci_insert_text(editor->sci, end_document, eol);
+
+ /* re-adjust the selection */
+ (*num_lines)++;
+ (*sel).end_line++;
+ }
+}
+
+
+/* set statusbar with message and select altered lines */
+static void
+user_indicate(GeanyEditor *editor, gint lines_affected, struct lo_lines sel)
+{
+ if(lines_affected < 0)
+ {
+ ui_set_statusbar(FALSE, _("Operation successful! %d lines removed."),
+ -lines_affected);
+
+ /* select lines to indicate to user what lines were altered */
+ sel.end_line += lines_affected;
+
+ if(sel.is_selection)
+ select_lines(editor, sel);
+ }
+ else if(lines_affected == 0)
+ {
+ ui_set_statusbar(FALSE, _("Operation successful! No lines removed."));
+
+ /* select lines to indicate to user what lines were altered */
+ if(sel.is_selection)
+ select_lines(editor, sel);
+ }
+ else
+ {
+ ui_set_statusbar(FALSE, _("Operation successful! %d lines affected."),
+ lines_affected);
+
+ /* select lines to indicate to user what lines were altered */
+ if(sel.is_selection)
+ select_lines(editor, sel);
+ }
+}
+
+
+/*
+ * Menu action for functions with indirect scintilla manipulation
+ * e.g. functions requiring **lines array, num_lines, *new_file
+*/
+static void
+action_indir_manip_item(GtkMenuItem *menuitem, gpointer gdata)
+{
+ /* function pointer to function to be used */
+ gint (*func)(gchar **lines, gint num_lines, gchar *new_file) = gdata;
+ GeanyDocument *doc = document_get_current();
+
+ struct lo_lines sel = get_current_sel_lines(doc->editor->sci);
+ gint num_lines = (sel.end_line - sel.start_line) + 1;
+
+ gint num_chars = 0;
+ gint i = 0;
+ gint lines_affected = 0;
+
+
+ /* if last line within selection ensure that the file ends with newline */
+ if((sel.end_line + 1) == sci_get_line_count(doc->editor->sci))
+ ensure_final_newline(doc->editor, &num_lines, &sel);
+
+ /* get num_chars and **lines */
+ gchar **lines = g_malloc(sizeof(gchar *) * num_lines);
+ for(i = 0; i < num_lines; i++)
+ {
+ num_chars += (sci_get_line_length(doc->editor->sci,
+ (i + sel.start_line)));
+
+ lines[i] = sci_get_line(doc->editor->sci,
+ (i + sel.start_line));
+ }
+
+ gchar *new_file = g_malloc(sizeof(gchar) * (num_chars + 1));
+ new_file[0] = '\0';
+
+ /* select lines that will be replaced with array */
+ select_lines(doc->editor, sel);
+
+ sci_start_undo_action(doc->editor->sci);
+
+
+ if(doc)
+ lines_affected = func(lines, num_lines, new_file);
+
+
+ /* set new document */
+ sci_replace_sel(doc->editor->sci, new_file);
+
+ /* select affected lines and set statusbar message */
+ user_indicate(doc->editor, lines_affected, sel);
+
+ sci_end_undo_action(doc->editor->sci);
+
+ /* free used memory */
+ for(i = 0; i < num_lines; i++)
+ g_free(lines[i]);
+ g_free(lines);
+ g_free(new_file);
+}
+
+
+
+/*
+ * Menu action for functions with direct scintilla manipulation
+ * e.g. no need for **lines array, *new_file...
+*/
+static void
+action_sci_manip_item(GtkMenuItem *menuitem, gpointer gdata)
+{
+ /* function pointer to gdata -- function to be used */
+ gint (*func)(ScintillaObject *, gint, gint) = gdata;
+ GeanyDocument *doc = document_get_current();
+ struct lo_lines sel = get_current_sel_lines(doc->editor->sci);
+ gint lines_affected = 0;
+
+
+ sci_start_undo_action(doc->editor->sci);
+
+ if(doc)
+ lines_affected = func(doc->editor->sci, sel.start_line, sel.end_line);
+
+ /* put message in ui_statusbar, and highlight lines that were affected */
+ user_indicate(doc->editor, lines_affected, sel);
- if(doc) sortlines(doc, GPOINTER_TO_INT(gdata));
+ sci_end_undo_action(doc->editor->sci);
}
@@ -65,21 +252,21 @@ lo_init(GeanyPlugin *plugin, gpointer gdata)
gpointer cb_data;
} menu_items[] = {
{ N_("Remove Duplicate Lines, _Sorted"),
- G_CALLBACK(action_func_item), (gpointer) rmdupst },
+ G_CALLBACK(action_indir_manip_item), (gpointer) rmdupst },
{ N_("Remove Duplicate Lines, _Ordered"),
- G_CALLBACK(action_func_item), (gpointer) rmdupln },
+ G_CALLBACK(action_indir_manip_item), (gpointer) rmdupln },
{ N_("Remove _Unique Lines"),
- G_CALLBACK(action_func_item), (gpointer) rmunqln },
+ G_CALLBACK(action_indir_manip_item), (gpointer) rmunqln },
{ NULL },
{ N_("Remove _Empty Lines"),
- G_CALLBACK(action_func_item), (gpointer) rmemtyln },
+ G_CALLBACK(action_sci_manip_item), (gpointer) rmemtyln },
{ N_("Remove _Whitespace Lines"),
- G_CALLBACK(action_func_item), (gpointer) rmwhspln },
+ G_CALLBACK(action_sci_manip_item), (gpointer) rmwhspln },
{ NULL },
{ N_("Sort Lines _Ascending"),
- G_CALLBACK(action_sort_item), GINT_TO_POINTER(1) },
+ G_CALLBACK(action_indir_manip_item), (gpointer) sortlnsasc },
{ N_("Sort Lines _Descending"),
- G_CALLBACK(action_sort_item), GINT_TO_POINTER(0) }
+ G_CALLBACK(action_indir_manip_item), (gpointer) sortlndesc }
};
main_menu_item = gtk_menu_item_new_with_mnemonic(_("_Line Operations"));
@@ -97,7 +284,10 @@ lo_init(GeanyPlugin *plugin, gpointer gdata)
else
{
item = gtk_menu_item_new_with_mnemonic(_(menu_items[i].label));
- g_signal_connect(item, "activate", menu_items[i].cb_activate, menu_items[i].cb_data);
+ g_signal_connect(item,
+ "activate",
+ menu_items[i].cb_activate,
+ menu_items[i].cb_data);
ui_add_document_sensitive(item);
}
@@ -106,7 +296,8 @@ lo_init(GeanyPlugin *plugin, gpointer gdata)
}
gtk_menu_item_set_submenu(GTK_MENU_ITEM(main_menu_item), submenu);
- gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu), main_menu_item);
+ gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu),
+ main_menu_item);
return TRUE;
}
@@ -125,8 +316,8 @@ void geany_load_module(GeanyPlugin *plugin)
main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
plugin->info->name = _("Line Operations");
- plugin->info->description = _("Line Operations provides a handful of functions that can be applied to a document such as, removing duplicate lines, removing empty lines, removing lines with only whitespace, and sorting lines.");
- plugin->info->version = "0.1";
+ plugin->info->description = _("Line Operations provides a handful of functions that can be applied to a document or selection such as, removing duplicate lines, removing empty lines, removing lines with only whitespace, and sorting lines.");
+ plugin->info->version = "0.2";
plugin->info->author = "Sylvan Mostert <smostert.dev at gmail.com>";
plugin->funcs->init = lo_init;
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Plugins-Commits
mailing list