bookmark.c 5.5 KB

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