1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin * *
3da2e3ebdSchin * This software is part of the ast package *
4*3e14f97fSRoger A. Faulkner * Copyright (c) 1982-2010 AT&T Intellectual Property *
5da2e3ebdSchin * and is licensed under the *
6da2e3ebdSchin * Common Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
8da2e3ebdSchin * *
9da2e3ebdSchin * A copy of the License is available at *
10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt *
11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12da2e3ebdSchin * *
13da2e3ebdSchin * Information and Software Systems Research *
14da2e3ebdSchin * AT&T Research *
15da2e3ebdSchin * Florham Park NJ *
16da2e3ebdSchin * *
17da2e3ebdSchin * David Korn <dgk@research.att.com> *
18da2e3ebdSchin * *
19da2e3ebdSchin ***********************************************************************/
20da2e3ebdSchin #pragma prototyped
21da2e3ebdSchin /* Original version by Michael T. Veach
22da2e3ebdSchin * Adapted for ksh by David Korn */
23da2e3ebdSchin /* EMACS_MODES: c tabstop=4
24da2e3ebdSchin
25da2e3ebdSchin One line screen editor for any program
26da2e3ebdSchin
27da2e3ebdSchin */
28da2e3ebdSchin
29da2e3ebdSchin
30da2e3ebdSchin /* The following is provided by:
31da2e3ebdSchin *
32da2e3ebdSchin * Matthijs N. Melchior
33da2e3ebdSchin * AT&T Network Systems International
34da2e3ebdSchin * APT Nederland
35da2e3ebdSchin * HV BZ335 x2962
36da2e3ebdSchin * hvlpb!mmelchio
37da2e3ebdSchin *
38da2e3ebdSchin * These are now on by default
39da2e3ebdSchin *
40da2e3ebdSchin * ESH_NFIRST
41da2e3ebdSchin * - A ^N as first history related command after the prompt will move
42da2e3ebdSchin * to the next command relative to the last known history position.
43da2e3ebdSchin * It will not start at the position where the last command was entered
44da2e3ebdSchin * as is done by the ^P command. Every history related command will
45da2e3ebdSchin * set both the current and last position. Executing a command will
46da2e3ebdSchin * only set the current position.
47da2e3ebdSchin *
48da2e3ebdSchin * ESH_KAPPEND
49da2e3ebdSchin * - Successive kill and delete commands will accumulate their data
50da2e3ebdSchin * in the kill buffer, by appending or prepending as appropriate.
51da2e3ebdSchin * This mode will be reset by any command not adding something to the
52da2e3ebdSchin * kill buffer.
53da2e3ebdSchin *
54da2e3ebdSchin * ESH_BETTER
55da2e3ebdSchin * - Some enhancements:
56da2e3ebdSchin * - argument for a macro is passed to its replacement
57da2e3ebdSchin * - ^X^H command to find out about history position (debugging)
58da2e3ebdSchin * - ^X^D command to show any debugging info
59da2e3ebdSchin *
60da2e3ebdSchin * I do not pretend these for changes are completely independent,
61da2e3ebdSchin * but you can use them to seperate features.
62da2e3ebdSchin */
63da2e3ebdSchin
64da2e3ebdSchin #include <ast.h>
65da2e3ebdSchin #include "FEATURE/cmds"
66da2e3ebdSchin #if KSHELL
67da2e3ebdSchin # include "defs.h"
6834f9b3eeSRoland Mainz #else
6934f9b3eeSRoland Mainz # include <ctype.h>
70da2e3ebdSchin #endif /* KSHELL */
71da2e3ebdSchin #include "io.h"
72da2e3ebdSchin
73da2e3ebdSchin #include "history.h"
74da2e3ebdSchin #include "edit.h"
75da2e3ebdSchin #include "terminal.h"
76da2e3ebdSchin
77da2e3ebdSchin #define ESH_NFIRST
78da2e3ebdSchin #define ESH_KAPPEND
79da2e3ebdSchin #define ESH_BETTER
80da2e3ebdSchin
81da2e3ebdSchin #undef putchar
82da2e3ebdSchin #define putchar(ed,c) ed_putchar(ed,c)
83da2e3ebdSchin #define beep() ed_ringbell()
84da2e3ebdSchin
85da2e3ebdSchin
86da2e3ebdSchin #if SHOPT_MULTIBYTE
87da2e3ebdSchin # define gencpy(a,b) ed_gencpy(a,b)
88da2e3ebdSchin # define genncpy(a,b,n) ed_genncpy(a,b,n)
89da2e3ebdSchin # define genlen(str) ed_genlen(str)
90da2e3ebdSchin static int print(int);
91da2e3ebdSchin static int _isword(int);
92da2e3ebdSchin # define isword(c) _isword(out[c])
93da2e3ebdSchin
94da2e3ebdSchin #else
95da2e3ebdSchin # define gencpy(a,b) strcpy((char*)(a),(char*)(b))
96da2e3ebdSchin # define genncpy(a,b,n) strncpy((char*)(a),(char*)(b),n)
97da2e3ebdSchin # define genlen(str) strlen(str)
98da2e3ebdSchin # define print(c) isprint(c)
99da2e3ebdSchin # define isword(c) (isalnum(out[c]) || (out[c]=='_'))
100da2e3ebdSchin #endif /*SHOPT_MULTIBYTE */
101da2e3ebdSchin
102da2e3ebdSchin typedef struct _emacs_
103da2e3ebdSchin {
104da2e3ebdSchin genchar *screen; /* pointer to window buffer */
105da2e3ebdSchin genchar *cursor; /* Cursor in real screen */
106da2e3ebdSchin int mark;
107da2e3ebdSchin int in_mult;
108da2e3ebdSchin char cr_ok;
109da2e3ebdSchin char CntrlO;
110da2e3ebdSchin char overflow; /* Screen overflow flag set */
111da2e3ebdSchin char scvalid; /* Screen is up to date */
1127c2fbfb3SApril Chin char lastdraw; /* last update type */
113da2e3ebdSchin int offset; /* Screen offset */
114da2e3ebdSchin enum
115da2e3ebdSchin {
116da2e3ebdSchin CRT=0, /* Crt terminal */
117da2e3ebdSchin PAPER /* Paper terminal */
118da2e3ebdSchin } terminal;
119da2e3ebdSchin Histloc_t _location;
120da2e3ebdSchin int prevdirection;
121da2e3ebdSchin Edit_t *ed; /* pointer to edit data */
122da2e3ebdSchin } Emacs_t;
123da2e3ebdSchin
124da2e3ebdSchin #define editb (*ep->ed)
125da2e3ebdSchin #define eol editb.e_eol
126da2e3ebdSchin #define cur editb.e_cur
127da2e3ebdSchin #define hline editb.e_hline
128da2e3ebdSchin #define hloff editb.e_hloff
129da2e3ebdSchin #define hismin editb.e_hismin
130da2e3ebdSchin #define usrkill editb.e_kill
131da2e3ebdSchin #define usrlnext editb.e_lnext
132da2e3ebdSchin #define usreof editb.e_eof
133da2e3ebdSchin #define usrerase editb.e_erase
134da2e3ebdSchin #define crallowed editb.e_crlf
135da2e3ebdSchin #define Prompt editb.e_prompt
136da2e3ebdSchin #define plen editb.e_plen
137da2e3ebdSchin #define kstack editb.e_killbuf
138da2e3ebdSchin #define lstring editb.e_search
139da2e3ebdSchin #define lookahead editb.e_lookahead
140da2e3ebdSchin #define env editb.e_env
141da2e3ebdSchin #define raw editb.e_raw
142da2e3ebdSchin #define histlines editb.e_hismax
143da2e3ebdSchin #define w_size editb.e_wsize
144da2e3ebdSchin #define drawbuff editb.e_inbuf
145da2e3ebdSchin #define killing editb.e_mode
146da2e3ebdSchin #define location ep->_location
147da2e3ebdSchin
148da2e3ebdSchin #define LBUF 100
149da2e3ebdSchin #define KILLCHAR UKILL
150da2e3ebdSchin #define ERASECHAR UERASE
151da2e3ebdSchin #define EOFCHAR UEOF
152da2e3ebdSchin #define LNEXTCHAR ULNEXT
153da2e3ebdSchin #define DELETE ('a'==97?0177:7)
154da2e3ebdSchin
155da2e3ebdSchin /**********************
156da2e3ebdSchin A large lookahead helps when the user is inserting
157da2e3ebdSchin characters in the middle of the line.
158da2e3ebdSchin ************************/
159da2e3ebdSchin
160da2e3ebdSchin
161da2e3ebdSchin typedef enum
162da2e3ebdSchin {
163da2e3ebdSchin FIRST, /* First time thru for logical line, prompt on screen */
164da2e3ebdSchin REFRESH, /* Redraw entire screen */
165da2e3ebdSchin APPEND, /* Append char before cursor to screen */
166da2e3ebdSchin UPDATE, /* Update the screen as need be */
167da2e3ebdSchin FINAL /* Update screen even if pending look ahead */
168da2e3ebdSchin } Draw_t;
169da2e3ebdSchin
170da2e3ebdSchin static void draw(Emacs_t*,Draw_t);
171da2e3ebdSchin static int escape(Emacs_t*,genchar*, int);
172da2e3ebdSchin static void putstring(Emacs_t*,char*);
173da2e3ebdSchin static void search(Emacs_t*,genchar*,int);
174da2e3ebdSchin static void setcursor(Emacs_t*,int, int);
175da2e3ebdSchin static void show_info(Emacs_t*,const char*);
176da2e3ebdSchin static void xcommands(Emacs_t*,int);
177da2e3ebdSchin
ed_emacsread(void * context,int fd,char * buff,int scend,int reedit)178da2e3ebdSchin int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
179da2e3ebdSchin {
180da2e3ebdSchin Edit_t *ed = (Edit_t*)context;
181da2e3ebdSchin register int c;
182da2e3ebdSchin register int i;
183da2e3ebdSchin register genchar *out;
184da2e3ebdSchin register int count;
185da2e3ebdSchin register Emacs_t *ep = ed->e_emacs;
186da2e3ebdSchin int adjust,oadjust;
187da2e3ebdSchin char backslash;
188da2e3ebdSchin genchar *kptr;
189da2e3ebdSchin char prompt[PRSIZE];
190da2e3ebdSchin genchar Screen[MAXLINE];
191da2e3ebdSchin if(!ep)
192da2e3ebdSchin {
193da2e3ebdSchin ep = ed->e_emacs = newof(0,Emacs_t,1,0);
194da2e3ebdSchin ep->ed = ed;
195da2e3ebdSchin ep->prevdirection = 1;
196da2e3ebdSchin location.hist_command = -5;
197da2e3ebdSchin }
198da2e3ebdSchin Prompt = prompt;
199da2e3ebdSchin ep->screen = Screen;
2007c2fbfb3SApril Chin ep->lastdraw = FINAL;
201da2e3ebdSchin if(tty_raw(ERRIO,0) < 0)
202da2e3ebdSchin {
203da2e3ebdSchin return(reedit?reedit:ed_read(context, fd,buff,scend,0));
204da2e3ebdSchin }
205da2e3ebdSchin raw = 1;
206da2e3ebdSchin /* This mess in case the read system call fails */
207da2e3ebdSchin
208da2e3ebdSchin ed_setup(ep->ed,fd,reedit);
209da2e3ebdSchin out = (genchar*)buff;
210da2e3ebdSchin #if SHOPT_MULTIBYTE
21134f9b3eeSRoland Mainz out = (genchar*)roundof(buff-(char*)0,sizeof(genchar));
21234f9b3eeSRoland Mainz if(reedit)
21334f9b3eeSRoland Mainz ed_internal(buff,out);
214da2e3ebdSchin #endif /* SHOPT_MULTIBYTE */
215da2e3ebdSchin if(!kstack)
216da2e3ebdSchin {
217da2e3ebdSchin kstack = (genchar*)malloc(CHARSIZE*MAXLINE);
218da2e3ebdSchin kstack[0] = '\0';
219da2e3ebdSchin }
220da2e3ebdSchin drawbuff = out;
221da2e3ebdSchin #ifdef ESH_NFIRST
222da2e3ebdSchin if (location.hist_command == -5) /* to be initialized */
223da2e3ebdSchin {
224da2e3ebdSchin kstack[0] = '\0'; /* also clear kstack... */
225da2e3ebdSchin location.hist_command = hline;
226da2e3ebdSchin location.hist_line = hloff;
227da2e3ebdSchin }
228da2e3ebdSchin if (location.hist_command <= hismin) /* don't start below minimum */
229da2e3ebdSchin {
230da2e3ebdSchin location.hist_command = hismin + 1;
231da2e3ebdSchin location.hist_line = 0;
232da2e3ebdSchin }
233da2e3ebdSchin ep->in_mult = hloff; /* save pos in last command */
234da2e3ebdSchin #endif /* ESH_NFIRST */
235da2e3ebdSchin i = sigsetjmp(env,0);
236da2e3ebdSchin if (i !=0)
237da2e3ebdSchin {
2387c2fbfb3SApril Chin if(ep->ed->e_multiline)
2397c2fbfb3SApril Chin {
2407c2fbfb3SApril Chin cur = eol;
2417c2fbfb3SApril Chin draw(ep,FINAL);
2427c2fbfb3SApril Chin ed_flush(ep->ed);
2437c2fbfb3SApril Chin }
244da2e3ebdSchin tty_cooked(ERRIO);
245da2e3ebdSchin if (i == UEOF)
246da2e3ebdSchin {
247da2e3ebdSchin return(0); /* EOF */
248da2e3ebdSchin }
249da2e3ebdSchin return(-1); /* some other error */
250da2e3ebdSchin }
251da2e3ebdSchin out[reedit] = 0;
252da2e3ebdSchin if(scend+plen > (MAXLINE-2))
253da2e3ebdSchin scend = (MAXLINE-2)-plen;
254da2e3ebdSchin ep->mark = 0;
255da2e3ebdSchin cur = eol;
256da2e3ebdSchin draw(ep,reedit?REFRESH:FIRST);
257da2e3ebdSchin adjust = -1;
258da2e3ebdSchin backslash = 0;
259da2e3ebdSchin if (ep->CntrlO)
260da2e3ebdSchin {
261da2e3ebdSchin #ifdef ESH_NFIRST
262da2e3ebdSchin ed_ungetchar(ep->ed,cntl('N'));
263da2e3ebdSchin #else
264da2e3ebdSchin location = hist_locate(sh.hist_ptr,location.hist_command,location.hist_line,1);
265da2e3ebdSchin if (location.hist_command < histlines)
266da2e3ebdSchin {
267da2e3ebdSchin hline = location.hist_command;
268da2e3ebdSchin hloff = location.hist_line;
269da2e3ebdSchin hist_copy((char*)kstack,MAXLINE, hline,hloff);
270da2e3ebdSchin # if SHOPT_MULTIBYTE
271da2e3ebdSchin ed_internal((char*)kstack,kstack);
272da2e3ebdSchin # endif /* SHOPT_MULTIBYTE */
273da2e3ebdSchin ed_ungetchar(ep->ed,cntl('Y'));
274da2e3ebdSchin }
275da2e3ebdSchin #endif /* ESH_NFIRST */
276da2e3ebdSchin }
277da2e3ebdSchin ep->CntrlO = 0;
278da2e3ebdSchin while ((c = ed_getchar(ep->ed,0)) != (-1))
279da2e3ebdSchin {
280da2e3ebdSchin if (backslash)
281da2e3ebdSchin {
282da2e3ebdSchin backslash = 0;
283da2e3ebdSchin if (c==usrerase||c==usrkill||(!print(c) &&
284da2e3ebdSchin (c!='\r'&&c!='\n')))
285da2e3ebdSchin {
286da2e3ebdSchin /* accept a backslashed character */
287da2e3ebdSchin cur--;
288da2e3ebdSchin out[cur++] = c;
289da2e3ebdSchin out[eol] = '\0';
290da2e3ebdSchin draw(ep,APPEND);
291da2e3ebdSchin continue;
292da2e3ebdSchin }
293da2e3ebdSchin }
294da2e3ebdSchin if (c == usrkill)
295da2e3ebdSchin {
296da2e3ebdSchin c = KILLCHAR ;
297da2e3ebdSchin }
298da2e3ebdSchin else if (c == usrerase)
299da2e3ebdSchin {
300da2e3ebdSchin c = ERASECHAR ;
301da2e3ebdSchin }
302da2e3ebdSchin else if (c == usrlnext)
303da2e3ebdSchin {
304da2e3ebdSchin c = LNEXTCHAR ;
305da2e3ebdSchin }
306da2e3ebdSchin else if ((c == usreof)&&(eol == 0))
307da2e3ebdSchin {
308da2e3ebdSchin c = EOFCHAR;
309da2e3ebdSchin }
310da2e3ebdSchin #ifdef ESH_KAPPEND
311da2e3ebdSchin if (--killing <= 0) /* reset killing flag */
312da2e3ebdSchin killing = 0;
313da2e3ebdSchin #endif
314da2e3ebdSchin oadjust = count = adjust;
315da2e3ebdSchin if(count<0)
316da2e3ebdSchin count = 1;
317da2e3ebdSchin adjust = -1;
318da2e3ebdSchin i = cur;
319da2e3ebdSchin switch(c)
320da2e3ebdSchin {
321da2e3ebdSchin case LNEXTCHAR:
322da2e3ebdSchin c = ed_getchar(ep->ed,2);
323da2e3ebdSchin goto do_default_processing;
324da2e3ebdSchin case cntl('V'):
325da2e3ebdSchin show_info(ep,fmtident(e_version));
326da2e3ebdSchin continue;
327da2e3ebdSchin case '\0':
328da2e3ebdSchin ep->mark = i;
329da2e3ebdSchin continue;
330da2e3ebdSchin case cntl('X'):
331da2e3ebdSchin xcommands(ep,count);
332da2e3ebdSchin continue;
333da2e3ebdSchin case EOFCHAR:
334da2e3ebdSchin ed_flush(ep->ed);
335da2e3ebdSchin tty_cooked(ERRIO);
336da2e3ebdSchin return(0);
337da2e3ebdSchin #ifdef u370
338da2e3ebdSchin case cntl('S') :
339da2e3ebdSchin case cntl('Q') :
340da2e3ebdSchin continue;
341da2e3ebdSchin #endif /* u370 */
342da2e3ebdSchin case '\t':
343da2e3ebdSchin if(cur>0 && ep->ed->sh->nextprompt)
344da2e3ebdSchin {
345da2e3ebdSchin if(ep->ed->e_tabcount==0)
346da2e3ebdSchin {
347da2e3ebdSchin ep->ed->e_tabcount=1;
348da2e3ebdSchin ed_ungetchar(ep->ed,ESC);
349da2e3ebdSchin goto do_escape;
350da2e3ebdSchin }
351da2e3ebdSchin else if(ep->ed->e_tabcount==1)
352da2e3ebdSchin {
353da2e3ebdSchin ed_ungetchar(ep->ed,'=');
354da2e3ebdSchin goto do_escape;
355da2e3ebdSchin }
356da2e3ebdSchin ep->ed->e_tabcount = 0;
357da2e3ebdSchin }
358da2e3ebdSchin do_default_processing:
359da2e3ebdSchin default:
360da2e3ebdSchin
361da2e3ebdSchin if ((eol+1) >= (scend)) /* will not fit on line */
362da2e3ebdSchin {
363da2e3ebdSchin ed_ungetchar(ep->ed,c); /* save character for next line */
364da2e3ebdSchin goto process;
365da2e3ebdSchin }
366da2e3ebdSchin for(i= ++eol; i>cur; i--)
367da2e3ebdSchin out[i] = out[i-1];
368da2e3ebdSchin backslash = (c == '\\');
369da2e3ebdSchin out[cur++] = c;
370da2e3ebdSchin draw(ep,APPEND);
371da2e3ebdSchin continue;
372da2e3ebdSchin case cntl('Y') :
373da2e3ebdSchin {
374da2e3ebdSchin c = genlen(kstack);
375da2e3ebdSchin if ((c + eol) > scend)
376da2e3ebdSchin {
377da2e3ebdSchin beep();
378da2e3ebdSchin continue;
379da2e3ebdSchin }
380da2e3ebdSchin ep->mark = i;
381da2e3ebdSchin for(i=eol;i>=cur;i--)
382da2e3ebdSchin out[c+i] = out[i];
383da2e3ebdSchin kptr=kstack;
384da2e3ebdSchin while (i = *kptr++)
385da2e3ebdSchin out[cur++] = i;
386da2e3ebdSchin draw(ep,UPDATE);
387da2e3ebdSchin eol = genlen(out);
388da2e3ebdSchin continue;
389da2e3ebdSchin }
390da2e3ebdSchin case '\n':
391da2e3ebdSchin case '\r':
392da2e3ebdSchin c = '\n';
393da2e3ebdSchin goto process;
394da2e3ebdSchin
395da2e3ebdSchin case DELETE: /* delete char 0x7f */
396da2e3ebdSchin case '\b': /* backspace, ^h */
397da2e3ebdSchin case ERASECHAR :
398da2e3ebdSchin if (count > i)
399da2e3ebdSchin count = i;
400da2e3ebdSchin #ifdef ESH_KAPPEND
401da2e3ebdSchin kptr = &kstack[count]; /* move old contents here */
402da2e3ebdSchin if (killing) /* prepend to killbuf */
403da2e3ebdSchin {
404da2e3ebdSchin c = genlen(kstack) + CHARSIZE; /* include '\0' */
405da2e3ebdSchin while(c--) /* copy stuff */
406da2e3ebdSchin kptr[c] = kstack[c];
407da2e3ebdSchin }
408da2e3ebdSchin else
409da2e3ebdSchin *kptr = 0; /* this is end of data */
410da2e3ebdSchin killing = 2; /* we are killing */
411da2e3ebdSchin i -= count;
412da2e3ebdSchin eol -= count;
413da2e3ebdSchin genncpy(kstack,out+i,cur-i);
414da2e3ebdSchin #else
415da2e3ebdSchin while ((count--)&&(i>0))
416da2e3ebdSchin {
417da2e3ebdSchin i--;
418da2e3ebdSchin eol--;
419da2e3ebdSchin }
420da2e3ebdSchin genncpy(kstack,out+i,cur-i);
421da2e3ebdSchin kstack[cur-i] = 0;
422da2e3ebdSchin #endif /* ESH_KAPPEND */
423da2e3ebdSchin gencpy(out+i,out+cur);
424da2e3ebdSchin ep->mark = i;
425da2e3ebdSchin goto update;
426da2e3ebdSchin case cntl('W') :
427da2e3ebdSchin #ifdef ESH_KAPPEND
428da2e3ebdSchin ++killing; /* keep killing flag */
429da2e3ebdSchin #endif
430da2e3ebdSchin if (ep->mark > eol )
431da2e3ebdSchin ep->mark = eol;
432da2e3ebdSchin if (ep->mark == i)
433da2e3ebdSchin continue;
434da2e3ebdSchin if (ep->mark > i)
435da2e3ebdSchin {
436da2e3ebdSchin adjust = ep->mark - i;
437da2e3ebdSchin ed_ungetchar(ep->ed,cntl('D'));
438da2e3ebdSchin continue;
439da2e3ebdSchin }
440da2e3ebdSchin adjust = i - ep->mark;
441da2e3ebdSchin ed_ungetchar(ep->ed,usrerase);
442da2e3ebdSchin continue;
443da2e3ebdSchin case cntl('D') :
444da2e3ebdSchin ep->mark = i;
445da2e3ebdSchin #ifdef ESH_KAPPEND
446da2e3ebdSchin if (killing)
447da2e3ebdSchin kptr = &kstack[genlen(kstack)]; /* append here */
448da2e3ebdSchin else
449da2e3ebdSchin kptr = kstack;
450da2e3ebdSchin killing = 2; /* we are now killing */
451da2e3ebdSchin #else
452da2e3ebdSchin kptr = kstack;
453da2e3ebdSchin #endif /* ESH_KAPPEND */
454da2e3ebdSchin while ((count--)&&(eol>0)&&(i<eol))
455da2e3ebdSchin {
456da2e3ebdSchin *kptr++ = out[i];
457da2e3ebdSchin eol--;
458da2e3ebdSchin while(1)
459da2e3ebdSchin {
460da2e3ebdSchin if ((out[i] = out[(i+1)])==0)
461da2e3ebdSchin break;
462da2e3ebdSchin i++;
463da2e3ebdSchin }
464da2e3ebdSchin i = cur;
465da2e3ebdSchin }
466da2e3ebdSchin *kptr = '\0';
467da2e3ebdSchin goto update;
468da2e3ebdSchin case cntl('C') :
469da2e3ebdSchin case cntl('F') :
470da2e3ebdSchin {
471da2e3ebdSchin int cntlC = (c==cntl('C'));
472da2e3ebdSchin while (count-- && eol>i)
473da2e3ebdSchin {
474da2e3ebdSchin if (cntlC)
475da2e3ebdSchin {
476da2e3ebdSchin c = out[i];
477da2e3ebdSchin #if SHOPT_MULTIBYTE
478da2e3ebdSchin if((c&~STRIP)==0 && islower(c))
479da2e3ebdSchin #else
480da2e3ebdSchin if(islower(c))
481da2e3ebdSchin #endif /* SHOPT_MULTIBYTE */
482da2e3ebdSchin {
483da2e3ebdSchin c += 'A' - 'a';
484da2e3ebdSchin out[i] = c;
485da2e3ebdSchin }
486da2e3ebdSchin }
487da2e3ebdSchin i++;
488da2e3ebdSchin }
489da2e3ebdSchin goto update;
490da2e3ebdSchin }
491da2e3ebdSchin case cntl(']') :
492da2e3ebdSchin c = ed_getchar(ep->ed,1);
493da2e3ebdSchin if ((count == 0) || (count > eol))
494da2e3ebdSchin {
495da2e3ebdSchin beep();
496da2e3ebdSchin continue;
497da2e3ebdSchin }
498da2e3ebdSchin if (out[i])
499da2e3ebdSchin i++;
500da2e3ebdSchin while (i < eol)
501da2e3ebdSchin {
502da2e3ebdSchin if (out[i] == c && --count==0)
503da2e3ebdSchin goto update;
504da2e3ebdSchin i++;
505da2e3ebdSchin }
506da2e3ebdSchin i = 0;
507da2e3ebdSchin while (i < cur)
508da2e3ebdSchin {
509da2e3ebdSchin if (out[i] == c && --count==0)
510da2e3ebdSchin break;
511da2e3ebdSchin i++;
512da2e3ebdSchin };
513da2e3ebdSchin
514da2e3ebdSchin update:
515da2e3ebdSchin cur = i;
516da2e3ebdSchin draw(ep,UPDATE);
517da2e3ebdSchin continue;
518da2e3ebdSchin
519da2e3ebdSchin case cntl('B') :
520da2e3ebdSchin if (count > i)
521da2e3ebdSchin count = i;
522da2e3ebdSchin i -= count;
523da2e3ebdSchin goto update;
524da2e3ebdSchin case cntl('T') :
525da2e3ebdSchin if ((sh_isoption(SH_EMACS))&& (eol!=i))
526da2e3ebdSchin i++;
527da2e3ebdSchin if (i >= 2)
528da2e3ebdSchin {
529da2e3ebdSchin c = out[i - 1];
530da2e3ebdSchin out[i-1] = out[i-2];
531da2e3ebdSchin out[i-2] = c;
532da2e3ebdSchin }
533da2e3ebdSchin else
534da2e3ebdSchin {
535da2e3ebdSchin if(sh_isoption(SH_EMACS))
536da2e3ebdSchin i--;
537da2e3ebdSchin beep();
538da2e3ebdSchin continue;
539da2e3ebdSchin }
540da2e3ebdSchin goto update;
541da2e3ebdSchin case cntl('A') :
542da2e3ebdSchin i = 0;
543da2e3ebdSchin goto update;
544da2e3ebdSchin case cntl('E') :
545da2e3ebdSchin i = eol;
546da2e3ebdSchin goto update;
547da2e3ebdSchin case cntl('U') :
548da2e3ebdSchin adjust = 4*count;
549da2e3ebdSchin continue;
550da2e3ebdSchin case KILLCHAR :
551da2e3ebdSchin cur = 0;
552da2e3ebdSchin oadjust = -1;
553da2e3ebdSchin case cntl('K') :
554da2e3ebdSchin if(oadjust >= 0)
555da2e3ebdSchin {
556da2e3ebdSchin #ifdef ESH_KAPPEND
557da2e3ebdSchin killing = 2; /* set killing signal */
558da2e3ebdSchin #endif
559da2e3ebdSchin ep->mark = count;
560da2e3ebdSchin ed_ungetchar(ep->ed,cntl('W'));
561da2e3ebdSchin continue;
562da2e3ebdSchin }
563da2e3ebdSchin i = cur;
564da2e3ebdSchin eol = i;
565da2e3ebdSchin ep->mark = i;
566da2e3ebdSchin #ifdef ESH_KAPPEND
567da2e3ebdSchin if (killing) /* append to kill buffer */
568da2e3ebdSchin gencpy(&kstack[genlen(kstack)], &out[i]);
569da2e3ebdSchin else
570da2e3ebdSchin gencpy(kstack,&out[i]);
571da2e3ebdSchin killing = 2; /* set killing signal */
572da2e3ebdSchin #else
573da2e3ebdSchin gencpy(kstack,&out[i]);
574da2e3ebdSchin #endif /* ESH_KAPPEND */
575da2e3ebdSchin out[i] = 0;
576da2e3ebdSchin draw(ep,UPDATE);
577da2e3ebdSchin if (c == KILLCHAR)
578da2e3ebdSchin {
579da2e3ebdSchin if (ep->terminal == PAPER)
580da2e3ebdSchin {
581da2e3ebdSchin putchar(ep->ed,'\n');
582da2e3ebdSchin putstring(ep,Prompt);
583da2e3ebdSchin }
584da2e3ebdSchin c = ed_getchar(ep->ed,0);
585da2e3ebdSchin if (c != usrkill)
586da2e3ebdSchin {
587da2e3ebdSchin ed_ungetchar(ep->ed,c);
588da2e3ebdSchin continue;
589da2e3ebdSchin }
590da2e3ebdSchin if (ep->terminal == PAPER)
591da2e3ebdSchin ep->terminal = CRT;
592da2e3ebdSchin else
593da2e3ebdSchin {
594da2e3ebdSchin ep->terminal = PAPER;
595da2e3ebdSchin putchar(ep->ed,'\n');
596da2e3ebdSchin putstring(ep,Prompt);
597da2e3ebdSchin }
598da2e3ebdSchin }
599da2e3ebdSchin continue;
600da2e3ebdSchin case cntl('L'):
6017c2fbfb3SApril Chin if(!ep->ed->e_nocrnl)
602da2e3ebdSchin ed_crlf(ep->ed);
603da2e3ebdSchin draw(ep,REFRESH);
6047c2fbfb3SApril Chin ep->ed->e_nocrnl = 0;
605da2e3ebdSchin continue;
606da2e3ebdSchin case cntl('[') :
607da2e3ebdSchin do_escape:
608da2e3ebdSchin adjust = escape(ep,out,oadjust);
609da2e3ebdSchin continue;
610da2e3ebdSchin case cntl('R') :
611da2e3ebdSchin search(ep,out,count);
612da2e3ebdSchin goto drawline;
613da2e3ebdSchin case cntl('P') :
614da2e3ebdSchin if (count <= hloff)
615da2e3ebdSchin hloff -= count;
616da2e3ebdSchin else
617da2e3ebdSchin {
618da2e3ebdSchin hline -= count - hloff;
619da2e3ebdSchin hloff = 0;
620da2e3ebdSchin }
621da2e3ebdSchin #ifdef ESH_NFIRST
622da2e3ebdSchin if (hline <= hismin)
623da2e3ebdSchin #else
624da2e3ebdSchin if (hline < hismin)
625da2e3ebdSchin #endif /* ESH_NFIRST */
626da2e3ebdSchin {
627da2e3ebdSchin hline = hismin+1;
628da2e3ebdSchin beep();
629da2e3ebdSchin #ifndef ESH_NFIRST
630da2e3ebdSchin continue;
631da2e3ebdSchin #endif
632da2e3ebdSchin }
633da2e3ebdSchin goto common;
634da2e3ebdSchin
635da2e3ebdSchin case cntl('O') :
636da2e3ebdSchin location.hist_command = hline;
637da2e3ebdSchin location.hist_line = hloff;
638da2e3ebdSchin ep->CntrlO = 1;
639da2e3ebdSchin c = '\n';
640da2e3ebdSchin goto process;
641da2e3ebdSchin case cntl('N') :
642da2e3ebdSchin #ifdef ESH_NFIRST
643da2e3ebdSchin hline = location.hist_command; /* start at saved position */
644da2e3ebdSchin hloff = location.hist_line;
645da2e3ebdSchin #endif /* ESH_NFIRST */
646da2e3ebdSchin location = hist_locate(sh.hist_ptr,hline,hloff,count);
647da2e3ebdSchin if (location.hist_command > histlines)
648da2e3ebdSchin {
649da2e3ebdSchin beep();
650da2e3ebdSchin #ifdef ESH_NFIRST
651da2e3ebdSchin location.hist_command = histlines;
652da2e3ebdSchin location.hist_line = ep->in_mult;
653da2e3ebdSchin #else
654da2e3ebdSchin continue;
655da2e3ebdSchin #endif /* ESH_NFIRST */
656da2e3ebdSchin }
657da2e3ebdSchin hline = location.hist_command;
658da2e3ebdSchin hloff = location.hist_line;
659da2e3ebdSchin common:
660da2e3ebdSchin #ifdef ESH_NFIRST
661da2e3ebdSchin location.hist_command = hline; /* save current position */
662da2e3ebdSchin location.hist_line = hloff;
663da2e3ebdSchin #endif
6647c2fbfb3SApril Chin cur = 0;
6657c2fbfb3SApril Chin draw(ep,UPDATE);
666da2e3ebdSchin hist_copy((char*)out,MAXLINE, hline,hloff);
667da2e3ebdSchin #if SHOPT_MULTIBYTE
668da2e3ebdSchin ed_internal((char*)(out),out);
669da2e3ebdSchin #endif /* SHOPT_MULTIBYTE */
670da2e3ebdSchin drawline:
671da2e3ebdSchin eol = genlen(out);
672da2e3ebdSchin cur = eol;
673da2e3ebdSchin draw(ep,UPDATE);
674da2e3ebdSchin continue;
675da2e3ebdSchin }
676da2e3ebdSchin
677da2e3ebdSchin }
678da2e3ebdSchin
679da2e3ebdSchin process:
680da2e3ebdSchin
681da2e3ebdSchin if (c == (-1))
682da2e3ebdSchin {
683da2e3ebdSchin lookahead = 0;
684da2e3ebdSchin beep();
685da2e3ebdSchin *out = '\0';
686da2e3ebdSchin }
687da2e3ebdSchin draw(ep,FINAL);
688da2e3ebdSchin tty_cooked(ERRIO);
689da2e3ebdSchin if(ed->e_nlist)
690da2e3ebdSchin {
691da2e3ebdSchin ed->e_nlist = 0;
692da2e3ebdSchin stakset(ed->e_stkptr,ed->e_stkoff);
693da2e3ebdSchin }
694da2e3ebdSchin if(c == '\n')
695da2e3ebdSchin {
696da2e3ebdSchin out[eol++] = '\n';
697da2e3ebdSchin out[eol] = '\0';
698da2e3ebdSchin ed_crlf(ep->ed);
699da2e3ebdSchin }
700da2e3ebdSchin #if SHOPT_MULTIBYTE
701da2e3ebdSchin ed_external(out,buff);
702da2e3ebdSchin #endif /* SHOPT_MULTIBYTE */
703da2e3ebdSchin i = strlen(buff);
704da2e3ebdSchin if (i)
705da2e3ebdSchin return(i);
706da2e3ebdSchin return(-1);
707da2e3ebdSchin }
708da2e3ebdSchin
show_info(Emacs_t * ep,const char * str)709da2e3ebdSchin static void show_info(Emacs_t *ep,const char *str)
710da2e3ebdSchin {
711da2e3ebdSchin register genchar *out = drawbuff;
712da2e3ebdSchin register int c;
713da2e3ebdSchin genchar string[LBUF];
714da2e3ebdSchin int sav_cur = cur;
715da2e3ebdSchin /* save current line */
716da2e3ebdSchin genncpy(string,out,sizeof(string)/sizeof(*string));
717da2e3ebdSchin *out = 0;
718da2e3ebdSchin cur = 0;
719da2e3ebdSchin #if SHOPT_MULTIBYTE
720da2e3ebdSchin ed_internal(str,out);
721da2e3ebdSchin #else
722da2e3ebdSchin gencpy(out,str);
723da2e3ebdSchin #endif /* SHOPT_MULTIBYTE */
724da2e3ebdSchin draw(ep,UPDATE);
725da2e3ebdSchin c = ed_getchar(ep->ed,0);
726da2e3ebdSchin if(c!=' ')
727da2e3ebdSchin ed_ungetchar(ep->ed,c);
728da2e3ebdSchin /* restore line */
729da2e3ebdSchin cur = sav_cur;
730da2e3ebdSchin genncpy(out,string,sizeof(string)/sizeof(*string));
731da2e3ebdSchin draw(ep,UPDATE);
732da2e3ebdSchin }
733da2e3ebdSchin
putstring(Emacs_t * ep,register char * sp)734da2e3ebdSchin static void putstring(Emacs_t* ep,register char *sp)
735da2e3ebdSchin {
736da2e3ebdSchin register int c;
737da2e3ebdSchin while (c= *sp++)
738da2e3ebdSchin putchar(ep->ed,c);
739da2e3ebdSchin }
740da2e3ebdSchin
741da2e3ebdSchin
escape(register Emacs_t * ep,register genchar * out,int count)742da2e3ebdSchin static int escape(register Emacs_t* ep,register genchar *out,int count)
743da2e3ebdSchin {
744da2e3ebdSchin register int i,value;
745da2e3ebdSchin int digit,ch;
746da2e3ebdSchin digit = 0;
747da2e3ebdSchin value = 0;
748da2e3ebdSchin while ((i=ed_getchar(ep->ed,0)),isdigit(i))
749da2e3ebdSchin {
750da2e3ebdSchin value *= 10;
751da2e3ebdSchin value += (i - '0');
752da2e3ebdSchin digit = 1;
753da2e3ebdSchin }
754da2e3ebdSchin if (digit)
755da2e3ebdSchin {
756da2e3ebdSchin ed_ungetchar(ep->ed,i) ;
757da2e3ebdSchin #ifdef ESH_KAPPEND
758da2e3ebdSchin ++killing; /* don't modify killing signal */
759da2e3ebdSchin #endif
760da2e3ebdSchin return(value);
761da2e3ebdSchin }
762da2e3ebdSchin value = count;
763da2e3ebdSchin if(value<0)
764da2e3ebdSchin value = 1;
765da2e3ebdSchin switch(ch=i)
766da2e3ebdSchin {
767da2e3ebdSchin case cntl('V'):
768da2e3ebdSchin show_info(ep,fmtident(e_version));
769da2e3ebdSchin return(-1);
770da2e3ebdSchin case ' ':
771da2e3ebdSchin ep->mark = cur;
772da2e3ebdSchin return(-1);
773da2e3ebdSchin
774da2e3ebdSchin #ifdef ESH_KAPPEND
775da2e3ebdSchin case '+': /* M-+ = append next kill */
776da2e3ebdSchin killing = 2;
777da2e3ebdSchin return -1; /* no argument for next command */
778da2e3ebdSchin #endif
779da2e3ebdSchin
780da2e3ebdSchin case 'p': /* M-p == ^W^Y (copy stack == kill & yank) */
781da2e3ebdSchin ed_ungetchar(ep->ed,cntl('Y'));
782da2e3ebdSchin ed_ungetchar(ep->ed,cntl('W'));
783da2e3ebdSchin #ifdef ESH_KAPPEND
784da2e3ebdSchin killing = 0; /* start fresh */
785da2e3ebdSchin #endif
786da2e3ebdSchin return(-1);
787da2e3ebdSchin
788da2e3ebdSchin case 'l': /* M-l == lower-case */
789da2e3ebdSchin case 'd':
790da2e3ebdSchin case 'c':
791da2e3ebdSchin case 'f':
792da2e3ebdSchin {
793da2e3ebdSchin i = cur;
794da2e3ebdSchin while(value-- && i<eol)
795da2e3ebdSchin {
796da2e3ebdSchin while ((out[i])&&(!isword(i)))
797da2e3ebdSchin i++;
798da2e3ebdSchin while ((out[i])&&(isword(i)))
799da2e3ebdSchin i++;
800da2e3ebdSchin }
801da2e3ebdSchin if(ch=='l')
802da2e3ebdSchin {
803da2e3ebdSchin value = i-cur;
804da2e3ebdSchin while (value-- > 0)
805da2e3ebdSchin {
806da2e3ebdSchin i = out[cur];
807da2e3ebdSchin #if SHOPT_MULTIBYTE
808da2e3ebdSchin if((i&~STRIP)==0 && isupper(i))
809da2e3ebdSchin #else
810da2e3ebdSchin if(isupper(i))
811da2e3ebdSchin #endif /* SHOPT_MULTIBYTE */
812da2e3ebdSchin {
813da2e3ebdSchin i += 'a' - 'A';
814da2e3ebdSchin out[cur] = i;
815da2e3ebdSchin }
816da2e3ebdSchin cur++;
817da2e3ebdSchin }
818da2e3ebdSchin draw(ep,UPDATE);
819da2e3ebdSchin return(-1);
820da2e3ebdSchin }
821da2e3ebdSchin
822da2e3ebdSchin else if(ch=='f')
823da2e3ebdSchin goto update;
824da2e3ebdSchin else if(ch=='c')
825da2e3ebdSchin {
826da2e3ebdSchin ed_ungetchar(ep->ed,cntl('C'));
827da2e3ebdSchin return(i-cur);
828da2e3ebdSchin }
829da2e3ebdSchin else
830da2e3ebdSchin {
831da2e3ebdSchin if (i-cur)
832da2e3ebdSchin {
833da2e3ebdSchin ed_ungetchar(ep->ed,cntl('D'));
834da2e3ebdSchin #ifdef ESH_KAPPEND
835da2e3ebdSchin ++killing; /* keep killing signal */
836da2e3ebdSchin #endif
837da2e3ebdSchin return(i-cur);
838da2e3ebdSchin }
839da2e3ebdSchin beep();
840da2e3ebdSchin return(-1);
841da2e3ebdSchin }
842da2e3ebdSchin }
843da2e3ebdSchin
844da2e3ebdSchin
845da2e3ebdSchin case 'b':
846da2e3ebdSchin case DELETE :
847da2e3ebdSchin case '\b':
848da2e3ebdSchin case 'h':
849da2e3ebdSchin {
850da2e3ebdSchin i = cur;
851da2e3ebdSchin while(value-- && i>0)
852da2e3ebdSchin {
853da2e3ebdSchin i--;
854da2e3ebdSchin while ((i>0)&&(!isword(i)))
855da2e3ebdSchin i--;
856da2e3ebdSchin while ((i>0)&&(isword(i-1)))
857da2e3ebdSchin i--;
858da2e3ebdSchin }
859da2e3ebdSchin if(ch=='b')
860da2e3ebdSchin goto update;
861da2e3ebdSchin else
862da2e3ebdSchin {
863da2e3ebdSchin ed_ungetchar(ep->ed,usrerase);
864da2e3ebdSchin #ifdef ESH_KAPPEND
865da2e3ebdSchin ++killing;
866da2e3ebdSchin #endif
867da2e3ebdSchin return(cur-i);
868da2e3ebdSchin }
869da2e3ebdSchin }
870da2e3ebdSchin
871da2e3ebdSchin case '>':
872da2e3ebdSchin ed_ungetchar(ep->ed,cntl('N'));
873da2e3ebdSchin #ifdef ESH_NFIRST
874da2e3ebdSchin if (ep->in_mult)
875da2e3ebdSchin {
876da2e3ebdSchin location.hist_command = histlines;
877da2e3ebdSchin location.hist_line = ep->in_mult - 1;
878da2e3ebdSchin }
879da2e3ebdSchin else
880da2e3ebdSchin {
881da2e3ebdSchin location.hist_command = histlines - 1;
882da2e3ebdSchin location.hist_line = 0;
883da2e3ebdSchin }
884da2e3ebdSchin #else
885da2e3ebdSchin hline = histlines-1;
886da2e3ebdSchin hloff = 0;
887da2e3ebdSchin #endif /* ESH_NFIRST */
888da2e3ebdSchin return(0);
889da2e3ebdSchin
890da2e3ebdSchin case '<':
891da2e3ebdSchin ed_ungetchar(ep->ed,cntl('P'));
892da2e3ebdSchin hloff = 0;
893da2e3ebdSchin #ifdef ESH_NFIRST
894da2e3ebdSchin hline = hismin + 1;
895da2e3ebdSchin return 0;
896da2e3ebdSchin #else
897da2e3ebdSchin return(hline-hismin);
898da2e3ebdSchin #endif /* ESH_NFIRST */
899da2e3ebdSchin
900da2e3ebdSchin
901da2e3ebdSchin case '#':
902da2e3ebdSchin ed_ungetchar(ep->ed,'\n');
903da2e3ebdSchin ed_ungetchar(ep->ed,(out[0]=='#')?cntl('D'):'#');
904da2e3ebdSchin ed_ungetchar(ep->ed,cntl('A'));
905da2e3ebdSchin return(-1);
906da2e3ebdSchin case '_' :
907da2e3ebdSchin case '.' :
908da2e3ebdSchin {
909da2e3ebdSchin genchar name[MAXLINE];
910da2e3ebdSchin char buf[MAXLINE];
911da2e3ebdSchin char *ptr;
912da2e3ebdSchin ptr = hist_word(buf,MAXLINE,(count?count:-1));
913da2e3ebdSchin if(ptr==0)
914da2e3ebdSchin {
915da2e3ebdSchin beep();
916da2e3ebdSchin break;
917da2e3ebdSchin }
918da2e3ebdSchin if ((eol - cur) >= sizeof(name))
919da2e3ebdSchin {
920da2e3ebdSchin beep();
921da2e3ebdSchin return(-1);
922da2e3ebdSchin }
923da2e3ebdSchin ep->mark = cur;
924da2e3ebdSchin gencpy(name,&out[cur]);
925da2e3ebdSchin while(*ptr)
926da2e3ebdSchin {
927da2e3ebdSchin out[cur++] = *ptr++;
928da2e3ebdSchin eol++;
929da2e3ebdSchin }
930da2e3ebdSchin gencpy(&out[cur],name);
931da2e3ebdSchin draw(ep,UPDATE);
932da2e3ebdSchin return(-1);
933da2e3ebdSchin }
934da2e3ebdSchin #if KSHELL
935da2e3ebdSchin
936da2e3ebdSchin /* file name expansion */
937da2e3ebdSchin case cntl('[') : /* filename completion */
938da2e3ebdSchin i = '\\';
939da2e3ebdSchin case '*': /* filename expansion */
940da2e3ebdSchin case '=': /* escape = - list all matching file names */
941da2e3ebdSchin ep->mark = cur;
942da2e3ebdSchin if(ed_expand(ep->ed,(char*)out,&cur,&eol,i,count) < 0)
943da2e3ebdSchin {
944da2e3ebdSchin if(ep->ed->e_tabcount==1)
945da2e3ebdSchin {
946da2e3ebdSchin ep->ed->e_tabcount=2;
947da2e3ebdSchin ed_ungetchar(ep->ed,cntl('\t'));
948da2e3ebdSchin return(-1);
949da2e3ebdSchin }
950da2e3ebdSchin beep();
951da2e3ebdSchin }
952da2e3ebdSchin else if(i=='=')
953da2e3ebdSchin {
954da2e3ebdSchin draw(ep,REFRESH);
955da2e3ebdSchin if(count>0)
956da2e3ebdSchin ep->ed->e_tabcount=0;
957da2e3ebdSchin else
958da2e3ebdSchin {
959da2e3ebdSchin i=ed_getchar(ep->ed,0);
960da2e3ebdSchin ed_ungetchar(ep->ed,i);
961da2e3ebdSchin if(isdigit(i))
962da2e3ebdSchin ed_ungetchar(ep->ed,ESC);
963da2e3ebdSchin }
964da2e3ebdSchin }
965da2e3ebdSchin else
966da2e3ebdSchin {
967da2e3ebdSchin if(i=='\\' && cur>ep->mark && (out[cur-1]=='/' || out[cur-1]==' '))
968da2e3ebdSchin ep->ed->e_tabcount=0;
969da2e3ebdSchin draw(ep,UPDATE);
970da2e3ebdSchin }
971da2e3ebdSchin return(-1);
972da2e3ebdSchin
973da2e3ebdSchin /* search back for character */
974da2e3ebdSchin case cntl(']'): /* feature not in book */
975da2e3ebdSchin {
976da2e3ebdSchin int c = ed_getchar(ep->ed,1);
977da2e3ebdSchin if ((value == 0) || (value > eol))
978da2e3ebdSchin {
979da2e3ebdSchin beep();
980da2e3ebdSchin return(-1);
981da2e3ebdSchin }
982da2e3ebdSchin i = cur;
983da2e3ebdSchin if (i > 0)
984da2e3ebdSchin i--;
985da2e3ebdSchin while (i >= 0)
986da2e3ebdSchin {
987da2e3ebdSchin if (out[i] == c && --value==0)
988da2e3ebdSchin goto update;
989da2e3ebdSchin i--;
990da2e3ebdSchin }
991da2e3ebdSchin i = eol;
992da2e3ebdSchin while (i > cur)
993da2e3ebdSchin {
994da2e3ebdSchin if (out[i] == c && --value==0)
995da2e3ebdSchin break;
996da2e3ebdSchin i--;
997da2e3ebdSchin };
998da2e3ebdSchin
999da2e3ebdSchin }
1000da2e3ebdSchin update:
1001da2e3ebdSchin cur = i;
1002da2e3ebdSchin draw(ep,UPDATE);
1003da2e3ebdSchin return(-1);
1004da2e3ebdSchin
1005da2e3ebdSchin #ifdef _cmd_tput
1006da2e3ebdSchin case cntl('L'): /* clear screen */
1007da2e3ebdSchin sh_trap("tput clear", 0);
1008da2e3ebdSchin draw(ep,REFRESH);
1009da2e3ebdSchin return(-1);
1010da2e3ebdSchin #endif
1011da2e3ebdSchin case '[': /* feature not in book */
1012da2e3ebdSchin switch(i=ed_getchar(ep->ed,1))
1013da2e3ebdSchin {
1014da2e3ebdSchin case 'A':
10157c2fbfb3SApril Chin if(cur>0 && eol==cur && (cur<(SEARCHSIZE-2) || ep->prevdirection == -2))
10167c2fbfb3SApril Chin {
10177c2fbfb3SApril Chin if(ep->lastdraw==APPEND && ep->prevdirection != -2)
10187c2fbfb3SApril Chin {
10197c2fbfb3SApril Chin out[cur] = 0;
10207c2fbfb3SApril Chin gencpy(&((genchar*)lstring)[1],out);
10217c2fbfb3SApril Chin #if SHOPT_MULTIBYTE
10227c2fbfb3SApril Chin ed_external(&((genchar*)lstring)[1],lstring+1);
10237c2fbfb3SApril Chin #endif /* SHOPT_MULTIBYTE */
10247c2fbfb3SApril Chin *lstring = '^';
10257c2fbfb3SApril Chin ep->prevdirection = -2;
10267c2fbfb3SApril Chin }
10277c2fbfb3SApril Chin if(*lstring)
10287c2fbfb3SApril Chin {
10297c2fbfb3SApril Chin ed_ungetchar(ep->ed,'\r');
10307c2fbfb3SApril Chin ed_ungetchar(ep->ed,cntl('R'));
10317c2fbfb3SApril Chin return(-1);
10327c2fbfb3SApril Chin }
10337c2fbfb3SApril Chin }
10347c2fbfb3SApril Chin *lstring = 0;
1035da2e3ebdSchin ed_ungetchar(ep->ed,cntl('P'));
1036da2e3ebdSchin return(-1);
1037da2e3ebdSchin case 'B':
1038da2e3ebdSchin ed_ungetchar(ep->ed,cntl('N'));
1039da2e3ebdSchin return(-1);
1040da2e3ebdSchin case 'C':
1041da2e3ebdSchin ed_ungetchar(ep->ed,cntl('F'));
1042da2e3ebdSchin return(-1);
1043da2e3ebdSchin case 'D':
1044da2e3ebdSchin ed_ungetchar(ep->ed,cntl('B'));
1045da2e3ebdSchin return(-1);
1046da2e3ebdSchin case 'H':
1047da2e3ebdSchin ed_ungetchar(ep->ed,cntl('A'));
1048da2e3ebdSchin return(-1);
1049da2e3ebdSchin case 'Y':
1050da2e3ebdSchin ed_ungetchar(ep->ed,cntl('E'));
1051da2e3ebdSchin return(-1);
1052da2e3ebdSchin default:
1053da2e3ebdSchin ed_ungetchar(ep->ed,i);
1054da2e3ebdSchin }
1055da2e3ebdSchin i = '_';
1056da2e3ebdSchin
1057da2e3ebdSchin default:
1058da2e3ebdSchin /* look for user defined macro definitions */
1059da2e3ebdSchin if(ed_macro(ep->ed,i))
1060da2e3ebdSchin # ifdef ESH_BETTER
1061da2e3ebdSchin return(count); /* pass argument to macro */
1062da2e3ebdSchin # else
1063da2e3ebdSchin return(-1);
1064da2e3ebdSchin # endif /* ESH_BETTER */
1065da2e3ebdSchin #else
1066da2e3ebdSchin update:
1067da2e3ebdSchin cur = i;
1068da2e3ebdSchin draw(ep,UPDATE);
1069da2e3ebdSchin return(-1);
1070da2e3ebdSchin
1071da2e3ebdSchin default:
1072da2e3ebdSchin #endif /* KSHELL */
1073da2e3ebdSchin beep();
1074da2e3ebdSchin return(-1);
1075da2e3ebdSchin }
107634f9b3eeSRoland Mainz return(-1);
1077da2e3ebdSchin }
1078da2e3ebdSchin
1079da2e3ebdSchin
1080da2e3ebdSchin /*
1081da2e3ebdSchin * This routine process all commands starting with ^X
1082da2e3ebdSchin */
1083da2e3ebdSchin
xcommands(register Emacs_t * ep,int count)1084da2e3ebdSchin static void xcommands(register Emacs_t *ep,int count)
1085da2e3ebdSchin {
1086da2e3ebdSchin register int i = ed_getchar(ep->ed,0);
1087da2e3ebdSchin NOT_USED(count);
1088da2e3ebdSchin switch(i)
1089da2e3ebdSchin {
1090da2e3ebdSchin case cntl('X'): /* exchange dot and mark */
1091da2e3ebdSchin if (ep->mark > eol)
1092da2e3ebdSchin ep->mark = eol;
1093da2e3ebdSchin i = ep->mark;
1094da2e3ebdSchin ep->mark = cur;
1095da2e3ebdSchin cur = i;
1096da2e3ebdSchin draw(ep,UPDATE);
1097da2e3ebdSchin return;
1098da2e3ebdSchin
1099da2e3ebdSchin #if KSHELL
1100da2e3ebdSchin # ifdef ESH_BETTER
1101da2e3ebdSchin case cntl('E'): /* invoke emacs on current command */
1102da2e3ebdSchin if(ed_fulledit(ep->ed)==-1)
1103da2e3ebdSchin beep();
1104da2e3ebdSchin else
1105da2e3ebdSchin {
1106da2e3ebdSchin #if SHOPT_MULTIBYTE
1107da2e3ebdSchin ed_internal((char*)drawbuff,drawbuff);
1108da2e3ebdSchin #endif /* SHOPT_MULTIBYTE */
1109da2e3ebdSchin ed_ungetchar(ep->ed,'\n');
1110da2e3ebdSchin }
1111da2e3ebdSchin return;
1112da2e3ebdSchin
1113da2e3ebdSchin # define itos(i) fmtbase((long)(i),0,0)/* want signed conversion */
1114da2e3ebdSchin
1115da2e3ebdSchin case cntl('H'): /* ^X^H show history info */
1116da2e3ebdSchin {
1117da2e3ebdSchin char hbuf[MAXLINE];
1118da2e3ebdSchin
1119da2e3ebdSchin strcpy(hbuf, "Current command ");
1120da2e3ebdSchin strcat(hbuf, itos(hline));
1121da2e3ebdSchin if (hloff)
1122da2e3ebdSchin {
1123da2e3ebdSchin strcat(hbuf, " (line ");
1124da2e3ebdSchin strcat(hbuf, itos(hloff+1));
1125da2e3ebdSchin strcat(hbuf, ")");
1126da2e3ebdSchin }
1127da2e3ebdSchin if ((hline != location.hist_command) ||
1128da2e3ebdSchin (hloff != location.hist_line))
1129da2e3ebdSchin {
1130da2e3ebdSchin strcat(hbuf, "; Previous command ");
1131da2e3ebdSchin strcat(hbuf, itos(location.hist_command));
1132da2e3ebdSchin if (location.hist_line)
1133da2e3ebdSchin {
1134da2e3ebdSchin strcat(hbuf, " (line ");
1135da2e3ebdSchin strcat(hbuf, itos(location.hist_line+1));
1136da2e3ebdSchin strcat(hbuf, ")");
1137da2e3ebdSchin }
1138da2e3ebdSchin }
1139da2e3ebdSchin show_info(ep,hbuf);
1140da2e3ebdSchin return;
1141da2e3ebdSchin }
1142da2e3ebdSchin # if 0 /* debugging, modify as required */
1143da2e3ebdSchin case cntl('D'): /* ^X^D show debugging info */
1144da2e3ebdSchin {
1145da2e3ebdSchin char debugbuf[MAXLINE];
1146da2e3ebdSchin
1147da2e3ebdSchin strcpy(debugbuf, "count=");
1148da2e3ebdSchin strcat(debugbuf, itos(count));
1149da2e3ebdSchin strcat(debugbuf, " eol=");
1150da2e3ebdSchin strcat(debugbuf, itos(eol));
1151da2e3ebdSchin strcat(debugbuf, " cur=");
1152da2e3ebdSchin strcat(debugbuf, itos(cur));
1153da2e3ebdSchin strcat(debugbuf, " crallowed=");
1154da2e3ebdSchin strcat(debugbuf, itos(crallowed));
1155da2e3ebdSchin strcat(debugbuf, " plen=");
1156da2e3ebdSchin strcat(debugbuf, itos(plen));
1157da2e3ebdSchin strcat(debugbuf, " w_size=");
1158da2e3ebdSchin strcat(debugbuf, itos(w_size));
1159da2e3ebdSchin
1160da2e3ebdSchin show_info(ep,debugbuf);
1161da2e3ebdSchin return;
1162da2e3ebdSchin }
1163da2e3ebdSchin # endif /* debugging code */
1164da2e3ebdSchin # endif /* ESH_BETTER */
1165da2e3ebdSchin #endif /* KSHELL */
1166da2e3ebdSchin
1167da2e3ebdSchin default:
1168da2e3ebdSchin beep();
1169da2e3ebdSchin return;
1170da2e3ebdSchin }
1171da2e3ebdSchin }
1172da2e3ebdSchin
search(Emacs_t * ep,genchar * out,int direction)1173da2e3ebdSchin static void search(Emacs_t* ep,genchar *out,int direction)
1174da2e3ebdSchin {
1175da2e3ebdSchin #ifndef ESH_NFIRST
1176da2e3ebdSchin Histloc_t location;
1177da2e3ebdSchin #endif
1178da2e3ebdSchin register int i,sl;
1179da2e3ebdSchin genchar str_buff[LBUF];
1180da2e3ebdSchin register genchar *string = drawbuff;
1181da2e3ebdSchin /* save current line */
1182da2e3ebdSchin int sav_cur = cur;
1183da2e3ebdSchin genncpy(str_buff,string,sizeof(str_buff)/sizeof(*str_buff));
1184da2e3ebdSchin string[0] = '^';
1185da2e3ebdSchin string[1] = 'R';
1186da2e3ebdSchin string[2] = '\0';
1187da2e3ebdSchin sl = 2;
1188da2e3ebdSchin cur = sl;
1189da2e3ebdSchin draw(ep,UPDATE);
1190da2e3ebdSchin while ((i = ed_getchar(ep->ed,1))&&(i != '\r')&&(i != '\n'))
1191da2e3ebdSchin {
1192da2e3ebdSchin if (i==usrerase || i==DELETE || i=='\b' || i==ERASECHAR)
1193da2e3ebdSchin {
1194da2e3ebdSchin if (sl > 2)
1195da2e3ebdSchin {
1196da2e3ebdSchin string[--sl] = '\0';
1197da2e3ebdSchin cur = sl;
1198da2e3ebdSchin draw(ep,UPDATE);
1199da2e3ebdSchin }
1200da2e3ebdSchin else
1201da2e3ebdSchin beep();
1202da2e3ebdSchin continue;
1203da2e3ebdSchin }
1204da2e3ebdSchin if (i==usrkill)
1205da2e3ebdSchin {
1206da2e3ebdSchin beep();
1207da2e3ebdSchin goto restore;
1208da2e3ebdSchin }
1209da2e3ebdSchin if (i == '\\')
1210da2e3ebdSchin {
1211da2e3ebdSchin string[sl++] = '\\';
1212da2e3ebdSchin string[sl] = '\0';
1213da2e3ebdSchin cur = sl;
1214da2e3ebdSchin draw(ep,APPEND);
1215da2e3ebdSchin i = ed_getchar(ep->ed,1);
1216da2e3ebdSchin string[--sl] = '\0';
1217da2e3ebdSchin }
1218da2e3ebdSchin string[sl++] = i;
1219da2e3ebdSchin string[sl] = '\0';
1220da2e3ebdSchin cur = sl;
1221da2e3ebdSchin draw(ep,APPEND);
1222da2e3ebdSchin }
1223da2e3ebdSchin i = genlen(string);
1224da2e3ebdSchin
12257c2fbfb3SApril Chin if(ep->prevdirection == -2 && i!=2 || direction!=1)
12267c2fbfb3SApril Chin ep->prevdirection = -1;
1227da2e3ebdSchin if (direction < 1)
1228da2e3ebdSchin {
1229da2e3ebdSchin ep->prevdirection = -ep->prevdirection;
1230da2e3ebdSchin direction = 1;
1231da2e3ebdSchin }
1232da2e3ebdSchin else
1233da2e3ebdSchin direction = -1;
1234da2e3ebdSchin if (i != 2)
1235da2e3ebdSchin {
1236da2e3ebdSchin #if SHOPT_MULTIBYTE
1237da2e3ebdSchin ed_external(string,(char*)string);
1238da2e3ebdSchin #endif /* SHOPT_MULTIBYTE */
1239da2e3ebdSchin strncpy(lstring,((char*)string)+2,SEARCHSIZE);
1240da2e3ebdSchin ep->prevdirection = direction;
1241da2e3ebdSchin }
1242da2e3ebdSchin else
1243da2e3ebdSchin direction = ep->prevdirection ;
1244da2e3ebdSchin location = hist_find(sh.hist_ptr,(char*)lstring,hline,1,direction);
1245da2e3ebdSchin i = location.hist_command;
1246da2e3ebdSchin if(i>0)
1247da2e3ebdSchin {
1248da2e3ebdSchin hline = i;
1249da2e3ebdSchin #ifdef ESH_NFIRST
1250da2e3ebdSchin hloff = location.hist_line = 0; /* display first line of multi line command */
1251da2e3ebdSchin #else
1252da2e3ebdSchin hloff = location.hist_line;
1253da2e3ebdSchin #endif /* ESH_NFIRST */
1254da2e3ebdSchin hist_copy((char*)out,MAXLINE, hline,hloff);
1255da2e3ebdSchin #if SHOPT_MULTIBYTE
1256da2e3ebdSchin ed_internal((char*)out,out);
1257da2e3ebdSchin #endif /* SHOPT_MULTIBYTE */
1258da2e3ebdSchin return;
1259da2e3ebdSchin }
1260da2e3ebdSchin if (i < 0)
1261da2e3ebdSchin {
1262da2e3ebdSchin beep();
1263da2e3ebdSchin #ifdef ESH_NFIRST
1264da2e3ebdSchin location.hist_command = hline;
1265da2e3ebdSchin location.hist_line = hloff;
1266da2e3ebdSchin #else
1267da2e3ebdSchin hloff = 0;
1268da2e3ebdSchin hline = histlines;
1269da2e3ebdSchin #endif /* ESH_NFIRST */
1270da2e3ebdSchin }
1271da2e3ebdSchin restore:
1272da2e3ebdSchin genncpy(string,str_buff,sizeof(str_buff)/sizeof(*str_buff));
1273da2e3ebdSchin cur = sav_cur;
1274da2e3ebdSchin return;
1275da2e3ebdSchin }
1276da2e3ebdSchin
1277da2e3ebdSchin
1278da2e3ebdSchin /* Adjust screen to agree with inputs: logical line and cursor */
1279da2e3ebdSchin /* If 'first' assume screen is blank */
1280da2e3ebdSchin /* Prompt is always kept on the screen */
1281da2e3ebdSchin
draw(register Emacs_t * ep,Draw_t option)1282da2e3ebdSchin static void draw(register Emacs_t *ep,Draw_t option)
1283da2e3ebdSchin {
1284da2e3ebdSchin #define NORMAL ' '
1285da2e3ebdSchin #define LOWER '<'
1286da2e3ebdSchin #define BOTH '*'
1287da2e3ebdSchin #define UPPER '>'
1288da2e3ebdSchin
1289da2e3ebdSchin register genchar *sptr; /* Pointer within screen */
1290da2e3ebdSchin genchar nscreen[2*MAXLINE]; /* New entire screen */
1291da2e3ebdSchin genchar *ncursor; /* New cursor */
1292da2e3ebdSchin register genchar *nptr; /* Pointer to New screen */
1293da2e3ebdSchin char longline; /* Line overflow */
1294da2e3ebdSchin genchar *logcursor;
1295da2e3ebdSchin genchar *nscend; /* end of logical screen */
1296da2e3ebdSchin register int i;
1297da2e3ebdSchin
1298da2e3ebdSchin nptr = nscreen;
1299da2e3ebdSchin sptr = drawbuff;
1300da2e3ebdSchin logcursor = sptr + cur;
1301da2e3ebdSchin longline = NORMAL;
13027c2fbfb3SApril Chin ep->lastdraw = option;
1303da2e3ebdSchin
1304da2e3ebdSchin if (option == FIRST || option == REFRESH)
1305da2e3ebdSchin {
1306da2e3ebdSchin ep->overflow = NORMAL;
1307da2e3ebdSchin ep->cursor = ep->screen;
1308da2e3ebdSchin ep->offset = 0;
1309da2e3ebdSchin ep->cr_ok = crallowed;
1310da2e3ebdSchin if (option == FIRST)
1311da2e3ebdSchin {
1312da2e3ebdSchin ep->scvalid = 1;
1313da2e3ebdSchin return;
1314da2e3ebdSchin }
1315da2e3ebdSchin *ep->cursor = '\0';
1316da2e3ebdSchin putstring(ep,Prompt); /* start with prompt */
1317da2e3ebdSchin }
1318da2e3ebdSchin
1319da2e3ebdSchin /*********************
1320da2e3ebdSchin Do not update screen if pending characters
1321da2e3ebdSchin **********************/
1322da2e3ebdSchin
1323da2e3ebdSchin if ((lookahead)&&(option != FINAL))
1324da2e3ebdSchin {
1325da2e3ebdSchin
1326da2e3ebdSchin ep->scvalid = 0; /* Screen is out of date, APPEND will not work */
1327da2e3ebdSchin
1328da2e3ebdSchin return;
1329da2e3ebdSchin }
1330da2e3ebdSchin
1331da2e3ebdSchin /***************************************
1332da2e3ebdSchin If in append mode, cursor at end of line, screen up to date,
1333da2e3ebdSchin the previous character was a 'normal' character,
1334da2e3ebdSchin and the window has room for another character.
1335da2e3ebdSchin Then output the character and adjust the screen only.
1336da2e3ebdSchin *****************************************/
1337da2e3ebdSchin
1338da2e3ebdSchin
1339da2e3ebdSchin i = *(logcursor-1); /* last character inserted */
1340da2e3ebdSchin
1341da2e3ebdSchin if ((option == APPEND)&&(ep->scvalid)&&(*logcursor == '\0')&&
1342da2e3ebdSchin print(i)&&((ep->cursor-ep->screen)<(w_size-1)))
1343da2e3ebdSchin {
1344da2e3ebdSchin putchar(ep->ed,i);
1345da2e3ebdSchin *ep->cursor++ = i;
1346da2e3ebdSchin *ep->cursor = '\0';
1347da2e3ebdSchin return;
1348da2e3ebdSchin }
1349da2e3ebdSchin
1350da2e3ebdSchin /* copy the line */
1351da2e3ebdSchin ncursor = nptr + ed_virt_to_phys(ep->ed,sptr,nptr,cur,0,0);
1352da2e3ebdSchin nptr += genlen(nptr);
1353da2e3ebdSchin sptr += genlen(sptr);
1354da2e3ebdSchin nscend = nptr - 1;
1355da2e3ebdSchin if(sptr == logcursor)
1356da2e3ebdSchin ncursor = nptr;
1357da2e3ebdSchin
1358da2e3ebdSchin /*********************
1359da2e3ebdSchin Does ncursor appear on the screen?
1360da2e3ebdSchin If not, adjust the screen offset so it does.
1361da2e3ebdSchin **********************/
1362da2e3ebdSchin
1363da2e3ebdSchin i = ncursor - nscreen;
1364da2e3ebdSchin
1365da2e3ebdSchin if ((ep->offset && i<=ep->offset)||(i >= (ep->offset+w_size)))
1366da2e3ebdSchin {
1367da2e3ebdSchin /* Center the cursor on the screen */
1368da2e3ebdSchin ep->offset = i - (w_size>>1);
1369da2e3ebdSchin if (--ep->offset < 0)
1370da2e3ebdSchin ep->offset = 0;
1371da2e3ebdSchin }
1372da2e3ebdSchin
1373da2e3ebdSchin /*********************
1374da2e3ebdSchin Is the range of screen[0] thru screen[w_size] up-to-date
1375da2e3ebdSchin with nscreen[offset] thru nscreen[offset+w_size] ?
1376da2e3ebdSchin If not, update as need be.
1377da2e3ebdSchin ***********************/
1378da2e3ebdSchin
1379da2e3ebdSchin nptr = &nscreen[ep->offset];
1380da2e3ebdSchin sptr = ep->screen;
1381da2e3ebdSchin
1382da2e3ebdSchin i = w_size;
1383da2e3ebdSchin
1384da2e3ebdSchin while (i-- > 0)
1385da2e3ebdSchin {
1386da2e3ebdSchin
1387da2e3ebdSchin if (*nptr == '\0')
1388da2e3ebdSchin {
1389da2e3ebdSchin *(nptr + 1) = '\0';
1390da2e3ebdSchin *nptr = ' ';
1391da2e3ebdSchin }
1392da2e3ebdSchin if (*sptr == '\0')
1393da2e3ebdSchin {
1394da2e3ebdSchin *(sptr + 1) = '\0';
1395da2e3ebdSchin *sptr = ' ';
1396da2e3ebdSchin }
1397da2e3ebdSchin if (*nptr == *sptr)
1398da2e3ebdSchin {
1399da2e3ebdSchin nptr++;
1400da2e3ebdSchin sptr++;
1401da2e3ebdSchin continue;
1402da2e3ebdSchin }
1403da2e3ebdSchin setcursor(ep,sptr-ep->screen,*nptr);
1404da2e3ebdSchin *sptr++ = *nptr++;
1405da2e3ebdSchin #if SHOPT_MULTIBYTE
1406da2e3ebdSchin while(*nptr==MARKER)
1407da2e3ebdSchin {
1408da2e3ebdSchin if(*sptr=='\0')
1409da2e3ebdSchin *(sptr + 1) = '\0';
1410da2e3ebdSchin *sptr++ = *nptr++;
1411da2e3ebdSchin i--;
1412da2e3ebdSchin ep->cursor++;
1413da2e3ebdSchin }
1414da2e3ebdSchin #endif /* SHOPT_MULTIBYTE */
1415da2e3ebdSchin }
14167c2fbfb3SApril Chin if(ep->ed->e_multiline && option == REFRESH && ep->ed->e_nocrnl==0)
14177c2fbfb3SApril Chin ed_setcursor(ep->ed, ep->screen, ep->cursor-ep->screen, ep->ed->e_peol, -1);
14187c2fbfb3SApril Chin
1419da2e3ebdSchin
1420da2e3ebdSchin /******************
1421da2e3ebdSchin
1422da2e3ebdSchin Screen overflow checks
1423da2e3ebdSchin
1424da2e3ebdSchin ********************/
1425da2e3ebdSchin
1426da2e3ebdSchin if (nscend >= &nscreen[ep->offset+w_size])
1427da2e3ebdSchin {
1428da2e3ebdSchin if (ep->offset > 0)
1429da2e3ebdSchin longline = BOTH;
1430da2e3ebdSchin else
1431da2e3ebdSchin longline = UPPER;
1432da2e3ebdSchin }
1433da2e3ebdSchin else
1434da2e3ebdSchin {
1435da2e3ebdSchin if (ep->offset > 0)
1436da2e3ebdSchin longline = LOWER;
1437da2e3ebdSchin }
1438da2e3ebdSchin
1439da2e3ebdSchin /* Update screen overflow indicator if need be */
1440da2e3ebdSchin
1441da2e3ebdSchin if (longline != ep->overflow)
1442da2e3ebdSchin {
1443da2e3ebdSchin setcursor(ep,w_size,longline);
1444da2e3ebdSchin ep->overflow = longline;
1445da2e3ebdSchin }
1446da2e3ebdSchin i = (ncursor-nscreen) - ep->offset;
1447da2e3ebdSchin setcursor(ep,i,0);
1448da2e3ebdSchin if(option==FINAL && ep->ed->e_multiline)
14497c2fbfb3SApril Chin setcursor(ep,nscend+1-nscreen,0);
1450da2e3ebdSchin ep->scvalid = 1;
1451da2e3ebdSchin return;
1452da2e3ebdSchin }
1453da2e3ebdSchin
1454da2e3ebdSchin /*
1455da2e3ebdSchin * put the cursor to the <newp> position within screen buffer
1456da2e3ebdSchin * if <c> is non-zero then output this character
1457da2e3ebdSchin * cursor is set to reflect the change
1458da2e3ebdSchin */
1459da2e3ebdSchin
setcursor(register Emacs_t * ep,register int newp,int c)1460da2e3ebdSchin static void setcursor(register Emacs_t *ep,register int newp,int c)
1461da2e3ebdSchin {
1462da2e3ebdSchin register int oldp = ep->cursor - ep->screen;
1463da2e3ebdSchin newp = ed_setcursor(ep->ed, ep->screen, oldp, newp, 0);
1464da2e3ebdSchin if(c)
1465da2e3ebdSchin {
1466da2e3ebdSchin putchar(ep->ed,c);
1467da2e3ebdSchin newp++;
1468da2e3ebdSchin }
1469da2e3ebdSchin ep->cursor = ep->screen+newp;
1470da2e3ebdSchin return;
1471da2e3ebdSchin }
1472da2e3ebdSchin
1473da2e3ebdSchin #if SHOPT_MULTIBYTE
print(register int c)1474da2e3ebdSchin static int print(register int c)
1475da2e3ebdSchin {
1476da2e3ebdSchin return((c&~STRIP)==0 && isprint(c));
1477da2e3ebdSchin }
1478da2e3ebdSchin
_isword(register int c)1479da2e3ebdSchin static int _isword(register int c)
1480da2e3ebdSchin {
1481da2e3ebdSchin return((c&~STRIP) || isalnum(c) || c=='_');
1482da2e3ebdSchin }
1483da2e3ebdSchin #endif /* SHOPT_MULTIBYTE */
1484