Commit | Line | Data |
---|---|---|
fb51ca13 C |
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 | #include "jove.h" | |
11 | #include "ctype.h" | |
12 | ||
13 | static int line_pos; | |
14 | ||
15 | ForChar() | |
16 | { | |
17 | register int num = exp; | |
18 | ||
19 | if (exp < 0) { | |
20 | exp = -exp; | |
21 | BackChar(); | |
22 | return; | |
23 | } | |
24 | exp = 1; | |
25 | while (--num >= 0) { | |
26 | if (eolp()) { /* Go to the next Line */ | |
27 | if (curline->l_next == 0) | |
28 | break; | |
29 | SetLine(curline->l_next); | |
30 | } else | |
31 | curchar++; | |
32 | } | |
33 | } | |
34 | ||
35 | BackChar() | |
36 | { | |
37 | register int num = exp; | |
38 | ||
39 | if (exp < 0) { | |
40 | exp = -exp; | |
41 | ForChar(); | |
42 | return; | |
43 | } | |
44 | exp = 1; | |
45 | while (--num >= 0) { | |
46 | if (bolp()) { | |
47 | if (curline->l_prev == 0) | |
48 | break; | |
49 | SetLine(curline->l_prev); | |
50 | Eol(); | |
51 | } else | |
52 | --curchar; | |
53 | } | |
54 | } | |
55 | ||
56 | NextLine() | |
57 | { | |
58 | if ((curline == curbuf->b_last) && eolp()) | |
59 | complain(NullStr); | |
60 | line_move(FORWARD, YES); | |
61 | } | |
62 | ||
63 | PrevLine() | |
64 | { | |
65 | if ((curline == curbuf->b_first) && bolp()) | |
66 | complain(NullStr); | |
67 | line_move(BACKWARD, YES); | |
68 | } | |
69 | ||
70 | /* moves to a different line in DIR; LINE_CMD says whether this is | |
71 | being called from NextLine() or PrevLine(), in which case it tries | |
72 | to line up the column with the column of the current line */ | |
73 | ||
74 | line_move(dir, line_cmd) | |
75 | { | |
76 | Line *(*proc)() = (dir == FORWARD) ? next_line : prev_line; | |
77 | Line *line; | |
78 | ||
79 | line = (*proc)(curline, exp); | |
80 | if (line == curline) { | |
81 | (dir == FORWARD) ? Eol() : Bol(); | |
82 | return; | |
83 | } | |
84 | ||
85 | if (line_cmd) { | |
86 | this_cmd = LINECMD; | |
87 | if (last_cmd != LINECMD) | |
88 | line_pos = calc_pos(linebuf, curchar); | |
89 | } | |
90 | SetLine(line); /* curline is in linebuf now */ | |
91 | if (line_cmd) | |
92 | curchar = how_far(curline, line_pos); | |
93 | } | |
94 | ||
95 | /* returns what cur_char should be for that position col */ | |
96 | ||
97 | how_far(line, col) | |
98 | Line *line; | |
99 | { | |
100 | register char *lp; | |
101 | register int pos, | |
102 | c; | |
103 | char *base; | |
104 | ||
105 | base = lp = lcontents(line); | |
106 | pos = 0; | |
107 | ||
108 | while (pos < col && (c = (*lp & 0177))) { | |
109 | if (c == '\t') | |
110 | pos += (tabstop - (pos % tabstop)); | |
111 | else if (isctrl(c)) | |
112 | pos += 2; | |
113 | else | |
114 | pos++; | |
115 | lp++; | |
116 | } | |
117 | ||
118 | return lp - base; | |
119 | } | |
120 | ||
121 | Bol() | |
122 | { | |
123 | curchar = 0; | |
124 | } | |
125 | ||
126 | Eol() | |
127 | { | |
128 | curchar = strlen(linebuf); | |
129 | } | |
130 | ||
131 | Eof() | |
132 | { | |
133 | PushPntp(curbuf->b_last); | |
134 | ToLast(); | |
135 | } | |
136 | ||
137 | Bof() | |
138 | { | |
139 | PushPntp(curbuf->b_first); | |
140 | ToFirst(); | |
141 | } | |
142 | ||
143 | /* Move forward (if dir > 0) or backward (if dir < 0) a sentence. Deals | |
144 | with all the kludgery involved with paragraphs, and moving backwards | |
145 | is particularly yucky. */ | |
146 | ||
147 | to_sent(dir) | |
148 | { | |
149 | Bufpos *new, | |
150 | old; | |
151 | extern char *ParaStr; | |
152 | ||
153 | DOTsave(&old); | |
154 | ||
155 | new = dosearch("^[ \t]*$\\|[?.!]", dir, 1); | |
156 | if (new == 0) { | |
157 | (dir < 0) ? ToFirst() : ToLast(); | |
158 | return; | |
159 | } | |
160 | SetDot(new); | |
161 | if (dir < 0) { | |
162 | to_word(1); | |
163 | if ((old.p_line == curline && old.p_char <= curchar) || | |
164 | (inorder(new->p_line, new->p_char, old.p_line, old.p_char) && | |
165 | inorder(old.p_line, old.p_char, curline, curchar))) { | |
166 | SetDot(new); | |
167 | to_sent(dir); | |
168 | } | |
169 | return; /* We're there? */ | |
170 | } | |
171 | if (blnkp(linebuf)) { | |
172 | Bol(); | |
173 | BackChar(); | |
174 | if (old.p_line == curline && old.p_char >= curchar) { | |
175 | to_word(1); /* Oh brother this is painful */ | |
176 | to_sent(1); | |
177 | } | |
178 | } else { | |
179 | extern int REbom; | |
180 | ||
181 | curchar = REbom + 1; /* Just after the [?.!] */ | |
182 | if (LookingAt("[\")] *\\|[\")]$", linebuf, curchar)) | |
183 | curchar++; | |
184 | else if (!eolp() && !LookingAt(" *", linebuf, curchar)) | |
185 | to_sent(dir); | |
186 | } | |
187 | } | |
188 | ||
189 | Bos() | |
190 | { | |
191 | int num = exp; | |
192 | ||
193 | if (exp < 0) { | |
194 | exp = -exp; | |
195 | Eos(); | |
196 | return; | |
197 | } | |
198 | ||
199 | exp = 1; | |
200 | ||
201 | while (--num >= 0) { | |
202 | to_sent(-1); | |
203 | if (bobp()) | |
204 | break; | |
205 | } | |
206 | } | |
207 | ||
208 | Eos() | |
209 | { | |
210 | int num = exp; | |
211 | ||
212 | if (exp < 0) { | |
213 | exp = -exp; | |
214 | Bos(); | |
215 | return; | |
216 | } | |
217 | ||
218 | exp = 1; | |
219 | ||
220 | while (--num >= 0) { | |
221 | to_sent(1); | |
222 | if (eobp()) | |
223 | break; | |
224 | } | |
225 | } | |
226 | ||
227 | ForWord() | |
228 | { | |
229 | register char c; | |
230 | register int num = exp; | |
231 | ||
232 | if (exp < 0) { | |
233 | exp = -exp; | |
234 | BackWord(); | |
235 | return; | |
236 | } | |
237 | exp = 1; | |
238 | while (--num >= 0) { | |
239 | to_word(1); | |
240 | while ((c = linebuf[curchar]) != 0 && isword(c)) | |
241 | curchar++; | |
242 | if (eobp()) | |
243 | break; | |
244 | } | |
245 | this_cmd = 0; /* Semi kludge to stop some unfavorable behavior */ | |
246 | } | |
247 | ||
248 | BackWord() | |
249 | { | |
250 | register int num = exp; | |
251 | register char c; | |
252 | ||
253 | if (exp < 0) { | |
254 | exp = -exp; | |
255 | ForWord(); | |
256 | return; | |
257 | } | |
258 | exp = 1; | |
259 | while (--num >= 0) { | |
260 | to_word(-1); | |
261 | while (!bolp() && (c = linebuf[curchar - 1], isword(c))) | |
262 | --curchar; | |
263 | if (bobp()) | |
264 | break; | |
265 | } | |
266 | this_cmd = 0; | |
267 | } |