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: }