1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-24 14:30:43 -08:00

Merge from origin/emacs-26

7296b6f Improve cl-do, cl-do* docstrings
d416109 Avoid returning early in 'while-no-input' due to subprocesses
e8a4d94 Cleanup when opening a new terminal fails. (Bug#32794)

# Conflicts:
#	etc/NEWS
This commit is contained in:
Glenn Morris 2018-10-03 09:23:16 -07:00
commit 48adb87bcb
7 changed files with 61 additions and 4 deletions

View file

@ -110,6 +110,16 @@ be removed prior using the changed 'shadow-*' commands.
The old name is an alias of the new name. Future Emacs version will The old name is an alias of the new name. Future Emacs version will
obsolete it. obsolete it.
---
** 'while-no-input' does not return due to input from subprocesses.
Input that arrived from subprocesses while some code executed inside
the 'while-no-input' form injected an internal buffer-switch event
that counted as input and would cause 'while-no-input' to return,
perhaps prematurely. These buffer-switch events are now by default
ignored by 'while-no-input'; if you need to get the old behavior,
remove 'buffer-switch' from the list of events in
'while-no-input-ignore-events'.
* Lisp Changes in Emacs 26.2 * Lisp Changes in Emacs 26.2

View file

@ -1779,7 +1779,24 @@ such that COMBO is equivalent to (and . CLAUSES)."
;;;###autoload ;;;###autoload
(defmacro cl-do (steps endtest &rest body) (defmacro cl-do (steps endtest &rest body)
"The Common Lisp `do' loop. "Bind variables and run BODY forms until END-TEST returns non-nil.
First, each VAR is bound to the associated INIT value as if by a `let' form.
Then, in each iteration of the loop, the END-TEST is evaluated; if true,
the loop is finished. Otherwise, the BODY forms are evaluated, then each
VAR is set to the associated STEP expression (as if by a `cl-psetq' form)
and the next iteration begins.
Once the END-TEST becomes true, the RESULT forms are evaluated (with
the VARs still bound to their values) to produce the result
returned by `cl-do'.
Note that the entire loop is enclosed in an implicit `nil' block, so
that you can use `cl-return' to exit at any time.
Also note that END-TEST is checked before evaluating BODY. If END-TEST
is initially non-nil, `cl-do' will exit without running BODY.
For more details, see `cl-do' description in Info node `(cl) Iteration'.
\(fn ((VAR INIT [STEP])...) (END-TEST [RESULT...]) BODY...)" \(fn ((VAR INIT [STEP])...) (END-TEST [RESULT...]) BODY...)"
(declare (indent 2) (declare (indent 2)
@ -1791,7 +1808,25 @@ such that COMBO is equivalent to (and . CLAUSES)."
;;;###autoload ;;;###autoload
(defmacro cl-do* (steps endtest &rest body) (defmacro cl-do* (steps endtest &rest body)
"The Common Lisp `do*' loop. "Bind variables and run BODY forms until END-TEST returns non-nil.
First, each VAR is bound to the associated INIT value as if by a `let*' form.
Then, in each iteration of the loop, the END-TEST is evaluated; if true,
the loop is finished. Otherwise, the BODY forms are evaluated, then each
VAR is set to the associated STEP expression (as if by a `setq'
form) and the next iteration begins.
Once the END-TEST becomes true, the RESULT forms are evaluated (with
the VARs still bound to their values) to produce the result
returned by `cl-do*'.
Note that the entire loop is enclosed in an implicit `nil' block, so
that you can use `cl-return' to exit at any time.
Also note that END-TEST is checked before evaluating BODY. If END-TEST
is initially non-nil, `cl-do*' will exit without running BODY.
This is to `cl-do' what `let*' is to `let'.
For more details, see `cl-do*' description in Info node `(cl) Iteration'.
\(fn ((VAR INIT [STEP])...) (END-TEST [RESULT...]) BODY...)" \(fn ((VAR INIT [STEP])...) (END-TEST [RESULT...]) BODY...)"
(declare (indent 2) (debug cl-do)) (declare (indent 2) (debug cl-do))

View file

@ -3570,7 +3570,7 @@ is allowed once again. (Immediately, if `inhibit-quit' is nil.)"
;; Don't throw `throw-on-input' on those events by default. ;; Don't throw `throw-on-input' on those events by default.
(setq while-no-input-ignore-events (setq while-no-input-ignore-events
'(focus-in focus-out help-echo iconify-frame '(focus-in focus-out help-echo iconify-frame
make-frame-visible selection-request)) make-frame-visible selection-request buffer-switch))
(defmacro while-no-input (&rest body) (defmacro while-no-input (&rest body)
"Execute BODY only as long as there's no pending input. "Execute BODY only as long as there's no pending input.

View file

@ -3554,6 +3554,7 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event,
case ICONIFY_EVENT: ignore_event = Qiconify_frame; break; case ICONIFY_EVENT: ignore_event = Qiconify_frame; break;
case DEICONIFY_EVENT: ignore_event = Qmake_frame_visible; break; case DEICONIFY_EVENT: ignore_event = Qmake_frame_visible; break;
case SELECTION_REQUEST_EVENT: ignore_event = Qselection_request; break; case SELECTION_REQUEST_EVENT: ignore_event = Qselection_request; break;
case BUFFER_SWITCH_EVENT: ignore_event = Qbuffer_switch; break;
default: ignore_event = Qnil; break; default: ignore_event = Qnil; break;
} }
@ -11082,6 +11083,8 @@ syms_of_keyboard (void)
/* Menu and tool bar item parts. */ /* Menu and tool bar item parts. */
DEFSYM (Qmenu_enable, "menu-enable"); DEFSYM (Qmenu_enable, "menu-enable");
DEFSYM (Qbuffer_switch, "buffer-switch");
#ifdef HAVE_NTGUI #ifdef HAVE_NTGUI
DEFSYM (Qlanguage_change, "language-change"); DEFSYM (Qlanguage_change, "language-change");
DEFSYM (Qend_session, "end-session"); DEFSYM (Qend_session, "end-session");

View file

@ -4008,6 +4008,7 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
char const *diagnostic char const *diagnostic
= (fd < 0) ? "Could not open file: %s" : "Not a tty device: %s"; = (fd < 0) ? "Could not open file: %s" : "Not a tty device: %s";
emacs_close (fd); emacs_close (fd);
delete_terminal_internal (terminal);
maybe_fatal (must_succeed, terminal, diagnostic, diagnostic, name); maybe_fatal (must_succeed, terminal, diagnostic, diagnostic, name);
} }

View file

@ -733,6 +733,7 @@ extern struct terminal *get_named_terminal (const char *);
extern struct terminal *create_terminal (enum output_method, extern struct terminal *create_terminal (enum output_method,
struct redisplay_interface *); struct redisplay_interface *);
extern void delete_terminal (struct terminal *); extern void delete_terminal (struct terminal *);
extern void delete_terminal_internal (struct terminal *);
extern Lisp_Object terminal_glyph_code (struct terminal *, int); extern Lisp_Object terminal_glyph_code (struct terminal *, int);
/* The initial terminal device, created by initial_term_init. */ /* The initial terminal device, created by initial_term_init. */

View file

@ -314,7 +314,6 @@ create_terminal (enum output_method type, struct redisplay_interface *rif)
void void
delete_terminal (struct terminal *terminal) delete_terminal (struct terminal *terminal)
{ {
struct terminal **tp;
Lisp_Object tail, frame; Lisp_Object tail, frame;
/* Protect against recursive calls. delete_frame calls the /* Protect against recursive calls. delete_frame calls the
@ -335,6 +334,14 @@ delete_terminal (struct terminal *terminal)
} }
} }
delete_terminal_internal (terminal);
}
void
delete_terminal_internal (struct terminal *terminal)
{
struct terminal **tp;
for (tp = &terminal_list; *tp != terminal; tp = &(*tp)->next_terminal) for (tp = &terminal_list; *tp != terminal; tp = &(*tp)->next_terminal)
if (! *tp) if (! *tp)
emacs_abort (); emacs_abort ();