home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume22 / nn6.4 / part06 / keymap.c next >
Encoding:
C/C++ Source or Header  |  1990-06-07  |  16.9 KB  |  805 lines

  1. /*
  2.  *    (c) Copyright 1990, Kim Fabricius Storm.  All rights reserved.
  3.  *
  4.  *    Keyboard (re)mapping
  5.  */
  6.  
  7. #include "config.h"
  8. #include "keymap.h"
  9. #include "term.h"
  10.  
  11.  
  12. /*
  13.  * standard keyboard mapping for more()
  14.  *
  15.  *    redraw            ^L, ^R
  16.  *    continue        space
  17.  *    repeat message        ^P
  18.  *    help            ?
  19.  *    shell escape        !
  20.  *    version            V
  21.  *    extended command    :
  22.  *    quit            Q
  23.  *
  24.  *    save            S, O
  25.  *    save, no header        W
  26.  *    reply            R
  27.  *    follow up        F
  28.  *    mail (forward)        M
  29.  *    cancel            C
  30.  *    unsubscribe        U
  31.  *    group overview        Y
  32.  *    print article        P
  33.  *    kill handling        K
  34.  *
  35.  *    update, goto next group    X
  36.  *    no update, next group    q, Z
  37.  *    return to menu        =
  38.  *    prev article        p
  39.  *    goto group        G
  40.  *
  41.  *    line forward        CR/NL
  42.  *    half page forward    d/^D
  43.  *    half page back        u/^U
  44.  *    full page back        BS, DEL, (up arrow)
  45.  *    goto line        g
  46.  *    goto match        /
  47.  *    next match        .
  48.  *
  49.  *    select subject        N, *
  50.  *
  51.  *    header            h
  52.  *    digest header        H
  53.  *    top            t
  54.  *    last page        $
  55.  *    leave article        l
  56.  *    leave article to next    L
  57.  *    next article        n
  58.  *    kill subject        k
  59.  *
  60.  *    rot13            D
  61.  *    compress        c
  62.  */
  63.  
  64. export int more_key_map[KEY_MAP_SIZE] = {
  65.  
  66. /* NUL ^@ */    K_UNBOUND,
  67. /* SOH ^A */    K_UNBOUND,
  68. /* STX ^B */    K_UNBOUND,
  69. /* ETX ^C */    K_UNBOUND,
  70. /* EOT ^D */        K_NEXT_HALF_PAGE,
  71. /* ENQ ^E */    K_UNBOUND,
  72. /* ACK ^F */    K_UNBOUND,
  73. /* BEL ^G */        K_INVALID,
  74. /* BS  ^H */        K_PREV_PAGE,
  75. /* TAB ^I */        K_SKIP_LINES,
  76. /* NL  ^J */        K_NEXT_LINE,
  77. /* VT  ^K */    K_UNBOUND,
  78. /* FF  ^L */        K_REDRAW,
  79. /* CR  ^M */        K_NEXT_LINE,
  80. /* SO  ^N */    K_UNBOUND,
  81. /* SI  ^O */    K_UNBOUND,
  82. /* DLE ^P */        K_LAST_MESSAGE,
  83. /* DC1 ^Q */    K_UNBOUND,
  84. /* DC2 ^R */        K_REDRAW,
  85. /* DC3 ^S */    K_UNBOUND,
  86. /* DC4 ^T */    K_UNBOUND,
  87. /* NAK ^U */        K_PREV_HALF_PAGE,
  88. /* SYN ^V */        K_NEXT_PAGE,
  89. /* ETB ^W */    K_UNBOUND,
  90. /* CAN ^X */    K_UNBOUND,
  91. /* EM  ^Y */    K_UNBOUND,
  92. /* SUB ^Z */    K_UNBOUND,
  93. /* ESC ^[ */    K_UNBOUND,
  94. /* FS  ^\ */    K_UNBOUND,
  95. /* GS  ^] */    K_UNBOUND,
  96. /* RS  ^^ */    K_UNBOUND,
  97. /* US  ^_ */    K_UNBOUND,
  98. /* SP  */        K_CONTINUE,
  99. /* !   */        K_SHELL,
  100. /* "   */    K_UNBOUND,
  101. /* #   */    K_UNBOUND,
  102. /* $   */        K_LAST_PAGE,
  103. /* %   */        K_PREVIEW,
  104. /* &   */    K_UNBOUND,
  105. /* '   */    K_UNBOUND,
  106. /* (   */    K_UNBOUND,
  107. /* )   */    K_UNBOUND,
  108. /* *   */        K_SELECT_SUBJECT,
  109. /* +   */    K_UNBOUND,
  110. /* ,   */    K_UNBOUND,
  111. /* -   */    K_UNBOUND,
  112. /* .   */        K_NEXT_MATCH,
  113. /* /   */        K_GOTO_MATCH,
  114. /* 0   */    K_UNBOUND,
  115. /* 1   */    K_UNBOUND,
  116. /* 2   */    K_UNBOUND,
  117. /* 3   */    K_UNBOUND,
  118. /* 4   */    K_UNBOUND,
  119. /* 5   */    K_UNBOUND,
  120. /* 6   */    K_UNBOUND,
  121. /* 7   */    K_UNBOUND,
  122. /* 8   */    K_UNBOUND,
  123. /* 9   */    K_UNBOUND,
  124. /* :   */         K_EXTENDED_CMD,
  125. /* ;   */    K_UNBOUND,
  126. /* <   */    K_UNBOUND,
  127. /* =   */        K_BACK_TO_MENU,
  128. /* >   */    K_UNBOUND,
  129. /* ?   */        K_HELP,
  130. /* @   */    K_UNBOUND,
  131. /* A   */    K_UNBOUND,
  132. /* B   */    K_UNBOUND,
  133. /* C   */        K_CANCEL,
  134. /* D   */        K_ROT13,
  135. /* E   */    K_UNBOUND,
  136. /* F   */        K_FOLLOW_UP,
  137. /* G   */        K_GOTO_GROUP,
  138. /* H   */        K_FULL_DIGEST,
  139. /* I   */    K_UNBOUND,
  140. /* J   */    K_UNBOUND,
  141. /* K   */        K_KILL_HANDLING,
  142. /* L   */        K_LEAVE_NEXT,
  143. /* M   */        K_MAIL_OR_FORWARD,
  144. /* N   */        K_NEXT_GROUP_NO_UPDATE,
  145. /* O   */        K_SAVE_SHORT_HEADER,
  146. /* P   */        K_PRINT,
  147. /* Q   */         K_QUIT,
  148. /* R   */        K_REPLY,
  149. /* S   */        K_SAVE_FULL_HEADER,
  150. /* T   */    K_UNBOUND,
  151. /* U   */        K_UNSUBSCRIBE,
  152. /* V   */         K_VERSION,
  153. /* W   */        K_SAVE_NO_HEADER,
  154. /* X   */        K_READ_GROUP_UPDATE,
  155. /* Y   */        K_GROUP_OVERVIEW,
  156. /* Z   */        K_BACK_TO_MENU,
  157. /* [   */    K_UNBOUND,
  158. /* \   */    K_UNBOUND,
  159. /* ]   */    K_UNBOUND,
  160. /* ^   */        K_FIRST_PAGE,
  161. /* _   */    K_UNBOUND,
  162. /* `   */    K_UNBOUND,
  163. /* a   */        K_FORW_ARTICLE,
  164. /* b   */        K_BACK_ARTICLE,
  165. /* c   */        K_COMPRESS,
  166. /* d   */        K_NEXT_HALF_PAGE,
  167. /* e   */    K_UNBOUND,
  168. /* f   */        K_FOLLOW_UP,
  169. /* g   */        K_GOTO_LINE,
  170. /* h   */        K_HEADER_PAGE,
  171. /* i   */    K_UNBOUND,
  172. /* j   */    K_UNBOUND,
  173. /* k   */        K_NEXT_SUBJECT,
  174. /* l   */        K_LEAVE_ARTICLE,
  175. /* m   */        K_MAIL_OR_FORWARD,
  176. /* n   */        K_NEXT_ARTICLE,
  177. /* o   */        K_SAVE_SHORT_HEADER,
  178. /* p   */        K_PREVIOUS /* article */,
  179. /* q   */        K_NEXT_GROUP_NO_UPDATE,
  180. /* r   */        K_REPLY,
  181. /* s   */        K_SAVE_FULL_HEADER,
  182. /* t   */        K_FIRST_PAGE,
  183. /* u   */        K_PREV_HALF_PAGE,
  184. /* v   */    K_UNBOUND,
  185. /* w   */        K_SAVE_NO_HEADER,
  186. /* x   */    K_UNBOUND,
  187. /* y   */    K_UNBOUND,
  188. /* z   */    K_UNBOUND,
  189. /* {   */    K_UNBOUND,
  190. /* |   */    K_UNBOUND,
  191. /* }   */    K_UNBOUND,
  192. /* ~   */    K_UNBOUND,
  193. /* DEL */        K_PREV_PAGE,
  194. /* 200 */    K_UNBOUND,
  195. /* up  */        K_PREV_PAGE,
  196. /* down */        K_NEXT_PAGE,
  197. /* left */    K_UNBOUND,
  198. /* right */    K_UNBOUND,
  199. /* #0  */    K_UNBOUND,
  200. /* #1  */    K_UNBOUND,
  201. /* #2  */    K_UNBOUND,
  202. /* #3  */    K_UNBOUND,
  203. /* #4  */    K_UNBOUND,
  204. /* #5  */    K_UNBOUND,
  205. /* #6  */    K_UNBOUND,
  206. /* #7  */    K_UNBOUND,
  207. /* #8  */    K_UNBOUND,
  208. /* #9  */    K_UNBOUND
  209. };
  210.  
  211.  
  212.  
  213. /*
  214.  * standard keyboard mappings for menu()
  215.  *
  216.  *    illegal command
  217.  *    redraw            ^L, ^R
  218.  *    continue        space
  219.  *    continue no mark    return, newline
  220.  *    repeat message        ^P
  221.  *    help            ?
  222.  *    shell escape        !
  223.  *    version            V
  224.  *    alternative commands    :
  225.  *    quit            Q
  226.  *
  227.  *    save            S, O
  228.  *    save, no header        W
  229.  *    reply            R
  230.  *    follow up        F
  231.  *    mail (forward)        M
  232.  *    cancel            C
  233.  *    unsubscribe        U
  234.  *    group overview        Y
  235.  *    kill handling        K
  236.  *    junk articles        J
  237.  *
  238.  *    read, then next        X
  239.  *    read, then same        Z
  240.  *    no update, next        N
  241.  *    prev group        P
  242.  *    goto group        G
  243.  *    advance group        A
  244.  *    back group        B
  245.  *
  246.  *    article identifier    a-z 0-9
  247.  *    inverse            @
  248.  *    select current, next    .
  249.  *    next            , (down arrow)
  250.  *    prev            / (up arrow)
  251.  *    select subject        *
  252.  *    range            -
  253.  *    auto select         +
  254.  *
  255.  *    next page        >
  256.  *    prev page        <
  257.  *    first page        ^
  258.  *    last page        $
  259.  *
  260.  *    pre-view article    %
  261.  *
  262.  *    layout            L
  263.  */
  264.  
  265.  
  266. export int menu_key_map[KEY_MAP_SIZE] = {
  267.  
  268. /* NUL ^@ */    K_UNBOUND,
  269. /* SOH ^A */    K_UNBOUND,
  270. /* STX ^B */    K_UNBOUND,
  271. /* ETX ^C */    K_UNBOUND,
  272. /* EOT ^D */    K_UNBOUND,
  273. /* ENQ ^E */    K_UNBOUND,
  274. /* ACK ^F */    K_UNBOUND,
  275. /* BEL ^G */        K_INVALID,
  276. /* BS  ^H */        K_PREV_LINE,
  277. /* TAB ^I */    K_UNBOUND,
  278. /* NL  ^J */        K_CONTINUE_NO_MARK,
  279. /* VT  ^K */    K_UNBOUND,
  280. /* FF  ^L */        K_REDRAW,
  281. /* CR  ^M */        K_CONTINUE_NO_MARK,
  282. /* SO  ^N */    K_UNBOUND,
  283. /* SI  ^O */    K_UNBOUND,
  284. /* DLE ^P */        K_LAST_MESSAGE,
  285. /* DC1 ^Q */    K_UNBOUND,
  286. /* DC2 ^R */        K_REDRAW,
  287. /* DC3 ^S */    K_UNBOUND,
  288. /* DC4 ^T */    K_UNBOUND,
  289. /* NAK ^U */    K_UNBOUND,
  290. /* SYN ^V */        K_NEXT_PAGE,
  291. /* ETB ^W */    K_UNBOUND,
  292. /* CAN ^X */    K_UNBOUND,
  293. /* EM  ^Y */    K_UNBOUND,
  294. /* SUB ^Z */    K_UNBOUND,
  295. /* ESC ^[ */    K_UNBOUND,
  296. /* FS  ^\ */    K_UNBOUND,
  297. /* GS  ^] */    K_UNBOUND,
  298. /* RS  ^^ */    K_UNBOUND,
  299. /* US  ^_ */    K_UNBOUND,
  300. /* SP  */        K_CONTINUE,
  301. /* !   */        K_SHELL,
  302. /* "   */        K_LAYOUT,
  303. /* #   */    K_UNBOUND,
  304. /* $   */        K_LAST_PAGE,
  305. /* %   */        K_PREVIEW,
  306. /* &   */    K_UNBOUND,
  307. /* '   */    K_UNBOUND,
  308. /* (   */    K_UNBOUND,
  309. /* )   */    K_UNBOUND,
  310. /* *   */        K_SELECT_SUBJECT,
  311. /* +   */        K_AUTO_SELECT,
  312. /* ,   */        K_NEXT_LINE,
  313. /* -   */        K_SELECT_RANGE,
  314. /* .   */        K_SELECT,
  315. /* /   */        K_PREV_LINE,
  316. /* 0   */    K_ARTICLE_ID + 26,
  317. /* 1   */    K_ARTICLE_ID + 27,
  318. /* 2   */    K_ARTICLE_ID + 28,
  319. /* 3   */    K_ARTICLE_ID + 29,
  320. /* 4   */    K_ARTICLE_ID + 30,
  321. /* 5   */    K_ARTICLE_ID + 31,
  322. /* 6   */    K_ARTICLE_ID + 32,
  323. /* 7   */    K_ARTICLE_ID + 33,
  324. /* 8   */    K_ARTICLE_ID + 34,
  325. /* 9   */    K_ARTICLE_ID + 35,
  326. /* :   */        K_EXTENDED_CMD,
  327. /* ;   */    K_UNBOUND,
  328. /* <   */        K_PREV_PAGE,
  329. /* =   */        K_GOTO_MATCH,
  330. /* >   */        K_NEXT_PAGE,
  331. /* ?   */        K_HELP,
  332. /* @   */        K_SELECT_INVERT,
  333. /* A   */        K_ADVANCE_GROUP,
  334. /* B   */        K_BACK_GROUP,
  335. /* C   */        K_CANCEL,
  336. /* D   */    K_UNBOUND,
  337. /* E   */    K_UNBOUND,
  338. /* F   */        K_FOLLOW_UP,
  339. /* G   */        K_GOTO_GROUP,
  340. /* H   */    K_UNBOUND,
  341. /* I   */    K_UNBOUND,
  342. /* J   */        K_JUNK_ARTICLES,
  343. /* K   */        K_KILL_HANDLING,
  344. /* L   */        K_LEAVE_NEXT,
  345. /* M   */        K_MAIL_OR_FORWARD,
  346. /* N   */        K_NEXT_GROUP_NO_UPDATE,
  347. /* O   */        K_SAVE_SHORT_HEADER,
  348. /* P   */        K_PREVIOUS /* group */,
  349. /* Q   */        K_QUIT,
  350. /* R   */        K_REPLY,
  351. /* S   */        K_SAVE_FULL_HEADER,
  352. /* T   */    K_UNBOUND,
  353. /* U   */        K_UNSUBSCRIBE,
  354. /* V   */        K_VERSION,
  355. /* W   */        K_SAVE_NO_HEADER,
  356. /* X   */        K_READ_GROUP_UPDATE,
  357. /* Y   */        K_GROUP_OVERVIEW,
  358. /* Z   */        K_READ_GROUP_THEN_SAME,
  359. /* [   */    K_UNBOUND,
  360. /* \   */    K_UNBOUND,
  361. /* ]   */    K_UNBOUND,
  362. /* ^   */        K_FIRST_PAGE,
  363. /* _   */    K_UNBOUND,
  364. /* `   */    K_UNBOUND,
  365. /* a   */    K_ARTICLE_ID +  0,
  366. /* b   */    K_ARTICLE_ID +  1,
  367. /* c   */    K_ARTICLE_ID +  2,
  368. /* d   */    K_ARTICLE_ID +  3,
  369. /* e   */    K_ARTICLE_ID +  4,
  370. /* f   */    K_ARTICLE_ID +  5,
  371. /* g   */    K_ARTICLE_ID +  6,
  372. /* h   */    K_ARTICLE_ID +  7,
  373. /* i   */    K_ARTICLE_ID +  8,
  374. /* j   */    K_ARTICLE_ID +  9,
  375. /* k   */    K_ARTICLE_ID + 10,
  376. /* l   */    K_ARTICLE_ID + 11,
  377. /* m   */    K_ARTICLE_ID + 12,
  378. /* n   */    K_ARTICLE_ID + 13,
  379. /* o   */    K_ARTICLE_ID + 14,
  380. /* p   */    K_ARTICLE_ID + 15,
  381. /* q   */    K_ARTICLE_ID + 16,
  382. /* r   */    K_ARTICLE_ID + 17,
  383. /* s   */    K_ARTICLE_ID + 18,
  384. /* t   */    K_ARTICLE_ID + 19,
  385. /* u   */    K_ARTICLE_ID + 20,
  386. /* v   */    K_ARTICLE_ID + 21,
  387. /* w   */    K_ARTICLE_ID + 22,
  388. /* x   */    K_ARTICLE_ID + 23,
  389. /* y   */    K_ARTICLE_ID + 24,
  390. /* z   */    K_ARTICLE_ID + 25,
  391. /* {   */    K_UNBOUND,
  392. /* |   */    K_UNBOUND,
  393. /* }   */    K_UNBOUND,
  394. /* ~   */        K_UNSELECT_ALL,
  395. /* DEL */        K_PREV_LINE,
  396. /* 200 */    K_UNBOUND,
  397. /* up  */        K_PREV_LINE,
  398. /* down */        K_NEXT_LINE,
  399. /* left */    K_UNBOUND,
  400. /* right */    K_UNBOUND,
  401. /* #0  */    K_UNBOUND,
  402. /* #1  */    K_UNBOUND,
  403. /* #2  */    K_UNBOUND,
  404. /* #3  */    K_UNBOUND,
  405. /* #4  */    K_UNBOUND,
  406. /* #5  */    K_UNBOUND,
  407. /* #6  */    K_UNBOUND,
  408. /* #7  */    K_UNBOUND,
  409. /* #8  */    K_UNBOUND,
  410. /* #9  */    K_UNBOUND
  411. };
  412.  
  413.  
  414.  
  415. static struct command_name_map {
  416.     char *    cmd_name;
  417.     int       cmd_code;
  418.     int          cmd_restriction;
  419. } command_name_map[] = {
  420.  
  421.     "advance-article",        K_FORW_ARTICLE,        K_ONLY_MORE,
  422.     "advance-group",        K_ADVANCE_GROUP,    0,
  423.     "article",            K_ARTICLE_ID,        K_ONLY_MENU,
  424.     "as",            K_EQUAL_KEY,        0,
  425.  
  426.     "back-article",        K_BACK_ARTICLE,        K_ONLY_MORE,
  427.     "back-group",        K_BACK_GROUP,        0,
  428.  
  429.     "cancel",            K_CANCEL,        0,
  430.     "command",            K_EXTENDED_CMD,        0,
  431.     "compress",            K_COMPRESS,        K_ONLY_MORE,
  432.     "continue",            K_CONTINUE,        0,
  433.     "continue-no-mark",        K_CONTINUE_NO_MARK,    K_ONLY_MENU,
  434.  
  435.     "decode",            K_UUDECODE,        0,
  436.  
  437.     "find",            K_GOTO_MATCH,        0,
  438.     "find-next",        K_NEXT_MATCH,        K_ONLY_MORE,
  439.     "follow",            K_FOLLOW_UP,        0,
  440.     "full-digest",        K_FULL_DIGEST,        K_ONLY_MORE,
  441.  
  442.     "goto-group",        K_GOTO_GROUP,        0,
  443.     "goto-menu",        K_BACK_TO_MENU,        K_ONLY_MORE,
  444.  
  445.     "help",            K_HELP,            0,
  446.  
  447.     "junk-articles",        K_JUNK_ARTICLES,    K_ONLY_MENU,
  448.  
  449.     "kill-select",        K_KILL_HANDLING,    0,
  450.  
  451.     "layout",            K_LAYOUT,        K_ONLY_MENU,
  452.     "leave-article",        K_LEAVE_ARTICLE,    K_ONLY_MORE,
  453.     "leave-next",        K_LEAVE_NEXT,        K_ONLY_MORE,
  454.     "line+1",            K_NEXT_LINE,        0,
  455.     "line-1",            K_PREV_LINE,        0,
  456.     "line=@",            K_GOTO_LINE,        K_ONLY_MORE,
  457.  
  458.     "macro",            K_MACRO,        0,
  459.     "mail",            K_MAIL_OR_FORWARD,    0,
  460.     "message",            K_LAST_MESSAGE,        0,
  461.  
  462.     "next-article",        K_NEXT_ARTICLE,        K_ONLY_MORE,
  463.     "next-group",        K_NEXT_GROUP_NO_UPDATE,    0,
  464.     "next-subject",        K_NEXT_SUBJECT,        K_ONLY_MORE,
  465.     "nil",            K_UNBOUND,        0,
  466.  
  467.     "overview",            K_GROUP_OVERVIEW,    0,
  468.  
  469.     "page+1",            K_NEXT_PAGE,        0,
  470.     "page+1/2",            K_NEXT_HALF_PAGE,    K_ONLY_MORE,
  471.     "page-1",            K_PREV_PAGE,        0,
  472.     "page-1/2",            K_PREV_HALF_PAGE,    K_ONLY_MORE,
  473.     "page=$",            K_LAST_PAGE,        0,
  474.     "page=0",            K_HEADER_PAGE,        0,
  475.     "page=1",            K_FIRST_PAGE,        0,
  476.     "page=@",            K_GOTO_PAGE,        K_ONLY_MORE,
  477.  
  478.     "patch",            K_PATCH,        0,
  479.     "post",            K_POST,            0,
  480.     "preview",            K_PREVIEW,        0,
  481.     "previous",            K_PREVIOUS,        0,
  482.     "print",            K_PRINT,        0,
  483.  
  484.     "quit",            K_QUIT,            0,
  485.  
  486.     "read-return",        K_READ_GROUP_THEN_SAME,    K_ONLY_MENU,
  487.     "read-skip",        K_READ_GROUP_UPDATE,    0,
  488.     "redraw",            K_REDRAW,        0,
  489.     "reply",            K_REPLY,        0,
  490.     "rot13",            K_ROT13,        K_ONLY_MORE,
  491.  
  492.     "save-body",        K_SAVE_NO_HEADER,    0,
  493.     "save-full",        K_SAVE_FULL_HEADER,    0,
  494.     "save-short",        K_SAVE_SHORT_HEADER,    0,
  495.     "select",            K_SELECT,        K_ONLY_MENU,
  496.     "select-auto",        K_AUTO_SELECT,        K_ONLY_MENU,
  497.     "select-invert",        K_SELECT_INVERT,    K_ONLY_MENU,
  498.     "select-range",        K_SELECT_RANGE,        K_ONLY_MENU,
  499.     "select-subject",        K_SELECT_SUBJECT,    0,
  500.     "shell",            K_SHELL,        0,
  501.     "skip-lines",        K_SKIP_LINES,        0,
  502.  
  503.     "unselect-all",        K_UNSELECT_ALL,        K_ONLY_MENU,
  504.     "unshar",            K_UNSHAR,        0,
  505.     "unsub",            K_UNSUBSCRIBE,        0,
  506.  
  507.     "version",            K_VERSION,        0,
  508.  
  509.     (char *)NULL,        0,            0
  510. };
  511.  
  512. static int name_map_size;
  513. static int max_cmd_name_length = 14;    /* recalculate if table is changed */
  514.  
  515. export key_type global_key_map[KEY_MAP_SIZE];
  516.  
  517.  
  518. init_key_map()
  519. {
  520.     register int c;
  521.     register struct command_name_map *cnmp;
  522.  
  523.     for (c = 0; c < KEY_MAP_SIZE; c++) global_key_map[c] = c;
  524.  
  525.     for (cnmp = command_name_map; cnmp->cmd_name; cnmp++);
  526.     name_map_size = cnmp - command_name_map;
  527. }
  528.  
  529.  
  530. lookup_command(command, restriction)
  531. char *command;
  532. int restriction;
  533. {
  534.     register struct command_name_map *cnmp;
  535.     register i, j, k, t;
  536.  
  537.     i = 0; j = name_map_size - 1;
  538.  
  539.     while (i <= j) {
  540.     k = (i + j) / 2;
  541.     cnmp = &command_name_map[k];
  542.  
  543.     if ( (t=strcmp(command, cnmp->cmd_name)) > 0)
  544.         i = k+1;
  545.     else
  546.     if (t < 0)
  547.         j = k-1;
  548.     else {
  549.         if (cnmp->cmd_restriction == 0
  550.         || (cnmp->cmd_restriction & restriction))
  551.         return cnmp->cmd_code;
  552.         break;
  553.     }
  554.     }
  555.  
  556.     return K_INVALID;
  557. }
  558.  
  559.  
  560. cmd_completion(path, index)
  561. char *path;
  562. int index;
  563. {
  564.     static char *head, *tail = NULL;
  565.     static int len;
  566.     static struct command_name_map *cmd, *help_cmd;
  567.  
  568.     if (index < 0) return 0;
  569.  
  570.     if (path) {
  571.     head = path;
  572.     tail = path + index;
  573.     while (*head && isspace(*head)) head++;
  574.     help_cmd = cmd = command_name_map;
  575.     len = tail - head;
  576.  
  577.     return 1;
  578.     }
  579.  
  580.     if (index) {
  581.     list_completion((char *)NULL);
  582.  
  583.     if (help_cmd->cmd_name == NULL)
  584.         help_cmd = command_name_map;
  585.  
  586.     for (;help_cmd->cmd_name; help_cmd++) {
  587.         index = strncmp(help_cmd->cmd_name, head, len);
  588.         if (index < 0) continue;
  589.         if (index > 0) {
  590.         help_cmd = command_name_map;
  591.         break;
  592.         }
  593.         if (list_completion(help_cmd->cmd_name) == 0) break;
  594.     }
  595.     fl;
  596.     return 1;
  597.     }
  598.  
  599.     for (; cmd->cmd_name; cmd++) {
  600.     if (len == 0)
  601.         index = 0;
  602.     else
  603.         index = strncmp(cmd->cmd_name, head, len);
  604.     if (index < 0) continue;
  605.     if (index > 0) break;
  606.     if (cmd->cmd_code == K_MACRO ||
  607.         cmd->cmd_code == K_ARTICLE_ID ||
  608.         cmd->cmd_code == K_EQUAL_KEY)
  609.         sprintf(tail, "%s ", cmd->cmd_name + len);
  610.     else
  611.         strcpy(tail, cmd->cmd_name + len);
  612.     cmd++;
  613.     return 1;
  614.     }
  615.     return 0;
  616. }
  617.  
  618.  
  619. char *command_name(cmd)
  620. int cmd;
  621. {
  622.     register struct command_name_map *cnmp;
  623.  
  624.     cmd &= ~GETC_COMMAND;
  625.  
  626.     for (cnmp = command_name_map; cnmp->cmd_name; cnmp++)
  627.     if (cnmp->cmd_code == cmd) return cnmp->cmd_name;
  628.  
  629.     return "unknown";
  630. }
  631.  
  632.  
  633. /*
  634.  * convert key name into ascii code
  635.  *
  636.  *    key names are:
  637.  *        c    character c
  638.  *        ^C    control-C
  639.  *        0xNN    hex value (0..0x7f)
  640.  *        0NNN    octal value (0..0177)
  641.  *        NNN    decimal value (0..127)
  642.  *        up, down, left, rigth    arrow keys
  643.  *        #0..#9            function keys (initially undefined)
  644.  */
  645.  
  646. key_type parse_key(str)
  647. char *str;
  648. {
  649.     int x;
  650.  
  651.     if (str[1] == NUL)
  652.     return str[0] & 0177;
  653.  
  654.     if (str[0] == '^')
  655.     if (str[1] == '?')
  656.         return 0177;
  657.     else
  658.         return CONTROL_(str[1]);
  659.  
  660.     if (isdigit(str[0])) {
  661.     if (str[0] == '0')
  662.         if (str[1] == 'x')
  663.         sscanf(str+2, "%x", &x);
  664.         else
  665.         sscanf(str+1, "%o", &x);
  666.     else
  667.         sscanf(str, "%d", &x);
  668.  
  669.     return x & 0177;
  670.     }
  671.  
  672.     if (str[0] == '#' && isdigit(str[1]))
  673.     return K_function(str[1] - '0');
  674.  
  675.     if (strcmp(str, "up") == 0)
  676.     return K_up_arrow;
  677.  
  678.     if (strcmp(str, "down") == 0)
  679.     return K_down_arrow;
  680.  
  681.     if (strcmp(str, "left") == 0)
  682.     return K_left_arrow;
  683.  
  684.     if (strcmp(str, "right") == 0)
  685.     return K_right_arrow;
  686.  
  687.     init_message("unknown key: %s", str);
  688.  
  689.     return 0200;
  690. }
  691.  
  692. char *key_name(c)
  693. key_type c;
  694. {
  695.     static char buf[3];
  696.  
  697.     if (c & 0200) {
  698.     switch (c) {
  699.      case K_up_arrow:
  700.         return "up";
  701.      case K_down_arrow:
  702.         return "down";
  703.      case K_left_arrow:
  704.         return "left";
  705.      case K_right_arrow:
  706.         return "right";
  707.      default:
  708.         buf[0] = '#';
  709.         buf[1] = (c - K_function(0)) + '0';
  710.         buf[2] = NUL;
  711.         goto out;
  712.     }
  713.     }
  714.  
  715.     if (c < SP) {
  716.     buf[0] = '^';
  717.     buf[1] = c + '@';
  718.     buf[2] = NUL;
  719.     goto out;
  720.     }
  721.  
  722.     if (c == 0177) {
  723.     strcpy(buf, "^?");
  724.     goto out;
  725.     }
  726.  
  727.     buf[0] = c;
  728.     buf[1] = NUL;
  729.  
  730.  out:
  731.     return buf;
  732. }
  733.  
  734.  
  735. dump_global_map()
  736. {
  737.     register key_type c;
  738.  
  739.     clrdisp();
  740.     so_printf("\1REMAPPED KEYS\1\n\n");
  741.     pg_init(2, 4);
  742.  
  743.     for (c = 0; c < KEY_MAP_SIZE; c++)
  744.     if (c != global_key_map[c]) {
  745.         if (pg_next() < 0) break;
  746.         printf("%s", key_name(c));
  747.         pg_indent(6);
  748.         printf("-> %s", key_name(global_key_map[c]));
  749.     }
  750.  
  751.     pg_end();
  752. }
  753.  
  754.  
  755. dump_key_map(map, where, restriction)
  756. int map[];
  757. char *where;
  758. int restriction;
  759. {
  760.     register struct command_name_map *cnmp;
  761.     register key_type c;
  762.     register int code, first_prt;
  763.     
  764.     clrdisp();
  765.     so_printf("\1KEY BINDINGS (%s)\1\n\n", where);
  766.  
  767.     if (restriction == K_ONLY_MENU) {
  768.     printf("\rarticle:  ");
  769.     for (c = 0; c < KEY_MAP_SIZE; c++)
  770.         if (map[c] & K_ARTICLE_ID) printf("%s", key_name(c));
  771.     }
  772.  
  773.     pg_init(4, 2);
  774.  
  775.     for (cnmp = command_name_map; cnmp->cmd_name; cnmp++) {
  776.     if (cnmp->cmd_restriction && cnmp->cmd_restriction != restriction)
  777.         continue;
  778.     if (cnmp->cmd_code == K_UNBOUND) continue;
  779.     if (cnmp->cmd_code == K_MACRO) continue;
  780.  
  781.     code = cnmp->cmd_code;
  782.     first_prt = 1;
  783.  
  784.     for (c = 0; c < KEY_MAP_SIZE; c++)
  785.         if (map[c] == code) {
  786.         if (first_prt) {
  787.             if (pg_next() < 0) goto out;
  788.             fputs(cnmp->cmd_name, stdout);
  789.             pg_indent(max_cmd_name_length);
  790.             first_prt = 0;
  791.         }
  792.         printf(" %s", key_name(c));
  793.         }
  794.     }
  795.  
  796.     for (c = 0; c < KEY_MAP_SIZE; c++)
  797.     if (map[c] & K_MACRO) {
  798.         if (pg_next() < 0) goto out;
  799.         printf("macro %d: %s", (map[c] & ~K_MACRO), key_name(c));
  800.     }
  801.  
  802.  out:
  803.     pg_end();
  804. }
  805.