1: /************************************************************************* 2: * This program is copyright (C) 1985, 1986 by Jonathan Payne. It is * 3: * provided to you without charge for use only on a licensed Unix * 4: * system. You may copy JOVE provided that this notice is included with * 5: * the copy. You may not sell copies of this program or versions * 6: * modified for use on microcomputer systems, unless the copies are * 7: * included with a Unix system distribution and the source is provided. * 8: *************************************************************************/ 9: 10: int MarksShouldFloat = 1; 11: 12: #include "jove.h" 13: 14: Mark * 15: MakeMark(line, column, type) 16: register Line *line; 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_floater = type; 23: curbuf->b_marks = newmark; 24: return newmark; 25: } 26: 27: DelMark(m) 28: register Mark *m; 29: { 30: register Mark *mp = curbuf->b_marks; 31: 32: if (m == mp) 33: curbuf->b_marks = m->m_next; 34: else { 35: while (mp != 0 && mp->m_next != m) 36: mp = mp->m_next; 37: if (mp == 0) 38: complain("Unknown mark!"); 39: mp->m_next = m->m_next; 40: } 41: free((char *) m); 42: } 43: 44: AllMarkSet(b, line, col) 45: Buffer *b; 46: register Line *line; 47: { 48: register Mark *mp; 49: 50: for (mp = b->b_marks; mp != 0; mp = mp->m_next) 51: MarkSet(mp, line, col); 52: } 53: 54: MarkSet(m, line, column) 55: Mark *m; 56: Line *line; 57: { 58: m->m_line = line; 59: m->m_char = column; 60: } 61: 62: PopMark() 63: { 64: int pmark; 65: 66: if (curmark == 0) 67: return; 68: if (curbuf->b_markring[(curbuf->b_themark + 1) % NMARKS] == 0) { 69: pmark = curbuf->b_themark; 70: do { 71: if (--pmark < 0) 72: pmark = NMARKS - 1; 73: } while (curbuf->b_markring[pmark] != 0); 74: 75: curbuf->b_markring[pmark] = MakeMark(curline, curchar, MarksShouldFloat); 76: ToMark(curmark); 77: DelMark(curmark); 78: curmark = 0; 79: } else 80: PtToMark(); 81: 82: pmark = curbuf->b_themark - 1; 83: if (pmark < 0) 84: pmark = NMARKS - 1; 85: curbuf->b_themark = pmark; 86: } 87: 88: SetMark() 89: { 90: if (exp_p) 91: PopMark(); 92: else 93: DoSetMark(curline, curchar); 94: } 95: 96: DoSetMark(l, c) 97: Line *l; 98: { 99: curbuf->b_themark = (curbuf->b_themark + 1) % NMARKS; 100: if (curmark == 0) 101: curmark = MakeMark(l, c, MarksShouldFloat); 102: else 103: MarkSet(curmark, l, c); 104: s_mess("[Point pushed]"); 105: } 106: 107: /* Move point to Mark */ 108: 109: ToMark(m) 110: Mark *m; 111: { 112: int len; 113: 114: if (m == 0) 115: return; 116: DotTo(m->m_line, m->m_char); 117: if (curchar > (len = length(curline))) 118: curchar = len; 119: } 120: 121: Mark * 122: CurMark() 123: { 124: if (curmark == 0) 125: complain("No mark."); 126: return curmark; 127: } 128: 129: PtToMark() 130: { 131: Line *mline; 132: int mchar; 133: Mark *m = CurMark(); 134: 135: mline = curline; 136: mchar = curchar; 137: 138: ToMark(m); 139: MarkSet(m, mline, mchar); 140: } 141: 142: /* Fix marks for after a deletion. For now, even marks that don't 143: float will actually float, because we can't allow marks to point 144: to non-existant lines. */ 145: 146: DFixMarks(line1, char1, line2, char2) 147: register Line *line1, 148: *line2; 149: { 150: register Mark *m; 151: Line *lp = line1; 152: 153: if (curbuf->b_marks == 0) 154: return; 155: while (lp != line2->l_next) { 156: for (m = curbuf->b_marks; m != 0; m = m->m_next) { 157: /* if (!m->m_floater) 158: continue; */ 159: if (m->m_line == lp) 160: m->m_char |= (1 << 15); 161: } 162: lp = lp->l_next; 163: } 164: for (m = curbuf->b_marks; m; m = m->m_next) { 165: /* if (!m->m_floater) 166: continue; */ 167: if ((m->m_char & (1 << 15)) == 0) 168: continue; /* Not effected */ 169: m->m_char &= ~(1 << 15); 170: if (m->m_line == line1 && m->m_char < char1) 171: continue; /* This mark is not affected */ 172: if (line1 == line2) { 173: if (m->m_char >= char1 && m->m_char <= char2) 174: m->m_char = char1; 175: else if (m->m_char > char2) 176: m->m_char -= (char2 - char1); 177: /* Same line move the mark backward */ 178: } else if (m->m_line == line2) { 179: if (m->m_char > char2) 180: m->m_char = char1 + (m->m_char - char2); 181: else 182: m->m_char = char1; 183: m->m_line = line1; 184: } else { 185: m->m_char = char1; 186: m->m_line = line1; 187: } 188: } 189: } 190: 191: /* Fix marks after an insertion. Marks that don't float are ignored 192: on insertion, which means PtToMark has to be careful ... */ 193: 194: IFixMarks(line1, char1, line2, char2) 195: register Line *line1, 196: *line2; 197: { 198: register Mark *m; 199: 200: for (m = curbuf->b_marks; m != 0; m = m->m_next) { 201: if (!m->m_floater) 202: continue; 203: if (m->m_line == line1) { 204: if (m->m_char > char1) { 205: m->m_line = line2; 206: if (line1 == line2) 207: m->m_char += (char2 - char1); 208: else 209: m->m_char = char2 + (m->m_char - char1); 210: } 211: } 212: } 213: }