Mercurial > emacs
comparison src/keyboard.c @ 3972:e49ff3115e7d
(read_char): After Fgarbage_collect, call redisplay.
(read_key_sequence): When inserting `menu-bar' prefix,
modify the position field to prevent doing so twice.
Do all these forms of event expansion after replayed events also.
Set last_real_key_start before each key.
Use last_real_key_start in criterion for being the first event.
(syms_of_keyboard): Doc fix.
(Vhelp_char): Renamed from help_char.
(Vprefix_help_command): New Lisp variable.
(read_key_sequence): Use that, for help char after prefix key.
(kbd_buffer_get_event): Clear f before calling mouse_position_hook.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 04 Jul 1993 02:21:02 +0000 |
parents | d620db2bc420 |
children | 992a1abeb6cd |
comparison
equal
deleted
inserted
replaced
3971:6e7afc0a7fbc | 3972:e49ff3115e7d |
---|---|
120 | 120 |
121 /* Nonzero means C-G should cause immediate error-signal. */ | 121 /* Nonzero means C-G should cause immediate error-signal. */ |
122 int immediate_quit; | 122 int immediate_quit; |
123 | 123 |
124 /* Character to recognize as the help char. */ | 124 /* Character to recognize as the help char. */ |
125 Lisp_Object help_char; | 125 Lisp_Object Vhelp_char; |
126 | 126 |
127 /* Form to execute when help char is typed. */ | 127 /* Form to execute when help char is typed. */ |
128 Lisp_Object Vhelp_form; | 128 Lisp_Object Vhelp_form; |
129 | |
130 /* Command to run when the help character follows a prefix key. */ | |
131 Lisp_Object Vprefix_help_command; | |
129 | 132 |
130 /* Character that causes a quit. Normally C-g. | 133 /* Character that causes a quit. Normally C-g. |
131 | 134 |
132 If we are running on an ordinary terminal, this must be an ordinary | 135 If we are running on an ordinary terminal, this must be an ordinary |
133 ASCII char, since we want to make it our interrupt character. | 136 ASCII char, since we want to make it our interrupt character. |
503 return; | 506 return; |
504 bcopy (name->data, ptr, name->size); | 507 bcopy (name->data, ptr, name->size); |
505 ptr += name->size; | 508 ptr += name->size; |
506 } | 509 } |
507 | 510 |
508 if (echoptr == echobuf && EQ (c, help_char)) | 511 if (echoptr == echobuf && EQ (c, Vhelp_char)) |
509 { | 512 { |
510 strcpy (ptr, " (Type ? for further options)"); | 513 strcpy (ptr, " (Type ? for further options)"); |
511 ptr += strlen (ptr); | 514 ptr += strlen (ptr); |
512 } | 515 } |
513 | 516 |
1478 /* If we have auto-saved and there is still no input | 1481 /* If we have auto-saved and there is still no input |
1479 available, garbage collect if there has been enough | 1482 available, garbage collect if there has been enough |
1480 consing going on to make it worthwhile. */ | 1483 consing going on to make it worthwhile. */ |
1481 if (!detect_input_pending () | 1484 if (!detect_input_pending () |
1482 && consing_since_gc > gc_cons_threshold / 2) | 1485 && consing_since_gc > gc_cons_threshold / 2) |
1483 Fgarbage_collect (); | 1486 { |
1487 Fgarbage_collect (); | |
1488 redisplay (); | |
1489 } | |
1484 } | 1490 } |
1485 } | 1491 } |
1486 } | 1492 } |
1487 | 1493 |
1488 /* Actually read a character, waiting if necessary. */ | 1494 /* Actually read a character, waiting if necessary. */ |
1585 reread: | 1591 reread: |
1586 last_input_char = c; | 1592 last_input_char = c; |
1587 num_input_chars++; | 1593 num_input_chars++; |
1588 | 1594 |
1589 /* Process the help character specially if enabled */ | 1595 /* Process the help character specially if enabled */ |
1590 if (EQ (c, help_char) && !NILP (Vhelp_form)) | 1596 if (EQ (c, Vhelp_char) && !NILP (Vhelp_form)) |
1591 { | 1597 { |
1592 Lisp_Object tem0; | 1598 Lisp_Object tem0; |
1593 count = specpdl_ptr - specpdl; | 1599 count = specpdl_ptr - specpdl; |
1594 | 1600 |
1595 record_unwind_protect (Fset_window_configuration, | 1601 record_unwind_protect (Fset_window_configuration, |
1912 } | 1918 } |
1913 } | 1919 } |
1914 } | 1920 } |
1915 else if (do_mouse_tracking && mouse_moved) | 1921 else if (do_mouse_tracking && mouse_moved) |
1916 { | 1922 { |
1917 FRAME_PTR f; | 1923 FRAME_PTR f = 0; |
1918 Lisp_Object bar_window; | 1924 Lisp_Object bar_window; |
1919 enum scroll_bar_part part; | 1925 enum scroll_bar_part part; |
1920 Lisp_Object x, y; | 1926 Lisp_Object x, y; |
1921 unsigned long time; | 1927 unsigned long time; |
1922 | 1928 |
3800 if (INTERACTIVE) | 3806 if (INTERACTIVE) |
3801 echo_truncate (echo_local_start); | 3807 echo_truncate (echo_local_start); |
3802 this_command_key_count = keys_local_start; | 3808 this_command_key_count = keys_local_start; |
3803 first_binding = local_first_binding; | 3809 first_binding = local_first_binding; |
3804 | 3810 |
3811 /* By default, assume each event is "real". */ | |
3812 last_real_key_start = t; | |
3813 | |
3805 /* Does mock_input indicate that we are re-reading a key sequence? */ | 3814 /* Does mock_input indicate that we are re-reading a key sequence? */ |
3806 if (t < mock_input) | 3815 if (t < mock_input) |
3807 { | 3816 { |
3808 key = keybuf[t]; | 3817 key = keybuf[t]; |
3809 add_command_key (key); | 3818 add_command_key (key); |
3812 | 3821 |
3813 /* If not, we should actually read a character. */ | 3822 /* If not, we should actually read a character. */ |
3814 else | 3823 else |
3815 { | 3824 { |
3816 struct buffer *buf = current_buffer; | 3825 struct buffer *buf = current_buffer; |
3817 | |
3818 last_real_key_start = t; | |
3819 | 3826 |
3820 key = read_char (!prompt, nmaps, submaps, last_nonmenu_event, | 3827 key = read_char (!prompt, nmaps, submaps, last_nonmenu_event, |
3821 &used_mouse_menu); | 3828 &used_mouse_menu); |
3822 | 3829 |
3823 /* read_char returns -1 at the end of a macro. | 3830 /* read_char returns -1 at the end of a macro. |
3828 t = 0; | 3835 t = 0; |
3829 goto done; | 3836 goto done; |
3830 } | 3837 } |
3831 | 3838 |
3832 Vquit_flag = Qnil; | 3839 Vquit_flag = Qnil; |
3833 | 3840 } |
3834 /* Clicks in non-text areas get prefixed by the symbol | 3841 |
3835 in their CHAR-ADDRESS field. For example, a click on | 3842 /* Clicks in non-text areas get prefixed by the symbol |
3836 the mode line is prefixed by the symbol `mode-line'. | 3843 in their CHAR-ADDRESS field. For example, a click on |
3837 | 3844 the mode line is prefixed by the symbol `mode-line'. |
3838 Furthermore, key sequences beginning with mouse clicks | 3845 |
3839 are read using the keymaps of the buffer clicked on, not | 3846 Furthermore, key sequences beginning with mouse clicks |
3840 the current buffer. So we may have to switch the buffer | 3847 are read using the keymaps of the buffer clicked on, not |
3841 here. | 3848 the current buffer. So we may have to switch the buffer |
3842 | 3849 here. |
3843 If the event was obtained from the unread_command_events | 3850 |
3844 queue, then don't expand it; we did that the first time | 3851 When we turn one event into two events, we must make sure |
3845 we read it. */ | 3852 that neither of the two looks like the original--so that, |
3846 if (EVENT_HAS_PARAMETERS (key)) | 3853 if we replay the events, they won't be expanded again. |
3854 If not for this, such reexpansion could happen either here | |
3855 or when user programs play with this-command-keys. */ | |
3856 if (EVENT_HAS_PARAMETERS (key)) | |
3857 { | |
3858 Lisp_Object kind = EVENT_HEAD_KIND (EVENT_HEAD (key)); | |
3859 | |
3860 if (EQ (kind, Qmouse_click)) | |
3847 { | 3861 { |
3848 Lisp_Object kind = EVENT_HEAD_KIND (EVENT_HEAD (key)); | 3862 Lisp_Object window = POSN_WINDOW (EVENT_START (key)); |
3849 | 3863 Lisp_Object posn = POSN_BUFFER_POSN (EVENT_START (key)); |
3850 if (EQ (kind, Qmouse_click)) | 3864 |
3865 if (XTYPE (posn) == Lisp_Cons) | |
3851 { | 3866 { |
3852 Lisp_Object window = POSN_WINDOW (EVENT_START (key)); | 3867 /* We're looking at the second event of a |
3853 Lisp_Object posn = POSN_BUFFER_POSN (EVENT_START (key)); | 3868 sequence which we expanded before. Set |
3854 | 3869 last_real_key_start appropriately. */ |
3855 /* Key sequences beginning with mouse clicks are | 3870 if (t > 0) |
3856 read using the keymaps in the buffer clicked on, | 3871 last_real_key_start = t - 1; |
3857 not the current buffer. If we're at the | |
3858 beginning of a key sequence, switch buffers. */ | |
3859 if (t == 0 | |
3860 && XTYPE (window) == Lisp_Window | |
3861 && XTYPE (XWINDOW (window)->buffer) == Lisp_Buffer | |
3862 && XBUFFER (XWINDOW (window)->buffer) != current_buffer) | |
3863 { | |
3864 keybuf[t] = key; | |
3865 mock_input = t + 1; | |
3866 | |
3867 /* Arrange to go back to the original buffer once we're | |
3868 done reading the key sequence. Note that we can't | |
3869 use save_excursion_{save,restore} here, because they | |
3870 save point as well as the current buffer; we don't | |
3871 want to save point, because redisplay may change it, | |
3872 to accommodate a Fset_window_start or something. We | |
3873 don't want to do this at the top of the function, | |
3874 because we may get input from a subprocess which | |
3875 wants to change the selected window and stuff (say, | |
3876 emacsclient). */ | |
3877 record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); | |
3878 | |
3879 set_buffer_internal (XBUFFER (XWINDOW (window)->buffer)); | |
3880 goto replay_sequence; | |
3881 } | |
3882 else if (XTYPE (posn) == Lisp_Symbol) | |
3883 { | |
3884 if (t + 1 >= bufsize) | |
3885 error ("key sequence too long"); | |
3886 keybuf[t] = posn; | |
3887 keybuf[t+1] = key; | |
3888 mock_input = t + 2; | |
3889 | |
3890 /* Zap the position in key, so we know that we've | |
3891 expanded it, and don't try to do so again. */ | |
3892 POSN_BUFFER_POSN (EVENT_START (key)) | |
3893 = Fcons (posn, Qnil); | |
3894 | |
3895 /* If we switched buffers while reading the first event, | |
3896 replay in case we switched keymaps too. */ | |
3897 if (buf != current_buffer && t == 0) | |
3898 goto replay_sequence; | |
3899 goto replay_key; | |
3900 } | |
3901 else if (XTYPE (posn) == Lisp_Cons) | |
3902 { | |
3903 /* We're looking at the second event of a | |
3904 sequence which we expanded before. Set | |
3905 last_real_key_start appropriately. */ | |
3906 if (last_real_key_start == t && t > 0) | |
3907 last_real_key_start = t - 1; | |
3908 } | |
3909 } | 3872 } |
3910 else if (EQ (kind, Qswitch_frame)) | 3873 |
3874 /* Key sequences beginning with mouse clicks are | |
3875 read using the keymaps in the buffer clicked on, | |
3876 not the current buffer. If we're at the | |
3877 beginning of a key sequence, switch buffers. */ | |
3878 if (last_real_key_start == 0 | |
3879 && XTYPE (window) == Lisp_Window | |
3880 && XTYPE (XWINDOW (window)->buffer) == Lisp_Buffer | |
3881 && XBUFFER (XWINDOW (window)->buffer) != current_buffer) | |
3911 { | 3882 { |
3912 /* If we're at the beginning of a key sequence, go | 3883 keybuf[t] = key; |
3913 ahead and return this event. If we're in the | 3884 mock_input = t + 1; |
3914 midst of a key sequence, delay it until the end. */ | 3885 |
3915 if (t > 0) | 3886 /* Arrange to go back to the original buffer once we're |
3916 { | 3887 done reading the key sequence. Note that we can't |
3917 delayed_switch_frame = key; | 3888 use save_excursion_{save,restore} here, because they |
3918 goto replay_key; | 3889 save point as well as the current buffer; we don't |
3919 } | 3890 want to save point, because redisplay may change it, |
3891 to accommodate a Fset_window_start or something. We | |
3892 don't want to do this at the top of the function, | |
3893 because we may get input from a subprocess which | |
3894 wants to change the selected window and stuff (say, | |
3895 emacsclient). */ | |
3896 record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); | |
3897 | |
3898 set_buffer_internal (XBUFFER (XWINDOW (window)->buffer)); | |
3899 goto replay_sequence; | |
3920 } | 3900 } |
3921 else | 3901 else if (XTYPE (posn) == Lisp_Symbol) |
3922 { | 3902 { |
3923 Lisp_Object posn = POSN_BUFFER_POSN (EVENT_START (key)); | 3903 /* Expand mode-line and scroll-bar events into two events: |
3924 | 3904 use posn as a fake prefix key. */ |
3925 /* Handle menu-bar events: | 3905 |
3926 insert the dummy prefix char `menu-bar'. */ | 3906 if (t + 1 >= bufsize) |
3927 if (EQ (posn, Qmenu_bar)) | 3907 error ("key sequence too long"); |
3928 { | 3908 keybuf[t] = posn; |
3929 if (t + 1 >= bufsize) | 3909 keybuf[t+1] = key; |
3930 error ("key sequence too long"); | 3910 mock_input = t + 2; |
3931 /* Run the Lucid hook. */ | 3911 |
3932 call1 (Vrun_hooks, Qactivate_menubar_hook); | 3912 /* Zap the position in key, so we know that we've |
3933 /* If it has changed current-menubar from previous value, | 3913 expanded it, and don't try to do so again. */ |
3934 really recompute the menubar from the value. */ | 3914 POSN_BUFFER_POSN (EVENT_START (key)) |
3935 if (! NILP (Vlucid_menu_bar_dirty_flag)) | 3915 = Fcons (posn, Qnil); |
3936 call0 (Qrecompute_lucid_menubar); | 3916 goto replay_key; |
3937 keybuf[t] = posn; | |
3938 keybuf[t+1] = key; | |
3939 mock_input = t + 2; | |
3940 goto replay_sequence; | |
3941 } | |
3942 } | 3917 } |
3943 } | 3918 } |
3944 | 3919 else if (EQ (kind, Qswitch_frame)) |
3945 /* If we switched buffers while reading the first event, | |
3946 replay in case we switched keymaps too. */ | |
3947 if (buf != current_buffer && t == 0) | |
3948 { | 3920 { |
3949 keybuf[t++] = key; | 3921 /* If we're at the beginning of a key sequence, go |
3950 mock_input = t; | 3922 ahead and return this event. If we're in the |
3951 goto replay_sequence; | 3923 midst of a key sequence, delay it until the end. */ |
3924 if (t > 0) | |
3925 { | |
3926 delayed_switch_frame = key; | |
3927 goto replay_key; | |
3928 } | |
3929 } | |
3930 else | |
3931 { | |
3932 Lisp_Object posn = POSN_BUFFER_POSN (EVENT_START (key)); | |
3933 | |
3934 /* Handle menu-bar events: | |
3935 insert the dummy prefix event `menu-bar'. */ | |
3936 if (EQ (posn, Qmenu_bar)) | |
3937 { | |
3938 if (t + 1 >= bufsize) | |
3939 error ("key sequence too long"); | |
3940 /* Run the Lucid hook. */ | |
3941 call1 (Vrun_hooks, Qactivate_menubar_hook); | |
3942 /* If it has changed current-menubar from previous value, | |
3943 really recompute the menubar from the value. */ | |
3944 if (! NILP (Vlucid_menu_bar_dirty_flag)) | |
3945 call0 (Qrecompute_lucid_menubar); | |
3946 keybuf[t] = posn; | |
3947 keybuf[t+1] = key; | |
3948 | |
3949 /* Zap the position in key, so we know that we've | |
3950 expanded it, and don't try to do so again. */ | |
3951 POSN_BUFFER_POSN (EVENT_START (key)) | |
3952 = Fcons (posn, Qnil); | |
3953 | |
3954 mock_input = t + 2; | |
3955 goto replay_sequence; | |
3956 } | |
3957 else if (XTYPE (posn) == Lisp_Cons) | |
3958 { | |
3959 /* We're looking at the second event of a | |
3960 sequence which we expanded before. Set | |
3961 last_real_key_start appropriately. */ | |
3962 if (last_real_key_start == t && t > 0) | |
3963 last_real_key_start = t - 1; | |
3964 } | |
3952 } | 3965 } |
3953 } | 3966 } |
3954 | 3967 |
3955 /* We have finally decided that KEY is something we might want | 3968 /* We have finally decided that KEY is something we might want |
3956 to look up. */ | 3969 to look up. */ |
3963 | 3976 |
3964 /* If KEY wasn't bound, we'll try some fallbacks. */ | 3977 /* If KEY wasn't bound, we'll try some fallbacks. */ |
3965 if (first_binding >= nmaps) | 3978 if (first_binding >= nmaps) |
3966 { | 3979 { |
3967 Lisp_Object head = EVENT_HEAD (key); | 3980 Lisp_Object head = EVENT_HEAD (key); |
3981 | |
3982 if (EQ (head, Vhelp_char)) | |
3983 { | |
3984 read_key_sequence_cmd = Vprefix_help_command; | |
3985 keybuf[t++] = key; | |
3986 last_nonmenu_event = key; | |
3987 goto done; | |
3988 } | |
3968 | 3989 |
3969 if (XTYPE (head) == Lisp_Symbol) | 3990 if (XTYPE (head) == Lisp_Symbol) |
3970 { | 3991 { |
3971 Lisp_Object breakdown = parse_modifiers (head); | 3992 Lisp_Object breakdown = parse_modifiers (head); |
3972 int modifiers = XINT (XCONS (XCONS (breakdown)->cdr)->car); | 3993 int modifiers = XINT (XCONS (XCONS (breakdown)->cdr)->car); |
5079 "*The frame in which the most recently read event occurred.\n\ | 5100 "*The frame in which the most recently read event occurred.\n\ |
5080 If the last event came from a keyboard macro, this is set to `macro'."); | 5101 If the last event came from a keyboard macro, this is set to `macro'."); |
5081 Vlast_event_frame = Qnil; | 5102 Vlast_event_frame = Qnil; |
5082 #endif | 5103 #endif |
5083 | 5104 |
5084 DEFVAR_LISP ("help-char", &help_char, | 5105 DEFVAR_LISP ("help-char", &Vhelp_char, |
5085 "Character to recognize as meaning Help.\n\ | 5106 "Character to recognize as meaning Help.\n\ |
5086 When it is read, do `(eval help-form)', and display result if it's a string.\n\ | 5107 When it is read, do `(eval help-form)', and display result if it's a string.\n\ |
5087 If the value of `help-form' is nil, this char can be read normally."); | 5108 If the value of `help-form' is nil, this char can be read normally."); |
5088 XSET (help_char, Lisp_Int, Ctl ('H')); | 5109 XSET (Vhelp_char, Lisp_Int, Ctl ('H')); |
5089 | 5110 |
5090 DEFVAR_LISP ("help-form", &Vhelp_form, | 5111 DEFVAR_LISP ("help-form", &Vhelp_form, |
5091 "Form to execute when character help-char is read.\n\ | 5112 "Form to execute when character `help-char' is read.\n\ |
5092 If the form returns a string, that string is displayed.\n\ | 5113 If the form returns a string, that string is displayed.\n\ |
5093 If `help-form' is nil, the help char is not recognized."); | 5114 If `help-form' is nil, the help char is not recognized."); |
5094 Vhelp_form = Qnil; | 5115 Vhelp_form = Qnil; |
5116 | |
5117 DEFVAR_LISP ("prefix-help-command", &Vprefix_help_command, | |
5118 "Command to run when `help-char' character follows a prefix key.\n\ | |
5119 This command is used only when there is no actual binding\n\ | |
5120 for that character after that prefix key."); | |
5121 Vprefix_help_command = Qnil; | |
5095 | 5122 |
5096 DEFVAR_LISP ("top-level", &Vtop_level, | 5123 DEFVAR_LISP ("top-level", &Vtop_level, |
5097 "Form to evaluate when Emacs starts up.\n\ | 5124 "Form to evaluate when Emacs starts up.\n\ |
5098 Useful to set before you dump a modified Emacs."); | 5125 Useful to set before you dump a modified Emacs."); |
5099 Vtop_level = Qnil; | 5126 Vtop_level = Qnil; |
5142 DEFVAR_LISP ("pre-command-hook", &Vpre_command_hook, | 5169 DEFVAR_LISP ("pre-command-hook", &Vpre_command_hook, |
5143 "Normal hook run before each command is executed."); | 5170 "Normal hook run before each command is executed."); |
5144 Vpre_command_hook = Qnil; | 5171 Vpre_command_hook = Qnil; |
5145 | 5172 |
5146 DEFVAR_LISP ("post-command-hook", &Vpost_command_hook, | 5173 DEFVAR_LISP ("post-command-hook", &Vpost_command_hook, |
5147 "Normal hook run before each command is executed."); | 5174 "Normal hook run after each command is executed."); |
5148 Vpost_command_hook = Qnil; | 5175 Vpost_command_hook = Qnil; |
5149 | 5176 |
5150 DEFVAR_LISP ("lucid-menu-bar-dirty-flag", &Vlucid_menu_bar_dirty_flag, | 5177 DEFVAR_LISP ("lucid-menu-bar-dirty-flag", &Vlucid_menu_bar_dirty_flag, |
5151 "t means menu bar, specified Lucid style, needs to be recomputed."); | 5178 "t means menu bar, specified Lucid style, needs to be recomputed."); |
5152 Vlucid_menu_bar_dirty_flag = Qnil; | 5179 Vlucid_menu_bar_dirty_flag = Qnil; |