int execute(int command) { static char command_line[128]; static int savedmac[128]; // sort out size limitations later static int *savedmacp = savedmac; static int nextc = 0; static int ecce_mode = FALSE; static int learning_mode = FALSE; static int update_required = (0==0); static int correction = 0; static int target_col = -1; // nasty modeful hack :-( if (command == ERR) { // *should* repaint the screen any time the keyboard is idle and // the display size has changed. Unfortunately it doesn't until // the next keypress. Not sure why. But better to leave this in // slightly broken than omit resizing altogether, which is severely // broken ... if ((!ecce_mode) && ((LAST_DISPLAY_LINE != LINES-1) || (DISPLAY_RIGHTMOST_COLUMN != COLS))) { LAST_DISPLAY_LINE = LINES-1; DISPLAY_RIGHTMOST_COLUMN = COLS; // update_display(pp, preferred_display_line); // refresh(); // return; } usleep(10000); } else { if (learning_mode) { if (command != ('E'&31)) { *savedmacp++ = command; *savedmacp = ERR; // record keystrokes before all other processing } } if ((command == ('L'&31)) && (!ecce_mode)) { if (learning_mode) { if (savedmacp != savedmac) savedmacp -= 1; // remove final ^L // get key sequence and assign learned commands to key sequence. // key sequence must be unique path through trie, not a prefix, otherwise can't assign. learning_mode = FALSE; if (savedmacp == savedmac) { // ^L^L - treat as a single ^L? clear(); update_required = (0==0); } } else { // Start learning mode! learning_mode = TRUE; savedmacp = savedmac; *savedmacp = ERR; } return; } else if (command == ('E'&31)) { // TEMPORARY PROOF OF CONCEPT: Execute stored macro learning_mode = FALSE; // quick hack to avoid recursion problems savedmacp = savedmac; while (*savedmacp != ERR) { execute(*savedmacp++); } return; } else if ((command == '\r') && (!ecce_mode)) { // don't special-case enter until in ecce mode } else { if ((!ecce_mode) && ((' ' <= command) && (command <= '~'))) { // although we want redefine characters to take precedence, // simply moving this test to the end does not work... ecce_mode = TRUE; nextc = 0; if (preferred_display_line == LAST_DISPLAY_LINE) preferred_display_line -= (correction = 1); LAST_DISPLAY_LINE -= 1; update_required = (0==0); } if (ecce_mode && (command == '\r')) { command_line[nextc] = '\0'; ecce_mode = FALSE; preferred_display_line += correction; correction = 0; LAST_DISPLAY_LINE += 1; nextc = 0; // execute the command here ecinner(command_line); command_line[nextc] = '\0'; target_col = -1; update_display(pp, preferred_display_line); if (*ecce_err != '\0') {int x=DISPLAY_LEFTMOST_COLUMN; char *s; move(LAST_DISPLAY_LINE, 0); s=ecce_err; standout(); for (;;) { if (*s == '\0') break; if (*s == '\n') break; // move(LAST_DISPLAY_LINE+1,x++); addch(*s++); } while (x++ < DISPLAY_RIGHTMOST_COLUMN) addch(' '); standend(); *ecce_err = '\0'; refresh(); } return(TRUE); } else if (ecce_mode) { int x, len; command_line[nextc++] = command; command_line[nextc] = '\0'; if (nextc == 127) nextc = 126; // truncate if (update_required) { update_required = (0!=0); update_display(pp, preferred_display_line); } move(LAST_DISPLAY_LINE+1, DISPLAY_LEFTMOST_COLUMN); standout(); len = strlen(command_line); // NEED TO OUTPUT PROMPT. need generic routine for // handling input line. Must be ready for "F!" so that // it prompts for the find/replace strings, for when we // bind commands like f// to a single key... for (x = 0; x < len; x++) { addch(command_line[x]); } standend(); for (x = DISPLAY_LEFTMOST_COLUMN+len; x < DISPLAY_RIGHTMOST_COLUMN; x++) { addch(' '); } move(LAST_DISPLAY_LINE+1, DISPLAY_LEFTMOST_COLUMN+strlen(command_line)); // Plus strlen(prompt) when added... refresh(); return(TRUE); } } } if (command == '\e' && getch() == ERR) { return(FALSE); // to add: HOME, END (start/end of file) } else if (command == KEY_DOWN || command == '\r') { int line, before, after; preferred_display_line += 1; if (preferred_display_line > LAST_DISPLAY_LINE) preferred_display_line = LAST_DISPLAY_LINE; generate_screen_line_start_pointers(pp, &line, &before); if (target_col < 0) target_col = before; { ecinner("m"); for (;;) { generate_screen_line_start_pointers(pp, &line, &after); if (after >= target_col) break; ecinner("r"); if (*ecce_err != '\0') break; } } update_required = (0==0); } else if (command == KEY_NPAGE || command == ' ' /* "more" clone? */) { preferred_display_line += LAST_DISPLAY_LINE; if (preferred_display_line > LAST_DISPLAY_LINE) preferred_display_line = LAST_DISPLAY_LINE; ecinnerf("m%0d", LAST_DISPLAY_LINE); update_required = (0==0); } else if (command == KEY_UP) { int line, before, after; preferred_display_line -= 1; if (preferred_display_line < FIRST_DISPLAY_LINE) preferred_display_line = FIRST_DISPLAY_LINE; generate_screen_line_start_pointers(pp, &line, &before); if (target_col < 0) target_col = before; { ecinner("m-r0"); for (;;) { generate_screen_line_start_pointers(pp, &line, &after); if (after <= target_col) break; ecinner("l"); } } update_required = (0==0); } else if (command == KEY_PPAGE) { preferred_display_line -= LAST_DISPLAY_LINE; if (preferred_display_line < FIRST_DISPLAY_LINE) preferred_display_line = FIRST_DISPLAY_LINE; ecinnerf("m-%0d", LAST_DISPLAY_LINE); update_required = (0==0); } else if (command == KEY_LEFT) { if (pp == lbeg && pp != fbeg) { ecinner("m-r0"); // see below ... ecinner("(l,m-r0)"); preferred_display_line -= 1; if (preferred_display_line < FIRST_DISPLAY_LINE) preferred_display_line = FIRST_DISPLAY_LINE; } else ecinner("l"); target_col = -1; update_required = (0==0); } else if (command == KEY_RIGHT) { if (fp == lend) { ecinner("m"); // use just ecinner("(r,m)") if ecinner is allowed to update the display info preferred_display_line += 1; if (preferred_display_line > LAST_DISPLAY_LINE) preferred_display_line = LAST_DISPLAY_LINE; } else ecinner("r"); target_col = -1; update_required = (0==0); } else if (command == ' ') { // 'next' - re-execute last ecce command ecinner("1"); target_col = -1; update_required = (0==0); } else if (command == ('L'&31)) { // refresh clear(); update_required = (0==0); } else if (command == ERR) { // update only when there is no more type-ahead if (update_required) { update_display(pp, preferred_display_line); refresh(); } update_required = (0!=0); } else { // Debug info: unknown key? move(0, DISPLAY_RIGHTMOST_COLUMN-9); {char *hex = "0123456789ABCDEF"; standout(); addch(hex[(command>>28)&15]); addch(hex[(command>>24)&15]); addch(hex[(command>>20)&15]); addch(hex[(command>>16)&15]); addch(hex[(command>>12)&15]); addch(hex[(command>>8)&15]); addch(hex[(command>>4)&15]); addch(hex[command&15]); standend(); } } return(TRUE); }