port of netbsd's tr
[minix.git] / commands / elvis / move5.c
blobaec5e785b0080526f7aa1e6b8ac51ea4527c4173
1 /* move5.c */
3 /* Author:
4 * Steve Kirkendall
5 * 14407 SW Teal Blvd. #C
6 * Beaverton, OR 97005
7 * kirkenda@cs.pdx.edu
8 */
11 /* This file contains the word-oriented movement functions */
13 #include "config.h"
14 #include "ctype.h"
15 #include "vi.h"
17 MARK m_fword(m, cnt, cmd, prevkey)
18 MARK m; /* movement is relative to this mark */
19 long cnt; /* a numeric argument */
20 int cmd; /* either 'w' or 'W' */
21 int prevkey;/* previous command... if 'c' then exclude whitespace */
23 REG long l;
24 REG char *text;
25 REG int i;
27 DEFAULT(1);
29 l = markline(m);
30 pfetch(l);
31 text = ptext + markidx(m);
33 #ifndef CRUNCH
34 /* As a special case, "cw" or "cW" on whitespace without a count
35 * treats the single whitespace character under the cursor as a word.
37 if (cnt == 1L && prevkey == 'c' && isspace(*text))
39 return m + 1L;
41 #endif
43 while (cnt-- > 0) /* yes, ASSIGNMENT! */
45 i = *text++;
47 if (cmd == 'W')
49 /* include any non-whitespace */
50 while (i && !isspace(i))
52 i = *text++;
55 else if (isalnum(i) || i == '_')
57 /* include an alphanumeric word */
58 while (i && isalnum(i))
60 i = *text++;
63 else
65 /* include contiguous punctuation */
66 while (i && !isalnum(i) && !isspace(i))
68 i = *text++;
72 /* if not part of "cw" or "cW" command... */
73 if (prevkey != 'c' || cnt > 0)
75 /* include trailing whitespace */
76 while (!i || isspace(i))
78 /* did we hit the end of this line? */
79 if (!i)
81 /* "dw" shouldn't delete newline after word */
82 if (prevkey && cnt == 0)
84 break;
87 /* move to next line, if there is one */
88 l++;
89 if (l > nlines)
91 return MARK_UNSET;
93 pfetch(l);
94 text = ptext;
97 i = *text++;
100 text--;
103 /* if argument to operator, then back off 1 char since "w" and "W"
104 * include the last char in the affected text.
106 if (prevkey)
108 text--;
111 /* construct a MARK for this place */
112 m = buildmark(text);
113 return m;
117 MARK m_bword(m, cnt, cmd)
118 MARK m; /* movement is relative to this mark */
119 long cnt; /* a numeric argument */
120 int cmd; /* either 'b' or 'B' */
122 REG long l;
123 REG char *text;
125 DEFAULT(1);
127 l = markline(m);
128 pfetch(l);
129 text = ptext + markidx(m);
130 while (cnt-- > 0) /* yes, ASSIGNMENT! */
132 text--;
134 /* include preceding whitespace */
135 while (text < ptext || isspace(*text))
137 /* did we hit the end of this line? */
138 if (text < ptext)
140 /* move to preceding line, if there is one */
141 l--;
142 if (l <= 0)
144 return MARK_UNSET;
146 pfetch(l);
147 text = ptext + plen - 1;
149 else
151 text--;
155 if (cmd == 'B')
157 /* include any non-whitespace */
158 while (text >= ptext && !isspace(*text))
160 text--;
163 else if (isalnum(*text) || *text == '_')
165 /* include an alphanumeric word */
166 while (text >= ptext && isalnum(*text))
168 text--;
171 else
173 /* include contiguous punctuation */
174 while (text >= ptext && !isalnum(*text) && !isspace(*text))
176 text--;
179 text++;
182 /* construct a MARK for this place */
183 m = buildmark(text);
184 return m;
187 MARK m_eword(m, cnt, cmd)
188 MARK m; /* movement is relative to this mark */
189 long cnt; /* a numeric argument */
190 int cmd; /* either 'e' or 'E' */
192 REG long l;
193 REG char *text;
194 REG int i;
196 DEFAULT(1);
198 l = markline(m);
199 pfetch(l);
200 text = ptext + markidx(m);
201 while (cnt-- > 0) /* yes, ASSIGNMENT! */
203 if (*text)
204 text++;
205 i = *text++;
207 /* include preceding whitespace */
208 while (!i || isspace(i))
210 /* did we hit the end of this line? */
211 if (!i)
213 /* move to next line, if there is one */
214 l++;
215 if (l > nlines)
217 return MARK_UNSET;
219 pfetch(l);
220 text = ptext;
223 i = *text++;
226 if (cmd == 'E')
228 /* include any non-whitespace */
229 while (i && !isspace(i))
231 i = *text++;
234 else if (isalnum(i) || i == '_')
236 /* include an alphanumeric word */
237 while (i && isalnum(i))
239 i = *text++;
242 else
244 /* include contiguous punctuation */
245 while (i && !isalnum(i) && !isspace(i))
247 i = *text++;
250 text -= 2;
253 /* construct a MARK for this place */
254 m = buildmark(text);
255 return m;