X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/c970a76059aba98b8ac3e5a6fb7e93ce45a6a329..5bcf005469998ba44f13880e68c918bd7bc96053:/src/keyboard.c?ds=sidebyside diff --git a/src/keyboard.c b/src/keyboard.c index 105131eedb..2aa4b51ccf 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1,5 +1,5 @@ /* Keyboard and mouse input; editor command loop. - Copyright (C) 1985,86,87,88,89,93,94,95,96,97,99, 2000 + Copyright (C) 1985,86,87,88,89,93,94,95,96,97,99, 2000, 2001 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -37,6 +37,7 @@ Boston, MA 02111-1307, USA. */ #include "dispextern.h" #include "syntax.h" #include "intervals.h" +#include "keymap.h" #include "blockinput.h" #include "puresize.h" #include "systime.h" @@ -103,9 +104,11 @@ extern int input_fd; #define KBD_BUFFER_SIZE 4096 #endif #else /* No X-windows, character input */ -#define KBD_BUFFER_SIZE 256 +#define KBD_BUFFER_SIZE 4096 #endif /* No X-windows */ +#define abs(x) ((x) >= 0 ? (x) : -(x)) + /* Following definition copied from eval.c */ struct backtrace @@ -188,13 +191,21 @@ extern struct backtrace *backtrace_list; Lisp_Object Vshow_help_function; +/* If a string, the message displayed before displaying a help-echo + in the echo area. */ + +Lisp_Object Vpre_help_message; + /* Nonzero means do menu prompting. */ + static int menu_prompting; /* Character to see next line of menu prompt. */ + static Lisp_Object menu_prompt_more_char; /* For longjmp to where kbd input is being done. */ + static jmp_buf getcjmp; /* True while doing kbd input. */ @@ -202,7 +213,7 @@ int waiting_for_input; /* True while displaying for echoing. Delays C-g throwing. */ -static int echoing; +int echoing; /* Non-null means we can start echoing at the next input pause even though there is something in the echo area. */ @@ -214,12 +225,12 @@ static struct kboard *ok_to_echo_at_next_pause; exists, and echo_message_buffer is eq to the current message buffer, we know that the message comes from echo_kboard. */ -static struct kboard *echo_kboard; +struct kboard *echo_kboard; /* The buffer used for echoing. Set in echo_now, reset in cancel_echoing. */ -static Lisp_Object echo_message_buffer; +Lisp_Object echo_message_buffer; /* Nonzero means disregard local maps for the menu bar. */ static int inhibit_local_menu_bar_menus; @@ -644,6 +655,10 @@ Lisp_Object Vdisable_point_adjustment; Lisp_Object Vglobal_disable_point_adjustment; +/* The time when Emacs started being idle. */ + +static EMACS_TIME timer_idleness_start_time; + /* Global variable declarations. */ @@ -676,14 +691,12 @@ static void save_getcjmp (); static void restore_getcjmp P_ ((jmp_buf)); static Lisp_Object apply_modifiers P_ ((int, Lisp_Object)); static void clear_event P_ ((struct input_event *)); +static void any_kboard_state P_ ((void)); /* Nonzero means don't try to suspend even if the operating system seems to support it. */ static int cannot_suspend; -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)>(b)?(a):(b)) - /* Install the string STR as the beginning of the string of echoing, so that it serves as a prompt for the next character. Also start echoing. */ @@ -879,8 +892,6 @@ static void add_command_key (key) Lisp_Object key; { - int size = XVECTOR (this_command_keys)->size; - /* If reset-this-command-length was called recently, obey it now. See the doc string of that function for an explanation of why. */ if (before_command_restore_flag) @@ -892,20 +903,15 @@ add_command_key (key) before_command_restore_flag = 0; } - if (this_command_key_count >= size) - { - Lisp_Object new_keys; - - new_keys = Fmake_vector (make_number (size * 2), Qnil); - bcopy (XVECTOR (this_command_keys)->contents, - XVECTOR (new_keys)->contents, - size * sizeof (Lisp_Object)); - - this_command_keys = new_keys; - } + if (this_command_key_count >= ASIZE (this_command_keys)) + this_command_keys = larger_vector (this_command_keys, + 2 * ASIZE (this_command_keys), + Qnil); - XVECTOR (this_command_keys)->contents[this_command_key_count++] = key; + AREF (this_command_keys, this_command_key_count) = key; + ++this_command_key_count; } + Lisp_Object recursive_edit_1 () @@ -920,13 +926,25 @@ recursive_edit_1 () } #ifdef HAVE_X_WINDOWS - /* The command loop has started a busy-cursor timer, so we have to + /* The command loop has started an hourglass timer, so we have to cancel it here, otherwise it will fire because the recursive edit can take some time. */ - if (display_busy_cursor_p) - cancel_busy_cursor (); + if (display_hourglass_p) + cancel_hourglass (); #endif + /* This function may have been called from a debugger called from + within redisplay, for instance by Edebugging a function called + from fontification-functions. We want to allow redisplay in + the debugging session. + + The recursive edit is left with a `(throw exit ...)'. The `exit' + tag is not caught anywhere in redisplay, i.e. when we leave the + recursive edit, the original redisplay leading to the recursive + edit will be unwound. The outcome should therefore be safe. */ + specbind (Qinhibit_redisplay, Qnil); + redisplaying_p = 0; + val = command_loop (); if (EQ (val, Qt)) Fsignal (Qquit, Qnil); @@ -957,50 +975,53 @@ force_auto_save_soon () } DEFUN ("recursive-edit", Frecursive_edit, Srecursive_edit, 0, 0, "", - "Invoke the editor command loop recursively.\n\ -To get out of the recursive edit, a command can do `(throw 'exit nil)';\n\ -that tells this function to return.\n\ -Alternately, `(throw 'exit t)' makes this function signal an error.\n\ -This function is called by the editor initialization to begin editing.") - () + doc: /* Invoke the editor command loop recursively. +To get out of the recursive edit, a command can do `(throw 'exit nil)'; +that tells this function to return. +Alternately, `(throw 'exit t)' makes this function signal an error. +This function is called by the editor initialization to begin editing. */) + () { int count = specpdl_ptr - specpdl; + Lisp_Object buffer; command_loop_level++; update_mode_lines = 1; - /* This function may have been called from a debugger called from - within redisplay, for instance by Edebugging a function called - from fontification-functions. We want to allow redisplay in - the debugging session. - - The recursive edit is left with a `(throw exit ...)'. The `exit' - tag is not caught anywhere in redisplay, i.e. when we leave the - recursive edit, the original redisplay leading to the recursive - edit will be unwound. The outcome should therefore be safe. */ - specbind (Qinhibit_redisplay, Qnil); - redisplaying_p = 0; + if (command_loop_level + && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer)) + buffer = Fcurrent_buffer (); + else + buffer = Qnil; + /* If we leave recursive_edit_1 below with a `throw' for instance, + like it is done in the splash screen display, we have to + make sure that we restore single_kboard as command_loop_1 + would have done if it were left normally. */ record_unwind_protect (recursive_edit_unwind, - (command_loop_level - && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer)) - ? Fcurrent_buffer () - : Qnil); + Fcons (buffer, single_kboard ? Qt : Qnil)); + recursive_edit_1 (); return unbind_to (count, Qnil); } Lisp_Object -recursive_edit_unwind (buffer) - Lisp_Object buffer; +recursive_edit_unwind (info) + Lisp_Object info; { - if (!NILP (buffer)) - Fset_buffer (buffer); - + if (BUFFERP (XCAR (info))) + Fset_buffer (XCAR (info)); + + if (NILP (XCDR (info))) + any_kboard_state (); + else + single_kboard_state (); + command_loop_level--; update_mode_lines = 1; return Qnil; } + static void any_kboard_state () @@ -1245,19 +1266,19 @@ top_level_1 () } DEFUN ("top-level", Ftop_level, Stop_level, 0, 0, "", - "Exit all recursive editing levels.") - () + doc: /* Exit all recursive editing levels. */) + () { #ifdef HAVE_X_WINDOWS - if (display_busy_cursor_p) - cancel_busy_cursor (); + if (display_hourglass_p) + cancel_hourglass (); #endif return Fthrow (Qtop_level, Qnil); } DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0, "", - "Exit from the innermost recursive edit or minibuffer.") - () + doc: /* Exit from the innermost recursive edit or minibuffer. */) + () { if (command_loop_level > 0 || minibuf_level > 0) Fthrow (Qexit, Qnil); @@ -1267,8 +1288,8 @@ DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0, } DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0, 0, "", - "Abort the command that requested this recursive edit or minibuffer input.") - () + doc: /* Abort the command that requested this recursive edit or minibuffer input. */) + () { if (command_loop_level > 0 || minibuf_level > 0) Fthrow (Qexit, Qt); @@ -1280,10 +1301,10 @@ DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0, /* This is the actual command reading loop, sans error-handling encapsulation. */ -Lisp_Object Fcommand_execute (); -static int read_key_sequence (); -void safe_run_hooks (); -static void adjust_point_for_property (); +static int read_key_sequence P_ ((Lisp_Object *, int, Lisp_Object, + int, int, int)); +void safe_run_hooks P_ ((Lisp_Object)); +static void adjust_point_for_property P_ ((int)); Lisp_Object command_loop_1 () @@ -1320,7 +1341,7 @@ command_loop_1 () /* If displaying a message, resize the echo area window to fit that message's size exactly. */ if (!NILP (echo_area_buffer[0])) - resize_echo_area_axactly (); + resize_echo_area_exactly (); if (!NILP (Vdeferred_action_list)) call0 (Vdeferred_action_function); @@ -1478,6 +1499,10 @@ command_loop_1 () this variable differently. */ Vdisable_point_adjustment = Qnil; + /* Process filters and timers may have messed with deactivate-mark. + reset it before we execute the command. */ + Vdeactivate_mark = Qnil; + /* Execute the command. */ Vthis_command = cmd; @@ -1606,8 +1631,8 @@ command_loop_1 () /* Here for a command that isn't executed directly */ #ifdef HAVE_X_WINDOWS - if (display_busy_cursor_p) - start_busy_cursor (); + if (display_hourglass_p) + start_hourglass (); #endif nonundocount = 0; @@ -1616,8 +1641,8 @@ command_loop_1 () Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil); #ifdef HAVE_X_WINDOWS - if (display_busy_cursor_p) - cancel_busy_cursor (); + if (display_hourglass_p) + cancel_hourglass (); #endif } directly_done: ; @@ -1631,7 +1656,7 @@ command_loop_1 () /* If displaying a message, resize the echo area window to fit that message's size exactly. */ if (!NILP (echo_area_buffer[0])) - resize_echo_area_axactly (); + resize_echo_area_exactly (); if (!NILP (Vdeferred_action_list)) safe_run_hooks (Qdeferred_action_function); @@ -2026,14 +2051,25 @@ show_help_echo (help, window, object, pos, ok_to_overwrite_keystroke_echo) { if (STRINGP (help)) { - int count = specpdl_ptr - specpdl; + int count = BINDING_STACK_SIZE (); + + if (!help_echo_showing_p) + Vpre_help_message = current_message (); + specbind (Qmessage_truncate_lines, Qt); message3_nolog (help, STRING_BYTES (XSTRING (help)), STRING_MULTIBYTE (help)); unbind_to (count, Qnil); } + else if (STRINGP (Vpre_help_message)) + { + message3_nolog (Vpre_help_message, + STRING_BYTES (XSTRING (Vpre_help_message)), + STRING_MULTIBYTE (Vpre_help_message)); + Vpre_help_message = Qnil; + } else - message (0); + message (0); } help_echo_showing_p = STRINGP (help); @@ -2090,6 +2126,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) volatile Lisp_Object also_record; volatile int reread; struct gcpro gcpro1, gcpro2; + EMACS_TIME last_idle_start; also_record = Qnil; @@ -2137,10 +2174,16 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) /* Undo what read_char_x_menu_prompt did when it unread additional keys returned by Fx_popup_menu. */ if (CONSP (c) - && (SYMBOLP (XCAR (c)) || INTEGERP (XCAR (c))) - && NILP (XCDR (c))) + && EQ (XCDR (c), Qdisabled) + && (SYMBOLP (XCAR (c)) || INTEGERP (XCAR (c)))) c = XCAR (c); - + + /* If the queued event is something that used the mouse, + set used_mouse_menu accordingly. */ + if (used_mouse_menu + && (EQ (c, Qtool_bar) || EQ (c, Qmenu_bar))) + *used_mouse_menu = 1; + reread = 1; goto reread_for_input_method; } @@ -2221,7 +2264,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) while (!input_pending) { if (help_echo_showing_p && !EQ (selected_window, minibuf_window)) - redisplay_preserve_echo_area (); + redisplay_preserve_echo_area (5); else redisplay (); @@ -2315,15 +2358,21 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) KBOARD *kb = FRAME_KBOARD (XFRAME (selected_frame)); if (kb != current_kboard) { - Lisp_Object *tailp = &kb->kbd_queue; + Lisp_Object link = kb->kbd_queue; /* We shouldn't get here if we were in single-kboard mode! */ if (single_kboard) abort (); - while (CONSP (*tailp)) - tailp = &XCDR (*tailp); - if (!NILP (*tailp)) - abort (); - *tailp = Fcons (c, Qnil); + if (CONSP (link)) + { + while (CONSP (XCDR (link))) + link = XCDR (link); + if (!NILP (XCDR (link))) + abort (); + } + if (!CONSP (link)) + kb->kbd_queue = Fcons (c, Qnil); + else + XSETCDR (link, Fcons (c, Qnil)); kb->kbd_queue_has_data = 1; current_kboard = kb; /* This is going to exit from read_char @@ -2538,12 +2587,18 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) #ifdef MULTI_KBOARD if (! NILP (c) && (kb != current_kboard)) { - Lisp_Object *tailp = &kb->kbd_queue; - while (CONSP (*tailp)) - tailp = &XCDR (*tailp); - if (!NILP (*tailp)) - abort (); - *tailp = Fcons (c, Qnil); + Lisp_Object link = kb->kbd_queue; + if (CONSP (link)) + { + while (CONSP (XCDR (link))) + link = XCDR (link); + if (!NILP (XCDR (link))) + abort (); + } + if (!CONSP (link)) + kb->kbd_queue = Fcons (c, Qnil); + else + XSETCDR (link, Fcons (c, Qnil)); kb->kbd_queue_has_data = 1; c = Qnil; if (single_kboard) @@ -2577,6 +2632,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) non_reread: + /* Record the last idle start time so that we can reset it + should the next event read be a help-echo. */ + last_idle_start = timer_idleness_start_time; timer_stop_idle (); start_polling (); @@ -2656,7 +2714,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar)) { /* Change menu-bar to (menu-bar) as the event "position". */ - POSN_BUFFER_POSN (EVENT_START (c)) = Fcons (posn, Qnil); + POSN_BUFFER_SET_POSN (EVENT_START (c), Fcons (posn, Qnil)); also_record = c; Vunread_command_events = Fcons (c, Vunread_command_events); @@ -2685,7 +2743,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) /* Now wipe the echo area, except for help events which do their own stuff with the echo area. */ - if (!CONSP (c) || !(EQ (Qhelp_echo, XCAR (c)))) + if (!CONSP (c) + || (!(EQ (Qhelp_echo, XCAR (c))) + && !(EQ (Qswitch_frame, XCAR (c))))) { if (!NILP (echo_area_buffer[0])) safe_run_hooks (Qecho_area_clear_hook); @@ -2787,12 +2847,21 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) if (CONSP (c) && EQ (XCAR (c), Qhelp_echo)) { /* (help-echo FRAME HELP WINDOW OBJECT POS). */ - Lisp_Object help, object, position, window; - help = Fnth (make_number (2), c); - window = Fnth (make_number (3), c); - object = Fnth (make_number (4), c); - position = Fnth (make_number (5), c); + Lisp_Object help, object, position, window, tem; + + tem = Fcdr (XCDR (c)); + help = Fcar (tem); + tem = Fcdr (tem); + window = Fcar (tem); + tem = Fcdr (tem); + object = Fcar (tem); + tem = Fcdr (tem); + position = Fcar (tem); + show_help_echo (help, window, object, position, 0); + + /* We stopped being idle for this event; undo that. */ + timer_idleness_start_time = last_idle_start; goto retry; } @@ -2920,7 +2989,7 @@ record_char (c) { Lisp_Object help; - help = Fnth (make_number (2), c); + help = Fcar (Fcdr (XCDR (c))); if (STRINGP (help)) { int last_idx; @@ -2933,7 +3002,7 @@ record_char (c) if (!CONSP (last_c) || !EQ (XCAR (last_c), Qhelp_echo) - || (last_help = Fnth (make_number (2), last_c), + || (last_help = Fcar (Fcdr (XCDR (last_c))), !EQ (last_help, help))) { total_keys++; @@ -3039,7 +3108,7 @@ tracking_off (old_value) redisplay. */ if (!readable_events (1)) { - redisplay_preserve_echo_area (); + redisplay_preserve_echo_area (6); get_input_pending (&input_pending, 1); } } @@ -3047,11 +3116,12 @@ tracking_off (old_value) } DEFUN ("track-mouse", Ftrack_mouse, Strack_mouse, 0, UNEVALLED, 0, - "Evaluate BODY with mouse movement events enabled.\n\ -Within a `track-mouse' form, mouse motion generates input events that\n\ -you can read with `read-event'.\n\ -Normally, mouse motion is ignored.") - (args) + doc: /* Evaluate BODY with mouse movement events enabled. +Within a `track-mouse' form, mouse motion generates input events that +you can read with `read-event'. +Normally, mouse motion is ignored. +usage: (track-mouse BODY ...) */) + (args) Lisp_Object args; { int count = specpdl_ptr - specpdl; @@ -3810,11 +3880,9 @@ swallow_events (do_display) get_input_pending (&input_pending, 1); if (timers_run != old_timers_run && do_display) - redisplay_preserve_echo_area (); + redisplay_preserve_echo_area (7); } -static EMACS_TIME timer_idleness_start_time; - /* Record the start of when Emacs is idle, for the sake of running idle-time timers. */ @@ -4010,17 +4078,18 @@ timer_check (do_it_now) if (NILP (vector[0])) { int was_locked = single_kboard; - int count = specpdl_ptr - specpdl; + int count = BINDING_STACK_SIZE (); + Lisp_Object old_deactivate_mark = Vdeactivate_mark; /* Mark the timer as triggered to prevent problems if the lisp code fails to reschedule it right. */ vector[0] = Qt; specbind (Qinhibit_quit, Qt); - + call1 (Qtimer_event_handler, chosen_timer); + Vdeactivate_mark = old_deactivate_mark; timers_run++; - unbind_to (count, Qnil); /* Resume allowing input from any kboard, if that was true before. */ @@ -4522,11 +4591,16 @@ static int last_mouse_x; static int last_mouse_y; static unsigned long button_down_time; -/* The maximum time between clicks to make a double-click, - or Qnil to disable double-click detection, - or Qt for no time limit. */ +/* The maximum time between clicks to make a double-click, or Qnil to + disable double-click detection, or Qt for no time limit. */ + Lisp_Object Vdouble_click_time; +/* Maximum number of pixels the mouse may be moved between clicks + to make a double-click. */ + +int double_click_fuzz; + /* The number of clicks in this multiple-click. */ int double_click_count; @@ -4630,12 +4704,35 @@ make_lispy_event (event) / sizeof (iso_lispy_function_keys[0]))); else #endif - return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET, - event->modifiers, - Qfunction_key, Qnil, - lispy_function_keys, &func_key_syms, - (sizeof (lispy_function_keys) - / sizeof (lispy_function_keys[0]))); + +#ifdef HAVE_X_WINDOWS + if (event->code - FUNCTION_KEY_OFFSET < 0 + || (event->code - FUNCTION_KEY_OFFSET + >= sizeof lispy_function_keys / sizeof *lispy_function_keys)) + { + /* EVENT->code is an unknown keysym, for example someone + assigned `ccaron' to a key in a locale where + XmbLookupString doesn't return a translation for it. */ + char *name; + Lisp_Object symbol; + + BLOCK_INPUT; + /* This returns a pointer to a static area. Don't free it. */ + name = XKeysymToString (event->code); + symbol = name ? intern (name) : Qnil; + UNBLOCK_INPUT; + + if (!NILP (symbol)) + return apply_modifiers (event->modifiers, symbol); + } +#endif /* HAVE_X_WINDOWS */ + + return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET, + event->modifiers, + Qfunction_key, Qnil, + lispy_function_keys, &func_key_syms, + (sizeof (lispy_function_keys) + / sizeof (lispy_function_keys[0]))); #ifdef HAVE_MOUSE /* A mouse click. Figure out where it is, decide whether it's @@ -4650,6 +4747,7 @@ make_lispy_event (event) Lisp_Object position; Lisp_Object *start_pos_ptr; Lisp_Object start_pos; + Lisp_Object window; position = Qnil; @@ -4657,8 +4755,7 @@ make_lispy_event (event) if (event->kind == mouse_click) { int part; - FRAME_PTR f = XFRAME (event->frame_or_window); - Lisp_Object window; + struct frame *f = XFRAME (event->frame_or_window); Lisp_Object posn; Lisp_Object string_info = Qnil; int row, column; @@ -4705,14 +4802,14 @@ make_lispy_event (event) for (i = 0; i < XVECTOR (items)->size; i += 4) { Lisp_Object pos, string; - string = XVECTOR (items)->contents[i + 1]; - pos = XVECTOR (items)->contents[i + 3]; + string = AREF (items, i + 1); + pos = AREF (items, i + 3); if (NILP (string)) break; if (column >= XINT (pos) && column < XINT (pos) + XSTRING (string)->size) { - item = XVECTOR (items)->contents[i]; + item = AREF (items, i); break; } } @@ -4771,7 +4868,16 @@ make_lispy_event (event) else if (part == 2) posn = Qvertical_line; else - XSETINT (posn, buffer_posn_from_coords (w, &wx, &wy)); + { + Lisp_Object object; + struct display_pos p; + buffer_posn_from_coords (w, &wx, &wy, &object, &p); + posn = make_number (CHARPOS (p.pos)); + if (STRINGP (object)) + string_info + = Fcons (object, + make_number (CHARPOS (p.string_pos))); + } } position @@ -4787,7 +4893,6 @@ make_lispy_event (event) else { /* It's a scrollbar click. */ - Lisp_Object window; Lisp_Object portion_whole; Lisp_Object part; @@ -4804,26 +4909,46 @@ make_lispy_event (event) } #endif /* not USE_TOOLKIT_SCROLL_BARS */ - if (button >= XVECTOR (button_down_location)->size) + if (button >= ASIZE (button_down_location)) { button_down_location = larger_vector (button_down_location, button + 1, Qnil); mouse_syms = larger_vector (mouse_syms, button + 1, Qnil); } - start_pos_ptr = &XVECTOR (button_down_location)->contents[button]; - + start_pos_ptr = &AREF (button_down_location, button); start_pos = *start_pos_ptr; *start_pos_ptr = Qnil; - is_double = (button == last_mouse_button - && XINT (event->x) == last_mouse_x - && XINT (event->y) == last_mouse_y - && button_down_time != 0 - && (EQ (Vdouble_click_time, Qt) - || (INTEGERP (Vdouble_click_time) - && ((int)(event->timestamp - button_down_time) - < XINT (Vdouble_click_time))))); + { + /* On window-system frames, use the value of + double-click-fuzz as is. On other frames, interpret it + as a multiple of 1/8 characters. */ + struct frame *f; + int fuzz; + + if (WINDOWP (event->frame_or_window)) + f = XFRAME (XWINDOW (event->frame_or_window)->frame); + else if (FRAMEP (event->frame_or_window)) + f = XFRAME (event->frame_or_window); + else + abort (); + + if (FRAME_WINDOW_P (f)) + fuzz = double_click_fuzz; + else + fuzz = double_click_fuzz / 8; + + is_double = (button == last_mouse_button + && (abs (XINT (event->x) - last_mouse_x) <= fuzz) + && (abs (XINT (event->y) - last_mouse_y) <= fuzz) + && button_down_time != 0 + && (EQ (Vdouble_click_time, Qt) + || (INTEGERP (Vdouble_click_time) + && ((int)(event->timestamp - button_down_time) + < XINT (Vdouble_click_time))))); + } + last_mouse_button = button; last_mouse_x = XINT (event->x); last_mouse_y = XINT (event->y); @@ -4849,12 +4974,11 @@ make_lispy_event (event) see if this was a click or a drag. */ else if (event->modifiers & up_modifier) { - /* If we did not see a down before this up, - ignore the up. Probably this happened because - the down event chose a menu item. - It would be an annoyance to treat the release - of the button that chose the menu item - as a separate event. */ + /* If we did not see a down before this up, ignore the up. + Probably this happened because the down event chose a + menu item. It would be an annoyance to treat the + release of the button that chose the menu item as a + separate event. */ if (!CONSP (start_pos)) return Qnil; @@ -4866,21 +4990,30 @@ make_lispy_event (event) else #endif { - /* The third element of every position should be the (x,y) - pair. */ Lisp_Object down; + EMACS_INT xdiff = double_click_fuzz, ydiff = double_click_fuzz; - down = Fnth (make_number (2), start_pos); - if (EQ (event->x, XCAR (down)) - && EQ (event->y, XCDR (down))) + /* The third element of every position + should be the (x,y) pair. */ + down = Fcar (Fcdr (Fcdr (start_pos))); + if (CONSP (down) + && INTEGERP (XCAR (down)) && INTEGERP (XCDR (down))) { - event->modifiers |= click_modifier; + xdiff = XFASTINT (event->x) - XFASTINT (XCAR (down)); + ydiff = XFASTINT (event->y) - XFASTINT (XCDR (down)); } + + if (xdiff < double_click_fuzz && xdiff > - double_click_fuzz + && ydiff < double_click_fuzz + && ydiff > - double_click_fuzz) + /* Mouse hasn't moved (much). */ + event->modifiers |= click_modifier; else { button_down_time = 0; event->modifiers |= drag_modifier; } + /* Don't check is_double; treat this as multiple if the down-event was multiple. */ if (double_click_count > 1) @@ -5054,9 +5187,13 @@ make_lispy_event (event) else if (part == 3) posn = Qheader_line; else - XSETINT (posn, - buffer_posn_from_coords (XWINDOW (window), - &column, &row)); + { + Lisp_Object object; + struct display_pos p; + buffer_posn_from_coords (XWINDOW (window), &column, &row, + &object, &p); + posn = make_number (CHARPOS (p.pos)); + } } { @@ -5133,7 +5270,12 @@ make_lispy_event (event) else if (part == 3) posn = Qheader_line; else - XSETINT (posn, buffer_posn_from_coords (w, &wx, &wy)); + { + Lisp_Object object; + struct display_pos p; + buffer_posn_from_coords (w, &wx, &wy, &object, &p); + posn = make_number (CHARPOS (p.pos)); + } } { @@ -5245,7 +5387,12 @@ make_lispy_movement (frame, bar_window, part, x, y, time) else if (area == 3) posn = Qheader_line; else - XSETINT (posn, buffer_posn_from_coords (w, &wx, &wy)); + { + Lisp_Object object; + struct display_pos p; + buffer_posn_from_coords (w, &wx, &wy, &object, &p); + posn = make_number (CHARPOS (p.pos)); + } } else if (frame != 0) { @@ -5299,7 +5446,7 @@ parse_modifiers_uncached (symbol, modifier_end) int i; int modifiers; - CHECK_SYMBOL (symbol, 1); + CHECK_SYMBOL (symbol); modifiers = 0; name = XSYMBOL (symbol)->name; @@ -5483,7 +5630,7 @@ parse_modifiers (symbol) STRING_BYTES (XSYMBOL (symbol)->name) - end), Qnil); - if (modifiers & ~(((EMACS_INT)1 << VALBITS) - 1)) + if (modifiers & ~VALMASK) abort (); XSETFASTINT (mask, modifiers); elements = Fcons (unmodified, Fcons (mask, Qnil)); @@ -5520,7 +5667,7 @@ apply_modifiers (modifiers, base) Lisp_Object cache, index, entry, new_symbol; /* Mask out upper bits. We don't know where this value's been. */ - modifiers &= ((EMACS_INT)1 << VALBITS) - 1; + modifiers &= VALMASK; /* The click modifier never figures into cache indices. */ cache = Fget (base, Qmodifier_cache); @@ -5719,13 +5866,13 @@ modify_event_symbol (symbol_num, modifiers, symbol_kind, name_alist_or_stem, event type as a number or a symbol. */ DEFUN ("event-convert-list", Fevent_convert_list, Sevent_convert_list, 1, 1, 0, - "Convert the event description list EVENT-DESC to an event type.\n\ -EVENT-DESC should contain one base event type (a character or symbol)\n\ -and zero or more modifier names (control, meta, hyper, super, shift, alt,\n\ -drag, down, double or triple). The base must be last.\n\ -The return value is an event type (a character or symbol) which\n\ -has the same base event type and all the specified modifiers.") - (event_desc) + doc: /* Convert the event description list EVENT-DESC to an event type. +EVENT-DESC should contain one base event type (a character or symbol) +and zero or more modifier names (control, meta, hyper, super, shift, alt, +drag, down, double or triple). The base must be last. +The return value is an event type (a character or symbol) which +has the same base event type and all the specified modifiers. */) + (event_desc) Lisp_Object event_desc; { Lisp_Object base; @@ -6206,25 +6353,6 @@ reinvoke_input_signal () -/* Return the prompt-string of a sparse keymap. - This is the first element which is a string. - Return nil if there is none. */ - -Lisp_Object -map_prompt (map) - Lisp_Object map; -{ - while (CONSP (map)) - { - register Lisp_Object tem; - tem = Fcar (map); - if (STRINGP (tem)) - return tem; - map = Fcdr (map); - } - return Qnil; -} - static void menu_bar_item P_ ((Lisp_Object, Lisp_Object)); static void menu_bar_one_keymap P_ ((Lisp_Object)); @@ -6303,7 +6431,7 @@ menu_bar_items (old) { /* No, so use major and minor mode keymaps and keymap property. */ int extra_maps = 2; - Lisp_Object map = get_local_map (PT, current_buffer, keymap); + Lisp_Object map = get_local_map (PT, current_buffer, Qkeymap); if (!NILP (map)) extra_maps = 3; nmaps = current_minor_maps (NULL, &tmaps); @@ -6312,7 +6440,7 @@ menu_bar_items (old) bcopy (tmaps, maps, nmaps * sizeof (maps[0])); if (!NILP (map)) maps[nmaps++] = map; - maps[nmaps++] = get_local_map (PT, current_buffer, local_map); + maps[nmaps++] = get_local_map (PT, current_buffer, Qlocal_map); } maps[nmaps++] = current_global_map; } @@ -6741,19 +6869,19 @@ parse_menu_item (item, notreal, inmenubar) { /* We have to create a cachelist. */ CHECK_IMPURE (start); - XCDR (start) = Fcons (Fcons (Qnil, Qnil), XCDR (start)); + XSETCDR (start, Fcons (Fcons (Qnil, Qnil), XCDR (start))); cachelist = XCAR (XCDR (start)); newcache = 1; tem = AREF (item_properties, ITEM_PROPERTY_KEYEQ); if (!NILP (keyhint)) { - XCAR (cachelist) = XCAR (keyhint); + XSETCAR (cachelist, XCAR (keyhint)); newcache = 0; } else if (STRINGP (tem)) { - XCDR (cachelist) = Fsubstitute_command_keys (tem); - XCAR (cachelist) = Qt; + XSETCDR (cachelist, Fsubstitute_command_keys (tem)); + XSETCAR (cachelist, Qt); } } @@ -6811,10 +6939,10 @@ parse_menu_item (item, notreal, inmenubar) && ! NILP (Fget (def, Qmenu_alias))) def = XSYMBOL (def)->function; tem = Fwhere_is_internal (def, Qnil, Qt, Qnil); - XCAR (cachelist) = tem; + XSETCAR (cachelist, tem); if (NILP (tem)) { - XCDR (cachelist) = Qnil; + XSETCDR (cachelist, Qnil); chkcache = 0; } } @@ -6835,7 +6963,7 @@ parse_menu_item (item, notreal, inmenubar) if (STRINGP (XCDR (prefix))) tem = concat2 (tem, XCDR (prefix)); } - XCDR (cachelist) = tem; + XSETCDR (cachelist, tem); } } @@ -6843,7 +6971,7 @@ parse_menu_item (item, notreal, inmenubar) if (newcache && !NILP (tem)) { tem = concat3 (build_string (" ("), tem, build_string (")")); - XCDR (cachelist) = tem; + XSETCDR (cachelist, tem); } /* If we only want to precompute equivalent key bindings, stop here. */ @@ -6955,7 +7083,7 @@ tool_bar_items (reuse, nitems) { /* No, so use major and minor mode keymaps and keymap property. */ int extra_maps = 2; - Lisp_Object map = get_local_map (PT, current_buffer, keymap); + Lisp_Object map = get_local_map (PT, current_buffer, Qkeymap); if (!NILP (map)) extra_maps = 3; nmaps = current_minor_maps (NULL, &tmaps); @@ -6964,7 +7092,7 @@ tool_bar_items (reuse, nitems) bcopy (tmaps, maps, nmaps * sizeof (maps[0])); if (!NILP (map)) maps[nmaps++] = map; - maps[nmaps++] = get_local_map (PT, current_buffer, local_map); + maps[nmaps++] = get_local_map (PT, current_buffer, Qlocal_map); } /* Add global keymap at the end. */ @@ -7314,7 +7442,7 @@ read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu) /* Get the menu name from the first map that has one (a prompt string). */ for (mapno = 0; mapno < nmaps; mapno++) { - name = map_prompt (maps[mapno]); + name = Fkeymap_prompt (maps[mapno]); if (!NILP (name)) break; } @@ -7356,14 +7484,12 @@ read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu) to indicate that they came from a mouse menu, so that when present in last_nonmenu_event they won't confuse things. */ - for (tem = XCDR (value); !NILP (tem); - tem = XCDR (tem)) + for (tem = XCDR (value); !NILP (tem); tem = XCDR (tem)) { record_menu_key (XCAR (tem)); if (SYMBOLP (XCAR (tem)) || INTEGERP (XCAR (tem))) - XCAR (tem) - = Fcons (XCAR (tem), Qnil); + XSETCAR (tem, Fcons (XCAR (tem), Qdisabled)); } /* If we got more than one event, put all but the first @@ -7426,7 +7552,7 @@ read_char_minibuf_menu_prompt (commandflag, nmaps, maps) /* Get the menu name from the first map that has one (a prompt string). */ for (mapno = 0; mapno < nmaps; mapno++) { - name = map_prompt (maps[mapno]); + name = Fkeymap_prompt (maps[mapno]); if (!NILP (name)) break; } @@ -7733,6 +7859,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, int can_return_switch_frame; int fix_current_buffer; { + volatile Lisp_Object from_string; volatile int count = specpdl_ptr - specpdl; /* How many keys there are in the current key sequence. */ @@ -7824,6 +7951,9 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, volatile int function_key_possible = 0; volatile int key_translation_possible = 0; + /* List of events for which a fake prefix key has been generated. */ + volatile Lisp_Object fake_prefixed_keys = Qnil; + /* Save the status of key translation before each step, so that we can restore this after downcasing. */ Lisp_Object prev_fkey_map; @@ -7838,6 +7968,9 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, int junk; #endif + struct gcpro gcpro1; + + GCPRO1 (fake_prefixed_keys); raw_keybuf_count = 0; last_nonmenu_event = Qnil; @@ -7884,8 +8017,9 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, &junk); #endif /* GOBBLE_FIRST_EVENT */ - orig_local_map = get_local_map (PT, current_buffer, local_map); - orig_keymap = get_local_map (PT, current_buffer, keymap); + orig_local_map = get_local_map (PT, current_buffer, Qlocal_map); + orig_keymap = get_local_map (PT, current_buffer, Qkeymap); + from_string = Qnil; /* We jump here when the key sequence has been thoroughly changed, and we need to rescan it starting from the beginning. When we jump here, @@ -8054,8 +8188,8 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, interrupted_kboard->kbd_queue); } mock_input = 0; - orig_local_map = get_local_map (PT, current_buffer, local_map); - orig_keymap = get_local_map (PT, current_buffer, keymap); + orig_local_map = get_local_map (PT, current_buffer, Qlocal_map); + orig_keymap = get_local_map (PT, current_buffer, Qkeymap); goto replay_sequence; } #endif @@ -8069,6 +8203,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, if (EQ (key, Qt)) { unbind_to (count, Qnil); + UNGCPRO; return -1; } @@ -8101,23 +8236,25 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, Fset_buffer (XWINDOW (selected_window)->buffer); } - orig_local_map = get_local_map (PT, current_buffer, local_map); - orig_keymap = get_local_map (PT, current_buffer, keymap); + orig_local_map = get_local_map (PT, current_buffer, Qlocal_map); + orig_keymap = get_local_map (PT, current_buffer, Qkeymap); goto replay_sequence; } /* If we have a quit that was typed in another frame, and quit_throw_to_read_char switched buffers, replay to get the right keymap. */ - if (XINT (key) == quit_char && current_buffer != starting_buffer) + if (INTEGERP (key) + && XINT (key) == quit_char + && current_buffer != starting_buffer) { GROW_RAW_KEYBUF; XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = key; keybuf[t++] = key; mock_input = t; Vquit_flag = Qnil; - orig_local_map = get_local_map (PT, current_buffer, local_map); - orig_keymap = get_local_map (PT, current_buffer, keymap); + orig_local_map = get_local_map (PT, current_buffer, Qlocal_map); + orig_keymap = get_local_map (PT, current_buffer, Qkeymap); goto replay_sequence; } @@ -8166,10 +8303,12 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, window = POSN_WINDOW (EVENT_START (key)); posn = POSN_BUFFER_POSN (EVENT_START (key)); - if (CONSP (posn)) + if (CONSP (posn) + || (!NILP (fake_prefixed_keys) + && !NILP (Fmemq (key, fake_prefixed_keys)))) { - /* We're looking at the second event of a - sequence which we expanded before. Set + /* We're looking a second time at an event for which + we generated a fake prefix key. Set last_real_key_start appropriately. */ if (t > 0) last_real_key_start = t - 1; @@ -8202,12 +8341,10 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, if (! FRAME_LIVE_P (XFRAME (selected_frame))) Fkill_emacs (Qnil); - set_buffer_internal (XBUFFER (XWINDOW - (window)->buffer) -); + set_buffer_internal (XBUFFER (XWINDOW (window)->buffer)); orig_local_map = get_local_map (PT, current_buffer, - local_map); - orig_keymap = get_local_map (PT, current_buffer, keymap); + Qlocal_map); + orig_keymap = get_local_map (PT, current_buffer, Qkeymap); goto replay_sequence; } @@ -8229,7 +8366,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, && XINT (pos) >= BEG && XINT (pos) <= Z) { map_here = get_local_map (XINT (pos), - current_buffer, local_map); + current_buffer, Qlocal_map); if (!EQ (map_here, orig_local_map)) { orig_local_map = map_here; @@ -8239,7 +8376,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, goto replay_sequence; } map_here = get_local_map (XINT (pos), - current_buffer, keymap); + current_buffer, Qkeymap); if (!EQ (map_here, orig_keymap)) { orig_keymap = map_here; @@ -8254,18 +8391,22 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, /* Expand mode-line and scroll-bar events into two events: use posn as a fake prefix key. */ - if (SYMBOLP (posn)) + if (SYMBOLP (posn) + && (NILP (fake_prefixed_keys) + || NILP (Fmemq (key, fake_prefixed_keys)))) { if (t + 1 >= bufsize) error ("Key sequence too long"); - keybuf[t] = posn; - keybuf[t+1] = key; - mock_input = t + 2; - /* Zap the position in key, so we know that we've - expanded it, and don't try to do so again. */ - POSN_BUFFER_POSN (EVENT_START (key)) - = Fcons (posn, Qnil); + keybuf[t] = posn; + keybuf[t + 1] = key; + mock_input = t + 2; + + /* Record that a fake prefix key has been generated + for KEY. Don't modify the event; this would + prevent proper action when the event is pushed + back tino unread-command-events. */ + fake_prefixed_keys = Fcons (key, fake_prefixed_keys); /* If on a mode line string with a local keymap, reconsider the key sequence with that keymap. */ @@ -8292,6 +8433,35 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, goto replay_key; } + else if (CONSP (POSN_STRING (EVENT_START (key))) + && NILP (from_string)) + { + /* For a click on a string, i.e. overlay string or a + string displayed via the `display' property, + consider `local-map' and `keymap' properties of + that string. */ + Lisp_Object string, pos, map, map2; + + string = POSN_STRING (EVENT_START (key)); + pos = XCDR (string); + string = XCAR (string); + if (XINT (pos) >= 0 + && XINT (pos) < XSTRING (string)->size) + { + map = Fget_text_property (pos, Qlocal_map, string); + if (!NILP (map)) + orig_local_map = map; + map2 = Fget_text_property (pos, Qkeymap, string); + if (!NILP (map2)) + orig_keymap = map2; + + if (!NILP (map) || !NILP (map2)) + { + from_string = string; + goto replay_sequence; + } + } + } } else if (CONSP (XCDR (key)) && CONSP (EVENT_START (key)) @@ -8311,8 +8481,8 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, /* Zap the position in key, so we know that we've expanded it, and don't try to do so again. */ - POSN_BUFFER_POSN (EVENT_START (key)) - = Fcons (posn, Qnil); + POSN_BUFFER_SET_POSN (EVENT_START (key), + Fcons (posn, Qnil)); mock_input = t + 2; goto replay_sequence; @@ -8805,63 +8975,57 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, + UNGCPRO; return t; } -#if 0 /* This doc string is too long for some compilers. - This commented-out definition serves for DOC. */ -DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 4, 0, - "Read a sequence of keystrokes and return as a string or vector.\n\ -The sequence is sufficient to specify a non-prefix command in the\n\ -current local and global maps.\n\ -\n\ -First arg PROMPT is a prompt string. If nil, do not prompt specially.\n\ -Second (optional) arg CONTINUE-ECHO, if non-nil, means this key echos\n\ -as a continuation of the previous key.\n\ -\n\ -The third (optional) arg DONT-DOWNCASE-LAST, if non-nil, means do not\n\ -convert the last event to lower case. (Normally any upper case event\n\ -is converted to lower case if the original event is undefined and the lower\n\ -case equivalent is defined.) A non-nil value is appropriate for reading\n\ -a key sequence to be defined.\n\ -\n\ -A C-g typed while in this function is treated like any other character,\n\ -and `quit-flag' is not set.\n\ -\n\ -If the key sequence starts with a mouse click, then the sequence is read\n\ -using the keymaps of the buffer of the window clicked in, not the buffer\n\ -of the selected window as normal.\n\ -""\n\ -`read-key-sequence' drops unbound button-down events, since you normally\n\ -only care about the click or drag events which follow them. If a drag\n\ -or multi-click event is unbound, but the corresponding click event would\n\ -be bound, `read-key-sequence' turns the event into a click event at the\n\ -drag's starting position. This means that you don't have to distinguish\n\ -between click and drag, double, or triple events unless you want to.\n\ -\n\ -`read-key-sequence' prefixes mouse events on mode lines, the vertical\n\ -lines separating windows, and scroll bars with imaginary keys\n\ -`mode-line', `vertical-line', and `vertical-scroll-bar'.\n\ -\n\ -Optional fourth argument CAN-RETURN-SWITCH-FRAME non-nil means that this\n\ -function will process a switch-frame event if the user switches frames\n\ -before typing anything. If the user switches frames in the middle of a\n\ -key sequence, or at the start of the sequence but CAN-RETURN-SWITCH-FRAME\n\ -is nil, then the event will be put off until after the current key sequence.\n\ -\n\ -`read-key-sequence' checks `function-key-map' for function key\n\ -sequences, where they wouldn't conflict with ordinary bindings. See\n\ -`function-key-map' for more details.\n\ -\n\ -The optional fifth argument COMMAND-LOOP, if non-nil, means\n\ -that this key sequence is being read by something that will\n\ -read commands one after another. It should be nil if the caller\n\ -will read just one key sequence.") - (prompt, continue_echo, dont_downcase_last, can_return_switch_frame, command-loop) -#endif - DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 5, 0, - 0) + doc: /* Read a sequence of keystrokes and return as a string or vector. +The sequence is sufficient to specify a non-prefix command in the +current local and global maps. + +First arg PROMPT is a prompt string. If nil, do not prompt specially. +Second (optional) arg CONTINUE-ECHO, if non-nil, means this key echos +as a continuation of the previous key. + +The third (optional) arg DONT-DOWNCASE-LAST, if non-nil, means do not +convert the last event to lower case. (Normally any upper case event +is converted to lower case if the original event is undefined and the lower +case equivalent is defined.) A non-nil value is appropriate for reading +a key sequence to be defined. + +A C-g typed while in this function is treated like any other character, +and `quit-flag' is not set. + +If the key sequence starts with a mouse click, then the sequence is read +using the keymaps of the buffer of the window clicked in, not the buffer +of the selected window as normal. + +`read-key-sequence' drops unbound button-down events, since you normally +only care about the click or drag events which follow them. If a drag +or multi-click event is unbound, but the corresponding click event would +be bound, `read-key-sequence' turns the event into a click event at the +drag's starting position. This means that you don't have to distinguish +between click and drag, double, or triple events unless you want to. + +`read-key-sequence' prefixes mouse events on mode lines, the vertical +lines separating windows, and scroll bars with imaginary keys +`mode-line', `vertical-line', and `vertical-scroll-bar'. + +Optional fourth argument CAN-RETURN-SWITCH-FRAME non-nil means that this +function will process a switch-frame event if the user switches frames +before typing anything. If the user switches frames in the middle of a +key sequence, or at the start of the sequence but CAN-RETURN-SWITCH-FRAME +is nil, then the event will be put off until after the current key sequence. + +`read-key-sequence' checks `function-key-map' for function key +sequences, where they wouldn't conflict with ordinary bindings. See +`function-key-map' for more details. + +The optional fifth argument COMMAND-LOOP, if non-nil, means +that this key sequence is being read by something that will +read commands one after another. It should be nil if the caller +will read just one key sequence. */) (prompt, continue_echo, dont_downcase_last, can_return_switch_frame, command_loop) Lisp_Object prompt, continue_echo, dont_downcase_last; @@ -8873,7 +9037,7 @@ DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 5, 0, int count = specpdl_ptr - specpdl; if (!NILP (prompt)) - CHECK_STRING (prompt, 0); + CHECK_STRING (prompt); QUIT; specbind (Qinput_method_exit_on_first_char, @@ -8892,8 +9056,8 @@ DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 5, 0, } #ifdef HAVE_X_WINDOWS - if (display_busy_cursor_p) - cancel_busy_cursor (); + if (display_hourglass_p) + cancel_hourglass (); #endif i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])), @@ -8904,8 +9068,8 @@ DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 5, 0, then proceeding with a lenghty compuation, but it's not good for code reading keys in a loop, like an input method. */ #ifdef HAVE_X_WINDOWS - if (display_busy_cursor_p) - start_busy_cursor (); + if (display_hourglass_p) + start_hourglass (); #endif #endif @@ -8920,9 +9084,9 @@ DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 5, 0, DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector, Sread_key_sequence_vector, 1, 5, 0, - "Like `read-key-sequence' but always return a vector.") - /* Don't break the following line for documentation's sake. */ - (prompt, continue_echo, dont_downcase_last, can_return_switch_frame, command_loop) + doc: /* Like `read-key-sequence' but always return a vector. */) + (prompt, continue_echo, dont_downcase_last, can_return_switch_frame, + command_loop) Lisp_Object prompt, continue_echo, dont_downcase_last; Lisp_Object can_return_switch_frame, command_loop; { @@ -8932,7 +9096,7 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector, int count = specpdl_ptr - specpdl; if (!NILP (prompt)) - CHECK_STRING (prompt, 0); + CHECK_STRING (prompt); QUIT; specbind (Qinput_method_exit_on_first_char, @@ -8951,8 +9115,8 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector, } #ifdef HAVE_X_WINDOWS - if (display_busy_cursor_p) - cancel_busy_cursor (); + if (display_hourglass_p) + cancel_hourglass (); #endif i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])), @@ -8960,8 +9124,8 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector, ! NILP (can_return_switch_frame), 0); #ifdef HAVE_X_WINDOWS - if (display_busy_cursor_p) - start_busy_cursor (); + if (display_hourglass_p) + start_hourglass (); #endif if (i == -1) @@ -8974,15 +9138,15 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector, } DEFUN ("command-execute", Fcommand_execute, Scommand_execute, 1, 4, 0, - "Execute CMD as an editor command.\n\ -CMD must be a symbol that satisfies the `commandp' predicate.\n\ -Optional second arg RECORD-FLAG non-nil\n\ -means unconditionally put this command in `command-history'.\n\ -Otherwise, that is done only if an arg is read using the minibuffer.\n\ -The argument KEYS specifies the value to use instead of (this-command-keys)\n\ -when reading the arguments; if it is nil, (this-command-keys) is used.\n\ -The argument SPECIAL, if non-nil, means that this command is executing\n\ -a special event, so ignore the prefix argument and don't clear it.") + doc: /* Execute CMD as an editor command. +CMD must be a symbol that satisfies the `commandp' predicate. +Optional second arg RECORD-FLAG non-nil +means unconditionally put this command in `command-history'. +Otherwise, that is done only if an arg is read using the minibuffer. +The argument KEYS specifies the value to use instead of (this-command-keys) +when reading the arguments; if it is nil, (this-command-keys) is used. +The argument SPECIAL, if non-nil, means that this command is executing +a special event, so ignore the prefix argument and don't clear it. */) (cmd, record_flag, keys, special) Lisp_Object cmd, record_flag, keys, special; { @@ -9047,7 +9211,7 @@ a special event, so ignore the prefix argument and don't clear it.") { tem = Fnthcdr (Vhistory_length, Vcommand_history); if (CONSP (tem)) - XCDR (tem) = Qnil; + XSETCDR (tem, Qnil); } } @@ -9074,9 +9238,9 @@ a special event, so ignore the prefix argument and don't clear it.") DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_command, - 1, 1, "P", - "Read function name, then read its arguments and call it.") - (prefixarg) + 1, 1, "P", + doc: /* Read function name, then read its arguments and call it. */) + (prefixarg) Lisp_Object prefixarg; { Lisp_Object function; @@ -9249,7 +9413,7 @@ current_active_maps (maps_p) { /* No, so use major and minor mode keymaps and keymap property. */ int extra_maps = 2; - Lisp_Object map = get_local_map (PT, current_buffer, keymap); + Lisp_Object map = get_local_map (PT, current_buffer, Qkeymap); if (!NILP (map)) extra_maps = 3; nmaps = current_minor_maps (NULL, &tmaps); @@ -9258,7 +9422,7 @@ current_active_maps (maps_p) bcopy (tmaps, maps, nmaps * sizeof (maps[0])); if (!NILP (map)) maps[nmaps++] = map; - maps[nmaps++] = get_local_map (PT, current_buffer, local_map); + maps[nmaps++] = get_local_map (PT, current_buffer, Qlocal_map); } maps[nmaps++] = current_global_map; @@ -9290,7 +9454,7 @@ detect_input_pending_run_timers (do_display) if (old_timers_run != timers_run && do_display) { - redisplay_preserve_echo_area (); + redisplay_preserve_echo_area (8); /* The following fixes a bug when using lazy-lock with lazy-lock-defer-on-the-fly set to t, i.e. when fontifying from an idle timer function. The symptom of the bug is that @@ -9327,9 +9491,10 @@ requeued_events_pending_p () DEFUN ("input-pending-p", Finput_pending_p, Sinput_pending_p, 0, 0, 0, - "T if command input is currently available with no waiting.\n\ -Actually, the value is nil only if we can be sure that no input is available.") - () + doc: /* Return t if command input is currently available with no wait. +Actually, the value is nil only if we can be sure that no input is available; +if there is a doubt, the value is t. */) + () { if (!NILP (Vunread_command_events) || unread_command_char != -1) return (Qt); @@ -9339,8 +9504,8 @@ Actually, the value is nil only if we can be sure that no input is available.") } DEFUN ("recent-keys", Frecent_keys, Srecent_keys, 0, 0, 0, - "Return vector of last 100 events, not counting those from keyboard macros.") - () + doc: /* Return vector of last 100 events, not counting those from keyboard macros. */) + () { Lisp_Object *keys = XVECTOR (recent_keys)->contents; Lisp_Object val; @@ -9361,17 +9526,17 @@ DEFUN ("recent-keys", Frecent_keys, Srecent_keys, 0, 0, 0, } DEFUN ("this-command-keys", Fthis_command_keys, Sthis_command_keys, 0, 0, 0, - "Return the key sequence that invoked this command.\n\ -The value is a string or a vector.") - () + doc: /* Return the key sequence that invoked this command. +The value is a string or a vector. */) + () { return make_event_array (this_command_key_count, XVECTOR (this_command_keys)->contents); } DEFUN ("this-command-keys-vector", Fthis_command_keys_vector, Sthis_command_keys_vector, 0, 0, 0, - "Return the key sequence that invoked this command, as a vector.") - () + doc: /* Return the key sequence that invoked this command, as a vector. */) + () { return Fvector (this_command_key_count, XVECTOR (this_command_keys)->contents); @@ -9379,11 +9544,11 @@ DEFUN ("this-command-keys-vector", Fthis_command_keys_vector, Sthis_command_keys DEFUN ("this-single-command-keys", Fthis_single_command_keys, Sthis_single_command_keys, 0, 0, 0, - "Return the key sequence that invoked this command.\n\ -Unlike `this-command-keys', this function's value\n\ -does not include prefix arguments.\n\ -The value is always a vector.") - () + doc: /* Return the key sequence that invoked this command. +Unlike `this-command-keys', this function's value +does not include prefix arguments. +The value is always a vector. */) + () { return Fvector (this_command_key_count - this_single_command_key_start, @@ -9393,30 +9558,30 @@ The value is always a vector.") DEFUN ("this-single-command-raw-keys", Fthis_single_command_raw_keys, Sthis_single_command_raw_keys, 0, 0, 0, - "Return the raw events that were read for this command.\n\ -Unlike `this-single-command-keys', this function's value\n\ -shows the events before all translations (except for input methods).\n\ -The value is always a vector.") - () + doc: /* Return the raw events that were read for this command. +Unlike `this-single-command-keys', this function's value +shows the events before all translations (except for input methods). +The value is always a vector. */) + () { return Fvector (raw_keybuf_count, (XVECTOR (raw_keybuf)->contents)); } DEFUN ("reset-this-command-lengths", Freset_this_command_lengths, - Sreset_this_command_lengths, 0, 0, 0, - "Used for complicated reasons in `universal-argument-other-key'.\n\ -\n\ -`universal-argument-other-key' rereads the event just typed.\n\ -It then gets translated through `function-key-map'.\n\ -The translated event gets included in the echo area and in\n\ -the value of `this-command-keys' in addition to the raw original event.\n\ -That is not right.\n\ -\n\ -Calling this function directs the translated event to replace\n\ -the original event, so that only one version of the event actually\n\ -appears in the echo area and in the value of `this-command-keys.'.") - () + Sreset_this_command_lengths, 0, 0, 0, + doc: /* Used for complicated reasons in `universal-argument-other-key'. + +`universal-argument-other-key' rereads the event just typed. +It then gets translated through `function-key-map'. +The translated event gets included in the echo area and in +the value of `this-command-keys' in addition to the raw original event. +That is not right. + +Calling this function directs the translated event to replace +the original event, so that only one version of the event actually +appears in the echo area and in the value of `this-command-keys'. */) + () { before_command_restore_flag = 1; before_command_key_count_1 = before_command_key_count; @@ -9425,10 +9590,10 @@ appears in the echo area and in the value of `this-command-keys.'.") } DEFUN ("clear-this-command-keys", Fclear_this_command_keys, - Sclear_this_command_keys, 0, 0, 0, - "Clear out the vector that `this-command-keys' returns.\n\ -Clear vector containing last 100 events.") - () + Sclear_this_command_keys, 0, 0, 0, + doc: /* Clear out the vector that `this-command-keys' returns. +Clear vector containing last 100 events. */) + () { int i; @@ -9442,8 +9607,8 @@ Clear vector containing last 100 events.") } DEFUN ("recursion-depth", Frecursion_depth, Srecursion_depth, 0, 0, 0, - "Return the current depth in recursive edits.") - () + doc: /* Return the current depth in recursive edits. */) + () { Lisp_Object temp; XSETFASTINT (temp, command_loop_level + minibuf_level); @@ -9451,10 +9616,10 @@ DEFUN ("recursion-depth", Frecursion_depth, Srecursion_depth, 0, 0, 0, } DEFUN ("open-dribble-file", Fopen_dribble_file, Sopen_dribble_file, 1, 1, - "FOpen dribble file: ", - "Start writing all keyboard characters to a dribble file called FILE.\n\ -If FILE is nil, close any open dribble file.") - (file) + "FOpen dribble file: ", + doc: /* Start writing all keyboard characters to a dribble file called FILE. +If FILE is nil, close any open dribble file. */) + (file) Lisp_Object file; { if (dribble) @@ -9473,9 +9638,9 @@ If FILE is nil, close any open dribble file.") } DEFUN ("discard-input", Fdiscard_input, Sdiscard_input, 0, 0, 0, - "Discard the contents of the terminal input buffer.\n\ -Also cancel any kbd macro being defined.") - () + doc: /* Discard the contents of the terminal input buffer. +Also cancel any kbd macro being defined. */) + () { current_kboard->defining_kbd_macro = Qnil; update_mode_lines++; @@ -9493,18 +9658,19 @@ Also cancel any kbd macro being defined.") } DEFUN ("suspend-emacs", Fsuspend_emacs, Ssuspend_emacs, 0, 1, "", - "Stop Emacs and return to superior process. You can resume later.\n\ -If `cannot-suspend' is non-nil, or if the system doesn't support job\n\ -control, run a subshell instead.\n\n\ -If optional arg STUFFSTRING is non-nil, its characters are stuffed\n\ -to be read as terminal input by Emacs's parent, after suspension.\n\ -\n\ -Before suspending, run the normal hook `suspend-hook'.\n\ -After resumption run the normal hook `suspend-resume-hook'.\n\ -\n\ -Some operating systems cannot stop the Emacs process and resume it later.\n\ -On such systems, Emacs starts a subshell instead of suspending.") - (stuffstring) + doc: /* Stop Emacs and return to superior process. You can resume later. +If `cannot-suspend' is non-nil, or if the system doesn't support job +control, run a subshell instead. + +If optional arg STUFFSTRING is non-nil, its characters are stuffed +to be read as terminal input by Emacs's parent, after suspension. + +Before suspending, run the normal hook `suspend-hook'. +After resumption run the normal hook `suspend-resume-hook'. + +Some operating systems cannot stop the Emacs process and resume it later. +On such systems, Emacs starts a subshell instead of suspending. */) + (stuffstring) Lisp_Object stuffstring; { int count = specpdl_ptr - specpdl; @@ -9513,7 +9679,7 @@ On such systems, Emacs starts a subshell instead of suspending.") struct gcpro gcpro1; if (!NILP (stuffstring)) - CHECK_STRING (stuffstring, 0); + CHECK_STRING (stuffstring); /* Run the functions in suspend-hook. */ if (!NILP (Vrun_hooks)) @@ -9797,23 +9963,23 @@ quit_throw_to_read_char () if (FRAMEP (internal_last_event_frame) && !EQ (internal_last_event_frame, selected_frame)) do_switch_frame (make_lispy_switch_frame (internal_last_event_frame), - Qnil, 0); + 0, 0); _longjmp (getcjmp, 1); } DEFUN ("set-input-mode", Fset_input_mode, Sset_input_mode, 3, 4, 0, - "Set mode of reading keyboard input.\n\ -First arg INTERRUPT non-nil means use input interrupts;\n\ - nil means use CBREAK mode.\n\ -Second arg FLOW non-nil means use ^S/^Q flow control for output to terminal\n\ - (no effect except in CBREAK mode).\n\ -Third arg META t means accept 8-bit input (for a Meta key).\n\ - META nil means ignore the top bit, on the assumption it is parity.\n\ - Otherwise, accept 8-bit input and don't use the top bit for Meta.\n\ -Optional fourth arg QUIT if non-nil specifies character to use for quitting.\n\ -See also `current-input-mode'.") - (interrupt, flow, meta, quit) + doc: /* Set mode of reading keyboard input. +First arg INTERRUPT non-nil means use input interrupts; + nil means use CBREAK mode. +Second arg FLOW non-nil means use ^S/^Q flow control for output to terminal + (no effect except in CBREAK mode). +Third arg META t means accept 8-bit input (for a Meta key). + META nil means ignore the top bit, on the assumption it is parity. + Otherwise, accept 8-bit input and don't use the top bit for Meta. +Optional fourth arg QUIT if non-nil specifies character to use for quitting. +See also `current-input-mode'. */) + (interrupt, flow, meta, quit) Lisp_Object interrupt, flow, meta, quit; { if (!NILP (quit) @@ -9875,20 +10041,20 @@ See also `current-input-mode'.") } DEFUN ("current-input-mode", Fcurrent_input_mode, Scurrent_input_mode, 0, 0, 0, - "Return information about the way Emacs currently reads keyboard input.\n\ -The value is a list of the form (INTERRUPT FLOW META QUIT), where\n\ - INTERRUPT is non-nil if Emacs is using interrupt-driven input; if\n\ - nil, Emacs is using CBREAK mode.\n\ - FLOW is non-nil if Emacs uses ^S/^Q flow control for output to the\n\ - terminal; this does not apply if Emacs uses interrupt-driven input.\n\ - META is t if accepting 8-bit input with 8th bit as Meta flag.\n\ - META nil means ignoring the top bit, on the assumption it is parity.\n\ - META is neither t nor nil if accepting 8-bit input and using\n\ - all 8 bits as the character code.\n\ - QUIT is the character Emacs currently uses to quit.\n\ -The elements of this list correspond to the arguments of\n\ -`set-input-mode'.") - () + doc: /* Return information about the way Emacs currently reads keyboard input. +The value is a list of the form (INTERRUPT FLOW META QUIT), where + INTERRUPT is non-nil if Emacs is using interrupt-driven input; if + nil, Emacs is using CBREAK mode. + FLOW is non-nil if Emacs uses ^S/^Q flow control for output to the + terminal; this does not apply if Emacs uses interrupt-driven input. + META is t if accepting 8-bit input with 8th bit as Meta flag. + META nil means ignoring the top bit, on the assumption it is parity. + META is neither t nor nil if accepting 8-bit input and using + all 8 bits as the character code. + QUIT is the character Emacs currently uses to quit. +The elements of this list correspond to the arguments of +`set-input-mode'. */) + () { Lisp_Object val[4]; @@ -9942,19 +10108,35 @@ wipe_kboard (kb) } #ifdef MULTI_KBOARD + +/* Free KB and memory referenced from it. */ + void delete_kboard (kb) - KBOARD *kb; + KBOARD *kb; { KBOARD **kbp; + for (kbp = &all_kboards; *kbp != kb; kbp = &(*kbp)->next_kboard) if (*kbp == NULL) abort (); *kbp = kb->next_kboard; + + /* Prevent a dangling reference to KB. */ + if (kb == current_kboard + && FRAMEP (selected_frame) + && FRAME_LIVE_P (XFRAME (selected_frame))) + { + current_kboard = XFRAME (selected_frame)->kboard; + if (current_kboard == kb) + abort (); + } + wipe_kboard (kb); xfree (kb); } -#endif + +#endif /* MULTI_KBOARD */ void init_keyboard () @@ -10048,9 +10230,12 @@ struct event_head head_table[] = { void syms_of_keyboard () { + Vpre_help_message = Qnil; + staticpro (&Vpre_help_message); + Vlispy_mouse_stem = build_string ("mouse"); staticpro (&Vlispy_mouse_stem); - + /* Tool-bars. */ QCimage = intern (":image"); staticpro (&QCimage); @@ -10304,369 +10489,377 @@ syms_of_keyboard () defsubr (&Sexecute_extended_command); DEFVAR_LISP ("last-command-char", &last_command_char, - "Last input event that was part of a command."); + doc: /* Last input event that was part of a command. */); DEFVAR_LISP_NOPRO ("last-command-event", &last_command_char, - "Last input event that was part of a command."); + doc: /* Last input event that was part of a command. */); DEFVAR_LISP ("last-nonmenu-event", &last_nonmenu_event, - "Last input event in a command, except for mouse menu events.\n\ -Mouse menus give back keys that don't look like mouse events;\n\ -this variable holds the actual mouse event that led to the menu,\n\ -so that you can determine whether the command was run by mouse or not."); + doc: /* Last input event in a command, except for mouse menu events. +Mouse menus give back keys that don't look like mouse events; +this variable holds the actual mouse event that led to the menu, +so that you can determine whether the command was run by mouse or not. */); DEFVAR_LISP ("last-input-char", &last_input_char, - "Last input event."); + doc: /* Last input event. */); DEFVAR_LISP_NOPRO ("last-input-event", &last_input_char, - "Last input event."); + doc: /* Last input event. */); DEFVAR_LISP ("unread-command-events", &Vunread_command_events, - "List of events to be read as the command input.\n\ -These events are processed first, before actual keyboard input."); + doc: /* List of events to be read as the command input. +These events are processed first, before actual keyboard input. */); Vunread_command_events = Qnil; DEFVAR_INT ("unread-command-char", &unread_command_char, - "If not -1, an object to be read as next command input event."); + doc: /* If not -1, an object to be read as next command input event. */); DEFVAR_LISP ("unread-post-input-method-events", &Vunread_post_input_method_events, - "List of events to be processed as input by input methods.\n\ -These events are processed after `unread-command-events', but\n\ -before actual keyboard input."); + doc: /* List of events to be processed as input by input methods. +These events are processed after `unread-command-events', but +before actual keyboard input. */); Vunread_post_input_method_events = Qnil; DEFVAR_LISP ("unread-input-method-events", &Vunread_input_method_events, - "List of events to be processed as input by input methods.\n\ -These events are processed after `unread-command-events', but\n\ -before actual keyboard input."); + doc: /* List of events to be processed as input by input methods. +These events are processed after `unread-command-events', but +before actual keyboard input. */); Vunread_input_method_events = Qnil; DEFVAR_LISP ("meta-prefix-char", &meta_prefix_char, - "Meta-prefix character code.\n\ -Meta-foo as command input turns into this character followed by foo."); + doc: /* Meta-prefix character code. +Meta-foo as command input turns into this character followed by foo. */); XSETINT (meta_prefix_char, 033); DEFVAR_KBOARD ("last-command", Vlast_command, - "The last command executed.\n\ -Normally a symbol with a function definition, but can be whatever was found\n\ -in the keymap, or whatever the variable `this-command' was set to by that\n\ -command.\n\ -\n\ -The value `mode-exit' is special; it means that the previous command\n\ -read an event that told it to exit, and it did so and unread that event.\n\ -In other words, the present command is the event that made the previous\n\ -command exit.\n\ -\n\ -The value `kill-region' is special; it means that the previous command\n\ -was a kill command."); + doc: /* The last command executed. +Normally a symbol with a function definition, but can be whatever was found +in the keymap, or whatever the variable `this-command' was set to by that +command. + +The value `mode-exit' is special; it means that the previous command +read an event that told it to exit, and it did so and unread that event. +In other words, the present command is the event that made the previous +command exit. + +The value `kill-region' is special; it means that the previous command +was a kill command. */); DEFVAR_KBOARD ("real-last-command", Vreal_last_command, - "Same as `last-command', but never altered by Lisp code."); + doc: /* Same as `last-command', but never altered by Lisp code. */); DEFVAR_LISP ("this-command", &Vthis_command, - "The command now being executed.\n\ -The command can set this variable; whatever is put here\n\ -will be in `last-command' during the following command."); + doc: /* The command now being executed. +The command can set this variable; whatever is put here +will be in `last-command' during the following command. */); Vthis_command = Qnil; DEFVAR_INT ("auto-save-interval", &auto_save_interval, - "*Number of input events between auto-saves.\n\ -Zero means disable autosaving due to number of characters typed."); + doc: /* *Number of input events between auto-saves. +Zero means disable autosaving due to number of characters typed. */); auto_save_interval = 300; DEFVAR_LISP ("auto-save-timeout", &Vauto_save_timeout, - "*Number of seconds idle time before auto-save.\n\ -Zero or nil means disable auto-saving due to idleness.\n\ -After auto-saving due to this many seconds of idle time,\n\ -Emacs also does a garbage collection if that seems to be warranted."); + doc: /* *Number of seconds idle time before auto-save. +Zero or nil means disable auto-saving due to idleness. +After auto-saving due to this many seconds of idle time, +Emacs also does a garbage collection if that seems to be warranted. */); XSETFASTINT (Vauto_save_timeout, 30); DEFVAR_LISP ("echo-keystrokes", &Vecho_keystrokes, - "*Nonzero means echo unfinished commands after this many seconds of pause.\n\ -The value may be integer or floating point."); + doc: /* *Nonzero means echo unfinished commands after this many seconds of pause. +The value may be integer or floating point. */); Vecho_keystrokes = make_number (1); DEFVAR_INT ("polling-period", &polling_period, - "*Interval between polling for input during Lisp execution.\n\ -The reason for polling is to make C-g work to stop a running program.\n\ -Polling is needed only when using X windows and SIGIO does not work.\n\ -Polling is automatically disabled in all other cases."); + doc: /* *Interval between polling for input during Lisp execution. +The reason for polling is to make C-g work to stop a running program. +Polling is needed only when using X windows and SIGIO does not work. +Polling is automatically disabled in all other cases. */); polling_period = 2; DEFVAR_LISP ("double-click-time", &Vdouble_click_time, - "*Maximum time between mouse clicks to make a double-click.\n\ -Measured in milliseconds. nil means disable double-click recognition;\n\ -t means double-clicks have no time limit and are detected\n\ -by position only."); + doc: /* *Maximum time between mouse clicks to make a double-click. +Measured in milliseconds. nil means disable double-click recognition; +t means double-clicks have no time limit and are detected +by position only. */); Vdouble_click_time = make_number (500); + DEFVAR_INT ("double-click-fuzz", &double_click_fuzz, + doc: /* *Maximum mouse movement between clicks to make a double-click. +On window-system frames, value is the number of pixels the mouse may have +moved horizontally or vertically between two clicks to make a double-click. +On non window-system frames, value is interpreted in units of 1/8 characters +instead of pixels. */); + double_click_fuzz = 3; + DEFVAR_BOOL ("inhibit-local-menu-bar-menus", &inhibit_local_menu_bar_menus, - "*Non-nil means inhibit local map menu bar menus."); + doc: /* *Non-nil means inhibit local map menu bar menus. */); inhibit_local_menu_bar_menus = 0; DEFVAR_INT ("num-input-keys", &num_input_keys, - "Number of complete key sequences read as input so far.\n\ -This includes key sequences read from keyboard macros.\n\ -The number is effectively the number of interactive command invocations."); + doc: /* Number of complete key sequences read as input so far. +This includes key sequences read from keyboard macros. +The number is effectively the number of interactive command invocations. */); num_input_keys = 0; DEFVAR_INT ("num-nonmacro-input-events", &num_nonmacro_input_events, - "Number of input events read from the keyboard so far.\n\ -This does not include events generated by keyboard macros."); + doc: /* Number of input events read from the keyboard so far. +This does not include events generated by keyboard macros. */); num_nonmacro_input_events = 0; DEFVAR_LISP ("last-event-frame", &Vlast_event_frame, - "The frame in which the most recently read event occurred.\n\ -If the last event came from a keyboard macro, this is set to `macro'."); + doc: /* The frame in which the most recently read event occurred. +If the last event came from a keyboard macro, this is set to `macro'. */); Vlast_event_frame = Qnil; /* This variable is set up in sysdep.c. */ DEFVAR_LISP ("tty-erase-char", &Vtty_erase_char, - "The ERASE character as set by the user with stty."); + doc: /* The ERASE character as set by the user with stty. */); DEFVAR_LISP ("help-char", &Vhelp_char, - "Character to recognize as meaning Help.\n\ -When it is read, do `(eval help-form)', and display result if it's a string.\n\ -If the value of `help-form' is nil, this char can be read normally."); + doc: /* Character to recognize as meaning Help. +When it is read, do `(eval help-form)', and display result if it's a string. +If the value of `help-form' is nil, this char can be read normally. */); XSETINT (Vhelp_char, Ctl ('H')); DEFVAR_LISP ("help-event-list", &Vhelp_event_list, - "List of input events to recognize as meaning Help.\n\ -These work just like the value of `help-char' (see that)."); + doc: /* List of input events to recognize as meaning Help. +These work just like the value of `help-char' (see that). */); Vhelp_event_list = Qnil; DEFVAR_LISP ("help-form", &Vhelp_form, - "Form to execute when character `help-char' is read.\n\ -If the form returns a string, that string is displayed.\n\ -If `help-form' is nil, the help char is not recognized."); + doc: /* Form to execute when character `help-char' is read. +If the form returns a string, that string is displayed. +If `help-form' is nil, the help char is not recognized. */); Vhelp_form = Qnil; DEFVAR_LISP ("prefix-help-command", &Vprefix_help_command, - "Command to run when `help-char' character follows a prefix key.\n\ -This command is used only when there is no actual binding\n\ -for that character after that prefix key."); + doc: /* Command to run when `help-char' character follows a prefix key. +This command is used only when there is no actual binding +for that character after that prefix key. */); Vprefix_help_command = Qnil; DEFVAR_LISP ("top-level", &Vtop_level, - "Form to evaluate when Emacs starts up.\n\ -Useful to set before you dump a modified Emacs."); + doc: /* Form to evaluate when Emacs starts up. +Useful to set before you dump a modified Emacs. */); Vtop_level = Qnil; DEFVAR_LISP ("keyboard-translate-table", &Vkeyboard_translate_table, - "Translate table for keyboard input, or nil.\n\ -Each character is looked up in this string and the contents used instead.\n\ -The value may be a string, a vector, or a char-table.\n\ -If it is a string or vector of length N,\n\ -character codes N and up are untranslated.\n\ -In a vector or a char-table, an element which is nil means \"no translation\"."); + doc: /* Translate table for keyboard input, or nil. +Each character is looked up in this string and the contents used instead. +The value may be a string, a vector, or a char-table. +If it is a string or vector of length N, +character codes N and up are untranslated. +In a vector or a char-table, an element which is nil means "no translation". */); Vkeyboard_translate_table = Qnil; DEFVAR_BOOL ("cannot-suspend", &cannot_suspend, - "Non-nil means to always spawn a subshell instead of suspending.\n\ -\(Even if the operating system has support for stopping a process.\)"); + doc: /* Non-nil means to always spawn a subshell instead of suspending. +\(Even if the operating system has support for stopping a process.\) */); cannot_suspend = 0; DEFVAR_BOOL ("menu-prompting", &menu_prompting, - "Non-nil means prompt with menus when appropriate.\n\ -This is done when reading from a keymap that has a prompt string,\n\ -for elements that have prompt strings.\n\ -The menu is displayed on the screen\n\ -if X menus were enabled at configuration\n\ -time and the previous event was a mouse click prefix key.\n\ -Otherwise, menu prompting uses the echo area."); + doc: /* Non-nil means prompt with menus when appropriate. +This is done when reading from a keymap that has a prompt string, +for elements that have prompt strings. +The menu is displayed on the screen +if X menus were enabled at configuration +time and the previous event was a mouse click prefix key. +Otherwise, menu prompting uses the echo area. */); menu_prompting = 1; DEFVAR_LISP ("menu-prompt-more-char", &menu_prompt_more_char, - "Character to see next line of menu prompt.\n\ -Type this character while in a menu prompt to rotate around the lines of it."); + doc: /* Character to see next line of menu prompt. +Type this character while in a menu prompt to rotate around the lines of it. */); XSETINT (menu_prompt_more_char, ' '); DEFVAR_INT ("extra-keyboard-modifiers", &extra_keyboard_modifiers, - "A mask of additional modifier keys to use with every keyboard character.\n\ -Emacs applies the modifiers of the character stored here to each keyboard\n\ -character it reads. For example, after evaluating the expression\n\ - (setq extra-keyboard-modifiers ?\\C-x)\n\ -all input characters will have the control modifier applied to them.\n\ -\n\ -Note that the character ?\\C-@, equivalent to the integer zero, does\n\ -not count as a control character; rather, it counts as a character\n\ -with no modifiers; thus, setting `extra-keyboard-modifiers' to zero\n\ -cancels any modification."); + doc: /* A mask of additional modifier keys to use with every keyboard character. +Emacs applies the modifiers of the character stored here to each keyboard +character it reads. For example, after evaluating the expression + (setq extra-keyboard-modifiers ?\\C-x) +all input characters will have the control modifier applied to them. + +Note that the character ?\\C-@, equivalent to the integer zero, does +not count as a control character; rather, it counts as a character +with no modifiers; thus, setting `extra-keyboard-modifiers' to zero +cancels any modification. */); extra_keyboard_modifiers = 0; DEFVAR_LISP ("deactivate-mark", &Vdeactivate_mark, - "If an editing command sets this to t, deactivate the mark afterward.\n\ -The command loop sets this to nil before each command,\n\ -and tests the value when the command returns.\n\ -Buffer modification stores t in this variable."); + doc: /* If an editing command sets this to t, deactivate the mark afterward. +The command loop sets this to nil before each command, +and tests the value when the command returns. +Buffer modification stores t in this variable. */); Vdeactivate_mark = Qnil; DEFVAR_LISP ("command-hook-internal", &Vcommand_hook_internal, - "Temporary storage of pre-command-hook or post-command-hook."); + doc: /* Temporary storage of pre-command-hook or post-command-hook. */); Vcommand_hook_internal = Qnil; DEFVAR_LISP ("pre-command-hook", &Vpre_command_hook, - "Normal hook run before each command is executed.\n\ -If an unhandled error happens in running this hook,\n\ -the hook value is set to nil, since otherwise the error\n\ -might happen repeatedly and make Emacs nonfunctional."); + doc: /* Normal hook run before each command is executed. +If an unhandled error happens in running this hook, +the hook value is set to nil, since otherwise the error +might happen repeatedly and make Emacs nonfunctional. */); Vpre_command_hook = Qnil; DEFVAR_LISP ("post-command-hook", &Vpost_command_hook, - "Normal hook run after each command is executed.\n\ -If an unhandled error happens in running this hook,\n\ -the hook value is set to nil, since otherwise the error\n\ -might happen repeatedly and make Emacs nonfunctional."); + doc: /* Normal hook run after each command is executed. +If an unhandled error happens in running this hook, +the hook value is set to nil, since otherwise the error +might happen repeatedly and make Emacs nonfunctional. */); Vpost_command_hook = Qnil; DEFVAR_LISP ("post-command-idle-hook", &Vpost_command_idle_hook, - "Normal hook run after each command is executed, if idle.\n\ -Errors running the hook are caught and ignored.\n\ -This feature is obsolete; use idle timers instead. See `etc/NEWS'."); + doc: /* Normal hook run after each command is executed, if idle. +Errors running the hook are caught and ignored. +This feature is obsolete; use idle timers instead. See `etc/NEWS'. */); Vpost_command_idle_hook = Qnil; DEFVAR_INT ("post-command-idle-delay", &post_command_idle_delay, - "Delay time before running `post-command-idle-hook'.\n\ -This is measured in microseconds."); + doc: /* Delay time before running `post-command-idle-hook'. +This is measured in microseconds. */); post_command_idle_delay = 100000; #if 0 DEFVAR_LISP ("echo-area-clear-hook", ..., - "Normal hook run when clearing the echo area."); + doc: /* Normal hook run when clearing the echo area. */); #endif Qecho_area_clear_hook = intern ("echo-area-clear-hook"); - XSYMBOL (Qecho_area_clear_hook)->value = Qnil; + SET_SYMBOL_VALUE (Qecho_area_clear_hook, Qnil); DEFVAR_LISP ("lucid-menu-bar-dirty-flag", &Vlucid_menu_bar_dirty_flag, - "t means menu bar, specified Lucid style, needs to be recomputed."); + doc: /* Non-nil means menu bar, specified Lucid style, needs to be recomputed. */); Vlucid_menu_bar_dirty_flag = Qnil; DEFVAR_LISP ("menu-bar-final-items", &Vmenu_bar_final_items, - "List of menu bar items to move to the end of the menu bar.\n\ -The elements of the list are event types that may have menu bar bindings."); + doc: /* List of menu bar items to move to the end of the menu bar. +The elements of the list are event types that may have menu bar bindings. */); Vmenu_bar_final_items = Qnil; DEFVAR_KBOARD ("overriding-terminal-local-map", Voverriding_terminal_local_map, - "Per-terminal keymap that overrides all other local keymaps.\n\ -If this variable is non-nil, it is used as a keymap instead of the\n\ -buffer's local map, and the minor mode keymaps and text property keymaps.\n\ -This variable is intended to let commands such as `universal-argumemnt'\n\ -set up a different keymap for reading the next command."); + doc: /* Per-terminal keymap that overrides all other local keymaps. +If this variable is non-nil, it is used as a keymap instead of the +buffer's local map, and the minor mode keymaps and text property keymaps. +This variable is intended to let commands such as `universal-argument' +set up a different keymap for reading the next command. */); DEFVAR_LISP ("overriding-local-map", &Voverriding_local_map, - "Keymap that overrides all other local keymaps.\n\ -If this variable is non-nil, it is used as a keymap instead of the\n\ -buffer's local map, and the minor mode keymaps and text property keymaps."); + doc: /* Keymap that overrides all other local keymaps. +If this variable is non-nil, it is used as a keymap instead of the +buffer's local map, and the minor mode keymaps and text property keymaps. */); Voverriding_local_map = Qnil; DEFVAR_LISP ("overriding-local-map-menu-flag", &Voverriding_local_map_menu_flag, - "Non-nil means `overriding-local-map' applies to the menu bar.\n\ -Otherwise, the menu bar continues to reflect the buffer's local map\n\ -and the minor mode maps regardless of `overriding-local-map'."); + doc: /* Non-nil means `overriding-local-map' applies to the menu bar. +Otherwise, the menu bar continues to reflect the buffer's local map +and the minor mode maps regardless of `overriding-local-map'. */); Voverriding_local_map_menu_flag = Qnil; DEFVAR_LISP ("special-event-map", &Vspecial_event_map, - "Keymap defining bindings for special events to execute at low level."); + doc: /* Keymap defining bindings for special events to execute at low level. */); Vspecial_event_map = Fcons (intern ("keymap"), Qnil); DEFVAR_LISP ("track-mouse", &do_mouse_tracking, - "*Non-nil means generate motion events for mouse motion."); + doc: /* *Non-nil means generate motion events for mouse motion. */); DEFVAR_KBOARD ("system-key-alist", Vsystem_key_alist, - "Alist of system-specific X windows key symbols.\n\ -Each element should have the form (N . SYMBOL) where N is the\n\ -numeric keysym code (sans the \"system-specific\" bit 1<<28)\n\ -and SYMBOL is its name."); + doc: /* Alist of system-specific X windows key symbols. +Each element should have the form (N . SYMBOL) where N is the +numeric keysym code (sans the \"system-specific\" bit 1<<28) +and SYMBOL is its name. */); DEFVAR_LISP ("deferred-action-list", &Vdeferred_action_list, - "List of deferred actions to be performed at a later time.\n\ -The precise format isn't relevant here; we just check whether it is nil."); + doc: /* List of deferred actions to be performed at a later time. +The precise format isn't relevant here; we just check whether it is nil. */); Vdeferred_action_list = Qnil; DEFVAR_LISP ("deferred-action-function", &Vdeferred_action_function, - "Function to call to handle deferred actions, after each command.\n\ -This function is called with no arguments after each command\n\ -whenever `deferred-action-list' is non-nil."); + doc: /* Function to call to handle deferred actions, after each command. +This function is called with no arguments after each command +whenever `deferred-action-list' is non-nil. */); Vdeferred_action_function = Qnil; DEFVAR_LISP ("suggest-key-bindings", &Vsuggest_key_bindings, - "*Non-nil means show the equivalent key-binding when M-x command has one.\n\ -The value can be a length of time to show the message for.\n\ -If the value is non-nil and not a number, we wait 2 seconds."); + doc: /* *Non-nil means show the equivalent key-binding when M-x command has one. +The value can be a length of time to show the message for. +If the value is non-nil and not a number, we wait 2 seconds. */); Vsuggest_key_bindings = Qt; DEFVAR_LISP ("timer-list", &Vtimer_list, - "List of active absolute time timers in order of increasing time"); + doc: /* List of active absolute time timers in order of increasing time. */); Vtimer_list = Qnil; DEFVAR_LISP ("timer-idle-list", &Vtimer_idle_list, - "List of active idle-time timers in order of increasing time"); + doc: /* List of active idle-time timers in order of increasing time. */); Vtimer_idle_list = Qnil; DEFVAR_LISP ("input-method-function", &Vinput_method_function, - "If non-nil, the function that implements the current input method.\n\ -It's called with one argument, a printing character that was just read.\n\ -\(That means a character with code 040...0176.)\n\ -Typically this function uses `read-event' to read additional events.\n\ -When it does so, it should first bind `input-method-function' to nil\n\ -so it will not be called recursively.\n\ -\n\ -The function should return a list of zero or more events\n\ -to be used as input. If it wants to put back some events\n\ -to be reconsidered, separately, by the input method,\n\ -it can add them to the beginning of `unread-command-events'.\n\ -\n\ -The input method function can find in `input-method-previous-method'\n\ -the previous echo area message.\n\ -\n\ -The input method function should refer to the variables\n\ -`input-method-use-echo-area' and `input-method-exit-on-first-char'\n\ -for guidance on what to do."); + doc: /* If non-nil, the function that implements the current input method. +It's called with one argument, a printing character that was just read. +\(That means a character with code 040...0176.) +Typically this function uses `read-event' to read additional events. +When it does so, it should first bind `input-method-function' to nil +so it will not be called recursively. + +The function should return a list of zero or more events +to be used as input. If it wants to put back some events +to be reconsidered, separately, by the input method, +it can add them to the beginning of `unread-command-events'. + +The input method function can find in `input-method-previous-method' +the previous echo area message. + +The input method function should refer to the variables +`input-method-use-echo-area' and `input-method-exit-on-first-char' +for guidance on what to do. */); Vinput_method_function = Qnil; DEFVAR_LISP ("input-method-previous-message", &Vinput_method_previous_message, - "When `input-method-function' is called, hold the previous echo area message.\n\ -This variable exists because `read-event' clears the echo area\n\ -before running the input method. It is nil if there was no message."); + doc: /* When `input-method-function' is called, hold the previous echo area message. +This variable exists because `read-event' clears the echo area +before running the input method. It is nil if there was no message. */); Vinput_method_previous_message = Qnil; DEFVAR_LISP ("show-help-function", &Vshow_help_function, - "If non-nil, the function that implements the display of help.\n\ -It's called with one argument, the help string to display."); + doc: /* If non-nil, the function that implements the display of help. +It's called with one argument, the help string to display. */); Vshow_help_function = Qnil; DEFVAR_LISP ("disable-point-adjustment", &Vdisable_point_adjustment, - "If non-nil, suppress point adjustment after executing a command.\n\ -\n\ -After a command is executed, if point is moved into a region that has\n\ -special properties (e.g. composition, display), we adjust point to\n\ -the boundary of the region. But, several special commands sets this\n\ -variable to non-nil, then we suppress the point adjustment.\n\ -\n\ -This variable is set to nil before reading a command, and is checked\n\ -just after executing the command"); + doc: /* If non-nil, suppress point adjustment after executing a command. + +After a command is executed, if point is moved into a region that has +special properties (e.g. composition, display), we adjust point to +the boundary of the region. But, several special commands sets this +variable to non-nil, then we suppress the point adjustment. + +This variable is set to nil before reading a command, and is checked +just after executing the command. */); Vdisable_point_adjustment = Qnil; DEFVAR_LISP ("global-disable-point-adjustment", &Vglobal_disable_point_adjustment, - "*If non-nil, always suppress point adjustment.\n\ -\n\ -The default value is nil, in which case, point adjustment are\n\ -suppressed only after special commands that set\n\ -`disable-point-adjustment' (which see) to non-nil."); + doc: /* *If non-nil, always suppress point adjustment. + +The default value is nil, in which case, point adjustment are +suppressed only after special commands that set +`disable-point-adjustment' (which see) to non-nil. */); Vglobal_disable_point_adjustment = Qnil; DEFVAR_BOOL ("update-menu-bindings", &update_menu_bindings, - "Non-nil means updating menu bindings is allowed.\n\ -A value of nil means menu bindings should not be updated.\n\ -Used during Emacs' startup."); + doc: /* Non-nil means updating menu bindings is allowed. +A value of nil means menu bindings should not be updated. +Used during Emacs' startup. */); update_menu_bindings = 1; DEFVAR_LISP ("minibuffer-message-timeout", &Vminibuffer_message_timeout, - "*How long to display an echo-area message when the minibuffer is active.\n\ -If the value is not a number, such messages don't time out."); + doc: /* *How long to display an echo-area message when the minibuffer is active. +If the value is not a number, such messages don't time out. */); Vminibuffer_message_timeout = make_number (2); }