Merge branch '1904_spec_bump_epoch'
[midnight-commander.git] / edit / bookmark.c
blob00dfe8ea5a1391cca6ccbd2964ec10a7568f2e49
1 /* editor book mark handling
3 Copyright (C) 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
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., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA.
23 /** \file
24 * \brief Source: editor book mark handling
25 * \author Paul Sheer
26 * \date 1996, 1997
29 #include <config.h>
31 #include <ctype.h>
32 #include <errno.h>
33 #include <stdarg.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <unistd.h>
42 #include "../src/global.h"
44 #include "edit-impl.h"
45 #include "edit-widget.h"
48 /* note, if there is more than one bookmark on a line, then they are
49 appended after each other and the last one is always the one found
50 by book_mark_found() i.e. last in is the one seen */
52 static struct _book_mark *double_marks (WEdit * edit, struct _book_mark *p)
54 (void) edit;
56 if (p->next)
57 while (p->next->line == p->line)
58 p = p->next;
59 return p;
62 /* returns the first bookmark on or before this line */
63 struct _book_mark *book_mark_find (WEdit * edit, int line)
65 struct _book_mark *p;
66 if (!edit->book_mark) {
67 /* must have an imaginary top bookmark at line -1 to make things less complicated */
68 edit->book_mark = g_malloc0 (sizeof (struct _book_mark));
69 edit->book_mark->line = -1;
70 return edit->book_mark;
72 for (p = edit->book_mark; p; p = p->next) {
73 if (p->line > line)
74 break; /* gone past it going downward */
75 if (p->line <= line) {
76 if (p->next) {
77 if (p->next->line > line) {
78 edit->book_mark = p;
79 return double_marks (edit, p);
81 } else {
82 edit->book_mark = p;
83 return double_marks (edit, p);
87 for (p = edit->book_mark; p; p = p->prev) {
88 if (p->next)
89 if (p->next->line <= line)
90 break; /* gone past it going upward */
91 if (p->line <= line) {
92 if (p->next) {
93 if (p->next->line > line) {
94 edit->book_mark = p;
95 return double_marks (edit, p);
97 } else {
98 edit->book_mark = p;
99 return double_marks (edit, p);
103 return 0; /* can't get here */
106 /* returns true if a bookmark exists at this line of color c */
107 int book_mark_query_color (WEdit * edit, int line, int c)
109 struct _book_mark *p;
110 if (!edit->book_mark)
111 return 0;
112 for (p = book_mark_find (edit, line); p; p = p->prev) {
113 if (p->line != line)
114 return 0;
115 if (p->c == c)
116 return 1;
118 return 0;
121 /* insert a bookmark at this line */
122 void
123 book_mark_insert (WEdit *edit, int line, int c)
125 struct _book_mark *p, *q;
126 p = book_mark_find (edit, line);
127 #if 0
128 if (p->line == line) {
129 /* already exists, so just change the color */
130 if (p->c != c) {
131 edit->force |= REDRAW_LINE;
132 p->c = c;
134 return;
136 #endif
137 edit->force |= REDRAW_LINE;
138 /* create list entry */
139 q = g_malloc0 (sizeof (struct _book_mark));
140 q->line = line;
141 q->c = c;
142 q->next = p->next;
143 /* insert into list */
144 q->prev = p;
145 if (p->next)
146 p->next->prev = q;
147 p->next = q;
150 /* remove a bookmark if there is one at this line matching this color - c of -1 clear all */
151 /* returns non-zero on not-found */
152 int book_mark_clear (WEdit * edit, int line, int c)
154 struct _book_mark *p, *q;
155 int r = 1;
156 if (!edit->book_mark)
157 return r;
158 for (p = book_mark_find (edit, line); p; p = q) {
159 q = p->prev;
160 if (p->line == line && (p->c == c || c == -1)) {
161 r = 0;
162 edit->force |= REDRAW_LINE;
163 edit->book_mark = p->prev;
164 p->prev->next = p->next;
165 if (p->next)
166 p->next->prev = p->prev;
167 g_free (p);
168 break;
171 /* if there is only our dummy book mark left, clear it for speed */
172 if (edit->book_mark->line == -1 && !edit->book_mark->next) {
173 g_free (edit->book_mark);
174 edit->book_mark = 0;
176 return r;
179 /* clear all bookmarks matching this color, if c is -1 clears all */
180 void book_mark_flush (WEdit * edit, int c)
182 struct _book_mark *p, *q;
183 if (!edit->book_mark)
184 return;
185 edit->force |= REDRAW_PAGE;
186 while (edit->book_mark->prev)
187 edit->book_mark = edit->book_mark->prev;
188 for (q = edit->book_mark->next; q; q = p) {
189 p = q->next;
190 if (q->c == c || c == -1) {
191 q->prev->next = q->next;
192 if (p)
193 p->prev = q->prev;
194 g_free (q);
197 if (!edit->book_mark->next) {
198 g_free (edit->book_mark);
199 edit->book_mark = 0;
203 /* shift down bookmarks after this line */
204 void book_mark_inc (WEdit * edit, int line)
206 if (edit->book_mark) {
207 struct _book_mark *p;
208 p = book_mark_find (edit, line);
209 for (p = p->next; p; p = p->next) {
210 p->line++;
215 /* shift up bookmarks after this line */
216 void book_mark_dec (WEdit * edit, int line)
218 if (edit->book_mark) {
219 struct _book_mark *p;
220 p = book_mark_find (edit, line);
221 for (p = p->next; p; p = p->next) {
222 p->line--;