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);
}