commit 28c01bd4841be69d01b6db661917f1be9830cc3d (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Sat Aug 6 14:50:04 2022 +0800 Correctly initialize values after a new device is enabled * src/xterm.c (handle_one_xevent): Initialize new device to zero. (bug#57011) diff --git a/src/xterm.c b/src/xterm.c index b1e564a923..8f84edc63e 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -22144,6 +22144,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, dpyinfo->devices = xrealloc (dpyinfo->devices, (sizeof *dpyinfo->devices * ++dpyinfo->num_devices)); + memset (dpyinfo->devices + dpyinfo->num_devices - 1, + 0, sizeof *dpyinfo->devices); device = &dpyinfo->devices[dpyinfo->num_devices - 1]; xi_populate_device_from_info (device, info); } commit 564571f712fcf0ffcb93eeca67f7716263c9def5 Author: Eli Zaretskii Date: Sat Aug 6 09:40:07 2022 +0300 ; * lisp/emacs-lisp/lisp.el (end-of-defun-moves-to-eol): Doc fix. diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el index cc8185e453..acae1a0b0a 100644 --- a/lisp/emacs-lisp/lisp.el +++ b/lisp/emacs-lisp/lisp.el @@ -508,11 +508,9 @@ So the function can assume that point is at the beginning of the defun body. It should move point to the first position after the defun.") (defvar end-of-defun-moves-to-eol t - "Defines whether `end-of-defun' moves to eol before doing -everything else. - -Set this to nil in major mode if this movement affects mode's -decisions about context in an unwanted way.") + "Whether `end-of-defun' moves to eol before doing anything else. +Set this to nil if this movement adversely affects the buffer's +major mode's decisions about context.") (defun buffer-end (arg) "Return the \"far end\" position of the buffer, in direction ARG. commit e46668847d8973b46f35d673e8156c05cecf7a27 Author: Eli Zaretskii Date: Sat Aug 6 09:11:01 2022 +0300 * src/puresize.h (BASE_PURESIZE): Bump the value. (Bug#57007) diff --git a/src/puresize.h b/src/puresize.h index 5516747ac2..4b746924bb 100644 --- a/src/puresize.h +++ b/src/puresize.h @@ -47,7 +47,7 @@ INLINE_HEADER_BEGIN #endif #ifndef BASE_PURESIZE -#define BASE_PURESIZE (2000000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA) +#define BASE_PURESIZE (2750000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA) #endif /* Increase BASE_PURESIZE by a ratio depending on the machine's word size. */ commit e87c0fdc14a785411b9b8d7f5b35415a7b576b59 Merge: a97e9d80db f3b9bccb45 Author: Stefan Kangas Date: Sat Aug 6 06:30:27 2022 +0200 Merge from origin/emacs-28 f3b9bccb45 * lisp/play/fortune.el: Doc fixes. commit a97e9d80db1c99e03566b36983037ef5f792207a Author: Po Lu Date: Sat Aug 6 10:59:15 2022 +0800 Improve XI focus handling for entry and exit events * src/xterm.c (handle_one_xevent): Skip useless x_detect_focus_change calls in more cases. diff --git a/src/xterm.c b/src/xterm.c index bb06ee1535..b1e564a923 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -12521,7 +12521,6 @@ xi_handle_focus_change (struct x_display_info *dpyinfo) if (new != focus && new) { - #ifdef HAVE_X_I18N if (FRAME_XIC (new)) XSetICFocus (FRAME_XIC (new)); @@ -12678,13 +12677,6 @@ x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame, } break; -#ifdef HAVE_XINPUT2 - case GenericEvent: - xi_focus_handle_for_device (dpyinfo, frame, - event->xcookie.data); - break; -#endif - case FocusIn: case FocusOut: /* Ignore transient focus events from hotkeys, window manager @@ -20110,7 +20102,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, are an inferiors of the frame's top window, which will get virtual events. */ if (any) - x_detect_focus_change (dpyinfo, any, event, &inev.ie); + xi_focus_handle_for_device (dpyinfo, any, xi_event); if (!any) any = x_any_window_to_frame (dpyinfo, enter->event); @@ -20250,7 +20242,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, #endif if (any) - x_detect_focus_change (dpyinfo, any, event, &inev.ie); + xi_focus_handle_for_device (dpyinfo, any, xi_event); #ifndef USE_X_TOOLKIT f = x_top_window_to_frame (dpyinfo, leave->event); commit 3fee3f59f2b71e64773037177c95a9a2bd99b0c9 Author: Po Lu Date: Sat Aug 6 10:28:00 2022 +0800 ; Update ldefs-boot.el again diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index 353ac443e3..4d9e7bb997 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -5014,8 +5014,6 @@ evaluate `compilation-shell-minor-mode'. The mode's hook is called both when the mode is enabled and when it is disabled. -\\{compilation-shell-minor-mode-map} - (fn &optional ARG)" t nil) (autoload 'compilation-minor-mode "compile" "\ Toggle Compilation minor mode. @@ -5039,8 +5037,6 @@ evaluate `compilation-minor-mode'. The mode's hook is called both when the mode is enabled and when it is disabled. -\\{compilation-minor-mode-map} - (fn &optional ARG)" t nil) (autoload 'compilation-next-error-function "compile" "\ Advance to the next error message and visit the file where the error was. @@ -8392,7 +8388,7 @@ A second call of this function without changing point inserts the next match. A call with prefix PREFIX reads the symbol to insert from the minibuffer with completion. -(fn PREFIX)" t nil) +(fn PREFIX)" '("P") nil) (autoload 'ebrowse-tags-loop-continue "ebrowse" "\ Repeat last operation on files in tree. FIRST-TIME non-nil means this is not a repetition, but the first time. @@ -9929,7 +9925,7 @@ When present, ID should be an opaque object used to identify the connection unequivocally. This is rarely needed and not available interactively. -(fn &key (SERVER (erc-compute-server)) (PORT (erc-compute-port)) (NICK (erc-compute-nick)) (USER (erc-compute-user)) PASSWORD (FULL-NAME (erc-compute-full-name)) ID)" t nil) +(fn &key (SERVER (erc-compute-server)) (PORT (erc-compute-port)) (NICK (erc-compute-nick)) (USER (erc-compute-user)) PASSWORD (FULL-NAME (erc-compute-full-name)) ID)" '((erc-select-read-args)) nil) (defalias 'erc-select #'erc) (autoload 'erc-tls "erc" "\ ERC is a powerful, modular, and extensible IRC client. @@ -9976,7 +9972,7 @@ symbol composed of letters from the Latin alphabet.) This option is generally unneeded, however. See info node `(erc) Connecting' for use cases. Not available interactively. -(fn &key (SERVER (erc-compute-server)) (PORT (erc-compute-port)) (NICK (erc-compute-nick)) (USER (erc-compute-user)) PASSWORD (FULL-NAME (erc-compute-full-name)) CLIENT-CERTIFICATE ID)" t nil) +(fn &key (SERVER (erc-compute-server)) (PORT (erc-compute-port)) (NICK (erc-compute-nick)) (USER (erc-compute-user)) PASSWORD (FULL-NAME (erc-compute-full-name)) CLIENT-CERTIFICATE ID)" '((let ((erc-default-port erc-default-port-tls)) (erc-select-read-args))) nil) (autoload 'erc-handle-irc-url "erc" "\ Use ERC to IRC on HOST:PORT in CHANNEL as USER with PASSWORD. If ERC is already connected to HOST:PORT, simply /join CHANNEL. @@ -10192,9 +10188,7 @@ it has to be wrapped in `(eval (quote ...))'. If NAME is already defined as a test and Emacs is running in batch mode, an error is signalled. -(fn NAME () [DOCSTRING] [:expected-result RESULT-TYPE] [:tags \\='(TAG...)] BODY...)" nil t) -(function-put 'ert-deftest 'doc-string-elt 3) -(function-put 'ert-deftest 'lisp-indent-function 2) +(fn NAME () [DOCSTRING] [:expected-result RESULT-TYPE] [:tags \\='(TAG...)] BODY...)" nil 'macro) (autoload 'ert-run-tests-batch "ert" "\ Run the tests specified by SELECTOR, printing results to the terminal. @@ -12275,8 +12269,6 @@ evaluate `flymake-mode'. The mode's hook is called both when the mode is enabled and when it is disabled. -\\{flymake-mode-map} - (fn &optional ARG)" t nil) (autoload 'flymake-mode-on "flymake" "\ Turn Flymake mode on." nil nil) @@ -15877,8 +15869,7 @@ inlined into the compiled format versions. This means that if you change its definition, you should explicitly call `ibuffer-recompile-formats'. -(fn SYMBOL (&key NAME INLINE PROPS SUMMARIZER) &rest BODY)" nil t) -(function-put 'define-ibuffer-column 'lisp-indent-function 'defun) +(fn SYMBOL (&key NAME INLINE PROPS SUMMARIZER) &rest BODY)" nil 'macro) (autoload 'define-ibuffer-sorter "ibuf-macs" "\ Define a method of sorting named NAME. DOCUMENTATION is the documentation of the function, which will be called @@ -15889,9 +15880,7 @@ For sorting, the forms in BODY will be evaluated with `a' bound to one buffer object, and `b' bound to another. BODY should return a non-nil value if and only if `a' is \"less than\" `b'. -(fn NAME DOCUMENTATION (&key DESCRIPTION) &rest BODY)" nil t) -(function-put 'define-ibuffer-sorter 'lisp-indent-function 1) -(function-put 'define-ibuffer-sorter 'doc-string-elt 2) +(fn NAME DOCUMENTATION (&key DESCRIPTION) &rest BODY)" nil 'macro) (autoload 'define-ibuffer-op "ibuf-macs" "\ Generate a function which operates on a buffer. OP becomes the name of the function; if it doesn't begin with @@ -15930,9 +15919,7 @@ BODY define the operation; they are forms to evaluate per each marked buffer. BODY is evaluated with `buf' bound to the buffer object. -(fn OP ARGS DOCUMENTATION (&key INTERACTIVE MARK MODIFIER-P DANGEROUS OPSTRING ACTIVE-OPSTRING BEFORE AFTER COMPLEX) &rest BODY)" nil t) -(function-put 'define-ibuffer-op 'lisp-indent-function 2) -(function-put 'define-ibuffer-op 'doc-string-elt 3) +(fn OP ARGS DOCUMENTATION (&key INTERACTIVE MARK MODIFIER-P DANGEROUS OPSTRING ACTIVE-OPSTRING BEFORE AFTER COMPLEX) &rest BODY)" nil 'macro) (autoload 'define-ibuffer-filter "ibuf-macs" "\ Define a filter named NAME. DOCUMENTATION is the documentation of the function. @@ -15947,9 +15934,7 @@ not a particular buffer should be displayed or not. The forms in BODY will be evaluated with BUF bound to the buffer object, and QUALIFIER bound to the current value of the filter. -(fn NAME DOCUMENTATION (&key READER DESCRIPTION) &rest BODY)" nil t) -(function-put 'define-ibuffer-filter 'lisp-indent-function 2) -(function-put 'define-ibuffer-filter 'doc-string-elt 2) +(fn NAME DOCUMENTATION (&key READER DESCRIPTION) &rest BODY)" nil 'macro) (register-definition-prefixes "ibuf-macs" '("ibuffer-")) @@ -25332,8 +25317,6 @@ evaluate `rectangle-mark-mode'. The mode's hook is called both when the mode is enabled and when it is disabled. -\\{rectangle-mark-mode-map} - (fn &optional ARG)" t nil) (register-definition-prefixes "rect" '("apply-on-rectangle" "clear-rectangle-line" "delete-" "extract-rectangle-" "killed-rectangle" "ope" "rectangle-" "spaces-string" "string-rectangle-")) @@ -35815,6 +35798,7 @@ Zone out, completely." t nil) (provide 'loaddefs) ;; Local Variables: +;; no-byte-compile: t ;; version-control: never ;; no-update-autoloads: t ;; coding: utf-8-emacs-unix commit 15a9e73a1793a61b87d3f460e2e4bc5b7df1e6a8 Author: Po Lu Date: Sat Aug 6 10:27:03 2022 +0800 * src/callproc.c (emacs_spawn): Fix Mac OS X build. diff --git a/src/callproc.c b/src/callproc.c index aec0a2f5a5..e8e4c48b5b 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -1488,7 +1488,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, /* Darwin doesn't let us run setsid after a vfork, so use fork when necessary. Below, we reset SIGCHLD handling after a vfork, as apparently macOS can mistakenly deliver SIGCHLD to the child. */ - if (pty != NULL) + if (pty_in || pty_out) pid = fork (); else pid = VFORK (); commit 4e091c8ddf6bf421a4dd0210a3a4b77a3ecf24f5 Author: Po Lu Date: Sat Aug 6 10:22:41 2022 +0800 ; Update ldefs-boot.el diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index 85985399db..353ac443e3 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -825,7 +825,7 @@ it is disabled. ;;; Generated autoloads from net/ange-ftp.el -(defalias 'ange-ftp-re-read-dir 'ange-ftp-reread-dir) +(define-obsolete-function-alias 'ange-ftp-re-read-dir #'ange-ftp-reread-dir "29.1") (autoload 'ange-ftp-reread-dir "ange-ftp" "\ Reread remote directory DIR to update the directory cache. The implementation of remote FTP file names caches directory contents @@ -1426,6 +1426,10 @@ Special commands: How many seconds passwords are cached, or nil to disable expiring. Overrides `password-cache-expiry' through a let-binding.") (custom-autoload 'auth-source-cache-expiry "auth-source" t) +(autoload 'auth-source-netrc-parse-all "auth-source" "\ +Parse FILE and return all entries. + +(fn FILE)" nil nil) (autoload 'authinfo-mode "auth-source" "\ Mode for editing .authinfo/.netrc files. @@ -1533,60 +1537,6 @@ it is disabled. (fn &optional ARG)" t nil) (register-definition-prefixes "autoinsert" '("auto-insert")) - -;;; Generated autoloads from emacs-lisp/autoload.el - -(put 'autoload-ensure-writable 'risky-local-variable t) -(autoload 'update-file-autoloads "autoload" "\ -Update the autoloads for FILE. -If prefix arg SAVE-AFTER is non-nil, save the buffer too. - -If FILE binds `generated-autoload-file' as a file-local variable, -autoloads are written into that file. Otherwise, the autoloads -file is determined by OUTFILE. If called interactively, prompt -for OUTFILE; if called from Lisp with OUTFILE nil, use the -existing value of `generated-autoload-file'. - -Return FILE if there was no autoload cookie in it, else nil. - -(fn FILE &optional SAVE-AFTER OUTFILE)" t nil) -(autoload 'update-directory-autoloads "autoload" "\ -Update autoload definitions for Lisp files in the directories DIRS. -In an interactive call, you must give one argument, the name of a -single directory. In a call from Lisp, you can supply multiple -directories as separate arguments, but this usage is discouraged. - -The function does NOT recursively descend into subdirectories of the -directory or directories specified. - -In an interactive call, prompt for a default output file for the -autoload definitions. When called from Lisp, use the existing -value of `generated-autoload-file'. If any Lisp file binds -`generated-autoload-file' as a file-local variable, write its -autoloads into the specified file instead. - -(fn &rest DIRS)" t nil) -(make-obsolete 'update-directory-autoloads 'make-directory-autoloads "28.1") -(autoload 'make-directory-autoloads "autoload" "\ -Update autoload definitions for Lisp files in the directories DIRS. -DIR can be either a single directory or a list of -directories. (The latter usage is discouraged.) - -The autoloads will be written to OUTPUT-FILE. If any Lisp file -binds `generated-autoload-file' as a file-local variable, write -its autoloads into the specified file instead. - -The function does NOT recursively descend into subdirectories of the -directory or directories specified. - -(fn DIR OUTPUT-FILE)" t nil) -(autoload 'batch-update-autoloads "autoload" "\ -Update loaddefs.el autoloads in batch mode. -Calls `update-directory-autoloads' on the command line arguments. -Definitions are written to `generated-autoload-file' (which -should be non-nil)." nil nil) -(register-definition-prefixes "autoload" '("autoload-" "batch-update-autoloads--summary" "generate-" "make-autoload" "no-update-autoloads")) - ;;; Generated autoloads from autorevert.el @@ -5064,6 +5014,8 @@ evaluate `compilation-shell-minor-mode'. The mode's hook is called both when the mode is enabled and when it is disabled. +\\{compilation-shell-minor-mode-map} + (fn &optional ARG)" t nil) (autoload 'compilation-minor-mode "compile" "\ Toggle Compilation minor mode. @@ -5087,6 +5039,8 @@ evaluate `compilation-minor-mode'. The mode's hook is called both when the mode is enabled and when it is disabled. +\\{compilation-minor-mode-map} + (fn &optional ARG)" t nil) (autoload 'compilation-next-error-function "compile" "\ Advance to the next error message and visit the file where the error was. @@ -6131,7 +6085,7 @@ omitted, a buffer named *Custom Themes* is used. ;;; Generated autoloads from cedet/ede/custom.el -(register-definition-prefixes "ede/custom" '("ede-" "eieio-ede-old-variables")) +(register-definition-prefixes "ede/custom" '("ede-")) ;;; Generated autoloads from vc/cvs-status.el @@ -7460,7 +7414,7 @@ Like \\[dired-jump] (`dired-jump') but in other window. ;;; Generated autoloads from dired-aux.el -(register-definition-prefixes "dired-aux" '("dired-" "minibuffer-default-add-dired-shell-commands")) +(register-definition-prefixes "dired-aux" '("dired-")) ;;; Generated autoloads from dired-x.el @@ -8438,7 +8392,7 @@ A second call of this function without changing point inserts the next match. A call with prefix PREFIX reads the symbol to insert from the minibuffer with completion. -(fn PREFIX)" '("P") nil) +(fn PREFIX)" t nil) (autoload 'ebrowse-tags-loop-continue "ebrowse" "\ Repeat last operation on files in tree. FIRST-TIME non-nil means this is not a repetition, but the first time. @@ -9362,7 +9316,7 @@ displayed." t nil) ;;; Generated autoloads from eshell/em-extpipe.el -(register-definition-prefixes "em-extpipe" '("em-extpipe--or-with-catch" "eshell-")) +(register-definition-prefixes "em-extpipe" '("eshell-")) ;;; Generated autoloads from eshell/em-glob.el @@ -9975,7 +9929,7 @@ When present, ID should be an opaque object used to identify the connection unequivocally. This is rarely needed and not available interactively. -(fn &key (SERVER (erc-compute-server)) (PORT (erc-compute-port)) (NICK (erc-compute-nick)) (USER (erc-compute-user)) PASSWORD (FULL-NAME (erc-compute-full-name)) ID)" '((erc-select-read-args)) nil) +(fn &key (SERVER (erc-compute-server)) (PORT (erc-compute-port)) (NICK (erc-compute-nick)) (USER (erc-compute-user)) PASSWORD (FULL-NAME (erc-compute-full-name)) ID)" t nil) (defalias 'erc-select #'erc) (autoload 'erc-tls "erc" "\ ERC is a powerful, modular, and extensible IRC client. @@ -10022,7 +9976,7 @@ symbol composed of letters from the Latin alphabet.) This option is generally unneeded, however. See info node `(erc) Connecting' for use cases. Not available interactively. -(fn &key (SERVER (erc-compute-server)) (PORT (erc-compute-port)) (NICK (erc-compute-nick)) (USER (erc-compute-user)) PASSWORD (FULL-NAME (erc-compute-full-name)) CLIENT-CERTIFICATE ID)" '((let ((erc-default-port erc-default-port-tls)) (erc-select-read-args))) nil) +(fn &key (SERVER (erc-compute-server)) (PORT (erc-compute-port)) (NICK (erc-compute-nick)) (USER (erc-compute-user)) PASSWORD (FULL-NAME (erc-compute-full-name)) CLIENT-CERTIFICATE ID)" t nil) (autoload 'erc-handle-irc-url "erc" "\ Use ERC to IRC on HOST:PORT in CHANNEL as USER with PASSWORD. If ERC is already connected to HOST:PORT, simply /join CHANNEL. @@ -10238,7 +10192,9 @@ it has to be wrapped in `(eval (quote ...))'. If NAME is already defined as a test and Emacs is running in batch mode, an error is signalled. -(fn NAME () [DOCSTRING] [:expected-result RESULT-TYPE] [:tags \\='(TAG...)] BODY...)" nil 'macro) +(fn NAME () [DOCSTRING] [:expected-result RESULT-TYPE] [:tags \\='(TAG...)] BODY...)" nil t) +(function-put 'ert-deftest 'doc-string-elt 3) +(function-put 'ert-deftest 'lisp-indent-function 2) (autoload 'ert-run-tests-batch "ert" "\ Run the tests specified by SELECTOR, printing results to the terminal. @@ -11908,7 +11864,7 @@ where the first string in the value of the variable `find-ls-option' specifies what to use in place of \"-ls\" as the final argument. (fn DIR REGEXP)" t nil) -(register-definition-prefixes "find-dired" '("find-" "kill-find" "lookfor-dired")) +(register-definition-prefixes "find-dired" '("find-" "kill-find")) ;;; Generated autoloads from find-file.el @@ -12319,6 +12275,8 @@ evaluate `flymake-mode'. The mode's hook is called both when the mode is enabled and when it is disabled. +\\{flymake-mode-map} + (fn &optional ARG)" t nil) (autoload 'flymake-mode-on "flymake" "\ Turn Flymake mode on." nil nil) @@ -13085,7 +13043,7 @@ detailed description of this mode. +-----------------------------------+----------------------------------+ (fn COMMAND-LINE)" t nil) -(register-definition-prefixes "gdb-mi" '("breakpoint" "def-gdb-" "gdb" "gud-" "hollow-right-triangle" "nil")) +(register-definition-prefixes "gdb-mi" '("breakpoint" "def-gdb-" "gdb" "gud-" "hollow-right-triangle")) ;;; Generated autoloads from emacs-lisp/generator.el @@ -13409,7 +13367,7 @@ CLEAN is obsolete and ignored. (autoload 'gnus-article-prepare-display "gnus-art" "\ Make the current buffer look like a nice article." nil nil) -(register-definition-prefixes "gnus-art" '(":keymap" "article-" "gnus-")) +(register-definition-prefixes "gnus-art" '("article-" "gnus-")) ;;; Generated autoloads from gnus/gnus-async.el @@ -13649,7 +13607,7 @@ The arguments have the same meaning as those of `gnus-read-ephemeral-bug-group', which see. (fn IDS &optional WINDOW-CONF)" t nil) -(register-definition-prefixes "gnus-group" '(":keymap" "gnus-")) +(register-definition-prefixes "gnus-group" '("gnus-")) ;;; Generated autoloads from gnus/gnus-html.el @@ -13842,7 +13800,7 @@ Like `message-reply'. (fn &optional TO-ADDRESS WIDE)" t nil) (define-mail-user-agent 'gnus-user-agent 'gnus-msg-mail 'message-send-and-exit 'message-kill-buffer 'message-send-hook) -(register-definition-prefixes "gnus-msg" '(":prefix" "gnus-")) +(register-definition-prefixes "gnus-msg" '("gnus-")) ;;; Generated autoloads from gnus/gnus-notifications.el @@ -14003,7 +13961,7 @@ Handler function for record returned by `gnus-summary-bookmark-make-record'. BOOKMARK is a bookmark name or a bookmark record. (fn BOOKMARK)" nil nil) -(register-definition-prefixes "gnus-sum" '(":keymap" "gnus-")) +(register-definition-prefixes "gnus-sum" '("gnus-")) ;;; Generated autoloads from gnus/gnus-topic.el @@ -14627,7 +14585,7 @@ FUNC is a function to handle input key. HELP-TEXT is a text set in `hangul-input-method-help-text'. (fn INPUT-METHOD FUNC HELP-TEXT &rest ARGS)" nil nil) -(register-definition-prefixes "quail/hangul" '("alphabetp" "hangul" "notzerop")) +(register-definition-prefixes "quail/hangul" '("hangul" "notzerop")) ;;; Generated autoloads from language/hanja-util.el @@ -15919,7 +15877,8 @@ inlined into the compiled format versions. This means that if you change its definition, you should explicitly call `ibuffer-recompile-formats'. -(fn SYMBOL (&key NAME INLINE PROPS SUMMARIZER) &rest BODY)" nil 'macro) +(fn SYMBOL (&key NAME INLINE PROPS SUMMARIZER) &rest BODY)" nil t) +(function-put 'define-ibuffer-column 'lisp-indent-function 'defun) (autoload 'define-ibuffer-sorter "ibuf-macs" "\ Define a method of sorting named NAME. DOCUMENTATION is the documentation of the function, which will be called @@ -15930,7 +15889,9 @@ For sorting, the forms in BODY will be evaluated with `a' bound to one buffer object, and `b' bound to another. BODY should return a non-nil value if and only if `a' is \"less than\" `b'. -(fn NAME DOCUMENTATION (&key DESCRIPTION) &rest BODY)" nil 'macro) +(fn NAME DOCUMENTATION (&key DESCRIPTION) &rest BODY)" nil t) +(function-put 'define-ibuffer-sorter 'lisp-indent-function 1) +(function-put 'define-ibuffer-sorter 'doc-string-elt 2) (autoload 'define-ibuffer-op "ibuf-macs" "\ Generate a function which operates on a buffer. OP becomes the name of the function; if it doesn't begin with @@ -15969,7 +15930,9 @@ BODY define the operation; they are forms to evaluate per each marked buffer. BODY is evaluated with `buf' bound to the buffer object. -(fn OP ARGS DOCUMENTATION (&key INTERACTIVE MARK MODIFIER-P DANGEROUS OPSTRING ACTIVE-OPSTRING BEFORE AFTER COMPLEX) &rest BODY)" nil 'macro) +(fn OP ARGS DOCUMENTATION (&key INTERACTIVE MARK MODIFIER-P DANGEROUS OPSTRING ACTIVE-OPSTRING BEFORE AFTER COMPLEX) &rest BODY)" nil t) +(function-put 'define-ibuffer-op 'lisp-indent-function 2) +(function-put 'define-ibuffer-op 'doc-string-elt 3) (autoload 'define-ibuffer-filter "ibuf-macs" "\ Define a filter named NAME. DOCUMENTATION is the documentation of the function. @@ -15984,7 +15947,9 @@ not a particular buffer should be displayed or not. The forms in BODY will be evaluated with BUF bound to the buffer object, and QUALIFIER bound to the current value of the filter. -(fn NAME DOCUMENTATION (&key READER DESCRIPTION) &rest BODY)" nil 'macro) +(fn NAME DOCUMENTATION (&key READER DESCRIPTION) &rest BODY)" nil t) +(function-put 'define-ibuffer-filter 'lisp-indent-function 2) +(function-put 'define-ibuffer-filter 'doc-string-elt 2) (register-definition-prefixes "ibuf-macs" '("ibuffer-")) @@ -16026,7 +15991,7 @@ Call Ibuffer and set point at the line listing the current buffer. If optional arg OTHER-WINDOW is non-nil, then use another window. (fn &optional OTHER-WINDOW)" t nil) -(register-definition-prefixes "ibuffer" '("filename" "ibuffer-" "locked" "mark" "mod" "name" "process" "read-only" "recency" "size")) +(register-definition-prefixes "ibuffer" '("ibuffer-")) ;;; Generated autoloads from calendar/icalendar.el @@ -18712,7 +18677,7 @@ This scans for ;;;###autoload forms and related things. The first element on the command line should be the (main) loaddefs.el output file, and the rest are the directories to use." nil nil) -(register-definition-prefixes "loaddefs-gen" '("autoload-" "generated-autoload-" "loaddefs-generate--")) +(register-definition-prefixes "loaddefs-gen" '("autoload-" "generated-autoload-" "loaddefs-generate--" "no-update-autoloads")) ;;; Generated autoloads from loadhist.el @@ -19739,7 +19704,7 @@ Major mode for editing Metafont sources. Major mode for editing MetaPost sources. (fn)" t nil) -(register-definition-prefixes "meta-mode" '("font-lock-match-meta-declaration-item-and-skip-to-next" "meta")) +(register-definition-prefixes "meta-mode" '("meta")) ;;; Generated autoloads from mh-e/mh-acros.el @@ -19924,7 +19889,7 @@ perform the operation on all messages in that region. \\{mh-folder-mode-map} (fn)" t nil) -(register-definition-prefixes "mh-folder" '(":keymap" "mh-")) +(register-definition-prefixes "mh-folder" '("mh-")) ;;; Generated autoloads from mh-e/mh-funcs.el @@ -19949,7 +19914,7 @@ perform the operation on all messages in that region. ;;; Generated autoloads from mh-e/mh-letter.el -(register-definition-prefixes "mh-letter" '(":keymap" "mh-")) +(register-definition-prefixes "mh-letter" '("mh-")) ;;; Generated autoloads from mh-e/mh-limit.el @@ -19974,7 +19939,7 @@ perform the operation on all messages in that region. ;;; Generated autoloads from mh-e/mh-search.el -(register-definition-prefixes "mh-search" '(":keymap" "mh-")) +(register-definition-prefixes "mh-search" '("mh-")) ;;; Generated autoloads from mh-e/mh-seq.el @@ -19984,12 +19949,12 @@ perform the operation on all messages in that region. ;;; Generated autoloads from mh-e/mh-show.el -(register-definition-prefixes "mh-show" '(":keymap" "mh-")) +(register-definition-prefixes "mh-show" '("mh-")) ;;; Generated autoloads from mh-e/mh-speed.el -(register-definition-prefixes "mh-speed" '(":keymap" "mh-")) +(register-definition-prefixes "mh-speed" '("mh-")) ;;; Generated autoloads from mh-e/mh-thread.el @@ -20572,7 +20537,7 @@ To test this function, evaluate: (autoload 'mpc "mpc" "\ Main entry point for MPC." t nil) -(register-definition-prefixes "mpc" '("mpc-" "tag-browser-tagtypes")) +(register-definition-prefixes "mpc" '("mpc-")) ;;; Generated autoloads from play/mpuz.el @@ -21030,17 +20995,6 @@ Open a network connection to HOST on PORT. (fn HOST PORT)" t nil) (register-definition-prefixes "net-utils" '("arp-program" "dns-lookup-program" "finger-X.500-host-regexps" "ftp-" "ifconfig-program" "ipconfig" "iwconfig-program" "net" "nslookup-" "ping-program" "route-program" "run-network-program" "smbclient" "traceroute-program" "whois-")) - -;;; Generated autoloads from net/netrc.el - -(autoload 'netrc-credentials "netrc" "\ -Return a user name/password pair. -Port specifications will be prioritized in the order they are -listed in the PORTS list. - -(fn MACHINE &rest PORTS)" nil nil) -(register-definition-prefixes "netrc" '("netrc-")) - ;;; Generated autoloads from net/network-stream.el @@ -23501,7 +23455,7 @@ Various indentation styles: K&R BSD BLK GNU LW Turning on Perl mode runs the normal hook `perl-mode-hook'. (fn)" t nil) -(register-definition-prefixes "perl-mode" '("indent-perl-exp" "mark-perl-function" "perl-")) +(register-definition-prefixes "perl-mode" '("perl-")) ;;; Generated autoloads from pgtk-dnd.el @@ -25378,6 +25332,8 @@ evaluate `rectangle-mark-mode'. The mode's hook is called both when the mode is enabled and when it is disabled. +\\{rectangle-mark-mode-map} + (fn &optional ARG)" t nil) (register-definition-prefixes "rect" '("apply-on-rectangle" "clear-rectangle-line" "delete-" "extract-rectangle-" "killed-rectangle" "ope" "rectangle-" "spaces-string" "string-rectangle-")) @@ -26889,7 +26845,7 @@ The mode's hook is called both when the mode is enabled and when it is disabled. (fn &optional ARG)" t nil) -(register-definition-prefixes "saveplace" '("load-save-place-alist-from-file" "save-place")) +(register-definition-prefixes "saveplace" '("save-place")) ;;; Generated autoloads from cedet/semantic/sb.el @@ -28603,7 +28559,7 @@ explicitly, and matters only if you need the extra headers installed through `spam-necessary-extra-headers'. (fn &rest SYMBOLS)" t nil) -(register-definition-prefixes "spam" '(":keymap" "spam-")) +(register-definition-prefixes "spam" '("spam-")) ;;; Generated autoloads from gnus/spam-report.el @@ -30211,7 +30167,7 @@ converts a table into plain text without frames. It is a companion to ;;; Generated autoloads from cedet/srecode/table.el -(register-definition-prefixes "srecode/table" '("object-sort-list" "srecode-")) +(register-definition-prefixes "srecode/table" '("srecode-")) ;;; Generated autoloads from emacs-lisp/tabulated-list.el @@ -31214,7 +31170,11 @@ If DATE lacks timezone information, GMT is assumed. (fn DATE)" nil nil) (defalias 'time-to-seconds 'float-time) -(defalias 'seconds-to-time 'time-convert) +(autoload 'seconds-to-time "time-date" "\ +Convert SECONDS to a proper time, like `current-time' would. +FORM means the same as in `time-convert'. + +(fn SECONDS &rest FORM)" nil nil) (autoload 'days-to-time "time-date" "\ Convert DAYS into a time value. @@ -32161,7 +32121,7 @@ FRAC should be the inverse of the fractional value; for example, a value of 2 would mean to use one half, a value of 4 would mean to use one quarter, etc. (fn WPM &optional WORDLEN FRAC)" t nil) -(register-definition-prefixes "type-break" '("timep" "type-break-")) +(register-definition-prefixes "type-break" '("type-break-")) ;;; Generated autoloads from international/ucs-normalize.el @@ -34550,7 +34510,7 @@ Toggle Viper on/off. If Viper is enabled, turn it off. Otherwise, turn it on." t nil) (autoload 'viper-mode "viper" "\ Turn on Viper emulation of Vi in Emacs. See Info node `(viper)Top'." t nil) -(register-definition-prefixes "viper" '("set-viper-state-in-major-mode" "this-major-mode-requires-vi-state" "viper-")) +(register-definition-prefixes "viper" '("viper-")) ;;; Generated autoloads from emulation/viper-cmd.el @@ -35497,7 +35457,7 @@ decompress the file if appropriate. See the documentation for the Default bookmark handler for Woman buffers. (fn BOOKMARK)" nil nil) -(register-definition-prefixes "woman" '("WoMan-" "menu-bar-manuals-menu" "set-woman-file-regexp" "woman")) +(register-definition-prefixes "woman" '("WoMan-" "woman")) ;;; Generated autoloads from textmodes/word-wrap-mode.el @@ -35742,7 +35702,7 @@ to control which program to use when looking for matches. ;;; Generated autoloads from progmodes/xscheme.el -(register-definition-prefixes "xscheme" '("default-xscheme-runlight" "exit-scheme-interaction-mode" "global-set-scheme-interaction-buffer" "local-" "reset-scheme" "run-scheme" "scheme-" "start-scheme" "verify-xscheme-buffer" "xscheme-")) +(register-definition-prefixes "xscheme" '("exit-scheme-interaction-mode" "global-set-scheme-interaction-buffer" "local-" "reset-scheme" "run-scheme" "scheme-" "start-scheme" "xscheme-")) ;;; Generated autoloads from nxml/xsd-regexp.el @@ -35855,7 +35815,6 @@ Zone out, completely." t nil) (provide 'loaddefs) ;; Local Variables: -;; no-byte-compile: t ;; version-control: never ;; no-update-autoloads: t ;; coding: utf-8-emacs-unix commit ef0546ffcdab57fa947efb2a255adec4f61efacd Author: Po Lu Date: Sat Aug 6 10:21:52 2022 +0800 Fix signature of `seconds-to-time' * lisp/calendar/time-date.el (seconds-to-time): Fix after change to time-convert. diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el index b80b47a33f..7e911d814d 100644 --- a/lisp/calendar/time-date.el +++ b/lisp/calendar/time-date.el @@ -174,7 +174,10 @@ If DATE lacks timezone information, GMT is assumed." (defalias 'time-to-seconds 'float-time) ;;;###autoload -(defalias 'seconds-to-time 'time-convert) +(defun seconds-to-time (seconds &rest form) + "Convert SECONDS to a proper time, like `current-time' would. +FORM means the same as in `time-convert'." + (time-convert seconds form)) ;;;###autoload (defun days-to-time (days) commit 32ab6d71058a35f784c644f5267ed0c72aeefcda Author: Po Lu Date: Sat Aug 6 10:17:38 2022 +0800 Improve XI focus handling * src/xterm.c (handle_one_xevent): Skip useless x_detect_focus_change calls in some cases. diff --git a/src/xterm.c b/src/xterm.c index 4bbcfb0e59..bb06ee1535 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -20016,11 +20016,11 @@ handle_one_xevent (struct x_display_info *dpyinfo, { case XI_FocusIn: { - XIFocusInEvent *focusin = (XIFocusInEvent *) xi_event; - struct xi_device_t *source; + XIFocusInEvent *focusin; + focusin = (XIFocusInEvent *) xi_event; any = x_any_window_to_frame (dpyinfo, focusin->event); - source = xi_device_from_id (dpyinfo, focusin->sourceid); + #ifdef USE_GTK /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap minimized/iconified windows; thus, for those WMs we won't get @@ -20049,24 +20049,19 @@ handle_one_xevent (struct x_display_info *dpyinfo, } } - x_detect_focus_change (dpyinfo, any, event, &inev.ie); + xi_focus_handle_for_device (dpyinfo, any, xi_event); - if (inev.ie.kind != NO_EVENT && source) - inev.ie.device = source->name; goto XI_OTHER; } case XI_FocusOut: { - XIFocusOutEvent *focusout = (XIFocusOutEvent *) xi_event; - struct xi_device_t *source; + XIFocusOutEvent *focusout; + focusout = (XIFocusOutEvent *) xi_event; any = x_any_window_to_frame (dpyinfo, focusout->event); - source = xi_device_from_id (dpyinfo, focusout->sourceid); - x_detect_focus_change (dpyinfo, any, event, &inev.ie); + xi_focus_handle_for_device (dpyinfo, any, xi_event); - if (inev.ie.kind != NO_EVENT && source) - inev.ie.device = source->name; goto XI_OTHER; } commit 4e59830bc0ab17cdbd85748b133c97837bed99e3 Author: Jim Porter Date: Tue Jul 19 21:36:54 2022 -0700 Add STREAM argument to 'process-tty-name' * src/process.c (process-tty-name): Add STREAM argument. * lisp/eshell/esh-io.el (eshell-close-target): Only call 'process-send-eof' once if the process's stdin is a pipe. * test/src/process-tests.el (make-process/test-connection-type): Check behavior of 'process-tty-name'. * doc/lispref/processes.texi (Process Information): Document the new argument. * etc/NEWS: Announce this change. diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index e253ab9de0..382053ab24 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -1243,15 +1243,24 @@ that are already closed, the value is either 0 or 256, depending on whether the connection was closed normally or abnormally. @end defun -@defun process-tty-name process +@defun process-tty-name process &optional stream This function returns the terminal name that @var{process} is using for its communication with Emacs---or @code{nil} if it is using pipes instead of a pty (see @code{process-connection-type} in -@ref{Asynchronous Processes}). If @var{process} represents a program -running on a remote host, the terminal name used by that program on -the remote host is provided as process property @code{remote-tty}. If -@var{process} represents a network, serial, or pipe connection, the -value is @code{nil}. +@ref{Asynchronous Processes}). By default, this function returns the +terminal name if any of @var{process}'s standard streams use a +terminal. If @var{stream} is one of @code{stdin}, @code{stdout}, or +@code{stderr}, this function returns the terminal name (or @code{nil}, +as above) that @var{process} uses for that stream specifically. You +can use this to determine whether a particular stream uses a pipe or a +pty. + +If @var{process} represents a program running on a remote host, this +function returns the @emph{local} terminal name that communicates with +@var{process}; you can get the terminal name used by that program on +the remote host with the process property @code{remote-tty}. If +@var{process} represents a network, serial, or pipe connection, this +function always returns @code{nil}. @end defun @defun process-coding-system process diff --git a/etc/NEWS b/etc/NEWS index 8a9744ab3e..bca3c4da78 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3333,7 +3333,10 @@ invocation. Such shells are POSIX conformant by default. ** 'make-process' can set connection type independently for input and output. When calling 'make-process', communication via pty can be enabled selectively for just input or output by passing a cons cell for -':connection-type', e.g. '(pipe . pty)'. +':connection-type', e.g. '(pipe . pty)'. When examining a process +later, you can determine whether a particular stream for a process +uses a pty by passing one of 'stdin', 'stdout', or 'stderr' as the +second argument to 'process-tty-name'. +++ ** 'signal-process' now consults the list 'signal-process-functions'. diff --git a/lisp/eshell/esh-io.el b/lisp/eshell/esh-io.el index c035890ddf..68e52a2c9c 100644 --- a/lisp/eshell/esh-io.el +++ b/lisp/eshell/esh-io.el @@ -276,18 +276,21 @@ STATUS should be non-nil on successful termination of the output." ;; If we're redirecting to a process (via a pipe, or process ;; redirection), send it EOF so that it knows we're finished. ((eshell-processp target) - ;; According to POSIX.1-2017, section 11.1.9, sending EOF causes - ;; all bytes waiting to be read to be sent to the process - ;; immediately. Thus, if there are any bytes waiting, we need to - ;; send EOF twice: once to flush the buffer, and a second time to - ;; cause the next read() to return a size of 0, indicating - ;; end-of-file to the reading process. However, some platforms - ;; (e.g. Solaris) actually require sending a *third* EOF. Since - ;; sending extra EOFs while the process is running shouldn't break - ;; anything, we'll just send the maximum we'd ever need. See - ;; bug#56025 for further details. - (let ((i 0)) - (while (and (<= (cl-incf i) 3) + ;; According to POSIX.1-2017, section 11.1.9, when communicating + ;; via terminal, sending EOF causes all bytes waiting to be read + ;; to be sent to the process immediately. Thus, if there are any + ;; bytes waiting, we need to send EOF twice: once to flush the + ;; buffer, and a second time to cause the next read() to return a + ;; size of 0, indicating end-of-file to the reading process. + ;; However, some platforms (e.g. Solaris) actually require sending + ;; a *third* EOF. Since sending extra EOFs while the process is + ;; running are a no-op, we'll just send the maximum we'd ever + ;; need. See bug#56025 for further details. + (let ((i 0) + ;; Only call `process-send-eof' once if communicating via a + ;; pipe (in truth, this just closes the pipe). + (max-attempts (if (process-tty-name target 'stdin) 3 1))) + (while (and (<= (cl-incf i) max-attempts) (eq (process-status target) 'run)) (process-send-eof target)))) diff --git a/src/process.c b/src/process.c index 68dbd8b68b..23479c0619 100644 --- a/src/process.c +++ b/src/process.c @@ -1243,14 +1243,31 @@ or t (process is stopped). */) return XPROCESS (process)->command; } -DEFUN ("process-tty-name", Fprocess_tty_name, Sprocess_tty_name, 1, 1, 0, +DEFUN ("process-tty-name", Fprocess_tty_name, Sprocess_tty_name, 1, 2, 0, doc: /* Return the name of the terminal PROCESS uses, or nil if none. This is the terminal that the process itself reads and writes on, -not the name of the pty that Emacs uses to talk with that terminal. */) - (register Lisp_Object process) +not the name of the pty that Emacs uses to talk with that terminal. + +If STREAM is nil, return the terminal name if any of PROCESS's +standard streams use a terminal for communication. If STREAM is one +of `stdin', `stdout', or `stderr', return the name of the terminal +PROCESS uses for that stream specifically, or nil if that stream +communicates via a pipe. */) + (register Lisp_Object process, Lisp_Object stream) { CHECK_PROCESS (process); - return XPROCESS (process)->tty_name; + register struct Lisp_Process *p = XPROCESS (process); + + if (NILP (stream)) + return p->tty_name; + else if (EQ (stream, Qstdin)) + return p->pty_in ? p->tty_name : Qnil; + else if (EQ (stream, Qstdout)) + return p->pty_out ? p->tty_name : Qnil; + else if (EQ (stream, Qstderr)) + return p->pty_out && NILP (p->stderrproc) ? p->tty_name : Qnil; + else + signal_error ("Unknown stream", stream); } static void diff --git a/test/src/process-tests.el b/test/src/process-tests.el index b801563feb..db8a504478 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -294,6 +294,9 @@ should be a TTY, respectively." "if [ -t 2 ]; then echo stderr; fi")) :buffer stdout-buffer args))) + (should (eq (and (process-tty-name proc 'stdin) t) (nth 0 ttys))) + (should (eq (and (process-tty-name proc 'stdout) t) (nth 1 ttys))) + (should (eq (and (process-tty-name proc 'stderr) t) (nth 2 ttys))) (process-test-wait-for-sentinel proc 0) (should (equal (with-current-buffer stdout-buffer (buffer-string)) expected-output)))) commit d7b89ea4077d4fe677ba0577245328819ee79cdc Author: Jim Porter Date: Sun Jul 17 20:25:00 2022 -0700 Allow creating processes where only one of stdin or stdout is a PTY * src/lisp.h (emacs_spawn): * src/callproc.c (emacs_spawn): Add PTY_IN and PTY_OUT arguments to specify which streams should be set up as a PTY. (call_process): Adjust call to 'emacs_spawn'. * src/process.h (Lisp_Process): Replace 'pty_flag' with 'pty_in' and 'pty_out'. * src/process.c (is_pty_from_symbol): New function. (make-process): Allow :connection-type to be a cons cell, and allow using a stderr process with a PTY for stdin/stdout. (create_process): Handle creating a process where only one of stdin or stdout is a PTY. * lisp/eshell/esh-proc.el (eshell-needs-pipe, eshell-needs-pipe-p): Remove. (eshell-gather-process-output): Use 'make-process' and set ':connection-type' as needed by the value of 'eshell-in-pipeline-p'. * lisp/net/tramp.el (tramp-handle-make-process): * lisp/net/tramp-adb.el (tramp-adb-handle-make-process): * lisp/net/tramp-sh.el (tramp-sh-handle-make-process): Don't signal an error when ':connection-type' is a cons cell. * test/src/process-tests.el (process-test-sentinel-wait-function-working-p): Allow passing PROC in, and rework into... (process-test-wait-for-sentinel): ... this. (process-test-sentinel-accept-process-output) (process-test-sentinel-sit-for, process-test-quoted-batfile) (process-test-stderr-filter): Use 'process-test-wait-for-sentinel'. (make/process/test-connection-type): New function. (make-process/connection-type/pty, make-process/connection-type/pty-2) (make-process/connection-type/pipe) (make-process/connection-type/pipe-2) (make-process/connection-type/in-pty) (make-process/connection-type/out-pty) (make-process/connection-type/pty-with-stderr-buffer) (make-process/connection-type/out-pty-with-stderr-buffer): New tests. * test/lisp/eshell/esh-proc-tests.el (esh-proc-test--detect-pty-cmd): New variable. (esh-proc-test/pipeline-connection-type/no-pipeline) (esh-proc-test/pipeline-connection-type/first) (esh-proc-test/pipeline-connection-type/middle) (esh-proc-test/pipeline-connection-type/last): New tests. * doc/lispref/processes.texi (Asynchronous Processes): Document new ':connection-type' behavior. (Output from Processes): Remove caveat about ':stderr' forcing 'make-process' to use pipes. * etc/NEWS: Announce this change (bug#56025). diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 1ef8fc3d03..e253ab9de0 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -705,12 +705,13 @@ coding system will apply. @xref{Default Coding Systems}. Initialize the type of device used to communicate with the subprocess. Possible values are @code{pty} to use a pty, @code{pipe} to use a pipe, or @code{nil} to use the default derived from the value of the -@code{process-connection-type} variable. This parameter and the value -of @code{process-connection-type} are ignored if a non-@code{nil} -value is specified for the @code{:stderr} parameter; in that case, the -type will always be @code{pipe}. On systems where ptys are not -available (MS-Windows), this parameter is likewise ignored, and pipes -are used unconditionally. +@code{process-connection-type} variable. If @var{type} is a cons cell +@w{@code{(@var{input} . @var{output})}}, then @var{input} will be used +for standard input and @var{output} for standard output (and standard +error if @code{:stderr} is @code{nil}). + +On systems where ptys are not available (MS-Windows), this parameter +is ignored, and pipes are used unconditionally. @item :noquery @var{query-flag} Initialize the process query flag to @var{query-flag}. @@ -1530,20 +1531,11 @@ a buffer, which is called the associated buffer of the process default filter discards the output. If the subprocess writes to its standard error stream, by default -the error output is also passed to the process filter function. If -Emacs uses a pseudo-TTY (pty) for communication with the subprocess, -then it is impossible to separate the standard output and standard -error streams of the subprocess, because a pseudo-TTY has only one -output channel. In that case, if you want to keep the output to those -streams separate, you should redirect one of them to a file---for -example, by using an appropriate shell command via -@code{start-process-shell-command} or a similar function. - - Alternatively, you could use the @code{:stderr} parameter with a +the error output is also passed to the process filter function. +Alternatively, you could use the @code{:stderr} parameter with a non-@code{nil} value in a call to @code{make-process} (@pxref{Asynchronous Processes, make-process}) to make the destination -of the error output separate from the standard output; in that case, -Emacs will use pipes for communicating with the subprocess. +of the error output separate from the standard output. When a subprocess terminates, Emacs reads any pending output, then stops reading output from that subprocess. Therefore, if the diff --git a/etc/NEWS b/etc/NEWS index dc8bd6ce24..8a9744ab3e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2332,6 +2332,12 @@ they will still be escaped, so the '.foo' symbol is still printed as and remapping parent of basic faces does not work reliably. Instead of remapping 'mode-line', you have to remap 'mode-line-active'. ++++ +** 'make-process' has been extended to support ptys when ':stderr' is set. +Previously, setting ':stderr' to a non-nil value would force the +process's connection to use pipes. Now, Emacs will use a pty for +stdin and stdout if requested no matter the value of ':stderr'. + --- ** User option 'mail-source-ignore-errors' is now obsolete. The whole mechanism for prompting users to continue in case of @@ -3323,6 +3329,12 @@ translation. This is useful when quoting shell arguments for a remote shell invocation. Such shells are POSIX conformant by default. ++++ +** 'make-process' can set connection type independently for input and output. +When calling 'make-process', communication via pty can be enabled +selectively for just input or output by passing a cons cell for +':connection-type', e.g. '(pipe . pty)'. + +++ ** 'signal-process' now consults the list 'signal-process-functions'. This is to determine which function has to be called in order to diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el index 70426ccaf2..99b43661f2 100644 --- a/lisp/eshell/esh-proc.el +++ b/lisp/eshell/esh-proc.el @@ -250,30 +250,6 @@ The prompt will be set to PROMPT." "A marker that tracks the beginning of output of the last subprocess. Used only on systems which do not support async subprocesses.") -(defvar eshell-needs-pipe - '("bc" - ;; xclip.el (in GNU ELPA) calls all of these with - ;; `process-connection-type' set to nil. - "pbpaste" "putclip" "xclip" "xsel" "wl-copy") - "List of commands which need `process-connection-type' to be nil. -Currently only affects commands in pipelines, and not those at -the front. If an element contains a directory part it must match -the full name of a command, otherwise just the nondirectory part must match.") - -(defun eshell-needs-pipe-p (command) - "Return non-nil if COMMAND needs `process-connection-type' to be nil. -See `eshell-needs-pipe'." - (and (bound-and-true-p eshell-in-pipeline-p) - (not (eq eshell-in-pipeline-p 'first)) - ;; FIXME should this return non-nil for anything that is - ;; neither 'first nor 'last? See bug#1388 discussion. - (catch 'found - (dolist (exe eshell-needs-pipe) - (if (string-equal exe (if (string-search "/" exe) - command - (file-name-nondirectory command))) - (throw 'found t)))))) - (defun eshell-gather-process-output (command args) "Gather the output from COMMAND + ARGS." (require 'esh-var) @@ -290,31 +266,36 @@ See `eshell-needs-pipe'." (cond ((fboundp 'make-process) (setq proc - (let ((process-connection-type - (unless (eshell-needs-pipe-p command) - process-connection-type)) - (command (file-local-name (expand-file-name command)))) - (apply #'start-file-process - (file-name-nondirectory command) nil command args))) + (let ((command (file-local-name (expand-file-name command))) + (conn-type (pcase (bound-and-true-p eshell-in-pipeline-p) + ('first '(nil . pipe)) + ('last '(pipe . nil)) + ('t 'pipe) + ('nil nil)))) + (make-process + :name (file-name-nondirectory command) + :buffer (current-buffer) + :command (cons command args) + :filter (if (eshell-interactive-output-p) + #'eshell-output-filter + #'eshell-insertion-filter) + :sentinel #'eshell-sentinel + :connection-type conn-type + :file-handler t))) (eshell-record-process-object proc) - (set-process-buffer proc (current-buffer)) - (set-process-filter proc (if (eshell-interactive-output-p) - #'eshell-output-filter - #'eshell-insertion-filter)) - (set-process-sentinel proc #'eshell-sentinel) (run-hook-with-args 'eshell-exec-hook proc) (when (fboundp 'process-coding-system) (let ((coding-systems (process-coding-system proc))) (setq decoding (car coding-systems) encoding (cdr coding-systems))) - ;; If start-process decided to use some coding system for + ;; If `make-process' decided to use some coding system for ;; decoding data sent from the process and the coding system ;; doesn't specify EOL conversion, we had better convert CRLF ;; to LF. (if (vectorp (coding-system-eol-type decoding)) (setq decoding (coding-system-change-eol-conversion decoding 'dos) changed t)) - ;; Even if start-process left the coding system for encoding + ;; Even if `make-process' left the coding system for encoding ;; data sent from the process undecided, we had better use the ;; same one as what we use for decoding. But, we should ;; suppress EOL conversion. diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index ef0cc2d66c..918de68ea9 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -877,7 +877,10 @@ implementation will be used." (signal 'wrong-type-argument (list #'symbolp coding))) (when (eq connection-type t) (setq connection-type 'pty)) - (unless (memq connection-type '(nil pipe pty)) + (unless (or (and (consp connection-type) + (memq (car connection-type) '(nil pipe pty)) + (memq (cdr connection-type) '(nil pipe pty))) + (memq connection-type '(nil pipe pty))) (signal 'wrong-type-argument (list #'symbolp connection-type))) (unless (or (null filter) (eq filter t) (functionp filter)) (signal 'wrong-type-argument (list #'functionp filter))) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 9e5347252a..38fffadd4e 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -2842,7 +2842,10 @@ implementation will be used." (signal 'wrong-type-argument (list #'symbolp coding))) (when (eq connection-type t) (setq connection-type 'pty)) - (unless (memq connection-type '(nil pipe pty)) + (unless (or (and (consp connection-type) + (memq (car connection-type) '(nil pipe pty)) + (memq (cdr connection-type) '(nil pipe pty))) + (memq connection-type '(nil pipe pty))) (signal 'wrong-type-argument (list #'symbolp connection-type))) (unless (or (null filter) (eq filter t) (functionp filter)) (signal 'wrong-type-argument (list #'functionp filter))) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index dcc8c632f9..ae31287ece 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -4708,7 +4708,10 @@ substitution. SPEC-LIST is a list of char/value pairs used for (signal 'wrong-type-argument (list #'symbolp coding))) (when (eq connection-type t) (setq connection-type 'pty)) - (unless (memq connection-type '(nil pipe pty)) + (unless (or (and (consp connection-type) + (memq (car connection-type) '(nil pipe pty)) + (memq (cdr connection-type) '(nil pipe pty))) + (memq connection-type '(nil pipe pty))) (signal 'wrong-type-argument (list #'symbolp connection-type))) (unless (or (null filter) (eq filter t) (functionp filter)) (signal 'wrong-type-argument (list #'functionp filter))) diff --git a/src/callproc.c b/src/callproc.c index dd162f36a6..aec0a2f5a5 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -650,7 +650,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, child_errno = emacs_spawn (&pid, filefd, fd_output, fd_error, new_argv, env, - SSDATA (current_dir), NULL, &oldset); + SSDATA (current_dir), NULL, false, false, &oldset); eassert ((child_errno == 0) == (0 < pid)); if (pid > 0) @@ -1412,14 +1412,15 @@ emacs_posix_spawn_init_attributes (posix_spawnattr_t *attributes, int emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, char **argv, char **envp, const char *cwd, - const char *pty, const sigset_t *oldset) + const char *pty_name, bool pty_in, bool pty_out, + const sigset_t *oldset) { #if USABLE_POSIX_SPAWN /* Prefer the simpler `posix_spawn' if available. `posix_spawn' doesn't yet support setting up pseudoterminals, so we fall back to `vfork' if we're supposed to use a pseudoterminal. */ - bool use_posix_spawn = pty == NULL; + bool use_posix_spawn = pty_name == NULL; posix_spawn_file_actions_t actions; posix_spawnattr_t attributes; @@ -1473,7 +1474,9 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, /* vfork, and prevent local vars from being clobbered by the vfork. */ pid_t *volatile newpid_volatile = newpid; const char *volatile cwd_volatile = cwd; - const char *volatile pty_volatile = pty; + const char *volatile ptyname_volatile = pty_name; + bool volatile ptyin_volatile = pty_in; + bool volatile ptyout_volatile = pty_out; char **volatile argv_volatile = argv; int volatile stdin_volatile = std_in; int volatile stdout_volatile = std_out; @@ -1495,7 +1498,9 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, newpid = newpid_volatile; cwd = cwd_volatile; - pty = pty_volatile; + pty_name = ptyname_volatile; + pty_in = ptyin_volatile; + pty_out = ptyout_volatile; argv = argv_volatile; std_in = stdin_volatile; std_out = stdout_volatile; @@ -1506,13 +1511,12 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, if (pid == 0) #endif /* not WINDOWSNT */ { - bool pty_flag = pty != NULL; /* Make the pty be the controlling terminal of the process. */ #ifdef HAVE_PTYS dissociate_controlling_tty (); /* Make the pty's terminal the controlling terminal. */ - if (pty_flag && std_in >= 0) + if (pty_in && std_in >= 0) { #ifdef TIOCSCTTY /* We ignore the return value @@ -1521,7 +1525,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, #endif } #if defined (LDISC1) - if (pty_flag && std_in >= 0) + if (pty_in && std_in >= 0) { struct termios t; tcgetattr (std_in, &t); @@ -1531,7 +1535,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, } #else #if defined (NTTYDISC) && defined (TIOCSETD) - if (pty_flag && std_in >= 0) + if (pty_in && std_in >= 0) { /* Use new line discipline. */ int ldisc = NTTYDISC; @@ -1548,18 +1552,21 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, both TIOCSCTTY is defined. */ /* Now close the pty (if we had it open) and reopen it. This makes the pty the controlling terminal of the subprocess. */ - if (pty_flag) + if (pty_name) { /* I wonder if emacs_close (emacs_open (pty, ...)) would work? */ - if (std_in >= 0) + if (pty_in && std_in >= 0) emacs_close (std_in); - std_out = std_in = emacs_open_noquit (pty, O_RDWR, 0); - + int ptyfd = emacs_open_noquit (pty_name, O_RDWR, 0); + if (pty_in) + std_in = ptyfd; + if (pty_out) + std_out = ptyfd; if (std_in < 0) { - emacs_perror (pty); + emacs_perror (pty_name); _exit (EXIT_CANCELED); } @@ -1599,7 +1606,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, /* Stop blocking SIGCHLD in the child. */ unblock_child_signal (oldset); - if (pty_flag) + if (pty_out) child_setup_tty (std_out); #endif diff --git a/src/lisp.h b/src/lisp.h index 8e36620fe5..fe6e98843d 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4943,7 +4943,8 @@ extern void setup_process_coding_systems (Lisp_Object); #endif extern int emacs_spawn (pid_t *, int, int, int, char **, char **, - const char *, const char *, const sigset_t *); + const char *, const char *, bool, bool, + const sigset_t *); extern char **make_environment_block (Lisp_Object) ATTRIBUTE_RETURNS_NONNULL; extern void init_callproc_1 (void); extern void init_callproc (void); diff --git a/src/process.c b/src/process.c index 1ac5a509e5..68dbd8b68b 100644 --- a/src/process.c +++ b/src/process.c @@ -1316,6 +1316,19 @@ set_process_filter_masks (struct Lisp_Process *p) add_process_read_fd (p->infd); } +static bool +is_pty_from_symbol (Lisp_Object symbol) +{ + if (EQ (symbol, Qpty)) + return true; + else if (EQ (symbol, Qpipe)) + return false; + else if (NILP (symbol)) + return !NILP (Vprocess_connection_type); + else + report_file_error ("Unknown connection type", symbol); +} + DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter, 2, 2, 0, doc: /* Give PROCESS the filter function FILTER; nil means default. @@ -1741,15 +1754,18 @@ signals to stop and continue a process. :connection-type TYPE -- TYPE is control type of device used to communicate with subprocesses. Values are `pipe' to use a pipe, `pty' to use a pty, or nil to use the default specified through -`process-connection-type'. +`process-connection-type'. If TYPE is a cons (INPUT . OUTPUT), then +INPUT will be used for standard input and OUTPUT for standard output +(and standard error if `:stderr' is nil). :filter FILTER -- Install FILTER as the process filter. :sentinel SENTINEL -- Install SENTINEL as the process sentinel. :stderr STDERR -- STDERR is either a buffer or a pipe process attached -to the standard error of subprocess. Specifying this implies -`:connection-type' is set to `pipe'. If STDERR is nil, standard error +to the standard error of subprocess. When specifying this, the +subprocess's standard error will always communicate via a pipe, no +matter the value of `:connection-type'. If STDERR is nil, standard error is mixed with standard output and sent to BUFFER or FILTER. (Note that specifying :stderr will create a new, separate (but associated) process, with its own filter and sentinel. See @@ -1845,22 +1861,20 @@ usage: (make-process &rest ARGS) */) CHECK_TYPE (NILP (tem), Qnull, tem); tem = plist_get (contact, QCconnection_type); - if (EQ (tem, Qpty)) - XPROCESS (proc)->pty_flag = true; - else if (EQ (tem, Qpipe)) - XPROCESS (proc)->pty_flag = false; - else if (NILP (tem)) - XPROCESS (proc)->pty_flag = !NILP (Vprocess_connection_type); + if (CONSP (tem)) + { + XPROCESS (proc)->pty_in = is_pty_from_symbol (XCAR (tem)); + XPROCESS (proc)->pty_out = is_pty_from_symbol (XCDR (tem)); + } else - report_file_error ("Unknown connection type", tem); - - if (!NILP (stderrproc)) { - pset_stderrproc (XPROCESS (proc), stderrproc); - - XPROCESS (proc)->pty_flag = false; + XPROCESS (proc)->pty_in = XPROCESS (proc)->pty_out = + is_pty_from_symbol (tem); } + if (!NILP (stderrproc)) + pset_stderrproc (XPROCESS (proc), stderrproc); + #ifdef HAVE_GNUTLS /* AKA GNUTLS_INITSTAGE(proc). */ verify (GNUTLS_STAGE_EMPTY == 0); @@ -2099,66 +2113,80 @@ static void create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) { struct Lisp_Process *p = XPROCESS (process); - int inchannel, outchannel; + int inchannel = -1, outchannel = -1; pid_t pid = -1; int vfork_errno; int forkin, forkout, forkerr = -1; - bool pty_flag = 0; + bool pty_in = false, pty_out = false; char pty_name[PTY_NAME_SIZE]; Lisp_Object lisp_pty_name = Qnil; + int ptychannel = -1, pty_tty = -1; sigset_t oldset; /* Ensure that the SIGCHLD handler can notify `wait_reading_process_output'. */ child_signal_init (); - inchannel = outchannel = -1; - - if (p->pty_flag) - outchannel = inchannel = allocate_pty (pty_name); + if (p->pty_in || p->pty_out) + ptychannel = allocate_pty (pty_name); - if (inchannel >= 0) + if (ptychannel >= 0) { - p->open_fd[READ_FROM_SUBPROCESS] = inchannel; #if ! defined (USG) || defined (USG_SUBTTY_WORKS) /* On most USG systems it does not work to open the pty's tty here, then close it and reopen it in the child. */ /* Don't let this terminal become our controlling terminal (in case we don't have one). */ - forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); - if (forkin < 0) + pty_tty = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); + if (pty_tty < 0) report_file_error ("Opening pty", Qnil); - p->open_fd[SUBPROCESS_STDIN] = forkin; -#else - forkin = forkout = -1; #endif /* not USG, or USG_SUBTTY_WORKS */ - pty_flag = 1; + pty_in = p->pty_in; + pty_out = p->pty_out; lisp_pty_name = build_string (pty_name); } + + /* Set up stdin for the child process. */ + if (ptychannel >= 0 && p->pty_in) + { + p->open_fd[SUBPROCESS_STDIN] = forkin = pty_tty; + outchannel = ptychannel; + } else { - if (emacs_pipe (p->open_fd + SUBPROCESS_STDIN) != 0 - || emacs_pipe (p->open_fd + READ_FROM_SUBPROCESS) != 0) + if (emacs_pipe (p->open_fd + SUBPROCESS_STDIN) != 0) report_file_error ("Creating pipe", Qnil); forkin = p->open_fd[SUBPROCESS_STDIN]; outchannel = p->open_fd[WRITE_TO_SUBPROCESS]; + } + + /* Set up stdout for the child process. */ + if (ptychannel >= 0 && p->pty_out) + { + forkout = pty_tty; + p->open_fd[READ_FROM_SUBPROCESS] = inchannel = ptychannel; + } + else + { + if (emacs_pipe (p->open_fd + READ_FROM_SUBPROCESS) != 0) + report_file_error ("Creating pipe", Qnil); inchannel = p->open_fd[READ_FROM_SUBPROCESS]; forkout = p->open_fd[SUBPROCESS_STDOUT]; #if defined(GNU_LINUX) && defined(F_SETPIPE_SZ) fcntl (inchannel, F_SETPIPE_SZ, read_process_output_max); #endif + } - if (!NILP (p->stderrproc)) - { - struct Lisp_Process *pp = XPROCESS (p->stderrproc); + if (!NILP (p->stderrproc)) + { + struct Lisp_Process *pp = XPROCESS (p->stderrproc); - forkerr = pp->open_fd[SUBPROCESS_STDOUT]; + forkerr = pp->open_fd[SUBPROCESS_STDOUT]; - /* Close unnecessary file descriptors. */ - close_process_fd (&pp->open_fd[WRITE_TO_SUBPROCESS]); - close_process_fd (&pp->open_fd[SUBPROCESS_STDIN]); - } + /* Close unnecessary file descriptors. */ + close_process_fd (&pp->open_fd[WRITE_TO_SUBPROCESS]); + close_process_fd (&pp->open_fd[SUBPROCESS_STDIN]); } if (FD_SETSIZE <= inchannel || FD_SETSIZE <= outchannel) @@ -2183,7 +2211,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) we just reopen the device (see emacs_get_tty_pgrp) as this is more portable (see USG_SUBTTY_WORKS above). */ - p->pty_flag = pty_flag; + p->pty_in = pty_in; + p->pty_out = pty_out; pset_status (p, Qrun); if (!EQ (p->command, Qt) @@ -2199,13 +2228,15 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) block_input (); block_child_signal (&oldset); - pty_flag = p->pty_flag; - eassert (pty_flag == ! NILP (lisp_pty_name)); + pty_in = p->pty_in; + pty_out = p->pty_out; + eassert ((pty_in || pty_out) == ! NILP (lisp_pty_name)); vfork_errno = emacs_spawn (&pid, forkin, forkout, forkerr, new_argv, env, SSDATA (current_dir), - pty_flag ? SSDATA (lisp_pty_name) : NULL, &oldset); + pty_in || pty_out ? SSDATA (lisp_pty_name) : NULL, + pty_in, pty_out, &oldset); eassert ((vfork_errno == 0) == (0 < pid)); @@ -2263,7 +2294,7 @@ create_pty (Lisp_Object process) { struct Lisp_Process *p = XPROCESS (process); char pty_name[PTY_NAME_SIZE]; - int pty_fd = !p->pty_flag ? -1 : allocate_pty (pty_name); + int pty_fd = !(p->pty_in || p->pty_out) ? -1 : allocate_pty (pty_name); if (pty_fd >= 0) { @@ -2301,7 +2332,7 @@ create_pty (Lisp_Object process) we just reopen the device (see emacs_get_tty_pgrp) as this is more portable (see USG_SUBTTY_WORKS above). */ - p->pty_flag = 1; + p->pty_in = p->pty_out = true; pset_status (p, Qrun); setup_process_coding_systems (process); @@ -2412,7 +2443,7 @@ usage: (make-pipe-process &rest ARGS) */) p->kill_without_query = 1; if (tem = plist_get (contact, QCstop), !NILP (tem)) pset_command (p, Qt); - eassert (! p->pty_flag); + eassert (! p->pty_in && ! p->pty_out); if (!EQ (p->command, Qt) && !EQ (p->filter, Qt)) @@ -3147,7 +3178,7 @@ usage: (make-serial-process &rest ARGS) */) p->kill_without_query = 1; if (tem = plist_get (contact, QCstop), !NILP (tem)) pset_command (p, Qt); - eassert (! p->pty_flag); + eassert (! p->pty_in && ! p->pty_out); if (!EQ (p->command, Qt) && !EQ (p->filter, Qt)) @@ -6808,7 +6839,7 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, error ("Process %s is not active", SDATA (p->name)); - if (!p->pty_flag) + if (! p->pty_in) current_group = Qnil; /* If we are using pgrps, get a pgrp number and make it negative. */ @@ -7177,7 +7208,7 @@ process has been transmitted to the serial port. */) send_process (proc, "", 0, Qnil); } - if (XPROCESS (proc)->pty_flag) + if (XPROCESS (proc)->pty_in) send_process (proc, "\004", 1, Qnil); else if (EQ (XPROCESS (proc)->type, Qserial)) { diff --git a/src/process.h b/src/process.h index 392b661ce6..92baf0c4cb 100644 --- a/src/process.h +++ b/src/process.h @@ -156,8 +156,9 @@ struct Lisp_Process /* True means kill silently if Emacs is exited. This is the inverse of the `query-on-exit' flag. */ bool_bf kill_without_query : 1; - /* True if communicating through a pty. */ - bool_bf pty_flag : 1; + /* True if communicating through a pty for input or output. */ + bool_bf pty_in : 1; + bool_bf pty_out : 1; /* Flag to set coding-system of the process buffer from the coding_system used to decode process output. */ bool_bf inherit_coding_system_flag : 1; diff --git a/test/lisp/eshell/esh-proc-tests.el b/test/lisp/eshell/esh-proc-tests.el index 7f461d1813..734bb91a6a 100644 --- a/test/lisp/eshell/esh-proc-tests.el +++ b/test/lisp/eshell/esh-proc-tests.el @@ -28,6 +28,15 @@ (file-name-directory (or load-file-name default-directory)))) +(defvar esh-proc-test--detect-pty-cmd + (concat "sh -c '" + "if [ -t 0 ]; then echo stdin; fi; " + "if [ -t 1 ]; then echo stdout; fi; " + "if [ -t 2 ]; then echo stderr; fi" + "'")) + +;;; Tests: + (ert-deftest esh-proc-test/sigpipe-exits-process () "Test that a SIGPIPE is properly sent to a process if a pipe closes" (skip-unless (and (executable-find "sh") @@ -44,6 +53,40 @@ (eshell-wait-for-subprocess t) (should (eq (process-list) nil)))) +(ert-deftest esh-proc-test/pipeline-connection-type/no-pipeline () + "Test that all streams are PTYs when a command is not in a pipeline." + (skip-unless (executable-find "sh")) + (should (equal (eshell-test-command-result esh-proc-test--detect-pty-cmd) + ;; PTYs aren't supported on MS-Windows. + (unless (eq system-type 'windows-nt) + "stdin\nstdout\nstderr\n")))) + +(ert-deftest esh-proc-test/pipeline-connection-type/first () + "Test that only stdin is a PTY when a command starts a pipeline." + (skip-unless (and (executable-find "sh") + (executable-find "cat"))) + (should (equal (eshell-test-command-result + (concat esh-proc-test--detect-pty-cmd " | cat")) + (unless (eq system-type 'windows-nt) + "stdin\n")))) + +(ert-deftest esh-proc-test/pipeline-connection-type/middle () + "Test that all streams are pipes when a command is in the middle of a +pipeline." + (skip-unless (and (executable-find "sh") + (executable-find "cat"))) + (should (equal (eshell-test-command-result + (concat "echo | " esh-proc-test--detect-pty-cmd " | cat")) + nil))) + +(ert-deftest esh-proc-test/pipeline-connection-type/last () + "Test that only output streams are PTYs when a command ends a pipeline." + (skip-unless (executable-find "sh")) + (should (equal (eshell-test-command-result + (concat "echo | " esh-proc-test--detect-pty-cmd)) + (unless (eq system-type 'windows-nt) + "stdout\nstderr\n")))) + (ert-deftest esh-proc-test/kill-pipeline () "Test that killing a pipeline of processes only emits a single prompt. See bug#54136." diff --git a/test/src/process-tests.el b/test/src/process-tests.el index aab95b2d73..b801563feb 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -38,10 +38,11 @@ ;; Timeout in seconds; the test fails if the timeout is reached. (defvar process-test-sentinel-wait-timeout 2.0) -;; Start a process that exits immediately. Call WAIT-FUNCTION, -;; possibly multiple times, to wait for the process to complete. -(defun process-test-sentinel-wait-function-working-p (wait-function) - (let ((proc (start-process "test" nil "bash" "-c" "exit 20")) +(defun process-test-wait-for-sentinel (proc exit-status &optional wait-function) + "Set a sentinel on PROC and wait for it to be called with EXIT-STATUS. +Call WAIT-FUNCTION, possibly multiple times, to wait for the +process to complete." + (let ((wait-function (or wait-function #'accept-process-output)) (sentinel-called nil) (start-time (float-time))) (set-process-sentinel proc (lambda (_proc _msg) @@ -50,21 +51,22 @@ (> (- (float-time) start-time) process-test-sentinel-wait-timeout))) (funcall wait-function)) - (cl-assert (eq (process-status proc) 'exit)) - (cl-assert (= (process-exit-status proc) 20)) - sentinel-called)) + (should sentinel-called) + (should (eq (process-status proc) 'exit)) + (should (= (process-exit-status proc) exit-status)))) (ert-deftest process-test-sentinel-accept-process-output () (skip-unless (executable-find "bash")) (with-timeout (60 (ert-fail "Test timed out")) - (should (process-test-sentinel-wait-function-working-p - #'accept-process-output)))) + (let ((proc (start-process "test" nil "bash" "-c" "exit 20"))) + (should (process-test-wait-for-sentinel proc 20))))) (ert-deftest process-test-sentinel-sit-for () (skip-unless (executable-find "bash")) (with-timeout (60 (ert-fail "Test timed out")) - (should - (process-test-sentinel-wait-function-working-p (lambda () (sit-for 0.01 t)))))) + (let ((proc (start-process "test" nil "bash" "-c" "exit 20"))) + (should (process-test-wait-for-sentinel + proc 20 (lambda () (sit-for 0.01 t))))))) (when (eq system-type 'windows-nt) (ert-deftest process-test-quoted-batfile () @@ -97,17 +99,8 @@ "echo hello stderr! >&2; " "exit 20")) :buffer stdout-buffer - :stderr stderr-buffer)) - (sentinel-called nil) - (start-time (float-time))) - (set-process-sentinel proc (lambda (_proc _msg) - (setq sentinel-called t))) - (while (not (or sentinel-called - (> (- (float-time) start-time) - process-test-sentinel-wait-timeout))) - (accept-process-output)) - (cl-assert (eq (process-status proc) 'exit)) - (cl-assert (= (process-exit-status proc) 20)) + :stderr stderr-buffer))) + (process-test-wait-for-sentinel proc 20) (should (with-current-buffer stdout-buffer (goto-char (point-min)) (looking-at "hello stdout!"))) @@ -118,8 +111,7 @@ (ert-deftest process-test-stderr-filter () (skip-unless (executable-find "bash")) (with-timeout (60 (ert-fail "Test timed out")) - (let* ((sentinel-called nil) - (stderr-sentinel-called nil) + (let* ((stderr-sentinel-called nil) (stdout-output nil) (stderr-output nil) (stdout-buffer (generate-new-buffer "*stdout*")) @@ -131,23 +123,14 @@ (concat "echo hello stdout!; " "echo hello stderr! >&2; " "exit 20")) - :stderr stderr-proc)) - (start-time (float-time))) + :stderr stderr-proc))) (set-process-filter proc (lambda (_proc input) (push input stdout-output))) - (set-process-sentinel proc (lambda (_proc _msg) - (setq sentinel-called t))) (set-process-filter stderr-proc (lambda (_proc input) (push input stderr-output))) (set-process-sentinel stderr-proc (lambda (_proc _input) (setq stderr-sentinel-called t))) - (while (not (or sentinel-called - (> (- (float-time) start-time) - process-test-sentinel-wait-timeout))) - (accept-process-output)) - (cl-assert (eq (process-status proc) 'exit)) - (cl-assert (= (process-exit-status proc) 20)) - (should sentinel-called) + (process-test-wait-for-sentinel proc 20) (should (equal 1 (with-current-buffer stdout-buffer (point-max)))) (should (equal "hello stdout!\n" @@ -289,6 +272,74 @@ (error :got-error)))) (should have-called-debugger)))) +(defun make-process/test-connection-type (ttys &rest args) + "Make a process and check whether its standard streams match TTYS. +This calls `make-process', passing ARGS to adjust how the process +is created. TTYS should be a list of 3 boolean values, +indicating whether the subprocess's stdin, stdout, and stderr +should be a TTY, respectively." + (declare (indent 1)) + (let* (;; MS-Windows doesn't support communicating via pty. + (ttys (if (eq system-type 'windows-nt) '(nil nil nil) ttys)) + (expected-output (concat (and (nth 0 ttys) "stdin\n") + (and (nth 1 ttys) "stdout\n") + (and (nth 2 ttys) "stderr\n"))) + (stdout-buffer (generate-new-buffer "*stdout*")) + (proc (apply + #'make-process + :name "test" + :command (list "sh" "-c" + (concat "if [ -t 0 ]; then echo stdin; fi; " + "if [ -t 1 ]; then echo stdout; fi; " + "if [ -t 2 ]; then echo stderr; fi")) + :buffer stdout-buffer + args))) + (process-test-wait-for-sentinel proc 0) + (should (equal (with-current-buffer stdout-buffer (buffer-string)) + expected-output)))) + +(ert-deftest make-process/connection-type/pty () + (skip-unless (executable-find "sh")) + (make-process/test-connection-type '(t t t) + :connection-type 'pty)) + +(ert-deftest make-process/connection-type/pty-2 () + (skip-unless (executable-find "sh")) + (make-process/test-connection-type '(t t t) + :connection-type '(pty . pty))) + +(ert-deftest make-process/connection-type/pipe () + (skip-unless (executable-find "sh")) + (make-process/test-connection-type '(nil nil nil) + :connection-type 'pipe)) + +(ert-deftest make-process/connection-type/pipe-2 () + (skip-unless (executable-find "sh")) + (make-process/test-connection-type '(nil nil nil) + :connection-type '(pipe . pipe))) + +(ert-deftest make-process/connection-type/in-pty () + (skip-unless (executable-find "sh")) + (make-process/test-connection-type '(t nil nil) + :connection-type '(pty . pipe))) + +(ert-deftest make-process/connection-type/out-pty () + (skip-unless (executable-find "sh")) + (make-process/test-connection-type '(nil t t) + :connection-type '(pipe . pty))) + +(ert-deftest make-process/connection-type/pty-with-stderr-buffer () + (skip-unless (executable-find "sh")) + (let ((stderr-buffer (generate-new-buffer "*stderr*"))) + (make-process/test-connection-type '(t t nil) + :connection-type 'pty :stderr stderr-buffer))) + +(ert-deftest make-process/connection-type/out-pty-with-stderr-buffer () + (skip-unless (executable-find "sh")) + (let ((stderr-buffer (generate-new-buffer "*stderr*"))) + (make-process/test-connection-type '(nil t nil) + :connection-type '(pipe . pty) :stderr stderr-buffer))) + (ert-deftest make-process/file-handler/found () "Check that the `:file-handler’ argument of `make-process’ works as expected if a file name handler is found." commit b70369c557efed3dcd86dc64a2e73e3480dea6af Author: Stefan Monnier Date: Fri Aug 5 18:46:31 2022 -0400 time-convert): Deprecate calls without an explicit FORM arg * lisp/subr.el (time-convert): Deprecate calls without an explicit FORM arg. * doc/lispref/os.texi (Time Conversion): Adjust doc accordingly. * lisp/calendar/time-date.el (days-to-time): * lisp/emacs-lisp/timer.el (timer-next-integral-multiple-of-time): * lisp/gnus/nnrss.el (nnrss-normalize-date): * lisp/epa-ks.el (epa-ks--parse-buffer): Silence corresponding warnings. diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index 5fb34fb9b6..d591b219cd 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -1541,7 +1541,7 @@ Year numbers count since the year 1 BCE, and do not skip zero as traditional Gregorian years do; for example, the year number @minus{}37 represents the Gregorian year 38 BCE@. -@defun time-convert time &optional form +@defun time-convert time form This function converts a time value into a Lisp timestamp. The optional @var{form} argument specifies the timestamp form to be @@ -1554,7 +1554,7 @@ representing the timestamp; for example, it is treated as 1000000000 if @var{time} is @code{nil} and the platform timestamp has nanosecond resolution. If @var{form} is @code{list}, this function returns an integer list @code{(@var{high} @var{low} @var{micro} @var{pico})}. -Although an omitted or @code{nil} @var{form} currently acts like +Although a @code{nil} @var{form} currently acts like @code{list}, this is planned to change in a future Emacs version, so callers requiring list timestamps should pass @code{list} explicitly. diff --git a/etc/NEWS b/etc/NEWS index 7145a8861e..dc8bd6ce24 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2525,6 +2525,10 @@ patcomp.el, pc-mode.el, pc-select.el, s-region.el, and sregex.el. * Lisp Changes in Emacs 29.1 +** The FORM arg of 'time-convert' is mandatory. +'time-convert' can still be called without it, as before, but the +compiler now emits a warning about this deprecated usage. + +++ ** Emacs now supports user-customizable and themable icons. These can be used for buttons in buffers and the like. See diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el index 7c99d05dc3..b80b47a33f 100644 --- a/lisp/calendar/time-date.el +++ b/lisp/calendar/time-date.el @@ -179,7 +179,10 @@ If DATE lacks timezone information, GMT is assumed." ;;;###autoload (defun days-to-time (days) "Convert DAYS into a time value." - (let ((time (time-convert (* 86400 days)))) + ;; FIXME: We should likely just pass `t' to `time-convert'. + ;; All uses I could find in Emacs, GNU ELPA, and NonGNU ELPA can handle + ;; any valid time representation as return value. + (let ((time (time-convert (* 86400 days) 'list))) ;; Traditionally, this returned a two-element list if DAYS was an integer. ;; Keep that tradition if time-convert outputs timestamps in list form. (if (and (integerp days) (consp (cdr time))) diff --git a/lisp/emacs-lisp/timer.el b/lisp/emacs-lisp/timer.el index aafb2e684f..b25a040a96 100644 --- a/lisp/emacs-lisp/timer.el +++ b/lisp/emacs-lisp/timer.el @@ -122,7 +122,7 @@ of SECS seconds since the epoch. SECS may be a fraction." (setq ticks (ash ticks 1)) (setq hz (ash hz 1))) (let ((more-ticks (+ ticks trunc-s-ticks))) - (time-convert (cons (- more-ticks (% more-ticks trunc-s-ticks)) hz))))) + (time-convert (cons (- more-ticks (% more-ticks trunc-s-ticks)) hz) t)))) (defun timer-relative-time (time secs &optional usecs psecs) "Advance TIME by SECS seconds. diff --git a/lisp/epa-ks.el b/lisp/epa-ks.el index f41429f773..7c60b659f0 100644 --- a/lisp/epa-ks.el +++ b/lisp/epa-ks.el @@ -295,13 +295,11 @@ enough, since keyservers have strict timeout settings." :created (and (match-string 4) (not (string-empty-p (match-string 4))) - (time-convert - (string-to-number (match-string 4)))) + (time-convert (string-to-number (match-string 4)) t)) :expires (and (match-string 5) (not (string-empty-p (match-string 5))) - (time-convert - (string-to-number (match-string 5)))) + (time-convert (string-to-number (match-string 5)) t)) :flags (mapcar (lambda (flag) (cdr (assq flag '((?r revoked) diff --git a/lisp/gnus/nnrss.el b/lisp/gnus/nnrss.el index 5047be1a6a..8c96d3e067 100644 --- a/lisp/gnus/nnrss.el +++ b/lisp/gnus/nnrss.el @@ -453,8 +453,8 @@ which RSS 2.0 allows." (let (case-fold-search vector year month day time zone given) (cond ((null date)) ; do nothing for this case ;; if the date is just digits (unix time stamp): - ((string-match "^[0-9]+$" date) - (setq given (time-convert (string-to-number date)))) + ((string-match "\\`[0-9]+\\'" date) + (setq given (time-convert (string-to-number date) t))) ;; RFC 822 ((string-match " [0-9]+ " date) (setq vector (timezone-parse-date date) diff --git a/lisp/subr.el b/lisp/subr.el index 2603b5ad25..4b1fc832da 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1857,6 +1857,7 @@ be a list of the form returned by `event-start' and `event-end'." (set-advertised-calling-convention 'redirect-frame-focus '(frame focus-frame) "24.3") (set-advertised-calling-convention 'libxml-parse-xml-region '(start end &optional base-url) "27.1") (set-advertised-calling-convention 'libxml-parse-html-region '(start end &optional base-url) "27.1") +(set-advertised-calling-convention 'time-convert '(time form) "29.1") ;;;; Obsolescence declarations for variables, and aliases. commit 32c603e9e557aa8bc448bd0b3af493a9244d1aae Author: Lars Ingebrigtsen Date: Fri Aug 5 23:48:33 2022 +0200 Ensure that leim-list.el is built * lisp/Makefile.in: Ensure that leim-list.el is built (bug#56998). diff --git a/lisp/Makefile.in b/lisp/Makefile.in index f0a66aafb5..14582611fd 100644 --- a/lisp/Makefile.in +++ b/lisp/Makefile.in @@ -187,8 +187,10 @@ org-manuals: main-first # The real dependencies of loaddefs.el aren't known to Make, they are # implemented in loaddefs-generate--emacs-batch, so autoloads is an -# "all" dependency. -autoloads: $(lisp)/emacs-lisp/loaddefs-gen.elc +# "all" dependency. "leim" isn't really a dependency here, but we +# need leim-list.el at about the same time, so ensure that it's +# generated, too. +autoloads: $(lisp)/emacs-lisp/loaddefs-gen.elc leim $(AM_V_GEN)$(emacs) \ -l $(lisp)/emacs-lisp/loaddefs-gen.elc \ -f loaddefs-generate--emacs-batch ${SUBDIRS_ALMOST} commit ea6c2e92958a10c7fd6b250f40fec66ac54a59ff Author: Stefan Kangas Date: Fri Aug 5 20:17:23 2022 +0200 Allow newline after def*-form for definition-prefix * lisp/emacs-lisp/loaddefs-gen.el (autoload-ignored-definitions): Add another semantic function. (loaddefs-generate--compute-prefixes): Allow newline after the "(def*" form. (Bug#57000) diff --git a/lisp/emacs-lisp/loaddefs-gen.el b/lisp/emacs-lisp/loaddefs-gen.el index afba9f8fbc..8aa17be765 100644 --- a/lisp/emacs-lisp/loaddefs-gen.el +++ b/lisp/emacs-lisp/loaddefs-gen.el @@ -68,6 +68,7 @@ be included.") "define-short-documentation-group" "def-edebug-elem-spec" "defvar-mode-local" + "defcustom-mode-local-semantic-dependency-system-include-path" "define-ibuffer-column" "define-ibuffer-sorter") "List of strings naming definitions to ignore for prefixes. @@ -456,7 +457,7 @@ don't include." (let ((prefs nil)) ;; Avoid (defvar ) by requiring a trailing space. (while (re-search-forward - "^(\\(def[^ \t]+\\)[ \t]+['(]*\\([^' ()\"\n]+\\)[\n \t]" nil t) + "^(\\(def[^ \t\n]+\\)[ \t\n]+['(]*\\([^' ()\"\n]+\\)[\n \t]" nil t) (unless (member (match-string 1) autoload-ignored-definitions) (let ((name (match-string-no-properties 2))) (when (save-excursion commit 50730a8b04ede381c958600a1400efe8d04d9dfc Author: Filipp Gunbin Date: Fri Aug 5 21:01:10 2022 +0300 Add variable end-of-defun-moves-to-eol * lisp/emacs-lisp/lisp.el (end-of-defun-moves-to-eol): New variable. (end-of-defun): Use it. diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el index 4b85414943..cc8185e453 100644 --- a/lisp/emacs-lisp/lisp.el +++ b/lisp/emacs-lisp/lisp.el @@ -507,6 +507,13 @@ It is called with no argument, right after calling `beginning-of-defun-raw'. So the function can assume that point is at the beginning of the defun body. It should move point to the first position after the defun.") +(defvar end-of-defun-moves-to-eol t + "Defines whether `end-of-defun' moves to eol before doing +everything else. + +Set this to nil in major mode if this movement affects mode's +decisions about context in an unwanted way.") + (defun buffer-end (arg) "Return the \"far end\" position of the buffer, in direction ARG. If ARG is positive, that's the end of the buffer. @@ -538,7 +545,9 @@ report errors as appropriate for this kind of usage." (push-mark)) (if (or (null arg) (= arg 0)) (setq arg 1)) (let ((pos (point)) - (beg (progn (end-of-line 1) (beginning-of-defun-raw 1) (point))) + (beg (progn (when end-of-defun-moves-to-eol + (end-of-line 1)) + (beginning-of-defun-raw 1) (point))) (skip (lambda () ;; When comparing point against pos, we want to consider that ;; if point was right after the end of the function, it's commit 0da97d66852a0ab3abd3b4116825338636ac9367 Author: Stefan Monnier Date: Fri Aug 5 12:34:47 2022 -0400 * src/keyboard.c (timer_check_2): Replace redundant test with assertion diff --git a/src/keyboard.c b/src/keyboard.c index 02e02448ff..81e73a2833 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -4642,27 +4642,27 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) /* If timer is ripe, run it if it hasn't been run. */ if (ripe) { - if (NILP (AREF (chosen_timer, 0))) - { - specpdl_ref count = SPECPDL_INDEX (); - Lisp_Object old_deactivate_mark = Vdeactivate_mark; + /* If we got here, presumably `decode_timer` has checked + that this timer has not yet been triggered. */ + eassert (NILP (AREF (chosen_timer, 0))); + specpdl_ref count = SPECPDL_INDEX (); + Lisp_Object old_deactivate_mark = Vdeactivate_mark; - /* Mark the timer as triggered to prevent problems if the lisp - code fails to reschedule it right. */ - ASET (chosen_timer, 0, Qt); + /* Mark the timer as triggered to prevent problems if the lisp + code fails to reschedule it right. */ + ASET (chosen_timer, 0, Qt); - specbind (Qinhibit_quit, Qt); + specbind (Qinhibit_quit, Qt); - call1 (Qtimer_event_handler, chosen_timer); - Vdeactivate_mark = old_deactivate_mark; - timers_run++; - unbind_to (count, Qnil); + call1 (Qtimer_event_handler, chosen_timer); + Vdeactivate_mark = old_deactivate_mark; + timers_run++; + unbind_to (count, Qnil); - /* Since we have handled the event, - we don't need to tell the caller to wake up and do it. */ - /* But the caller must still wait for the next timer, so - return 0 to indicate that. */ - } + /* Since we have handled the event, + we don't need to tell the caller to wake up and do it. */ + /* But the caller must still wait for the next timer, so + return 0 to indicate that. */ nexttime = make_timespec (0, 0); break; commit eb7fe81e6db8d630521098a728713e10c9d59c74 Author: Stefan Monnier Date: Fri Aug 5 10:38:59 2022 -0400 timer.el: Avoid repeated timers https://mail.gnu.org/archive/html/emacs-devel/2022-07/msg01127.html points out that end-users can get bitten by this, accidentally calling `timer-activate` on an already activated timer. * lisp/emacs-lisp/timer.el (timer--activate): Signal an error if we try to re-add a timer that's already on the timer-list. diff --git a/lisp/emacs-lisp/timer.el b/lisp/emacs-lisp/timer.el index fd29abf40a..aafb2e684f 100644 --- a/lisp/emacs-lisp/timer.el +++ b/lisp/emacs-lisp/timer.el @@ -159,32 +159,42 @@ SECS may be a fraction." timer) (defun timer--activate (timer &optional triggered-p reuse-cell idle) - (if (and (timerp timer) - (integerp (timer--high-seconds timer)) - (integerp (timer--low-seconds timer)) - (integerp (timer--usecs timer)) - (integerp (timer--psecs timer)) - (timer--function timer)) - (let ((timers (if idle timer-idle-list timer-list)) - last) - ;; Skip all timers to trigger before the new one. - (while (and timers (timer--time-less-p (car timers) timer)) - (setq last timers - timers (cdr timers))) - (if reuse-cell - (progn - (setcar reuse-cell timer) - (setcdr reuse-cell timers)) - (setq reuse-cell (cons timer timers))) - ;; Insert new timer after last which possibly means in front of queue. - (setf (cond (last (cdr last)) - (idle timer-idle-list) - (t timer-list)) - reuse-cell) - (setf (timer--triggered timer) triggered-p) - (setf (timer--idle-delay timer) idle) - nil) - (error "Invalid or uninitialized timer"))) + (let ((timers (if idle timer-idle-list timer-list)) + last) + (cond + ((not (and (timerp timer) + (integerp (timer--high-seconds timer)) + (integerp (timer--low-seconds timer)) + (integerp (timer--usecs timer)) + (integerp (timer--psecs timer)) + (timer--function timer))) + (error "Invalid or uninitialized timer")) + ;; FIXME: This is not reliable because `idle-delay' is only set late, + ;; by `timer-activate-when-idle' :-( + ;;((not (eq (not idle) + ;; (not (timer--idle-delay timer)))) + ;; (error "idle arg %S out of sync with idle-delay field of timer: %S" + ;; idle timer)) + ((memq timer timers) + (error "Timer already activated")) + (t + ;; Skip all timers to trigger before the new one. + (while (and timers (timer--time-less-p (car timers) timer)) + (setq last timers + timers (cdr timers))) + (if reuse-cell + (progn + (setcar reuse-cell timer) + (setcdr reuse-cell timers)) + (setq reuse-cell (cons timer timers))) + ;; Insert new timer after last which possibly means in front of queue. + (setf (cond (last (cdr last)) + (idle timer-idle-list) + (t timer-list)) + reuse-cell) + (setf (timer--triggered timer) triggered-p) + (setf (timer--idle-delay timer) idle) + nil)))) (defun timer-activate (timer &optional triggered-p reuse-cell) "Insert TIMER into `timer-list'. @@ -216,7 +226,7 @@ the time of the current timer. That's because the activated timer will fire right away." (timer--activate timer (not dont-wait) reuse-cell 'idle)) -(defalias 'disable-timeout 'cancel-timer) +(defalias 'disable-timeout #'cancel-timer) (defun cancel-timer (timer) "Remove TIMER from the list of active timers." @@ -430,7 +440,7 @@ The action is to call FUNCTION with arguments ARGS. This function returns a timer object which you can use in `cancel-timer'." (interactive "sRun after delay (seconds): \nNRepeat interval: \naFunction: ") - (apply 'run-at-time secs repeat function args)) + (apply #'run-at-time secs repeat function args)) (defun add-timeout (secs function object &optional repeat) "Add a timer to run SECS seconds from now, to call FUNCTION on OBJECT. @@ -457,7 +467,7 @@ This function returns a timer object which you can use in `cancel-timer'." (interactive (list (read-from-minibuffer "Run after idle (seconds): " nil nil t) (y-or-n-p "Repeat each time Emacs is idle? ") - (intern (completing-read "Function: " obarray 'fboundp t)))) + (intern (completing-read "Function: " obarray #'fboundp t)))) (let ((timer (timer-create))) (timer-set-function timer function args) (timer-set-idle-time timer secs repeat) commit df263dd7586436b06262e32aa3614e11ed3a6182 Author: Stefan Monnier Date: Fri Aug 5 09:41:03 2022 -0400 bytecomp.el: Update comments referring to `make-docfile` diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index cc9cbd9da5..b1f4f01b3a 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2404,8 +2404,8 @@ Call from the source buffer." (defun byte-compile-output-file-form (form) ;; Write the given form to the output buffer, being careful of docstrings - ;; in defvar, defvaralias, defconst, autoload and - ;; custom-declare-variable because make-docfile is so amazingly stupid. + ;; (for `byte-compile-dynamic-docstrings') in defvar, defvaralias, + ;; defconst, autoload, and custom-declare-variable. ;; defalias calls are output directly by byte-compile-file-form-defmumble; ;; it does not pay to first build the defalias in defmumble and then parse ;; it here. @@ -2589,8 +2589,8 @@ list that represents a doc string reference. (t (byte-compile-keep-pending form))))) -;; Functions and variables with doc strings must be output separately, -;; so make-docfile can recognize them. Most other things can be output +;; Functions and variables with doc strings must be output specially, +;; for `byte-compile-dynamic-docstrings'. Most other things can be output ;; as byte-code. (put 'autoload 'byte-hunk-handler 'byte-compile-file-form-autoload) @@ -4989,7 +4989,7 @@ binding slots have been popped." ;; ;; FIXME: we also use this hunk-handler to implement the function's ;; dynamic docstring feature (via byte-compile-file-form-defmumble). - ;; We should actually implement it (more elegantly) in + ;; We should probably actually implement it (more elegantly) in ;; byte-compile-lambda so it applies to all lambdas. We did it here ;; so the resulting .elc format was recognizable by make-docfile, ;; but since then we stopped using DOC for the docstrings of commit aff596127476c0fbcb11ccbbce63f32d03785653 Author: Eli Zaretskii Date: Fri Aug 5 15:53:06 2022 +0300 Avoid assertion violations in 'back_to_previous_visible_line_start' * src/xdisp.c (init_iterator): Always initialize narrowed_begv to zero, since SET_WITH_NARROWED_BEGV depends on it being non-zero as an indication that long-line optimizations are in use. (back_to_previous_visible_line_start): When long-line optimizations are in effect, we may end up not on a newline. diff --git a/src/xdisp.c b/src/xdisp.c index 099efed2db..3ca0022a6d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -3473,8 +3473,9 @@ init_iterator (struct it *it, struct window *w, &it->bidi_it); } - if (current_buffer->long_line_optimizations_p) - it->narrowed_begv = 0; + /* This is set only when long_line_optimizations_p is non-zero + for the current buffer. */ + it->narrowed_begv = 0; /* Compute faces etc. */ reseat (it, it->current.pos, true); @@ -7412,7 +7413,7 @@ back_to_previous_visible_line_start (struct it *it) it->continuation_lines_width = 0; eassert (IT_CHARPOS (*it) >= BEGV); - eassert (it->narrowed_begv > BEGV + eassert (it->narrowed_begv > 0 /* long-line optimizations: all bets off */ || IT_CHARPOS (*it) == BEGV || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n'); CHECK_IT (it); commit 900b09c0235d54d56ef5e88d04cca61bc71cbbb7 Author: Stefan Monnier Date: Fri Aug 5 08:18:04 2022 -0400 bytecomp.el: Further simplifications enabled by commit 59732a83c8875c * lisp/emacs-lisp/bytecomp.el (byte-compile-output-docform): Don't insert a \n before the #@ docstrings since make-docfile doesn't scan .elc files any more. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 7d2971502d..cc9cbd9da5 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2454,9 +2454,6 @@ list that represents a doc string reference. (and (>= (nth 1 info) 0) dynamic-docstrings (progn - ;; Make the doc string start at beginning of line - ;; for make-docfile's sake. - (insert "\n") (setq position (byte-compile-output-as-comment (nth (nth 1 info) form) nil)) commit 9149672e7f0aa79a064f10bc882fc5c5d617ee8a Author: Lars Ingebrigtsen Date: Fri Aug 5 14:06:22 2022 +0200 Fix lisp/Makefile.in autoloads dependency * lisp/Makefile.in (autoloads): Ensure that loaddefs-gen.elc exists before making autoloads. diff --git a/lisp/Makefile.in b/lisp/Makefile.in index fc05d39d2a..f0a66aafb5 100644 --- a/lisp/Makefile.in +++ b/lisp/Makefile.in @@ -188,7 +188,7 @@ org-manuals: main-first # The real dependencies of loaddefs.el aren't known to Make, they are # implemented in loaddefs-generate--emacs-batch, so autoloads is an # "all" dependency. -autoloads: +autoloads: $(lisp)/emacs-lisp/loaddefs-gen.elc $(AM_V_GEN)$(emacs) \ -l $(lisp)/emacs-lisp/loaddefs-gen.elc \ -f loaddefs-generate--emacs-batch ${SUBDIRS_ALMOST} commit b7a896731c6574d9a5e4c0b33ce06a8969b5644a Author: Stefan Kangas Date: Fri Aug 5 13:36:38 2022 +0200 Make ange-ftp-re-read-dir compat alias obsolete * lisp/net/ange-ftp.el (ange-ftp-re-read-dir): Make alias obsolete. Update callers. diff --git a/lisp/gnus/nnheader.el b/lisp/gnus/nnheader.el index 92df41ea82..634cc251b8 100644 --- a/lisp/gnus/nnheader.el +++ b/lisp/gnus/nnheader.el @@ -920,9 +920,9 @@ first. Otherwise, find the newest one, though it may take a time." (defvar ange-ftp-path-format) (defun nnheader-re-read-dir (path) "Re-read directory PATH if PATH is on a remote system." - (when (and (fboundp 'ange-ftp-re-read-dir) (boundp 'ange-ftp-path-format)) + (when (and (fboundp 'ange-ftp-reread-dir) (boundp 'ange-ftp-path-format)) (when (string-match (car ange-ftp-path-format) path) - (ange-ftp-re-read-dir path)))) + (ange-ftp-reread-dir path)))) (defun nnheader-insert-file-contents (filename &optional visit beg end replace) "Like `insert-file-contents', q.v., but only reads in the file. diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el index 52b900be0c..6ffa65a2dd 100644 --- a/lisp/net/ange-ftp.el +++ b/lisp/net/ange-ftp.el @@ -4099,11 +4099,11 @@ E.g., ;; Put these lines uncommented in your .emacs if you want C-r to refresh ;; ange-ftp's cache whilst doing filename completion. ;; -;;(define-key minibuffer-local-completion-map "\C-r" 'ange-ftp-re-read-dir) -;;(define-key minibuffer-local-must-match-map "\C-r" 'ange-ftp-re-read-dir) +;;(define-key minibuffer-local-completion-map "\C-r" 'ange-ftp-reread-dir) +;;(define-key minibuffer-local-must-match-map "\C-r" 'ange-ftp-reread-dir) ;;;###autoload -(defalias 'ange-ftp-re-read-dir 'ange-ftp-reread-dir) +(define-obsolete-function-alias 'ange-ftp-re-read-dir #'ange-ftp-reread-dir "29.1") ;;;###autoload (defun ange-ftp-reread-dir (&optional dir) commit 7fccb83d076b174ada420bb9fe002687aa11f96b Author: Lars Ingebrigtsen Date: Fri Aug 5 13:51:19 2022 +0200 Make loaddefs.el dependencies more explicit in src/Makefile.in * src/Makefile.in (LC_ALL): Add loaddefs.el as a dependency, too, since that file may be deleted, but the loaddefs.elc file still exists. This causes problems in nativecomp builds. diff --git a/src/Makefile.in b/src/Makefile.in index 9ef4561c4a..92a8790efd 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -635,7 +635,7 @@ Emacs.pdmp: $(pdmp) endif ifeq ($(DUMPING),pdumper) -$(pdmp): emacs$(EXEEXT) $(lispsource)/loaddefs.elc +$(pdmp): emacs$(EXEEXT) $(lispsource)/loaddefs.el $(lispsource)/loaddefs.elc LC_ALL=C $(RUN_TEMACS) -batch $(BUILD_DETAILS) -l loadup --temacs=pdump \ --bin-dest $(BIN_DESTDIR) --eln-dest $(ELN_DESTDIR) cp -f $@ $(bootstrap_pdmp) commit c388578fb1aa714f2cf5ae2ad8a2933ca902b9df Author: Stefan Kangas Date: Fri Aug 5 13:00:06 2022 +0200 Rename object-sort-list to srecode-object-sort-list * lisp/cedet/srecode/table.el (srecode-object-sort-list): Rename from 'object-sort-list'. Retain old name as an obsolete alias. diff --git a/lisp/cedet/srecode/table.el b/lisp/cedet/srecode/table.el index 3dfbb9d58b..f77898f906 100644 --- a/lisp/cedet/srecode/table.el +++ b/lisp/cedet/srecode/table.el @@ -200,13 +200,13 @@ INIT are the initialization parameters for the new template table." ;; go front-to-back, the highest priority items are put ;; into the search table first, allowing lower priority items ;; to be the items found in the search table. - (object-sort-list mt 'modetables (lambda (a b) - (> (oref a priority) - (oref b priority)))) + (srecode-object-sort-list mt 'modetables (lambda (a b) + (> (oref a priority) + (oref b priority)))) ;; Return it. new)) -(defun object-sort-list (object slot predicate) +(defun srecode-object-sort-list (object slot predicate) "Sort the items in OBJECT's SLOT. Use PREDICATE is the same as for the `sort' function." (when (slot-boundp object slot) @@ -284,6 +284,8 @@ Use PREDICATE is the same as for the `sort' function." (setq temp (cdr temp)))) ) +(define-obsolete-function-alias 'object-sort-list + #'srecode-object-sort-list "29.1") (provide 'srecode/table) commit 010e2e5e5e2c45c9aab08dffbe83f9acb4a87191 Author: Stefan Kangas Date: Fri Aug 5 12:55:28 2022 +0200 Fix namespace problems in viper.el * lisp/emulation/viper.el (viper-this-major-mode-requires-vi-state): Rename from 'this-major-mode-requires-vi-state'. Retain old name as an obsolete alias. (viper-set-state-in-major-mode): Rename from 'set-viper-state-in-major-mode'. Retain old name as an obsolete alias. diff --git a/lisp/emulation/viper.el b/lisp/emulation/viper.el index be87d788e9..4c2ee1ce23 100644 --- a/lisp/emulation/viper.el +++ b/lisp/emulation/viper.el @@ -605,7 +605,7 @@ This startup message appears whenever you load Viper, unless you type \\`y' now. ;; Apply a little heuristic to invoke vi state on major-modes ;; that are not listed in viper-vi-state-mode-list -(defun this-major-mode-requires-vi-state (mode) +(defun viper-this-major-mode-requires-vi-state (mode) (let ((major-mode mode)) (cond ((apply #'derived-mode-p viper-vi-state-mode-list) t) ((apply #'derived-mode-p viper-emacs-state-mode-list) nil) @@ -634,7 +634,7 @@ This startup message appears whenever you load Viper, unless you type \\`y' now. (remove-hook symbol #'viper-minibuffer-post-command-hook) (remove-hook symbol #'viper-minibuffer-setup-sentinel) (remove-hook symbol #'viper-major-mode-change-sentinel) - (remove-hook symbol #'set-viper-state-in-major-mode) + (remove-hook symbol #'viper-set-state-in-major-mode) (remove-hook symbol #'viper-post-command-sentinel) ))) @@ -786,12 +786,12 @@ It also can't undo some Viper settings." (defvar viper-new-major-mode-buffer-list nil) ;; set appropriate Viper state in buffers that changed major mode -(defun set-viper-state-in-major-mode () +(defun viper-set-state-in-major-mode () (mapc (lambda (buf) (if (viper-buffer-live-p buf) (with-current-buffer buf - (cond ((and (this-major-mode-requires-vi-state major-mode) + (cond ((and (viper-this-major-mode-requires-vi-state major-mode) (eq viper-current-state 'emacs-state)) (viper-mode)) ((cl-member-if #'derived-mode-p viper-emacs-state-mode-list) @@ -810,7 +810,7 @@ It also can't undo some Viper settings." ;; clear the list of bufs that changed major mode (setq viper-new-major-mode-buffer-list nil) ;; change the global value of hook - (remove-hook 'viper-post-command-hooks #'set-viper-state-in-major-mode)) + (remove-hook 'viper-post-command-hooks #'viper-set-state-in-major-mode)) ;; sets up post-command-hook to turn viper-mode, if the current mode is ;; fundamental @@ -820,7 +820,7 @@ It also can't undo some Viper settings." (setq viper-new-major-mode-buffer-list (cons (current-buffer) viper-new-major-mode-buffer-list)))) ;; change the global value of hook - (add-hook 'viper-post-command-hooks #'set-viper-state-in-major-mode t)) + (add-hook 'viper-post-command-hooks #'viper-set-state-in-major-mode t)) ;;; Handling of tty's ESC event @@ -891,7 +891,7 @@ Two differences: (viper-setup-ESC-to-escape t) (add-hook 'change-major-mode-hook #'viper-major-mode-change-sentinel) - (add-hook 'find-file-hook #'set-viper-state-in-major-mode) + (add-hook 'find-file-hook #'viper-set-state-in-major-mode) ;; keep this because many modes we don't know about use this hook (defvar text-mode-hook) @@ -1242,12 +1242,15 @@ These two lines must come in the order given.")) (when (eq viper-current-state 'emacs-state) (viper-change-state-to-emacs)) - (if (this-major-mode-requires-vi-state major-mode) + (if (viper-this-major-mode-requires-vi-state major-mode) (viper-mode)) - (add-function :after initial-major-mode #'set-viper-state-in-major-mode)) - + (add-function :after initial-major-mode #'viper-set-state-in-major-mode)) +(define-obsolete-function-alias 'set-viper-state-in-major-mode + #'viper-set-state-in-major-mode "29.1") +(define-obsolete-function-alias 'this-major-mode-requires-vi-state + #'viper-this-major-mode-requires-vi-state "29.1") (run-hooks 'viper-load-hook) ; the last chance to change something commit 8f438f224c5894b8b6cf2dc3479772e2490f80be Author: Stefan Kangas Date: Fri Aug 5 12:49:38 2022 +0200 Fix namespace problems in xscheme.el * lisp/progmodes/xscheme.el (xscheme-default-runlight): Rename from 'default-xscheme-runlight'. Retain old name as an obsolete alias. (xscheme-verify-buffer): Rename from 'verify-xscheme-buffer'. Retain old name as an obsolete alias. diff --git a/lisp/progmodes/xscheme.el b/lisp/progmodes/xscheme.el index 6e21131e4a..4fb543a3bf 100644 --- a/lisp/progmodes/xscheme.el +++ b/lisp/progmodes/xscheme.el @@ -1,7 +1,6 @@ ;;; xscheme.el --- run MIT Scheme under Emacs -*- lexical-binding: t; -*- -;; Copyright (C) 1986-1987, 1989-1990, 2001-2022 Free Software -;; Foundation, Inc. +;; Copyright (C) 1986-2022 Free Software Foundation, Inc. ;; Maintainer: emacs-devel@gnu.org ;; Keywords: languages, lisp @@ -71,7 +70,9 @@ by the scheme process, so additional control-g's are to be ignored.") (defvar xscheme-string-receiver nil "Procedure to send the string argument from the scheme process.") -(defconst default-xscheme-runlight +(define-obsolete-variable-alias 'default-xscheme-runlight + 'xscheme-default-runlight "29.1") +(defconst xscheme-default-runlight '(": " xscheme-runlight-string) "Default global (shared) xscheme-runlight mode line format.") @@ -240,7 +241,7 @@ With argument, asks for a command line." (list (read-buffer "Scheme interaction buffer: " xscheme-buffer-name t))) - (let ((process-name (verify-xscheme-buffer buffer-name nil))) + (let ((process-name (xscheme-verify-buffer buffer-name nil))) (setq-default xscheme-buffer-name buffer-name) (setq-default xscheme-process-name process-name) (setq-default xscheme-runlight-string @@ -248,8 +249,8 @@ With argument, asks for a command line." xscheme-runlight-string)) (setq-default xscheme-runlight (if (eq (process-status process-name) 'run) - default-xscheme-runlight - "")))) + xscheme-default-runlight + "")))) (defun local-set-scheme-interaction-buffer (buffer-name) "Set the scheme interaction buffer for the current buffer." @@ -257,7 +258,7 @@ With argument, asks for a command line." (list (read-buffer "Scheme interaction buffer: " xscheme-buffer-name t))) - (let ((process-name (verify-xscheme-buffer buffer-name t))) + (let ((process-name (xscheme-verify-buffer buffer-name t))) (setq-local xscheme-buffer-name buffer-name) (setq-local xscheme-process-name process-name) (setq-local xscheme-runlight @@ -273,7 +274,7 @@ With argument, asks for a command line." (kill-local-variable 'xscheme-process-name) (kill-local-variable 'xscheme-runlight)) -(defun verify-xscheme-buffer (buffer-name localp) +(defun xscheme-verify-buffer (buffer-name localp) (if (and localp (xscheme-process-buffer-current-p)) (error "Cannot change the interaction buffer of an interaction buffer")) (let* ((buffer (get-buffer buffer-name)) @@ -921,8 +922,8 @@ the remaining input.") (setq scheme-mode-line-process '(": " xscheme-runlight-string)) (xscheme-mode-line-initialize name) (if (equal name (default-value 'xscheme-buffer-name)) - (setq-default xscheme-runlight default-xscheme-runlight)))) - (if (or (eq xscheme-runlight default-xscheme-runlight) + (setq-default xscheme-runlight xscheme-default-runlight)))) + (if (or (eq xscheme-runlight xscheme-default-runlight) (equal xscheme-runlight "")) (setq xscheme-runlight (list ": " 'xscheme-buffer-name ": " "?"))) (rplaca (nthcdr 3 xscheme-runlight) @@ -1180,6 +1181,8 @@ the remaining input.") (if (nth 2 state) 'many 'one))))) (set-syntax-table old-syntax-table))))) +(define-obsolete-function-alias 'verify-xscheme-buffer #'xscheme-verify-buffer "29.1") + (provide 'xscheme) ;;; xscheme.el ends here commit 0c106ce87ced346dc7280a0c9943b0e2e6dd8c37 Author: Stefan Kangas Date: Fri Aug 5 12:28:59 2022 +0200 Fix namespace problem in saveplace.el * lisp/saveplace.el (save-place-load-alist-from-file): Rename from 'load-save-place-alist-from-file'. Retain old name as an obsolete alias. Update callers. diff --git a/lisp/saveplace.el b/lisp/saveplace.el index 3830e4b16c..4b13331312 100644 --- a/lisp/saveplace.el +++ b/lisp/saveplace.el @@ -191,7 +191,7 @@ file names." ;; First check to make sure alist has been loaded in from the master ;; file. If not, do so, then feel free to modify the alist. It ;; will be saved again when Emacs is killed. - (or save-place-loaded (load-save-place-alist-from-file)) + (or save-place-loaded (save-place-load-alist-from-file)) (let* ((directory (and (derived-mode-p 'dired-mode) (boundp 'dired-subdir-alist) dired-subdir-alist @@ -278,7 +278,7 @@ may have changed) back to `save-place-alist'." (file-error (message "Saving places: can't write %s" file))) (kill-buffer (current-buffer)))))) -(defun load-save-place-alist-from-file () +(defun save-place-load-alist-from-file () (if (not save-place-loaded) (progn (setq save-place-loaded t) @@ -352,7 +352,7 @@ may have changed) back to `save-place-alist'." (defun save-place-find-file-hook () "Function added to `find-file-hook' by `save-place-mode'. It runs the hook `save-place-after-find-file-hook'." - (or save-place-loaded (load-save-place-alist-from-file)) + (or save-place-loaded (save-place-load-alist-from-file)) (let ((cell (assoc buffer-file-name save-place-alist))) (if cell (progn @@ -367,7 +367,7 @@ It runs the hook `save-place-after-find-file-hook'." (defun save-place-dired-hook () "Position the point in a Dired buffer." - (or save-place-loaded (load-save-place-alist-from-file)) + (or save-place-loaded (save-place-load-alist-from-file)) (let* ((directory (and (derived-mode-p 'dired-mode) (boundp 'dired-subdir-alist) dired-subdir-alist @@ -396,5 +396,8 @@ It runs the hook `save-place-after-find-file-hook'." (if save-place-loaded (save-place-alist-to-file))) +(define-obsolete-function-alias 'load-save-place-alist-from-file + #'save-place-load-alist-from-file "29.1") + (provide 'saveplace) ;;; saveplace.el ends here diff --git a/test/lisp/saveplace-tests.el b/test/lisp/saveplace-tests.el index 6f66f3fa34..99318d295d 100644 --- a/test/lisp/saveplace-tests.el +++ b/test/lisp/saveplace-tests.el @@ -84,7 +84,7 @@ (save-place-file (ert-resource-file "saveplace")) (save-place-alist nil)) - (load-save-place-alist-from-file) + (save-place-load-alist-from-file) (should (equal save-place-alist '(("/home/skangas/.emacs.d/cache/recentf" . 1306) ("/home/skangas/wip/emacs/" commit ab810804370b791749c6db5fdfef1be1a08e9903 Author: Stefan Kangas Date: Fri Aug 5 12:23:00 2022 +0200 Make two perl-mode aliases obsolete * lisp/progmodes/perl-mode.el (indent-perl-exp) (mark-perl-function): Make obsolete. diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el index 92b47ce88f..70cb460568 100644 --- a/lisp/progmodes/perl-mode.el +++ b/lisp/progmodes/perl-mode.el @@ -1120,7 +1120,6 @@ Returns (parse-state) if line starts inside a string." (t (forward-char -1) (forward-comment (- (point))) t))))) ;; note: this may be slower than the c-mode version, but I can understand it. -(defalias 'indent-perl-exp 'perl-indent-exp) (defun perl-indent-exp () "Indent each line of the Perl grouping following point." (interactive) @@ -1220,7 +1219,6 @@ With argument, repeat that many times; negative args move backward." (goto-char (point-min))))) (setq arg (1+ arg))))) -(defalias 'mark-perl-function 'perl-mark-function) (defun perl-mark-function () "Put mark at end of Perl function, point at beginning." (interactive) @@ -1230,6 +1228,9 @@ With argument, repeat that many times; negative args move backward." (perl-beginning-of-function) (backward-paragraph)) +(define-obsolete-function-alias 'indent-perl-exp #'perl-indent-exp "29.1") +(define-obsolete-function-alias 'mark-perl-function #'perl-mark-function "29.1") + (provide 'perl-mode) ;;; perl-mode.el ends here commit 250f09d2f3927a650329dfb1165670f3d9b5bb5b Author: Stefan Kangas Date: Fri Aug 5 12:08:19 2022 +0200 Fix namespace problem in ede/custom.el * lisp/cedet/ede/custom.el (ede-eieio-old-variables): Rename from 'ede-eieio-old-variables'. Retain old name as an obsolete alias. diff --git a/lisp/cedet/ede/custom.el b/lisp/cedet/ede/custom.el index 2d4f408e96..0854c8cc47 100644 --- a/lisp/cedet/ede/custom.el +++ b/lisp/cedet/ede/custom.el @@ -35,7 +35,9 @@ (require 'ede) (eval-when-compile (require 'eieio-custom)) -(defvar eieio-ede-old-variables nil +(define-obsolete-variable-alias 'ede-eieio-old-variables + 'eieio-ede-old-variables "29.1") +(defvar ede-eieio-old-variables nil "The old variables for a project.") ;;; Customization Commands @@ -50,7 +52,7 @@ (let* ((ov (oref (ede-current-project) local-variables)) (cp (ede-current-project))) (ede-customize cp) - (setq-local eieio-ede-old-variables ov))) + (setq-local ede-eieio-old-variables ov))) ;;;###autoload (defalias 'customize-project #'ede-customize-project) @@ -178,9 +180,9 @@ OBJ is the target object to customize." ;; These hooks are used when finishing up a customization. (cl-defmethod eieio-done-customizing ((proj ede-project)) "Call this when a user finishes customizing PROJ." - (let ((ov eieio-ede-old-variables) + (let ((ov ede-eieio-old-variables) (nv (oref proj local-variables))) - (setq eieio-ede-old-variables nil) + (setq ede-eieio-old-variables nil) (while ov (if (not (assoc (car (car ov)) nv)) (save-excursion commit 5426f67006cd9b30dd3cb3768ba6ca59681f68e8 Author: Stefan Kangas Date: Fri Aug 5 11:46:47 2022 +0200 * test/lisp/env-tests.el: New file. diff --git a/lisp/env.el b/lisp/env.el index a35383a13b..5cdedbfb99 100644 --- a/lisp/env.el +++ b/lisp/env.el @@ -1,6 +1,6 @@ ;;; env.el --- functions to manipulate environment variables -*- lexical-binding:t -*- -;; Copyright (C) 1991, 1994, 2000-2022 Free Software Foundation, Inc. +;; Copyright (C) 1991-2022 Free Software Foundation, Inc. ;; Maintainer: emacs-devel@gnu.org ;; Keywords: processes, unix diff --git a/test/lisp/env-tests.el b/test/lisp/env-tests.el new file mode 100644 index 0000000000..fd3d3cb273 --- /dev/null +++ b/test/lisp/env-tests.el @@ -0,0 +1,40 @@ +;;; env-tests.el --- Tests for env.el -*- lexical-binding: t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Code: + +(require 'env) +(require 'ert) + +(ert-deftest test-substitute-env-in-file-name () + (should (equal (substitute-env-in-file-name "foo_${HOME}_bar") + (concat "foo_" (getenv "HOME") "_bar")))) + +(ert-deftest test-getenv-setenv () + (should (equal (setenv "EMACS_ENV_EL_TEST_VAR" "foobar") "foobar")) + (should (equal (getenv "EMACS_ENV_EL_TEST_VAR") "foobar")) + (should-not (getenv "LIKELY_TO_BE_NON_EXISTENT_FOO_BAR_BAZ"))) + +(ert-deftest test-with-environment-variables () + (let ((A "TEST") (B "/foo/bar")) + (with-environment-variables ((A B)) + (should (equal (getenv A) B))))) + +(provide 'env-tests) +;;; env-tests.el ends here commit f3b9bccb45965d288f5e14448eacb2f2980a0bfa Author: Stefan Kangas Date: Tue Jul 26 15:12:19 2022 +0200 * lisp/play/fortune.el: Doc fixes. diff --git a/lisp/play/fortune.el b/lisp/play/fortune.el index 3bc51f6d68..d6360e5022 100644 --- a/lisp/play/fortune.el +++ b/lisp/play/fortune.el @@ -1,6 +1,6 @@ ;;; fortune.el --- use fortune to create signatures -*- lexical-binding: t -*- -;; Copyright (C) 1999, 2001-2022 Free Software Foundation, Inc. +;; Copyright (C) 1999-2022 Free Software Foundation, Inc. ;; Author: Holger Schauer ;; Keywords: games utils mail @@ -21,38 +21,48 @@ ;; along with GNU Emacs. If not, see . ;;; Commentary: + ;; This utility allows you to automatically cut regions to a fortune ;; file. In case that the region stems from an article buffer (mail or ;; news), it will try to automatically determine the author of the -;; fortune. It will also allow you to compile your fortune-database +;; fortune. It will also allow you to compile your fortune database ;; as well as providing a function to extract a fortune for use as your ;; signature. +;; ;; Of course, it can simply display a fortune, too. ;; Use prefix arguments to specify different fortune databases. - +;; ;;; Installation: - -;; Please check the customize settings -- you will at least have to -;; modify the values of `fortune-dir' and `fortune-file'. - +;; +;; Please type `M-x customize-group RET fortune RET' -- you will at +;; least have to modify the user options `fortune-dir' and +;; `fortune-file'. +;; ;; I then use this in my .gnus: -;;(message "Making new signature: %s" (fortune-to-signature "~/fortunes/")) +;; +;; (message "Making new signature: %s" +;; (fortune-to-signature "~/fortunes/")) +;; ;; This automagically creates a new signature when starting up Gnus. -;; Note that the call to fortune-to-signature specifies a directory in which -;; several fortune-files and their databases are stored. - -;; If you like to get a new signature for every message, you can also hook -;; it into message-mode: -;; (add-hook 'message-setup-hook 'fortune-to-signature) -;; This time no fortune-file is specified, so fortune-to-signature would use -;; the default-file as specified by fortune-file. - -;; I have also this in my .gnus: -;;(add-hook 'gnus-article-mode-hook -;; (lambda () -;; (define-key gnus-article-mode-map "i" 'fortune-from-region))) +;; Note that the call to `fortune-to-signature' specifies a directory +;; in which several fortune files and their databases are stored. +;; +;; To get a new signature for every message, you can hook it into +;; `message-mode': +;; +;; (add-hook 'message-setup-hook #'fortune-to-signature) +;; +;; This time no fortune file is specified, so `fortune-to-signature' +;; would use the default file as specified by `fortune-file'. +;; +;; I also have this in my .gnus: +;; +;; (add-hook 'gnus-article-mode-hook +;; (lambda () +;; (define-key gnus-article-mode-map "i" #'fortune-from-region))) +;; ;; which allows marking a region and then pressing "i" so that the marked -;; region will be automatically added to my favorite fortune-file. +;; region will be automatically added to my favorite fortune file. ;;; Code: @@ -166,7 +176,7 @@ If INTERACTIVE is non-nil, don't compile the fortune file afterwards." (fortune-compile file))))) (defun fortune-ask-file () - "Asks the user for a file-name." + "Asks the user for a file name." (expand-file-name (read-file-name "Fortune file to use: " commit cbe1af96a266d7153c3dde098194a7e154902b60 Author: Po Lu Date: Fri Aug 5 16:26:01 2022 +0800 Fix oldXMenu grab handling * src/xmenu.c (x_menu_translate_generic_event, pop_down_menu): Clear grab correctly on individual XI2 devices. diff --git a/src/xmenu.c b/src/xmenu.c index 3be0fb1876..5b8a8f77a2 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -232,6 +232,7 @@ static void x_menu_translate_generic_event (XEvent *event) { struct x_display_info *dpyinfo; + struct xi_device_t *device; XEvent copy; XIDeviceEvent *xev; @@ -265,6 +266,16 @@ x_menu_translate_generic_event (XEvent *event) copy.xbutton.button = xev->detail; copy.xbutton.same_screen = True; + device = xi_device_from_id (dpyinfo, xev->deviceid); + + /* I don't know the repercussions of changing + device->grab on XI_ButtonPress events, so be safe and + only do what is necessary to prevent the grab from + being left invalid as XMenuActivate swallows + events. */ + if (device && xev->evtype == XI_ButtonRelease) + device->grab &= ~(1 << xev->detail); + XPutBackEvent (dpyinfo->display, ©); break; @@ -2507,6 +2518,10 @@ pop_down_menu (void *arg) struct pop_down_menu *data = arg; struct frame *f = data->frame; XMenu *menu = data->menu; +#ifdef HAVE_XINPUT2 + int i; + struct xi_device_t *device; +#endif block_input (); #ifndef MSDOS @@ -2526,6 +2541,17 @@ pop_down_menu (void *arg) results, and it is a pain to ask which are actually held now. */ FRAME_DISPLAY_INFO (f)->grabbed = 0; +#ifdef HAVE_XINPUT2 + /* Likewise for XI grabs when the mouse is released on top of the + menu itself. */ + + for (i = 0; i < FRAME_DISPLAY_INFO (f)->num_devices; ++i) + { + device = &FRAME_DISPLAY_INFO (f)->devices[i]; + device->grab = 0; + } +#endif + #endif /* HAVE_X_WINDOWS */ unblock_input (); commit 9aa959efebc5b87022096c089a41ff8c899694c5 Author: Po Lu Date: Fri Aug 5 16:12:25 2022 +0800 ; * etc/NEWS: Fix typo. diff --git a/etc/NEWS b/etc/NEWS index 2fb83e1923..7145a8861e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -59,7 +59,7 @@ If a constant file name is required, the file can be renamed to "emacs.pdmp", and Emacs will find it during startup anyway. --- -** Emacs now uses of XInput 2 for input events. +** Emacs now uses XInput 2 for input events. If your X server has support and you have the XInput 2 development headers installed, Emacs will use the X Input Extension for handling input. If this causes problems, you can configure Emacs with the commit faf1f037987ccef81b3f1a18bfc5ea4de867983e Author: Po Lu Date: Fri Aug 5 16:12:07 2022 +0800 Improve C-x C-q in emacs-news-mode * lisp/textmodes/emacs-news-mode.el (emacs-news-mode-map) (emacs-news-view-mode-map): Make C-x C-q switch to the appropriate mode for editing, and vice versa. (emacs-news-mode): Disable button-mode and make buffer read-write. diff --git a/lisp/textmodes/emacs-news-mode.el b/lisp/textmodes/emacs-news-mode.el index af0aa2ddea..c7fa9fa2b2 100644 --- a/lisp/textmodes/emacs-news-mode.el +++ b/lisp/textmodes/emacs-news-mode.el @@ -56,10 +56,12 @@ "C-c C-g" #'emacs-news-goto-section "C-c C-j" #'emacs-news-find-heading "C-c C-e" #'emacs-news-count-untagged-entries + "C-x C-q" #'emacs-news-view-mode " " #'emacs-news-open-line) (defvar-keymap emacs-news-view-mode-map - :parent emacs-news-common-map) + :parent emacs-news-common-map + "C-x C-q" #'emacs-news-mode) (defvar emacs-news-mode-font-lock-keywords `(("^---$" 0 'emacs-news-does-not-need-documentation) @@ -78,6 +80,11 @@ ;;;###autoload (define-derived-mode emacs-news-mode text-mode "NEWS" "Major mode for editing the Emacs NEWS file." + ;; Disable buttons. + (button-mode nil) + ;; And make the buffer writable. This is used when toggling + ;; emacs-news-mode. + (setq buffer-read-only nil) (setq-local fill-paragraph-function #'emacs-news--fill-paragraph) (emacs-news--mode-common))