?? 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);
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
#endif
void 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 _STANDALONE
int 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 + -