home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
- * is provided to you without charge, and with no warranty. You may give *
- * away copies of JOVE, including sources, provided that this notice is *
- * included in all the files. *
- ***************************************************************************/
-
- #include "jove.h"
-
- int MarksShouldFloat = 1;
-
- Mark *
- MakeMark(line, column, type)
- register Line *line;
- int column,
- type;
- {
- register Mark *newmark = (Mark *) emalloc(sizeof *newmark);
-
- MarkSet(newmark, line, column);
- newmark->m_next = curbuf->b_marks;
- newmark->m_flags = type;
- curbuf->b_marks = newmark;
- return newmark;
- }
-
- void
- flush_marks(b)
- Buffer *b;
- {
- register Mark *m,
- *next;
-
- m = b->b_marks;
- while (m != 0) {
- next = m->m_next;
- free((char *) m);
- m = next;
- }
- }
-
- void
- DelMark(m)
- register Mark *m;
- {
- register Mark *mp = curbuf->b_marks;
-
- if (m == mp)
- curbuf->b_marks = m->m_next;
- else {
- while (mp != 0 && mp->m_next != m)
- mp = mp->m_next;
- if (mp == 0)
- complain("Unknown mark!");
- mp->m_next = m->m_next;
- }
- free((char *) m);
- }
-
- void
- AllMarkSet(b, line, col)
- Buffer *b;
- register Line *line;
- int col;
- {
- register Mark *mp;
-
- for (mp = b->b_marks; mp != 0; mp = mp->m_next)
- MarkSet(mp, line, col);
- }
-
- void
- MarkSet(m, line, column)
- Mark *m;
- Line *line;
- int column;
- {
- m->m_line = line;
- m->m_char = column;
- }
-
- void
- PopMark()
- {
- int pmark;
-
- if (curmark == 0)
- return;
- if (curbuf->b_markring[(curbuf->b_themark + 1) % NMARKS] == 0) {
- pmark = curbuf->b_themark;
- do {
- if (--pmark < 0)
- pmark = NMARKS - 1;
- } while (curbuf->b_markring[pmark] != 0);
-
- curbuf->b_markring[pmark] = MakeMark(curline, curchar, MarksShouldFloat ? M_FLOATER : M_FIXED);
- ToMark(curmark);
- DelMark(curmark);
- curmark = 0;
- } else
- PtToMark();
-
- pmark = curbuf->b_themark - 1;
- if (pmark < 0)
- pmark = NMARKS - 1;
- curbuf->b_themark = pmark;
- }
-
- void
- SetMark()
- {
- if (is_an_arg())
- PopMark();
- else
- set_mark();
- }
-
- void
- set_mark()
- {
- do_set_mark(curline, curchar);
- }
-
- void
- do_set_mark(l, c)
- Line *l;
- int c;
- {
- curbuf->b_themark = (curbuf->b_themark + 1) % NMARKS;
- if (curmark == 0)
- curmark = MakeMark(l, c, MarksShouldFloat ? M_FLOATER : M_FIXED);
- else
- MarkSet(curmark, l, c);
- s_mess("[Point pushed]");
- }
-
- /* Move point to Mark */
-
- void
- ToMark(m)
- Mark *m;
- {
- int len;
-
- if (m == 0)
- return;
- DotTo(m->m_line, m->m_char);
- if (curchar > (len = length(curline)))
- curchar = len;
- }
-
- Mark *
- CurMark()
- {
- if (curmark == 0)
- complain("No mark.");
- return curmark;
- }
-
- void
- PtToMark()
- {
- Line *mline;
- int mchar;
- Mark *m = CurMark();
-
- mline = curline;
- mchar = curchar;
-
- ToMark(m);
- MarkSet(m, mline, mchar);
- }
-
- /* Fix marks for after a deletion. For now, even marks that don't
- float will actually float, because we can't allow marks to point
- to non-existant lines. */
-
- void
- DFixMarks(line1, char1, line2, char2)
- register Line *line1,
- *line2;
- int char1,
- char2;
- {
- register Mark *m;
- Line *lp = line1;
-
- if (curbuf->b_marks == 0)
- return;
- while (lp != line2->l_next) {
- for (m = curbuf->b_marks; m != 0; m = m->m_next)
- if (m->m_line == lp)
- m->m_char |= (1 << 15);
- lp = lp->l_next;
- }
- for (m = curbuf->b_marks; m; m = m->m_next) {
- if ((m->m_char & (1 << 15)) == 0)
- continue; /* Not effected */
- m->m_char &= ~(1 << 15);
- if (m->m_line == line1 && m->m_char < char1)
- continue; /* This mark is not affected */
- if (line1 == line2) {
- if (m->m_char >= char1 && m->m_char <= char2)
- m->m_char = char1;
- else if (m->m_char > char2)
- m->m_char -= (char2 - char1);
- /* Same line move the mark backward */
- } else if (m->m_line == line2) {
- if (m->m_char > char2)
- m->m_char = char1 + (m->m_char - char2);
- else
- m->m_char = char1;
- m->m_flags |= M_BIG_DELETE;
- m->m_line = line1;
- } else {
- m->m_char = char1;
- m->m_line = line1;
- m->m_flags |= M_BIG_DELETE;
- }
- }
- }
-
- /* Fix marks after an insertion. Marks that don't float are ignored
- on insertion, which means PtToMark has to be careful ... */
-
- void
- IFixMarks(line1, char1, line2, char2)
- register Line *line1,
- *line2;
- int char1,
- char2;
- {
- register Mark *m;
-
- for (m = curbuf->b_marks; m != 0; m = m->m_next) {
- if ((m->m_flags & M_FLOATER) == 0)
- continue;
- if (m->m_line == line1) {
- if (m->m_char > char1) {
- m->m_line = line2;
- if (line1 == line2)
- m->m_char += (char2 - char1);
- else
- m->m_char = char2 + (m->m_char - char1);
- }
- }
- }
- }
-