📄 hist.c
字号:
break; case 'B': forward_history(); break; case 'C': forward_char(); break; case 'D': backward_char(); break; }}static voidback_over_char(ch) char ch;{ backspace(); if (!isprint(ch)) backspace();}static voidremove_char(ch) char ch;{ erasechar(); if (!isprint(ch)) erasechar();}static voidecho_rest_of_line(){ echo_string(HS.pos, HS.end - HS.pos);}static voidgoto_start_of_line(){ while (HS.pos > HS.buf) back_over_char(*--HS.pos);}static voidgoto_end_of_line(){ echo_rest_of_line(); HS.pos = HS.end;}static voiddecrement_end(n) int n;{ HS.end -= n; if (HS.mark && (HS.mark > HS.end)) HS.mark = NULL;}static voidignore_char(){}static voidflush_input(){ echo_rest_of_line(); while (HS.end > HS.buf) remove_char(*--HS.end); HS.pos = HS.buf; HS.mark = NULL;}static voidstart_of_line(){ goto_start_of_line();}static voidend_of_line(){ goto_end_of_line();}static voidforward_char(){ if (HS.pos < HS.end) echo_char(*HS.pos++);}static voidbackward_char(){ if (HS.pos > HS.buf) back_over_char(*--HS.pos);}static voiduppercase_word(){ while ((HS.pos < HS.end) && !in_word(*HS.pos)) echo_char(*HS.pos++); while ((HS.pos < HS.end) && in_word(*HS.pos)) { if ((*HS.pos >= 'a') && (*HS.pos <= 'z')) *HS.pos += 'A' - 'a'; echo_char(*HS.pos++); }}static voidlowercase_word(){ while ((HS.pos < HS.end) && !in_word(*HS.pos)) echo_char(*HS.pos++); while ((HS.pos < HS.end) && in_word(*HS.pos)) { if ((*HS.pos >= 'A') && (*HS.pos <= 'Z')) *HS.pos += 'a' - 'A'; echo_char(*HS.pos++); }}static voidforward_word(){ while ((HS.pos < HS.end) && !in_word(*HS.pos)) echo_char(*HS.pos++); while ((HS.pos < HS.end) && in_word(*HS.pos)) echo_char(*HS.pos++);}static voidbackward_word(){ if ((HS.pos > HS.buf) && in_word(*HS.pos)) back_over_char(*--HS.pos); while ((HS.pos > HS.buf) && !in_word(*HS.pos)) back_over_char(*--HS.pos); while ((HS.pos > HS.buf) && in_word(*HS.pos)) back_over_char(*--HS.pos); if ((HS.pos < HS.end) && !in_word(*HS.pos)) echo_char(*HS.pos++);}static voidforward_kill_char(){ int rest; char ch; rest = HS.end - HS.pos; if (rest-- <= 0) return; ch = *HS.pos; if (rest > 0) { memcpy(HS.pos, HS.pos + 1, rest); *(HS.end - 1) = ch; } echo_rest_of_line(); remove_char(ch); decrement_end(1); while (rest > 0) back_over_char(HS.pos[--rest]);}static voiddelete_char(){ if (HS.end > HS.buf) forward_kill_char();}static voidbackward_kill_char(){ if (HS.pos > HS.buf) { HS.pos--; back_over_char(*HS.pos); forward_kill_char(); }}static voidforward_kill_word(){ char *cp; if (HS.pos >= HS.end) return; echo_rest_of_line(); for (cp = HS.end; cp > HS.pos;) remove_char(*--cp); cp = HS.pos; while ((cp < HS.end) && !in_word(*cp)) cp++; while ((cp < HS.end) && in_word(*cp)) cp++; savetext(HS.pos, cp - HS.pos); memcpy(HS.pos, cp, HS.end - cp); decrement_end(cp - HS.pos); echo_rest_of_line(); for (cp = HS.end; cp > HS.pos;) back_over_char(*--cp);}static voidkill_line(){ if (HS.end <= HS.pos) return; savetext(HS.pos, HS.end - HS.pos); echo_rest_of_line(); while (HS.end > HS.pos) remove_char(*--HS.end); decrement_end(0);}/* * This is the function which completes a command line editing session. * The final line length is returned in the HS.linelen variable. * The line is NOT put into the edit history, so that the caller can * decide whether or not this should be done. */static voidnew_line(){ int len; newline(); fflush(stdout); HS.mark = NULL; HS.end[0] = '\n'; HS.end[1] = '\0'; len = HS.end - HS.buf + 1; if (len <= 1) { HS.curhist = HS.histcount; HS.linelen = 1; return; } HS.curhist = HS.histcount; HS.pos = HS.buf; HS.end = HS.buf; HS.linelen = len;}static voidsave_line(){ int len; len = HS.end - HS.buf; if (len > 0) { hist_saveline(HS.buf, len); flush_input(); } HS.curhist = HS.histcount;}static voidgoto_line(){ int num; char *cp; HIST *hp; num = 0; cp = HS.buf; while ((*cp >= '0') && (*cp <= '9') && (cp < HS.pos)) num = num * 10 + (*cp++ - '0'); if ((num <= 0) || (num > HS.histcount) || (cp != HS.pos)) { beep(); return; } flush_input(); HS.curhist = HS.histcount - num; hp = get_event(HS.curhist); memcpy(HS.buf, hp->data, hp->len); HS.end = &HS.buf[hp->len]; goto_end_of_line();}static voidforward_history(){ HIST *hp; flush_input(); if (++HS.curhist >= HS.histcount) HS.curhist = 0; hp = get_event(HS.curhist); if (hp) { memcpy(HS.buf, hp->data, hp->len); HS.end = &HS.buf[hp->len]; } goto_end_of_line();}static voidbackward_history(){ HIST *hp; flush_input(); if (--HS.curhist < 0) HS.curhist = HS.histcount - 1; hp = get_event(HS.curhist); if (hp) { memcpy(HS.buf, hp->data, hp->len); HS.end = &HS.buf[hp->len]; } goto_end_of_line();}static voidinsert_char(key) int key;{ int len; int rest; len = HS.end - HS.buf; if (len >= HS.bufsize) { beep(); return; } rest = HS.end - HS.pos; if (rest > 0) memrcpy(HS.pos + 1, HS.pos, rest); HS.end++; *HS.pos++ = key; echo_char(key); echo_rest_of_line(); while (rest > 0) back_over_char(HS.pos[--rest]);}static voidinsert_string(str, len) int len; char *str;{ int rest; int totallen; if (len <= 0) return; totallen = (HS.end - HS.buf) + len; if (totallen > HS.bufsize) { beep(); return; } rest = HS.end - HS.pos; if (rest > 0) memrcpy(HS.pos + len, HS.pos, rest); HS.end += len; memcpy(HS.pos, str, len); HS.pos += len; echo_string(str, len); echo_rest_of_line(); while (rest > 0) back_over_char(HS.pos[--rest]);}static voidlist_history(){ HIST *hp; int num; for (num = 0; num < HS.histcount; num++) { hp = get_event(num); printf("\n%3d: ", HS.histcount - num); echo_string(hp->data, hp->len); } refresh_line();}static voidrefresh_line(){ char *cp; newline(); fputs(HS.prompt, stdout); if (HS.end > HS.buf) { echo_string(HS.buf, HS.end - HS.buf); cp = HS.end; while (cp > HS.pos) back_over_char(*--cp); }}static voidswap_chars(){ char ch1; char ch2; if ((HS.pos <= HS.buf) || (HS.pos >= HS.end)) return; ch1 = *HS.pos--; ch2 = *HS.pos; *HS.pos++ = ch1; *HS.pos = ch2; back_over_char(ch2); echo_char(ch1); echo_char(ch2); back_over_char(ch2);}static voidset_mark(){ HS.mark = HS.pos;}static voidsave_region(){ int len; if (HS.mark == NULL) return; len = HS.mark - HS.pos; if (len > 0) savetext(HS.pos, len); if (len < 0) savetext(HS.mark, -len);}static voidkill_region(){ char *cp; char *left; char *right; if ((HS.mark == NULL) || (HS.mark == HS.pos)) return; echo_rest_of_line(); if (HS.mark < HS.pos) { left = HS.mark; right = HS.pos; HS.pos = HS.mark; } else { left = HS.pos; right = HS.mark; HS.mark = HS.pos; } savetext(left, right - left); for (cp = HS.end; cp > left;) remove_char(*--cp); if (right < HS.end) memcpy(left, right, HS.end - right); decrement_end(right - left); echo_rest_of_line(); for (cp = HS.end; cp > HS.pos;) back_over_char(*--cp);}static voidyank(){ insert_string(save_buffer, save_len);}static voidreverse_search(){ int len; int count; int testhist; HIST *hp; char *save_pos; count = HS.histcount; len = HS.pos - HS.buf; if (len <= 0) count = 0; testhist = HS.curhist; do { if (--count < 0) { beep(); return; } if (--testhist < 0) testhist = HS.histcount - 1; hp = get_event(testhist); } while ((hp == NULL) || (hp->len < len) || memcmp(hp->data, HS.buf, len)); HS.curhist = testhist; save_pos = HS.pos; flush_input(); memcpy(HS.buf, hp->data, hp->len); HS.end = &HS.buf[hp->len]; goto_end_of_line(); while (HS.pos > save_pos) back_over_char(*--HS.pos);}static voidquote_char(){ int ch; ch = fgetc(stdin); if (ch != EOF) insert_char(ch);}/* * Save data in the save buffer. */static voidsavetext(str, len) int len; char *str;{ save_len = 0; if (len <= 0) return; if (len > SAVE_SIZE) len = SAVE_SIZE; memcpy(save_buffer, str, len); save_len = len;}/* * Test whether a character is part of a word. */static intin_word(ch) char ch;{ return (isalnum(ch) || (ch == '_'));}static voiderasechar(){ fputs("\b \b", stdout);}static voidnewline(){ fputc('\n', stdout);}static voidbackspace(){ fputc('\b', stdout);}static voidbeep(){ fputc('\007', stdout);}static voidecho_char(ch) int ch;{ if (isprint(ch)) putchar(ch); else { putchar('^'); putchar((ch + '@') & 0x7f); }}static voidecho_string(str, len) int len; char *str;{ while (len-- > 0) echo_char(*str++);}static voidmemrcpy(dest, src, len) int len; char *dest, *src;{ dest += len - 1; src += len - 1; while (len-- > 0) *dest-- = *src--;}static voidquit_calc(){ hist_term(); putchar('\n'); exit(0);}#ifdef HIST_TEST/* * Main routine to test history. */main(argc, argv) int argc; char *argv[];{ char *filename; int len; char buf[256]; filename = NULL; if (argc > 1) filename = argv[1]; switch (hist_init(filename)) { case HIST_SUCCESS: break; case HIST_NOFILE: fprintf(stderr, "Binding file was not found\n"); break; case HIST_NOTTY: fprintf(stderr, "Cannot set terminal parameters\n"); break; case HIST_INITED: fprintf(stderr, "Hist is already inited\n"); break; default: fprintf(stderr, "Unknown error from hist_init\n"); break; } do { len = hist_getline("HIST> ", buf, sizeof(buf)); hist_saveline(buf, len); } while (len && (buf[0] != 'q')); hist_term(); return 0;}#endif/* END CODE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -