*** empty log message ***
[midnight-commander.git] / edit / bookmark.c
blob9bc918ba743f708d2157952b51ceb971d7b0172f
1 /* editor book mark handling
3 Copyright (C) 1996, 1997 the Free Software Foundation
5 Authors: 1996, 1997 Paul Sheer
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307, USA.
24 #include <config.h>
25 #include "edit.h"
27 /* note, if there is more than one bookmark on a line, then they are
28 appended after each other and the last one is always the one found
29 by book_mark_found() i.e. last in is the one seen */
31 static inline struct _book_mark *double_marks (WEdit * edit, struct _book_mark *p)
33 if (p->next)
34 while (p->next->line == p->line)
35 p = p->next;
36 return p;
39 /* returns the first bookmark on or before this line */
40 struct _book_mark *book_mark_find (WEdit * edit, int line)
42 struct _book_mark *p;
43 if (!edit->book_mark) {
44 /* must have an imaginary top bookmark at line -1 to make things less complicated */
45 edit->book_mark = malloc (sizeof (struct _book_mark));
46 memset (edit->book_mark, 0, sizeof (struct _book_mark));
47 edit->book_mark->line = -1;
48 return edit->book_mark;
50 for (p = edit->book_mark; p; p = p->next) {
51 if (p->line > line)
52 break; /* gone past it going downward */
53 if (p->line <= line) {
54 if (p->next) {
55 if (p->next->line > line) {
56 edit->book_mark = p;
57 return double_marks (edit, p);
59 } else {
60 edit->book_mark = p;
61 return double_marks (edit, p);
65 for (p = edit->book_mark; p; p = p->prev) {
66 if (p->next)
67 if (p->next->line <= line)
68 break; /* gone past it going upward */
69 if (p->line <= line) {
70 if (p->next) {
71 if (p->next->line > line) {
72 edit->book_mark = p;
73 return double_marks (edit, p);
75 } else {
76 edit->book_mark = p;
77 return double_marks (edit, p);
81 return 0; /* can't get here */
84 /* returns true if a bookmark exists at this line of colour c */
85 int book_mark_query_color (WEdit * edit, int line, int c)
87 struct _book_mark *p;
88 if (!edit->book_mark)
89 return 0;
90 for (p = book_mark_find (edit, line); p; p = p->prev) {
91 if (p->line != line)
92 return 0;
93 if (p->c == c)
94 return 1;
96 return 0;
99 /* returns the number of bookmarks at this line and a list of their colours in c
100 up to a maximum of 8 colours */
101 int book_mark_query_all (WEdit * edit, int line, int *c)
103 int i;
104 struct _book_mark *p;
105 if (!edit->book_mark)
106 return 0;
107 for (i = 0, p = book_mark_find (edit, line); p && i < 8; p = p->prev, i++) {
108 if (p->line != line)
109 return i;
110 c[i] = p->c;
112 return i;
115 /* insert a bookmark at this line */
116 void book_mark_insert (WEdit * edit, int line, int c)
118 struct _book_mark *p, *q;
119 p = book_mark_find (edit, line);
120 #if 0
121 if (p->line == line) { /* already exists, so just change the colour */
122 if (p->c != c) {
123 edit->force |= REDRAW_LINE;
124 p->c = c;
126 return;
128 #endif
129 edit->force |= REDRAW_LINE;
130 /* create list entry */
131 q = malloc (sizeof (struct _book_mark));
132 memset (q, 0, sizeof (struct _book_mark));
133 q->line = line;
134 q->c = c;
135 q->next = p->next;
136 /* insert into list */
137 q->prev = p;
138 if (p->next)
139 p->next->prev = q;
140 p->next = q;
143 /* remove a bookmark if there is one at this line matching this colour - c of -1 clear all */
144 /* returns non-zero on not-found */
145 int book_mark_clear (WEdit * edit, int line, int c)
147 struct _book_mark *p, *q;
148 int r = 1;
149 if (!edit->book_mark)
150 return r;
151 for (p = book_mark_find (edit, line); p; p = q) {
152 q = p->prev;
153 if (p->line == line && (p->c == c || c == -1)) {
154 r = 0;
155 edit->force |= REDRAW_LINE;
156 edit->book_mark = p->prev;
157 p->prev->next = p->next;
158 if (p->next)
159 p->next->prev = p->prev;
160 free (p);
161 break;
164 /* if there is only our dummy book mark left, clear it for speed */
165 if (edit->book_mark->line == -1 && !edit->book_mark->next) {
166 free (edit->book_mark);
167 edit->book_mark = 0;
169 return r;
172 /* clear all bookmarks matching this colour, if c is -1 clears all */
173 void book_mark_flush (WEdit * edit, int c)
175 struct _book_mark *p, *q;
176 if (!edit->book_mark)
177 return;
178 edit->force |= REDRAW_PAGE;
179 while (edit->book_mark->prev)
180 edit->book_mark = edit->book_mark->prev;
181 for (q = edit->book_mark->next; q; q = p) {
182 p = q->next;
183 if (q->c == c || c == -1) {
184 q->prev->next = q->next;
185 if (p)
186 p->prev = q->prev;
187 free (q);
190 if (!edit->book_mark->next) {
191 free (edit->book_mark);
192 edit->book_mark = 0;
196 /* shift down bookmarks after this line */
197 void book_mark_inc (WEdit * edit, int line)
199 if (edit->book_mark) {
200 struct _book_mark *p;
201 p = book_mark_find (edit, line);
202 for (p = p->next; p; p = p->next) {
203 p->line++;
208 /* shift up bookmarks after this line */
209 void book_mark_dec (WEdit * edit, int line)
211 if (edit->book_mark) {
212 struct _book_mark *p;
213 p = book_mark_find (edit, line);
214 for (p = p->next; p; p = p->next) {
215 p->line--;