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;
76 char *editline_history_file;
79 EL_USER_COMPLETION_FUNCTION_TYPE*el_user_completion_function = NULL;
85 TOupper, TOlower, TOcapitalize
91 typedef struct _KEYMAP {
99 typedef struct _HISTORY {
114 extern CONST ECHAR *el_Input;
115 STATIC ECHAR *Line = NULL;
116 STATIC CONST
char *Prompt = NULL;
117 STATIC ECHAR *Yanked = NULL;
118 STATIC
char *Screen = NULL;
127 extern int el_PushBack;
128 extern int el_Pushed;
129 FORWARD KEYMAP Map[33];
130 FORWARD KEYMAP MetaMap[64];
131 STATIC ESIZE_T Length;
132 STATIC ESIZE_T ScreenCount;
133 STATIC ESIZE_T ScreenSize;
134 STATIC ECHAR *backspace = NULL;
135 STATIC ECHAR *upline = NULL;
136 STATIC ECHAR *clrpage = NULL;
137 STATIC ECHAR *downline = NULL;
138 STATIC ECHAR *move_right = NULL;
139 STATIC ECHAR *newline = NULL;
140 STATIC ECHAR *bol = NULL;
141 STATIC ECHAR *nextline = NULL;
144 STATIC
int RequireNLforWrap = 1;
145 STATIC
int el_intr_pending = 0;
149 extern void TTYflush();
150 STATIC
void TTYput(ECHAR c);
151 STATIC
void TTYputs(ECHAR *p);
152 STATIC
void TTYshow(ECHAR c);
153 STATIC
void TTYstring(ECHAR *p);
154 extern unsigned int TTYget();
155 STATIC
void TTYinfo();
156 STATIC
void print_columns(
int ac,
char **av);
157 STATIC
void reposition(
int reset);
158 STATIC
void left(STATUS Change);
159 STATIC
void right(STATUS Change);
160 STATIC STATUS ring_bell();
162 STATIC STATUS do_macro(
unsigned int c);
164 STATIC STATUS do_forward(STATUS move);
165 STATIC STATUS do_case(ECHAR type);
166 STATIC STATUS case_down_word();
167 STATIC STATUS case_up_word();
169 STATIC
void clear_line();
170 STATIC STATUS insert_string(ECHAR *p);
171 STATIC ECHAR *next_hist();
172 STATIC ECHAR *prev_hist();
173 STATIC STATUS do_insert_hist(ECHAR *p);
174 STATIC STATUS do_hist(ECHAR *(*move)());
175 STATIC STATUS h_next();
176 STATIC STATUS h_prev();
177 STATIC STATUS h_first();
178 STATIC STATUS h_last();
179 STATIC
int substrcmp(
char *text,
char *pat,
int len);
180 STATIC ECHAR *search_hist(ECHAR *search, ECHAR *(*move)());
181 STATIC STATUS h_search();
182 STATIC STATUS fd_char();
183 STATIC
void save_yank(
int begin,
int i);
184 STATIC STATUS delete_string(
int count);
185 STATIC STATUS bk_char();
186 STATIC STATUS bk_del_char();
187 STATIC STATUS redisplay();
188 STATIC STATUS kill_line();
189 STATIC
char *rsearch_hist(
char *patt,
int *lpos,
int *cpos);
190 STATIC STATUS h_risearch();
191 STATIC STATUS insert_char(
int c);
192 STATIC STATUS meta();
193 STATIC STATUS emacs(
unsigned int c);
194 STATIC STATUS TTYspecial(
unsigned int c);
195 STATIC ECHAR *editinput();
196 STATIC
void hist_add(ECHAR *p);
197 STATIC STATUS beg_line();
198 STATIC STATUS del_char();
199 STATIC STATUS end_line();
200 STATIC ECHAR *find_word();
201 STATIC STATUS c_complete();
202 STATIC STATUS c_possible();
203 STATIC STATUS accept_line();
204 STATIC STATUS transpose();
205 STATIC STATUS quote();
206 STATIC STATUS wipe();
207 STATIC STATUS mk_set();
208 STATIC STATUS exchange();
209 STATIC STATUS yank();
210 STATIC STATUS copy_region();
211 STATIC STATUS move_to_char();
212 STATIC STATUS fd_word();
213 STATIC STATUS fd_kill_word();
214 STATIC STATUS bk_word();
215 STATIC STATUS bk_kill_word();
216 STATIC
int argify(ECHAR *line, ECHAR ***avp);
217 STATIC STATUS last_argument();
220 int rl_meta_chars = 0;
225 STATIC ECHAR *editinput();
226 #if defined(USE_TERMCAP)
227 extern char *getenv();
228 extern char *tgetstr();
229 extern int tgetent();
230 extern int tgetnum();
241 (void)write(1, Screen, ScreenCount);
246 STATIC
void TTYput(ECHAR c)
248 Screen[ScreenCount] = c;
249 if (++ScreenCount >= ScreenSize - 1) {
250 ScreenSize += SCREEN_INC;
251 RENEW(Screen,
char, ScreenSize);
255 STATIC
void TTYputs(ECHAR *p)
261 STATIC
void TTYshow(ECHAR c)
271 else if (rl_meta_chars && ISMETA(c)) {
280 STATIC
void TTYstring(ECHAR *p)
288 #define TTYback() (backspace ? TTYputs((ECHAR *)backspace) : TTYput('\b'))
291 STATIC
int printlen(CONST
char *p)
296 if ((*p == DEL) || (ISCTL(*p)))
298 else if (rl_meta_chars && ISMETA(*p))
306 STATIC
int screen_pos()
310 int p = strlen(Prompt);
313 for (i=0; i < Point; i++)
314 if ((Line[i] == DEL) ||
317 else if (rl_meta_chars && ISMETA(Line[i]))
325 STATIC
void TTYback()
329 int sp = screen_pos();
331 if (upline && sp && (sp%TTYwidth == 0))
335 for (i=0; i < TTYwidth; i++)
339 TTYputs((ECHAR *)backspace);
344 STATIC
void TTYinfo()
347 #if defined(USE_TERMCAP)
353 #if defined(TIOCGWINSZ)
358 #if defined(TIOCGWINSZ)
360 if (ioctl(0, TIOCGWINSZ, &W) >= 0
361 && W.ws_col > 0 && W.ws_row > 0) {
362 TTYwidth = (int)W.ws_col;
363 TTYrows = (
int)W.ws_row;
370 TTYwidth = TTYrows = 0;
371 #if defined(USE_TERMCAP)
372 buff = walloc(
char,2048);
373 buff2 = walloc(
char,2048);
375 if ((term = getenv(
"TERM")) == NULL)
377 if (tgetent(buff, term) < 0) {
378 TTYwidth = SCREEN_WIDTH;
379 TTYrows = SCREEN_ROWS;
382 backspace = (ECHAR *)tgetstr(
"le", &bp);
383 upline = (ECHAR *)tgetstr(
"up", &bp);
384 clrpage = (ECHAR *)tgetstr(
"cl", &bp);
385 nextline = (ECHAR *)tgetstr(
"nl", &bp);
387 nextline = (ECHAR *)
"\n";
388 if (strncmp(term,
"pcansi", 6)==0 || strncmp(term,
"cygwin", 6)==0)
390 bol = (ECHAR *)
"\033[0G";
391 RequireNLforWrap = 0;
394 bol = (ECHAR *)tgetstr(
"cr", &bp);
398 newline= walloc(ECHAR, 20);
399 strcpy((
char *)newline,(
char *)bol);
400 strcat((
char *)newline,(
char *)nextline);
402 downline = (ECHAR *)newline;
403 move_right = (ECHAR *)tgetstr(
"nd", &bp);
404 if (!move_right || !downline)
406 TTYwidth = tgetnum(
"co");
407 TTYrows = tgetnum(
"li");
410 #if defined(TIOCGWINSZ)
411 if (ioctl(0, TIOCGWINSZ, &W) >= 0) {
412 TTYwidth = (int)W.ws_col;
413 TTYrows = (
int)W.ws_row;
417 if (TTYwidth <= 0 || TTYrows <= 0) {
418 TTYwidth = SCREEN_WIDTH;
419 TTYrows = SCREEN_ROWS;
427 STATIC
void print_columns(
int ac,
char **av)
441 TTYputs((ECHAR *)newline);
442 sprintf(info1,
"There are %d possibilities. Do you really \n",ac);
443 TTYputs((ECHAR *)info1);
444 TTYputs((ECHAR *)
"want to see them all (y/n) ? ");
445 while (((c = TTYget()) != EOF) && ((strchr(
"YyNn ",c) == NULL)))
447 if (strchr(
"Nn",c) != NULL)
449 TTYputs((ECHAR *)newline);
455 for (longest = 0, i = 0; i < ac; i++)
456 if ((j = strlen((
char *)av[i])) > longest)
458 cols = TTYwidth / (longest + 3);
459 if (cols < 1) cols = 1;
461 TTYputs((ECHAR *)newline);
462 for (skip = ac / cols + 1, i = 0; i < skip; i++) {
463 for (j = i; j < ac; j += skip) {
464 for (p = (ECHAR *)av[j], len = strlen((
char *)p), k = len;
468 while (++len < longest + 3)
471 TTYputs((ECHAR *)newline);
475 STATIC
void reposition(
int reset)
484 for (i=screen_pos()/TTYwidth; i > 0; i--)
485 if (upline) TTYputs(upline);
487 TTYputs((ECHAR *)Prompt);
488 pos = printlen(Prompt);
490 for (i = 0; i < End; i++)
494 pos += printlen(ppp);
495 if ((pos%TTYwidth) == 0)
496 if (RequireNLforWrap && downline) TTYputs(downline);
503 if (rl_meta_chars && ISMETA(Line[Point]))
508 else if (ISCTL(Line[Point]))
515 STATIC
void left(STATUS Change)
519 if (ISCTL(Line[Point - 1]))
521 else if (rl_meta_chars && ISMETA(Line[Point - 1])) {
526 if (Change == CSmove)
530 STATIC
void right(STATUS Change)
532 TTYshow(Line[Point]);
533 if (Change == CSmove)
535 if ((screen_pos())%TTYwidth == 0)
536 if (downline && RequireNLforWrap) TTYputs(downline);
539 STATIC STATUS ring_bell()
547 STATIC STATUS do_macro(
unsigned int c)
556 if ((el_Input = (ECHAR *)getenv((
char *)name)) == NULL) {
564 STATIC STATUS do_forward(STATUS move)
573 for ( ; Point < End && (*p ==
' ' || !isalnum(*p)); p++)
576 for (; Point < End && isalnum(*p); p++)
581 }
while (++i < Repeat);
586 STATIC STATUS do_case(ECHAR type)
595 (void)do_forward(CSstay);
597 if ((count = Point - OP) < 0)
599 for ( ; Point > OP; Point --)
601 if ((end = Point + count) > End)
603 for (i = Point, p = &Line[Point]; Point < end; p++) {
604 if ((type == TOupper) ||
605 ((type == TOcapitalize) && (Point == i)))
610 else if (isupper(*p))
618 STATIC STATUS case_down_word()
620 return do_case(TOlower);
623 STATIC STATUS case_up_word()
625 return do_case(TOupper);
628 STATIC STATUS case_cap_word()
630 return do_case(TOcapitalize);
640 for (extras = 0, i = Point, p = &Line[i]; i < End; i++, p++) {
647 else if (rl_meta_chars && ISMETA(*p)) {
652 else if ((screen_pos())%TTYwidth == 0)
653 if (downline && RequireNLforWrap) TTYputs(downline);
661 if (rl_meta_chars && ISMETA(Line[Point-1]))
666 else if (ISCTL(Line[Point-1]))
674 STATIC
void clear_line()
678 for (i=screen_pos()/TTYwidth; i > 0; i--)
679 if (upline) TTYputs(upline);
680 for (i=0; i < strlen(Prompt); i++)
686 for (i=screen_pos()/TTYwidth; i > 0; i--)
687 if (upline) TTYputs(upline);
693 STATIC STATUS insert_string(ECHAR *p)
700 len = strlen((
char *)p);
701 if (End + len >= Length) {
702 if ((
new = NEW(ECHAR, Length + len + MEM_INC)) == NULL)
705 COPYFROMTO(
new, Line, Length);
709 Length += len + MEM_INC;
712 for (q = &Line[Point], i = End - Point; --i >= 0; )
714 COPYFROMTO(&Line[Point], p, len);
718 pos1 = printlen((
char *)&Line[Point]);
719 TTYstring(&Line[Point]);
721 if ((pos0+pos1)%TTYwidth == 0)
722 if (downline && RequireNLforWrap) TTYputs(downline);
726 if (upline && (Point != End))
729 pos1 = printlen((
char *)&Line[Point]);
730 for (i=((pos0%TTYwidth)+pos1)/TTYwidth; i > 0; i--)
731 if (upline) TTYputs(upline);
733 for (i=0 ; i < (pos0%TTYwidth); i++)
737 return Point == End ? CSstay : CSmove;
741 STATIC ECHAR *next_hist()
743 return H.Pos >= H.Size - 1 ? NULL : H.Lines[++H.Pos];
746 STATIC ECHAR *prev_hist()
748 return H.Pos == 0 ? NULL : H.Lines[--H.Pos];
751 STATIC STATUS do_insert_hist(ECHAR *p)
756 for (i=screen_pos()/TTYwidth; i > 0; i--)
757 if (upline) TTYputs(upline);
762 return insert_string(p);
765 STATIC STATUS do_hist(ECHAR *(*move)())
772 if ((p = (*move)()) == NULL)
774 }
while (++i < Repeat);
775 return do_insert_hist(p);
778 STATIC STATUS h_next()
780 return do_hist(next_hist);
783 STATIC STATUS h_prev()
785 return do_hist(prev_hist);
788 STATIC STATUS h_first()
790 return do_insert_hist(H.Lines[H.Pos = 0]);
793 STATIC STATUS h_last()
795 return do_insert_hist(H.Lines[H.Pos = H.Size - 1]);
801 STATIC
int substrcmp(
char *text,
char *pat,
int len)
805 if ((c = *pat) ==
'\0')
806 return *text ==
'\0';
807 for ( ; *text; text++)
808 if (*text == c && strncmp(text, pat, len) == 0)
813 STATIC ECHAR *search_hist(ECHAR *search, ECHAR *(*move)())
815 static ECHAR *old_search;
822 if (search && *search) {
825 old_search = (ECHAR *)STRDUP((
const char *)search);
828 if (old_search == NULL || *old_search ==
'\0')
834 if (*search ==
'^') {
836 pat = (
char *)(search + 1);
840 pat = (
char *)search;
844 for (pos = H.Pos; (*move)() != NULL; )
845 if ((*match)((
char *)H.Lines[H.Pos], pat, len) == 0)
846 return H.Lines[H.Pos];
851 STATIC STATUS h_search()
853 static int Searching;
854 CONST
char *old_prompt;
865 TTYputs((ECHAR *)Prompt);
866 move = Repeat == NO_ARG ? prev_hist : next_hist;
867 p = search_hist(editinput(), move);
870 TTYputs((ECHAR *)Prompt);
873 return do_insert_hist(p);
876 STATIC STATUS fd_char()
885 }
while (++i < Repeat);
889 STATIC
void save_yank(
int begin,
int i)
899 if ((Yanked = NEW(ECHAR, (ESIZE_T)i + 1)) != NULL) {
900 COPYFROMTO(Yanked, &Line[begin], i);
905 STATIC STATUS delete_string(
int count)
911 if (count <= 0 || End == Point)
914 if (Point + count > End && (count = End - Point) <= 0)
918 save_yank(Point, count);
920 tLine = STRDUP((
char *)Line);
922 for (q = Point, i = End - (Point + count) + 1; --i >= 0; q++)
923 Line[q] = tLine[q+count];
927 pos1 = printlen((
char *)&Line[Point]);
928 TTYstring(&Line[Point]);
929 if ((pos1 > 0) && (pos0+pos1)%TTYwidth == 0)
930 if (downline && RequireNLforWrap) TTYputs(downline);
936 for (i=((pos0%TTYwidth)+pos1)/TTYwidth; i > 0; i--)
937 if (upline) TTYputs(upline);
939 for (i=0 ; i < (pos0%TTYwidth); i++)
946 STATIC STATUS bk_char()
955 }
while (++i < Repeat);
960 STATIC STATUS bk_del_char()
969 }
while (++i < Repeat);
971 return delete_string(i);
974 STATIC STATUS redisplay()
976 if (clrpage) TTYputs(clrpage);
978 TTYputs((ECHAR *)newline);
984 STATIC STATUS kill_line()
988 if (Repeat != NO_ARG) {
989 if (Repeat < Point) {
993 (void)delete_string(i - Point);
995 else if (Repeat > Point) {
997 (void)delete_string(Repeat - Point - 1);
1002 save_yank(Point, End - Point);
1009 STATIC
char *rsearch_hist(
char *patt,
int *lpos,
int *cpos)
1013 for (; *lpos > 0; (*lpos)--)
1015 for ( ; (*cpos) >= 0 ; (*cpos)--)
1018 if (strncmp(patt,(
char *)H.Lines[*lpos]+*cpos,strlen(patt)) == 0)
1020 return (
char *)H.Lines[*lpos];
1024 *cpos = strlen((
char *)H.Lines[(*lpos)-1]);
1029 STATIC STATUS h_risearch()
1032 CONST
char *old_prompt;
1033 char *pat, *hist, *nhist;
1035 int patsize, patend, i;
1039 old_prompt = Prompt;
1041 nprompt = walloc(
char,80+160);
1042 pat = walloc(
char,80);
1048 cpos = strlen((
char *)H.Lines[lpos]);
1051 sprintf(nprompt,
"(reverse-i-search)`%s': ",pat);
1054 do_insert_hist((ECHAR *)hist);
1056 for (i=strlen((
char *)H.Lines[lpos]); i>cpos; i--) bk_char();
1058 if ((c >=
' ') || (c == CTL(
'R')))
1062 else if (patend < 79)
1073 nhist = rsearch_hist(pat,&lpos,&cpos);
1089 }
while ((c >=
' ') || (c == CTL(
'R')));
1093 Prompt = old_prompt;
1094 TTYputs((ECHAR *)Prompt);
1098 s = do_insert_hist((ECHAR *)hist);
1100 for (i=strlen((
char *)H.Lines[lpos]); i>cpos; i--) s = bk_char();
1107 STATIC STATUS insert_char(
int c)
1115 if (Repeat == NO_ARG || Repeat < 2) {
1118 return insert_string(buff);
1121 if ((p = NEW(ECHAR, Repeat + 1)) == NULL)
1123 for (i = Repeat, q = p; --i >= 0; )
1127 s = insert_string(p);
1132 STATIC STATUS meta()
1137 if ((c = TTYget()) == EOF)
1139 #if defined(ANSI_ARROWS)
1141 if (c ==
'[' || c ==
'O')
1142 switch (c = TTYget()) {
1143 default:
return ring_bell();
1144 case EOF:
return CSeof;
1145 case 'A':
return h_prev();
1146 case 'B':
return h_next();
1147 case 'C':
return fd_char();
1148 case 'D':
return bk_char();
1153 for (Repeat = c -
'0'; (c = TTYget()) != EOF && isdigit(c); )
1154 Repeat = Repeat * 10 + c -
'0';
1162 for (OldPoint = Point, kp = MetaMap; kp->Function; kp++)
1164 return (*kp->Function)();
1165 if (rl_meta_chars == 0)
1167 insert_char(META(c));
1174 STATIC STATUS emacs(
unsigned int c)
1179 if (ISMETA(c) && rl_meta_chars)
1182 el_PushBack = UNMETA(c);
1185 for (kp = Map; kp->Function; kp++)
1188 s = kp->Function ? (*kp->Function)() : insert_char((
int)c);
1195 STATIC STATUS TTYspecial(
unsigned int c)
1202 if (c == rl_erase || c == DEL)
1203 return bk_del_char();
1206 for (i=screen_pos()/TTYwidth; i > 0; i--)
1207 if (upline) TTYputs(upline);
1214 if (c == rl_intr || c == rl_quit) {
1219 el_intr_pending = 1;
1225 if (c == rl_eof && Point == 0 && End == 0)
1231 STATIC ECHAR *editinput()
1236 OldPoint = Point = Mark = End = 0;
1239 while ((c = TTYget()) != EOF)
1241 switch (TTYspecial(c)) {
1270 STATIC
void hist_add(ECHAR *p)
1274 if ((p = (ECHAR *)STRDUP((
char *)p)) == NULL)
1276 if (H.Size < editline_histsize)
1277 H.Lines[H.Size++] = p;
1279 DISPOSE(H.Lines[0]);
1280 for (i = 0; i < editline_histsize - 1; i++)
1281 H.Lines[i] = H.Lines[i + 1];
1288 void write_history(
const char *history_file)
1293 if ((fd = fopen(history_file,
"wb")) == NULL)
1295 fprintf(stderr,
"editline: can't access history file \"%s\"\n",
1300 for (i=0; i < H.Size; i++)
1301 fprintf(fd,
"%s\n",H.Lines[i]);
1305 void read_history(
const char *history_file)
1311 H.Lines = NEW(ECHAR *,editline_histsize);
1315 if ((fd = fopen(history_file,
"rb")) == NULL)
1318 while ((c=getc(fd)) != EOF)
1321 for (i=0; ((c=getc(fd)) !=
'\n') && (c != EOF); i++)
1336 rl_reset_terminal(
char *p)
1345 char *readline(CONST
char *prompt)
1351 if ((Line = NEW(ECHAR, Length)) == NULL)
1358 ScreenSize = SCREEN_INC;
1359 Screen = NEW(
char, ScreenSize);
1360 Prompt = prompt ? prompt : (
char *)el_NIL;
1361 el_intr_pending = 0;
1362 if (el_no_echo == 1)
1365 TTYputs((ECHAR *)Prompt);
1370 TTYputs((ECHAR *)Prompt);
1373 line = (ECHAR *)STRDUP((
char *)line);
1374 TTYputs((ECHAR *)newline);
1379 DISPOSE(H.Lines[--H.Size]);
1380 if (el_intr_pending)
1382 return (
char *)line;
1389 if (p == NULL || *p ==
'\0')
1392 #if defined(UNIQUE_HISTORY)
1393 if (H.Pos && strcmp(p, H.Lines[H.Pos - 1]) == 0)
1396 hist_add((ECHAR *)p);
1400 STATIC STATUS beg_line()
1404 for (i=screen_pos()/TTYwidth; i > 0; i--)
1405 if (upline) TTYputs(upline);
1412 STATIC STATUS del_char()
1414 return delete_string(Repeat == NO_ARG ? 1 : Repeat);
1417 STATIC STATUS end_line()
1422 TTYput(Line[Point]);
1434 STATIC ECHAR *find_word()
1436 static char SEPS[] =
"#;&|^$=`'{}()<>\n\t ";
1441 for (p = &Line[Point]; p > Line && strchr(SEPS, (
char)p[-1]) == NULL; p--)
1443 len = Point - (p - Line) + 1;
1444 if ((
new = NEW(ECHAR, len)) == NULL)
1446 COPYFROMTO(
new, p, len);
1447 new[len - 1] =
'\0';
1456 char *el_current_sym()
1459 char *symbol = NULL;
1471 (strchr(
"()' \t\n\r",Line[i]) != NULL));
1477 for (; i < End; i++)
1478 if (strchr(
"()' \t\n\r\"",Line[i]) != NULL)
1480 for (j=i-1; j >=0; j--)
1481 if (strchr(
"()' \t\n\r\"",Line[j]) != NULL)
1484 symbol = walloc(
char,i-j);
1485 strncpy(symbol,(
char *)&Line[j+1],i-(j+1));
1486 symbol[i-(j+1)] =
'\0';
1491 static char *completion_to_ambiguity(
int index,
char **possibles)
1502 for ( ; extending; e++)
1504 for (i=0; possibles[i] != NULL; i++)
1505 if (possibles[i][e] != possibles[0][e])
1517 p = walloc(
char,(e-index)+1);
1518 strncpy(p,possibles[0]+index,e-index);
1524 static char **el_file_completion_function(
char * text,
int start,
int end)
1533 word = walloc(
char,(end-start)+1);
1534 strncpy(word,text+start,end-start);
1535 word[end-start]=
'\0';
1537 ac = rl_list_possib(word,&matches1);
1543 matches2 = walloc(
char *,ac+1);
1544 for (i=0; i < ac; i++)
1545 matches2[i] = matches1[i];
1552 STATIC STATUS c_complete()
1559 char **possibles=NULL;
1561 int started_with_quote = 0;
1565 for (start=Point; start > 0; start--)
1566 if (strchr(
"()' \t\n\r\"",Line[start-1]) != NULL)
1568 word = walloc(
char,(Point-start)+1);
1569 strncpy(word,(
char *)(Line+start),Point-start);
1570 word[Point-start]=
'\0';
1571 if ((start > 0) && (Line[start-1] ==
'"'))
1572 started_with_quote = 1;
1574 if (el_user_completion_function)
1576 possibles = el_user_completion_function((
char *)Line,start,Point);
1577 if (possibles == NULL)
1579 possibles = el_file_completion_function((
char *)Line,start,Point);
1582 for (start=Point; start > 0; start--)
1583 if (strchr(
"()' \t\n\r\"/",Line[start-1]) != NULL)
1587 for (possiblesc=0; possibles[possiblesc] != NULL; possiblesc++);
1589 if ((!possibles) || (possiblesc == 0))
1591 else if (possiblesc == 1)
1593 p = walloc(
char,strlen(possibles[0])-(Point-start)+2);
1594 sprintf(p,
"%s ",possibles[0]+(Point-start));
1595 if ((strlen(p) > 1) && (p[strlen(p)-2] ==
'/'))
1596 p[strlen(p)-1] =
'\0';
1597 else if (started_with_quote)
1598 p[strlen(p)-1] =
'"';
1600 s = insert_string((ECHAR *)p);
1603 else if ((p = completion_to_ambiguity(Point-start,possibles)) != NULL)
1605 s = insert_string((ECHAR *)p);
1611 print_columns(possiblesc,possibles);
1616 for (i=0; possibles && possibles[i] != NULL; i++)
1617 wfree(possibles[i]);
1626 STATIC STATUS c_complete_old()
1634 p = (ECHAR *)rl_complete((
char *)word, &unique);
1638 s = insert_string(p);
1648 STATIC STATUS c_possible()
1658 ac = rl_list_possib((
char *)word, (
char ***) ((
void *) &av));
1662 print_columns(ac, (
char **)av);
1672 STATIC STATUS accept_line()
1678 #ifdef SYSTEM_IS_WIN32
1679 STATIC STATUS end_of_input()
1686 STATIC STATUS transpose()
1693 c = Line[Point - 1];
1695 Line[Point - 1] = Line[Point];
1696 TTYshow(Line[Point - 1]);
1703 STATIC STATUS quote()
1707 return (c = TTYget()) == EOF ? CSeof : insert_char((
int)c);
1710 STATIC STATUS wipe()
1724 return delete_string(Mark - Point);
1727 STATIC STATUS mk_set()
1733 STATIC STATUS exchange()
1737 if ((c = TTYget()) != CTL(
'X'))
1738 return c == EOF ? CSeof : ring_bell();
1740 if ((c = Mark) <= End) {
1748 STATIC STATUS yank()
1750 if (Yanked && *Yanked)
1751 return insert_string(Yanked);
1755 STATIC STATUS copy_region()
1761 save_yank(Mark, Point - Mark);
1763 save_yank(Point, Mark - Point);
1768 STATIC STATUS move_to_char()
1774 if ((c = TTYget()) == EOF)
1776 for (i = Point + 1, p = &Line[i]; i < End; i++, p++)
1784 STATIC STATUS fd_word()
1786 return do_forward(CSmove);
1789 STATIC STATUS fd_kill_word()
1795 (void)do_forward(CSmove);
1798 for ( ; Point > OP; Point --)
1800 return delete_string(i);
1805 STATIC STATUS bk_word()
1812 for (p = &Line[Point]; p > Line && !isalnum(p[-1]); p--)
1815 for (; p > Line && p[-1] !=
' ' && isalnum(p[-1]); p--)
1820 }
while (++i < Repeat);
1825 STATIC STATUS bk_kill_word()
1828 if (OldPoint != Point)
1829 return delete_string(OldPoint - Point);
1833 STATIC
int argify(ECHAR *line, ECHAR ***avp)
1842 if ((*avp = p = NEW(ECHAR*, i))== NULL)
1845 for (c = line; isspace(*c); c++)
1847 if (*c ==
'\n' || *c ==
'\0')
1850 for (ac = 0, p[ac++] = c; *c && *c !=
'\n'; ) {
1853 if (*c && *c !=
'\n') {
1855 new = NEW(ECHAR*, i + MEM_INC);
1860 COPYFROMTO(
new, p, i *
sizeof (
char **));
1876 STATIC STATUS last_argument()
1883 if (H.Size == 1 || (p = H.Lines[H.Size - 2]) == NULL)
1886 if ((p = (ECHAR *)STRDUP((
char *)p)) == NULL)
1888 ac = argify(p, &av);
1890 if (Repeat != NO_ARG)
1891 s = Repeat < ac ? insert_string(av[Repeat]) : ring_bell();
1893 s = ac ? insert_string(av[ac - 1]) : CSstay;
1901 STATIC KEYMAP Map[33] = {
1902 { CTL(
'@'), ring_bell },
1903 { CTL(
'A'), beg_line },
1904 { CTL(
'B'), bk_char },
1905 { CTL(
'D'), del_char },
1906 { CTL(
'E'), end_line },
1907 { CTL(
'F'), fd_char },
1908 { CTL(
'G'), ring_bell },
1909 { CTL(
'H'), bk_del_char },
1910 { CTL(
'I'), c_complete },
1911 { CTL(
'J'), accept_line },
1912 { CTL(
'K'), kill_line },
1913 { CTL(
'L'), redisplay },
1914 { CTL(
'M'), accept_line },
1915 { CTL(
'N'), h_next },
1916 { CTL(
'O'), ring_bell },
1917 { CTL(
'P'), h_prev },
1918 { CTL(
'Q'), ring_bell },
1919 { CTL(
'R'), h_risearch },
1920 { CTL(
'S'), h_search },
1921 { CTL(
'T'), transpose },
1922 { CTL(
'U'), ring_bell },
1923 { CTL(
'V'), quote },
1925 { CTL(
'X'), exchange },
1927 #ifdef SYSTEM_IS_WIN32
1928 { CTL(
'Z'), end_of_input },
1930 { CTL(
'Z'), ring_bell },
1933 { CTL(
']'), move_to_char },
1934 { CTL(
'^'), ring_bell },
1935 { CTL(
'_'), ring_bell },
1939 STATIC KEYMAP MetaMap[64]= {
1940 { CTL(
'H'), bk_kill_word },
1941 { DEL, bk_kill_word },
1943 {
'.', last_argument },
1946 {
'?', c_possible },
1948 {
'c', case_cap_word },
1949 {
'd', fd_kill_word },
1951 {
'l', case_down_word },
1952 {
'u', case_up_word },
1954 {
'w', copy_region },
1958 void el_bind_key_in_metamap(
char c, Keymap_Function func)
1963 for (i=0; MetaMap[i].Key != 0; i++)
1965 if (MetaMap[i].Key == c)
1967 MetaMap[i].Function = func;
1975 fprintf(stderr,
"editline: MetaMap table full, requires increase\n");
1979 MetaMap[i].Function = func;
1981 MetaMap[i+1].Function = 0;
1982 MetaMap[i+1].Key = 0;