aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1993-07-04 02:21:02 +0000
committerRichard M. Stallman1993-07-04 02:21:02 +0000
commit7e85b93579088b041c61443ae19bba83ecffeab5 (patch)
tree34ed6f9cc87e85b8bc3d9b19203b7a53dc49cc55 /src
parent58bf6042169d93d1fbe96cab97be5c2999b63063 (diff)
downloademacs-7e85b93579088b041c61443ae19bba83ecffeab5.tar.gz
emacs-7e85b93579088b041c61443ae19bba83ecffeab5.zip
(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.
Diffstat (limited to 'src')
-rw-r--r--src/keyboard.c261
1 files changed, 144 insertions, 117 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 278f0dbb342..e0d7276a286 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -122,11 +122,14 @@ static int echoing;
122int immediate_quit; 122int immediate_quit;
123 123
124/* Character to recognize as the help char. */ 124/* Character to recognize as the help char. */
125Lisp_Object help_char; 125Lisp_Object Vhelp_char;
126 126
127/* Form to execute when help char is typed. */ 127/* Form to execute when help char is typed. */
128Lisp_Object Vhelp_form; 128Lisp_Object Vhelp_form;
129 129
130/* Command to run when the help character follows a prefix key. */
131Lisp_Object Vprefix_help_command;
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
@@ -505,7 +508,7 @@ echo_char (c)
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);
@@ -1480,7 +1483,10 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
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 }
@@ -1587,7 +1593,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
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;
@@ -1914,7 +1920,7 @@ kbd_buffer_get_event ()
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;
@@ -3802,6 +3808,9 @@ read_key_sequence (keybuf, bufsize, prompt)
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 {
@@ -3815,8 +3824,6 @@ read_key_sequence (keybuf, bufsize, prompt)
3815 { 3824 {
3816 struct buffer *buf = current_buffer; 3825 struct buffer *buf = current_buffer;
3817 3826
3818 last_real_key_start = t;
3819
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
@@ -3830,125 +3837,131 @@ read_key_sequence (keybuf, bufsize, prompt)
3830 } 3837 }
3831 3838
3832 Vquit_flag = Qnil; 3839 Vquit_flag = Qnil;
3840 }
3833 3841
3834 /* Clicks in non-text areas get prefixed by the symbol 3842 /* Clicks in non-text areas get prefixed by the symbol
3835 in their CHAR-ADDRESS field. For example, a click on 3843 in their CHAR-ADDRESS field. For example, a click on
3836 the mode line is prefixed by the symbol `mode-line'. 3844 the mode line is prefixed by the symbol `mode-line'.
3837 3845
3838 Furthermore, key sequences beginning with mouse clicks 3846 Furthermore, key sequences beginning with mouse clicks
3839 are read using the keymaps of the buffer clicked on, not 3847 are read using the keymaps of the buffer clicked on, not
3840 the current buffer. So we may have to switch the buffer 3848 the current buffer. So we may have to switch the buffer
3841 here. 3849 here.
3850
3851 When we turn one event into two events, we must make sure
3852 that neither of the two looks like the original--so that,
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));
3842 3859
3843 If the event was obtained from the unread_command_events 3860 if (EQ (kind, Qmouse_click))
3844 queue, then don't expand it; we did that the first time
3845 we read it. */
3846 if (EVENT_HAS_PARAMETERS (key))
3847 { 3861 {
3848 Lisp_Object kind = EVENT_HEAD_KIND (EVENT_HEAD (key)); 3862 Lisp_Object window = POSN_WINDOW (EVENT_START (key));
3863 Lisp_Object posn = POSN_BUFFER_POSN (EVENT_START (key));
3849 3864
3850 if (EQ (kind, Qmouse_click)) 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:
3904 use posn as a fake prefix key. */
3924 3905
3925 /* Handle menu-bar events: 3906 if (t + 1 >= bufsize)
3926 insert the dummy prefix char `menu-bar'. */ 3907 error ("key sequence too long");
3927 if (EQ (posn, Qmenu_bar)) 3908 keybuf[t] = posn;
3928 { 3909 keybuf[t+1] = key;
3929 if (t + 1 >= bufsize) 3910 mock_input = t + 2;
3930 error ("key sequence too long"); 3911
3931 /* Run the Lucid hook. */ 3912 /* Zap the position in key, so we know that we've
3932 call1 (Vrun_hooks, Qactivate_menubar_hook); 3913 expanded it, and don't try to do so again. */
3933 /* If it has changed current-menubar from previous value, 3914 POSN_BUFFER_POSN (EVENT_START (key))
3934 really recompute the menubar from the value. */ 3915 = Fcons (posn, Qnil);
3935 if (! NILP (Vlucid_menu_bar_dirty_flag)) 3916 goto replay_key;
3936 call0 (Qrecompute_lucid_menubar);
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
@@ -3966,6 +3979,14 @@ read_key_sequence (keybuf, bufsize, prompt)
3966 { 3979 {
3967 Lisp_Object head = EVENT_HEAD (key); 3980 Lisp_Object head = EVENT_HEAD (key);
3968 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 }
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);
@@ -5081,18 +5102,24 @@ 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\
5086When it is read, do `(eval help-form)', and display result if it's a string.\n\ 5107When it is read, do `(eval help-form)', and display result if it's a string.\n\
5087If the value of `help-form' is nil, this char can be read normally."); 5108If 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\
5092If the form returns a string, that string is displayed.\n\ 5113If the form returns a string, that string is displayed.\n\
5093If `help-form' is nil, the help char is not recognized."); 5114If `help-form' is nil, the help char is not recognized.");
5094 Vhelp_form = Qnil; 5115 Vhelp_form = Qnil;
5095 5116
5117 DEFVAR_LISP ("prefix-help-command", &Vprefix_help_command,
5118 "Command to run when `help-char' character follows a prefix key.\n\
5119This command is used only when there is no actual binding\n\
5120for that character after that prefix key.");
5121 Vprefix_help_command = Qnil;
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\
5098Useful to set before you dump a modified Emacs."); 5125Useful to set before you dump a modified Emacs.");
@@ -5144,7 +5171,7 @@ Buffer modification stores t in this variable.");
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,