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;