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