Annotation of src/usr.bin/mg/word.c, Revision 1.16
1.16 ! lum 1: /* $OpenBSD: word.c,v 1.15 2008/09/15 16:11:35 kjell Exp $ */
1.10 kjell 2:
3: /* This file is in the public domain. */
1.4 niklas 4:
1.1 deraadt 5: /*
6: * Word mode commands.
1.5 mickey 7: * The routines in this file implement commands that work word at a time.
1.3 millert 8: * There are all sorts of word mode commands.
9: */
10:
11: #include "def.h"
1.1 deraadt 12:
1.11 kjell 13: RSIZE countfword(void);
14:
1.1 deraadt 15: /*
1.5 mickey 16: * Move the cursor backward by "n" words. All of the details of motion are
1.3 millert 17: * performed by the "backchar" and "forwchar" routines.
1.1 deraadt 18: */
1.2 millert 19: /* ARGSUSED */
1.3 millert 20: int
1.8 cloder 21: backword(int f, int n)
1.1 deraadt 22: {
1.2 millert 23: if (n < 0)
1.9 db 24: return (forwword(f | FFRAND, -n));
1.1 deraadt 25: if (backchar(FFRAND, 1) == FALSE)
1.9 db 26: return (FALSE);
1.1 deraadt 27: while (n--) {
28: while (inword() == FALSE) {
29: if (backchar(FFRAND, 1) == FALSE)
1.9 db 30: return (TRUE);
1.1 deraadt 31: }
32: while (inword() != FALSE) {
33: if (backchar(FFRAND, 1) == FALSE)
1.9 db 34: return (TRUE);
1.1 deraadt 35: }
36: }
1.9 db 37: return (forwchar(FFRAND, 1));
1.1 deraadt 38: }
39:
40: /*
1.3 millert 41: * Move the cursor forward by the specified number of words. All of the
1.1 deraadt 42: * motion is done by "forwchar".
43: */
1.2 millert 44: /* ARGSUSED */
1.3 millert 45: int
1.8 cloder 46: forwword(int f, int n)
1.1 deraadt 47: {
48: if (n < 0)
1.9 db 49: return (backword(f | FFRAND, -n));
1.1 deraadt 50: while (n--) {
51: while (inword() == FALSE) {
52: if (forwchar(FFRAND, 1) == FALSE)
1.9 db 53: return (TRUE);
1.1 deraadt 54: }
55: while (inword() != FALSE) {
56: if (forwchar(FFRAND, 1) == FALSE)
1.9 db 57: return (TRUE);
1.1 deraadt 58: }
59: }
1.9 db 60: return (TRUE);
1.1 deraadt 61: }
62:
63: /*
1.3 millert 64: * Move the cursor forward by the specified number of words. As you move,
1.1 deraadt 65: * convert any characters to upper case.
66: */
1.2 millert 67: /* ARGSUSED */
1.3 millert 68: int
1.8 cloder 69: upperword(int f, int n)
1.1 deraadt 70: {
1.15 kjell 71: int c, s;
1.11 kjell 72: RSIZE size;
1.1 deraadt 73:
1.15 kjell 74: if ((s = checkdirty(curbp)) != TRUE)
75: return (s);
1.7 vincent 76: if (curbp->b_flag & BFREADONLY) {
1.16 ! lum 77: dobeep();
1.7 vincent 78: ewprintf("Buffer is read-only");
79: return (FALSE);
80: }
81:
1.2 millert 82: if (n < 0)
1.9 db 83: return (FALSE);
1.1 deraadt 84: while (n--) {
85: while (inword() == FALSE) {
86: if (forwchar(FFRAND, 1) == FALSE)
1.9 db 87: return (TRUE);
1.1 deraadt 88: }
1.11 kjell 89: size = countfword();
90: undo_add_change(curwp->w_dotp, curwp->w_doto, size);
1.12 deraadt 91:
1.1 deraadt 92: while (inword() != FALSE) {
93: c = lgetc(curwp->w_dotp, curwp->w_doto);
94: if (ISLOWER(c) != FALSE) {
95: c = TOUPPER(c);
96: lputc(curwp->w_dotp, curwp->w_doto, c);
1.14 kjell 97: lchange(WFFULL);
1.1 deraadt 98: }
99: if (forwchar(FFRAND, 1) == FALSE)
1.9 db 100: return (TRUE);
1.1 deraadt 101: }
102: }
1.9 db 103: return (TRUE);
1.1 deraadt 104: }
105:
106: /*
1.3 millert 107: * Move the cursor forward by the specified number of words. As you move
1.1 deraadt 108: * convert characters to lower case.
109: */
1.2 millert 110: /* ARGSUSED */
1.3 millert 111: int
1.8 cloder 112: lowerword(int f, int n)
1.1 deraadt 113: {
1.15 kjell 114: int c, s;
1.11 kjell 115: RSIZE size;
1.1 deraadt 116:
1.15 kjell 117: if ((s = checkdirty(curbp)) != TRUE)
118: return (s);
1.7 vincent 119: if (curbp->b_flag & BFREADONLY) {
1.16 ! lum 120: dobeep();
1.7 vincent 121: ewprintf("Buffer is read-only");
122: return (FALSE);
123: }
1.2 millert 124: if (n < 0)
1.9 db 125: return (FALSE);
1.1 deraadt 126: while (n--) {
127: while (inword() == FALSE) {
128: if (forwchar(FFRAND, 1) == FALSE)
1.9 db 129: return (TRUE);
1.1 deraadt 130: }
1.11 kjell 131: size = countfword();
132: undo_add_change(curwp->w_dotp, curwp->w_doto, size);
133:
1.1 deraadt 134: while (inword() != FALSE) {
135: c = lgetc(curwp->w_dotp, curwp->w_doto);
136: if (ISUPPER(c) != FALSE) {
137: c = TOLOWER(c);
138: lputc(curwp->w_dotp, curwp->w_doto, c);
1.14 kjell 139: lchange(WFFULL);
1.1 deraadt 140: }
141: if (forwchar(FFRAND, 1) == FALSE)
1.9 db 142: return (TRUE);
1.1 deraadt 143: }
144: }
1.9 db 145: return (TRUE);
1.1 deraadt 146: }
147:
148: /*
1.3 millert 149: * Move the cursor forward by the specified number of words. As you move
1.5 mickey 150: * convert the first character of the word to upper case, and subsequent
151: * characters to lower case. Error if you try to move past the end of the
1.3 millert 152: * buffer.
1.1 deraadt 153: */
1.2 millert 154: /* ARGSUSED */
1.3 millert 155: int
1.8 cloder 156: capword(int f, int n)
1.1 deraadt 157: {
1.15 kjell 158: int c, s;
1.11 kjell 159: RSIZE size;
1.1 deraadt 160:
1.15 kjell 161: if ((s = checkdirty(curbp)) != TRUE)
162: return (s);
1.7 vincent 163: if (curbp->b_flag & BFREADONLY) {
1.16 ! lum 164: dobeep();
1.7 vincent 165: ewprintf("Buffer is read-only");
166: return (FALSE);
167: }
168:
1.2 millert 169: if (n < 0)
1.9 db 170: return (FALSE);
1.1 deraadt 171: while (n--) {
172: while (inword() == FALSE) {
173: if (forwchar(FFRAND, 1) == FALSE)
1.9 db 174: return (TRUE);
1.1 deraadt 175: }
1.11 kjell 176: size = countfword();
177: undo_add_change(curwp->w_dotp, curwp->w_doto, size);
178:
1.1 deraadt 179: if (inword() != FALSE) {
180: c = lgetc(curwp->w_dotp, curwp->w_doto);
181: if (ISLOWER(c) != FALSE) {
182: c = TOUPPER(c);
183: lputc(curwp->w_dotp, curwp->w_doto, c);
1.14 kjell 184: lchange(WFFULL);
1.1 deraadt 185: }
186: if (forwchar(FFRAND, 1) == FALSE)
1.9 db 187: return (TRUE);
1.1 deraadt 188: while (inword() != FALSE) {
189: c = lgetc(curwp->w_dotp, curwp->w_doto);
190: if (ISUPPER(c) != FALSE) {
191: c = TOLOWER(c);
192: lputc(curwp->w_dotp, curwp->w_doto, c);
1.14 kjell 193: lchange(WFFULL);
1.1 deraadt 194: }
195: if (forwchar(FFRAND, 1) == FALSE)
1.9 db 196: return (TRUE);
1.1 deraadt 197: }
198: }
199: }
1.9 db 200: return (TRUE);
1.1 deraadt 201: }
1.11 kjell 202:
203: /*
204: * Count characters in word, from current position
205: */
206: RSIZE
207: countfword()
208: {
1.13 deraadt 209: RSIZE size;
210: struct line *dotp;
211: int doto;
1.11 kjell 212:
213: dotp = curwp->w_dotp;
214: doto = curwp->w_doto;
215: size = 0;
216:
217: while (inword() != FALSE) {
218: if (forwchar(FFRAND, 1) == FALSE)
219: /* hit the end of the buffer */
220: goto out;
221: ++size;
222: }
223: out:
224: curwp->w_dotp = dotp;
225: curwp->w_doto = doto;
226: return (size);
227: }
228:
1.1 deraadt 229:
230: /*
231: * Kill forward by "n" words.
232: */
1.2 millert 233: /* ARGSUSED */
1.3 millert 234: int
1.8 cloder 235: delfword(int f, int n)
1.1 deraadt 236: {
1.13 deraadt 237: RSIZE size;
238: struct line *dotp;
239: int doto;
1.15 kjell 240: int s;
1.1 deraadt 241:
1.15 kjell 242: if ((s = checkdirty(curbp)) != TRUE)
243: return (s);
1.7 vincent 244: if (curbp->b_flag & BFREADONLY) {
1.16 ! lum 245: dobeep();
1.7 vincent 246: ewprintf("Buffer is read-only");
247: return (FALSE);
248: }
1.1 deraadt 249: if (n < 0)
1.9 db 250: return (FALSE);
1.3 millert 251:
252: /* purge kill buffer */
253: if ((lastflag & CFKILL) == 0)
1.1 deraadt 254: kdelete();
1.3 millert 255:
1.1 deraadt 256: thisflag |= CFKILL;
257: dotp = curwp->w_dotp;
258: doto = curwp->w_doto;
259: size = 0;
1.3 millert 260:
1.1 deraadt 261: while (n--) {
262: while (inword() == FALSE) {
263: if (forwchar(FFRAND, 1) == FALSE)
1.3 millert 264: /* hit the end of the buffer */
265: goto out;
1.1 deraadt 266: ++size;
267: }
268: while (inword() != FALSE) {
269: if (forwchar(FFRAND, 1) == FALSE)
1.3 millert 270: /* hit the end of the buffer */
271: goto out;
1.1 deraadt 272: ++size;
273: }
274: }
275: out:
276: curwp->w_dotp = dotp;
277: curwp->w_doto = doto;
278: return (ldelete(size, KFORW));
279: }
280:
281: /*
1.5 mickey 282: * Kill backwards by "n" words. The rules for success and failure are now
283: * different, to prevent strange behavior at the start of the buffer. The
284: * command only fails if something goes wrong with the actual delete of the
285: * characters. It is successful even if no characters are deleted, or if you
286: * say delete 5 words, and there are only 4 words left. I considered making
287: * the first call to "backchar" special, but decided that that would just be
1.3 millert 288: * weird. Normally this is bound to "M-Rubout" and to "M-Backspace".
1.1 deraadt 289: */
1.2 millert 290: /* ARGSUSED */
1.3 millert 291: int
1.8 cloder 292: delbword(int f, int n)
1.1 deraadt 293: {
1.3 millert 294: RSIZE size;
1.15 kjell 295: int s;
1.7 vincent 296:
1.15 kjell 297: if ((s = checkdirty(curbp)) != TRUE)
298: return (s);
1.7 vincent 299: if (curbp->b_flag & BFREADONLY) {
1.16 ! lum 300: dobeep();
1.7 vincent 301: ewprintf("Buffer is read-only");
302: return (FALSE);
303: }
1.1 deraadt 304:
1.2 millert 305: if (n < 0)
1.9 db 306: return (FALSE);
1.3 millert 307:
308: /* purge kill buffer */
309: if ((lastflag & CFKILL) == 0)
1.1 deraadt 310: kdelete();
311: thisflag |= CFKILL;
312: if (backchar(FFRAND, 1) == FALSE)
1.3 millert 313: /* hit buffer start */
314: return (TRUE);
315:
316: /* one deleted */
317: size = 1;
1.1 deraadt 318: while (n--) {
319: while (inword() == FALSE) {
320: if (backchar(FFRAND, 1) == FALSE)
1.3 millert 321: /* hit buffer start */
322: goto out;
1.1 deraadt 323: ++size;
324: }
325: while (inword() != FALSE) {
326: if (backchar(FFRAND, 1) == FALSE)
1.3 millert 327: /* hit buffer start */
328: goto out;
1.1 deraadt 329: ++size;
330: }
331: }
332: if (forwchar(FFRAND, 1) == FALSE)
1.9 db 333: return (FALSE);
1.3 millert 334:
335: /* undo assumed delete */
336: --size;
1.1 deraadt 337: out:
1.9 db 338: return (ldelete(size, KBACK));
1.1 deraadt 339: }
340:
341: /*
1.3 millert 342: * Return TRUE if the character at dot is a character that is considered to be
1.9 db 343: * part of a word. The word character list is hard coded. Should be settable.
1.1 deraadt 344: */
1.3 millert 345: int
1.8 cloder 346: inword(void)
1.2 millert 347: {
348: /* can't use lgetc in ISWORD due to bug in OSK cpp */
1.9 db 349: return (curwp->w_doto != llength(curwp->w_dotp) &&
350: ISWORD(curwp->w_dotp->l_text[curwp->w_doto]));
1.1 deraadt 351: }