995
|
1 /*
|
|
2 * The routines in this file move the cursor around on the screen. They
|
|
3 * compute a new value for the cursor, then adjust ".". The display code
|
|
4 * always updates the cursor location, so only moves between lines, or
|
|
5 * functions that adjust the top line in the window and invalidate the
|
|
6 * framing, are hard.
|
|
7 */
|
|
8 #include <stdio.h>
|
|
9 #include "ueed.h"
|
|
10
|
|
11 /*
|
|
12 * Move the cursor to the
|
|
13 * beginning of the current line.
|
|
14 * Trivial.
|
|
15 */
|
|
16 gotobol(f, n)
|
|
17 {
|
|
18 curwp->w_doto = 0;
|
|
19 return (TRUE);
|
|
20 }
|
|
21
|
|
22 /*
|
|
23 * Move the cursor backwards by "n" characters. If "n" is less than zero call
|
|
24 * "forwchar" to actually do the move. Otherwise compute the new cursor
|
|
25 * location. Error if you try and move out of the buffer. Set the flag if the
|
|
26 * line pointer for dot changes.
|
|
27 */
|
|
28 backchar(f, n)
|
|
29 register int n;
|
|
30 {
|
|
31 register LINE *lp;
|
|
32
|
|
33 if (n < 0)
|
|
34 return (forwchar(f, -n));
|
|
35 while (n--) {
|
|
36 if (curwp->w_doto == 0) {
|
|
37 if ((lp=lback(curwp->w_dotp)) == curbp->b_linep)
|
|
38 return (FALSE);
|
|
39 curwp->w_dotp = lp;
|
|
40 curwp->w_doto = llength(lp);
|
|
41 curwp->w_flag |= WFMOVE;
|
|
42 } else
|
|
43 curwp->w_doto--;
|
|
44 }
|
|
45 return (TRUE);
|
|
46 }
|
|
47
|
|
48 /*
|
|
49 * Move the cursor to the end of the current line. Trivial. No errors.
|
|
50 */
|
|
51 gotoeol(f, n)
|
|
52 {
|
|
53 curwp->w_doto = llength(curwp->w_dotp);
|
|
54 return (TRUE);
|
|
55 }
|
|
56
|
|
57 /*
|
|
58 * Move the cursor forwwards by "n" characters. If "n" is less than zero call
|
|
59 * "backchar" to actually do the move. Otherwise compute the new cursor
|
|
60 * location, and move ".". Error if you try and move off the end of the
|
|
61 * buffer. Set the flag if the line pointer for dot changes.
|
|
62 */
|
|
63 forwchar(f, n)
|
|
64 register int n;
|
|
65 {
|
|
66 if (n < 0)
|
|
67 return (backchar(f, -n));
|
|
68 while (n--) {
|
|
69 if (curwp->w_doto == llength(curwp->w_dotp)) {
|
|
70 if (curwp->w_dotp == curbp->b_linep)
|
|
71 return (FALSE);
|
|
72 curwp->w_dotp = lforw(curwp->w_dotp);
|
|
73 curwp->w_doto = 0;
|
|
74 curwp->w_flag |= WFMOVE;
|
|
75 } else
|
|
76 curwp->w_doto++;
|
|
77 }
|
|
78 return (TRUE);
|
|
79 }
|
|
80
|
|
81 /*
|
|
82 * Goto the beginning of the buffer. Massive adjustment of dot. This is
|
|
83 * considered to be hard motion; it really isn't if the original value of dot
|
|
84 * is the same as the new value of dot. Normally bound to "M-<".
|
|
85 */
|
|
86 gotobob(f, n)
|
|
87 {
|
|
88 curwp->w_dotp = lforw(curbp->b_linep);
|
|
89 curwp->w_doto = 0;
|
|
90 curwp->w_flag |= WFHARD;
|
|
91 return (TRUE);
|
|
92 }
|
|
93
|
|
94 /*
|
|
95 * Move to the end of the buffer. Dot is always put at the end of the file
|
|
96 * (ZJ). The standard screen code does most of the hard parts of update.
|
|
97 * Bound to "M->".
|
|
98 */
|
|
99 gotoeob(f, n)
|
|
100 {
|
|
101 curwp->w_dotp = curbp->b_linep;
|
|
102 curwp->w_doto = 0;
|
|
103 curwp->w_flag |= WFHARD;
|
|
104 return (TRUE);
|
|
105 }
|
|
106
|
|
107 /*
|
|
108 * Move forward by full lines. If the number of lines to move is less than
|
|
109 * zero, call the backward line function to actually do it. The last command
|
|
110 * controls how the goal column is set. Bound to "C-N". No errors are
|
|
111 * possible.
|
|
112 */
|
|
113 forwline(f, n)
|
|
114 {
|
|
115 register LINE *dlp;
|
|
116
|
|
117 if (n < 0)
|
|
118 return (backline(f, -n));
|
|
119 if ((lastflag&CFCPCN) == 0) /* Reset goal if last */
|
|
120 curgoal = curcol; /* not C-P or C-N */
|
|
121 thisflag |= CFCPCN;
|
|
122 dlp = curwp->w_dotp;
|
|
123 while (n-- && dlp!=curbp->b_linep)
|
|
124 dlp = lforw(dlp);
|
|
125 curwp->w_dotp = dlp;
|
|
126 curwp->w_doto = getgoal(dlp);
|
|
127 curwp->w_flag |= WFMOVE;
|
|
128 return (TRUE);
|
|
129 }
|
|
130
|
|
131 /*
|
|
132 * This function is like "forwline", but goes backwards. The scheme is exactly
|
|
133 * the same. Check for arguments that are less than zero and call your
|
|
134 * alternate. Figure out the new line and call "movedot" to perform the
|
|
135 * motion. No errors are possible. Bound to "C-P".
|
|
136 */
|
|
137 backline(f, n)
|
|
138 {
|
|
139 register LINE *dlp;
|
|
140
|
|
141 if (n < 0)
|
|
142 return (forwline(f, -n));
|
|
143 if ((lastflag&CFCPCN) == 0) /* Reset goal if the */
|
|
144 curgoal = curcol; /* last isn't C-P, C-N */
|
|
145 thisflag |= CFCPCN;
|
|
146 dlp = curwp->w_dotp;
|
|
147 while (n-- && lback(dlp)!=curbp->b_linep)
|
|
148 dlp = lback(dlp);
|
|
149 curwp->w_dotp = dlp;
|
|
150 curwp->w_doto = getgoal(dlp);
|
|
151 curwp->w_flag |= WFMOVE;
|
|
152 return (TRUE);
|
|
153 }
|
|
154
|
|
155 /*
|
|
156 * This routine, given a pointer to a LINE, and the current cursor goal
|
|
157 * column, return the best choice for the offset. The offset is returned.
|
|
158 * Used by "C-N" and "C-P".
|
|
159 */
|
|
160 getgoal(dlp)
|
|
161 register LINE *dlp;
|
|
162 {
|
|
163 register int c;
|
|
164 register int col;
|
|
165 register int newcol;
|
|
166 register int dbo;
|
|
167
|
|
168 col = 0;
|
|
169 dbo = 0;
|
|
170 while (dbo != llength(dlp)) {
|
|
171 c = lgetc(dlp, dbo);
|
|
172 newcol = col;
|
|
173 if (c == '\t')
|
|
174 newcol |= 0x07;
|
|
175 else if (c<0x20 || c==0x7F)
|
|
176 ++newcol;
|
|
177 ++newcol;
|
|
178 if (newcol > curgoal)
|
|
179 break;
|
|
180 col = newcol;
|
|
181 ++dbo;
|
|
182 }
|
|
183 return (dbo);
|
|
184 }
|
|
185
|
|
186 /*
|
|
187 * Scroll forward by a specified number of lines, or by a full page if no
|
|
188 * argument. Bound to "C-V". The "2" in the arithmetic on the window size is
|
|
189 * the overlap; this value is the default overlap value in ITS EMACS. Because
|
|
190 * this zaps the top line in the display window, we have to do a hard update.
|
|
191 */
|
|
192 forwpage(f, n)
|
|
193 register int n;
|
|
194 {
|
|
195 register LINE *lp;
|
|
196
|
|
197 if (f == FALSE) {
|
|
198 n = curwp->w_ntrows - 2; /* Default scroll. */
|
|
199 if (n <= 0) /* Forget the overlap */
|
|
200 n = 1; /* if tiny window. */
|
|
201 } else if (n < 0)
|
|
202 return (backpage(f, -n));
|
|
203 #ifdef CVMVAS
|
|
204 else /* Convert from pages */
|
|
205 n *= curwp->w_ntrows; /* to lines. */
|
|
206 #endif
|
|
207 lp = curwp->w_linep;
|
|
208 while (n-- && lp!=curbp->b_linep)
|
|
209 lp = lforw(lp);
|
|
210 curwp->w_linep = lp;
|
|
211 curwp->w_dotp = lp;
|
|
212 curwp->w_doto = 0;
|
|
213 curwp->w_flag |= WFHARD;
|
|
214 return (TRUE);
|
|
215 }
|
|
216
|
|
217 /*
|
|
218 * This command is like "forwpage", but it goes backwards. The "2", like
|
|
219 * above, is the overlap between the two windows. The value is from the ITS
|
|
220 * EMACS manual. Bound to "M-V". We do a hard update for exactly the same
|
|
221 * reason.
|
|
222 */
|
|
223 backpage(f, n)
|
|
224 register int n;
|
|
225 {
|
|
226 register LINE *lp;
|
|
227
|
|
228 if (f == FALSE) {
|
|
229 n = curwp->w_ntrows - 2; /* Default scroll. */
|
|
230 if (n <= 0) /* Don't blow up if the */
|
|
231 n = 1; /* window is tiny. */
|
|
232 } else if (n < 0)
|
|
233 return (forwpage(f, -n));
|
|
234 #ifdef CVMVAS
|
|
235 else /* Convert from pages */
|
|
236 n *= curwp->w_ntrows; /* to lines. */
|
|
237 #endif
|
|
238 lp = curwp->w_linep;
|
|
239 while (n-- && lback(lp)!=curbp->b_linep)
|
|
240 lp = lback(lp);
|
|
241 curwp->w_linep = lp;
|
|
242 curwp->w_dotp = lp;
|
|
243 curwp->w_doto = 0;
|
|
244 curwp->w_flag |= WFHARD;
|
|
245 return (TRUE);
|
|
246 }
|
|
247
|
|
248 /*
|
|
249 * Set the mark in the current window to the value of "." in the window. No
|
|
250 * errors are possible. Bound to "M-.".
|
|
251 */
|
|
252 setmark(f, n)
|
|
253 {
|
|
254 curwp->w_markp = curwp->w_dotp;
|
|
255 curwp->w_marko = curwp->w_doto;
|
|
256 mlwrite("[Mark set]");
|
|
257 return (TRUE);
|
|
258 }
|
|
259
|
|
260 /*
|
|
261 * Swap the values of "." and "mark" in the current window. This is pretty
|
|
262 * easy, bacause all of the hard work gets done by the standard routine
|
|
263 * that moves the mark about. The only possible error is "no mark". Bound to
|
|
264 * "C-X C-X".
|
|
265 */
|
|
266 swapmark(f, n)
|
|
267 {
|
|
268 register LINE *odotp;
|
|
269 register int odoto;
|
|
270
|
|
271 if (curwp->w_markp == NULL) {
|
|
272 mlwrite("No mark in this window");
|
|
273 return (FALSE);
|
|
274 }
|
|
275 odotp = curwp->w_dotp;
|
|
276 odoto = curwp->w_doto;
|
|
277 curwp->w_dotp = curwp->w_markp;
|
|
278 curwp->w_doto = curwp->w_marko;
|
|
279 curwp->w_markp = odotp;
|
|
280 curwp->w_marko = odoto;
|
|
281 curwp->w_flag |= WFMOVE;
|
|
282 return (TRUE);
|
|
283 }
|