comparison 3rdparty/packages/uemacs/uebasic.c @ 995:48c646212b1c

'microEMACS' for OS-9. Posted to USENET net.micro.6809, 4-May-86. Picked up from Google groups
author roug
date Sun, 23 Feb 2003 21:26:32 +0000
parents
children
comparison
equal deleted inserted replaced
994:bef1844de0dc 995:48c646212b1c
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 }