home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / jove-4.16-src.tgz / tar.out / bsd / jove / marks.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  273 lines

  1. /************************************************************************
  2.  * This program is Copyright (C) 1986-1996 by Jonathan Payne.  JOVE is  *
  3.  * provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is *
  5.  * included in all the files.                                           *
  6.  ************************************************************************/
  7.  
  8. #include "jove.h"
  9. #include "fmt.h"
  10. #include "marks.h"
  11. #include "disp.h"
  12.  
  13. private Mark    *FreeMarksList = NULL;
  14.  
  15. #define RecycleMark(m)    { \
  16.     (m)->m_next = FreeMarksList; \
  17.     FreeMarksList = (m); \
  18.     (m)->m_line = NULL; /* DEBUG */ \
  19. }
  20.  
  21. Mark *
  22. MakeMark(line, column)
  23. register LinePtr    line;
  24. int    column;
  25. {
  26.     register Mark    *newmark;
  27.  
  28.     if ((newmark = FreeMarksList) != NULL)
  29.         FreeMarksList = newmark->m_next;
  30.     else
  31.         newmark = (Mark *) emalloc(sizeof *newmark);
  32.     MarkSet(newmark, line, column);
  33.     newmark->m_big_delete = NO;
  34.     newmark->m_next = curbuf->b_marks;
  35.     curbuf->b_marks = newmark;
  36.     return newmark;
  37. }
  38.  
  39. void
  40. flush_marks(b)
  41. Buffer    *b;
  42. {
  43.     register Mark    *m,
  44.             *next;
  45.  
  46.     for (m = b->b_marks; m != NULL; m = next) {
  47.         next = m->m_next;
  48.         RecycleMark(m)
  49.     }
  50. }
  51.  
  52. private void
  53. DelBufMark(b, m)
  54. Buffer    *b;
  55. register Mark    *m;
  56. {
  57.     register Mark    *mp = b->b_marks;
  58.  
  59.     if (MarkHighlighting)
  60.         makedirty(m->m_line);
  61.     if (m == mp)
  62.         b->b_marks = m->m_next;
  63.     else {
  64.         while (mp != NULL && mp->m_next != m)
  65.             mp = mp->m_next;
  66.         if (mp == NULL)
  67.             complain("Unknown mark!");
  68.         mp->m_next = m->m_next;
  69.     }
  70.     RecycleMark(m);
  71. }
  72.  
  73. void
  74. DelMark(m)
  75. register Mark    *m;
  76. {
  77.     DelBufMark(curbuf, m);
  78. }
  79.  
  80. /* AllMarkReset is used when a buffer is completely replaced.
  81.    We delete the marks in the mark ring, but we cannot find
  82.    the references to other marks, so those we make point
  83.    to the start of the buffer. */
  84.  
  85. void
  86. AllMarkReset(b, line)
  87. Buffer    *b;
  88. register LinePtr    line;
  89. {
  90.     {
  91.         register Mark    **mpp;
  92.  
  93.         for (mpp = &b->b_markring[0]; mpp != &b->b_markring[NMARKS]; mpp++) {
  94.             if (*mpp != NULL) {
  95.                 DelBufMark(b, *mpp);
  96.                 *mpp = NULL;
  97.             }
  98.         }
  99.         b->b_themark = 0;
  100.     }
  101.  
  102.     {
  103.         register Mark    *mp;
  104.  
  105.         for (mp = b->b_marks; mp != NULL; mp = mp->m_next)
  106.             MarkSet(mp, line, 0);
  107.     }
  108. }
  109.  
  110. void
  111. MarkSet(m, line, column)
  112. Mark    *m;
  113. LinePtr    line;
  114. int    column;
  115. {
  116.     m->m_line = line;
  117.     m->m_char = column;
  118.     m->m_big_delete = NO;
  119.     if (MarkHighlighting)
  120.         makedirty(line);
  121. }
  122.  
  123. void
  124. PopMark()
  125. {
  126.     int    pmark;
  127.  
  128.     if (curmark == NULL)
  129.         return;
  130.     ExchPtMark();
  131.     pmark = curbuf->b_themark;
  132.     do {
  133.         if (--pmark < 0)
  134.             pmark = NMARKS - 1;
  135.     } while (curbuf->b_markring[pmark] == NULL);
  136.     curbuf->b_themark = pmark;
  137.     if (MarkHighlighting)
  138.         makedirty(curmark->m_line);
  139. }
  140.  
  141. void
  142. SetMark()
  143. {
  144.     if (is_an_arg())
  145.         PopMark();
  146.     else
  147.         set_mark();
  148. }
  149.  
  150. void
  151. set_mark()
  152. {
  153.     do_set_mark(curline, curchar);
  154. }
  155.  
  156. void
  157. do_set_mark(l, c)
  158. LinePtr    l;
  159. int    c;
  160. {
  161.     Mark    **mr = curbuf->b_markring;
  162.     int    tm = curbuf->b_themark;
  163.  
  164.     if (mr[tm] != NULL) {
  165.         if (MarkHighlighting)
  166.             makedirty(mr[tm]->m_line);
  167.         curbuf->b_themark = tm = (tm + 1) % NMARKS;
  168.         if (mr[NMARKS-1] == NULL) {
  169.             /* there is an empty slot: make sure one is here */
  170.             int    i;
  171.  
  172.             for (i = NMARKS-1; i != tm; i--)
  173.                 mr[i] = mr[i-1];
  174.             mr[i] = NULL;
  175.         }
  176.     }
  177.     if (mr[tm] == NULL)
  178.         mr[tm] = MakeMark(l, c);
  179.     else
  180.         MarkSet(mr[tm], l, c);
  181.     s_mess("[Point pushed]");
  182. }
  183.  
  184. /* Move point to Mark */
  185.  
  186. void
  187. ToMark(m)
  188. Mark    *m;
  189. {
  190.     int    len;
  191.  
  192.     if (m == NULL)
  193.         return;
  194.     DotTo(m->m_line, m->m_char);
  195.     if (curchar > (len = length(curline)))
  196.         curchar = len;
  197. }
  198.  
  199. Mark *
  200. CurMark()
  201. {
  202.     if (curmark == NULL)
  203.         complain("No mark.");
  204.     return curmark;
  205. }
  206.  
  207. void
  208. ExchPtMark()
  209. {
  210.     LinePtr    mline;
  211.     int    mchar;
  212.     Mark    *m = CurMark();
  213.  
  214.     mline = curline;
  215.     mchar = curchar;
  216.  
  217.     ToMark(m);
  218.     if (MarkHighlighting)
  219.         makedirty(m->m_line);
  220.     MarkSet(m, mline, mchar);
  221. }
  222.  
  223. /* Fix marks after a deletion. */
  224.  
  225. void
  226. DFixMarks(line1, char1, line2, char2)
  227. register LinePtr    line1,
  228.         line2;
  229. int    char1,
  230.     char2;
  231. {
  232.     register Mark    *m;
  233.     LinePtr    lp;
  234.  
  235.     if (curbuf->b_marks == NULL)
  236.         return;
  237.     for (lp = line1; lp != line2->l_next; lp = lp->l_next) {
  238.         for (m = curbuf->b_marks; m != NULL; m = m->m_next) {
  239.             if (m->m_line == lp
  240.             && (lp != line1 || m->m_char > char1))
  241.             {
  242.                 if (lp == line2 && m->m_char > char2) {
  243.                     m->m_char -= char2-char1;
  244.                 } else {
  245.                     m->m_char = char1;
  246.                     if (line1 != line2)
  247.                         m->m_big_delete = YES;
  248.                 }
  249.                 m->m_line = line1;
  250.             }
  251.         }
  252.     }
  253. }
  254.  
  255. /* Fix marks after an insertion. */
  256.  
  257. void
  258. IFixMarks(line1, char1, line2, char2)
  259. register LinePtr    line1,
  260.         line2;
  261. int    char1,
  262.     char2;
  263. {
  264.     register Mark    *m;
  265.  
  266.     for (m = curbuf->b_marks; m != NULL; m = m->m_next) {
  267.         if (m->m_line == line1 && m->m_char > char1) {
  268.             m->m_line = line2;
  269.             m->m_char += char2 - char1;
  270.         }
  271.     }
  272. }
  273.