|
|
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: #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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.