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