📄 keyboard.c
字号:
(){ if (command_loop_level > 0 || minibuf_level > 0) Fthrow (Qexit, Qnil); error ("No recursive edit is in progress");}DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0, 0, "", "Abort the command that requested this recursive edit or minibuffer input.") (){ if (command_loop_level > 0 || minibuf_level > 0) Fthrow (Qexit, Qt); error ("No recursive edit is in progress");}/* This is the actual command reading loop, sans error-handling encapsulation */Lisp_Object Fcommand_execute ();Lisp_Objectcommand_loop_1 (){ Lisp_Object cmd; int lose; int nonundocount; char keybuf[30]; int i; int no_redisplay; int no_direct; Vprefix_arg = Qnil; waiting_for_input = 0; cancel_echoing (); last_command = Qt; nonundocount = 0; no_redisplay = 0; this_command_key_count = 0; while (1) { /* Install chars successfully executed in kbd macro */ if (defining_kbd_macro && NULL (Vprefix_arg)) finalize_kbd_macro_chars (); /* Make sure current window's buffer is selected. */ if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer) set_buffer_internal (XBUFFER (XWINDOW (selected_window)->buffer)); /* Display any malloc warning that just came out. Use while because displaying one warning can cause another. */ while (pending_malloc_warning) display_malloc_warning (); no_direct = 0; /* If minibuffer on and echo area in use, wait 2 sec and redraw minibufer. */ if (minibuf_level && echo_area_contents) { int count = specpdl_ptr - specpdl; specbind (Qinhibit_quit, Qt); Fsit_for (make_number (2), Qnil); unbind_to (count); echo_area_contents = 0; no_direct = 1; if (!NULL (Vquit_flag)) { Vquit_flag = Qnil; unread_command_char = quit_char; } } i = 0;#if 0 /* If prev. command was directly displayed, we don't need redisplay. Try shortcut for reading single-char key sequence. */ if (no_redisplay) i = fast_read_one_key (keybuf);#endif /* 0 */ /* Shortcut not applicable or found a prefix key. Take full precautions and read key sequence the hard way. */ if (i == 0) {#ifdef C_ALLOCA alloca (0); /* Cause a garbage collection now */ /* Since we can free the most stuff here. */#endif /* C_ALLOCA */ /* Read next key sequence; i gets its length. */ i = read_key_sequence (keybuf, sizeof keybuf, 0, no_redisplay && buffer_shared <= 1); } /* Now we have read a key sequence of length I, or else I is 0 and we found end of file. */ if (i == 0) /* End of file -- happens only in */ return Qnil; /* a kbd macro, at the end */ last_command_char = keybuf[i - 1]; cmd = read_key_sequence_cmd; if (!NULL (Vexecuting_macro)) { if (!NULL (Vquit_flag)) { Vexecuting_macro = Qt; QUIT; /* Make some noise. */ /* Will return since macro now empty. */ } } /* Do redisplay processing after this command except in special cases identified below that set no_redisplay to 1. */ no_redisplay = 0; /* Execute the command. */ if (NULL (cmd)) { /* nil means key is undefined. */ bell (); defining_kbd_macro = 0; update_mode_lines++; Vprefix_arg = Qnil; } else { this_command = cmd; if (NULL (Vprefix_arg) && ! no_direct) { if (EQ (cmd, Qforward_char) && point < ZV) { lose = FETCH_CHAR (point); SET_PT (point + 1); if (lose >= ' ' && lose < 0177 && (XFASTINT (XWINDOW (selected_window)->last_modified) >= MODIFF) && (XFASTINT (XWINDOW (selected_window)->last_point) == point) && !windows_or_buffers_changed && EQ (current_buffer->selective_display, Qnil) && !detect_input_pending () && NULL (Vexecuting_macro)) no_redisplay = direct_output_forward_char (1); goto directly_done; } else if (EQ (cmd, Qbackward_char) && point > BEGV) { SET_PT (point - 1); lose = FETCH_CHAR (point); if (lose >= ' ' && lose < 0177 && (XFASTINT (XWINDOW (selected_window)->last_modified) >= MODIFF) && (XFASTINT (XWINDOW (selected_window)->last_point) == point) && !windows_or_buffers_changed && EQ (current_buffer->selective_display, Qnil) && !detect_input_pending () && NULL (Vexecuting_macro)) no_redisplay = direct_output_forward_char (-1); goto directly_done; } else if (EQ (cmd, Qself_insert_command)) { if (NULL (Vexecuting_macro) && !EQ (minibuf_window, selected_window)) { if (!nonundocount || nonundocount >= 20) { Fundo_boundary (); nonundocount = 0; } nonundocount++; } lose = (XFASTINT (XWINDOW (selected_window)->last_modified) < MODIFF) || (XFASTINT (XWINDOW (selected_window)->last_point) != point) || MODIFF <= current_buffer->save_modified || windows_or_buffers_changed || !EQ (current_buffer->selective_display, Qnil) || detect_input_pending () || !NULL (Vexecuting_macro); if (self_insert_internal (last_command_char, 0)) { lose = 1; nonundocount = 0; } if (!lose && (point == ZV || FETCH_CHAR (point) == '\n') && last_command_char >= ' ' && last_command_char < 0177) no_redisplay = direct_output_for_insert (last_command_char); goto directly_done; } } /* Here for a command that isn't executed directly */ nonundocount = 0; if (NULL (Vprefix_arg)) Fundo_boundary (); Fcommand_execute (cmd, Qnil); directly_done: ; } if (NULL (Vprefix_arg)) { last_command = this_command; this_command_key_count = 0; cancel_echoing (); } }}/* Input of single characters from keyboard */Lisp_Object print_help ();int echo_flag;int echo_now;/* Alarm interrupt calls this and requests echoing at earliest safe time. */request_echo (){ int old_errno = errno; /* Note: no need to reestablish handler on USG systems because it is established, if approriate, each time an alarm is requested. */#ifdef subprocesses#ifdef BSD4_1 extern int select_alarmed; if (select_alarmed == 0) { select_alarmed = 1; sigrelse (SIGALRM); return; }#endif#endif#ifdef BSD4_1 sigisheld (SIGALRM);#endif if (echo_now) echo (); else echo_flag = 1;#ifdef BSD4_1 sigunhold (SIGALRM);#endif errno = old_errno;}/* Nonzero means polling for input is temporarily suppresed. */int poll_suppress_count;/* Number of seconds between polling for input. */int polling_period;#ifdef POLL_FOR_INPUTint polling_for_input;/* Handle an alarm once each second and read pending input so as to handle a C-g if it comces in. */input_poll_signal (){ int junk; if (!waiting_for_input) read_avail_input (&junk); signal (SIGALRM, input_poll_signal); alarm (polling_period);}#endif/* Begin signals to poll for input, if they are appropriate. This function is called unconditionally from various places. */start_polling (){#ifdef POLL_FOR_INPUT if (read_socket_hook) { poll_suppress_count--; if (poll_suppress_count == 0) { signal (SIGALRM, input_poll_signal); polling_for_input = 1; alarm (polling_period); } }#endif}/* Turn off polling. */stop_polling (){#ifdef POLL_FOR_INPUT if (read_socket_hook) { if (poll_suppress_count == 0) { polling_for_input = 0; alarm (0); } poll_suppress_count++; }#endif}/* read a character from the keyboard; call the redisplay if needed *//* commandflag 0 means do not do auto-saving, but do do redisplay. -1 means do not do redisplay, but do do autosaving. 1 means do both. */read_command_char (commandflag) int commandflag;{ register int c; int alarmtime; int count; Lisp_Object tem; jmp_buf save_jump; extern request_echo (); if (unread_command_char >= 0) { c = unread_command_char; unread_command_char = -1; if (this_command_key_count == 0) goto reread_first; goto reread; } if (!NULL (Vexecuting_macro)) { if (XTYPE (Vexecuting_macro) != Lisp_String || XSTRING (Vexecuting_macro)->size <= executing_macro_index) return -1; QUIT; c = XSTRING (Vexecuting_macro)->data[executing_macro_index++]; goto from_macro; } /* Save outer setjmp data, in case called recursively. */ bcopy (getcjmp, save_jump, sizeof getcjmp); stop_polling (); if (commandflag >= 0 && !detect_input_pending ()) redisplay (); if (commandflag != 0 && auto_save_interval > 0 && num_input_chars - last_auto_save > max (auto_save_interval, 20) && !detect_input_pending ()) Fdo_auto_save (Qnil); if (_setjmp (getcjmp)) { c = quit_char; waiting_for_input = 0; input_available_clear_word = 0; goto non_reread; } /* Message turns off echoing unless more keystrokes turn it on again. */ if (echo_area_contents && *echo_area_contents && echo_area_contents != echobuf) cancel_echoing (); else /* If already echoing, continue, and prompt. */ echo_dash (); /* If in middle of key sequence and minibuffer not active, start echoing if enough time elapses. */ if (minibuf_level == 0 && !immediate_echo && this_command_key_count > 0 && echo_keystrokes > 0 && (echo_area_contents == 0 || *echo_area_contents == 0)) { /* Else start echoing if user waits more than `alarmtime' seconds. */ /* This interrupt either calls echo right away or sets echo_flag, which causes echo to be called by set_waiting_for_input's next invocation. */ signal (SIGALRM, request_echo); echo_flag = 0; echo_now = 0; alarmtime = echo_keystrokes; alarm ((unsigned) alarmtime); } c = kbd_buffer_read_command_char (); non_reread: bcopy (save_jump, getcjmp, sizeof getcjmp); /* Cancel alarm if it was set and has not already gone off. */ if (alarmtime > 0) alarm (0); echo_area_contents = 0; if (c < 0) return -1; c &= meta_key ? 0377 : 0177; if (XTYPE (Vkeyboard_translate_table) == Lisp_String && XSTRING (Vkeyboard_translate_table)->size > c) c = XSTRING (Vkeyboard_translate_table)->data[c]; total_keys++; recent_keys[recent_keys_index] = c; recent_keys_index = (recent_keys_index + 1) % sizeof recent_keys; if (dribble) { putc (c, dribble); fflush (dribble); } store_kbd_macro_char (c); start_polling (); from_macro: reread_first: /* Rereading a char and it is the first in a command. */ echo_char (c); /* Record this character as part of the current key. */ if (this_command_key_count == this_command_keys_size) { this_command_keys_size *= 2; this_command_keys = (char *) xrealloc (this_command_keys, this_command_keys_size); } this_command_keys[this_command_key_count++] = c; /* Rereading in the middle of a command. */ reread: last_input_char = c; num_input_chars++; /* Process the help character specially if enabled */ if (c == help_char && !NULL (Vhelp_form)) { count = specpdl_ptr - specpdl; record_unwind_protect (Fset_window_configuration, Fcurrent_window_configuration ()); tem = Feval (Vhelp_form); if (XTYPE (tem) == Lisp_String) internal_with_output_to_temp_buffer ("*Help*", print_help, tem); cancel_echoing (); c = read_command_char (0); /* Remove the help from the screen */ unbind_to (count); redisplay (); if (c == 040) { cancel_echoing (); c = read_command_char (0); } } return c;}Lisp_Objectprint_help (object) Lisp_Object object;{ Fprinc (object, Qnil); return Qnil;}/* Low level keyboard input. Read characters into kbd_buffer from which they are obtained by kbd_buffer_read_command_char. *//* Set this for debugging, to have a way to get out */int stop_character;/* Store a character obtained at interrupt level into kbd_buffer, fifo */kbd_buffer_store_char (c) register int c;{ c &= 0377; if (c == quit_char || ((c == (0200 | quit_char)) && !meta_key)) { interrupt_signal (); return; } if (c && c == stop_character) { sys_suspend (); return; } if (kbd_ptr != kbd_buffer) { bcopy (kbd_ptr, kbd_buffer, kbd_count); kbd_ptr = kbd_buffer; } if (kbd_count < sizeof kbd_buffer) { kbd_buffer[kbd_count++] = c; }}kbd_buffer_read_command_char (){ register int c; if (noninteractive) { c = getchar (); return c; } /* Either ordinary input buffer or C-g buffered means we can return. */ while (!kbd_count) { if (!NULL (Vquit_flag)) quit_throw_to_read_command_char (); /* One way or another, wait until input is available; then, if interrupt handlers have not read it, read it now. */#ifdef VMS wait_for_kbd_input ();#else/* Note SIGIO has been undef'd if FIONREAD is missing. */#ifdef SIGIO gobble_input ();#endif /* SIGIO */ if (!kbd_count) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -