summaryrefslogtreecommitdiffstats
path: root/src/editor/bookmark.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/editor/bookmark.c')
-rw-r--r--src/editor/bookmark.c347
1 files changed, 347 insertions, 0 deletions
diff --git a/src/editor/bookmark.c b/src/editor/bookmark.c
new file mode 100644
index 0000000..59c53d2
--- /dev/null
+++ b/src/editor/bookmark.c
@@ -0,0 +1,347 @@
+/*
+ Editor book mark handling
+
+ Copyright (C) 2001-2022
+ Free Software Foundation, Inc.
+
+ Written by:
+ Paul Sheer, 1996, 1997
+
+ This file is part of the Midnight Commander.
+
+ The Midnight Commander is free software: you can redistribute it
+ and/or modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ The Midnight Commander is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** \file
+ * \brief Source: editor book mark handling
+ * \author Paul Sheer
+ * \date 1996, 1997
+ */
+
+#include <config.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "lib/global.h"
+#include "lib/util.h" /* MAX_SAVED_BOOKMARKS */
+
+#include "editwidget.h"
+
+/*** global variables ****************************************************************************/
+
+/*** file scope macro definitions ****************************************************************/
+
+/*** file scope type declarations ****************************************************************/
+
+/*** file scope variables ************************************************************************/
+
+/*** file scope functions ************************************************************************/
+/* --------------------------------------------------------------------------------------------- */
+
+/** note, if there is more than one bookmark on a line, then they are
+ appended after each other and the last one is always the one found
+ by book_mark_found() i.e. last in is the one seen */
+
+static edit_book_mark_t *
+double_marks (WEdit * edit, edit_book_mark_t * p)
+{
+ (void) edit;
+
+ if (p->next != NULL)
+ while (p->next->line == p->line)
+ p = p->next;
+ return p;
+}
+
+/* --------------------------------------------------------------------------------------------- */
+/** returns the first bookmark on or before this line */
+
+edit_book_mark_t *
+book_mark_find (WEdit * edit, long line)
+{
+ edit_book_mark_t *p;
+
+ if (edit->book_mark == NULL)
+ {
+ /* must have an imaginary top bookmark at line -1 to make things less complicated */
+ edit->book_mark = g_new0 (edit_book_mark_t, 1);
+ edit->book_mark->line = -1;
+ return edit->book_mark;
+ }
+
+ for (p = edit->book_mark; p != NULL; p = p->next)
+ {
+ if (p->line > line)
+ break; /* gone past it going downward */
+
+ if (p->next != NULL)
+ {
+ if (p->next->line > line)
+ {
+ edit->book_mark = p;
+ return double_marks (edit, p);
+ }
+ }
+ else
+ {
+ edit->book_mark = p;
+ return double_marks (edit, p);
+ }
+ }
+
+ for (p = edit->book_mark; p != NULL; p = p->prev)
+ {
+ if (p->next != NULL && p->next->line <= line)
+ break; /* gone past it going upward */
+
+ if (p->line <= line)
+ {
+ if (p->next != NULL)
+ {
+ if (p->next->line > line)
+ {
+ edit->book_mark = p;
+ return double_marks (edit, p);
+ }
+ }
+ else
+ {
+ edit->book_mark = p;
+ return double_marks (edit, p);
+ }
+ }
+ }
+
+ return NULL; /* can't get here */
+}
+
+/* --------------------------------------------------------------------------------------------- */
+/*** public functions ****************************************************************************/
+/* --------------------------------------------------------------------------------------------- */
+
+/**
+ * Check if bookmark bookmark exists at this line of this color
+ *
+ * @param edit editor object
+ * @param line line where book mark is
+ * @param c color of book mark
+ * @return TRUE if bookmark exists at this line of color c, FALSE otherwise
+ */
+
+gboolean
+book_mark_query_color (WEdit * edit, long line, int c)
+{
+ if (edit->book_mark != NULL)
+ {
+ edit_book_mark_t *p;
+
+ for (p = book_mark_find (edit, line); p != NULL; p = p->prev)
+ {
+ if (p->line != line)
+ return FALSE;
+ if (p->c == c)
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/* --------------------------------------------------------------------------------------------- */
+/** insert a bookmark at this line */
+
+void
+book_mark_insert (WEdit * edit, long line, int c)
+{
+ edit_book_mark_t *p, *q;
+
+ p = book_mark_find (edit, line);
+#if 0
+ if (p->line == line)
+ {
+ /* already exists, so just change the color */
+ if (p->c != c)
+ {
+ p->c = c;
+ edit->force |= REDRAW_LINE;
+ }
+ return;
+ }
+#endif
+ /* create list entry */
+ q = g_new (edit_book_mark_t, 1);
+ q->line = line;
+ q->c = c;
+ q->next = p->next;
+ /* insert into list */
+ q->prev = p;
+ if (p->next != NULL)
+ p->next->prev = q;
+ p->next = q;
+
+ edit->force |= REDRAW_LINE;
+}
+
+/* --------------------------------------------------------------------------------------------- */
+/**
+ * Remove a bookmark if there is one at this line matching this color - c of -1 clear all
+ *
+ * @param edit editor object
+ * @param line line where book mark is
+ * @param c color of book mark or -1 to clear all book marks on this line
+ * @return FALSE if not found, TRUE otherwise
+ */
+
+gboolean
+book_mark_clear (WEdit * edit, long line, int c)
+{
+ edit_book_mark_t *p, *q;
+ gboolean r = FALSE;
+
+ if (edit->book_mark == NULL)
+ return r;
+
+ for (p = book_mark_find (edit, line); p != NULL; p = q)
+ {
+ q = p->prev;
+ if (p->line == line && (p->c == c || c == -1))
+ {
+ r = TRUE;
+ edit->book_mark = p->prev;
+ p->prev->next = p->next;
+ if (p->next != NULL)
+ p->next->prev = p->prev;
+ g_free (p);
+ edit->force |= REDRAW_LINE;
+ break;
+ }
+ }
+ /* if there is only our dummy book mark left, clear it for speed */
+ if (edit->book_mark->line == -1 && edit->book_mark->next == NULL)
+ MC_PTR_FREE (edit->book_mark);
+
+ return r;
+}
+
+/* --------------------------------------------------------------------------------------------- */
+/** clear all bookmarks matching this color, if c is -1 clears all */
+
+void
+book_mark_flush (WEdit * edit, int c)
+{
+ edit_book_mark_t *p, *q;
+
+ if (edit->book_mark == NULL)
+ return;
+
+ while (edit->book_mark->prev != NULL)
+ edit->book_mark = edit->book_mark->prev;
+
+ for (q = edit->book_mark->next; q != NULL; q = p)
+ {
+ p = q->next;
+ if (q->c == c || c == -1)
+ {
+ q->prev->next = q->next;
+ if (p != NULL)
+ p->prev = q->prev;
+ g_free (q);
+ }
+ }
+ if (edit->book_mark->next == NULL)
+ MC_PTR_FREE (edit->book_mark);
+
+ edit->force |= REDRAW_PAGE;
+}
+
+/* --------------------------------------------------------------------------------------------- */
+/** shift down bookmarks after this line */
+
+void
+book_mark_inc (WEdit * edit, long line)
+{
+ if (edit->book_mark != NULL)
+ {
+ edit_book_mark_t *p;
+
+ p = book_mark_find (edit, line);
+ for (p = p->next; p != NULL; p = p->next)
+ p->line++;
+ }
+}
+
+/* --------------------------------------------------------------------------------------------- */
+/** shift up bookmarks after this line */
+
+void
+book_mark_dec (WEdit * edit, long line)
+{
+ if (edit->book_mark != NULL)
+ {
+ edit_book_mark_t *p;
+
+ p = book_mark_find (edit, line);
+ for (p = p->next; p != NULL; p = p->next)
+ p->line--;
+ }
+}
+
+/* --------------------------------------------------------------------------------------------- */
+/** prepare line positions of bookmarks to be saved to file */
+
+void
+book_mark_serialize (WEdit * edit, int color)
+{
+ if (edit->serialized_bookmarks != NULL)
+ g_array_set_size (edit->serialized_bookmarks, 0);
+
+ if (edit->book_mark != NULL)
+ {
+ edit_book_mark_t *p;
+
+ if (edit->serialized_bookmarks == NULL)
+ edit->serialized_bookmarks = g_array_sized_new (FALSE, FALSE, sizeof (size_t),
+ MAX_SAVED_BOOKMARKS);
+
+ for (p = book_mark_find (edit, 0); p != NULL; p = p->next)
+ if (p->c == color && p->line >= 0)
+ g_array_append_val (edit->serialized_bookmarks, p->line);
+ }
+}
+
+/* --------------------------------------------------------------------------------------------- */
+/** restore bookmarks from saved line positions */
+
+void
+book_mark_restore (WEdit * edit, int color)
+{
+ if (edit->serialized_bookmarks != NULL)
+ {
+ size_t i;
+
+ for (i = 0; i < edit->serialized_bookmarks->len; i++)
+ book_mark_insert (edit, g_array_index (edit->serialized_bookmarks, size_t, i), color);
+ }
+}
+
+/* --------------------------------------------------------------------------------------------- */