void rl_echo(t_rl *rl) { char buff[2048]; size_t len; if (!rl_checkperf(rl->used, &len)) { if (len) ft_fprintf(1, "%*.*s", len, len, "...[Echo stop here... but line still saving input ;)]"); return ; } if (rl->diff.type == RL_TCURSORONLY) rl_goto(buff, *echo_cursor(), rl->ante_cursor); else { rl_goto(buff, *echo_cursor(), rl->diff.begin); tm_cap("cd"); if (rl->diff.type == RL_TAPPEND) write(1, rl->buffer + rl->diff.begin, rl->diff.offset); if (rl->real != rl->post_cursor) { write(1, rl->buffer + rl->post_cursor, rl->real - rl->post_cursor); rl_last_co(rl->used); } rl_goto(buff, rl->used, rl->ante_cursor); } *echo_cursor() = rl->ante_cursor; }
/* * Handle kill character */ static void rl_key_kill (void) { rl_goto (0); rl_linecompress (&rl_temp, 0, -1); s_repl (&rl_yank, rl_temp.txt); rl_tab_state = 0; rl_tab_len = 0; rl_key_cut (); }
/* * Shows the prompt */ void ReadLinePrompt () { int gpos = rl_colpos; if (rl_prompt_stat == 1) return; #if DEBUG_RL fprintf (stderr, "killoper: %s\n", s_qquote (rl_operate.txt)); #endif s_init (&rl_operate, "", 0); if (rl_prompt_stat == 2) rl_goto (0); if (rl_prompt_stat == 2) { s_catc (&rl_operate, '\r'); #ifdef ANSI_TERM s_cat (&rl_operate, ANSI_CLEAR); #endif rl_prompt_stat = 0; } #if DEBUG_RL fprintf (stderr, "oper(rm): %s\n", s_qquote (rl_operate.txt)); #endif printf ("%s", rl_operate.txt); if (rl_prompt_stat == 0) { rl_print ("\r"); rl_print (rl_prompt.txt); rl_prompt_len = rl_pos (); rl_prompt_stat = 1; rl_colpos = 0; } s_init (&rl_operate, "", 0); rl_recheck (TRUE); rl_goto (gpos); printf ("%s", rl_operate.txt); }
/* * Handle end key */ static void rl_key_end (void) { int gpos; if (rl_tab_state > 0) rl_tab_accept (); if (rl_ucspos >= rl_ucscol.len) return; gpos = rl_colpos; while (rl_ucspos < rl_ucscol.len) gpos += rl_ucscol.txt[rl_ucspos++]; rl_goto (gpos); }
static void rl_checkautoexpand (void) { const char *replacement; if (!rl_bytepos) return; rl_linecompress (&rl_temp, 0, -1); replacement = AliasExpand (rl_temp.txt, rl_bytepos, TRUE); if (!replacement) return; rl_tab_state = 0; rl_goto (0); rl_lineexpand (replacement); }
/* * Re-check remaining line for multicolumn line break problems */ static void rl_recheck (BOOL clear) { int gpos, i; gpos = rl_colpos; while (rl_ucspos < rl_ucscol.len) { if (rl_ucs_at (&rl_ucs, rl_ucspos) == WEOF) { s_deln (&rl_ucs, sizeof (wint_tt) * rl_ucspos, sizeof (wint_tt)); s_delc (&rl_ucsbytes, rl_ucspos); s_delc (&rl_ucscol, rl_ucspos); s_delc (&rl_display, rl_bytepos); } else if (((rl_prompt_len + rl_colpos) % rl_columns) + (UBYTE)rl_ucscol.txt[rl_ucspos] > rl_columns) { for (i = (rl_columns - ((rl_prompt_len + rl_colpos) % rl_columns)); i > 0; i--) { wint_tt weof = WEOF; s_insn (&rl_ucs, sizeof (wint_tt) * rl_ucspos, (const char *)&weof, sizeof (wint_tt)); s_insc (&rl_ucscol, rl_ucspos, 1); s_insc (&rl_ucsbytes, rl_ucspos++, 1); s_insc (&rl_display, rl_bytepos++, ' '); s_catc (&rl_operate, ' '); rl_colpos++; } } else { s_catn (&rl_operate, rl_display.txt + rl_bytepos, rl_ucsbytes.txt[rl_ucspos]); rl_bytepos += rl_ucsbytes.txt[rl_ucspos]; rl_colpos += rl_ucscol.txt[rl_ucspos]; rl_ucspos++; } } #ifdef ANSI_TERM s_cat (&rl_operate, " \b"); if (clear) s_cat (&rl_operate, ANSI_CLEAR); #else s_cat (&rl_operate, " \b\b\b\b\b"); #endif rl_goto (gpos); }
/* * Hides the prompt */ void ReadLinePromptHide () { int pos = rl_colpos; ReadLineHandleSig (); if (rl_prompt_stat == 0) return; s_init (&rl_operate, "", 0); rl_goto (0); s_catc (&rl_operate, '\r'); #ifdef ANSI_TERM s_cat (&rl_operate, ANSI_CLEAR); #endif printf ("%s", rl_operate.txt); rl_prompt_stat = 0; rl_colpos = pos; rl_print ("\r"); }
/* * Go an amount of glyphs to the right */ static int rl_right (UDWORD i) { int gpos; if (rl_ucspos >= rl_ucscol.len) return FALSE; gpos = rl_colpos; for ( ; i > 0; i--) { if (rl_ucspos < rl_ucscol.len) gpos += rl_ucscol.txt[rl_ucspos++]; while (rl_ucspos < rl_ucscol.len && (!rl_ucscol.txt[rl_ucspos] || (rl_ucs_at (&rl_ucs, rl_ucspos) == WEOF))) gpos += rl_ucscol.txt[rl_ucspos++]; } rl_goto (gpos); return TRUE; }
/* * Go an amount of glyphs to the left */ static int rl_left (UDWORD i) { int gpos; if (!rl_ucspos) return FALSE; gpos = rl_colpos; for ( ; i > 0; i--) { while (rl_ucspos > 0 && (!rl_ucscol.txt[rl_ucspos - 1] || (rl_ucs_at (&rl_ucs, rl_ucspos - 1) == WEOF))) gpos -= rl_ucscol.txt[--rl_ucspos]; if (rl_ucspos > 0) gpos -= rl_ucscol.txt[--rl_ucspos]; } rl_goto (gpos); return TRUE; }
/* * Process one byte of input */ str_t ReadLine (UBYTE newbyte) { strc_t input, inputucs; static UWORD ucsesc; UWORD ucs; ReadLineHandleSig (); s_catc (&rl_input, newbyte); input = ConvFrom (&rl_input, prG->enc_loc); if (input->txt[0] == CHAR_INCOMPLETE) { if (strcmp (rl_input.txt, ConvTo (input->txt, prG->enc_loc)->txt)) return NULL; } rl_inputdone = 0; rl_signal &= ~1; inputucs = ConvTo (input->txt, ENC_UCS2BE); ucs = ((UBYTE)inputucs->txt[1]) | (((UBYTE)inputucs->txt[0]) << 8); s_init (&rl_input, "", 0); s_init (&rl_operate, "", 0); rl_dump_line (); ReadLinePrompt (); switch (rl_stat) { case 0: if (0) ; #if HAVE_TCGETATTR #if defined(VERASE) else if (ucs == tty_attr.c_cc[VERASE] && tty_attr.c_cc[VERASE] != _POSIX_VDISABLE) rl_key_backspace (); #endif #if defined(VEOF) else if (ucs == tty_attr.c_cc[VEOF] && tty_attr.c_cc[VEOF] != _POSIX_VDISABLE) { rl_tab_cancel (); if (rl_ucscol.len) { rl_key_left (); rl_key_delete (); } else { rl_insert ('q'); rl_historyadd (); } } #endif #if defined(VKILL) else if (ucs == tty_attr.c_cc[VKILL] && tty_attr.c_cc[VKILL] != _POSIX_VDISABLE) rl_key_kill (); #endif #if defined(VREPRINT) else if (ucs == tty_attr.c_cc[VREPRINT] && tty_attr.c_cc[VREPRINT] != _POSIX_VDISABLE) ReadLinePromptHide (); #endif #endif else switch (ucs) { case 1: /* ^A */ rl_tab_cancel (); rl_goto (0); break; case 5: /* ^E */ rl_key_end (); break; case 8: /* ^H = \b */ rl_key_backspace (); break; case 9: /* ^I = \t */ rl_key_tab (); break; case 11: /* ^K */ rl_key_cut (); break; case 12: /* ^L */ ReadLineClrScr (); break; case '\r': case '\n': rl_tab_accept (); if (rl_tab_state == 0) rl_checkautoexpand (); rl_key_end (); rl_historyadd (); break; case 23: /* ^W */ rl_key_delete_backward_word (); break; case 25: /* ^Y */ if (rl_yank) { rl_tab_state = 0; rl_goto (0); rl_lineexpand (rl_yank); } break; case 27: /* ^[ = ESC */ #ifdef ANSI_TERM rl_stat = 1; #endif break; case 32: /* = SPACE */ if (rl_tab_state > 0) rl_tab_accept (); else if (rl_tab_state == 0) rl_checkautoexpand (); rl_insert (' '); break; case 127: /* DEL */ if (prG->flags & FLAG_DELBS) rl_key_backspace (); else rl_key_delete (); break; case 0x9b: /* CSI */ #ifdef ANSI_TERM if (ENC(enc_loc) == ENC_LATIN1) { rl_stat = 2; break; } #else printf ("\a"); break; #endif /* fall-through */ default: rl_key_insert (ucs); } break; #ifdef ANSI_TERM case 1: /* state 1: ESC was pressed */ rl_stat = 0; if (ucs == 'u' || ucs == 'U') rl_stat = 10; else if (ucs == '[' || ucs == 'O') rl_stat = 2; else if (ucs == 'b') rl_key_backward_word (); else if (ucs == 'f') rl_key_forward_word (); else if (ucs == 127) rl_key_delete_backward_word (); else printf ("\a"); break; case 2: /* state 2: CSI was typed */ rl_stat = 0; switch (ucs) { case 'A': /* up */ rl_tab_cancel (); rl_historyback (); break; case 'B': /* down */ rl_tab_cancel (); rl_historyforward (); break; case 'C': /* right */ rl_key_right (); break; case 'D': /* left */ rl_key_left (); break; case 'H': /* home */ rl_tab_cancel (); rl_goto (0); break; case 'F': /* end */ rl_key_end (); break; case 'Z': /* shift tab */ rl_key_shifttab (); break; case '3': /* + ~ = delete */ rl_stat = 3; break; case '1': /* + ~ = home */ case '7': /* + ~ = home */ rl_stat = 4; break; case '4': /* + ~ = end */ case '8': /* + ~ = end */ rl_stat = 5; break; default: printf ("\a"); } break; case 3: /* state 3: incomplete delete key */ rl_stat = 0; if (ucs == '~') rl_key_delete (); else printf ("\a"); break; case 4: /* state 4: incomplete home key */ rl_stat = 0; if (ucs == '~') { rl_tab_cancel (); rl_goto (0); } else printf ("\a"); break; case 5: /* state 5: incomplete end key */ rl_stat = 0; if (ucs == '~') rl_key_end (); else printf ("\a"); break; case 10: /* state 10: unicode sequence to be entered */ rl_stat++; if (ucs >= '0' && ucs <= '9') ucsesc = ucs - '0'; else if (ucs >= 'a' && ucs <= 'f') ucsesc = ucs - 'a' + 10; else if (ucs >= 'A' && ucs <= 'F') ucsesc = ucs - 'A' + 10; else { rl_stat = 0; printf ("\a"); } break; case 11: rl_stat++; ucsesc <<= 4; if (ucs >= '0' && ucs <= '9') ucsesc |= ucs - '0'; else if (ucs >= 'a' && ucs <= 'f') ucsesc |= ucs - 'a' + 10; else if (ucs >= 'A' && ucs <= 'F') ucsesc |= ucs - 'A' + 10; else { rl_stat = 0; printf ("\a"); } break; case 12: rl_stat++; ucsesc <<= 4; if (ucs >= '0' && ucs <= '9') ucsesc |= ucs - '0'; else if (ucs >= 'a' && ucs <= 'f') ucsesc |= ucs - 'a' + 10; else if (ucs >= 'A' && ucs <= 'F') ucsesc |= ucs - 'A' + 10; else { rl_stat = 0; printf ("\a"); } break; case 13: rl_stat = 0; ucsesc <<= 4; if (ucs >= '0' && ucs <= '9') ucsesc |= ucs - '0'; else if (ucs >= 'a' && ucs <= 'f') ucsesc |= ucs - 'a' + 10; else if (ucs >= 'A' && ucs <= 'F') ucsesc |= ucs - 'A' + 10; else { printf ("\a"); break; } rl_key_insert (ucsesc); break; } #endif #if DEBUG_RL fprintf (stderr, "oper: %s\n", s_qquote (rl_operate.txt)); #endif rl_dump_line (); if (rl_operate.len) printf ("%s", rl_operate.txt); if (!rl_inputdone) return NULL; printf ("\n"); return &rl_temp; }