home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / jove414s.zip / marks.c < prev    next >
C/C++ Source or Header  |  1991-07-06  |  5KB  |  249 lines

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