Mercurial > hg > Members > kono > nitros9-code
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 } |