root/src/editor/bookmark.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. double_marks
  2. book_mark_find
  3. book_mark_query_color
  4. book_mark_insert
  5. book_mark_clear
  6. book_mark_flush
  7. book_mark_inc
  8. book_mark_dec
  9. book_mark_serialize
  10. book_mark_restore

   1 /*
   2    Editor book mark handling
   3 
   4    Copyright (C) 2001-2024
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Paul Sheer, 1996, 1997
   9 
  10    This file is part of the Midnight Commander.
  11 
  12    The Midnight Commander is free software: you can redistribute it
  13    and/or modify it under the terms of the GNU General Public License as
  14    published by the Free Software Foundation, either version 3 of the License,
  15    or (at your option) any later version.
  16 
  17    The Midnight Commander is distributed in the hope that it will be useful,
  18    but WITHOUT ANY WARRANTY; without even the implied warranty of
  19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20    GNU General Public License for more details.
  21 
  22    You should have received a copy of the GNU General Public License
  23    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  24  */
  25 
  26 /** \file
  27  *  \brief Source: editor book mark handling
  28  *  \author Paul Sheer
  29  *  \date 1996, 1997
  30  */
  31 
  32 #include <config.h>
  33 
  34 #include <ctype.h>
  35 #include <stdarg.h>
  36 #include <stdio.h>
  37 #include <stdlib.h>
  38 #include <string.h>
  39 
  40 #include <sys/types.h>
  41 #include <sys/stat.h>
  42 #include <unistd.h>
  43 
  44 #include "lib/global.h"
  45 #include "lib/util.h"           /* MAX_SAVED_BOOKMARKS */
  46 
  47 #include "editwidget.h"
  48 
  49 /*** global variables ****************************************************************************/
  50 
  51 /*** file scope macro definitions ****************************************************************/
  52 
  53 /*** file scope type declarations ****************************************************************/
  54 
  55 /*** forward declarations (file scope functions) *************************************************/
  56 
  57 /*** file scope variables ************************************************************************/
  58 
  59 /* --------------------------------------------------------------------------------------------- */
  60 /*** file scope functions ************************************************************************/
  61 /* --------------------------------------------------------------------------------------------- */
  62 
  63 /** note, if there is more than one bookmark on a line, then they are
  64    appended after each other and the last one is always the one found
  65    by book_mark_found() i.e. last in is the one seen */
  66 
  67 static edit_book_mark_t *
  68 double_marks (WEdit *edit, edit_book_mark_t *p)
     /* [previous][next][first][last][top][bottom][index][help]  */
  69 {
  70     (void) edit;
  71 
  72     if (p->next != NULL)
  73         while (p->next->line == p->line)
  74             p = p->next;
  75     return p;
  76 }
  77 
  78 /* --------------------------------------------------------------------------------------------- */
  79 /** returns the first bookmark on or before this line */
  80 
  81 edit_book_mark_t *
  82 book_mark_find (WEdit *edit, long line)
     /* [previous][next][first][last][top][bottom][index][help]  */
  83 {
  84     edit_book_mark_t *p;
  85 
  86     if (edit->book_mark == NULL)
  87     {
  88         /* must have an imaginary top bookmark at line -1 to make things less complicated  */
  89         edit->book_mark = g_new0 (edit_book_mark_t, 1);
  90         edit->book_mark->line = -1;
  91         return edit->book_mark;
  92     }
  93 
  94     for (p = edit->book_mark; p != NULL; p = p->next)
  95     {
  96         if (p->line > line)
  97             break;              /* gone past it going downward */
  98 
  99         if (p->next != NULL)
 100         {
 101             if (p->next->line > line)
 102             {
 103                 edit->book_mark = p;
 104                 return double_marks (edit, p);
 105             }
 106         }
 107         else
 108         {
 109             edit->book_mark = p;
 110             return double_marks (edit, p);
 111         }
 112     }
 113 
 114     for (p = edit->book_mark; p != NULL; p = p->prev)
 115     {
 116         if (p->next != NULL && p->next->line <= line)
 117             break;              /* gone past it going upward */
 118 
 119         if (p->line <= line)
 120         {
 121             if (p->next != NULL)
 122             {
 123                 if (p->next->line > line)
 124                 {
 125                     edit->book_mark = p;
 126                     return double_marks (edit, p);
 127                 }
 128             }
 129             else
 130             {
 131                 edit->book_mark = p;
 132                 return double_marks (edit, p);
 133             }
 134         }
 135     }
 136 
 137     return NULL;                /* can't get here */
 138 }
 139 
 140 /* --------------------------------------------------------------------------------------------- */
 141 /*** public functions ****************************************************************************/
 142 /* --------------------------------------------------------------------------------------------- */
 143 
 144 /** 
 145  * Check if bookmark bookmark exists at this line of this color
 146  *
 147  * @param edit editor object
 148  * @param line line where book mark is
 149  * @param c color of book mark
 150  * @return TRUE if bookmark exists at this line of color c, FALSE otherwise
 151  */
 152 
 153 gboolean
 154 book_mark_query_color (WEdit *edit, long line, int c)
     /* [previous][next][first][last][top][bottom][index][help]  */
 155 {
 156     if (edit->book_mark != NULL)
 157     {
 158         edit_book_mark_t *p;
 159 
 160         for (p = book_mark_find (edit, line); p != NULL; p = p->prev)
 161         {
 162             if (p->line != line)
 163                 return FALSE;
 164             if (p->c == c)
 165                 return TRUE;
 166         }
 167     }
 168 
 169     return FALSE;
 170 }
 171 
 172 /* --------------------------------------------------------------------------------------------- */
 173 /** insert a bookmark at this line */
 174 
 175 void
 176 book_mark_insert (WEdit *edit, long line, int c)
     /* [previous][next][first][last][top][bottom][index][help]  */
 177 {
 178     edit_book_mark_t *p, *q;
 179 
 180     p = book_mark_find (edit, line);
 181 #if 0
 182     if (p->line == line)
 183     {
 184         /* already exists, so just change the color */
 185         if (p->c != c)
 186         {
 187             p->c = c;
 188             edit->force |= REDRAW_LINE;
 189         }
 190         return;
 191     }
 192 #endif
 193     /* create list entry */
 194     q = g_new (edit_book_mark_t, 1);
 195     q->line = line;
 196     q->c = c;
 197     q->next = p->next;
 198     /* insert into list */
 199     q->prev = p;
 200     if (p->next != NULL)
 201         p->next->prev = q;
 202     p->next = q;
 203 
 204     edit->force |= REDRAW_LINE;
 205 }
 206 
 207 /* --------------------------------------------------------------------------------------------- */
 208 /** 
 209  * Remove a bookmark if there is one at this line matching this color - c of -1 clear all
 210  *
 211  * @param edit editor object
 212  * @param line line where book mark is
 213  * @param c color of book mark or -1 to clear all book marks on this line
 214  * @return FALSE if not found, TRUE otherwise
 215  */
 216 
 217 gboolean
 218 book_mark_clear (WEdit *edit, long line, int c)
     /* [previous][next][first][last][top][bottom][index][help]  */
 219 {
 220     edit_book_mark_t *p, *q;
 221     gboolean r = FALSE;
 222 
 223     if (edit->book_mark == NULL)
 224         return r;
 225 
 226     for (p = book_mark_find (edit, line); p != NULL; p = q)
 227     {
 228         q = p->prev;
 229         if (p->line == line && (p->c == c || c == -1))
 230         {
 231             r = TRUE;
 232             edit->book_mark = p->prev;
 233             p->prev->next = p->next;
 234             if (p->next != NULL)
 235                 p->next->prev = p->prev;
 236             g_free (p);
 237             edit->force |= REDRAW_LINE;
 238             break;
 239         }
 240     }
 241     /* if there is only our dummy book mark left, clear it for speed */
 242     if (edit->book_mark->line == -1 && edit->book_mark->next == NULL)
 243         MC_PTR_FREE (edit->book_mark);
 244 
 245     return r;
 246 }
 247 
 248 /* --------------------------------------------------------------------------------------------- */
 249 /** clear all bookmarks matching this color, if c is -1 clears all */
 250 
 251 void
 252 book_mark_flush (WEdit *edit, int c)
     /* [previous][next][first][last][top][bottom][index][help]  */
 253 {
 254     edit_book_mark_t *p, *q;
 255 
 256     if (edit->book_mark == NULL)
 257         return;
 258 
 259     while (edit->book_mark->prev != NULL)
 260         edit->book_mark = edit->book_mark->prev;
 261 
 262     for (q = edit->book_mark->next; q != NULL; q = p)
 263     {
 264         p = q->next;
 265         if (q->c == c || c == -1)
 266         {
 267             q->prev->next = q->next;
 268             if (p != NULL)
 269                 p->prev = q->prev;
 270             g_free (q);
 271         }
 272     }
 273     if (edit->book_mark->next == NULL)
 274         MC_PTR_FREE (edit->book_mark);
 275 
 276     edit->force |= REDRAW_PAGE;
 277 }
 278 
 279 /* --------------------------------------------------------------------------------------------- */
 280 /** shift down bookmarks after this line */
 281 
 282 void
 283 book_mark_inc (WEdit *edit, long line)
     /* [previous][next][first][last][top][bottom][index][help]  */
 284 {
 285     if (edit->book_mark != NULL)
 286     {
 287         edit_book_mark_t *p;
 288 
 289         p = book_mark_find (edit, line);
 290         for (p = p->next; p != NULL; p = p->next)
 291             p->line++;
 292     }
 293 }
 294 
 295 /* --------------------------------------------------------------------------------------------- */
 296 /** shift up bookmarks after this line */
 297 
 298 void
 299 book_mark_dec (WEdit *edit, long line)
     /* [previous][next][first][last][top][bottom][index][help]  */
 300 {
 301     if (edit->book_mark != NULL)
 302     {
 303         edit_book_mark_t *p;
 304 
 305         p = book_mark_find (edit, line);
 306         for (p = p->next; p != NULL; p = p->next)
 307             p->line--;
 308     }
 309 }
 310 
 311 /* --------------------------------------------------------------------------------------------- */
 312 /** prepare line positions of bookmarks to be saved to file */
 313 
 314 void
 315 book_mark_serialize (WEdit *edit, int color)
     /* [previous][next][first][last][top][bottom][index][help]  */
 316 {
 317     if (edit->serialized_bookmarks != NULL)
 318         g_array_set_size (edit->serialized_bookmarks, 0);
 319 
 320     if (edit->book_mark != NULL)
 321     {
 322         edit_book_mark_t *p;
 323 
 324         if (edit->serialized_bookmarks == NULL)
 325             edit->serialized_bookmarks = g_array_sized_new (FALSE, FALSE, sizeof (size_t),
 326                                                             MAX_SAVED_BOOKMARKS);
 327 
 328         for (p = book_mark_find (edit, 0); p != NULL; p = p->next)
 329             if (p->c == color && p->line >= 0)
 330                 g_array_append_val (edit->serialized_bookmarks, p->line);
 331     }
 332 }
 333 
 334 /* --------------------------------------------------------------------------------------------- */
 335 /** restore bookmarks from saved line positions */
 336 
 337 void
 338 book_mark_restore (WEdit *edit, int color)
     /* [previous][next][first][last][top][bottom][index][help]  */
 339 {
 340     if (edit->serialized_bookmarks != NULL)
 341     {
 342         size_t i;
 343 
 344         for (i = 0; i < edit->serialized_bookmarks->len; i++)
 345             book_mark_insert (edit, g_array_index (edit->serialized_bookmarks, size_t, i), color);
 346     }
 347 }
 348 
 349 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */