📄 readline.c
字号:
redraw_line(prompt); break; case 0177: /* DEL */ case 010: /* ^H */ if(cur_pos > 0) { cur_pos -= 1; backspace(); for(i=cur_pos; i<max_pos; i++) cur_line[i] = cur_line[i+1]; max_pos -= 1; fix_line(); } break; case 004: /* ^D */ if(max_pos == 0) { reset_termio(); return((char *)NULL); } if(cur_pos < max_pos) { for(i=cur_pos; i<max_pos; i++) cur_line[i] = cur_line[i+1]; max_pos -= 1; fix_line(); } break; case 025: /* ^U */ clear_line(prompt); break; case 027: /* ^W */ while((cur_pos > 0) && (cur_line[cur_pos-1] == SPACE)) { cur_pos -= 1; backspace(); } while((cur_pos > 0) && (cur_line[cur_pos-1] != SPACE)) { cur_pos -= 1; backspace(); } clear_eoline(); max_pos = cur_pos; break; case '\n': /* ^J */ case '\r': /* ^M */ user_putc(NEWLINE); cur_line[max_pos+1] = '\0'; cur_line = (char *)ralloc(cur_line, (unsigned long)(strlen(cur_line)+2), "line resize"); line_len=0; reset_termio(); return cur_line; default: break; } } }}/* fix up the line from cur_pos to max_pos *//* do not need any terminal capabilities except backspace, *//* and space overwrites a character */static void fix_line(){ int i; /* write tail of string */ user_putsn(&cur_line[cur_pos],max_pos - cur_pos); /* write a space at the end of the line in case we deleted one */ user_putc(SPACE); /* backup to original position */ for(i=max_pos+1; i>cur_pos; i--) backspace();}/* redraw the entire line, putting the cursor where it belongs */static void redraw_line(char *prompt){ int i; user_puts(prompt); user_puts(cur_line); /* put the cursor where it belongs */ for(i=max_pos; i>cur_pos; i--) backspace();}/* clear cur_line and the screen line */static void clear_line(char *prompt){ int i; memset(cur_line,0,max_pos); for(i=cur_pos; i>0; i--) backspace(); for(i=0; i<max_pos; i++) user_putc(SPACE); user_putc('\r'); user_puts(prompt); cur_pos = 0; max_pos = 0;}static void backupTo(char to, char from){ int cmode = 0; int k = 1,i = cur_pos-1; backspace(); while(i-- > 0) { backspace(); if(cur_line[i] == '\'') { if(cmode & 1) cmode &= ~1; else cmode |= 1; continue; }else if(cur_line[i] == '\"') { if(cmode & 2) cmode &= ~2; else cmode |= 2; continue; } if(cur_line[i] == to && !cmode) { if(!--k) break; }else if(cur_line[i] == from && !cmode) k++; } if(k) { user_putc(BELL); i = 0; } else delay(CLOCKS_PER_SEC / 2); user_putsn(&cur_line[i],cur_pos - i);} /* clear to end of line and the screen end of line */static void clear_eoline(){ int i; for(i=cur_pos; i<max_pos; i++) cur_line[i] = '\0'; for(i=cur_pos; i<max_pos; i++) user_putc(SPACE); for(i=cur_pos; i<max_pos; i++) backspace();}/* copy line to cur_line, draw it and set cur_pos and max_pos */static void copy_line(char *line){ while(strlen(line)+1>line_len) { extend_cur_line(); } strcpy(cur_line, line); user_puts(cur_line); cur_pos = max_pos = strlen(cur_line);}/* add line to the history */#ifndef _HistLimit /* history limiter */#define _HistLimit 500#endifvoid EiC_add_history(unsigned char *line){ static unsigned int limit = 0; struct hist *entry; if(limit == _HistLimit && EndHist) { free(EndHist->line); entry = EndHist; EndHist = EndHist->next; EndHist->prev = NULL; } else { entry = (struct hist *)alloc((unsigned long)sizeof(struct hist),"history"); limit++; } entry->line = alloc((unsigned long)(strlen(line)+1),"history"); strcpy(entry->line, line); entry->prev = history; entry->next = NULL; if(history != NULL) { history->next = entry; } else /* get first entry */ EndHist = entry; history = entry; HistLineNo++;}int EiC_getHistLineNo(){ return HistLineNo;} void EiC_save_history(FILE *to, int from){ int cl = HistLineNo - 1; struct hist *p; p = history; while(cl-- > from) p = p->prev; while(p) { fprintf(to,"%s\n",p->line); p = p->next; }}/* show all history lines */void EiC_show_history(FILE *fp){ struct hist *p; p = EndHist; while(p) { fputs(p->line,fp); putc(NEWLINE,fp); p = p->next; } fflush(fp);}int EiC_load_history(char * fname, int prompt){#define BufSz 512 int i; char buff[BufSz]; char *line; FILE *fp = fopen(fname,"r"); if(prompt) set_termio(); if(fp) { while(fgets(buff,BufSz-2,fp)) { for(i=0;buff[i] && buff[i] != '\n';++i) ; if(!buff[i]) buff[i++] = '\\'; buff[i] = 0; if(prompt) { printf("Re-enter [%s] (Y/N/E)?",buff); switch(special_getc()) { case 'y': case 'Y': user_puts(" Y\n"); break; case 'e': case 'E': user_puts(" E\n"); copy_line(buff); line = editLine("edit: "); if(*line) EiC_add_history(line); free(line); set_termio(); continue; default: user_puts(" N\n"); continue; } } EiC_add_history(buff); } fclose(fp); i = 1; } else i = 0; if(prompt) reset_termio(); printf("added %d lines\n",HistLineNo); return i;#undef BufSz} #if defined(WIN32)/* Convert Arrow keystrokes to Control characters: */static char msdos_getch(){ int c = _getch(); if (c == 224 || c== 0) { c = _getch(); /* Get the extended code. */ switch (c) { case 75: /* Left Arrow. */ c = 002; break; case 77: /* Right Arrow. */ c = 006; break; case 72: /* Up Arrow. */ c = 020; break; case 80: /* Down Arrow. */ c = 016; break; case 115: /* Ctl Left Arrow. */ case 71: /* Home */ c = 001; break; case 116: /* Ctl Right Arrow. */ case 79: /* End */ c = 005; break; case 83: /* Delete */ c = 004; break; default: c = 0; break; } } else if (c == 033) { /* ESC */ c = 025; } return c;}static void set_termio() {} static void reset_termio() {}#else/* Convert ANSI arrow keys to control characters */static int ansi_getc(){ int c = getc(stdin); if (c == 033) { c = getc(stdin); /* check for CSI */ if (c == '[') { c = getc(stdin); /* get command character */ switch (c) { case 'D': /* left arrow key */ c = 002; break; case 'C': /* right arrow key */ c = 006; break; case 'A': /* up arrow key */ c = 020; break; case 'B': /* down arrow key */ c = 016; break; } } } return c;}/* set termio so we can do our own input processing */static void set_termio(){ if(term_set == 0) { tcgetattr(0, &orig_termio); rl_termio = orig_termio; rl_termio.c_iflag &= ~(BRKINT|PARMRK|INPCK/*|IUCLC*/|IXON|IXOFF); rl_termio.c_iflag |= (IGNBRK|IGNPAR); /* rl_termio.c_oflag &= ~(ONOCR); Costas Sphocleous Irvine,CA */ rl_termio.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|NOFLSH); rl_termio.c_lflag |= (ISIG); rl_termio.c_cc[VMIN] = 1; rl_termio.c_cc[VTIME] = 0; term_chars[VERASE] = orig_termio.c_cc[VERASE]; term_chars[VEOF] = orig_termio.c_cc[VEOF]; term_chars[VKILL] = orig_termio.c_cc[VKILL]; term_chars[VWERASE] = orig_termio.c_cc[VWERASE]; term_chars[VREPRINT] = orig_termio.c_cc[VREPRINT]; term_chars[VSUSP] = orig_termio.c_cc[VSUSP]; /* disable suspending process on ^Z */ rl_termio.c_cc[VSUSP] = 0; tcsetattr(0, TCSADRAIN, &rl_termio); term_set = 1; } } static void reset_termio(){ if(term_set == 1) { tcsetattr(0, TCSADRAIN, &orig_termio); term_set = 0; }}#endif#ifdef _STANDALONEint main(){ char * line = NULL; printf("**Press ^D in empty line to exit**\n"); do { line = EiC_readline("$$> "); if (line) { if(*line) EiC_add_history(line); free(line); } } while(line); printf("\n-----------------\n"); EiC_show_history(stdout); return 0;}#endif#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -