comparison src/keyboard.c @ 32140:6c61e0dbf542

(update_menu_bindings): New variable. (parse_menu_item): Use AREF. If update_menu_bindings is 0, don't update menu bindings. (syms_of_keyboard): New Lisp variable `update-menu-bindings'.
author Gerd Moellmann <gerd@gnu.org>
date Wed, 04 Oct 2000 19:00:10 +0000
parents 6a45a15137b0
children 13415f4f854a
comparison
equal deleted inserted replaced
32139:6d8322cfbf71 32140:6c61e0dbf542
449 449
450 /* 1 if should obey 0200 bit in input chars as "Meta", 2 if should 450 /* 1 if should obey 0200 bit in input chars as "Meta", 2 if should
451 keep 0200 bit in input chars. 0 to ignore the 0200 bit. */ 451 keep 0200 bit in input chars. 0 to ignore the 0200 bit. */
452 452
453 int meta_key; 453 int meta_key;
454
455 /* Non-zero means force key bindings update in parse_menu_item. */
456
457 int update_menu_bindings;
454 458
455 extern char *pending_malloc_warning; 459 extern char *pending_malloc_warning;
456 460
457 /* Circular buffer for pre-read keyboard input. */ 461 /* Circular buffer for pre-read keyboard input. */
458 462
6480 item_properties 6484 item_properties
6481 = Fmake_vector (make_number (ITEM_PROPERTY_ENABLE + 1), Qnil); 6485 = Fmake_vector (make_number (ITEM_PROPERTY_ENABLE + 1), Qnil);
6482 6486
6483 /* Initialize optional entries. */ 6487 /* Initialize optional entries. */
6484 for (i = ITEM_PROPERTY_DEF; i < ITEM_PROPERTY_ENABLE; i++) 6488 for (i = ITEM_PROPERTY_DEF; i < ITEM_PROPERTY_ENABLE; i++)
6485 XVECTOR (item_properties)->contents[i] = Qnil; 6489 AREF (item_properties, i) = Qnil;
6486 XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE] = Qt; 6490 AREF (item_properties, ITEM_PROPERTY_ENABLE) = Qt;
6487 6491
6488 /* Save the item here to protect it from GC. */ 6492 /* Save the item here to protect it from GC. */
6489 XVECTOR (item_properties)->contents[ITEM_PROPERTY_ITEM] = item; 6493 AREF (item_properties, ITEM_PROPERTY_ITEM) = item;
6490 6494
6491 item_string = XCAR (item); 6495 item_string = XCAR (item);
6492 6496
6493 start = item; 6497 start = item;
6494 item = XCDR (item); 6498 item = XCDR (item);
6495 if (STRINGP (item_string)) 6499 if (STRINGP (item_string))
6496 { 6500 {
6497 /* Old format menu item. */ 6501 /* Old format menu item. */
6498 XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME] = item_string; 6502 AREF (item_properties, ITEM_PROPERTY_NAME) = item_string;
6499 6503
6500 /* Maybe help string. */ 6504 /* Maybe help string. */
6501 if (CONSP (item) && STRINGP (XCAR (item))) 6505 if (CONSP (item) && STRINGP (XCAR (item)))
6502 { 6506 {
6503 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP] 6507 AREF (item_properties, ITEM_PROPERTY_HELP) = XCAR (item);
6504 = XCAR (item);
6505 start = item; 6508 start = item;
6506 item = XCDR (item); 6509 item = XCDR (item);
6507 } 6510 }
6508 6511
6509 /* Maybe key binding cache. */ 6512 /* Maybe key binding cache. */
6514 cachelist = XCAR (item); 6517 cachelist = XCAR (item);
6515 item = XCDR (item); 6518 item = XCDR (item);
6516 } 6519 }
6517 6520
6518 /* This is the real definition--the function to run. */ 6521 /* This is the real definition--the function to run. */
6519 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF] = item; 6522 AREF (item_properties, ITEM_PROPERTY_DEF) = item;
6520 6523
6521 /* Get enable property, if any. */ 6524 /* Get enable property, if any. */
6522 if (SYMBOLP (item)) 6525 if (SYMBOLP (item))
6523 { 6526 {
6524 tem = Fget (item, Qmenu_enable); 6527 tem = Fget (item, Qmenu_enable);
6525 if (!NILP (tem)) 6528 if (!NILP (tem))
6526 XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE] = tem; 6529 AREF (item_properties, ITEM_PROPERTY_ENABLE) = tem;
6527 } 6530 }
6528 } 6531 }
6529 else if (EQ (item_string, Qmenu_item) && CONSP (item)) 6532 else if (EQ (item_string, Qmenu_item) && CONSP (item))
6530 { 6533 {
6531 /* New format menu item. */ 6534 /* New format menu item. */
6532 XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME] 6535 AREF (item_properties, ITEM_PROPERTY_NAME) = XCAR (item);
6533 = XCAR (item);
6534 start = XCDR (item); 6536 start = XCDR (item);
6535 if (CONSP (start)) 6537 if (CONSP (start))
6536 { 6538 {
6537 /* We have a real binding. */ 6539 /* We have a real binding. */
6538 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF] 6540 AREF (item_properties, ITEM_PROPERTY_DEF) = XCAR (start);
6539 = XCAR (start);
6540 6541
6541 item = XCDR (start); 6542 item = XCDR (start);
6542 /* Is there a cache list with key equivalences. */ 6543 /* Is there a cache list with key equivalences. */
6543 if (CONSP (item) && CONSP (XCAR (item))) 6544 if (CONSP (item) && CONSP (XCAR (item)))
6544 { 6545 {
6551 { 6552 {
6552 tem = XCAR (item); 6553 tem = XCAR (item);
6553 item = XCDR (item); 6554 item = XCDR (item);
6554 6555
6555 if (EQ (tem, QCenable)) 6556 if (EQ (tem, QCenable))
6556 XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE] 6557 AREF (item_properties, ITEM_PROPERTY_ENABLE) = XCAR (item);
6557 = XCAR (item);
6558 else if (EQ (tem, QCvisible) && !notreal) 6558 else if (EQ (tem, QCvisible) && !notreal)
6559 { 6559 {
6560 /* If got a visible property and that evaluates to nil 6560 /* If got a visible property and that evaluates to nil
6561 then ignore this item. */ 6561 then ignore this item. */
6562 tem = menu_item_eval_property (XCAR (item)); 6562 tem = menu_item_eval_property (XCAR (item));
6563 if (NILP (tem)) 6563 if (NILP (tem))
6564 return 0; 6564 return 0;
6565 } 6565 }
6566 else if (EQ (tem, QChelp)) 6566 else if (EQ (tem, QChelp))
6567 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP] 6567 AREF (item_properties, ITEM_PROPERTY_HELP) = XCAR (item);
6568 = XCAR (item);
6569 else if (EQ (tem, QCfilter)) 6568 else if (EQ (tem, QCfilter))
6570 filter = item; 6569 filter = item;
6571 else if (EQ (tem, QCkey_sequence)) 6570 else if (EQ (tem, QCkey_sequence))
6572 { 6571 {
6573 tem = XCAR (item); 6572 tem = XCAR (item);
6578 } 6577 }
6579 else if (EQ (tem, QCkeys)) 6578 else if (EQ (tem, QCkeys))
6580 { 6579 {
6581 tem = XCAR (item); 6580 tem = XCAR (item);
6582 if (CONSP (tem) || (STRINGP (tem) && NILP (cachelist))) 6581 if (CONSP (tem) || (STRINGP (tem) && NILP (cachelist)))
6583 XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ] 6582 AREF (item_properties, ITEM_PROPERTY_KEYEQ) = tem;
6584 = tem;
6585 } 6583 }
6586 else if (EQ (tem, QCbutton) && CONSP (XCAR (item))) 6584 else if (EQ (tem, QCbutton) && CONSP (XCAR (item)))
6587 { 6585 {
6588 Lisp_Object type; 6586 Lisp_Object type;
6589 tem = XCAR (item); 6587 tem = XCAR (item);
6590 type = XCAR (tem); 6588 type = XCAR (tem);
6591 if (EQ (type, QCtoggle) || EQ (type, QCradio)) 6589 if (EQ (type, QCtoggle) || EQ (type, QCradio))
6592 { 6590 {
6593 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED] 6591 AREF (item_properties, ITEM_PROPERTY_SELECTED)
6594 = XCDR (tem); 6592 = XCDR (tem);
6595 XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE] 6593 AREF (item_properties, ITEM_PROPERTY_TYPE)
6596 = type; 6594 = type;
6597 } 6595 }
6598 } 6596 }
6599 item = XCDR (item); 6597 item = XCDR (item);
6600 } 6598 }
6605 else 6603 else
6606 return 0; /* not a menu item */ 6604 return 0; /* not a menu item */
6607 6605
6608 /* If item string is not a string, evaluate it to get string. 6606 /* If item string is not a string, evaluate it to get string.
6609 If we don't get a string, skip this item. */ 6607 If we don't get a string, skip this item. */
6610 item_string = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME]; 6608 item_string = AREF (item_properties, ITEM_PROPERTY_NAME);
6611 if (!(STRINGP (item_string) || notreal)) 6609 if (!(STRINGP (item_string) || notreal))
6612 { 6610 {
6613 item_string = menu_item_eval_property (item_string); 6611 item_string = menu_item_eval_property (item_string);
6614 if (!STRINGP (item_string)) 6612 if (!STRINGP (item_string))
6615 return 0; 6613 return 0;
6616 XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME] = item_string; 6614 AREF (item_properties, ITEM_PROPERTY_NAME) = item_string;
6617 } 6615 }
6618 6616
6619 /* If got a filter apply it on definition. */ 6617 /* If got a filter apply it on definition. */
6620 def = XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF]; 6618 def = AREF (item_properties, ITEM_PROPERTY_DEF);
6621 if (!NILP (filter)) 6619 if (!NILP (filter))
6622 { 6620 {
6623 def = menu_item_eval_property (list2 (XCAR (filter), 6621 def = menu_item_eval_property (list2 (XCAR (filter),
6624 list2 (Qquote, def))); 6622 list2 (Qquote, def)));
6625 6623
6626 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF] = def; 6624 AREF (item_properties, ITEM_PROPERTY_DEF) = def;
6627 } 6625 }
6628 6626
6629 /* If we got no definition, this item is just unselectable text which 6627 /* If we got no definition, this item is just unselectable text which
6630 is OK in a submenu but not in the menubar. */ 6628 is OK in a submenu but not in the menubar. */
6631 if (NILP (def)) 6629 if (NILP (def))
6632 return (inmenubar ? 0 : 1); 6630 return (inmenubar ? 0 : 1);
6633 6631
6634 /* Enable or disable selection of item. */ 6632 /* Enable or disable selection of item. */
6635 tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE]; 6633 tem = AREF (item_properties, ITEM_PROPERTY_ENABLE);
6636 if (!EQ (tem, Qt)) 6634 if (!EQ (tem, Qt))
6637 { 6635 {
6638 if (notreal) 6636 if (notreal)
6639 tem = Qt; 6637 tem = Qt;
6640 else 6638 else
6641 tem = menu_item_eval_property (tem); 6639 tem = menu_item_eval_property (tem);
6642 if (inmenubar && NILP (tem)) 6640 if (inmenubar && NILP (tem))
6643 return 0; /* Ignore disabled items in menu bar. */ 6641 return 0; /* Ignore disabled items in menu bar. */
6644 XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE] = tem; 6642 AREF (item_properties, ITEM_PROPERTY_ENABLE) = tem;
6645 } 6643 }
6646 6644
6647 /* See if this is a separate pane or a submenu. */ 6645 /* See if this is a separate pane or a submenu. */
6648 def = XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF]; 6646 def = AREF (item_properties, ITEM_PROPERTY_DEF);
6649 tem = get_keymap_1 (def, 0, 1); 6647 tem = get_keymap_1 (def, 0, 1);
6650 /* For a subkeymap, just record its details and exit. */ 6648 /* For a subkeymap, just record its details and exit. */
6651 if (!NILP (tem)) 6649 if (!NILP (tem))
6652 { 6650 {
6653 XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP] = tem; 6651 AREF (item_properties, ITEM_PROPERTY_MAP) = tem;
6654 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF] = tem; 6652 AREF (item_properties, ITEM_PROPERTY_DEF) = tem;
6655 return 1; 6653 return 1;
6656 } 6654 }
6655
6657 /* At the top level in the menu bar, do likewise for commands also. 6656 /* At the top level in the menu bar, do likewise for commands also.
6658 The menu bar does not display equivalent key bindings anyway. 6657 The menu bar does not display equivalent key bindings anyway.
6659 ITEM_PROPERTY_DEF is already set up properly. */ 6658 ITEM_PROPERTY_DEF is already set up properly. */
6660 if (inmenubar > 0) 6659 if (inmenubar > 0)
6661 return 1; 6660 return 1;
6666 /* We have to create a cachelist. */ 6665 /* We have to create a cachelist. */
6667 CHECK_IMPURE (start); 6666 CHECK_IMPURE (start);
6668 XCDR (start) = Fcons (Fcons (Qnil, Qnil), XCDR (start)); 6667 XCDR (start) = Fcons (Fcons (Qnil, Qnil), XCDR (start));
6669 cachelist = XCAR (XCDR (start)); 6668 cachelist = XCAR (XCDR (start));
6670 newcache = 1; 6669 newcache = 1;
6671 tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ]; 6670 tem = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
6672 if (!NILP (keyhint)) 6671 if (!NILP (keyhint))
6673 { 6672 {
6674 XCAR (cachelist) = XCAR (keyhint); 6673 XCAR (cachelist) = XCAR (keyhint);
6675 newcache = 0; 6674 newcache = 0;
6676 } 6675 }
6678 { 6677 {
6679 XCDR (cachelist) = Fsubstitute_command_keys (tem); 6678 XCDR (cachelist) = Fsubstitute_command_keys (tem);
6680 XCAR (cachelist) = Qt; 6679 XCAR (cachelist) = Qt;
6681 } 6680 }
6682 } 6681 }
6682
6683 tem = XCAR (cachelist); 6683 tem = XCAR (cachelist);
6684 if (!EQ (tem, Qt)) 6684 if (!EQ (tem, Qt))
6685 { 6685 {
6686 int chkcache = 0; 6686 int chkcache = 0;
6687 Lisp_Object prefix; 6687 Lisp_Object prefix;
6688 6688
6689 if (!NILP (tem)) 6689 if (!NILP (tem))
6690 tem = Fkey_binding (tem, Qnil); 6690 tem = Fkey_binding (tem, Qnil);
6691 6691
6692 prefix = XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ]; 6692 prefix = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
6693 if (CONSP (prefix)) 6693 if (CONSP (prefix))
6694 { 6694 {
6695 def = XCAR (prefix); 6695 def = XCAR (prefix);
6696 prefix = XCDR (prefix); 6696 prefix = XCDR (prefix);
6697 } 6697 }
6698 else 6698 else
6699 def = XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF]; 6699 def = AREF (item_properties, ITEM_PROPERTY_DEF);
6700 6700
6701 if (NILP (XCAR (cachelist))) /* Have no saved key. */ 6701 if (!update_menu_bindings)
6702 chkcache = 0;
6703 else if (NILP (XCAR (cachelist))) /* Have no saved key. */
6702 { 6704 {
6703 if (newcache /* Always check first time. */ 6705 if (newcache /* Always check first time. */
6704 /* Should we check everything when precomputing key 6706 /* Should we check everything when precomputing key
6705 bindings? */ 6707 bindings? */
6706 /* || notreal */
6707 /* If something had no key binding before, don't recheck it 6708 /* If something had no key binding before, don't recheck it
6708 because that is too slow--except if we have a list of 6709 because that is too slow--except if we have a list of
6709 rebound commands in Vdefine_key_rebound_commands, do 6710 rebound commands in Vdefine_key_rebound_commands, do
6710 recheck any command that appears in that list. */ 6711 recheck any command that appears in that list. */
6711 || (CONSP (Vdefine_key_rebound_commands) 6712 || (CONSP (Vdefine_key_rebound_commands)
6726 /* Recompute equivalent key binding. If the command is an alias 6727 /* Recompute equivalent key binding. If the command is an alias
6727 for another (such as lmenu.el set it up), see if the original 6728 for another (such as lmenu.el set it up), see if the original
6728 command name has equivalent keys. Otherwise look up the 6729 command name has equivalent keys. Otherwise look up the
6729 specified command itself. We don't try both, because that 6730 specified command itself. We don't try both, because that
6730 makes lmenu menus slow. */ 6731 makes lmenu menus slow. */
6731 if (SYMBOLP (def) && SYMBOLP (XSYMBOL (def)->function) 6732 if (SYMBOLP (def)
6733 && SYMBOLP (XSYMBOL (def)->function)
6732 && ! NILP (Fget (def, Qmenu_alias))) 6734 && ! NILP (Fget (def, Qmenu_alias)))
6733 def = XSYMBOL (def)->function; 6735 def = XSYMBOL (def)->function;
6734 tem = Fwhere_is_internal (def, Qnil, Qt, Qnil); 6736 tem = Fwhere_is_internal (def, Qnil, Qt, Qnil);
6735 XCAR (cachelist) = tem; 6737 XCAR (cachelist) = tem;
6736 if (NILP (tem)) 6738 if (NILP (tem))
6770 /* If we only want to precompute equivalent key bindings, stop here. */ 6772 /* If we only want to precompute equivalent key bindings, stop here. */
6771 if (notreal) 6773 if (notreal)
6772 return 1; 6774 return 1;
6773 6775
6774 /* If we have an equivalent key binding, use that. */ 6776 /* If we have an equivalent key binding, use that. */
6775 XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ] = tem; 6777 AREF (item_properties, ITEM_PROPERTY_KEYEQ) = tem;
6776 6778
6777 /* Include this when menu help is implemented. 6779 /* Include this when menu help is implemented.
6778 tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]; 6780 tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP];
6779 if (!(NILP (tem) || STRINGP (tem))) 6781 if (!(NILP (tem) || STRINGP (tem)))
6780 { 6782 {
6784 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP] = tem; 6786 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP] = tem;
6785 } 6787 }
6786 */ 6788 */
6787 6789
6788 /* Handle radio buttons or toggle boxes. */ 6790 /* Handle radio buttons or toggle boxes. */
6789 tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED]; 6791 tem = AREF (item_properties, ITEM_PROPERTY_SELECTED);
6790 if (!NILP (tem)) 6792 if (!NILP (tem))
6791 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED] 6793 AREF (item_properties, ITEM_PROPERTY_SELECTED)
6792 = menu_item_eval_property (tem); 6794 = menu_item_eval_property (tem);
6793 6795
6794 return 1; 6796 return 1;
6795 } 6797 }
6796 6798
10626 \n\ 10628 \n\
10627 The default value is nil, in which case, point adjustment are\n\ 10629 The default value is nil, in which case, point adjustment are\n\
10628 suppressed only after special commands that set\n\ 10630 suppressed only after special commands that set\n\
10629 `disable-point-adjustment' (which see) to non-nil."); 10631 `disable-point-adjustment' (which see) to non-nil.");
10630 Vglobal_disable_point_adjustment = Qnil; 10632 Vglobal_disable_point_adjustment = Qnil;
10633
10634 DEFVAR_LISP ("update-menu-bindings", &update_menu_bindings,
10635 "Non-nil means updating menu bindings is allowed.\n\
10636 A value of nil means menu bindings should not be updated.\n\
10637 Used during Emacs' startup.");
10638 update_menu_bindings = 1;
10631 } 10639 }
10632 10640
10633 void 10641 void
10634 keys_of_keyboard () 10642 keys_of_keyboard ()
10635 { 10643 {