📄 editline.c
字号:
else if (rl_meta_chars && ISMETA(*p)) { i = 3; TTYput(' '); TTYput(' '); } TTYbackn(i); *p = '\0'; return CSmove; } if (Point + count > End && (count = End - Point) <= 0) return CSstay; if (count > 1) save_yank(Point, count); for (p = &Line[Point], i = End - (Point + count) + 1; --i >= 0; p++) p[0] = p[count]; ceol(); End -= count; TTYstring(&Line[Point]); return CSmove;}STATIC STATUSbk_char(){ int i; i = 0; do { if (Point == 0) break; left(CSmove); } while (++i < Repeat); return CSstay;}STATIC STATUSbk_del_char(){ int i; i = 0; do { if (Point == 0) break; left(CSmove); } while (++i < Repeat); return delete_string(i);}STATIC STATUSkill_line(){ int i; if (Repeat != NO_ARG) { if (Repeat < Point) { i = Point; Point = Repeat; reposition(); (void)delete_string(i - Point); } else if (Repeat > Point) { right(CSmove); (void)delete_string(Repeat - Point - 1); } return CSmove; } save_yank(Point, End - Point); Line[Point] = '\0'; ceol(); End = Point; return CSstay;}STATIC STATUSinsert_char(c) int c;{ STATUS s; CHAR buff[2]; CHAR *p; CHAR *q; int i; if (Repeat == NO_ARG || Repeat < 2) { buff[0] = c; buff[1] = '\0'; return insert_string(buff); } if ((p = NEW(CHAR, Repeat + 1)) == NULL) return CSstay; for (i = Repeat, q = p; --i >= 0; ) *q++ = c; *q = '\0'; Repeat = 0; s = insert_string(p); DISPOSE(p); return s;}STATIC STATUSmeta(){ unsigned int c; KEYMAP *kp; if ((c = TTYget()) == EOF) return CSeof;#if defined(ANSI_ARROWS) /* Also include VT-100 arrows. */ if (c == '[' || c == 'O') switch (c = TTYget()) { default: return ring_bell(); case EOF: return CSeof; case 'A': return h_prev(); case 'B': return h_next(); case 'C': return fd_char(); case 'D': return bk_char(); }#endif /* defined(ANSI_ARROWS) */ if (isdigit(c)) { for (Repeat = c - '0'; (c = TTYget()) != EOF && isdigit(c); ) Repeat = Repeat * 10 + c - '0'; Pushed = 1; PushBack = c; return CSstay; } if (isupper(c)) return do_macro(c); for (kp = MetaMap; kp->Function; kp++) if (kp->Key == c) return (*kp->Function)(); return ring_bell();}STATIC STATUSemacs(c) unsigned int c;{ STATUS s; KEYMAP *kp; OldPoint = Point; if (rl_meta_chars && ISMETA(c)) { Pushed = 1; PushBack = UNMETA(c); return meta(); } for (kp = Map; kp->Function; kp++) if (kp->Key == c) break; s = kp->Function ? (*kp->Function)() : insert_char((int)c); if (!Pushed) /* No pushback means no repeat count; hacky, but true. */ Repeat = NO_ARG; return s;}STATIC STATUSTTYspecial(c) unsigned int c;{ if (ISMETA(c)) return CSdispatch; if (c == rl_erase || c == DEL) return bk_del_char(); if (c == rl_kill) { if (Point != 0) { Point = 0; reposition(); } Repeat = NO_ARG; return kill_line(); } if (c == rl_eof && Point == 0 && End == 0) return CSeof; if (c == rl_intr) { Signal = SIGINT; return CSsignal; } if (c == rl_quit) { Signal = SIGQUIT; return CSeof; } return CSdispatch;}STATIC CHAR *editinput(){ unsigned int c; Repeat = NO_ARG; OldPoint = Point = Mark = End = 0; Line[0] = '\0'; Signal = -1; while ((c = TTYget()) != EOF) switch (TTYspecial(c)) { case CSdone: return Line; case CSeof: return NULL; case CSsignal: return (CHAR *)""; case CSmove: reposition(); break; case CSdispatch: switch (emacs(c)) { case CSdone: return Line; case CSeof: return NULL; case CSsignal: return (CHAR *)""; case CSmove: reposition(); break; case CSdispatch: case CSstay: break; } break; case CSstay: break; } return NULL;}STATIC voidhist_add(p) CHAR *p;{ int i; if ((p = (CHAR *)strdup((char *)p)) == NULL) return; if (H.Size < HIST_SIZE) H.Lines[H.Size++] = p; else { DISPOSE(H.Lines[0]); for (i = 0; i < HIST_SIZE - 1; i++) H.Lines[i] = H.Lines[i + 1]; H.Lines[i] = p; } H.Pos = H.Size - 1;}/*** For compatibility with FSF readline.*//* ARGSUSED0 */voidrl_reset_terminal(p) char *p;{}voidrl_initialize(){}char *readline(prompt) CONST char *prompt;{ CHAR *line; int s; if (Line == NULL) { Length = MEM_INC; if ((Line = NEW(CHAR, Length)) == NULL) return NULL; } TTYinfo(); rl_ttyset(0); hist_add(NIL); ScreenSize = SCREEN_INC; Screen = NEW(char, ScreenSize); Prompt = prompt ? prompt : (char *)NIL; TTYputs((CONST CHAR *)Prompt); if ((line = editinput()) != NULL) { line = (CHAR *)strdup((char *)line); TTYputs((CHAR *)NEWLINE); TTYflush(); } rl_ttyset(1); DISPOSE(Screen); DISPOSE(H.Lines[--H.Size]); if (Signal > 0) { s = Signal; Signal = 0; (void)kill(getpid(), s); } return (char *)line;}voidadd_history(p) char *p;{ if (p == NULL || *p == '\0') return;#if defined(UNIQUE_HISTORY) if (H.Pos && strcmp(p, (char *) H.Lines[H.Pos - 1]) == 0) return;#endif /* defined(UNIQUE_HISTORY) */ if (H.Size && strcmp(p, (char *) H.Lines[H.Size - 1]) == 0) return; hist_add((CHAR *)p);}STATIC STATUSbeg_line(){ if (Point) { Point = 0; return CSmove; } return CSstay;}STATIC STATUSdel_char(){ return delete_string(Repeat == NO_ARG ? 1 : Repeat);}STATIC STATUSend_line(){ if (Point != End) { Point = End; return CSmove; } return CSstay;}/*** Move back to the beginning of the current word and return an** allocated copy of it.*/STATIC CHAR *find_word(){ static char SEPS[] = "#:;&|^$=`'{}()<>\n\t "; CHAR *p; CHAR *new; SIZE_T len; for (p = &Line[Point]; p > Line && strchr(SEPS, (char)p[-1]) == NULL; p--) continue; len = Point - (p - Line) + 1; if ((new = NEW(CHAR, len)) == NULL) return NULL; COPYFROMTO(new, p, len); new[len - 1] = '\0'; return new;}STATIC STATUSc_possible(){ CHAR **av; CHAR *word; int ac; word = find_word(); ac = rl_list_possib((char *)word, (char ***)&av); if (word) DISPOSE(word); if (ac) { columns(ac, av); while (--ac >= 0) DISPOSE(av[ac]); DISPOSE(av); return CSmove; } return ring_bell();}STATIC STATUSc_complete(){ CHAR *p; CHAR *word; int unique; STATUS s; word = find_word(); p = (CHAR *)rl_complete((char *)word, &unique); if (word) DISPOSE(word); if (p && *p) { s = insert_string(p);#if ANNOYING_NOISE if (!unique) (void)ring_bell();#endif DISPOSE(p); return s; } return c_possible();}STATIC STATUSaccept_line(){ Line[End] = '\0'; return CSdone;}STATIC STATUStranspose(){ CHAR c; if (Point) { if (Point == End) left(CSmove); c = Line[Point - 1]; left(CSstay); Line[Point - 1] = Line[Point]; TTYshow(Line[Point - 1]); Line[Point++] = c; TTYshow(c); } return CSstay;}STATIC STATUSquote(){ unsigned int c; return (c = TTYget()) == EOF ? CSeof : insert_char((int)c);}STATIC STATUSwipe(){ int i; if (Mark > End) return ring_bell(); if (Point > Mark) { i = Point; Point = Mark; Mark = i; reposition(); } return delete_string(Mark - Point);}STATIC STATUSmk_set(){ Mark = Point; return CSstay;}STATIC STATUSexchange(){ unsigned int c; if ((c = TTYget()) != CTL('X')) return c == EOF ? CSeof : ring_bell(); if ((c = Mark) <= End) { Mark = Point; Point = c; return CSmove; } return CSstay;}STATIC STATUSyank(){ if (Yanked && *Yanked) return insert_string(Yanked); return CSstay;}STATIC STATUScopy_region(){ if (Mark > End) return ring_bell(); if (Point > Mark) save_yank(Mark, Point - Mark); else save_yank(Point, Mark - Point); return CSstay;}STATIC STATUSmove_to_char(){ unsigned int c; int i; CHAR *p; if ((c = TTYget()) == EOF) return CSeof; for (i = Point + 1, p = &Line[i]; i < End; i++, p++) if (*p == c) { Point = i; return CSmove; } return CSstay;}STATIC STATUSfd_word(){ return do_forward(CSmove);}STATIC STATUSfd_kill_word(){ int i; (void)do_forward(CSstay); if (OldPoint != Point) { i = Point - OldPoint; Point = OldPoint; return delete_string(i); } return CSstay;}STATIC STATUSbk_word(){ int i; CHAR *p; i = 0; do { for (p = &Line[Point]; p > Line && !isalnum(p[-1]); p--) left(CSmove); for (; p > Line && p[-1] != ' ' && isalnum(p[-1]); p--) left(CSmove); if (Point == 0) break; } while (++i < Repeat); return CSstay;}STATIC STATUSbk_kill_word(){ (void)bk_word(); if (OldPoint != Point) return delete_string(OldPoint - Point); return CSstay;}STATIC intargify(line, avp) CHAR *line; CHAR ***avp;{ CHAR *c; CHAR **p; CHAR **new; int ac; int i; i = MEM_INC; if ((*avp = p = NEW(CHAR*, i))== NULL) return 0; for (c = line; isspace(*c); c++) continue; if (*c == '\n' || *c == '\0') return 0; for (ac = 0, p[ac++] = c; *c && *c != '\n'; ) { if (isspace(*c)) { *c++ = '\0'; if (*c && *c != '\n') { if (ac + 1 == i) { new = NEW(CHAR*, i + MEM_INC); if (new == NULL) { p[ac] = NULL; return ac; } COPYFROMTO(new, p, i * sizeof (char **)); i += MEM_INC; DISPOSE(p); *avp = p = new; } p[ac++] = c; } } else c++; } *c = '\0'; p[ac] = NULL; return ac;}STATIC STATUSlast_argument(){ CHAR **av; CHAR *p; STATUS s; int ac; if (H.Size == 1 || (p = H.Lines[H.Size - 2]) == NULL) return ring_bell(); if ((p = (CHAR *)strdup((char *)p)) == NULL) return CSstay; ac = argify(p, &av); if (Repeat != NO_ARG) s = Repeat < ac ? insert_string(av[Repeat]) : ring_bell(); else s = ac ? insert_string(av[ac - 1]) : CSstay; if (ac) DISPOSE(av); DISPOSE(p); return s;}STATIC KEYMAP Map[33] = { { CTL('@'), mk_set }, { CTL('A'), beg_line }, { CTL('B'), bk_char }, { CTL('D'), del_char }, { CTL('E'), end_line }, { CTL('F'), fd_char }, { CTL('G'), ring_bell }, { CTL('H'), bk_del_char }, { CTL('I'), c_complete }, { CTL('J'), accept_line }, { CTL('K'), kill_line }, { CTL('L'), redisplay }, { CTL('M'), accept_line }, { CTL('N'), h_next }, { CTL('O'), ring_bell }, { CTL('P'), h_prev }, { CTL('Q'), ring_bell }, { CTL('R'), h_search }, { CTL('S'), ring_bell }, { CTL('T'), transpose }, { CTL('U'), ring_bell }, { CTL('V'), quote }, { CTL('W'), bk_kill_word }, { CTL('X'), exchange }, { CTL('Y'), yank }, { CTL('Z'), end_line }, { CTL('['), meta }, { CTL(']'), move_to_char }, { CTL('^'), ring_bell }, { CTL('_'), ring_bell }, { 0, NULL }};STATIC KEYMAP MetaMap[17]= { { CTL('H'), wipe }, { DEL, wipe }, { ' ', mk_set }, { '.', last_argument }, { '<', h_first }, { '>', h_last }, { '?', c_possible }, { 'b', bk_word }, { 'd', fd_kill_word }, { 'f', fd_word }, { 'l', case_down_word }, { 'm', toggle_meta_mode }, { 'u', case_up_word }, { 'y', yank }, { 'w', copy_region }, { 0, NULL }};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -