62 #define SCREEN_WIDTH 80
63 #define SCREEN_ROWS 24
67 #define CTL(x) (char)((x) & 0x1F)
68 #define ISCTL(x) ((x) && (x) < ' ')
69 #define UNCTL(x) (char)((x) + 64)
70 #define META(x) (char)((x) | 0x80)
71 #define ISMETA(x) ((x) & 0x80)
72 #define UNMETA(x) (char)((x) & 0x7F)
75 int editline_histsize=256;
78 EL_USER_COMPLETION_FUNCTION_TYPE*el_user_completion_function = NULL;
84 TOupper, TOlower, TOcapitalize
90 typedef struct _KEYMAP {
98 typedef struct _HISTORY {
113 extern CONST ECHAR *el_Input;
114 STATIC ECHAR *Line = NULL;
115 STATIC CONST
char *Prompt = NULL;
116 STATIC ECHAR *Yanked = NULL;
117 STATIC
char *Screen = NULL;
126 extern int el_PushBack;
127 extern int el_Pushed;
128 FORWARD KEYMAP Map[33];
129 FORWARD KEYMAP MetaMap[64];
130 STATIC ESIZE_T Length;
131 STATIC ESIZE_T ScreenCount;
132 STATIC ESIZE_T ScreenSize;
133 STATIC ECHAR *backspace = NULL;
134 STATIC ECHAR *upline = NULL;
135 STATIC ECHAR *clrpage = NULL;
136 STATIC ECHAR *downline = NULL;
137 STATIC ECHAR *move_right = NULL;
138 STATIC ECHAR *newline = NULL;
139 STATIC ECHAR *bol = NULL;
140 STATIC ECHAR *nextline = NULL;
143 STATIC
int RequireNLforWrap = 1;
144 STATIC
int el_intr_pending = 0;
148 extern void TTYflush();
149 STATIC
void TTYput(ECHAR c);
150 STATIC
void TTYputs(ECHAR *p);
151 STATIC
void TTYshow(ECHAR c);
152 STATIC
void TTYstring(ECHAR *p);
153 extern unsigned int TTYget();
154 STATIC
void TTYinfo();
155 STATIC
void print_columns(
int ac,
char **av);
156 STATIC
void reposition(
int reset);
157 STATIC
void left(STATUS Change);
158 STATIC
void right(STATUS Change);
159 STATIC STATUS ring_bell();
161 STATIC STATUS do_macro(
unsigned int c);
163 STATIC STATUS do_forward(STATUS move);
164 STATIC STATUS do_case(ECHAR type);
165 STATIC STATUS case_down_word();
166 STATIC STATUS case_up_word();
168 STATIC
void clear_line();
169 STATIC STATUS insert_string(ECHAR *p);
170 STATIC ECHAR *next_hist();
171 STATIC ECHAR *prev_hist();
172 STATIC STATUS do_insert_hist(ECHAR *p);
173 STATIC STATUS do_hist(ECHAR *(*move)());
174 STATIC STATUS h_next();
175 STATIC STATUS h_prev();
176 STATIC STATUS h_first();
177 STATIC STATUS h_last();
178 STATIC
int substrcmp(
char *text,
char *pat,
int len);
179 STATIC ECHAR *search_hist(ECHAR *search, ECHAR *(*move)());
180 STATIC STATUS h_search();
181 STATIC STATUS fd_char();
182 STATIC
void save_yank(
int begin,
int i);
183 STATIC STATUS delete_string(
int count);
184 STATIC STATUS bk_char();
185 STATIC STATUS bk_del_char();
186 STATIC STATUS redisplay();
187 STATIC STATUS kill_line();
188 STATIC
char *rsearch_hist(
char *patt,
int *lpos,
int *cpos);
189 STATIC STATUS h_risearch();
190 STATIC STATUS insert_char(
int c);
191 STATIC STATUS meta();
192 STATIC STATUS emacs(
unsigned int c);
193 STATIC STATUS TTYspecial(
unsigned int c);
194 STATIC ECHAR *editinput();
195 STATIC
void hist_add(ECHAR *p);
196 STATIC STATUS beg_line();
197 STATIC STATUS del_char();
198 STATIC STATUS end_line();
199 STATIC ECHAR *find_word();
200 STATIC STATUS c_complete();
201 STATIC STATUS c_possible();
202 STATIC STATUS accept_line();
203 STATIC STATUS transpose();
204 STATIC STATUS quote();
205 STATIC STATUS wipe();
206 STATIC STATUS mk_set();
207 STATIC STATUS exchange();
208 STATIC STATUS yank();
209 STATIC STATUS copy_region();
210 STATIC STATUS move_to_char();
211 STATIC STATUS fd_word();
212 STATIC STATUS fd_kill_word();
213 STATIC STATUS bk_word();
214 STATIC STATUS bk_kill_word();
215 STATIC
int argify(ECHAR *line, ECHAR ***avp);
216 STATIC STATUS last_argument();
219 int rl_meta_chars = 0;
224 STATIC ECHAR *editinput();
225 #if defined(USE_TERMCAP)
226 extern char *getenv();
227 extern char *tgetstr();
228 extern int tgetent();
229 extern int tgetnum();
240 (void)write(1, Screen, ScreenCount);
245 STATIC
void TTYput(ECHAR c)
247 Screen[ScreenCount] = c;
248 if (++ScreenCount >= ScreenSize - 1) {
249 ScreenSize += SCREEN_INC;
250 RENEW(Screen,
char, ScreenSize);
254 STATIC
void TTYputs(ECHAR *p)
260 STATIC
void TTYshow(ECHAR c)
270 else if (rl_meta_chars && ISMETA(c)) {
279 STATIC
void TTYstring(ECHAR *p)
287 #define TTYback() (backspace ? TTYputs((ECHAR *)backspace) : TTYput('\b'))
290 STATIC
int printlen(CONST
char *p)
295 if ((*p == DEL) || (ISCTL(*p)))
297 else if (rl_meta_chars && ISMETA(*p))
305 STATIC
int screen_pos()
309 int p = strlen(Prompt);
312 for (i=0; i < Point; i++)
313 if ((Line[i] == DEL) ||
316 else if (rl_meta_chars && ISMETA(Line[i]))
324 STATIC
void TTYback()
328 int sp = screen_pos();
330 if (upline && sp && (sp%TTYwidth == 0))
334 for (i=0; i < TTYwidth; i++)
338 TTYputs((ECHAR *)backspace);
343 STATIC
void TTYinfo()
346 #if defined(USE_TERMCAP)
352 #if defined(TIOCGWINSZ)
357 #if defined(TIOCGWINSZ)
359 if (ioctl(0, TIOCGWINSZ, &W) >= 0
360 && W.ws_col > 0 && W.ws_row > 0) {
361 TTYwidth = (int)W.ws_col;
362 TTYrows = (
int)W.ws_row;
369 TTYwidth = TTYrows = 0;
370 #if defined(USE_TERMCAP)
371 buff = walloc(
char,2048);
372 buff2 = walloc(
char,2048);
374 if ((term = getenv(
"TERM")) == NULL)
376 if (tgetent(buff, term) < 0) {
377 TTYwidth = SCREEN_WIDTH;
378 TTYrows = SCREEN_ROWS;
381 backspace = (ECHAR *)tgetstr(
"le", &bp);
382 upline = (ECHAR *)tgetstr(
"up", &bp);
383 clrpage = (ECHAR *)tgetstr(
"cl", &bp);
384 nextline = (ECHAR *)tgetstr(
"nl", &bp);
386 nextline = (ECHAR *)
"\n";
387 if (strncmp(term,
"pcansi", 6)==0 || strncmp(term,
"cygwin", 6)==0)
389 bol = (ECHAR *)
"\033[0G";
390 RequireNLforWrap = 0;
393 bol = (ECHAR *)tgetstr(
"cr", &bp);
397 newline= walloc(ECHAR, 20);
398 strcpy((
char *)newline,(
char *)bol);
399 strcat((
char *)newline,(
char *)nextline);
401 downline = (ECHAR *)newline;
402 move_right = (ECHAR *)tgetstr(
"nd", &bp);
403 if (!move_right || !downline)
405 TTYwidth = tgetnum(
"co");
406 TTYrows = tgetnum(
"li");
409 #if defined(TIOCGWINSZ)
410 if (ioctl(0, TIOCGWINSZ, &W) >= 0) {
411 TTYwidth = (int)W.ws_col;
412 TTYrows = (
int)W.ws_row;
416 if (TTYwidth <= 0 || TTYrows <= 0) {
417 TTYwidth = SCREEN_WIDTH;
418 TTYrows = SCREEN_ROWS;
426 STATIC
void print_columns(
int ac,
char **av)
440 TTYputs((ECHAR *)newline);
441 sprintf(info1,
"There are %d possibilities. Do you really \n",ac);
442 TTYputs((ECHAR *)info1);
443 TTYputs((ECHAR *)
"want to see them all (y/n) ? ");
444 while (((c = TTYget()) != EOF) && ((strchr(
"YyNn ",c) == NULL)))
446 if (strchr(
"Nn",c) != NULL)
448 TTYputs((ECHAR *)newline);
454 for (longest = 0, i = 0; i < ac; i++)
455 if ((j = strlen((
char *)av[i])) > longest)
457 cols = TTYwidth / (longest + 3);
458 if (cols < 1) cols = 1;
460 TTYputs((ECHAR *)newline);
461 for (skip = ac / cols + 1, i = 0; i < skip; i++) {
462 for (j = i; j < ac; j += skip) {
463 for (p = (ECHAR *)av[j], len = strlen((
char *)p), k = len;
467 while (++len < longest + 3)
470 TTYputs((ECHAR *)newline);
474 STATIC
void reposition(
int reset)
483 for (i=screen_pos()/TTYwidth; i > 0; i--)
484 if (upline) TTYputs(upline);
486 TTYputs((ECHAR *)Prompt);
487 pos = printlen(Prompt);
489 for (i = 0; i < End; i++)
493 pos += printlen(ppp);
494 if ((pos%TTYwidth) == 0)
495 if (RequireNLforWrap && downline) TTYputs(downline);
502 if (rl_meta_chars && ISMETA(Line[Point]))
507 else if (ISCTL(Line[Point]))
514 STATIC
void left(STATUS Change)
518 if (ISCTL(Line[Point - 1]))
520 else if (rl_meta_chars && ISMETA(Line[Point - 1])) {
525 if (Change == CSmove)
529 STATIC
void right(STATUS Change)
531 TTYshow(Line[Point]);
532 if (Change == CSmove)
534 if ((screen_pos())%TTYwidth == 0)
535 if (downline && RequireNLforWrap) TTYputs(downline);
538 STATIC STATUS ring_bell()
546 STATIC STATUS do_macro(
unsigned int c)
555 if ((el_Input = (ECHAR *)getenv((
char *)name)) == NULL) {
563 STATIC STATUS do_forward(STATUS move)
572 for ( ; Point < End && (*p ==
' ' || !isalnum(*p)); p++)
575 for (; Point < End && isalnum(*p); p++)
580 }
while (++i < Repeat);
585 STATIC STATUS do_case(ECHAR type)
594 (void)do_forward(CSstay);
596 if ((count = Point - OP) < 0)
598 for ( ; Point > OP; Point --)
600 if ((end = Point + count) > End)
602 for (i = Point, p = &Line[Point]; Point < end; p++) {
603 if ((type == TOupper) ||
604 ((type == TOcapitalize) && (Point == i)))
609 else if (isupper(*p))
617 STATIC STATUS case_down_word()
619 return do_case(TOlower);
622 STATIC STATUS case_up_word()
624 return do_case(TOupper);
627 STATIC STATUS case_cap_word()
629 return do_case(TOcapitalize);
639 for (extras = 0, i = Point, p = &Line[i]; i < End; i++, p++) {
646 else if (rl_meta_chars && ISMETA(*p)) {
651 else if ((screen_pos())%TTYwidth == 0)
652 if (downline && RequireNLforWrap) TTYputs(downline);
660 if (rl_meta_chars && ISMETA(Line[Point-1]))
665 else if (ISCTL(Line[Point-1]))
673 STATIC
void clear_line()
677 for (i=screen_pos()/TTYwidth; i > 0; i--)
678 if (upline) TTYputs(upline);
679 for (i=0; i < strlen(Prompt); i++)
685 for (i=screen_pos()/TTYwidth; i > 0; i--)
686 if (upline) TTYputs(upline);
692 STATIC STATUS insert_string(ECHAR *p)
699 len = strlen((
char *)p);
700 if (End + len >= Length) {
701 if ((
new = NEW(ECHAR, Length + len + MEM_INC)) == NULL)
704 COPYFROMTO(
new, Line, Length);
708 Length += len + MEM_INC;
711 for (q = &Line[Point], i = End - Point; --i >= 0; )
713 COPYFROMTO(&Line[Point], p, len);
717 pos1 = printlen((
char *)&Line[Point]);
718 TTYstring(&Line[Point]);
720 if ((pos0+pos1)%TTYwidth == 0)
721 if (downline && RequireNLforWrap) TTYputs(downline);
725 if (upline && (Point != End))
728 pos1 = printlen((
char *)&Line[Point]);
729 for (i=((pos0%TTYwidth)+pos1)/TTYwidth; i > 0; i--)
730 if (upline) TTYputs(upline);
732 for (i=0 ; i < (pos0%TTYwidth); i++)
736 return Point == End ? CSstay : CSmove;
740 STATIC ECHAR *next_hist()
742 return H.Pos >= H.Size - 1 ? NULL : H.Lines[++H.Pos];
745 STATIC ECHAR *prev_hist()
747 return H.Pos == 0 ? NULL : H.Lines[--H.Pos];
750 STATIC STATUS do_insert_hist(ECHAR *p)
755 for (i=screen_pos()/TTYwidth; i > 0; i--)
756 if (upline) TTYputs(upline);
761 return insert_string(p);
764 STATIC STATUS do_hist(ECHAR *(*move)())
771 if ((p = (*move)()) == NULL)
773 }
while (++i < Repeat);
774 return do_insert_hist(p);
777 STATIC STATUS h_next()
779 return do_hist(next_hist);
782 STATIC STATUS h_prev()
784 return do_hist(prev_hist);
787 STATIC STATUS h_first()
789 return do_insert_hist(H.Lines[H.Pos = 0]);
792 STATIC STATUS h_last()
794 return do_insert_hist(H.Lines[H.Pos = H.Size - 1]);
800 STATIC
int substrcmp(
char *text,
char *pat,
int len)
804 if ((c = *pat) ==
'\0')
805 return *text ==
'\0';
806 for ( ; *text; text++)
807 if (*text == c && strncmp(text, pat, len) == 0)
812 STATIC ECHAR *search_hist(ECHAR *search, ECHAR *(*move)())
814 static ECHAR *old_search;
821 if (search && *search) {
824 old_search = (ECHAR *)STRDUP((
const char *)search);
827 if (old_search == NULL || *old_search ==
'\0')
833 if (*search ==
'^') {
835 pat = (
char *)(search + 1);
839 pat = (
char *)search;
843 for (pos = H.Pos; (*move)() != NULL; )
844 if ((*match)((
char *)H.Lines[H.Pos], pat, len) == 0)
845 return H.Lines[H.Pos];
850 STATIC STATUS h_search()
852 static int Searching;
853 CONST
char *old_prompt;
864 TTYputs((ECHAR *)Prompt);
865 move = Repeat == NO_ARG ? prev_hist : next_hist;
866 p = search_hist(editinput(), move);
869 TTYputs((ECHAR *)Prompt);
872 return do_insert_hist(p);
875 STATIC STATUS fd_char()
884 }
while (++i < Repeat);
888 STATIC
void save_yank(
int begin,
int i)
898 if ((Yanked = NEW(ECHAR, (ESIZE_T)i + 1)) != NULL) {
899 COPYFROMTO(Yanked, &Line[begin], i);
904 STATIC STATUS delete_string(
int count)
910 if (count <= 0 || End == Point)
913 if (Point + count > End && (count = End - Point) <= 0)
917 save_yank(Point, count);
919 tLine = STRDUP((
char *)Line);
921 for (q = Point, i = End - (Point + count) + 1; --i >= 0; q++)
922 Line[q] = tLine[q+count];
926 pos1 = printlen((
char *)&Line[Point]);
927 TTYstring(&Line[Point]);
928 if ((pos1 > 0) && (pos0+pos1)%TTYwidth == 0)
929 if (downline && RequireNLforWrap) TTYputs(downline);
935 for (i=((pos0%TTYwidth)+pos1)/TTYwidth; i > 0; i--)
936 if (upline) TTYputs(upline);
938 for (i=0 ; i < (pos0%TTYwidth); i++)
945 STATIC STATUS bk_char()
954 }
while (++i < Repeat);
959 STATIC STATUS bk_del_char()
968 }
while (++i < Repeat);
970 return delete_string(i);
973 STATIC STATUS redisplay()
975 if (clrpage) TTYputs(clrpage);
977 TTYputs((ECHAR *)newline);
983 STATIC STATUS kill_line()
987 if (Repeat != NO_ARG) {
988 if (Repeat < Point) {
992 (void)delete_string(i - Point);
994 else if (Repeat > Point) {
996 (void)delete_string(Repeat - Point - 1);
1001 save_yank(Point, End - Point);
1008 STATIC
char *rsearch_hist(
char *patt,
int *lpos,
int *cpos)
1012 for (; *lpos > 0; (*lpos)--)
1014 for ( ; (*cpos) >= 0 ; (*cpos)--)
1017 if (strncmp(patt,(
char *)H.Lines[*lpos]+*cpos,strlen(patt)) == 0)
1019 return (
char *)H.Lines[*lpos];
1023 *cpos = strlen((
char *)H.Lines[(*lpos)-1]);
1028 STATIC STATUS h_risearch()
1031 CONST
char *old_prompt;
1032 char *pat, *hist, *nhist;
1038 old_prompt = Prompt;
1040 nprompt = walloc(
char,80+160);
1041 pat = walloc(
char,80);
1046 cpos = strlen((
char *)H.Lines[lpos]);
1049 sprintf(nprompt,
"(reverse-i-search)`%s': ",pat);
1052 do_insert_hist((ECHAR *)hist);
1054 for (i=strlen((
char *)H.Lines[lpos]); i>cpos; i--) bk_char();
1056 if ((c >=
' ') || (c == CTL(
'R')))
1060 else if (patend < 79)
1071 nhist = rsearch_hist(pat,&lpos,&cpos);
1087 }
while ((c >=
' ') || (c == CTL(
'R')));
1091 Prompt = old_prompt;
1092 TTYputs((ECHAR *)Prompt);
1096 s = do_insert_hist((ECHAR *)hist);
1098 for (i=strlen((
char *)H.Lines[lpos]); i>cpos; i--) s = bk_char();
1105 STATIC STATUS insert_char(
int c)
1113 if (Repeat == NO_ARG || Repeat < 2) {
1116 return insert_string(buff);
1119 if ((p = NEW(ECHAR, Repeat + 1)) == NULL)
1121 for (i = Repeat, q = p; --i >= 0; )
1125 s = insert_string(p);
1130 STATIC STATUS meta()
1135 if ((c = TTYget()) == EOF)
1137 #if defined(ANSI_ARROWS)
1139 if (c ==
'[' || c ==
'O')
1140 switch (c = TTYget()) {
1141 default:
return ring_bell();
1142 case EOF:
return CSeof;
1143 case 'A':
return h_prev();
1144 case 'B':
return h_next();
1145 case 'C':
return fd_char();
1146 case 'D':
return bk_char();
1151 for (Repeat = c -
'0'; (c = TTYget()) != EOF && isdigit(c); )
1152 Repeat = Repeat * 10 + c -
'0';
1160 for (OldPoint = Point, kp = MetaMap; kp->Function; kp++)
1162 return (*kp->Function)();
1163 if (rl_meta_chars == 0)
1165 insert_char(META(c));
1172 STATIC STATUS emacs(
unsigned int c)
1177 if (ISMETA(c) && rl_meta_chars)
1180 el_PushBack = UNMETA(c);
1183 for (kp = Map; kp->Function; kp++)
1186 s = kp->Function ? (*kp->Function)() : insert_char((
int)c);
1193 STATIC STATUS TTYspecial(
unsigned int c)
1200 if (c == rl_erase || c == DEL)
1201 return bk_del_char();
1204 for (i=screen_pos()/TTYwidth; i > 0; i--)
1205 if (upline) TTYputs(upline);
1212 if (c == rl_intr || c == rl_quit) {
1217 el_intr_pending = 1;
1223 if (c == rl_eof && Point == 0 && End == 0)
1229 STATIC ECHAR *editinput()
1234 OldPoint = Point = Mark = End = 0;
1237 while ((c = TTYget()) != EOF)
1239 switch (TTYspecial(c)) {
1268 STATIC
void hist_add(ECHAR *p)
1272 if ((p = (ECHAR *)STRDUP((
char *)p)) == NULL)
1274 if (H.Size < editline_histsize)
1275 H.Lines[H.Size++] = p;
1277 DISPOSE(H.Lines[0]);
1278 for (i = 0; i < editline_histsize - 1; i++)
1279 H.Lines[i] = H.Lines[i + 1];
1286 void write_history(
const char *history_file)
1291 if ((fd = fopen(history_file,
"wb")) == NULL)
1293 fprintf(stderr,
"editline: can't access history file \"%s\"\n",
1298 for (i=0; i < H.Size; i++)
1299 fprintf(fd,
"%s\n",H.Lines[i]);
1303 void read_history(
const char *history_file)
1309 H.Lines = NEW(ECHAR *,editline_histsize);
1313 if ((fd = fopen(history_file,
"rb")) == NULL)
1316 while ((c=getc(fd)) != EOF)
1319 for (i=0; ((c=getc(fd)) !=
'\n') && (c != EOF); i++)
1334 rl_reset_terminal(
char *p)
1343 char *readline(CONST
char *prompt)
1349 if ((Line = NEW(ECHAR, Length)) == NULL)
1356 ScreenSize = SCREEN_INC;
1357 Screen = NEW(
char, ScreenSize);
1358 Prompt = prompt ? prompt : (
char *)el_NIL;
1359 el_intr_pending = 0;
1360 if (el_no_echo == 1)
1363 TTYputs((ECHAR *)Prompt);
1368 TTYputs((ECHAR *)Prompt);
1371 line = (ECHAR *)STRDUP((
char *)line);
1372 TTYputs((ECHAR *)newline);
1377 DISPOSE(H.Lines[--H.Size]);
1378 if (el_intr_pending)
1380 return (
char *)line;
1387 if (p == NULL || *p ==
'\0')
1390 #if defined(UNIQUE_HISTORY)
1391 if (H.Pos && strcmp(p, H.Lines[H.Pos - 1]) == 0)
1394 hist_add((ECHAR *)p);
1398 STATIC STATUS beg_line()
1402 for (i=screen_pos()/TTYwidth; i > 0; i--)
1403 if (upline) TTYputs(upline);
1410 STATIC STATUS del_char()
1412 return delete_string(Repeat == NO_ARG ? 1 : Repeat);
1415 STATIC STATUS end_line()
1420 TTYput(Line[Point]);
1432 STATIC ECHAR *find_word()
1434 static char SEPS[] =
"#;&|^$=`'{}()<>\n\t ";
1439 for (p = &Line[Point]; p > Line && strchr(SEPS, (
char)p[-1]) == NULL; p--)
1441 len = Point - (p - Line) + 1;
1442 if ((
new = NEW(ECHAR, len)) == NULL)
1444 COPYFROMTO(
new, p, len);
1445 new[len - 1] =
'\0';
1454 char *el_current_sym()
1457 char *symbol = NULL;
1469 (strchr(
"()' \t\n\r",Line[i]) != NULL));
1475 for (; i < End; i++)
1476 if (strchr(
"()' \t\n\r\"",Line[i]) != NULL)
1478 for (j=i-1; j >=0; j--)
1479 if (strchr(
"()' \t\n\r\"",Line[j]) != NULL)
1482 symbol = walloc(
char,i-j);
1483 strncpy(symbol,(
char *)&Line[j+1],i-(j+1));
1484 symbol[i-(j+1)] =
'\0';
1489 static char *completion_to_ambiguity(
int index,
char **possibles)
1500 for ( ; extending; e++)
1502 for (i=0; possibles[i] != NULL; i++)
1503 if (possibles[i][e] != possibles[0][e])
1515 p = walloc(
char,(e-index)+1);
1516 strncpy(p,possibles[0]+index,e-index);
1522 static char **el_file_completion_function(
char * text,
int start,
int end)
1531 word = walloc(
char,(end-start)+1);
1532 strncpy(word,text+start,end-start);
1533 word[end-start]=
'\0';
1535 ac = rl_list_possib(word,&matches1);
1541 matches2 = walloc(
char *,ac+1);
1542 for (i=0; i < ac; i++)
1543 matches2[i] = matches1[i];
1550 STATIC STATUS c_complete()
1557 char **possibles=NULL;
1559 int started_with_quote = 0;
1563 for (start=Point; start > 0; start--)
1564 if (strchr(
"()' \t\n\r\"",Line[start-1]) != NULL)
1566 word = walloc(
char,(Point-start)+1);
1567 strncpy(word,(
char *)(Line+start),Point-start);
1568 word[Point-start]=
'\0';
1569 if ((start > 0) && (Line[start-1] ==
'"'))
1570 started_with_quote = 1;
1572 if (el_user_completion_function)
1574 possibles = el_user_completion_function((
char *)Line,start,Point);
1575 if (possibles == NULL)
1577 possibles = el_file_completion_function((
char *)Line,start,Point);
1580 for (start=Point; start > 0; start--)
1581 if (strchr(
"()' \t\n\r\"/",Line[start-1]) != NULL)
1585 for (possiblesc=0; possibles[possiblesc] != NULL; possiblesc++);
1587 if ((!possibles) || (possiblesc == 0))
1589 else if (possiblesc == 1)
1591 p = walloc(
char,strlen(possibles[0])-(Point-start)+2);
1592 sprintf(p,
"%s ",possibles[0]+(Point-start));
1593 if ((strlen(p) > 1) && (p[strlen(p)-2] ==
'/'))
1594 p[strlen(p)-1] =
'\0';
1595 else if (started_with_quote)
1596 p[strlen(p)-1] =
'"';
1598 s = insert_string((ECHAR *)p);
1601 else if ((p = completion_to_ambiguity(Point-start,possibles)) != NULL)
1603 s = insert_string((ECHAR *)p);
1609 print_columns(possiblesc,possibles);
1614 for (i=0; possibles && possibles[i] != NULL; i++)
1615 wfree(possibles[i]);
1624 STATIC STATUS c_complete_old()
1632 p = (ECHAR *)rl_complete((
char *)word, &unique);
1636 s = insert_string(p);
1646 STATIC STATUS c_possible()
1656 ac = rl_list_possib((
char *)word, (
char ***) ((
void *) &av));
1660 print_columns(ac, (
char **)av);
1670 STATIC STATUS accept_line()
1676 #ifdef SYSTEM_IS_WIN32
1677 STATIC STATUS end_of_input()
1684 STATIC STATUS transpose()
1691 c = Line[Point - 1];
1693 Line[Point - 1] = Line[Point];
1694 TTYshow(Line[Point - 1]);
1701 STATIC STATUS quote()
1705 return (c = TTYget()) == EOF ? CSeof : insert_char((
int)c);
1708 STATIC STATUS wipe()
1722 return delete_string(Mark - Point);
1725 STATIC STATUS mk_set()
1731 STATIC STATUS exchange()
1735 if ((c = TTYget()) != CTL(
'X'))
1736 return c == EOF ? CSeof : ring_bell();
1738 if ((c = Mark) <= End) {
1746 STATIC STATUS yank()
1748 if (Yanked && *Yanked)
1749 return insert_string(Yanked);
1753 STATIC STATUS copy_region()
1759 save_yank(Mark, Point - Mark);
1761 save_yank(Point, Mark - Point);
1766 STATIC STATUS move_to_char()
1772 if ((c = TTYget()) == EOF)
1774 for (i = Point + 1, p = &Line[i]; i < End; i++, p++)
1782 STATIC STATUS fd_word()
1784 return do_forward(CSmove);
1787 STATIC STATUS fd_kill_word()
1793 (void)do_forward(CSmove);
1796 for ( ; Point > OP; Point --)
1798 return delete_string(i);
1803 STATIC STATUS bk_word()
1810 for (p = &Line[Point]; p > Line && !isalnum(p[-1]); p--)
1813 for (; p > Line && p[-1] !=
' ' && isalnum(p[-1]); p--)
1818 }
while (++i < Repeat);
1823 STATIC STATUS bk_kill_word()
1826 if (OldPoint != Point)
1827 return delete_string(OldPoint - Point);
1831 STATIC
int argify(ECHAR *line, ECHAR ***avp)
1840 if ((*avp = p = NEW(ECHAR*, i))== NULL)
1843 for (c = line; isspace(*c); c++)
1845 if (*c ==
'\n' || *c ==
'\0')
1848 for (ac = 0, p[ac++] = c; *c && *c !=
'\n'; ) {
1851 if (*c && *c !=
'\n') {
1853 new = NEW(ECHAR*, i + MEM_INC);
1858 COPYFROMTO(
new, p, i *
sizeof (
char **));
1874 STATIC STATUS last_argument()
1881 if (H.Size == 1 || (p = H.Lines[H.Size - 2]) == NULL)
1884 if ((p = (ECHAR *)STRDUP((
char *)p)) == NULL)
1886 ac = argify(p, &av);
1888 if (Repeat != NO_ARG)
1889 s = Repeat < ac ? insert_string(av[Repeat]) : ring_bell();
1891 s = ac ? insert_string(av[ac - 1]) : CSstay;
1899 STATIC KEYMAP Map[33] = {
1900 { CTL(
'@'), ring_bell },
1901 { CTL(
'A'), beg_line },
1902 { CTL(
'B'), bk_char },
1903 { CTL(
'D'), del_char },
1904 { CTL(
'E'), end_line },
1905 { CTL(
'F'), fd_char },
1906 { CTL(
'G'), ring_bell },
1907 { CTL(
'H'), bk_del_char },
1908 { CTL(
'I'), c_complete },
1909 { CTL(
'J'), accept_line },
1910 { CTL(
'K'), kill_line },
1911 { CTL(
'L'), redisplay },
1912 { CTL(
'M'), accept_line },
1913 { CTL(
'N'), h_next },
1914 { CTL(
'O'), ring_bell },
1915 { CTL(
'P'), h_prev },
1916 { CTL(
'Q'), ring_bell },
1917 { CTL(
'R'), h_risearch },
1918 { CTL(
'S'), h_search },
1919 { CTL(
'T'), transpose },
1920 { CTL(
'U'), ring_bell },
1921 { CTL(
'V'), quote },
1923 { CTL(
'X'), exchange },
1925 #ifdef SYSTEM_IS_WIN32
1926 { CTL(
'Z'), end_of_input },
1928 { CTL(
'Z'), ring_bell },
1931 { CTL(
']'), move_to_char },
1932 { CTL(
'^'), ring_bell },
1933 { CTL(
'_'), ring_bell },
1937 STATIC KEYMAP MetaMap[64]= {
1938 { CTL(
'H'), bk_kill_word },
1939 { DEL, bk_kill_word },
1941 {
'.', last_argument },
1944 {
'?', c_possible },
1946 {
'c', case_cap_word },
1947 {
'd', fd_kill_word },
1949 {
'l', case_down_word },
1950 {
'u', case_up_word },
1952 {
'w', copy_region },
1956 void el_bind_key_in_metamap(
char c, Keymap_Function func)
1961 for (i=0; MetaMap[i].Key != 0; i++)
1963 if (MetaMap[i].Key == c)
1965 MetaMap[i].Function = func;
1973 fprintf(stderr,
"editline: MetaMap table full, requires increase\n");
1977 MetaMap[i].Function = func;
1979 MetaMap[i+1].Function = 0;
1980 MetaMap[i+1].Key = 0;