diff options
| author | Kim F. Storm | 2002-07-12 23:47:31 +0000 |
|---|---|---|
| committer | Kim F. Storm | 2002-07-12 23:47:31 +0000 |
| commit | 325309f50513a4cc7719329857c3bb6f2149c655 (patch) | |
| tree | 260f62f5734b9d8313c8dab9794fdf307d1612d4 /src | |
| parent | a3dd6af2b5baf3b62a4221a634d849eac3ae0e15 (diff) | |
| download | emacs-325309f50513a4cc7719329857c3bb6f2149c655.tar.gz emacs-325309f50513a4cc7719329857c3bb6f2149c655.zip | |
(command_loop_1): Invert check on Vmemory_full.
Diffstat (limited to 'src')
| -rw-r--r-- | src/keyboard.c | 314 |
1 files changed, 111 insertions, 203 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index 7a202fc7eaa..db9e9ad8f19 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -660,6 +660,11 @@ Lisp_Object Vdisable_point_adjustment; | |||
| 660 | 660 | ||
| 661 | Lisp_Object Vglobal_disable_point_adjustment; | 661 | Lisp_Object Vglobal_disable_point_adjustment; |
| 662 | 662 | ||
| 663 | /* A function to display keyboard-menus, and read the user's response. | ||
| 664 | If nil, keyboard menus are disabled. */ | ||
| 665 | |||
| 666 | Lisp_Object Vkey_menu_prompt_function; | ||
| 667 | |||
| 663 | /* The time when Emacs started being idle. */ | 668 | /* The time when Emacs started being idle. */ |
| 664 | 669 | ||
| 665 | static EMACS_TIME timer_idleness_start_time; | 670 | static EMACS_TIME timer_idleness_start_time; |
| @@ -1359,7 +1364,7 @@ command_loop_1 () | |||
| 1359 | this_command_key_count = 0; | 1364 | this_command_key_count = 0; |
| 1360 | this_single_command_key_start = 0; | 1365 | this_single_command_key_start = 0; |
| 1361 | 1366 | ||
| 1362 | if (! NILP (Vmemory_full)) | 1367 | if (NILP (Vmemory_full)) |
| 1363 | { | 1368 | { |
| 1364 | /* Make sure this hook runs after commands that get errors and | 1369 | /* Make sure this hook runs after commands that get errors and |
| 1365 | throw to top level. */ | 1370 | throw to top level. */ |
| @@ -7666,12 +7671,6 @@ read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu) | |||
| 7666 | return Qnil ; | 7671 | return Qnil ; |
| 7667 | } | 7672 | } |
| 7668 | 7673 | ||
| 7669 | /* Buffer in use so far for the minibuf prompts for menu keymaps. | ||
| 7670 | We make this bigger when necessary, and never free it. */ | ||
| 7671 | static char *read_char_minibuf_menu_text; | ||
| 7672 | /* Size of that buffer. */ | ||
| 7673 | static int read_char_minibuf_menu_width; | ||
| 7674 | |||
| 7675 | static Lisp_Object | 7674 | static Lisp_Object |
| 7676 | read_char_minibuf_menu_prompt (commandflag, nmaps, maps) | 7675 | read_char_minibuf_menu_prompt (commandflag, nmaps, maps) |
| 7677 | int commandflag ; | 7676 | int commandflag ; |
| @@ -7680,12 +7679,13 @@ read_char_minibuf_menu_prompt (commandflag, nmaps, maps) | |||
| 7680 | { | 7679 | { |
| 7681 | int mapno; | 7680 | int mapno; |
| 7682 | register Lisp_Object name; | 7681 | register Lisp_Object name; |
| 7683 | int nlength; | ||
| 7684 | int width = FRAME_WIDTH (SELECTED_FRAME ()) - 4; | ||
| 7685 | int idx = -1; | 7682 | int idx = -1; |
| 7686 | int nobindings = 1; | ||
| 7687 | Lisp_Object rest, vector; | 7683 | Lisp_Object rest, vector; |
| 7688 | char *menu; | 7684 | /* This is a list of the prompt and individual menu entries passed to |
| 7685 | lisp for formatting and display. The format is: | ||
| 7686 | MENU_LIST : (MENU_PROMPT ENTRY...) | ||
| 7687 | ENTRY : (EVENT PROMPT [BINDING [TOGGLE_TYPE TOGGLE_STATE]]) */ | ||
| 7688 | Lisp_Object menu_list = Qnil; | ||
| 7689 | 7689 | ||
| 7690 | vector = Qnil; | 7690 | vector = Qnil; |
| 7691 | name = Qnil; | 7691 | name = Qnil; |
| @@ -7693,20 +7693,6 @@ read_char_minibuf_menu_prompt (commandflag, nmaps, maps) | |||
| 7693 | if (! menu_prompting) | 7693 | if (! menu_prompting) |
| 7694 | return Qnil; | 7694 | return Qnil; |
| 7695 | 7695 | ||
| 7696 | /* Make sure we have a big enough buffer for the menu text. */ | ||
| 7697 | if (read_char_minibuf_menu_text == 0) | ||
| 7698 | { | ||
| 7699 | read_char_minibuf_menu_width = width + 4; | ||
| 7700 | read_char_minibuf_menu_text = (char *) xmalloc (width + 4); | ||
| 7701 | } | ||
| 7702 | else if (width + 4 > read_char_minibuf_menu_width) | ||
| 7703 | { | ||
| 7704 | read_char_minibuf_menu_width = width + 4; | ||
| 7705 | read_char_minibuf_menu_text | ||
| 7706 | = (char *) xrealloc (read_char_minibuf_menu_text, width + 4); | ||
| 7707 | } | ||
| 7708 | menu = read_char_minibuf_menu_text; | ||
| 7709 | |||
| 7710 | /* Get the menu name from the first map that has one (a prompt string). */ | 7696 | /* Get the menu name from the first map that has one (a prompt string). */ |
| 7711 | for (mapno = 0; mapno < nmaps; mapno++) | 7697 | for (mapno = 0; mapno < nmaps; mapno++) |
| 7712 | { | 7698 | { |
| @@ -7719,204 +7705,109 @@ read_char_minibuf_menu_prompt (commandflag, nmaps, maps) | |||
| 7719 | if (!STRINGP (name)) | 7705 | if (!STRINGP (name)) |
| 7720 | return Qnil; | 7706 | return Qnil; |
| 7721 | 7707 | ||
| 7722 | /* Prompt string always starts with map's prompt, and a space. */ | ||
| 7723 | strcpy (menu, XSTRING (name)->data); | ||
| 7724 | nlength = STRING_BYTES (XSTRING (name)); | ||
| 7725 | menu[nlength++] = ':'; | ||
| 7726 | menu[nlength++] = ' '; | ||
| 7727 | menu[nlength] = 0; | ||
| 7728 | |||
| 7729 | /* Start prompting at start of first map. */ | 7708 | /* Start prompting at start of first map. */ |
| 7730 | mapno = 0; | 7709 | mapno = 0; |
| 7731 | rest = maps[mapno]; | 7710 | rest = maps[mapno]; |
| 7732 | 7711 | ||
| 7733 | /* Present the documented bindings, a line at a time. */ | 7712 | /* Loop over elements of map. */ |
| 7734 | while (1) | 7713 | for (;;) |
| 7735 | { | 7714 | { |
| 7736 | int notfirst = 0; | 7715 | Lisp_Object elt; |
| 7737 | int i = nlength; | ||
| 7738 | Lisp_Object obj; | ||
| 7739 | int ch; | ||
| 7740 | Lisp_Object orig_defn_macro; | ||
| 7741 | 7716 | ||
| 7742 | /* Loop over elements of map. */ | 7717 | /* If reached end of map, start at beginning of next map. */ |
| 7743 | while (i < width) | 7718 | if (NILP (rest)) |
| 7744 | { | 7719 | { |
| 7745 | Lisp_Object elt; | 7720 | mapno++; |
| 7721 | if (mapno == nmaps) | ||
| 7722 | /* Done with all maps. */ | ||
| 7723 | break; | ||
| 7724 | rest = maps[mapno]; | ||
| 7725 | } | ||
| 7746 | 7726 | ||
| 7747 | /* If reached end of map, start at beginning of next map. */ | 7727 | /* Look at the next element of the map. */ |
| 7748 | if (NILP (rest)) | 7728 | if (idx >= 0) |
| 7749 | { | 7729 | elt = AREF (vector, idx); |
| 7750 | mapno++; | 7730 | else |
| 7751 | /* At end of last map, wrap around to first map if just starting, | 7731 | elt = Fcar_safe (rest); |
| 7752 | or end this line if already have something on it. */ | ||
| 7753 | if (mapno == nmaps) | ||
| 7754 | { | ||
| 7755 | mapno = 0; | ||
| 7756 | if (notfirst || nobindings) break; | ||
| 7757 | } | ||
| 7758 | rest = maps[mapno]; | ||
| 7759 | } | ||
| 7760 | 7732 | ||
| 7761 | /* Look at the next element of the map. */ | 7733 | if (idx < 0 && VECTORP (elt)) |
| 7762 | if (idx >= 0) | 7734 | { |
| 7763 | elt = XVECTOR (vector)->contents[idx]; | 7735 | /* If we found a dense table in the keymap, |
| 7764 | else | 7736 | advanced past it, but start scanning its contents. */ |
| 7765 | elt = Fcar_safe (rest); | 7737 | rest = Fcdr_safe (rest); |
| 7738 | vector = elt; | ||
| 7739 | idx = 0; | ||
| 7740 | } | ||
| 7741 | else | ||
| 7742 | { | ||
| 7743 | /* An ordinary element. */ | ||
| 7744 | Lisp_Object event, tem; | ||
| 7766 | 7745 | ||
| 7767 | if (idx < 0 && VECTORP (elt)) | 7746 | if (idx < 0) |
| 7768 | { | 7747 | { |
| 7769 | /* If we found a dense table in the keymap, | 7748 | event = Fcar_safe (elt); /* alist */ |
| 7770 | advanced past it, but start scanning its contents. */ | 7749 | elt = Fcdr_safe (elt); |
| 7771 | rest = Fcdr_safe (rest); | ||
| 7772 | vector = elt; | ||
| 7773 | idx = 0; | ||
| 7774 | } | 7750 | } |
| 7775 | else | 7751 | else |
| 7776 | { | 7752 | { |
| 7777 | /* An ordinary element. */ | 7753 | XSETINT (event, idx); /* vector */ |
| 7778 | Lisp_Object event, tem; | 7754 | } |
| 7779 | |||
| 7780 | if (idx < 0) | ||
| 7781 | { | ||
| 7782 | event = Fcar_safe (elt); /* alist */ | ||
| 7783 | elt = Fcdr_safe (elt); | ||
| 7784 | } | ||
| 7785 | else | ||
| 7786 | { | ||
| 7787 | XSETINT (event, idx); /* vector */ | ||
| 7788 | } | ||
| 7789 | |||
| 7790 | /* Ignore the element if it has no prompt string. */ | ||
| 7791 | if (INTEGERP (event) && parse_menu_item (elt, 0, -1)) | ||
| 7792 | { | ||
| 7793 | /* 1 if the char to type matches the string. */ | ||
| 7794 | int char_matches; | ||
| 7795 | Lisp_Object upcased_event, downcased_event; | ||
| 7796 | Lisp_Object desc = Qnil; | ||
| 7797 | Lisp_Object s | ||
| 7798 | = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME]; | ||
| 7799 | |||
| 7800 | upcased_event = Fupcase (event); | ||
| 7801 | downcased_event = Fdowncase (event); | ||
| 7802 | char_matches = (XINT (upcased_event) == XSTRING (s)->data[0] | ||
| 7803 | || XINT (downcased_event) == XSTRING (s)->data[0]); | ||
| 7804 | if (! char_matches) | ||
| 7805 | desc = Fsingle_key_description (event, Qnil); | ||
| 7806 | |||
| 7807 | #if 0 /* It is redundant to list the equivalent key bindings because | ||
| 7808 | the prefix is what the user has already typed. */ | ||
| 7809 | tem | ||
| 7810 | = XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ]; | ||
| 7811 | if (!NILP (tem)) | ||
| 7812 | /* Insert equivalent keybinding. */ | ||
| 7813 | s = concat2 (s, tem); | ||
| 7814 | #endif | ||
| 7815 | tem | ||
| 7816 | = XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE]; | ||
| 7817 | if (EQ (tem, QCradio) || EQ (tem, QCtoggle)) | ||
| 7818 | { | ||
| 7819 | /* Insert button prefix. */ | ||
| 7820 | Lisp_Object selected | ||
| 7821 | = XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED]; | ||
| 7822 | if (EQ (tem, QCradio)) | ||
| 7823 | tem = build_string (NILP (selected) ? "(*) " : "( ) "); | ||
| 7824 | else | ||
| 7825 | tem = build_string (NILP (selected) ? "[X] " : "[ ] "); | ||
| 7826 | s = concat2 (tem, s); | ||
| 7827 | } | ||
| 7828 | |||
| 7829 | |||
| 7830 | /* If we have room for the prompt string, add it to this line. | ||
| 7831 | If this is the first on the line, always add it. */ | ||
| 7832 | if ((XSTRING (s)->size + i + 2 | ||
| 7833 | + (char_matches ? 0 : XSTRING (desc)->size + 3)) | ||
| 7834 | < width | ||
| 7835 | || !notfirst) | ||
| 7836 | { | ||
| 7837 | int thiswidth; | ||
| 7838 | |||
| 7839 | /* Punctuate between strings. */ | ||
| 7840 | if (notfirst) | ||
| 7841 | { | ||
| 7842 | strcpy (menu + i, ", "); | ||
| 7843 | i += 2; | ||
| 7844 | } | ||
| 7845 | notfirst = 1; | ||
| 7846 | nobindings = 0 ; | ||
| 7847 | |||
| 7848 | /* If the char to type doesn't match the string's | ||
| 7849 | first char, explicitly show what char to type. */ | ||
| 7850 | if (! char_matches) | ||
| 7851 | { | ||
| 7852 | /* Add as much of string as fits. */ | ||
| 7853 | thiswidth = XSTRING (desc)->size; | ||
| 7854 | if (thiswidth + i > width) | ||
| 7855 | thiswidth = width - i; | ||
| 7856 | bcopy (XSTRING (desc)->data, menu + i, thiswidth); | ||
| 7857 | i += thiswidth; | ||
| 7858 | strcpy (menu + i, " = "); | ||
| 7859 | i += 3; | ||
| 7860 | } | ||
| 7861 | |||
| 7862 | /* Add as much of string as fits. */ | ||
| 7863 | thiswidth = XSTRING (s)->size; | ||
| 7864 | if (thiswidth + i > width) | ||
| 7865 | thiswidth = width - i; | ||
| 7866 | bcopy (XSTRING (s)->data, menu + i, thiswidth); | ||
| 7867 | i += thiswidth; | ||
| 7868 | menu[i] = 0; | ||
| 7869 | } | ||
| 7870 | else | ||
| 7871 | { | ||
| 7872 | /* If this element does not fit, end the line now, | ||
| 7873 | and save the element for the next line. */ | ||
| 7874 | strcpy (menu + i, "..."); | ||
| 7875 | break; | ||
| 7876 | } | ||
| 7877 | } | ||
| 7878 | 7755 | ||
| 7879 | /* Move past this element. */ | 7756 | /* Ignore the element if it has no prompt string. */ |
| 7880 | if (idx >= 0 && idx + 1 >= XVECTOR (vector)->size) | 7757 | if (INTEGERP (event) && parse_menu_item (elt, 0, -1)) |
| 7881 | /* Handle reaching end of dense table. */ | 7758 | { |
| 7882 | idx = -1; | 7759 | /* The list describing this entry. */ |
| 7883 | if (idx >= 0) | 7760 | Lisp_Object entry = Qnil; |
| 7884 | idx++; | 7761 | Lisp_Object prop_val; |
| 7885 | else | 7762 | |
| 7886 | rest = Fcdr_safe (rest); | 7763 | prop_val = AREF (item_properties, ITEM_PROPERTY_TYPE); |
| 7764 | if (EQ (prop_val, QCradio) || EQ (prop_val, QCtoggle)) | ||
| 7765 | /* This is a `toggle-able' menu-entry, make the | ||
| 7766 | tail of the list describe it. */ | ||
| 7767 | entry | ||
| 7768 | = Fcons (prop_val, | ||
| 7769 | Fcons (AREF (item_properties, | ||
| 7770 | ITEM_PROPERTY_SELECTED), | ||
| 7771 | entry)); | ||
| 7772 | |||
| 7773 | /* Equivalent keybinding. */ | ||
| 7774 | prop_val = AREF (item_properties, ITEM_PROPERTY_KEYEQ); | ||
| 7775 | if (!NILP (entry) || !NILP (prop_val)) | ||
| 7776 | entry = Fcons (prop_val, entry); | ||
| 7777 | |||
| 7778 | /* The string prompt. */ | ||
| 7779 | prop_val = AREF (item_properties, ITEM_PROPERTY_NAME); | ||
| 7780 | entry = Fcons (prop_val, entry); | ||
| 7781 | |||
| 7782 | /* Finally, the car of the list is the event. */ | ||
| 7783 | entry = Fcons (event, entry); | ||
| 7784 | |||
| 7785 | /* Push this entry on the the list of entries. */ | ||
| 7786 | menu_list = Fcons (entry, menu_list); | ||
| 7887 | } | 7787 | } |
| 7888 | } | ||
| 7889 | 7788 | ||
| 7890 | /* Prompt with that and read response. */ | 7789 | /* Move past this element. */ |
| 7891 | message2_nolog (menu, strlen (menu), | 7790 | if (idx >= 0 && idx + 1 >= XVECTOR (vector)->size) |
| 7892 | ! NILP (current_buffer->enable_multibyte_characters)); | 7791 | /* Handle reaching end of dense table. */ |
| 7792 | idx = -1; | ||
| 7793 | if (idx >= 0) | ||
| 7794 | idx++; | ||
| 7795 | else | ||
| 7796 | rest = Fcdr_safe (rest); | ||
| 7797 | } | ||
| 7798 | } | ||
| 7893 | 7799 | ||
| 7894 | /* Make believe its not a keyboard macro in case the help char | 7800 | /* Put the entries in the proper order for the display function. */ |
| 7895 | is pressed. Help characters are not recorded because menu prompting | 7801 | menu_list = Fnreverse (menu_list); |
| 7896 | is not used on replay. | ||
| 7897 | */ | ||
| 7898 | orig_defn_macro = current_kboard->defining_kbd_macro; | ||
| 7899 | current_kboard->defining_kbd_macro = Qnil; | ||
| 7900 | do | ||
| 7901 | obj = read_char (commandflag, 0, 0, Qt, 0); | ||
| 7902 | while (BUFFERP (obj)); | ||
| 7903 | current_kboard->defining_kbd_macro = orig_defn_macro; | ||
| 7904 | 7802 | ||
| 7905 | if (!INTEGERP (obj)) | 7803 | /* The car of the entries list is the prompt for the whole menu. */ |
| 7906 | return obj; | 7804 | menu_list = Fcons (name, menu_list); |
| 7907 | else | ||
| 7908 | ch = XINT (obj); | ||
| 7909 | 7805 | ||
| 7910 | if (! EQ (obj, menu_prompt_more_char) | 7806 | /* Display the menu, and prompt for a key. */ |
| 7911 | && (!INTEGERP (menu_prompt_more_char) | 7807 | if (NILP (Vkey_menu_prompt_function)) |
| 7912 | || ! EQ (obj, make_number (Ctl (XINT (menu_prompt_more_char)))))) | 7808 | return Qnil; |
| 7913 | { | 7809 | else |
| 7914 | if (!NILP (current_kboard->defining_kbd_macro)) | 7810 | return call1 (Vkey_menu_prompt_function, menu_list); |
| 7915 | store_kbd_macro_char (obj); | ||
| 7916 | return obj; | ||
| 7917 | } | ||
| 7918 | /* Help char - go round again */ | ||
| 7919 | } | ||
| 7920 | } | 7811 | } |
| 7921 | 7812 | ||
| 7922 | /* Reading key sequences. */ | 7813 | /* Reading key sequences. */ |
| @@ -11012,6 +10903,23 @@ Used during Emacs' startup. */); | |||
| 11012 | doc: /* *How long to display an echo-area message when the minibuffer is active. | 10903 | doc: /* *How long to display an echo-area message when the minibuffer is active. |
| 11013 | If the value is not a number, such messages don't time out. */); | 10904 | If the value is not a number, such messages don't time out. */); |
| 11014 | Vminibuffer_message_timeout = make_number (2); | 10905 | Vminibuffer_message_timeout = make_number (2); |
| 10906 | |||
| 10907 | DEFVAR_LISP ("key-menu-prompt-function", &Vkey_menu_prompt_function, | ||
| 10908 | doc: /* A function to display keyboard-menus, and read the user's response. | ||
| 10909 | If nil, keyboard menus are disabled. | ||
| 10910 | |||
| 10911 | It is called with single argument, which is a list describing the keyboard menu | ||
| 10912 | and should return the key the user types. | ||
| 10913 | |||
| 10914 | The argument is a list of the prompt and individual menu entries. | ||
| 10915 | The format is as follows: | ||
| 10916 | |||
| 10917 | MENU : (PROMPT ENTRY...) | ||
| 10918 | ENTRY : (EVENT PROMPT [BINDING [TOGGLE_TYPE TOGGLE_STATE]]) | ||
| 10919 | |||
| 10920 | Note that there is a prompt for the whole menu, and one for each | ||
| 10921 | individual entry. */); | ||
| 10922 | Vkey_menu_prompt_function = Qnil; | ||
| 11015 | } | 10923 | } |
| 11016 | 10924 | ||
| 11017 | void | 10925 | void |