|
|
1.1 root 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: /* Routines to perform all kinds of deletion. */
11:
12: #include "jove.h"
13:
14: /* Assumes that either line1 or line2 is actual the current line, so it can
15: put its result into linebuf. */
16:
17: patchup(line1, char1, line2, char2)
18: Line *line1,
19: *line2;
20: register int char1,
21: char2;
22: {
23: if (line1 != line2)
24: ChkWindows(line1, line2);
25: DotTo(line1, char1);
26: modify();
27: linecopy(linebuf, curchar, lcontents(line2) + char2);
28:
29: /* The following is a redisplay optimization. */
30: if (line1 != line2 && (char1 == 0 && char2 == 0))
31: line1->l_dline = line2->l_dline;
32:
33: DFixMarks(line1, char1, line2, char2);
34: makedirty(curline);
35: }
36:
37: /* Deletes the region by unlinking the lines in the middle,
38: and patching things up. The unlinked lines are still in
39: order. */
40:
41: Line *
42: reg_delete(line1, char1, line2, char2)
43: Line *line1,
44: *line2;
45: {
46: register Line *retline;
47:
48: if ((line1 == line2 && char1 == char2) || line2 == 0)
49: complain((char *) 0);
50: (void) fixorder(&line1, &char1, &line2, &char2);
51:
52: retline = nbufline(); /* New buffer line */
53:
54: (void) ltobuf(line1, genbuf);
55: if (line1 == line2)
56: genbuf[char2] = '\0';
57:
58: retline->l_prev = 0;
59: retline->l_dline = putline(&genbuf[char1]);
60: patchup(line1, char1, line2, char2);
61:
62: if (line1 == line2)
63: retline->l_next = 0;
64: else {
65: retline->l_next = line1->l_next;
66: (void) ltobuf(line2, genbuf);
67: genbuf[char2] = '\0';
68: line2->l_dline = putline(genbuf);
69: /* Shorten this line */
70: }
71:
72: if (line1 != line2) {
73: line1->l_next = line2->l_next;
74: if (line1->l_next)
75: line1->l_next->l_prev = line1;
76: else
77: curbuf->b_last = line1;
78: line2->l_next = 0;
79: }
80:
81: return retline;
82: }
83:
84: lremove(line1, line2)
85: register Line *line1,
86: *line2;
87: {
88: Line *next = line1->l_next;
89:
90: if (line1 == line2)
91: return;
92: line1->l_next = line2->l_next;
93: if (line1->l_next)
94: line1->l_next->l_prev = line1;
95: else
96: curbuf->b_last = line1;
97: lfreereg(next, line2); /* Put region at end of free line list. */
98: }
99:
100: /* Delete character forward */
101:
102: DelNChar()
103: {
104: del_char(1);
105: }
106:
107: /* Delete character backward */
108:
109: DelPChar()
110: {
111: if (MinorMode(OverWrite)) {
112: int count = min(exp, curchar);
113:
114: DoTimes(BackChar(), count);
115: LastKeyStruck = ' '; /* can you say gross? */
116: DoTimes(SelfInsert(), count);
117: DoTimes(BackChar(), count);
118: } else
119: del_char(0);
120: }
121:
122: /* Delete some characters. If deleting `forward' then call for_char
123: to the final position otherwise call back_char. Then delete the
124: region between the two with patchup(). */
125:
126: del_char(forward)
127: {
128: Bufpos before,
129: after;
130: int killp = (exp_p && abs(exp) > 1);
131:
132: DOTsave(&before);
133: (forward) ? ForChar() : BackChar();
134: if (before.p_line == curline && before.p_char == curchar)
135: complain((char *) 0);
136: if (killp)
137: reg_kill(before.p_line, before.p_char, 1);
138: else {
139: DOTsave(&after);
140: (void) fixorder(&before.p_line, &before.p_char, &after.p_line, &after.p_char);
141: patchup(before.p_line, before.p_char, after.p_line, after.p_char);
142: lremove(before.p_line, after.p_line);
143: }
144: }
145:
146: /* This kills a region between point, and line1/char1 and puts it on
147: the kill-ring. If the last command was one of the kill commands,
148: the region is appended (prepended if backwards) to the last entry. */
149:
150: int killptr = 0;
151: Line *killbuf[NUMKILLS];
152:
153: reg_kill(line2, char2, dot_moved)
154: Line *line2;
155: {
156: Line *nl,
157: *line1 = curline;
158: int char1 = curchar;
159: int backwards;
160:
161: backwards = !fixorder(&line1, &char1, &line2, &char2);
162: /* This is a kludge! But it possible for commands that don't
163: know which direction they are deleting in (e.g., delete
164: previous word could have been called with a negative argument
165: in which case, it wouldn't know that it really deleted
166: forward. */
167:
168: if (!dot_moved)
169: backwards = !backwards;
170:
171: DotTo(line1, char1);
172:
173: nl = reg_delete(line1, char1, line2, char2);
174:
175: if (last_cmd != KILLCMD) {
176: killptr = ((killptr + 1) % NUMKILLS);
177: lfreelist(killbuf[killptr]);
178: killbuf[killptr] = nl;
179: } else {
180: Line *lastln = lastline(nl);
181:
182: if (backwards)
183: (void) DoYank(nl, 0, lastln, length(lastln), killbuf[killptr], 0, (Buffer *) 0);
184: else {
185: Line *olastln = lastline(killbuf[killptr]);
186:
187: (void) DoYank(nl, 0, lastln, length(lastln), olastln, length(olastln), (Buffer *) 0);
188: }
189: }
190: this_cmd = KILLCMD;
191: }
192:
193: DelReg()
194: {
195: register Mark *mp = CurMark();
196:
197: reg_kill(mp->m_line, mp->m_char, 0);
198: }
199:
200: /* Save a region. A pretend kill. */
201:
202: CopyRegion()
203: {
204: register Line *nl;
205: register Mark *mp;
206: register int status;
207:
208: mp = CurMark();
209: if (mp->m_line == curline && mp->m_char == curchar)
210: complain((char *) 0);
211:
212: killptr = ((killptr + 1) % NUMKILLS);
213: if (killbuf[killptr])
214: lfreelist(killbuf[killptr]);
215: nl = killbuf[killptr] = nbufline();
216: SavLine(nl, NullStr);
217: nl->l_next = nl->l_prev = 0;
218:
219: status = inorder(mp->m_line, mp->m_char, curline, curchar);
220: if (status == -1)
221: return;
222:
223: if (status)
224: (void) DoYank(mp->m_line, mp->m_char, curline, curchar,
225: nl, 0, (Buffer *) 0);
226: else
227: (void) DoYank(curline, curchar, mp->m_line, mp->m_char,
228: nl, 0, (Buffer *) 0);
229: }
230:
231: DelWtSpace()
232: {
233: register char *ep = &linebuf[curchar],
234: *sp = &linebuf[curchar];
235:
236: while (*ep == ' ' || *ep == '\t')
237: ep++;
238: while (sp > linebuf && *(sp - 1) == ' ' || *(sp - 1) == '\t')
239: sp--;
240: if (sp != ep) {
241: curchar = sp - linebuf;
242: DFixMarks(curline, curchar, curline, curchar + (ep - sp));
243: strcpy(sp, ep);
244: makedirty(curline);
245: modify();
246: }
247: }
248:
249: DelBlnkLines()
250: {
251: register Mark *dot;
252: int all;
253:
254: exp = 1;
255: if (!blnkp(&linebuf[curchar]))
256: return;
257: dot = MakeMark(curline, curchar, FLOATER);
258: all = !blnkp(linebuf);
259: while (blnkp(linebuf) && curline->l_prev)
260: SetLine(curline->l_prev);
261: all |= (firstp(curline));
262: Eol();
263: DelWtSpace();
264: line_move(FORWARD, NO);
265: while (blnkp(linebuf) && !eobp()) {
266: DelWtSpace();
267: DelNChar();
268: }
269: if (!all && !eobp())
270: OpenLine();
271: ToMark(dot);
272: DelMark(dot);
273: }
274:
275: DelNWord()
276: {
277: dword(1);
278: }
279:
280: DelPWord()
281: {
282: dword(0);
283: }
284:
285: dword(forward)
286: {
287: Bufpos savedot;
288:
289: DOTsave(&savedot);
290: forward ? ForWord() : BackWord();
291: reg_kill(savedot.p_line, savedot.p_char, 1);
292: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.