1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1982-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * David Korn <dgk@research.att.com> *
19 ***********************************************************************/
21 /* Original version by Michael T. Veach
22 * Adapted for ksh by David Korn */
23 /* EMACS_MODES: c tabstop=4
25 One line screen editor for any program
30 /* The following is provided by:
32 * Matthijs N. Melchior
33 * AT&T Network Systems International
38 * These are now on by default
41 * - A ^N as first history related command after the prompt will move
42 * to the next command relative to the last known history position.
43 * It will not start at the position where the last command was entered
44 * as is done by the ^P command. Every history related command will
45 * set both the current and last position. Executing a command will
46 * only set the current position.
49 * - Successive kill and delete commands will accumulate their data
50 * in the kill buffer, by appending or prepending as appropriate.
51 * This mode will be reset by any command not adding something to the
55 * - Some enhancements:
56 * - argument for a macro is passed to its replacement
57 * - ^X^H command to find out about history position (debugging)
58 * - ^X^D command to show any debugging info
60 * I do not pretend these for changes are completely independent,
61 * but you can use them to seperate features.
65 #include "FEATURE/cmds"
82 #define putchar(ed,c) ed_putchar(ed,c)
83 #define beep() ed_ringbell()
87 # define gencpy(a,b) ed_gencpy(a,b)
88 # define genncpy(a,b,n) ed_genncpy(a,b,n)
89 # define genlen(str) ed_genlen(str)
90 static int print(int);
91 static int _isword(int);
92 # define isword(c) _isword(out[c])
95 # define gencpy(a,b) strcpy((char*)(a),(char*)(b))
96 # define genncpy(a,b,n) strncpy((char*)(a),(char*)(b),n)
97 # define genlen(str) strlen(str)
98 # define print(c) isprint(c)
99 # define isword(c) (isalnum(out[c]) || (out[c]=='_'))
100 #endif /*SHOPT_MULTIBYTE */
102 typedef struct _emacs_
104 genchar
*screen
; /* pointer to window buffer */
105 genchar
*cursor
; /* Cursor in real screen */
110 char overflow
; /* Screen overflow flag set */
111 char scvalid
; /* Screen is up to date */
112 char lastdraw
; /* last update type */
113 int offset
; /* Screen offset */
116 CRT
=0, /* Crt terminal */
117 PAPER
/* Paper terminal */
121 Edit_t
*ed
; /* pointer to edit data */
124 #define editb (*ep->ed)
125 #define eol editb.e_eol
126 #define cur editb.e_cur
127 #define hline editb.e_hline
128 #define hloff editb.e_hloff
129 #define hismin editb.e_hismin
130 #define usrkill editb.e_kill
131 #define usrlnext editb.e_lnext
132 #define usreof editb.e_eof
133 #define usrerase editb.e_erase
134 #define crallowed editb.e_crlf
135 #define Prompt editb.e_prompt
136 #define plen editb.e_plen
137 #define kstack editb.e_killbuf
138 #define lstring editb.e_search
139 #define lookahead editb.e_lookahead
140 #define env editb.e_env
141 #define raw editb.e_raw
142 #define histlines editb.e_hismax
143 #define w_size editb.e_wsize
144 #define drawbuff editb.e_inbuf
145 #define killing editb.e_mode
146 #define location ep->_location
149 #define KILLCHAR UKILL
150 #define ERASECHAR UERASE
152 #define LNEXTCHAR ULNEXT
153 #define DELETE ('a'==97?0177:7)
155 /**********************
156 A large lookahead helps when the user is inserting
157 characters in the middle of the line.
158 ************************/
163 FIRST
, /* First time thru for logical line, prompt on screen */
164 REFRESH
, /* Redraw entire screen */
165 APPEND
, /* Append char before cursor to screen */
166 UPDATE
, /* Update the screen as need be */
167 FINAL
/* Update screen even if pending look ahead */
170 static void draw(Emacs_t
*,Draw_t
);
171 static int escape(Emacs_t
*,genchar
*, int);
172 static void putstring(Emacs_t
*,char*);
173 static void search(Emacs_t
*,genchar
*,int);
174 static void setcursor(Emacs_t
*,int, int);
175 static void show_info(Emacs_t
*,const char*);
176 static void xcommands(Emacs_t
*,int);
178 int ed_emacsread(void *context
, int fd
,char *buff
,int scend
, int reedit
)
180 Edit_t
*ed
= (Edit_t
*)context
;
183 register genchar
*out
;
185 register Emacs_t
*ep
= ed
->e_emacs
;
190 genchar Screen
[MAXLINE
];
193 ep
= ed
->e_emacs
= newof(0,Emacs_t
,1,0);
195 ep
->prevdirection
= 1;
196 location
.hist_command
= -5;
200 ep
->lastdraw
= FINAL
;
201 if(tty_raw(ERRIO
,0) < 0)
203 return(reedit
?reedit
:ed_read(context
, fd
,buff
,scend
,0));
206 /* This mess in case the read system call fails */
208 ed_setup(ep
->ed
,fd
,reedit
);
209 out
= (genchar
*)buff
;
211 out
= (genchar
*)roundof(buff
-(char*)0,sizeof(genchar
));
213 ed_internal(buff
,out
);
214 #endif /* SHOPT_MULTIBYTE */
217 kstack
= (genchar
*)malloc(CHARSIZE
*MAXLINE
);
222 if (location
.hist_command
== -5) /* to be initialized */
224 kstack
[0] = '\0'; /* also clear kstack... */
225 location
.hist_command
= hline
;
226 location
.hist_line
= hloff
;
228 if (location
.hist_command
<= hismin
) /* don't start below minimum */
230 location
.hist_command
= hismin
+ 1;
231 location
.hist_line
= 0;
233 ep
->in_mult
= hloff
; /* save pos in last command */
234 #endif /* ESH_NFIRST */
235 i
= sigsetjmp(env
,0);
238 if(ep
->ed
->e_multiline
)
249 return(-1); /* some other error */
252 if(scend
+plen
> (MAXLINE
-2))
253 scend
= (MAXLINE
-2)-plen
;
256 draw(ep
,reedit
?REFRESH
:FIRST
);
262 ed_ungetchar(ep
->ed
,cntl('N'));
264 location
= hist_locate(sh
.hist_ptr
,location
.hist_command
,location
.hist_line
,1);
265 if (location
.hist_command
< histlines
)
267 hline
= location
.hist_command
;
268 hloff
= location
.hist_line
;
269 hist_copy((char*)kstack
,MAXLINE
, hline
,hloff
);
271 ed_internal((char*)kstack
,kstack
);
272 # endif /* SHOPT_MULTIBYTE */
273 ed_ungetchar(ep
->ed
,cntl('Y'));
275 #endif /* ESH_NFIRST */
278 while ((c
= ed_getchar(ep
->ed
,0)) != (-1))
283 if (c
==usrerase
||c
==usrkill
||(!print(c
) &&
286 /* accept a backslashed character */
298 else if (c
== usrerase
)
302 else if (c
== usrlnext
)
306 else if ((c
== usreof
)&&(eol
== 0))
311 if (--killing
<= 0) /* reset killing flag */
314 oadjust
= count
= adjust
;
322 c
= ed_getchar(ep
->ed
,2);
323 goto do_default_processing
;
325 show_info(ep
,fmtident(e_version
));
343 if(cur
>0 && ep
->ed
->sh
->nextprompt
)
345 if(ep
->ed
->e_tabcount
==0)
347 ep
->ed
->e_tabcount
=1;
348 ed_ungetchar(ep
->ed
,ESC
);
351 else if(ep
->ed
->e_tabcount
==1)
353 ed_ungetchar(ep
->ed
,'=');
356 ep
->ed
->e_tabcount
= 0;
358 do_default_processing
:
361 if ((eol
+1) >= (scend
)) /* will not fit on line */
363 ed_ungetchar(ep
->ed
,c
); /* save character for next line */
366 for(i
= ++eol
; i
>cur
; i
--)
368 backslash
= (c
== '\\');
375 if ((c
+ eol
) > scend
)
381 for(i
=eol
;i
>=cur
;i
--)
395 case DELETE
: /* delete char 0x7f */
396 case '\b': /* backspace, ^h */
401 kptr
= &kstack
[count
]; /* move old contents here */
402 if (killing
) /* prepend to killbuf */
404 c
= genlen(kstack
) + CHARSIZE
; /* include '\0' */
405 while(c
--) /* copy stuff */
409 *kptr
= 0; /* this is end of data */
410 killing
= 2; /* we are killing */
413 genncpy(kstack
,out
+i
,cur
-i
);
415 while ((count
--)&&(i
>0))
420 genncpy(kstack
,out
+i
,cur
-i
);
422 #endif /* ESH_KAPPEND */
423 gencpy(out
+i
,out
+cur
);
428 ++killing
; /* keep killing flag */
436 adjust
= ep
->mark
- i
;
437 ed_ungetchar(ep
->ed
,cntl('D'));
440 adjust
= i
- ep
->mark
;
441 ed_ungetchar(ep
->ed
,usrerase
);
447 kptr
= &kstack
[genlen(kstack
)]; /* append here */
450 killing
= 2; /* we are now killing */
453 #endif /* ESH_KAPPEND */
454 while ((count
--)&&(eol
>0)&&(i
<eol
))
460 if ((out
[i
] = out
[(i
+1)])==0)
471 int cntlC
= (c
==cntl('C'));
472 while (count
-- && eol
>i
)
478 if((c
&~STRIP
)==0 && islower(c
))
481 #endif /* SHOPT_MULTIBYTE */
492 c
= ed_getchar(ep
->ed
,1);
493 if ((count
== 0) || (count
> eol
))
502 if (out
[i
] == c
&& --count
==0)
509 if (out
[i
] == c
&& --count
==0)
525 if ((sh_isoption(SH_EMACS
))&& (eol
!=i
))
535 if(sh_isoption(SH_EMACS
))
557 killing
= 2; /* set killing signal */
560 ed_ungetchar(ep
->ed
,cntl('W'));
567 if (killing
) /* append to kill buffer */
568 gencpy(&kstack
[genlen(kstack
)], &out
[i
]);
570 gencpy(kstack
,&out
[i
]);
571 killing
= 2; /* set killing signal */
573 gencpy(kstack
,&out
[i
]);
574 #endif /* ESH_KAPPEND */
579 if (ep
->terminal
== PAPER
)
581 putchar(ep
->ed
,'\n');
582 putstring(ep
,Prompt
);
584 c
= ed_getchar(ep
->ed
,0);
587 ed_ungetchar(ep
->ed
,c
);
590 if (ep
->terminal
== PAPER
)
594 ep
->terminal
= PAPER
;
595 putchar(ep
->ed
,'\n');
596 putstring(ep
,Prompt
);
601 if(!ep
->ed
->e_nocrnl
)
604 ep
->ed
->e_nocrnl
= 0;
608 adjust
= escape(ep
,out
,oadjust
);
611 search(ep
,out
,count
);
618 hline
-= count
- hloff
;
625 #endif /* ESH_NFIRST */
636 location
.hist_command
= hline
;
637 location
.hist_line
= hloff
;
643 hline
= location
.hist_command
; /* start at saved position */
644 hloff
= location
.hist_line
;
645 #endif /* ESH_NFIRST */
646 location
= hist_locate(sh
.hist_ptr
,hline
,hloff
,count
);
647 if (location
.hist_command
> histlines
)
651 location
.hist_command
= histlines
;
652 location
.hist_line
= ep
->in_mult
;
655 #endif /* ESH_NFIRST */
657 hline
= location
.hist_command
;
658 hloff
= location
.hist_line
;
661 location
.hist_command
= hline
; /* save current position */
662 location
.hist_line
= hloff
;
666 hist_copy((char*)out
,MAXLINE
, hline
,hloff
);
668 ed_internal((char*)(out
),out
);
669 #endif /* SHOPT_MULTIBYTE */
692 stakset(ed
->e_stkptr
,ed
->e_stkoff
);
701 ed_external(out
,buff
);
702 #endif /* SHOPT_MULTIBYTE */
709 static void show_info(Emacs_t
*ep
,const char *str
)
711 register genchar
*out
= drawbuff
;
713 genchar string
[LBUF
];
715 /* save current line */
716 genncpy(string
,out
,sizeof(string
)/sizeof(*string
));
720 ed_internal(str
,out
);
723 #endif /* SHOPT_MULTIBYTE */
725 c
= ed_getchar(ep
->ed
,0);
727 ed_ungetchar(ep
->ed
,c
);
730 genncpy(out
,string
,sizeof(string
)/sizeof(*string
));
734 static void putstring(Emacs_t
* ep
,register char *sp
)
742 static int escape(register Emacs_t
* ep
,register genchar
*out
,int count
)
744 register int i
,value
;
748 while ((i
=ed_getchar(ep
->ed
,0)),isdigit(i
))
756 ed_ungetchar(ep
->ed
,i
) ;
758 ++killing
; /* don't modify killing signal */
768 show_info(ep
,fmtident(e_version
));
775 case '+': /* M-+ = append next kill */
777 return -1; /* no argument for next command */
780 case 'p': /* M-p == ^W^Y (copy stack == kill & yank) */
781 ed_ungetchar(ep
->ed
,cntl('Y'));
782 ed_ungetchar(ep
->ed
,cntl('W'));
784 killing
= 0; /* start fresh */
788 case 'l': /* M-l == lower-case */
794 while(value
-- && i
<eol
)
796 while ((out
[i
])&&(!isword(i
)))
798 while ((out
[i
])&&(isword(i
)))
808 if((i
&~STRIP
)==0 && isupper(i
))
811 #endif /* SHOPT_MULTIBYTE */
826 ed_ungetchar(ep
->ed
,cntl('C'));
833 ed_ungetchar(ep
->ed
,cntl('D'));
835 ++killing
; /* keep killing signal */
851 while(value
-- && i
>0)
854 while ((i
>0)&&(!isword(i
)))
856 while ((i
>0)&&(isword(i
-1)))
863 ed_ungetchar(ep
->ed
,usrerase
);
872 ed_ungetchar(ep
->ed
,cntl('N'));
876 location
.hist_command
= histlines
;
877 location
.hist_line
= ep
->in_mult
- 1;
881 location
.hist_command
= histlines
- 1;
882 location
.hist_line
= 0;
887 #endif /* ESH_NFIRST */
891 ed_ungetchar(ep
->ed
,cntl('P'));
897 return(hline
-hismin
);
898 #endif /* ESH_NFIRST */
902 ed_ungetchar(ep
->ed
,'\n');
903 ed_ungetchar(ep
->ed
,(out
[0]=='#')?cntl('D'):'#');
904 ed_ungetchar(ep
->ed
,cntl('A'));
909 genchar name
[MAXLINE
];
912 ptr
= hist_word(buf
,MAXLINE
,(count
?count
:-1));
918 if ((eol
- cur
) >= sizeof(name
))
924 gencpy(name
,&out
[cur
]);
930 gencpy(&out
[cur
],name
);
936 /* file name expansion */
937 case cntl('[') : /* filename completion */
939 case '*': /* filename expansion */
940 case '=': /* escape = - list all matching file names */
942 if(ed_expand(ep
->ed
,(char*)out
,&cur
,&eol
,i
,count
) < 0)
944 if(ep
->ed
->e_tabcount
==1)
946 ep
->ed
->e_tabcount
=2;
947 ed_ungetchar(ep
->ed
,cntl('\t'));
956 ep
->ed
->e_tabcount
=0;
959 i
=ed_getchar(ep
->ed
,0);
960 ed_ungetchar(ep
->ed
,i
);
962 ed_ungetchar(ep
->ed
,ESC
);
967 if(i
=='\\' && cur
>ep
->mark
&& (out
[cur
-1]=='/' || out
[cur
-1]==' '))
968 ep
->ed
->e_tabcount
=0;
973 /* search back for character */
974 case cntl(']'): /* feature not in book */
976 int c
= ed_getchar(ep
->ed
,1);
977 if ((value
== 0) || (value
> eol
))
987 if (out
[i
] == c
&& --value
==0)
994 if (out
[i
] == c
&& --value
==0)
1006 case cntl('L'): /* clear screen */
1007 sh_trap("tput clear", 0);
1011 case '[': /* feature not in book */
1012 switch(i
=ed_getchar(ep
->ed
,1))
1015 if(cur
>0 && eol
==cur
&& (cur
<(SEARCHSIZE
-2) || ep
->prevdirection
== -2))
1017 if(ep
->lastdraw
==APPEND
&& ep
->prevdirection
!= -2)
1020 gencpy(&((genchar
*)lstring
)[1],out
);
1022 ed_external(&((genchar
*)lstring
)[1],lstring
+1);
1023 #endif /* SHOPT_MULTIBYTE */
1025 ep
->prevdirection
= -2;
1029 ed_ungetchar(ep
->ed
,'\r');
1030 ed_ungetchar(ep
->ed
,cntl('R'));
1035 ed_ungetchar(ep
->ed
,cntl('P'));
1038 ed_ungetchar(ep
->ed
,cntl('N'));
1041 ed_ungetchar(ep
->ed
,cntl('F'));
1044 ed_ungetchar(ep
->ed
,cntl('B'));
1047 ed_ungetchar(ep
->ed
,cntl('A'));
1050 ed_ungetchar(ep
->ed
,cntl('E'));
1053 ed_ungetchar(ep
->ed
,i
);
1058 /* look for user defined macro definitions */
1059 if(ed_macro(ep
->ed
,i
))
1061 return(count
); /* pass argument to macro */
1064 # endif /* ESH_BETTER */
1081 * This routine process all commands starting with ^X
1084 static void xcommands(register Emacs_t
*ep
,int count
)
1086 register int i
= ed_getchar(ep
->ed
,0);
1090 case cntl('X'): /* exchange dot and mark */
1101 case cntl('E'): /* invoke emacs on current command */
1102 if(ed_fulledit(ep
->ed
)==-1)
1107 ed_internal((char*)drawbuff
,drawbuff
);
1108 #endif /* SHOPT_MULTIBYTE */
1109 ed_ungetchar(ep
->ed
,'\n');
1113 # define itos(i) fmtbase((long)(i),0,0)/* want signed conversion */
1115 case cntl('H'): /* ^X^H show history info */
1119 strcpy(hbuf
, "Current command ");
1120 strcat(hbuf
, itos(hline
));
1123 strcat(hbuf
, " (line ");
1124 strcat(hbuf
, itos(hloff
+1));
1127 if ((hline
!= location
.hist_command
) ||
1128 (hloff
!= location
.hist_line
))
1130 strcat(hbuf
, "; Previous command ");
1131 strcat(hbuf
, itos(location
.hist_command
));
1132 if (location
.hist_line
)
1134 strcat(hbuf
, " (line ");
1135 strcat(hbuf
, itos(location
.hist_line
+1));
1142 # if 0 /* debugging, modify as required */
1143 case cntl('D'): /* ^X^D show debugging info */
1145 char debugbuf
[MAXLINE
];
1147 strcpy(debugbuf
, "count=");
1148 strcat(debugbuf
, itos(count
));
1149 strcat(debugbuf
, " eol=");
1150 strcat(debugbuf
, itos(eol
));
1151 strcat(debugbuf
, " cur=");
1152 strcat(debugbuf
, itos(cur
));
1153 strcat(debugbuf
, " crallowed=");
1154 strcat(debugbuf
, itos(crallowed
));
1155 strcat(debugbuf
, " plen=");
1156 strcat(debugbuf
, itos(plen
));
1157 strcat(debugbuf
, " w_size=");
1158 strcat(debugbuf
, itos(w_size
));
1160 show_info(ep
,debugbuf
);
1163 # endif /* debugging code */
1164 # endif /* ESH_BETTER */
1173 static void search(Emacs_t
* ep
,genchar
*out
,int direction
)
1179 genchar str_buff
[LBUF
];
1180 register genchar
*string
= drawbuff
;
1181 /* save current line */
1183 genncpy(str_buff
,string
,sizeof(str_buff
)/sizeof(*str_buff
));
1190 while ((i
= ed_getchar(ep
->ed
,1))&&(i
!= '\r')&&(i
!= '\n'))
1192 if (i
==usrerase
|| i
==DELETE
|| i
=='\b' || i
==ERASECHAR
)
1196 string
[--sl
] = '\0';
1211 string
[sl
++] = '\\';
1215 i
= ed_getchar(ep
->ed
,1);
1216 string
[--sl
] = '\0';
1225 if(ep
->prevdirection
== -2 && i
!=2 || direction
!=1)
1226 ep
->prevdirection
= -1;
1229 ep
->prevdirection
= -ep
->prevdirection
;
1237 ed_external(string
,(char*)string
);
1238 #endif /* SHOPT_MULTIBYTE */
1239 strncpy(lstring
,((char*)string
)+2,SEARCHSIZE
);
1240 ep
->prevdirection
= direction
;
1243 direction
= ep
->prevdirection
;
1244 location
= hist_find(sh
.hist_ptr
,(char*)lstring
,hline
,1,direction
);
1245 i
= location
.hist_command
;
1250 hloff
= location
.hist_line
= 0; /* display first line of multi line command */
1252 hloff
= location
.hist_line
;
1253 #endif /* ESH_NFIRST */
1254 hist_copy((char*)out
,MAXLINE
, hline
,hloff
);
1256 ed_internal((char*)out
,out
);
1257 #endif /* SHOPT_MULTIBYTE */
1264 location
.hist_command
= hline
;
1265 location
.hist_line
= hloff
;
1269 #endif /* ESH_NFIRST */
1272 genncpy(string
,str_buff
,sizeof(str_buff
)/sizeof(*str_buff
));
1278 /* Adjust screen to agree with inputs: logical line and cursor */
1279 /* If 'first' assume screen is blank */
1280 /* Prompt is always kept on the screen */
1282 static void draw(register Emacs_t
*ep
,Draw_t option
)
1289 register genchar
*sptr
; /* Pointer within screen */
1290 genchar nscreen
[2*MAXLINE
]; /* New entire screen */
1291 genchar
*ncursor
; /* New cursor */
1292 register genchar
*nptr
; /* Pointer to New screen */
1293 char longline
; /* Line overflow */
1295 genchar
*nscend
; /* end of logical screen */
1300 logcursor
= sptr
+ cur
;
1302 ep
->lastdraw
= option
;
1304 if (option
== FIRST
|| option
== REFRESH
)
1306 ep
->overflow
= NORMAL
;
1307 ep
->cursor
= ep
->screen
;
1309 ep
->cr_ok
= crallowed
;
1310 if (option
== FIRST
)
1316 putstring(ep
,Prompt
); /* start with prompt */
1319 /*********************
1320 Do not update screen if pending characters
1321 **********************/
1323 if ((lookahead
)&&(option
!= FINAL
))
1326 ep
->scvalid
= 0; /* Screen is out of date, APPEND will not work */
1331 /***************************************
1332 If in append mode, cursor at end of line, screen up to date,
1333 the previous character was a 'normal' character,
1334 and the window has room for another character.
1335 Then output the character and adjust the screen only.
1336 *****************************************/
1339 i
= *(logcursor
-1); /* last character inserted */
1341 if ((option
== APPEND
)&&(ep
->scvalid
)&&(*logcursor
== '\0')&&
1342 print(i
)&&((ep
->cursor
-ep
->screen
)<(w_size
-1)))
1351 ncursor
= nptr
+ ed_virt_to_phys(ep
->ed
,sptr
,nptr
,cur
,0,0);
1352 nptr
+= genlen(nptr
);
1353 sptr
+= genlen(sptr
);
1355 if(sptr
== logcursor
)
1358 /*********************
1359 Does ncursor appear on the screen?
1360 If not, adjust the screen offset so it does.
1361 **********************/
1363 i
= ncursor
- nscreen
;
1365 if ((ep
->offset
&& i
<=ep
->offset
)||(i
>= (ep
->offset
+w_size
)))
1367 /* Center the cursor on the screen */
1368 ep
->offset
= i
- (w_size
>>1);
1369 if (--ep
->offset
< 0)
1373 /*********************
1374 Is the range of screen[0] thru screen[w_size] up-to-date
1375 with nscreen[offset] thru nscreen[offset+w_size] ?
1376 If not, update as need be.
1377 ***********************/
1379 nptr
= &nscreen
[ep
->offset
];
1403 setcursor(ep
,sptr
-ep
->screen
,*nptr
);
1406 while(*nptr
==MARKER
)
1414 #endif /* SHOPT_MULTIBYTE */
1416 if(ep
->ed
->e_multiline
&& option
== REFRESH
&& ep
->ed
->e_nocrnl
==0)
1417 ed_setcursor(ep
->ed
, ep
->screen
, ep
->cursor
-ep
->screen
, ep
->ed
->e_peol
, -1);
1422 Screen overflow checks
1424 ********************/
1426 if (nscend
>= &nscreen
[ep
->offset
+w_size
])
1439 /* Update screen overflow indicator if need be */
1441 if (longline
!= ep
->overflow
)
1443 setcursor(ep
,w_size
,longline
);
1444 ep
->overflow
= longline
;
1446 i
= (ncursor
-nscreen
) - ep
->offset
;
1448 if(option
==FINAL
&& ep
->ed
->e_multiline
)
1449 setcursor(ep
,nscend
+1-nscreen
,0);
1455 * put the cursor to the <newp> position within screen buffer
1456 * if <c> is non-zero then output this character
1457 * cursor is set to reflect the change
1460 static void setcursor(register Emacs_t
*ep
,register int newp
,int c
)
1462 register int oldp
= ep
->cursor
- ep
->screen
;
1463 newp
= ed_setcursor(ep
->ed
, ep
->screen
, oldp
, newp
, 0);
1469 ep
->cursor
= ep
->screen
+newp
;
1474 static int print(register int c
)
1476 return((c
&~STRIP
)==0 && isprint(c
));
1479 static int _isword(register int c
)
1481 return((c
&~STRIP
) || isalnum(c
) || c
=='_');
1483 #endif /* SHOPT_MULTIBYTE */