995
|
1 /*
|
|
2 * This file contains the command processing functions for a number of random
|
|
3 * commands. There is no functional grouping here, for sure.
|
|
4 */
|
|
5
|
|
6 #include <stdio.h>
|
|
7 #include "ueed.h"
|
|
8
|
|
9 int tabsize; /* Tab size (0: use real tabs) */
|
|
10
|
|
11 /*
|
|
12 * Set fill column to n.
|
|
13 */
|
|
14 setfillcol(f, n)
|
|
15 {
|
|
16 fillcol = n;
|
|
17 return(TRUE);
|
|
18 }
|
|
19
|
|
20 /*
|
|
21 * Display the current position of the cursor, in origin 1 X-Y coordinates,
|
|
22 * the character that is under the cursor (in hex), and the fraction of the
|
|
23 * text that is before the cursor. The displayed column is not the current
|
|
24 * column, but the column that would be used on an infinite width display.
|
|
25 * Normally this is bound to "C-X =".
|
|
26 */
|
|
27 showcpos(f, n)
|
|
28 {
|
|
29 register LINE *clp;
|
|
30 register long nch;
|
|
31 register long nbc;
|
|
32 register int cac;
|
|
33 register int ratio;
|
|
34 register int col;
|
|
35 register int i;
|
|
36 register int c;
|
|
37 register int nl;
|
|
38 register int cl;
|
|
39 #ifdef OSK
|
|
40 char mline[80];
|
|
41 #endif
|
|
42
|
|
43 clp = lforw(curbp->b_linep); /* Grovel the data. */
|
|
44 nch = 0;
|
|
45 nl = 0;
|
|
46 while (clp != curbp->b_linep) {
|
|
47 if (clp == curwp->w_dotp) {
|
|
48 nbc = nch + curwp->w_doto;
|
|
49 cac = (curwp->w_doto < llength(clp))
|
|
50 ? lgetc(clp, curwp->w_doto)
|
|
51 : '\n';
|
|
52 cl = nl;
|
|
53 }
|
|
54 nch += llength(clp)+1;
|
|
55
|
|
56 clp = lforw(clp);
|
|
57 nl++;
|
|
58 }
|
|
59 if (clp == curwp->w_dotp) { /* special case for end of buffer */
|
|
60 nbc = nch;
|
|
61 cac = '\n';
|
|
62 cl = nl;
|
|
63 }
|
|
64 col = getccol(FALSE); /* Get real column. */
|
|
65 ratio = 0; /* Ratio before dot. */
|
|
66 if (nch != 0)
|
|
67 ratio = (100L*nbc) / nch;
|
|
68 #ifdef OSK
|
|
69 /* osk objects to this varargs technique with more than 2 arguments */
|
|
70 /* while I was changing things I made it display more info */
|
|
71 sprintf(mline,
|
|
72 "X=%d Y=%d CH=0x%02X (%s%c) Line %d of %d; Char %ld of %ld (%d%%%%)",
|
|
73 col+1, currow+1, cac, (cac<' ')?"^":"", (cac<' ')?cac+'@':cac,
|
|
74 cl, nl, nbc, nch, ratio);
|
|
75 mlwrite(mline);
|
|
76 #else
|
|
77 /* note nl (number of lines) and cl (current line) arn't yet displayed */
|
|
78 mlwrite("X=%d Y=%d CH=0x%x .=%D (%d%% of %D)",
|
|
79 col+1, currow+1, cac, nbc, ratio, nch);
|
|
80 #endif
|
|
81 return (TRUE);
|
|
82 }
|
|
83
|
|
84 /*
|
|
85 * Return current column. Stop at first non-blank given TRUE argument.
|
|
86 */
|
|
87 getccol(bflg)
|
|
88 int bflg;
|
|
89 {
|
|
90 register int c, i, col;
|
|
91 col = 0;
|
|
92 for (i=0; i<curwp->w_doto; ++i) {
|
|
93 c = lgetc(curwp->w_dotp, i);
|
|
94 if (c!=' ' && c!='\t' && bflg)
|
|
95 break;
|
|
96 if (c == '\t')
|
|
97 col |= 0x07;
|
|
98 else if (c<0x20 || c==0x7F)
|
|
99 ++col;
|
|
100 ++col;
|
|
101 }
|
|
102 return(col);
|
|
103 }
|
|
104
|
|
105 /*
|
|
106 * Twiddle the two characters on either side of dot. If dot is at the end of
|
|
107 * the line twiddle the two characters before it. Return with an error if dot
|
|
108 * is at the beginning of line; it seems to be a bit pointless to make this
|
|
109 * work. This fixes up a very common typo with a single stroke. Normally bound
|
|
110 * to "C-T". This always works within a line, so "WFEDIT" is good enough.
|
|
111 */
|
|
112 twiddle(f, n)
|
|
113 {
|
|
114 register LINE *dotp;
|
|
115 register int doto;
|
|
116 register int cl;
|
|
117 register int cr;
|
|
118
|
|
119 dotp = curwp->w_dotp;
|
|
120 doto = curwp->w_doto;
|
|
121 if (doto==llength(dotp) && --doto<0)
|
|
122 return (FALSE);
|
|
123 cr = lgetc(dotp, doto);
|
|
124 if (--doto < 0)
|
|
125 return (FALSE);
|
|
126 cl = lgetc(dotp, doto);
|
|
127 lputc(dotp, doto+0, cr);
|
|
128 lputc(dotp, doto+1, cl);
|
|
129 lchange(WFEDIT);
|
|
130 return (TRUE);
|
|
131 }
|
|
132
|
|
133 /*
|
|
134 * Quote the next character, and insert it into the buffer. All the characters
|
|
135 * are taken literally, with the exception of the newline, which always has
|
|
136 * its line splitting meaning. The character is always read, even if it is
|
|
137 * inserted 0 times, for regularity. Bound to "M-Q" (for me) and "C-Q" (for
|
|
138 * Rich, and only on terminals that don't need XON-XOFF).
|
|
139 */
|
|
140 quote(f, n)
|
|
141 {
|
|
142 register int s;
|
|
143 register int c;
|
|
144
|
|
145 c = (*term.t_getchar)();
|
|
146 if (n < 0)
|
|
147 return (FALSE);
|
|
148 if (n == 0)
|
|
149 return (TRUE);
|
|
150 if (c == '\n') {
|
|
151 do {
|
|
152 s = lnewline();
|
|
153 } while (s==TRUE && --n);
|
|
154 return (s);
|
|
155 }
|
|
156 return (linsert(n, c));
|
|
157 }
|
|
158
|
|
159 /*
|
|
160 * Set tab size if given non-default argument (n <> 1). Otherwise, insert a
|
|
161 * tab into file. If given argument, n, of zero, change to true tabs.
|
|
162 * If n > 1, simulate tab stop every n-characters using spaces. This has to be
|
|
163 * done in this slightly funny way because the tab (in ASCII) has been turned
|
|
164 * into "C-I" (in 10 bit code) already. Bound to "C-I".
|
|
165 */
|
|
166 tab(f, n)
|
|
167 {
|
|
168 if (n < 0)
|
|
169 return (FALSE);
|
|
170 if (n == 0 || n > 1) {
|
|
171 tabsize = n;
|
|
172 return(TRUE);
|
|
173 }
|
|
174 if (! tabsize)
|
|
175 return(linsert(1, '\t'));
|
|
176 return(linsert(tabsize - (getccol(FALSE) % tabsize), ' '));
|
|
177 }
|
|
178
|
|
179 /*
|
|
180 * Open up some blank space. The basic plan is to insert a bunch of newlines,
|
|
181 * and then back up over them. Everything is done by the subcommand
|
|
182 * procerssors. They even handle the looping. Normally this is bound to "C-O".
|
|
183 */
|
|
184 openline(f, n)
|
|
185 {
|
|
186 register int i;
|
|
187 register int s;
|
|
188
|
|
189 if (n < 0)
|
|
190 return (FALSE);
|
|
191 if (n == 0)
|
|
192 return (TRUE);
|
|
193 i = n; /* Insert newlines. */
|
|
194 do {
|
|
195 s = lnewline();
|
|
196 } while (s==TRUE && --i);
|
|
197 if (s == TRUE) /* Then back up overtop */
|
|
198 s = backchar(f, n); /* of them all. */
|
|
199 return (s);
|
|
200 }
|
|
201
|
|
202 /*
|
|
203 * Insert a newline. Bound to "C-M". If you are at the end of the line and the
|
|
204 * next line is a blank line, just move into the blank line. This makes "C-O"
|
|
205 * and "C-X C-O" work nicely, and reduces the ammount of screen update that
|
|
206 * has to be done. This would not be as critical if screen update were a lot
|
|
207 * more efficient.
|
|
208 */
|
|
209 newline(f, n)
|
|
210 {
|
|
211 int nicol;
|
|
212 register LINE *lp;
|
|
213 register int s;
|
|
214
|
|
215 if (n < 0)
|
|
216
|
|
217 return (FALSE);
|
|
218 while (n--) {
|
|
219 lp = curwp->w_dotp;
|
|
220 if (llength(lp) == curwp->w_doto
|
|
221 && lp != curbp->b_linep
|
|
222 && llength(lforw(lp)) == 0) {
|
|
223 if ((s=forwchar(FALSE, 1)) != TRUE)
|
|
224 return (s);
|
|
225 } else if ((s=lnewline()) != TRUE)
|
|
226 return (s);
|
|
227 }
|
|
228 return (TRUE);
|
|
229 }
|
|
230
|
|
231 /*
|
|
232 * Delete blank lines around dot. What this command does depends if dot is
|
|
233 * sitting on a blank line. If dot is sitting on a blank line, this command
|
|
234 * deletes all the blank lines above and below the current line. If it is
|
|
235 * sitting on a non blank line then it deletes all of the blank lines after
|
|
236 * the line. Normally this command is bound to "C-X C-O". Any argument is
|
|
237 * ignored.
|
|
238 */
|
|
239 deblank(f, n)
|
|
240 {
|
|
241 register LINE *lp1;
|
|
242 register LINE *lp2;
|
|
243 register int nld;
|
|
244
|
|
245 lp1 = curwp->w_dotp;
|
|
246 while (llength(lp1)==0 && (lp2=lback(lp1))!=curbp->b_linep)
|
|
247 lp1 = lp2;
|
|
248 lp2 = lp1;
|
|
249 nld = 0;
|
|
250 while ((lp2=lforw(lp2))!=curbp->b_linep && llength(lp2)==0)
|
|
251 ++nld;
|
|
252 if (nld == 0)
|
|
253 return (TRUE);
|
|
254 curwp->w_dotp = lforw(lp1);
|
|
255 curwp->w_doto = 0;
|
|
256 return (ldelete(nld));
|
|
257 }
|
|
258
|
|
259
|