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