/* * $LynxId: LYEditmap.c,v 1.75 2018/03/10 01:31:27 tom Exp $ * * LYEditMap.c * Keybindings for line and form editing. */ #include #include #include #include #include #include #include /* KEYMAP_SIZE, LKC_*, LYK_* - kw */ #include #define PUTS(buf) (*target->isa->put_string)(target, buf) /* * * * * LynxEditactionCodes * * * * */ #ifdef USE_ALT_BINDINGS /* Last valid index for the (lynxkeycode+modifier -> lynxeditactioncode) * tables. Currently all three tables are the same. - kw */ #define LAST_MOD1_LKC 0x111 #define LAST_MOD2_LKC 0x111 #define LAST_MOD3_LKC 0x111 /* Get (lynxkeycode+modifier -> lynxeditactioncode) mapping, intermediate. */ #define LKC_TO_LEC_M1(c) ((c)>LAST_MOD1_LKC? (int)LYE_UNMOD: Mod1Binding[c]) #define LKC_TO_LEC_M2(c) ((c)>LAST_MOD2_LKC? (int)LYE_UNMOD: Mod2Binding[c]) #define LKC_TO_LEC_M3(c) ((c)>LAST_MOD3_LKC? (int)LYE_UNMOD: Mod3Binding[c]) #endif /* USE_ALT_BINDINGS */ int current_lineedit = 0; /* Index into LYLineEditors[] */ int escape_bound = 0; /* User wanted Escape to perform actions? */ /* * See LYStrings.h for the LYE definitions. */ /* *INDENT-OFF* */ struct emap { const char *name; const int code; const char *descr; }; #define SEPARATOR {"", -1, ""} static struct emap ekmap[] = { {"NOP", LYE_NOP, "Do Nothing"}, {"CHAR", LYE_CHAR, "Insert printable char"}, SEPARATOR, {"ENTER", LYE_ENTER, "Input complete, return char"}, {"TAB", LYE_TAB, "Input complete, return TAB"}, {"STOP", LYE_STOP, "Input deactivated"}, {"ABORT", LYE_ABORT, "Input cancelled"}, SEPARATOR, {"PASS", LYE_FORM_PASS, "Fields only: input complete"}, SEPARATOR, {"DELBL", LYE_DELBL, "Delete back to BOL"}, {"DELEL", LYE_DELEL, "Delete thru EOL"}, {"DELN", LYE_DELN, "Delete next/curr char"}, {"DELP", LYE_DELP, "Delete prev char"}, {"DELNW", LYE_DELNW, "Delete next word"}, {"DELPW", LYE_DELPW, "Delete prev word"}, SEPARATOR, {"ERASE", LYE_ERASE, "Erase the line"}, SEPARATOR, {"BOL", LYE_BOL, "Go to begin of line"}, {"EOL", LYE_EOL, "Go to end of line"}, {"FORW", LYE_FORW, "Cursor forwards"}, {"FORW_RL", LYE_FORW_RL, "Cursor forwards or right link"}, {"BACK", LYE_BACK, "Cursor backwards"}, {"BACK_LL", LYE_BACK_LL, "Cursor backwards or left link"}, {"FORWW", LYE_FORWW, "Word forward"}, {"BACKW", LYE_BACKW, "Word back"}, SEPARATOR, {"LOWER", LYE_LOWER, "Lower case the line"}, {"UPPER", LYE_UPPER, "Upper case the line"}, SEPARATOR, {"LKCMD", LYE_LKCMD, "Invoke command prompt"}, {"SWMAP", LYE_SWMAP, "Switch input keymap"}, SEPARATOR, {"C1CHAR", LYE_C1CHAR, "Insert C1 char if printable"}, {"SETM1", LYE_SETM1, "Set modifier 1 flag"}, {"SETM2", LYE_SETM2, "Set modifier 2 flag"}, {"UNMOD", LYE_UNMOD, "Fall back to no-modifier command"}, SEPARATOR, {"TPOS", LYE_TPOS, "Transpose characters"}, {"SETMARK", LYE_SETMARK, "emacs-like set-mark-command"}, {"XPMARK", LYE_XPMARK, "emacs-like exchange-point-and-mark"}, {"KILLREG", LYE_KILLREG, "emacs-like kill-region"}, {"YANK", LYE_YANK, "emacs-like yank"}, #ifdef CAN_CUT_AND_PASTE SEPARATOR, {"PASTE", LYE_PASTE, "ClipBoard to Lynx"}, #endif SEPARATOR, {"AIX", LYE_AIX, "Hex 97"}, {0, -1, 0}, }; #undef SEPARATOR /* *INDENT-ON* */ static LYEditCode DefaultEditBinding[KEYMAP_SIZE]; #ifdef USE_ALT_BINDINGS static LYEditCode BetterEditBinding[KEYMAP_SIZE]; static LYEditCode BashlikeEditBinding[KEYMAP_SIZE]; /* * If a modifier bit is set in a lynxkeycode, it is first looked up here. * * Currently this table isn't specific to the current_lineedit value, it is * shared by all alternative "Bindings" to save space. However, if the * modifier flag is set only by a LYE_SETMn lynxeditaction, this table can have * effect only for those Bindings that map a lynxkeycode to LYE_SETMn. ( This * doesn't apply if the modifier is already being set in LYgetch(). ) - kw */ static LYEditCode Mod1Binding[KEYMAP_SIZE]; /* Two more tables here, but currently they are all the same. In other words, we are cheating to save space, until there is a need for different tables. - kw */ static LYEditCode *Mod2Binding = Mod1Binding; static LYEditCode *Mod3Binding = Mod1Binding; static const LYEditInit initMod1Binding[] = { {CTL('A'), LYE_BOL}, {CTL('B'), LYE_BACKW}, {CTL('C'), LYE_UNMOD}, {CTL('D'), LYK_NEXT_LINK | LYE_FORM_LAC}, {CTL('E'), LYK_EDITTEXTAREA | LYE_FORM_LAC}, {CTL('F'), LYE_FORWW}, {CTL('G'), LYE_ABORT}, {CTL('H'), LYE_DELPW}, {CTL('I'), LYE_UNMOD}, {CTL('J'), LYE_ENTER}, {CTL('K'), LYK_LPOS_NEXT_LINK | LYE_FORM_LAC}, {CTL('L'), LYE_FORM_PASS}, {CTL('M'), LYE_ENTER}, {CTL('N'), LYE_FORWW}, {CTL('O'), LYE_UNMOD}, {CTL('P'), LYE_BACKW}, {CTL('R'), LYE_BACKW}, {CTL('U'), LYE_FORM_PASS}, {CTL('W'), LYE_KILLREG}, {CTL('X'), LYE_XPMARK}, {CTL('Y'), LYE_UNMOD}, {CTL('Z'), LYE_FORM_PASS}, {CTL('\\'), LYE_FORM_PASS}, {CTL(']'), LYE_FORM_PASS}, {CTL('^'), LYE_UNMOD}, {' ', LYE_UNMOD}, {'!', LYE_UNMOD}, {'"', LYE_UNMOD}, {'#', LYE_UNMOD}, {'$', LYE_UNMOD}, {'%', LYE_UNMOD}, {'&', LYE_UNMOD}, {'\'', LYE_UNMOD}, {'(', LYE_UNMOD}, {')', LYE_UNMOD}, {'*', LYE_UNMOD}, {'+', LYE_UNMOD}, {',', LYE_UNMOD}, {'-', LYE_UNMOD}, {'.', LYE_UNMOD}, {'/', LYE_FORM_PASS}, {'0', LYE_UNMOD}, {'1', LYE_UNMOD}, {'2', LYE_UNMOD}, {'3', LYE_UNMOD}, {'4', LYE_UNMOD}, {'5', LYE_UNMOD}, {'6', LYE_UNMOD}, {'7', LYE_UNMOD}, {'8', LYE_UNMOD}, {'9', LYE_UNMOD}, {':', LYE_UNMOD}, {';', LYE_UNMOD}, {'<', LYK_HOME | LYE_FORM_LAC}, {'=', LYE_UNMOD}, {'>', LYK_END | LYE_FORM_LAC}, {'?', LYE_UNMOD}, {'@', LYE_C1CHAR}, {'A', LYE_C1CHAR}, {'B', LYE_C1CHAR}, {'C', LYE_C1CHAR}, {'D', LYE_C1CHAR}, {'E', LYE_C1CHAR}, {'F', LYE_C1CHAR}, {'G', LYE_C1CHAR}, {'H', LYE_C1CHAR}, {'I', LYE_C1CHAR}, {'J', LYE_C1CHAR}, {'K', LYE_C1CHAR}, {'L', LYE_C1CHAR}, {'M', LYE_C1CHAR}, {'N', LYE_C1CHAR}, {'O', LYE_C1CHAR}, {'P', LYE_C1CHAR}, {'Q', LYE_C1CHAR}, {'R', LYE_C1CHAR}, {'S', LYE_C1CHAR}, {'T', LYE_C1CHAR}, {'U', LYE_C1CHAR}, {'V', LYE_C1CHAR}, {'W', LYE_C1CHAR}, {'X', LYE_C1CHAR}, {'Y', LYE_C1CHAR}, {'Z', LYE_C1CHAR}, {'[', LYE_C1CHAR}, {'\\', LYE_C1CHAR}, {']', LYE_C1CHAR}, {'^', LYE_C1CHAR}, {'_', LYE_C1CHAR}, {'`', LYE_UNMOD}, {'a', LYE_BOL}, {'b', LYE_BACKW}, {'c', LYE_UNMOD}, {'d', LYE_DELNW}, {'e', LYK_EDITTEXTAREA | LYE_FORM_LAC}, {'f', LYE_FORWW}, {'g', LYK_GROWTEXTAREA | LYE_FORM_LAC}, {'h', LYE_CHAR}, {'i', LYK_INSERTFILE | LYE_FORM_LAC}, {'j', LYE_CHAR}, {'k', LYE_ERASE}, {'l', LYE_LOWER}, {'m', LYE_CHAR}, {'n', LYE_FORM_PASS}, {'o', LYE_UNMOD}, {'p', LYE_CHAR}, {'u', LYE_UPPER}, {'z', LYE_UNMOD}, {'{', LYE_UNMOD}, {'|', LYE_UNMOD}, {'}', LYE_UNMOD}, {'~', LYE_UNMOD}, {DEL_KEY, LYE_DELPW}, {160, LYE_UNMOD}, {161, LYE_UNMOD}, {162, LYE_UNMOD}, {163, LYE_UNMOD}, {164, LYE_UNMOD}, {165, LYE_UNMOD}, {166, LYE_UNMOD}, {167, LYE_UNMOD}, {168, LYE_UNMOD}, {169, LYE_UNMOD}, {170, LYE_UNMOD}, {171, LYE_UNMOD}, {172, LYE_UNMOD}, {173, LYE_UNMOD}, {174, LYE_UNMOD}, {175, LYE_UNMOD}, {176, LYE_UNMOD}, {177, LYE_UNMOD}, {178, LYE_UNMOD}, {179, LYE_UNMOD}, {180, LYE_UNMOD}, {181, LYE_UNMOD}, {182, LYE_UNMOD}, {183, LYE_UNMOD}, {184, LYE_UNMOD}, {185, LYE_UNMOD}, {186, LYE_UNMOD}, {187, LYE_UNMOD}, {188, LYE_UNMOD}, {189, LYE_UNMOD}, {190, LYE_UNMOD}, {191, LYE_UNMOD}, {192, LYE_UNMOD}, {193, LYE_UNMOD}, {194, LYE_UNMOD}, {195, LYE_UNMOD}, {196, LYE_UNMOD}, {197, LYE_UNMOD}, {198, LYE_UNMOD}, {199, LYE_UNMOD}, {200, LYE_UNMOD}, {201, LYE_UNMOD}, {202, LYE_UNMOD}, {203, LYE_UNMOD}, {204, LYE_UNMOD}, {205, LYE_UNMOD}, {206, LYE_UNMOD}, {207, LYE_UNMOD}, {208, LYE_UNMOD}, {209, LYE_UNMOD}, {210, LYE_UNMOD}, {211, LYE_UNMOD}, {212, LYE_UNMOD}, {213, LYE_UNMOD}, {214, LYE_UNMOD}, {215, LYE_UNMOD}, {216, LYE_UNMOD}, {217, LYE_UNMOD}, {218, LYE_UNMOD}, {219, LYE_UNMOD}, {220, LYE_UNMOD}, {221, LYE_UNMOD}, {222, LYE_UNMOD}, {223, LYE_UNMOD}, {224, LYE_UNMOD}, {225, LYE_UNMOD}, {226, LYE_UNMOD}, {227, LYE_UNMOD}, {228, LYE_UNMOD}, {229, LYE_UNMOD}, {230, LYE_UNMOD}, {231, LYE_UNMOD}, {232, LYE_UNMOD}, {233, LYE_UNMOD}, {234, LYE_UNMOD}, {235, LYE_UNMOD}, {236, LYE_UNMOD}, {237, LYE_UNMOD}, {238, LYE_UNMOD}, {239, LYE_UNMOD}, {240, LYE_UNMOD}, {241, LYE_UNMOD}, {242, LYE_UNMOD}, {243, LYE_UNMOD}, {244, LYE_UNMOD}, {245, LYE_UNMOD}, {246, LYE_UNMOD}, {247, LYE_UNMOD}, {248, LYE_UNMOD}, {249, LYE_UNMOD}, {250, LYE_UNMOD}, {251, LYE_UNMOD}, {252, LYE_UNMOD}, {253, LYE_UNMOD}, {254, LYE_UNMOD}, {255, LYE_UNMOD}, {UPARROW_KEY, LYE_UNMOD}, {DNARROW_KEY, LYE_UNMOD}, {RTARROW_KEY, LYE_UNMOD}, {LTARROW_KEY, LYE_UNMOD}, {PGDOWN_KEY, LYE_UNMOD}, {PGUP_KEY, LYE_UNMOD}, {HOME_KEY, LYE_FORM_PASS}, {END_KEY, LYE_FORM_PASS}, {F1_KEY, LYK_DWIMHELP | LYE_FORM_LAC}, {DO_KEY, LYE_UNMOD}, #if (defined(_WINDOWS) || defined(__DJGPP__)) {FIND_KEY, LYE_UNMOD}, {SELECT_KEY, LYE_UNMOD}, #else {FIND_KEY, LYK_WHEREIS | LYE_FORM_LAC}, {SELECT_KEY, LYK_NEXT | LYE_FORM_LAC}, #endif {INSERT_KEY, LYE_UNMOD}, {DO_NOTHING, LYE_UNMOD}, {BACKTAB_KEY, LYE_UNMOD}, #if (defined(_WINDOWS) || defined(__DJGPP__)) && defined(USE_SLANG) && !defined(DJGPP_KEYHANDLER) {272, LYE_DELPW}, #else {272, LYE_UNMOD}, #endif {273, LYE_UNMOD}, {-1, LYE_UNKNOWN} }; LYEditConfig LYModifierBindings[] = { {"Modifier Binding", initMod1Binding, Mod1Binding}, }; #endif /* USE_ALT_BINDINGS */ static const LYEditInit initDefaultEditor[] = { {CTL('A'), LYE_BOL}, {CTL('B'), LYE_DELPW}, {CTL('C'), LYE_ABORT}, {CTL('D'), LYE_DELN}, {CTL('E'), LYE_EOL}, {CTL('F'), LYE_DELNW}, {CTL('G'), LYE_ABORT}, {CTL('H'), LYE_DELP}, {CTL('I'), LYE_TAB}, {CTL('J'), LYE_ENTER}, {CTL('K'), LYE_LOWER}, {CTL('M'), LYE_ENTER}, {CTL('N'), LYE_FORWW}, {CTL('O'), LYE_ABORT}, {CTL('P'), LYE_BACKW}, {CTL('R'), LYE_DELN}, {CTL('T'), LYE_UPPER}, {CTL('U'), LYE_ERASE}, {CTL('V'), LYE_LKCMD}, #ifdef CAN_CUT_AND_PASTE {CTL('W'), LYE_PASTE}, #endif {CTL('X'), LYE_SETM1}, {CTL('^'), LYE_SWMAP}, {CTL('_'), LYE_DELEL}, {' ', LYE_CHAR}, {'!', LYE_CHAR}, {'"', LYE_CHAR}, {'#', LYE_CHAR}, {'$', LYE_CHAR}, {'%', LYE_CHAR}, {'&', LYE_CHAR}, {'\'', LYE_CHAR}, {'(', LYE_CHAR}, {')', LYE_CHAR}, {'*', LYE_CHAR}, {'+', LYE_CHAR}, {',', LYE_CHAR}, {'-', LYE_CHAR}, {'.', LYE_CHAR}, {'/', LYE_CHAR}, {'0', LYE_CHAR}, {'1', LYE_CHAR}, {'2', LYE_CHAR}, {'3', LYE_CHAR}, {'4', LYE_CHAR}, {'5', LYE_CHAR}, {'6', LYE_CHAR}, {'7', LYE_CHAR}, {'8', LYE_CHAR}, {'9', LYE_CHAR}, {':', LYE_CHAR}, {';', LYE_CHAR}, {'<', LYE_CHAR}, {'=', LYE_CHAR}, {'>', LYE_CHAR}, {'?', LYE_CHAR}, {'@', LYE_CHAR}, {'A', LYE_CHAR}, {'B', LYE_CHAR}, {'C', LYE_CHAR}, {'D', LYE_CHAR}, {'E', LYE_CHAR}, {'F', LYE_CHAR}, {'G', LYE_CHAR}, {'H', LYE_CHAR}, {'I', LYE_CHAR}, {'J', LYE_CHAR}, {'K', LYE_CHAR}, {'L', LYE_CHAR}, {'M', LYE_CHAR}, {'N', LYE_CHAR}, {'O', LYE_CHAR}, {'P', LYE_CHAR}, {'Q', LYE_CHAR}, {'R', LYE_CHAR}, {'S', LYE_CHAR}, {'T', LYE_CHAR}, {'U', LYE_CHAR}, {'V', LYE_CHAR}, {'W', LYE_CHAR}, {'X', LYE_CHAR}, {'Y', LYE_CHAR}, {'Z', LYE_CHAR}, {'[', LYE_CHAR}, {'\\', LYE_CHAR}, {']', LYE_CHAR}, {'^', LYE_CHAR}, {'_', LYE_CHAR}, {'`', LYE_CHAR}, {'a', LYE_CHAR}, {'b', LYE_CHAR}, {'c', LYE_CHAR}, {'d', LYE_CHAR}, {'e', LYE_CHAR}, {'f', LYE_CHAR}, {'g', LYE_CHAR}, {'h', LYE_CHAR}, {'i', LYE_CHAR}, {'j', LYE_CHAR}, {'k', LYE_CHAR}, {'l', LYE_CHAR}, {'m', LYE_CHAR}, {'n', LYE_CHAR}, {'o', LYE_CHAR}, {'p', LYE_CHAR}, {'q', LYE_CHAR}, {'r', LYE_CHAR}, {'s', LYE_CHAR}, {'t', LYE_CHAR}, {'u', LYE_CHAR}, {'v', LYE_CHAR}, {'w', LYE_CHAR}, {'x', LYE_CHAR}, {'y', LYE_CHAR}, {'z', LYE_CHAR}, {'{', LYE_CHAR}, {'|', LYE_CHAR}, {'}', LYE_CHAR}, {'~', LYE_CHAR}, {DEL_KEY, LYE_DELP}, {128, LYE_CHAR}, {129, LYE_CHAR}, {130, LYE_CHAR}, {131, LYE_CHAR}, {132, LYE_CHAR}, {133, LYE_CHAR}, {134, LYE_CHAR}, {135, LYE_CHAR}, {136, LYE_CHAR}, {137, LYE_CHAR}, {138, LYE_CHAR}, {139, LYE_CHAR}, {140, LYE_CHAR}, {141, LYE_CHAR}, #ifdef CJK_EX /* 1997/11/03 (Mon) 20:30:54 */ {142, LYE_CHAR}, #else {142, LYE_AIX}, #endif {143, LYE_CHAR}, {144, LYE_CHAR}, {145, LYE_CHAR}, {146, LYE_CHAR}, {147, LYE_CHAR}, {148, LYE_CHAR}, {149, LYE_CHAR}, {150, LYE_CHAR}, {151, LYE_CHAR}, {152, LYE_CHAR}, {153, LYE_CHAR}, {154, LYE_CHAR}, {155, LYE_CHAR}, {156, LYE_CHAR}, {157, LYE_CHAR}, {158, LYE_CHAR}, {159, LYE_CHAR}, {160, LYE_CHAR}, {161, LYE_CHAR}, {162, LYE_CHAR}, {163, LYE_CHAR}, {164, LYE_CHAR}, {165, LYE_CHAR}, {166, LYE_CHAR}, {167, LYE_CHAR}, {168, LYE_CHAR}, {169, LYE_CHAR}, {170, LYE_CHAR}, {171, LYE_CHAR}, {172, LYE_CHAR}, {173, LYE_CHAR}, {174, LYE_CHAR}, {175, LYE_CHAR}, {176, LYE_CHAR}, {177, LYE_CHAR}, {178, LYE_CHAR}, {179, LYE_CHAR}, {180, LYE_CHAR}, {181, LYE_CHAR}, {182, LYE_CHAR}, {183, LYE_CHAR}, {184, LYE_CHAR}, {185, LYE_CHAR}, {186, LYE_CHAR}, {187, LYE_CHAR}, {188, LYE_CHAR}, {189, LYE_CHAR}, {190, LYE_CHAR}, {191, LYE_CHAR}, {192, LYE_CHAR}, {193, LYE_CHAR}, {194, LYE_CHAR}, {195, LYE_CHAR}, {196, LYE_CHAR}, {197, LYE_CHAR}, {198, LYE_CHAR}, {199, LYE_CHAR}, {200, LYE_CHAR}, {201, LYE_CHAR}, {202, LYE_CHAR}, {203, LYE_CHAR}, {204, LYE_CHAR}, {205, LYE_CHAR}, {206, LYE_CHAR}, {207, LYE_CHAR}, {208, LYE_CHAR}, {209, LYE_CHAR}, {210, LYE_CHAR}, {211, LYE_CHAR}, {212, LYE_CHAR}, {213, LYE_CHAR}, {214, LYE_CHAR}, {215, LYE_CHAR}, {216, LYE_CHAR}, {217, LYE_CHAR}, {218, LYE_CHAR}, {219, LYE_CHAR}, {220, LYE_CHAR}, {221, LYE_CHAR}, {222, LYE_CHAR}, {223, LYE_CHAR}, {224, LYE_CHAR}, {225, LYE_CHAR}, {226, LYE_CHAR}, {227, LYE_CHAR}, {228, LYE_CHAR}, {229, LYE_CHAR}, {230, LYE_CHAR}, {231, LYE_CHAR}, {232, LYE_CHAR}, {233, LYE_CHAR}, {234, LYE_CHAR}, {235, LYE_CHAR}, {236, LYE_CHAR}, {237, LYE_CHAR}, {238, LYE_CHAR}, {239, LYE_CHAR}, {240, LYE_CHAR}, {241, LYE_CHAR}, {242, LYE_CHAR}, {243, LYE_CHAR}, {244, LYE_CHAR}, {245, LYE_CHAR}, {246, LYE_CHAR}, {247, LYE_CHAR}, {248, LYE_CHAR}, {249, LYE_CHAR}, {250, LYE_CHAR}, {251, LYE_CHAR}, {252, LYE_CHAR}, {253, LYE_CHAR}, {254, LYE_CHAR}, {255, LYE_CHAR}, {UPARROW_KEY, LYE_FORM_PASS}, {DNARROW_KEY, LYE_FORM_PASS}, {RTARROW_KEY, LYE_FORW}, {LTARROW_KEY, LYE_BACK}, {PGDOWN_KEY, LYE_FORM_PASS}, {PGUP_KEY, LYE_FORM_PASS}, {HOME_KEY, LYE_BOL}, {END_KEY, LYE_EOL}, {F1_KEY, LYE_FORM_PASS}, #if !(defined(_WINDOWS) || defined(__DJGPP__)) {DO_KEY, LYE_TAB}, {FIND_KEY, LYE_BOL}, {SELECT_KEY, LYE_EOL}, #endif {REMOVE_KEY, LYE_DELP}, {BACKTAB_KEY, LYE_FORM_PASS}, #if (defined(_WINDOWS) || defined(__DJGPP__)) && defined(USE_SLANG) && !defined(DJGPP_KEYHANDLER) {272, LYE_DELP}, {273, LYE_ENTER}, #endif {-1, LYE_UNKNOWN} }; #ifdef USE_ALT_BINDINGS static const LYEditInit initBetterEditor[] = { {CTL('A'), LYE_BOL}, {CTL('B'), LYE_BACK}, {CTL('C'), LYE_ABORT}, {CTL('D'), LYE_DELN}, {CTL('E'), LYE_EOL}, {CTL('F'), LYE_FORW}, {CTL('G'), LYE_ABORT}, {CTL('H'), LYE_DELP}, {CTL('I'), LYE_ENTER}, {CTL('J'), LYE_ENTER}, {CTL('K'), LYE_DELEL}, {CTL('M'), LYE_ENTER}, {CTL('N'), LYE_FORWW}, {CTL('O'), LYE_ABORT}, {CTL('P'), LYE_BACKW}, {CTL('R'), LYE_DELPW}, {CTL('T'), LYE_DELNW}, {CTL('U'), LYE_ERASE}, {CTL('V'), LYE_LKCMD}, #ifdef CAN_CUT_AND_PASTE {CTL('W'), LYE_PASTE}, #endif {CTL('X'), LYE_SETM1}, {CTL('^'), LYE_UPPER}, {CTL('_'), LYE_LOWER}, {' ', LYE_CHAR}, {'!', LYE_CHAR}, {'"', LYE_CHAR}, {'#', LYE_CHAR}, {'$', LYE_CHAR}, {'%', LYE_CHAR}, {'&', LYE_CHAR}, {'\'', LYE_CHAR}, {'(', LYE_CHAR}, {')', LYE_CHAR}, {'*', LYE_CHAR}, {'+', LYE_CHAR}, {',', LYE_CHAR}, {'-', LYE_CHAR}, {'.', LYE_CHAR}, {'/', LYE_CHAR}, {'0', LYE_CHAR}, {'1', LYE_CHAR}, {'2', LYE_CHAR}, {'3', LYE_CHAR}, {'4', LYE_CHAR}, {'5', LYE_CHAR}, {'6', LYE_CHAR}, {'7', LYE_CHAR}, {'8', LYE_CHAR}, {'9', LYE_CHAR}, {':', LYE_CHAR}, {';', LYE_CHAR}, {'<', LYE_CHAR}, {'=', LYE_CHAR}, {'>', LYE_CHAR}, {'?', LYE_CHAR}, {'@', LYE_CHAR}, {'A', LYE_CHAR}, {'B', LYE_CHAR}, {'C', LYE_CHAR}, {'D', LYE_CHAR}, {'E', LYE_CHAR}, {'F', LYE_CHAR}, {'G', LYE_CHAR}, {'H', LYE_CHAR}, {'I', LYE_CHAR}, {'J', LYE_CHAR}, {'K', LYE_CHAR}, {'L', LYE_CHAR}, {'M', LYE_CHAR}, {'N', LYE_CHAR}, {'O', LYE_CHAR}, {'P', LYE_CHAR}, {'Q', LYE_CHAR}, {'R', LYE_CHAR}, {'S', LYE_CHAR}, {'T', LYE_CHAR}, {'U', LYE_CHAR}, {'V', LYE_CHAR}, {'W', LYE_CHAR}, {'X', LYE_CHAR}, {'Y', LYE_CHAR}, {'Z', LYE_CHAR}, {'[', LYE_CHAR}, {'\\', LYE_CHAR}, {']', LYE_CHAR}, {'^', LYE_CHAR}, {'_', LYE_CHAR}, {'`', LYE_CHAR}, {'a', LYE_CHAR}, {'b', LYE_CHAR}, {'c', LYE_CHAR}, {'d', LYE_CHAR}, {'e', LYE_CHAR}, {'f', LYE_CHAR}, {'g', LYE_CHAR}, {'h', LYE_CHAR}, {'i', LYE_CHAR}, {'j', LYE_CHAR}, {'k', LYE_CHAR}, {'l', LYE_CHAR}, {'m', LYE_CHAR}, {'n', LYE_CHAR}, {'o', LYE_CHAR}, {'p', LYE_CHAR}, {'q', LYE_CHAR}, {'r', LYE_CHAR}, {'s', LYE_CHAR}, {'t', LYE_CHAR}, {'u', LYE_CHAR}, {'v', LYE_CHAR}, {'w', LYE_CHAR}, {'x', LYE_CHAR}, {'y', LYE_CHAR}, {'z', LYE_CHAR}, {'{', LYE_CHAR}, {'|', LYE_CHAR}, {'}', LYE_CHAR}, {'~', LYE_CHAR}, {DEL_KEY, LYE_DELP}, {128, LYE_CHAR}, {129, LYE_CHAR}, {130, LYE_CHAR}, {131, LYE_CHAR}, {132, LYE_CHAR}, {133, LYE_CHAR}, {134, LYE_CHAR}, {135, LYE_CHAR}, {136, LYE_CHAR}, {137, LYE_CHAR}, {138, LYE_CHAR}, {139, LYE_CHAR}, {140, LYE_CHAR}, {141, LYE_CHAR}, #ifdef CJK_EX /* 1997/11/03 (Mon) 20:30:54 */ {142, LYE_CHAR}, #else {142, LYE_AIX}, #endif {143, LYE_CHAR}, {144, LYE_CHAR}, {145, LYE_CHAR}, {146, LYE_CHAR}, {147, LYE_CHAR}, {148, LYE_CHAR}, {149, LYE_CHAR}, {150, LYE_CHAR}, {151, LYE_CHAR}, {152, LYE_CHAR}, {153, LYE_CHAR}, {154, LYE_CHAR}, {155, LYE_CHAR}, {156, LYE_CHAR}, {157, LYE_CHAR}, {158, LYE_CHAR}, {159, LYE_CHAR}, {160, LYE_CHAR}, {161, LYE_CHAR}, {162, LYE_CHAR}, {163, LYE_CHAR}, {164, LYE_CHAR}, {165, LYE_CHAR}, {166, LYE_CHAR}, {167, LYE_CHAR}, {168, LYE_CHAR}, {169, LYE_CHAR}, {170, LYE_CHAR}, {171, LYE_CHAR}, {172, LYE_CHAR}, {173, LYE_CHAR}, {174, LYE_CHAR}, {175, LYE_CHAR}, {176, LYE_CHAR}, {177, LYE_CHAR}, {178, LYE_CHAR}, {179, LYE_CHAR}, {180, LYE_CHAR}, {181, LYE_CHAR}, {182, LYE_CHAR}, {183, LYE_CHAR}, {184, LYE_CHAR}, {185, LYE_CHAR}, {186, LYE_CHAR}, {187, LYE_CHAR}, {188, LYE_CHAR}, {189, LYE_CHAR}, {190, LYE_CHAR}, {191, LYE_CHAR}, {192, LYE_CHAR}, {193, LYE_CHAR}, {194, LYE_CHAR}, {195, LYE_CHAR}, {196, LYE_CHAR}, {197, LYE_CHAR}, {198, LYE_CHAR}, {199, LYE_CHAR}, {200, LYE_CHAR}, {201, LYE_CHAR}, {202, LYE_CHAR}, {203, LYE_CHAR}, {204, LYE_CHAR}, {205, LYE_CHAR}, {206, LYE_CHAR}, {207, LYE_CHAR}, {208, LYE_CHAR}, {209, LYE_CHAR}, {210, LYE_CHAR}, {211, LYE_CHAR}, {212, LYE_CHAR}, {213, LYE_CHAR}, {214, LYE_CHAR}, {215, LYE_CHAR}, {216, LYE_CHAR}, {217, LYE_CHAR}, {218, LYE_CHAR}, {219, LYE_CHAR}, {220, LYE_CHAR}, {221, LYE_CHAR}, {222, LYE_CHAR}, {223, LYE_CHAR}, {224, LYE_CHAR}, {225, LYE_CHAR}, {226, LYE_CHAR}, {227, LYE_CHAR}, {228, LYE_CHAR}, {229, LYE_CHAR}, {230, LYE_CHAR}, {231, LYE_CHAR}, {232, LYE_CHAR}, {233, LYE_CHAR}, {234, LYE_CHAR}, {235, LYE_CHAR}, {236, LYE_CHAR}, {237, LYE_CHAR}, {238, LYE_CHAR}, {239, LYE_CHAR}, {240, LYE_CHAR}, {241, LYE_CHAR}, {242, LYE_CHAR}, {243, LYE_CHAR}, {244, LYE_CHAR}, {245, LYE_CHAR}, {246, LYE_CHAR}, {247, LYE_CHAR}, {248, LYE_CHAR}, {249, LYE_CHAR}, {250, LYE_CHAR}, {251, LYE_CHAR}, {252, LYE_CHAR}, {253, LYE_CHAR}, {254, LYE_CHAR}, {255, LYE_CHAR}, {UPARROW_KEY, LYE_FORM_PASS}, {DNARROW_KEY, LYE_FORM_PASS}, {RTARROW_KEY, LYE_FORW}, {LTARROW_KEY, LYE_BACK}, {PGDOWN_KEY, LYE_FORM_PASS}, {PGUP_KEY, LYE_FORM_PASS}, {HOME_KEY, LYE_BOL}, {END_KEY, LYE_EOL}, {F1_KEY, LYE_FORM_PASS}, #if !(defined(_WINDOWS) || defined(__DJGPP__)) {DO_KEY, LYE_TAB}, {FIND_KEY, LYE_BOL}, {SELECT_KEY, LYE_EOL}, #endif {REMOVE_KEY, LYE_DELP}, {BACKTAB_KEY, LYE_FORM_PASS}, #if (defined(_WINDOWS) || defined(__DJGPP__)) && defined(USE_SLANG) && !defined(DJGPP_KEYHANDLER) {272, LYE_DELP}, {273, LYE_ENTER}, #endif {-1, LYE_UNKNOWN} }; static const LYEditInit initBashlikeEditor[] = { {CTL('@'), LYE_SETMARK}, {CTL('A'), LYE_BOL}, {CTL('B'), LYE_BACK}, {CTL('C'), LYE_ABORT}, {CTL('D'), LYE_DELN}, {CTL('E'), LYE_EOL | LYE_DF}, {CTL('F'), LYE_FORW}, {CTL('G'), LYE_ABORT}, {CTL('H'), LYE_DELP}, {CTL('I'), LYE_TAB}, {CTL('J'), LYE_ENTER}, {CTL('K'), LYE_DELEL | LYE_DF}, {CTL('L'), LYE_FORM_PASS}, {CTL('M'), LYE_ENTER}, {CTL('N'), LYE_FORM_PASS}, {CTL('O'), LYE_FORM_PASS}, {CTL('P'), LYE_FORM_PASS}, {CTL('R'), LYE_BACKW}, {CTL('S'), LYE_FORWW}, {CTL('T'), LYE_TPOS}, {CTL('U'), LYE_DELBL}, {CTL('V'), LYE_LKCMD}, {CTL('W'), LYE_DELPW}, {CTL('X'), LYE_SETM1}, {CTL('Y'), LYE_YANK}, {CTL('Z'), LYE_FORM_PASS}, {CTL('['), LYE_SETM2}, {CTL('\\'), LYE_FORM_PASS}, {CTL(']'), LYE_FORM_PASS}, {CTL('^'), LYE_SWMAP}, {CTL('_'), LYE_ABORT}, {' ', LYE_CHAR}, {'!', LYE_CHAR}, {'"', LYE_CHAR}, {'#', LYE_CHAR}, {'$', LYE_CHAR}, {'%', LYE_CHAR}, {'&', LYE_CHAR}, {'\'', LYE_CHAR}, {'(', LYE_CHAR}, {')', LYE_CHAR}, {'*', LYE_CHAR}, {'+', LYE_CHAR}, {',', LYE_CHAR}, {'-', LYE_CHAR}, {'.', LYE_CHAR}, {'/', LYE_CHAR}, {'0', LYE_CHAR}, {'1', LYE_CHAR}, {'2', LYE_CHAR}, {'3', LYE_CHAR}, {'4', LYE_CHAR}, {'5', LYE_CHAR}, {'6', LYE_CHAR}, {'7', LYE_CHAR}, {'8', LYE_CHAR}, {'9', LYE_CHAR}, {':', LYE_CHAR}, {';', LYE_CHAR}, {'<', LYE_CHAR}, {'=', LYE_CHAR}, {'>', LYE_CHAR}, {'?', LYE_CHAR}, {'@', LYE_CHAR}, {'A', LYE_CHAR}, {'B', LYE_CHAR}, {'C', LYE_CHAR}, {'D', LYE_CHAR}, {'E', LYE_CHAR}, {'F', LYE_CHAR}, {'G', LYE_CHAR}, {'H', LYE_CHAR}, {'I', LYE_CHAR}, {'J', LYE_CHAR}, {'K', LYE_CHAR}, {'L', LYE_CHAR}, {'M', LYE_CHAR}, {'N', LYE_CHAR}, {'O', LYE_CHAR}, {'P', LYE_CHAR}, {'Q', LYE_CHAR}, {'R', LYE_CHAR}, {'S', LYE_CHAR}, {'T', LYE_CHAR}, {'U', LYE_CHAR}, {'V', LYE_CHAR}, {'W', LYE_CHAR}, {'X', LYE_CHAR}, {'Y', LYE_CHAR}, {'Z', LYE_CHAR}, {'[', LYE_CHAR}, {'\\', LYE_CHAR}, {']', LYE_CHAR}, {'^', LYE_CHAR}, {'_', LYE_CHAR}, {'`', LYE_CHAR}, {'a', LYE_CHAR}, {'b', LYE_CHAR}, {'c', LYE_CHAR}, {'d', LYE_CHAR}, {'e', LYE_CHAR}, {'f', LYE_CHAR}, {'g', LYE_CHAR}, {'h', LYE_CHAR}, {'i', LYE_CHAR}, {'j', LYE_CHAR}, {'k', LYE_CHAR}, {'l', LYE_CHAR}, {'m', LYE_CHAR}, {'n', LYE_CHAR}, {'o', LYE_CHAR}, {'p', LYE_CHAR}, {'q', LYE_CHAR}, {'r', LYE_CHAR}, {'s', LYE_CHAR}, {'t', LYE_CHAR}, {'u', LYE_CHAR}, {'v', LYE_CHAR}, {'w', LYE_CHAR}, {'x', LYE_CHAR}, {'y', LYE_CHAR}, {'z', LYE_CHAR}, {'{', LYE_CHAR}, {'|', LYE_CHAR}, {'}', LYE_CHAR}, {'~', LYE_CHAR}, {DEL_KEY, LYE_DELP}, {128, LYE_CHAR}, {129, LYE_CHAR}, {130, LYE_CHAR}, {131, LYE_CHAR}, {132, LYE_CHAR}, {133, LYE_CHAR}, {134, LYE_CHAR}, {135, LYE_CHAR}, {136, LYE_CHAR}, {137, LYE_CHAR}, {138, LYE_CHAR}, {139, LYE_CHAR}, {140, LYE_CHAR}, {141, LYE_CHAR}, {142, LYE_CHAR}, {143, LYE_CHAR}, {144, LYE_CHAR}, {145, LYE_CHAR}, {146, LYE_CHAR}, {147, LYE_CHAR}, {148, LYE_CHAR}, {149, LYE_CHAR}, {150, LYE_CHAR}, {151, LYE_AIX}, {152, LYE_CHAR}, {153, LYE_CHAR}, {154, LYE_CHAR}, {155, LYE_CHAR}, {156, LYE_CHAR}, {157, LYE_CHAR}, {158, LYE_CHAR}, {159, LYE_CHAR}, {160, LYE_CHAR}, {161, LYE_CHAR}, {162, LYE_CHAR}, {163, LYE_CHAR}, {164, LYE_CHAR}, {165, LYE_CHAR}, {166, LYE_CHAR}, {167, LYE_CHAR}, {168, LYE_CHAR}, {169, LYE_CHAR}, {170, LYE_CHAR}, {171, LYE_CHAR}, {172, LYE_CHAR}, {173, LYE_CHAR}, {174, LYE_CHAR}, {175, LYE_CHAR}, {176, LYE_CHAR}, {177, LYE_CHAR}, {178, LYE_CHAR}, {179, LYE_CHAR}, {180, LYE_CHAR}, {181, LYE_CHAR}, {182, LYE_CHAR}, {183, LYE_CHAR}, {184, LYE_CHAR}, {185, LYE_CHAR}, {186, LYE_CHAR}, {187, LYE_CHAR}, {188, LYE_CHAR}, {189, LYE_CHAR}, {190, LYE_CHAR}, {191, LYE_CHAR}, {192, LYE_CHAR}, {193, LYE_CHAR}, {194, LYE_CHAR}, {195, LYE_CHAR}, {196, LYE_CHAR}, {197, LYE_CHAR}, {198, LYE_CHAR}, {199, LYE_CHAR}, {200, LYE_CHAR}, {201, LYE_CHAR}, {202, LYE_CHAR}, {203, LYE_CHAR}, {204, LYE_CHAR}, {205, LYE_CHAR}, {206, LYE_CHAR}, {207, LYE_CHAR}, {208, LYE_CHAR}, {209, LYE_CHAR}, {210, LYE_CHAR}, {211, LYE_CHAR}, {212, LYE_CHAR}, {213, LYE_CHAR}, {214, LYE_CHAR}, {215, LYE_CHAR}, {216, LYE_CHAR}, {217, LYE_CHAR}, {218, LYE_CHAR}, {219, LYE_CHAR}, {220, LYE_CHAR}, {221, LYE_CHAR}, {222, LYE_CHAR}, {223, LYE_CHAR}, {224, LYE_CHAR}, {225, LYE_CHAR}, {226, LYE_CHAR}, {227, LYE_CHAR}, {228, LYE_CHAR}, {229, LYE_CHAR}, {230, LYE_CHAR}, {231, LYE_CHAR}, {232, LYE_CHAR}, {233, LYE_CHAR}, {234, LYE_CHAR}, {235, LYE_CHAR}, {236, LYE_CHAR}, {237, LYE_CHAR}, {238, LYE_CHAR}, {239, LYE_CHAR}, {240, LYE_CHAR}, {241, LYE_CHAR}, {242, LYE_CHAR}, {243, LYE_CHAR}, {244, LYE_CHAR}, {245, LYE_CHAR}, {246, LYE_CHAR}, {247, LYE_CHAR}, {248, LYE_CHAR}, {249, LYE_CHAR}, {250, LYE_CHAR}, {251, LYE_CHAR}, {252, LYE_CHAR}, {253, LYE_CHAR}, {254, LYE_CHAR}, {255, LYE_CHAR}, {UPARROW_KEY, LYE_FORM_PASS}, {DNARROW_KEY, LYE_FORM_PASS}, {RTARROW_KEY, LYE_FORW}, {LTARROW_KEY, LYE_BACK}, {PGDOWN_KEY, LYE_FORM_PASS}, {PGUP_KEY, LYE_FORM_PASS}, {HOME_KEY, LYE_BOL}, {END_KEY, LYE_EOL}, {F1_KEY, LYE_FORM_PASS}, #if !(defined(_WINDOWS) || defined(__DJGPP__)) {DO_KEY, LYE_TAB}, {FIND_KEY, LYE_BOL}, {SELECT_KEY, LYE_EOL}, #endif {REMOVE_KEY, LYE_DELN}, {BACKTAB_KEY, LYE_FORM_PASS}, #if (defined(_WINDOWS) || defined(__DJGPP__)) && defined(USE_SLANG) && !defined(DJGPP_KEYHANDLER) {272, LYE_DELP}, {273, LYE_ENTER}, #endif {-1, LYE_UNKNOWN} }; #endif /* USE_ALT_BINDINGS */ LYEditConfig LYLineEditors[] = { {"Default Binding", initDefaultEditor, DefaultEditBinding}, #ifdef USE_ALT_BINDINGS {"Alternate Bindings", initBetterEditor, BetterEditBinding}, {"Bash-like Bindings", initBashlikeEditor, BashlikeEditBinding}, #endif }; const char *LYEditorNames[TABLESIZE(LYLineEditors) + 1]; /* * Add the URL (relative to helpfilepath) used for context-dependent * help on form field editing. * * The order must correspond to that of LYLineditNames. */ const char *LYLineeditHelpURLs[] = { EDIT_HELP, #ifdef USE_ALT_BINDINGS ALT_EDIT_HELP, BASHLIKE_EDIT_HELP, #endif (char *) 0 }; static struct emap *name2emap(const char *name) { struct emap *mp; struct emap *result = 0; if (non_empty(name)) { for (mp = ekmap; mp->name != NULL; mp++) { if (strcasecomp(mp->name, name) == 0) { result = mp; break; } } } return result; } static struct emap *code2emap(int code) { struct emap *mp; struct emap *result = 0; for (mp = ekmap; mp->name != NULL; mp++) { if (mp->code == code) { result = mp; break; } } return result; } /* * Return editactioncode whose name is the string func. func must be present * in the ekmap table. returns -1 if not found. - kw */ int lecname_to_lec(const char *func) { struct emap *mp; int result = -1; if ((mp = name2emap(func)) != 0) { result = mp->code; } return result; } const char *lec_to_lecname(int code) { struct emap *mp; const char *result = 0; if ((mp = code2emap(code)) != 0) { result = mp->name; } return result; } int EditBinding(int xlkc) { int editaction, xleac = LYE_UNMOD; int c = xlkc & LKC_MASK; if (xlkc == -1) return LYE_NOP; /* maybe LYE_ABORT? or LYE_FORM_LAC|LYK_UNKNOWN? */ #ifdef NOT_ASCII if (c < 256) { c = TOASCII(c); } #endif #ifdef USE_ALT_BINDINGS /* * Get intermediate code from one of the lynxkeycode+modifier tables if * applicable, otherwise get the lynxeditactioncode directly. If we have * more than one modifier bits, the first currently wins. - kw */ if (xlkc & LKC_ISLECLAC) { return LKC2_TO_LEC(xlkc); } else if (xlkc & LKC_MOD1) { xleac = LKC_TO_LEC_M1(c); } else if (xlkc & LKC_MOD2) { xleac = LKC_TO_LEC_M2(c); } else if (xlkc & LKC_MOD3) { xleac = LKC_TO_LEC_M3(c); } else { xleac = UCH(CurrentLineEditor()[c]); } #endif /* * If we have an intermediate code that says "same as without modifier", * look that up now; otherwise we are already done. - kw */ if (xleac == LYE_UNMOD) { editaction = CurrentLineEditor()[c]; } else { editaction = xleac; } return editaction; } /* * Install lec as the lynxeditaction for lynxkeycode xlkc. func must be * present in the revmap table. For normal (non-modifier) lynxkeycodes, * select_edi selects which of the alternative line-editor binding tables is * modified. If select_edi is positive, only the table given by it is modified * (the DefaultEditBinding table is numbered 1). If select_edi is 0, all * tables are modified. If select_edi is negative, all tables except the one * given by abs(select_edi) are modified. returns TRUE if the mapping was * made, FALSE if not. Note that this remapping cannot be undone (as might be * desirable as a result of re-parsing lynx.cfg), we don't remember the * original editaction from the Bindings tables anywhere. - kw */ BOOL LYRemapEditBinding(int xlkc, int lec, int select_edi) { int j; int c = xlkc & LKC_MASK; BOOLEAN success = FALSE; if (xlkc >= 0 && !(xlkc & LKC_ISLAC) && (c < KEYMAP_SIZE)) { LYEditCode code = (LYEditCode) lec; #ifdef USE_ALT_BINDINGS if (xlkc & LKC_MOD1) { if (c <= LAST_MOD1_LKC) { Mod1Binding[c] = code; success = TRUE; } } else if (xlkc & LKC_MOD2) { if (c <= LAST_MOD2_LKC) { Mod2Binding[c] = code; success = TRUE; } } else if (xlkc & LKC_MOD3) { if (c <= LAST_MOD3_LKC) { Mod3Binding[c] = code; success = TRUE; } } else #endif /* USE_ALT_BINDINGS */ { #ifndef UCHAR_MAX #define UCHAR_MAX 255 #endif if ((unsigned int) lec <= UCHAR_MAX) { if (select_edi > 0) { if ((unsigned int) select_edi < TABLESIZE(LYLineEditors)) { LYLineEditors[select_edi - 1].used[c] = code; success = TRUE; } } else { for (j = 0; j < (int) TABLESIZE(LYLineEditors); j++) { success = TRUE; if ((select_edi < 0) && ((j + 1 + select_edi) == 0)) continue; LYLineEditors[j].used[c] = code; } } } } } return success; } /* * Macro to walk through lkc-indexed tables up to imax, in the (ASCII) order * 97 - 122 ('a' - 'z'), * 32 - 96 (' ' - '`', includes 'A' - 'Z'), * 123 - 126 ('{' - '~'), * 0 - 31 (^@ - ^_), * 256 - imax, * 127 - 255 */ #define NEXT_I(i,imax) ((i==122) ? 32 : (i==96) ? 123 : (i==126) ? 0 :\ (i==31) ? 256 : (i==imax) ? 127 :\ (i==255) ? (-1) :i+1) #define FIRST_I 97 int LYKeyForEditAction(int lec) { int editaction, i; for (i = FIRST_I; i >= 0; i = NEXT_I(i, KEYMAP_SIZE - 1)) { editaction = CurrentLineEditor()[i]; if (editaction == lec) { #ifdef NOT_ASCII if (i < 256) { return FROMASCII(i); } else #endif return i; } } return (-1); } /* * Given a lynxactioncode, return a key (lynxkeycode) or sequence of two keys * that results in the given action while forms-editing. The main keycode is * returned as function value, possibly with modifier bits set; in addition, if * applicable, a key that sets the required modifier flag is returned in * *pmodkey if (pmodkey!=NULL). Non-lineediting bindings that would require * typing LYE_LKCMD (default ^V) to activate are not checked here, the caller * should do that separately if required. If no key is bound by current * line-editor bindings to the action, -1 is returned. * * This is all a bit long - it is general enough to continue to work should the * three ModBinding[] become different tables. - kw */ int LYEditKeyForAction(int lac, int *pmodkey) { int editaction, i, c; int mod1found = -1, mod2found = -1, mod3found = -1; if (pmodkey) *pmodkey = -1; for (i = FIRST_I; i >= 0; i = NEXT_I(i, KEYMAP_SIZE - 1)) { editaction = CurrentLineEditor()[i]; #ifdef NOT_ASCII if (i < 256) { c = FROMASCII(i); } else #endif c = i; if (editaction == (lac | LYE_FORM_LAC)) return c; if (editaction == LYE_FORM_PASS) { #if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE) if (lynx_edit_mode && !no_dired_support && lac && LKC_TO_LAC(key_override, c) == lac) return c; #endif /* DIRED_SUPPORT && OK_OVERRIDE */ if (LKC_TO_LAC(keymap, c) == lac) return c; } if (editaction == LYE_TAB) { #if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE) if (lynx_edit_mode && !no_dired_support && lac && LKC_TO_LAC(key_override, '\t') == lac) return c; #endif /* DIRED_SUPPORT && OK_OVERRIDE */ if (LKC_TO_LAC(keymap, '\t') == lac) return c; } if (editaction == LYE_SETM1 && mod1found < 0) mod1found = i; if (editaction == LYE_SETM2 && mod2found < 0) mod2found = i; if ((editaction & LYE_DF) && mod3found < 0) mod3found = i; } #ifdef USE_ALT_BINDINGS if (mod3found >= 0) { for (i = mod3found; i >= 0; i = NEXT_I(i, LAST_MOD3_LKC)) { editaction = CurrentLineEditor()[i]; if (!(editaction & LYE_DF)) continue; editaction = Mod3Binding[i]; #ifdef NOT_ASCII if (i < 256) { c = FROMASCII(i); } else #endif c = i; if (pmodkey) *pmodkey = c; if (editaction == (lac | LYE_FORM_LAC)) return (c | LKC_MOD3); if (editaction == LYE_FORM_PASS) { #if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE) if (lynx_edit_mode && !no_dired_support && lac && LKC_TO_LAC(key_override, c) == lac) return (c | LKC_MOD3); #endif /* DIRED_SUPPORT && OK_OVERRIDE */ if (LKC_TO_LAC(keymap, c) == lac) return (c | LKC_MOD3); } if (editaction == LYE_TAB) { #if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE) if (lynx_edit_mode && !no_dired_support && lac && LKC_TO_LAC(key_override, '\t') == lac) return (c | LKC_MOD3); #endif /* DIRED_SUPPORT && OK_OVERRIDE */ if (LKC_TO_LAC(keymap, '\t') == lac) return (c | LKC_MOD3); } } } if (mod1found >= 0) { if (pmodkey) { #ifdef NOT_ASCII if (mod1found < 256) { *pmodkey = FROMASCII(mod1found); } else #endif *pmodkey = mod1found; } for (i = FIRST_I; i >= 0; i = NEXT_I(i, LAST_MOD1_LKC)) { editaction = Mod1Binding[i]; #ifdef NOT_ASCII if (i < 256) { c = FROMASCII(i); } else #endif c = i; if (editaction == (lac | LYE_FORM_LAC)) return (c | LKC_MOD1); if (editaction == LYE_FORM_PASS) { #if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE) if (lynx_edit_mode && !no_dired_support && lac && LKC_TO_LAC(key_override, c) == lac) return (c | LKC_MOD1); #endif /* DIRED_SUPPORT && OK_OVERRIDE */ if (LKC_TO_LAC(keymap, c) == lac) return (c | LKC_MOD1); } if (editaction == LYE_TAB) { #if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE) if (lynx_edit_mode && !no_dired_support && lac && LKC_TO_LAC(key_override, '\t') == lac) return (c | LKC_MOD1); #endif /* DIRED_SUPPORT && OK_OVERRIDE */ if (LKC_TO_LAC(keymap, '\t') == lac) return (c | LKC_MOD1); } } } if (mod2found >= 0) { if (pmodkey) { #ifdef NOT_ASCII if (mod1found < 256) { *pmodkey = FROMASCII(mod1found); } else #endif *pmodkey = mod1found; } for (i = FIRST_I; i >= 0; i = NEXT_I(i, LAST_MOD2_LKC)) { editaction = Mod2Binding[i]; #ifdef NOT_ASCII if (i < 256) { c = FROMASCII(i); } else #endif c = i; if (editaction == (lac | LYE_FORM_LAC)) return (c | LKC_MOD2); if (editaction == LYE_FORM_PASS) { #if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE) if (lynx_edit_mode && !no_dired_support && lac && LKC_TO_LAC(key_override, c) == lac) return (c | LKC_MOD2); #endif /* DIRED_SUPPORT && OK_OVERRIDE */ if (LKC_TO_LAC(keymap, c) == lac) return (c | LKC_MOD2); } if (editaction == LYE_TAB) { #if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE) if (lynx_edit_mode && !no_dired_support && lac && LKC_TO_LAC(key_override, '\t') == lac) return (c | LKC_MOD2); #endif /* DIRED_SUPPORT && OK_OVERRIDE */ if (LKC_TO_LAC(keymap, '\t') == lac) return (c | LKC_MOD2); } } } #endif /* USE_ALT_BINDINGS */ if (pmodkey) *pmodkey = -1; return (-1); } #if 0 /* * This function was useful in converting the hand-crafted key-bindings to * their reusable form in 2.8.8 -TD */ static void checkEditMap(LYEditConfig * table) { unsigned j, k; char comment[80]; int first = TRUE; for (j = 0; table->init[j].code >= 0; ++j) { int code = table->init[j].code; if (table->init[j].edit != table->used[code]) { if (first) { printf("TABLE %s\n", table->name); first = FALSE; } printf("%u: init %d vs used %d\n", j, table->init[j].edit, table->used[code]); } } for (j = 0; j < KEYMAP_SIZE; ++j) { int code = (int) j; BOOL found = FALSE; for (k = 0; table->init[k].code >= 0; ++k) { if (code == table->init[k].code) { found = TRUE; break; } } if (!found) { if (table->used[j] != 0) { int edit = table->used[j]; int has_DF = (edit & LYE_DF); int has_LAC = (edit & LYE_FORM_LAC); const char *prefix = "LYE_"; const char *name = 0; edit &= 0x7f; if (has_LAC) { Kcmd *cmd = LYKeycodeToKcmd(edit); if (cmd != 0) { prefix = "LYK_"; name = cmd->name; } } else { name = lec_to_lecname(edit); } if (j < 32) { char temp[80]; const char *what = 0; switch (j) { case 0: what = "nul"; break; case 17: what = "XON"; break; case 19: what = "XOFF"; break; default: sprintf(temp, "^%c", j + 'A'); what = temp; break; } sprintf(comment, "\t/* %s */", what); } else if (j < 127) { sprintf(comment, "\t/* %c */", j); } else { const char *what = LYextraKeysToName(j); if (Non_Empty(what)) { sprintf(comment, "\t/* %s%s */", what, ((StrChr(what, '_') != 0) ? "" : "_KEY")); } else { strcpy(comment, ""); } } if (name == 0) { name = "XXX"; } else if (!strcasecomp(name, "PASS")) { name = "FORM_PASS"; } if (first) { printf("TABLE %s\n", table->name); first = FALSE; } printf("\t{ %d, %s%s%s%s },%s\n", code, prefix, name, has_DF ? "|LYE_DF" : "", has_LAC ? "|LYE_FORM_LAC" : "", comment); } } } } #else #define checkEditMap(table) /* nothing */ #endif static void initLineEditor(LYEditConfig * table) { unsigned k; LYEditCode *used = table->used; const LYEditInit *init = table->init; memset(used, 0, sizeof(LYEditCode) * KEYMAP_SIZE); for (k = 0; init[k].code >= 0; ++k) { int code = init[k].code; used[code] = init[k].edit; } checkEditMap(table); } /* * Reset the editor bindings to their default values. */ void LYinitEditmap(void) { unsigned j; for (j = 0; j < TABLESIZE(LYLineEditors); ++j) { LYEditorNames[j] = LYLineEditors[j].name; initLineEditor(&LYLineEditors[j]); } #ifdef USE_ALT_BINDINGS for (j = 0; j < TABLESIZE(LYModifierBindings); ++j) { initLineEditor(&LYModifierBindings[j]); } #endif } static char *showRanges(int *state) { char *result = 0; int range[2]; int i; range[0] = range[1] = -1; for (i = 0; i < KEYMAP_SIZE; ++i) { if (!state[i]) { int code = CurrentLineEditor()[i]; if (code == LYE_CHAR) { if (range[0] < 0) range[0] = i; range[1] = i; state[i] = 3; } else if (range[0] >= 0) { if (non_empty(result)) StrAllocCat(result, ", "); HTSprintf(&result, "%d-%d", range[0], range[1]); range[0] = range[1] = -1; } } } return result; } static int LYLoadEditmap(const char *arg GCC_UNUSED, HTParentAnchor *anAnchor, HTFormat format_out, HTStream *sink) { #define FORMAT " %-*s %-*s - %s\n" HTFormat format_in = WWW_HTML; HTStream *target; int state[KEYMAP_SIZE]; int width[2]; char *buf = 0; char *ranges = 0; struct emap *mp; int i; int hanging; int wrapped; int had_output = FALSE; int result; if ((target = HTStreamStack(format_in, format_out, sink, anAnchor)) != 0) { anAnchor->no_cache = TRUE; HTSprintf0(&buf, "\n\n%s\n\n\n", CURRENT_EDITMAP_TITLE); PUTS(buf); HTSprintf0(&buf, "
\n");
	PUTS(buf);

	/* determine the column-widths we will use for showing bindings */
	width[0] = 0;
	width[1] = 0;
	for (i = 0; i < KEYMAP_SIZE; ++i) {
	    int code = CurrentLineEditor()[i];

	    if (code == LYE_NOP) {
		state[i] = 1;
	    } else {
		int need;

		if ((mp = code2emap(code)) != 0) {
		    state[i] = 0;
		    if ((need = (int) strlen(mp->name)) > width[0])
			width[0] = need;
		    if ((need = (int) strlen(mp->descr)) > width[1])
			width[1] = need;
		} else {
		    state[i] = 2;
		}
	    }
	}
	hanging = 2 + width[0] + 2 + width[1] + 5;
	wrapped = hanging;

	/*
	 * Tell which set of bindings we are showing, and link to the
	 * handcrafted page, which adds explanations.
	 */
	PUTS(gettext("These are the current edit-bindings:"));
	HTSprintf0(&buf,
		   " %s\n\n",
		   LYLineeditHelpURL(),
		   LYEditorNames[current_lineedit]);
	PUTS(buf);

	/* Show by groups to match the arrangement in the handmade files. */
	for (mp = ekmap; mp->name != 0; ++mp) {
	    if (isEmpty(mp->name)) {
		if (had_output) {
		    PUTS("\n");
		    had_output = FALSE;
		}
	    } else if (mp->code == LYE_CHAR) {
		ranges = showRanges(state);
		HTSprintf0(&buf, FORMAT,
			   width[0], mp->name,
			   width[1], mp->descr,
			   ranges);
		FREE(ranges);
		PUTS(buf);
		had_output = TRUE;
	    } else {
		for (i = 0; i < KEYMAP_SIZE; ++i) {
		    int code = CurrentLineEditor()[i];

		    if ((code == mp->code) && !state[i]) {
			char *value = LYKeycodeToString(i, (i >= 160 &&
							    i <= 255));
			int before = wrapped + (ranges ? ((int)
							  strlen(ranges)) : 0);
			int after = before;

			if (non_empty(ranges)) {
			    StrAllocCat(ranges, ", ");
			    after += 2;
			}
			after += (int) strlen(value) + 2;
			if ((before / LYcols) != (after / LYcols)) {
			    wrapped += (LYcols - (before % LYcols));
			    HTSprintf(&ranges, "\n%-*s", hanging, " ");
			}
			StrAllocCat(ranges, value);
		    }
		}
		if (non_empty(ranges)) {
		    LYEntify(&ranges, TRUE);
		    HTSprintf0(&buf, FORMAT,
			       width[0], mp->name,
			       width[1], mp->descr,
			       ranges);
		    PUTS(buf);
		    FREE(ranges);
		    had_output = TRUE;
		}
	    }
	}

	HTSprintf0(&buf, "
\n\n\n"); PUTS(buf); (*target->isa->_free) (target); result = HT_LOADED; } else { HTSprintf0(&buf, CANNOT_CONVERT_I_TO_O, HTAtom_name(format_in), HTAtom_name(format_out)); HTAlert(buf); result = HT_NOT_LOADED; } FREE(ranges); FREE(buf); return result; #undef FORMAT } #ifdef GLOBALDEF_IS_MACRO #define _LYEDITMAP_C_GLOBALDEF_1_INIT { "LYNXEDITMAP", LYLoadEditmap, 0} GLOBALDEF(HTProtocol, LYLynxEditmap, _LYEDITMAP_C_GLOBALDEF_1_INIT); #else GLOBALDEF HTProtocol LYLynxEditmap = { "LYNXEDITMAP", LYLoadEditmap, 0 }; #endif /* GLOBALDEF_IS_MACRO */