home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume8 / jove / part05 / marks.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-02-02  |  4.1 KB  |  212 lines

  1. /************************************************************************
  2.  * This program is Copyright (C) 1986 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. int    MarksShouldFloat = 1;
  9.  
  10. #include "jove.h"
  11.  
  12. Mark *
  13. MakeMark(line, column, type)
  14. register Line    *line;
  15. {
  16.     register Mark    *newmark = (Mark *) emalloc(sizeof *newmark);
  17.  
  18.     MarkSet(newmark, line, column);
  19.     newmark->m_next = curbuf->b_marks;
  20.     newmark->m_floater = type;
  21.     curbuf->b_marks = newmark;
  22.     return newmark;
  23. }
  24.  
  25. DelMark(m)
  26. register Mark    *m;
  27. {
  28.     register Mark    *mp = curbuf->b_marks;
  29.  
  30.     if (m == mp)
  31.         curbuf->b_marks = m->m_next;
  32.     else {
  33.         while (mp != 0 && mp->m_next != m)
  34.             mp = mp->m_next;
  35.         if (mp == 0)
  36.             complain("Unknown mark!");
  37.         mp->m_next = m->m_next;
  38.     }
  39.     free((char *) m);
  40. }
  41.  
  42. AllMarkSet(b, line, col)
  43. Buffer    *b;
  44. register Line    *line;
  45. {
  46.     register Mark    *mp;
  47.  
  48.     for (mp = b->b_marks; mp != 0; mp = mp->m_next)
  49.         MarkSet(mp, line, col);
  50. }
  51.  
  52. MarkSet(m, line, column)
  53. Mark    *m;
  54. Line    *line;
  55. {
  56.     m->m_line = line;
  57.     m->m_char = column;
  58. }
  59.  
  60. PopMark()
  61. {
  62.     int    pmark;
  63.  
  64.     if (curmark == 0)
  65.         return;
  66.     if (curbuf->b_markring[(curbuf->b_themark + 1) % NMARKS] == 0) {
  67.         pmark = curbuf->b_themark;
  68.         do {
  69.             if (--pmark < 0)
  70.                 pmark = NMARKS - 1;
  71.         } while (curbuf->b_markring[pmark] != 0);
  72.  
  73.         curbuf->b_markring[pmark] = MakeMark(curline, curchar, MarksShouldFloat);
  74.         ToMark(curmark);
  75.         DelMark(curmark);
  76.         curmark = 0;
  77.     } else
  78.         PtToMark();
  79.  
  80.     pmark = curbuf->b_themark - 1;
  81.     if (pmark < 0)
  82.         pmark = NMARKS - 1;
  83.     curbuf->b_themark = pmark;
  84. }
  85.  
  86. SetMark()
  87. {
  88.     if (exp_p)
  89.         PopMark();
  90.     else
  91.         DoSetMark(curline, curchar);
  92. }
  93.  
  94. DoSetMark(l, c)
  95. Line    *l;
  96. {
  97.     curbuf->b_themark = (curbuf->b_themark + 1) % NMARKS;
  98.     if (curmark == 0)
  99.         curmark = MakeMark(l, c, MarksShouldFloat);
  100.     else
  101.         MarkSet(curmark, l, c);
  102.     s_mess("[Point pushed]");
  103. }
  104.  
  105. /* Move point to Mark */
  106.  
  107. ToMark(m)
  108. Mark    *m;
  109. {
  110.     int    len;
  111.  
  112.     if (m == 0)
  113.         return;
  114.     DotTo(m->m_line, m->m_char);
  115.     if (curchar > (len = length(curline)))
  116.         curchar = len;
  117. }
  118.  
  119. Mark *
  120. CurMark()
  121. {
  122.     if (curmark == 0)
  123.         complain("No mark.");
  124.     return curmark;
  125. }
  126.  
  127. PtToMark()
  128. {
  129.     Line    *mline;
  130.     int    mchar;
  131.     Mark    *m = CurMark();
  132.  
  133.     mline = curline;
  134.     mchar = curchar;
  135.  
  136.     ToMark(m);
  137.     MarkSet(m, mline, mchar);
  138. }
  139.  
  140. /* Fix marks for after a deletion.  For now, even marks that don't
  141.    float will actually float, because we can't allow marks to point
  142.    to non-existant lines. */
  143.  
  144. DFixMarks(line1, char1, line2, char2)
  145. register Line    *line1,
  146.         *line2;
  147. {
  148.     register Mark    *m;
  149.     Line    *lp = line1;
  150.  
  151.     if (curbuf->b_marks == 0)
  152.         return;
  153.     while (lp != line2->l_next) {
  154.         for (m = curbuf->b_marks; m != 0; m = m->m_next) {
  155. /*            if (!m->m_floater)
  156.                 continue; */
  157.             if (m->m_line == lp)
  158.                 m->m_char |= (1 << 15);
  159.         }
  160.         lp = lp->l_next;
  161.     }
  162.     for (m = curbuf->b_marks; m; m = m->m_next) {
  163. /*        if (!m->m_floater)
  164.             continue; */
  165.         if ((m->m_char & (1 << 15)) == 0)
  166.             continue;    /* Not effected */
  167.         m->m_char &= ~(1 << 15);
  168.         if (m->m_line == line1 && m->m_char < char1)
  169.             continue;    /* This mark is not affected */
  170.         if (line1 == line2) {
  171.             if (m->m_char >= char1 && m->m_char <= char2)
  172.                 m->m_char = char1;
  173.             else if (m->m_char > char2)
  174.                 m->m_char -= (char2 - char1);
  175.             /* Same line move the mark backward */
  176.         } else if (m->m_line == line2) {
  177.             if (m->m_char > char2)
  178.                 m->m_char = char1 + (m->m_char - char2);
  179.             else
  180.                 m->m_char = char1;
  181.             m->m_line = line1;
  182.         } else {
  183.             m->m_char = char1;
  184.             m->m_line = line1;
  185.         }
  186.     }
  187. }
  188.  
  189. /* Fix marks after an insertion.  Marks that don't float are ignored
  190.    on insertion, which means PtToMark has to be careful ... */
  191.  
  192. IFixMarks(line1, char1, line2, char2)
  193. register Line    *line1,
  194.         *line2;
  195. {
  196.     register Mark    *m;
  197.  
  198.     for (m = curbuf->b_marks; m != 0; m = m->m_next) {
  199.         if (!m->m_floater)
  200.             continue;
  201.         if (m->m_line == line1) {
  202.             if (m->m_char > char1) {
  203.                 m->m_line = line2;
  204.                 if (line1 == line2)
  205.                     m->m_char += (char2 - char1);
  206.                 else
  207.                     m->m_char = char2 + (m->m_char - char1);
  208.             }
  209.         } 
  210.     }
  211. }
  212.