mc/gtkedit/bookmark.c
Paul Sheer f7bc648b90 mcedit updates to reflect cooledit-3.11.6
a large number of minor changes have been made
	those really interested can check the cooledit
	changelogs.
	in particular, on the fly spell checking has been
	added. this is not yet enabled for use, but the code
	is there.
	syntax highlighting optimisations have been made
	and various syntax rules added for some new
	languages.
	comprehensive bookmarking support has been added, but
	this requires keybindings still.
1999-07-21 20:03:23 +00:00

252 lines
6.2 KiB
C

/* editor book mark handling
Copyright (C) 1996, 1997 the Free Software Foundation
Authors: 1996, 1997 Paul Sheer
This program 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 2 of the License, or
(at your option) any later version.
This program 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA.
*/
#include <config.h>
#include "edit.h"
#if defined (HAVE_MAD) && ! defined (MIDNIGHT) && ! defined (GTK)
#include "mad.h"
#endif
/* 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 inline struct _book_mark *double_marks (WEdit * edit, struct _book_mark *p)
{
if (p->next)
while (p->next->line == p->line)
p = p->next;
return p;
}
/* returns the first bookmark on or before this line */
struct _book_mark *book_mark_find (WEdit * edit, int line)
{
struct _book_mark *p;
if (!edit->book_mark) {
/* must have an imaginary top bookmark at line -1 to make things less complicated */
edit->book_mark = malloc (sizeof (struct _book_mark));
memset (edit->book_mark, 0, sizeof (struct _book_mark));
edit->book_mark->line = -1;
return edit->book_mark;
}
for (p = edit->book_mark; p; p = p->next) {
if (p->line > line)
break; /* gone past it going downward */
if (p->line <= line) {
if (p->next) {
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; p = p->prev) {
if (p->next)
if (p->next->line <= line)
break; /* gone past it going upward */
if (p->line <= line) {
if (p->next) {
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 0; /* can't get here */
}
/* returns true if a bookmark exists at this line of colour c */
int book_mark_query_color (WEdit * edit, int line, int c)
{
struct _book_mark *p;
if (!edit->book_mark)
return 0;
for (p = book_mark_find (edit, line); p; p = p->prev) {
if (p->line != line)
return 0;
if (p->c == c)
return 1;
}
return 0;
}
/* returns the number of bookmarks at this line and a list of their colours in c
up to a maximum of 8 colours */
int book_mark_query_all (WEdit * edit, int line, int *c)
{
int i;
struct _book_mark *p;
if (!edit->book_mark)
return 0;
for (i = 0, p = book_mark_find (edit, line); p && i < 8; p = p->prev, i++) {
if (p->line != line)
return i;
c[i] = p->c;
}
return i;
}
/* insert a bookmark at this line */
void book_mark_insert (WEdit * edit, int line, int c)
{
struct _book_mark *p, *q;
p = book_mark_find (edit, line);
#if 0
if (p->line == line) { /* already exists, so just change the colour */
if (p->c != c) {
edit->force |= REDRAW_LINE;
p->c = c;
}
return;
}
#endif
edit->force |= REDRAW_LINE;
/* create list entry */
q = malloc (sizeof (struct _book_mark));
memset (q, 0, sizeof (struct _book_mark));
q->line = line;
q->c = c;
q->next = p->next;
/* insert into list */
q->prev = p;
if (p->next)
p->next->prev = q;
p->next = q;
#if !defined (GTK) && !defined (MIDNIGHT)
render_scrollbar (edit->widget->vert_scrollbar);
#endif
}
/* remove a bookmark if there is one at this line matching this colour - c of -1 clear all */
/* returns non-zero on not-found */
int book_mark_clear (WEdit * edit, int line, int c)
{
struct _book_mark *p, *q;
int r = 1;
int rend = 0;
if (!edit->book_mark)
return r;
for (p = book_mark_find (edit, line); p; p = q) {
q = p->prev;
if (p->line == line && (p->c == c || c == -1)) {
r = 0;
edit->force |= REDRAW_LINE;
edit->book_mark = p->prev;
p->prev->next = p->next;
if (p->next)
p->next->prev = p->prev;
rend = 1;
free (p);
break;
}
}
/* if there is only our dummy book mark left, clear it for speed */
if (edit->book_mark->line == -1 && !edit->book_mark->next) {
free (edit->book_mark);
edit->book_mark = 0;
}
#if !defined (GTK) && !defined (MIDNIGHT)
if (rend)
render_scrollbar (edit->widget->vert_scrollbar);
#endif
return r;
}
/* clear all bookmarks matching this colour, if c is -1 clears all */
void book_mark_flush (WEdit * edit, int c)
{
struct _book_mark *p, *q;
int rend = 0;
if (!edit->book_mark)
return;
edit->force |= REDRAW_PAGE;
while (edit->book_mark->prev)
edit->book_mark = edit->book_mark->prev;
for (q = edit->book_mark->next; q; q = p) {
p = q->next;
if (q->c == c || c == -1) {
q->prev->next = q->next;
if (p)
p->prev = q->prev;
rend = 1;
free (q);
}
}
if (!edit->book_mark->next) {
free (edit->book_mark);
edit->book_mark = 0;
}
#if !defined (GTK) && !defined (MIDNIGHT)
if (rend)
render_scrollbar (edit->widget->vert_scrollbar);
#endif
}
/* shift down bookmarks after this line */
void book_mark_inc (WEdit * edit, int line)
{
int rend = 0;
if (edit->book_mark) {
struct _book_mark *p;
p = book_mark_find (edit, line);
for (p = p->next; p; p = p->next) {
p->line++;
rend = 1;
}
}
#if !defined (GTK) && !defined (MIDNIGHT)
if (rend)
render_scrollbar (edit->widget->vert_scrollbar);
#endif
}
/* shift up bookmarks after this line */
void book_mark_dec (WEdit * edit, int line)
{
int rend = 0;
if (edit->book_mark) {
struct _book_mark *p;
p = book_mark_find (edit, line);
for (p = p->next; p; p = p->next) {
p->line--;
rend = 1;
}
}
#if !defined (GTK) && !defined (MIDNIGHT)
if (rend)
render_scrollbar (edit->widget->vert_scrollbar);
#endif
}