commit c679756a9fb3ebd9a9b5fa9c9c64641fe493e8d8 (HEAD, refs/remotes/origin/master) Author: Juri Linkov Date: Wed Jul 13 09:58:14 2022 +0300 ; Fix typos in the manual diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi index cadac7e453..96e05a902d 100644 --- a/doc/emacs/display.texi +++ b/doc/emacs/display.texi @@ -893,7 +893,7 @@ of 1.2; to change this factor, customize the variable to the @code{text-scale-adjust} command restores the default height, the same as typing @kbd{C-x C-0}. -@cindex ajust global font size +@cindex adjust global font size @findex global-text-scale-adjust @vindex global-text-scale-adjust-resizes-frames @kindex C-x C-M-+ diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index 20468c0c17..404978b315 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -2362,7 +2362,7 @@ formats. These can be added with the viewing Krita files as simple images, you could say something like: @lisp -(image-converter-add +(image-converter-add-handler "kra" (lambda (file data-p) (if data-p commit 28797db5c96a660ca08fa35b748683ddbaf4c44e Author: Po Lu Date: Wed Jul 13 05:46:59 2022 +0000 ; * lisp/term/haiku-win.el: Fix compiler warnings. diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el index bbc263df68..b36e3037ee 100644 --- a/lisp/term/haiku-win.el +++ b/lisp/term/haiku-win.el @@ -206,6 +206,7 @@ VALUE as a unibyte string, or nil if VALUE was not a string." (declare-function haiku-selection-owner-p "haikuselect.c") (declare-function haiku-put-resource "haikufns.c") (declare-function haiku-drag-message "haikuselect.c") +(declare-function haiku-selection-timestamp "haikuselect.c") (defun haiku--handle-x-command-line-resources (command-line-resources) "Handle command line X resources specified with the option `-xrm'. commit defe6cf2d941ceee2d7e11cc991da6a62fd52398 Author: Po Lu Date: Wed Jul 13 05:44:31 2022 +0000 Implement TIMESTAMP target for Haiku selections * lisp/term/haiku-win.el (haiku-selection-targets): Fix return values. (gui-backend-get-selection): Handle TIMESTAMP specially. * src/haiku_select.cc (be_get_clipboard_count): New function. * src/haikuselect.c (Fhaiku_selection_timestamp): New function. (syms_of_haikuselect): Add new defsubr. * src/haikuselect.h: Update prototypes. diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el index f6e4829cad..bbc263df68 100644 --- a/lisp/term/haiku-win.el +++ b/lisp/term/haiku-win.el @@ -249,7 +249,7 @@ If TYPE is nil, return \"text/plain\"." "Find the types of data available from CLIPBOARD. CLIPBOARD should be the symbol `PRIMARY', `SECONDARY' or `CLIPBOARD'. Return the available types as a list of strings." - (mapcar #'car (haiku-selection-data clipboard nil))) + (delq 'type (mapcar #'car (haiku-selection-data clipboard nil)))) (defun haiku-select-encode-xstring (_selection value) "Convert VALUE to a system message association. @@ -288,12 +288,19 @@ or a pair of markers) and turns it into a file system reference." (cl-defmethod gui-backend-get-selection (type data-type &context (window-system haiku)) - (if (eq data-type 'TARGETS) - (apply #'vector (mapcar #'intern - (haiku-selection-targets type))) - (if (eq type 'XdndSelection) - haiku-dnd-selection-value - (haiku-selection-data type (haiku--selection-type-to-mime data-type))))) + (cond + ((eq data-type 'TARGETS) + (apply #'vector (mapcar #'intern + (haiku-selection-targets type)))) + ;; The timestamp here is really the number of times a program has + ;; put data into the selection. But it always increases, so it + ;; makes sense if one imagines that time is frozen until + ;; immediately before that happens. + ((eq data-type 'TIMESTAMP) + (haiku-selection-timestamp type)) + ((eq type 'XdndSelection) haiku-dnd-selection-value) + (t (haiku-selection-data type + (haiku--selection-type-to-mime data-type))))) (cl-defmethod gui-backend-set-selection (type value &context (window-system haiku)) diff --git a/src/haiku_select.cc b/src/haiku_select.cc index e1f2a81524..872da1d6c4 100644 --- a/src/haiku_select.cc +++ b/src/haiku_select.cc @@ -508,3 +508,12 @@ be_selection_outdated_p (enum haiku_clipboard id, int64 count) return false; } + +int64 +be_get_clipboard_count (enum haiku_clipboard id) +{ + BClipboard *clipboard; + + clipboard = get_clipboard_object (id); + return clipboard->SystemCount (); +} diff --git a/src/haikuselect.c b/src/haikuselect.c index 9d8c4a2cd1..dc0a7edf43 100644 --- a/src/haikuselect.c +++ b/src/haikuselect.c @@ -54,6 +54,23 @@ haiku_get_clipboard_name (Lisp_Object clipboard) signal_error ("Invalid clipboard", clipboard); } +DEFUN ("haiku-selection-timestamp", Fhaiku_selection_timestamp, + Shaiku_selection_timestamp, 1, 1, 0, + doc: /* Retrieve the "timestamp" of the clipboard CLIPBOARD. +CLIPBOARD can either be the symbol `PRIMARY', `SECONDARY' or +`CLIPBOARD'. The timestamp is returned as a number describing the +number of times programs have put data into CLIPBOARD. */) + (Lisp_Object clipboard) +{ + enum haiku_clipboard clipboard_name; + int64 timestamp; + + clipboard_name = haiku_get_clipboard_name (clipboard); + timestamp = be_get_clipboard_count (clipboard_name); + + return INT_TO_INTEGER (timestamp); +} + DEFUN ("haiku-selection-data", Fhaiku_selection_data, Shaiku_selection_data, 2, 2, 0, doc: /* Retrieve content typed as NAME from the clipboard @@ -1122,6 +1139,7 @@ These are only called if a connection to the Haiku display was opened. */); DEFSYM (Qalready_running, "already-running"); defsubr (&Shaiku_selection_data); + defsubr (&Shaiku_selection_timestamp); defsubr (&Shaiku_selection_put); defsubr (&Shaiku_selection_owner_p); defsubr (&Shaiku_drag_message); diff --git a/src/haikuselect.h b/src/haikuselect.h index 61efeb9cd9..42e9c93f7e 100644 --- a/src/haikuselect.h +++ b/src/haikuselect.h @@ -67,6 +67,7 @@ extern void be_unlock_clipboard (enum haiku_clipboard, bool); extern void be_handle_clipboard_changed_message (void); extern void be_start_watching_selection (enum haiku_clipboard); extern bool be_selection_outdated_p (enum haiku_clipboard, int64); +extern int64 be_get_clipboard_count (enum haiku_clipboard); #ifdef __cplusplus }; commit 6fba6a3c4a429cba480fe29156bfd87dc130bfe1 Merge: 14a56f52c5 a3dab1e621 Author: Stefan Kangas Date: Wed Jul 13 06:46:11 2022 +0200 Merge from origin/emacs-28 a3dab1e621 Don't mention cl-cXXXr aliases in cl-lib manual commit 14a56f52c5b57b69aaa2af08204d649c749fcb97 Author: Po Lu Date: Wed Jul 13 12:36:08 2022 +0800 New user option 'webjump-use-internal-browser' * lisp/net/webjump.el (webjump-use-internal-browser): New defcustom. (webjump): Respect it. Reported by Youmu . diff --git a/etc/NEWS b/etc/NEWS index 9f302bdfb5..b46f33fd67 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2030,6 +2030,11 @@ Set it to nil to exclude line numbering from kills and copies. ** Miscellaneous +--- +*** New user option 'webjump-use-internal-browser'. +When non-nil, WebJump will use an internal browser to open web pages, +instead of the default external browser. + +++ *** New user option 'font-lock-ignore'. This option provides a mechanism to selectively disable font-lock diff --git a/lisp/net/webjump.el b/lisp/net/webjump.el index b2ef47898c..9886a4c79d 100644 --- a/lisp/net/webjump.el +++ b/lisp/net/webjump.el @@ -79,6 +79,14 @@ :prefix "webjump-" :group 'browse-url) +(defcustom webjump-use-internal-browser nil + "Whether or not to force the use of an internal browser. +If non-nil, WebJump will always use an internal browser (such as +EWW or xwidget-webkit) to open web pages, as opposed to an +external browser like IceCat." + :version "29.1" + :type 'boolean) + (defconst webjump-sample-sites '( ;; FSF, not including Emacs-specific. @@ -255,18 +263,32 @@ Please submit bug reports and other feedback to the author, Neil W. Van Dyke webjump-sites t)) (name (car item)) (expr (cdr item))) - (browse-url (webjump-url-fix - (cond ((not expr) "") - ((stringp expr) expr) - ((vectorp expr) (webjump-builtin expr name)) - ((listp expr) (eval expr t)) - ((symbolp expr) - (if (fboundp expr) - (funcall expr name) - (error "WebJump URL function \"%s\" undefined" - expr))) - (t (error "WebJump URL expression for \"%s\" invalid" - name))))))) + (if webjump-use-internal-browser + (browse-url-with-browser-kind + 'internal (webjump-url-fix + (cond ((not expr) "") + ((stringp expr) expr) + ((vectorp expr) (webjump-builtin expr name)) + ((listp expr) (eval expr t)) + ((symbolp expr) + (if (fboundp expr) + (funcall expr name) + (error "WebJump URL function \"%s\" undefined" + expr))) + (t (error "WebJump URL expression for \"%s\" invalid" + name))))) + (browse-url (webjump-url-fix + (cond ((not expr) "") + ((stringp expr) expr) + ((vectorp expr) (webjump-builtin expr name)) + ((listp expr) (eval expr t)) + ((symbolp expr) + (if (fboundp expr) + (funcall expr name) + (error "WebJump URL function \"%s\" undefined" + expr))) + (t (error "WebJump URL expression for \"%s\" invalid" + name)))))))) (defun webjump-builtin (expr name) (if (< (length expr) 1) commit 6be201cf51e0b1c69e713dec318cef18eef4c617 Author: Po Lu Date: Wed Jul 13 11:01:59 2022 +0800 Fix closing displays when preserving selections is enabled * src/frame.c (delete_frame): Bind `x-auto-preserve-selections' to nil if deleting display. * src/xselect.c (x_clear_frame_selections): Pass original frame to that function. * src/xterm.c (x_preserve_selections): Fix determining the new owner. (syms_of_xterm): New defsym `x-auto-preserve-selections'. * src/xterm.h: Update prototypes. diff --git a/src/frame.c b/src/frame.c index 923ef2d609..a39e1c4944 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1933,6 +1933,9 @@ delete_frame (Lisp_Object frame, Lisp_Object force) int is_tooltip_frame; bool nochild = !FRAME_PARENT_FRAME (f); Lisp_Object minibuffer_child_frame = Qnil; +#ifdef HAVE_X_WINDOWS + specpdl_ref ref; +#endif if (!FRAME_LIVE_P (f)) return Qnil; @@ -2116,7 +2119,18 @@ delete_frame (Lisp_Object frame, Lisp_Object force) /* Clear any X selections for this frame. */ #ifdef HAVE_X_WINDOWS if (FRAME_X_P (f)) - x_clear_frame_selections (f); + { + /* Don't preserve selections when a display is going away, since + that sends stuff down the wire. */ + + ref = SPECPDL_INDEX (); + + if (EQ (force, Qnoelisp)) + specbind (Qx_auto_preserve_selections, Qnil); + + x_clear_frame_selections (f); + unbind_to (ref, Qnil); + } #endif #ifdef HAVE_PGTK diff --git a/src/xselect.c b/src/xselect.c index baab2c5c18..1750cfb8bd 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -1128,7 +1128,7 @@ x_clear_frame_selections (struct frame *f) } if (x_auto_preserve_selections) - x_preserve_selections (dpyinfo, lost); + x_preserve_selections (dpyinfo, lost, frame); } /* True if any properties for DISPLAY and WINDOW diff --git a/src/xterm.c b/src/xterm.c index 6e3a941719..fa54d5c9e2 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -27956,7 +27956,8 @@ x_uncatch_errors_for_lisp (struct x_display_info *dpyinfo) being deleted. */ void -x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost) +x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost, + Lisp_Object current_owner) { Lisp_Object tail, frame, new_owner, tem; Time timestamp; @@ -27975,6 +27976,7 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost) FOR_EACH_FRAME (tail, frame) { if (FRAME_X_P (XFRAME (frame)) + && !EQ (frame, current_owner) && FRAME_DISPLAY_INFO (XFRAME (frame)) == dpyinfo) { new_owner = frame; @@ -28105,6 +28107,7 @@ syms_of_xterm (void) DEFSYM (Qlatin_1, "latin-1"); DEFSYM (Qnow, "now"); DEFSYM (Qx_dnd_targets_list, "x-dnd-targets-list"); + DEFSYM (Qx_auto_preserve_selections, "x-auto-preserve-selections"); #ifdef USE_GTK xg_default_icon_file = build_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg"); diff --git a/src/xterm.h b/src/xterm.h index 9b91ee4556..6afd08eab2 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1643,7 +1643,8 @@ extern void xic_set_statusarea (struct frame *); extern void xic_set_xfontset (struct frame *, const char *); extern bool x_defined_color (struct frame *, const char *, Emacs_Color *, bool, bool); -extern void x_preserve_selections (struct x_display_info *, Lisp_Object); +extern void x_preserve_selections (struct x_display_info *, Lisp_Object, + Lisp_Object); #ifdef HAVE_X_I18N extern void free_frame_xic (struct frame *); # if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT commit 113a6a0a885c8bfb1f3c75a8a985a73686662113 Author: Lars Ingebrigtsen Date: Wed Jul 13 01:53:20 2022 +0200 Tweak image-converter-add-handler interface * doc/emacs/files.texi (Image Mode): Adjust documentation. * lisp/image/image-converter.el (image-convert): Let the converter know whether it's a file or not. diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index da13820476..20468c0c17 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -2364,15 +2364,19 @@ viewing Krita files as simple images, you could say something like: @lisp (image-converter-add "kra" - (lambda (file) - (call-process "unzip" nil t nil - "-qq" "-c" "-x" file "mergedimage.png")))) + (lambda (file data-p) + (if data-p + (error "Can't decode non-files") + (call-process "unzip" nil t nil + "-qq" "-c" "-x" file "mergedimage.png")))) @end lisp The function takes two parameters, where the first is a file name suffix, and the second is a function to do the ``conversion''. This -function takes one parameter, the file name, and should output an -image in @code{image-convert-to-format} format in the current buffer. +function takes two parameters, where the first is the file name or a +string with the data, and the second says whether the first parameter +is data or not, and should output an image in +@code{image-convert-to-format} format in the current buffer. @findex thumbs-mode @cindex mode, Thumbs diff --git a/lisp/image/image-converter.el b/lisp/image/image-converter.el index ed3ba49071..9c2f24819a 100644 --- a/lisp/image/image-converter.el +++ b/lisp/image/image-converter.el @@ -136,7 +136,7 @@ converted image data is returned as a string." (file-name-extension source))) (extra-converter (gethash type image-converter--extra-converters))) (if extra-converter - (funcall extra-converter source) + (funcall extra-converter source format) (when-let ((err (image-converter--convert image-converter source format))) (error "%s" err)))) @@ -309,9 +309,11 @@ Only suffixes that map to `image-mode' are returned." ;;;###autoload (defun image-converter-add-handler (suffix converter) "Make Emacs use CONVERTER to parse image files that end with SUFFIX. -CONVERTER is a function with one parameter, the file name. The -converter should output the image in the current buffer, -converted to `image-convert-to-format'." +CONVERTER is a function with two parameters, where the first is +the file name or a string with the image data, and the second is +non-nil if the first parameter is image data. The converter +should output the image in the current buffer, converted to +`image-convert-to-format'." (cl-pushnew suffix image-converter-file-name-extensions :test #'equal) (setq image-converter-file-name-extensions (sort image-converter-file-name-extensions #'string<)) commit cbe9a55923601e4dcfd8538488723094cd7a7cac Author: Lars Ingebrigtsen Date: Wed Jul 13 01:39:55 2022 +0200 Autoload image-converter-add-handler * lisp/image/image-converter.el (image-converter-add-handler): Autoload. diff --git a/etc/NEWS b/etc/NEWS index c2900b0bc4..9f302bdfb5 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1709,6 +1709,12 @@ this message for SVG and XPM. *** New commands: 'image-flip-horizontally' and 'image-flip-vertically'. These commands horizontally and vertically flip the image under point. +** Images + ++++ +*** Users can now add special image conversion functions. +This is done via 'image-converter-add-handler'. + ** Image-Dired +++ diff --git a/lisp/image/image-converter.el b/lisp/image/image-converter.el index 0c189af8e5..ed3ba49071 100644 --- a/lisp/image/image-converter.el +++ b/lisp/image/image-converter.el @@ -306,6 +306,7 @@ Only suffixes that map to `image-mode' are returned." "-"))))) "ffmpeg error when converting"))) +;;;###autoload (defun image-converter-add-handler (suffix converter) "Make Emacs use CONVERTER to parse image files that end with SUFFIX. CONVERTER is a function with one parameter, the file name. The commit 3b802f029e89786c17b4bf6af760360f61d14fb9 Author: Lars Ingebrigtsen Date: Wed Jul 13 01:36:54 2022 +0200 Add support for viewing "images" such as Krita (.kra) files * doc/emacs/files.texi (Image Mode): Document it. * lisp/image/image-converter.el (image-converter-add-handler): New function (bug#48415). (image-convert): Use it. diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index 7b4e31e5f8..da13820476 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -2355,6 +2355,25 @@ can be used to transform the image in question to @acronym{PNG} before displaying. GraphicsMagick, ImageMagick and @command{ffmpeg} are currently supported for image conversions. +@findex image-converter-add-handler + In addition, you may wish to add special handlers for certain image +formats. These can be added with the +@code{image-converter-add-handler} function. For instance, to allow +viewing Krita files as simple images, you could say something like: + +@lisp +(image-converter-add + "kra" + (lambda (file) + (call-process "unzip" nil t nil + "-qq" "-c" "-x" file "mergedimage.png")))) +@end lisp + +The function takes two parameters, where the first is a file name +suffix, and the second is a function to do the ``conversion''. This +function takes one parameter, the file name, and should output an +image in @code{image-convert-to-format} format in the current buffer. + @findex thumbs-mode @cindex mode, Thumbs The Image-Dired package can also be used to view images as diff --git a/lisp/image/image-converter.el b/lisp/image/image-converter.el index 9ce46f01a3..0c189af8e5 100644 --- a/lisp/image/image-converter.el +++ b/lisp/image/image-converter.el @@ -68,6 +68,8 @@ not, conversion will fail." (imagemagick :command "convert" :probe ("-list" "format"))) "List of supported image converters to try.") +(defvar image-converter--extra-converters (make-hash-table :test #'equal)) + (defun image-converter-initialize () "Determine the external image converter to be used. This also determines which external formats we can parse." @@ -123,15 +125,21 @@ converted image data is returned as a string." (error "IMAGE-FORMAT should be a symbol like `image/png'")) (with-temp-buffer (set-buffer-multibyte nil) - (when-let ((err (image-converter--convert - image-converter - (if (listp image) - (plist-get (cdr image) :file) - image) - (if (listp image) - (plist-get (cdr image) :data-p) - image-format)))) - (error "%s" err)) + (let* ((source (if (listp image) + (plist-get (cdr image) :file) + image)) + (format (if (listp image) + (plist-get (cdr image) :data-p) + image-format)) + (type (if format + (image-converter--mime-type format) + (file-name-extension source))) + (extra-converter (gethash type image-converter--extra-converters))) + (if extra-converter + (funcall extra-converter source) + (when-let ((err (image-converter--convert + image-converter source format))) + (error "%s" err)))) (if (listp image) ;; Return an image object that's the same as we were passed, ;; but ignore the :type value. @@ -298,6 +306,18 @@ Only suffixes that map to `image-mode' are returned." "-"))))) "ffmpeg error when converting"))) +(defun image-converter-add-handler (suffix converter) + "Make Emacs use CONVERTER to parse image files that end with SUFFIX. +CONVERTER is a function with one parameter, the file name. The +converter should output the image in the current buffer, +converted to `image-convert-to-format'." + (cl-pushnew suffix image-converter-file-name-extensions :test #'equal) + (setq image-converter-file-name-extensions + (sort image-converter-file-name-extensions #'string<)) + (setq image-converter-regexp + (concat "\\." (regexp-opt image-converter-file-name-extensions) "\\'")) + (setf (gethash suffix image-converter--extra-converters) converter)) + (provide 'image-converter) ;;; image-converter.el ends here commit fe50d914a95e78687e3341b526f19a71de583963 Author: Eli Zaretskii Date: Tue Jul 12 20:00:16 2022 +0300 ; * lisp/dirtrack.el: Restore important information in commentary. diff --git a/lisp/dirtrack.el b/lisp/dirtrack.el index 080c02294e..4f092f95e0 100644 --- a/lisp/dirtrack.el +++ b/lisp/dirtrack.el @@ -26,12 +26,14 @@ ;; Shell directory tracking by watching the prompt. ;; ;; This is yet another attempt at a directory-tracking package for -;; Emacs shell-mode. However, this package makes one strong assumption: -;; that you can customize your shell's prompt to contain the -;; current working directory. Most shells do support this, including -;; almost every type of Bourne and C shell on Unix, the native shells on -;; Windows, and most 3rd party Windows shells. If you cannot do this, or -;; do not wish to, this package will be useless to you. +;; Emacs shell-mode. However, this package makes one strong +;; assumption: that you can customize your shell's prompt to contain +;; the current working directory. Most shells do support this, +;; including almost every type of Bourne and C shell on Unix, the +;; native shells on Windows 9X (COMMAND.COM) and modern MS-Windows +;; systems (cmd.exe), and most 3rd party MS-Windows shells. If you +;; cannot do this, or do not wish to, this package will be useless to +;; you. ;; ;; Installation: ;; @@ -62,7 +64,7 @@ ;; ;; Examples: ;; -;; 1) On Windows NT, my prompt is set to emacs$S$P$G. +;; 1) On MS-Windows, my prompt is set to emacs$S$P$G. ;; 'dirtrack-list' is set to (list "^emacs \\([a-zA-Z]:.*\\)>" 1) ;; ;; 2) On Solaris running bash, my prompt is set like this: @@ -99,9 +101,9 @@ ;; with a ~ in it). ;; ;; The same behavior can occur if you use dirtrack with remote filesystems -;; (using telnet, etc.) as Emacs will be checking the local filesystem, not -;; the remote one. This problem is not specific to dirtrack, but also -;; affects file completion, etc. +;; (using telnet, ssh, etc.) as Emacs will be checking the local +;; filesystem, not the remote one. This problem is not specific to dirtrack, +;; but also affects file completion, etc. ;;; Code: commit 5f0ef3c9d8b564d277bd78e05b688994658a4073 Author: Stefan Kangas Date: Tue Jul 12 18:42:52 2022 +0200 ; * lisp/dirtrack.el: Improve commentary. diff --git a/lisp/dirtrack.el b/lisp/dirtrack.el index da60840f8b..080c02294e 100644 --- a/lisp/dirtrack.el +++ b/lisp/dirtrack.el @@ -30,9 +30,8 @@ ;; that you can customize your shell's prompt to contain the ;; current working directory. Most shells do support this, including ;; almost every type of Bourne and C shell on Unix, the native shells on -;; Windows95 (COMMAND.COM) and Windows NT (CMD.EXE), and most 3rd party -;; Windows shells. If you cannot do this, or do not wish to, this package -;; will be useless to you. +;; Windows, and most 3rd party Windows shells. If you cannot do this, or +;; do not wish to, this package will be useless to you. ;; ;; Installation: ;; @@ -92,7 +91,7 @@ ;; A final note: ;; ;; I run LOTS of shell buffers through Emacs, sometimes as different users -;; (eg, when logged in as myself, I'll run a root shell in the same Emacs). +;; (e.g., when logged in as myself, I'll run a root shell in the same Emacs). ;; If you do this, and the shell prompt contains a ~, Emacs will interpret ;; this relative to the user which owns the Emacs process, not the user ;; who owns the shell buffer. This may cause dirtrack to behave strangely @@ -100,9 +99,9 @@ ;; with a ~ in it). ;; ;; The same behavior can occur if you use dirtrack with remote filesystems -;; (using telnet, rlogin, etc) as Emacs will be checking the local -;; filesystem, not the remote one. This problem is not specific to dirtrack, -;; but also affects file completion, etc. +;; (using telnet, etc.) as Emacs will be checking the local filesystem, not +;; the remote one. This problem is not specific to dirtrack, but also +;; affects file completion, etc. ;;; Code: commit c518b06ae65091d24132e8c6768a8b06e03b6d87 Author: Stefan Kangas Date: Tue Jul 12 16:32:50 2022 +0200 Drop obsolete rsh/rlogin from two user options * lisp/net/ange-ftp.el (ange-ftp-gateway-program): * lisp/net/imap.el (imap-shell-program): Drop obsolete "rsh"/"rlogin". diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el index 9937c022d9..8355ca4838 100644 --- a/lisp/net/ange-ftp.el +++ b/lisp/net/ange-ftp.el @@ -1,7 +1,6 @@ ;;; ange-ftp.el --- transparent FTP support for GNU Emacs -*- lexical-binding:t -*- -;; Copyright (C) 1989-1996, 1998, 2000-2022 Free Software Foundation, -;; Inc. +;; Copyright (C) 1989-2022 Free Software Foundation, Inc. ;; Author: Andy Norman (ange@hplb.hpl.hp.com) ;; Maintainer: emacs-devel@gnu.org @@ -870,13 +869,10 @@ Both telnet and rlogin do something like this." (defcustom ange-ftp-gateway-program remote-shell-program "Name of program to spawn a shell on the gateway machine. -Valid candidates are rsh (remsh on some systems), telnet and rlogin. See also the gateway variable above." :group 'ange-ftp - :type '(choice (const "rsh") - (const "telnet") - (const "rlogin") - string)) + :type 'string + :version "29.1") (defcustom ange-ftp-gateway-prompt-pattern "^[^#$%>;\n]*[#$%>;] *" "Regexp matching prompt after complete login sequence on gateway machine. diff --git a/lisp/net/imap.el b/lisp/net/imap.el index ac24efdccb..0b6488292d 100644 --- a/lisp/net/imap.el +++ b/lisp/net/imap.el @@ -175,16 +175,15 @@ the list is tried until a successful connection is made." :type '(repeat string)) (defcustom imap-shell-program '("ssh %s imapd" - "rsh %s imapd" - "ssh %g ssh %s imapd" - "rsh %g rsh %s imapd") + "ssh %g ssh %s imapd") "A list of strings, containing commands for IMAP connection. Within a string, %s is replaced with the server address, %p with port number on server, %g with `imap-shell-host', and %l with `imap-default-user'. The program should read IMAP commands from stdin and write IMAP response to stdout. Each entry in the list is tried until a successful connection is made." - :type '(repeat string)) + :type '(repeat string) + :version "29.1") (defcustom imap-process-connection-type nil "Value for `process-connection-type' to use for Kerberos4, GSSAPI, shell and SSL. commit 0b94747ddc0391205b921adb5f3b6b488cca6b59 Author: Stefan Kangas Date: Tue Jul 12 16:32:07 2022 +0200 Make pcomplete/{rsh,rlogin} into alias for pcomplete/ssh * lisp/pcmpl-unix.el (pcomplete/rlogin, pcomplete/rsh): Make into aliases for 'pcomplete/ssh', as "rsh" and "rlogin" is more often than not aliases for "ssh" on modern machines. diff --git a/lisp/pcmpl-unix.el b/lisp/pcmpl-unix.el index 0074722be7..8774f091c8 100644 --- a/lisp/pcmpl-unix.el +++ b/lisp/pcmpl-unix.el @@ -197,6 +197,10 @@ Uses both `pcmpl-ssh-config-file' and `pcmpl-ssh-known-hosts-file'." (pcomplete-opt "1246AaCfgKkMNnqsTtVvXxYbcDeFiLlmOopRSw") (pcomplete-here (pcmpl-ssh-hosts))) +;;;###autoload +(defalias 'pcomplete/rsh #'pcomplete/ssh) +(defalias 'pcomplete/rlogin #'pcomplete/ssh) + ;;;###autoload (defun pcomplete/scp () "Completion rules for the `scp' command. @@ -229,22 +233,12 @@ Includes files as well as host names followed by a colon." (defalias 'pcomplete/ftp 'pcmpl-unix-complete-hostname) (defalias 'pcomplete/ncftp 'pcmpl-unix-complete-hostname) (defalias 'pcomplete/ping 'pcmpl-unix-complete-hostname) -(defalias 'pcomplete/rlogin 'pcmpl-unix-complete-hostname) ;;;###autoload (defun pcomplete/telnet () (pcomplete-opt "xl(pcmpl-unix-user-names)") (pcmpl-unix-complete-hostname)) -;;;###autoload -(defun pcomplete/rsh () - "Complete `rsh', which, after the user and hostname, is like xargs." - (pcomplete-opt "l(pcmpl-unix-user-names)") - (pcmpl-unix-complete-hostname) - (pcomplete-here (funcall pcomplete-command-completion-function)) - (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1)) - pcomplete-default-completion-function))) - (provide 'pcmpl-unix) ;;; pcmpl-unix.el ends here commit 4650ea9c25514831d925e5006ea0c3679344333b Author: Eli Zaretskii Date: Tue Jul 12 17:10:40 2022 +0300 ; Fix recent additions to the Eshell manual * doc/misc/eshell.texi (Variables): Fix a @footnote. (Variables): Fix indexing and @item's in a @table. diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index a72fc925c6..f6ec1e268a 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -847,9 +847,11 @@ For example, you could handle a subset of the options for the @node Variables @section Variables -Since Eshell is just an Emacs REPL@footnote{Read-Eval-Print Loop}, it -does not have its own scope, and simply stores variables the same you -would in an Elisp program. Eshell provides a command version of +Since Eshell is just an Emacs @acronym{REPL}@footnote{ +Short for ``Read-Eval-Print Loop''. +} +, it does not have its own scope, and simply stores variables the same +you would in an Elisp program. Eshell provides a command version of @code{setq} for convenience. @subsection Built-in variables @@ -857,44 +859,44 @@ Eshell knows a few built-in variables: @table @code -@item $PWD -@item $+ @vindex $PWD @vindex $+ +@item $PWD +@itemx $+ This variable always contains the current working directory. -@item $OLDPWD -@item $- @vindex $OLDPWD @vindex $- +@item $OLDPWD +@itemx $- This variable always contains the previous working directory (the current working directory from before the last @code{cd} command). When using @code{$-}, you can also access older directories in the -directory ring via subscripting, e.g. @samp{$-[1]} refers to the +directory ring via subscripting, e.g.@: @samp{$-[1]} refers to the working directory @emph{before} the previous one. -@item $_ @vindex $_ +@item $_ This refers to the last argument of the last command. With a subscript, you can access any argument of the last command. For example, @samp{$_[1]} refers to the second argument of the last command (excluding the command name itself). -@item $$ @vindex $$ +@item $$ This is the result of the last command. In case of an external command, it is @code{t} or @code{nil}. -@item $? @vindex $? +@item $? This variable contains the exit code of the last command. If the last command was a Lisp function, it is 0 for successful completion or 1 otherwise. -@item $COLUMNS -@item $LINES @vindex $COLUMNS @vindex $LINES +@item $COLUMNS +@itemx $LINES These variables tell the number of columns and lines, respectively, that are currently visible in the Eshell window. They are both copied to the environment, so external commands invoked from commit df5613c45ed54ea5303a0122333d2bde83785785 Author: Eli Zaretskii Date: Tue Jul 12 17:03:08 2022 +0300 ; * lisp/eshell/esh-var.el (eshell-variable-aliases-list): Doc fix. diff --git a/lisp/eshell/esh-var.el b/lisp/eshell/esh-var.el index cbd7942de4..2c92567773 100644 --- a/lisp/eshell/esh-var.el +++ b/lisp/eshell/esh-var.el @@ -188,27 +188,28 @@ accessed via the syntax `$NAME'. If VALUE is a function, its behavior depends on the value of SIMPLE-FUNCTION. If SIMPLE-FUNCTION is nil, call VALUE with two -arguments: the list of the indices that was used in the reference and -whether the variable was used within double quotes. For example, if -`NAME' were aliased to a function, a reference of `$NAME[10][20]' -would result in that function being called with the arguments -`((\"10\") (\"20\"))' and nil. If SIMPLE-FUNCTION is non-nil, call -the function with no arguments and then pass its result to -`eshell-apply-indices'. +arguments: the list of the indices that were used in the reference, +and either t or nil depending on whether or not the variable was +quoted with double quotes. For example, if `NAME' were aliased +to a function, a reference of `$NAME[10][20]' would result in that +function being called with the arguments `((\"10\") (\"20\"))' and +nil. +If SIMPLE-FUNCTION is non-nil, call the function with no arguments +and then pass its return value to `eshell-apply-indices'. If VALUE is a string, return the value for the variable with that name in the current environment. If no variable with that name exists in the environment, but if a symbol with that same name exists and has -a value bound to it, return its value instead. You can prioritize -symbol values over environment values by setting -`eshell-prefer-lisp-variables' to t. +a value bound to it, return that symbol's value instead. You can +prefer symbol values over environment values by setting the value +of `eshell-prefer-lisp-variables' to t. If VALUE is a symbol, return the value bound to it. If VALUE has any other type, signal an error. Additionally, if COPY-TO-ENVIRONMENT is non-nil, the alias should be -copied to the environment of created subprocesses." +copied (a.k.a. \"exported\") to the environment of created subprocesses." :type '(repeat (list string sexp (choice (const :tag "Copy to environment" t) (const :tag "Use only in Eshell" nil)))) commit 0143e9166656ddd601789e49c1a322111acd77b7 Author: Michael Albinus Date: Tue Jul 12 15:42:17 2022 +0200 Remove rsh from Tramp manual, Overview section * doc/misc/tramp.texi (Overview, Frequently Asked Questions): Don't mention obsolete rsh and rcp. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 2699ca92c1..1ebe5f562a 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -179,11 +179,10 @@ interface to remote files as if they are local files. @value{tramp}'s transparency extends to editing, version control, and @code{dired}. @value{tramp} can access remote hosts using any number of access -methods, such as @command{ssh}, @command{rsh}, @command{rlogin}, -@command{telnet}, and related programs. If these programs can -successfully pass @acronym{ASCII} characters, @value{tramp} can use -them. @value{tramp} does not require or mandate 8-bit clean -connections. +methods, such as @command{ssh}, @command{scp}, @command{telnet}, and +related programs. If these programs can successfully pass +@acronym{ASCII} characters, @value{tramp} can use them. @value{tramp} +does not require or mandate 8-bit clean connections. @value{tramp}'s most common access method is through @command{ssh}, a more secure alternative to @command{ftp} and other older access @@ -231,10 +230,10 @@ first time connecting to that host, here's what happens: @itemize @item -@value{tramp} invokes @samp{telnet @var{host}} or @samp{rsh @var{host} --l @var{user}} and establishes an external process to connect to the -remote host. @value{tramp} communicates with the process through an -Emacs buffer, which also shows output from the remote host. +@value{tramp} invokes @samp{telnet @var{host}} or @samp{ssh -l +@var{user} @var{host}} and establishes an external process to connect +to the remote host. @value{tramp} communicates with the process +through an Emacs buffer, which also shows output from the remote host. @item The remote host may prompt for a login name (for @command{telnet}, for @@ -244,7 +243,7 @@ followed by a newline. @item The remote host may then prompt for a password or passphrase (for -@command{rsh} or for @command{telnet}). @value{tramp} displays the +@command{ssh} or for @command{telnet}). @value{tramp} displays the password prompt in the minibuffer. @value{tramp} then sends whatever is entered to the remote host, followed by a newline. @@ -5620,6 +5619,7 @@ Disable @value{tramp} file name completion: (customize-set-variable 'ido-enable-tramp-completion nil) @end lisp +@c Obsolete since Emacs 29.1. @item @file{rlogin.el} @@ -5685,8 +5685,8 @@ What is the difference between Ange FTP and @value{tramp}? The difference is that Ange FTP uses @command{ftp} to transfer files between the local and the remote host, whereas @value{tramp} uses a -combination of @command{rsh} and @command{rcp} or other work-alike -programs, such as @command{ssh}/@command{scp}. +combination of @command{ssh} and @command{scp} or other work-alike +programs. @end itemize commit 18d83b94528c503f2cd6d0a89f2c5db2d5d48165 Author: Jim Porter Date: Wed Jul 6 21:59:11 2022 -0700 Ensure Eshell variable aliases properly handle indexing * lisp/eshell/em-dirs.el (eshell-dirs-initialize): Properly handle indexing for variable aliases. * lisp/eshell/esh-var (eshell-variable-aliases-list): Properly handle indexing for variable aliases, and add SIMPLE-FUNCTION entry for aliases. (eshell-get-variable): Update how variable alias functions are called. * test/lisp/eshell/em-alias-tests.el (em-alias-test/alias-arg-vars-indices) (em-alias-test/alias-arg-vars-split-indices) (em-alias-test/alias-all-args-var-split-indices): * test/lisp/eshell/em-dirs-tests.el (em-dirs-test/pwd-var-indices) (em-dirs-test/oldpwd-var-indices) (em-dirs-test/directory-ring-var-indices): * test/lisp/eshell/esh-var-tests.el (esh-var-test/inside-emacs-var-split-indices) (esh-var-test/last-result-var-split-indices): New tests. (esh-var-test/last-arg-var-split-indices): Expand test to check conversion behavior inside double quotes (bug#56509). diff --git a/lisp/eshell/em-dirs.el b/lisp/eshell/em-dirs.el index a3cf0b9131..00880b9f28 100644 --- a/lisp/eshell/em-dirs.el +++ b/lisp/eshell/em-dirs.el @@ -175,22 +175,26 @@ Thus, this does not include the current directory.") (setq-local eshell-variable-aliases-list (append eshell-variable-aliases-list - `(("-" ,(lambda (indices) - (if (not indices) - (unless (ring-empty-p eshell-last-dir-ring) - (expand-file-name - (ring-ref eshell-last-dir-ring 0))) - (expand-file-name - (eshell-apply-indices eshell-last-dir-ring indices))))) - ("+" "PWD") - ("PWD" ,(lambda (_indices) - (expand-file-name (eshell/pwd))) - t) - ("OLDPWD" ,(lambda (_indices) - (unless (ring-empty-p eshell-last-dir-ring) - (expand-file-name - (ring-ref eshell-last-dir-ring 0)))) - t)))) + `(("-" ,(lambda (indices quoted) + (if (not indices) + (unless (ring-empty-p eshell-last-dir-ring) + (expand-file-name + (ring-ref eshell-last-dir-ring 0))) + ;; Apply the first index, expand the file name, + ;; and then apply the rest of the indices. + (eshell-apply-indices + (expand-file-name + (eshell-apply-indices eshell-last-dir-ring + (list (car indices)) quoted)) + (cdr indices) quoted)))) + ("+" "PWD") + ("PWD" ,(lambda () (expand-file-name (eshell/pwd))) + t t) + ("OLDPWD" ,(lambda () + (unless (ring-empty-p eshell-last-dir-ring) + (expand-file-name + (ring-ref eshell-last-dir-ring 0)))) + t t)))) (when eshell-cd-on-directory (setq-local eshell-interpreter-alist diff --git a/lisp/eshell/esh-var.el b/lisp/eshell/esh-var.el index e1535c1c5d..cbd7942de4 100644 --- a/lisp/eshell/esh-var.el +++ b/lisp/eshell/esh-var.el @@ -152,59 +152,63 @@ if they are quoted with a backslash." (defcustom eshell-variable-aliases-list `(;; for eshell.el - ("COLUMNS" ,(lambda (_indices) (window-body-width nil 'remap)) t) - ("LINES" ,(lambda (_indices) (window-body-height nil 'remap)) t) + ("COLUMNS" ,(lambda () (window-body-width nil 'remap)) t t) + ("LINES" ,(lambda () (window-body-height nil 'remap)) t t) ("INSIDE_EMACS" eshell-inside-emacs t) ;; for eshell-cmd.el - ("_" ,(lambda (indices) + ("_" ,(lambda (indices quoted) (if (not indices) (car (last eshell-last-arguments)) (eshell-apply-indices eshell-last-arguments - indices)))) + indices quoted)))) ("?" eshell-last-command-status) ("$" eshell-last-command-result) ;; for em-alias.el and em-script.el ("0" eshell-command-name) - ("1" ,(lambda (_indices) (nth 0 eshell-command-arguments))) - ("2" ,(lambda (_indices) (nth 1 eshell-command-arguments))) - ("3" ,(lambda (_indices) (nth 2 eshell-command-arguments))) - ("4" ,(lambda (_indices) (nth 3 eshell-command-arguments))) - ("5" ,(lambda (_indices) (nth 4 eshell-command-arguments))) - ("6" ,(lambda (_indices) (nth 5 eshell-command-arguments))) - ("7" ,(lambda (_indices) (nth 6 eshell-command-arguments))) - ("8" ,(lambda (_indices) (nth 7 eshell-command-arguments))) - ("9" ,(lambda (_indices) (nth 8 eshell-command-arguments))) - ("*" ,(lambda (indices) - (if (not indices) - eshell-command-arguments - (eshell-apply-indices eshell-command-arguments - indices))))) + ("1" ,(lambda () (nth 0 eshell-command-arguments)) nil t) + ("2" ,(lambda () (nth 1 eshell-command-arguments)) nil t) + ("3" ,(lambda () (nth 2 eshell-command-arguments)) nil t) + ("4" ,(lambda () (nth 3 eshell-command-arguments)) nil t) + ("5" ,(lambda () (nth 4 eshell-command-arguments)) nil t) + ("6" ,(lambda () (nth 5 eshell-command-arguments)) nil t) + ("7" ,(lambda () (nth 6 eshell-command-arguments)) nil t) + ("8" ,(lambda () (nth 7 eshell-command-arguments)) nil t) + ("9" ,(lambda () (nth 8 eshell-command-arguments)) nil t) + ("*" eshell-command-arguments)) "This list provides aliasing for variable references. -Each member defines the name of a variable, and a Lisp value used to +Each member is of the following form: + + (NAME VALUE [COPY-TO-ENVIRONMENT] [SIMPLE-FUNCTION]) + +NAME defines the name of the variable, VALUE is a Lisp value used to compute the string value that will be returned when the variable is accessed via the syntax `$NAME'. -If the value is a function, call that function with one argument: the -list of the indices that was used in the reference. For example, if +If VALUE is a function, its behavior depends on the value of +SIMPLE-FUNCTION. If SIMPLE-FUNCTION is nil, call VALUE with two +arguments: the list of the indices that was used in the reference and +whether the variable was used within double quotes. For example, if `NAME' were aliased to a function, a reference of `$NAME[10][20]' -would result in that function being called with the argument -`((\"10\") (\"20\"))'. (For more details, see `eshell-apply-indices'). +would result in that function being called with the arguments +`((\"10\") (\"20\"))' and nil. If SIMPLE-FUNCTION is non-nil, call +the function with no arguments and then pass its result to +`eshell-apply-indices'. -If the value is a string, return the value for the variable with that +If VALUE is a string, return the value for the variable with that name in the current environment. If no variable with that name exists in the environment, but if a symbol with that same name exists and has a value bound to it, return its value instead. You can prioritize symbol values over environment values by setting `eshell-prefer-lisp-variables' to t. -If the value is a symbol, return the value bound to it. +If VALUE is a symbol, return the value bound to it. -If the value has any other type, signal an error. +If VALUE has any other type, signal an error. -Additionally, each member may specify if it should be copied to the -environment of created subprocesses." +Additionally, if COPY-TO-ENVIRONMENT is non-nil, the alias should be +copied to the environment of created subprocesses." :type '(repeat (list string sexp (choice (const :tag "Copy to environment" t) (const :tag "Use only in Eshell" nil)))) @@ -550,10 +554,19 @@ For example, \"[0 1][2]\" becomes: INDICES is a list of index-lists (see `eshell-parse-indices'). If QUOTED is non-nil, this was invoked inside double-quotes." (if-let ((alias (assoc name eshell-variable-aliases-list))) - (let ((target (cadr alias))) + (let ((target (nth 1 alias))) (cond ((functionp target) - (funcall target indices)) + (if (nth 3 alias) + (eshell-apply-indices (funcall target) indices quoted) + (condition-case nil + (funcall target indices quoted) + (wrong-number-of-arguments + (display-warning + :warning (concat "Function for `eshell-variable-aliases-list' " + "entry should accept two arguments: INDICES " + "and QUOTED.'")) + (funcall target indices))))) ((symbolp target) (eshell-apply-indices (symbol-value target) indices quoted)) (t diff --git a/test/lisp/eshell/em-alias-tests.el b/test/lisp/eshell/em-alias-tests.el index 762f125a78..497159e346 100644 --- a/test/lisp/eshell/em-alias-tests.el +++ b/test/lisp/eshell/em-alias-tests.el @@ -47,6 +47,23 @@ (eshell-insert-command "alias show-args 'printnl $0 \"$1 $2\"'") (eshell-command-result-p "show-args one two" "show-args\none two\n"))) +(ert-deftest em-alias-test/alias-arg-vars-indices () + "Test alias with $1, $2, ... variables using indices" + (with-temp-eshell + (eshell-insert-command "alias funny-sum '+ $1[0] $2[1]'") + (eshell-command-result-p "funny-sum (list 1 2) (list 3 4)" + "5\n"))) + +(ert-deftest em-alias-test/alias-arg-vars-split-indices () + "Test alias with $0, $1, ... variables using split indices" + (with-temp-eshell + (eshell-insert-command "alias my-prefix 'echo $0[- 0]'") + (eshell-command-result-p "my-prefix" + "my\n") + (eshell-insert-command "alias funny-sum '+ $1[: 0] $2[: 1]'") + (eshell-command-result-p "funny-sum 1:2 3:4" + "5\n"))) + (ert-deftest em-alias-test/alias-all-args-var () "Test alias with the $* variable" (with-temp-eshell @@ -61,4 +78,10 @@ (eshell-insert-command "alias add-pair '+ $*[0] $*[1]'") (eshell-command-result-p "add-pair 1 2" "3\n"))) +(ert-deftest em-alias-test/alias-all-args-var-split-indices () + "Test alias with the $* variable using split indices" + (with-temp-eshell + (eshell-insert-command "alias add-funny-pair '+ $*[0][: 0] $*[1][: 1]'") + (eshell-command-result-p "add-funny-pair 1:2 3:4" "5\n"))) + ;; em-alias-tests.el ends here diff --git a/test/lisp/eshell/em-dirs-tests.el b/test/lisp/eshell/em-dirs-tests.el index 69480051e4..8e96cc0747 100644 --- a/test/lisp/eshell/em-dirs-tests.el +++ b/test/lisp/eshell/em-dirs-tests.el @@ -40,6 +40,14 @@ (should (equal (eshell-test-command-result "echo $PWD") (expand-file-name default-directory))))) +(ert-deftest em-dirs-test/pwd-var-indices () + "Test using the $PWD variable with indices." + (let ((default-directory "/some/path/here")) + (should (equal (eshell-test-command-result "echo $PWD[/ 1]") + "some")) + (should (equal (eshell-test-command-result "echo $PWD[/ 1 3]") + '("some" "here"))))) + (ert-deftest em-dirs-test/short-pwd-var () "Test using the $+ (current directory) variable." (let ((default-directory "/some/path")) @@ -56,6 +64,16 @@ (eshell-command-result-p "echo $OLDPWD" "/some/path\n")))) +(ert-deftest em-dirs-test/oldpwd-var-indices () + "Test using the $OLDPWD variable with indices." + (let (eshell-last-dir-ring-file-name) + (with-temp-eshell + (ring-insert eshell-last-dir-ring "/some/path/here") + (eshell-command-result-p "echo $OLDPWD[/ 1]" + "some\n") + (eshell-command-result-p "echo $OLDPWD[/ 1 3]" + "(\"some\" \"here\")\n")))) + (ert-deftest em-dirs-test/directory-ring-var () "Test using the $- (directory ring) variable." (let (eshell-last-dir-ring-file-name) @@ -71,4 +89,14 @@ (eshell-command-result-p "echo $-[1]" "/some/path\n")))) +(ert-deftest em-dirs-test/directory-ring-var-indices () + "Test using the $- (directory ring) variable with multiple indices." + (let (eshell-last-dir-ring-file-name) + (with-temp-eshell + (ring-insert eshell-last-dir-ring "/some/path/here") + (eshell-command-result-p "echo $-[0][/ 1]" + "some\n") + (eshell-command-result-p "echo $-[1][/ 1 3]" + "(\"some\" \"here\")\n")))) + ;; em-dirs-tests.el ends here diff --git a/test/lisp/eshell/esh-var-tests.el b/test/lisp/eshell/esh-var-tests.el index 955190aee0..54e701a6aa 100644 --- a/test/lisp/eshell/esh-var-tests.el +++ b/test/lisp/eshell/esh-var-tests.el @@ -494,6 +494,12 @@ inside double-quotes" (format "INSIDE_EMACS=%s,eshell" emacs-version)))) +(ert-deftest esh-var-test/inside-emacs-var-split-indices () + "Test using \"INSIDE_EMACS\" with split indices" + (with-temp-eshell + (eshell-command-result-p "echo $INSIDE_EMACS[, 1]" + "eshell"))) + (ert-deftest esh-var-test/last-result-var () "Test using the \"last result\" ($$) variable" (with-temp-eshell @@ -506,6 +512,16 @@ inside double-quotes" (eshell-command-result-p "+ 1 2; + $$ $$" "3\n6\n"))) +(ert-deftest esh-var-test/last-result-var-split-indices () + "Test using the \"last result\" ($$) variable with split indices" + (with-temp-eshell + (eshell-command-result-p + "string-join (list \"01\" \"02\") :; + $$[: 1] 3" + "01:02\n5\n") + (eshell-command-result-p + "string-join (list \"01\" \"02\") :; echo \"$$[: 1]\"" + "01:02\n02\n"))) + (ert-deftest esh-var-test/last-arg-var () "Test using the \"last arg\" ($_) variable" (with-temp-eshell @@ -523,7 +539,9 @@ inside double-quotes" (ert-deftest esh-var-test/last-arg-var-split-indices () "Test using the \"last arg\" ($_) variable with split indices" (with-temp-eshell - (eshell-command-result-p "concat 01:02 03:04; echo $_[0][: 1]" - "01:0203:04\n2\n"))) + (eshell-command-result-p "concat 01:02 03:04; + $_[0][: 1] 5" + "01:0203:04\n7\n") + (eshell-command-result-p "concat 01:02 03:04; echo \"$_[0][: 1]\"" + "01:0203:04\n02\n"))) ;; esh-var-tests.el ends here commit ba1923f1f1bba69bc13620042a00e315946ba82a Author: Jim Porter Date: Fri Jul 8 18:41:07 2022 -0700 Allow Eshell variable aliases to point to other aliases In particular, this resolves an issue where '$+' referenced the real environment variable '$PWD' instead of the Eshell variable alias of the same name. This meant that changing directories in Eshell wouldn't update the value of '$+'. * lisp/eshell/esh-var.el (eshell-get-variable): Allow Eshell variable aliaes to point to other aliases. * test/lisp/eshell/em-dirs-tests.el (em-dirs-test/pwd-var) (em-dirs-test/short-pwd-var): Adapt tests to check this case (bug#56509). diff --git a/lisp/eshell/esh-var.el b/lisp/eshell/esh-var.el index 5092d2c6a5..e1535c1c5d 100644 --- a/lisp/eshell/esh-var.el +++ b/lisp/eshell/esh-var.el @@ -549,27 +549,26 @@ For example, \"[0 1][2]\" becomes: "Get the value for the variable NAME. INDICES is a list of index-lists (see `eshell-parse-indices'). If QUOTED is non-nil, this was invoked inside double-quotes." - (let* ((alias (assoc name eshell-variable-aliases-list)) - (var (if alias - (cadr alias) - name))) - (if (and alias (functionp var)) - (funcall var indices) - (eshell-apply-indices - (cond - ((stringp var) - (let ((sym (intern-soft var))) - (if (and sym (boundp sym) - (or eshell-prefer-lisp-variables - (memq sym eshell--local-vars) ; bug#15372 - (not (getenv var)))) - (symbol-value sym) - (getenv var)))) - ((symbolp var) - (symbol-value var)) - (t - (error "Unknown variable `%s'" (eshell-stringify var)))) - indices quoted)))) + (if-let ((alias (assoc name eshell-variable-aliases-list))) + (let ((target (cadr alias))) + (cond + ((functionp target) + (funcall target indices)) + ((symbolp target) + (eshell-apply-indices (symbol-value target) indices quoted)) + (t + (eshell-get-variable target indices quoted)))) + (unless (stringp name) + (error "Unknown variable `%s'" (eshell-stringify name))) + (eshell-apply-indices + (let ((sym (intern-soft name))) + (if (and sym (boundp sym) + (or eshell-prefer-lisp-variables + (memq sym eshell--local-vars) ; bug#15372 + (not (getenv name)))) + (symbol-value sym) + (getenv name))) + indices quoted))) (defun eshell-apply-indices (value indices &optional quoted) "Apply to VALUE all of the given INDICES, returning the sub-result. diff --git a/test/lisp/eshell/em-dirs-tests.el b/test/lisp/eshell/em-dirs-tests.el index eb27acd208..69480051e4 100644 --- a/test/lisp/eshell/em-dirs-tests.el +++ b/test/lisp/eshell/em-dirs-tests.el @@ -36,13 +36,15 @@ (ert-deftest em-dirs-test/pwd-var () "Test using the $PWD variable." - (should (equal (eshell-test-command-result "echo $PWD") - (expand-file-name (eshell/pwd))))) + (let ((default-directory "/some/path")) + (should (equal (eshell-test-command-result "echo $PWD") + (expand-file-name default-directory))))) (ert-deftest em-dirs-test/short-pwd-var () "Test using the $+ (current directory) variable." - (should (equal (eshell-test-command-result "echo $+") - (expand-file-name (eshell/pwd))))) + (let ((default-directory "/some/path")) + (should (equal (eshell-test-command-result "echo $+") + (expand-file-name default-directory))))) (ert-deftest em-dirs-test/oldpwd-var () "Test using the $OLDPWD variable." commit e51ae63ec28c46f37436f649d6421859c1ad0077 Author: Jim Porter Date: Sun Jul 3 20:05:29 2022 -0700 Improve tests/organization for built-in variables * lisp/eshell/em-dirs.el (eshell-inside-emacs) (eshell-dirs-initialize): Move 'INSIDE_EMACS' from here... * lisp/eshell/esh-var.el (eshell-inside-emacs) (eshell-variable-aliases-alist): ... to here, and improve doc string. * test/lisp/eshell/eshell-tests.el (eshell-test/inside-emacs-var): Move from here... * test/lisp/eshell/esh-var-tests.el (esh-var-test/inside-emacs-var): ... to here. (esh-var-test/last-arg-var-indices) (esh-var-test/last-arg-var-split-indices): New tests. * test/lisp/eshell/em-alias-tests.el: * test/lisp/eshell/em-dirs-tests.el: * test/lisp/eshell-em-script-tests.el: New files. * doc/misc/eshell.texi (Built-ins): Fix 'cd' documentation; it works with the directory ring, not the directory stack. Move built-in variables documentation from here... (Variables): ... to here, and add documentation for missing built-in variables. diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 6a348f37dc..a72fc925c6 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -354,11 +354,11 @@ Giving the command @kbd{cd -} changes back to the previous working directory (this is the same as @kbd{cd $-}). @item -The command @kbd{cd =} shows the directory stack. Each line is +The command @kbd{cd =} shows the directory ring. Each line is numbered. @item -With @kbd{cd =foo}, Eshell searches the directory stack for a directory +With @kbd{cd =foo}, Eshell searches the directory ring for a directory matching the regular expression @samp{foo}, and changes to that directory. @@ -845,23 +845,40 @@ For example, you could handle a subset of the options for the @end defmac +@node Variables +@section Variables +Since Eshell is just an Emacs REPL@footnote{Read-Eval-Print Loop}, it +does not have its own scope, and simply stores variables the same you +would in an Elisp program. Eshell provides a command version of +@code{setq} for convenience. + @subsection Built-in variables Eshell knows a few built-in variables: @table @code +@item $PWD @item $+ +@vindex $PWD @vindex $+ This variable always contains the current working directory. +@item $OLDPWD @item $- +@vindex $OLDPWD @vindex $- This variable always contains the previous working directory (the current working directory from before the last @code{cd} command). +When using @code{$-}, you can also access older directories in the +directory ring via subscripting, e.g. @samp{$-[1]} refers to the +working directory @emph{before} the previous one. @item $_ @vindex $_ -It refers to the last argument of the last command. +This refers to the last argument of the last command. With a +subscript, you can access any argument of the last command. For +example, @samp{$_[1]} refers to the second argument of the last +command (excluding the command name itself). @item $$ @vindex $$ @@ -870,21 +887,29 @@ command, it is @code{t} or @code{nil}. @item $? @vindex $? -This variable contains the exit code of the last command (0 or 1 for -Lisp functions, based on successful completion). +This variable contains the exit code of the last command. If the last +command was a Lisp function, it is 0 for successful completion or 1 +otherwise. + +@item $COLUMNS +@item $LINES +@vindex $COLUMNS +@vindex $LINES +These variables tell the number of columns and lines, respectively, +that are currently visible in the Eshell window. They are both +copied to the environment, so external commands invoked from +Eshell can consult them to do the right thing. + +@item $INSIDE_EMACS +This variable indicates to external commands that they are being +invoked from within Emacs so they can adjust their behavior if +necessary. Its value is @code{@var{emacs-version},eshell}. @end table @xref{Aliases}, for the built-in variables @samp{$*}, @samp{$1}, @samp{$2}, @dots{}, in alias definitions. -@node Variables -@section Variables -Since Eshell is just an Emacs REPL@footnote{Read-Eval-Print Loop}, it -does not have its own scope, and simply stores variables the same you -would in an Elisp program. Eshell provides a command version of -@code{setq} for convenience. - @node Aliases @section Aliases diff --git a/lisp/eshell/em-dirs.el b/lisp/eshell/em-dirs.el index 5396044d8c..a3cf0b9131 100644 --- a/lisp/eshell/em-dirs.el +++ b/lisp/eshell/em-dirs.el @@ -168,9 +168,6 @@ Thus, this does not include the current directory.") (defvar eshell-last-dir-ring nil "The last directory that Eshell was in.") -(defconst eshell-inside-emacs (format "%s,eshell" emacs-version) - "Value for the `INSIDE_EMACS' environment variable.") - ;;; Functions: (defun eshell-dirs-initialize () ;Called from `eshell-mode' via intern-soft! @@ -193,8 +190,6 @@ Thus, this does not include the current directory.") (unless (ring-empty-p eshell-last-dir-ring) (expand-file-name (ring-ref eshell-last-dir-ring 0)))) - t) - ("INSIDE_EMACS" eshell-inside-emacs t)))) (when eshell-cd-on-directory diff --git a/lisp/eshell/esh-var.el b/lisp/eshell/esh-var.el index 17add9b668..5092d2c6a5 100644 --- a/lisp/eshell/esh-var.el +++ b/lisp/eshell/esh-var.el @@ -113,6 +113,9 @@ (require 'pcomplete) (require 'ring) +(defconst eshell-inside-emacs (format "%s,eshell" emacs-version) + "Value for the `INSIDE_EMACS' environment variable.") + (defgroup eshell-var nil "Variable interpolation is introduced whenever the `$' character appears unquoted in any argument (except when that argument is @@ -151,6 +154,7 @@ if they are quoted with a backslash." `(;; for eshell.el ("COLUMNS" ,(lambda (_indices) (window-body-width nil 'remap)) t) ("LINES" ,(lambda (_indices) (window-body-height nil 'remap)) t) + ("INSIDE_EMACS" eshell-inside-emacs t) ;; for eshell-cmd.el ("_" ,(lambda (indices) @@ -160,6 +164,8 @@ if they are quoted with a backslash." indices)))) ("?" eshell-last-command-status) ("$" eshell-last-command-result) + + ;; for em-alias.el and em-script.el ("0" eshell-command-name) ("1" ,(lambda (_indices) (nth 0 eshell-command-arguments))) ("2" ,(lambda (_indices) (nth 1 eshell-command-arguments))) @@ -180,13 +186,11 @@ Each member defines the name of a variable, and a Lisp value used to compute the string value that will be returned when the variable is accessed via the syntax `$NAME'. -If the value is a function, call that function with two arguments: the -list of the indices that was used in the reference, and whether the -user is requesting the length of the ultimate element. For example, a -reference of `$NAME[10][20]' would result in the function for alias -`NAME' being called (assuming it were aliased to a function), and the -arguments passed to this function would be the list `(10 20)', and -nil. +If the value is a function, call that function with one argument: the +list of the indices that was used in the reference. For example, if +`NAME' were aliased to a function, a reference of `$NAME[10][20]' +would result in that function being called with the argument +`((\"10\") (\"20\"))'. (For more details, see `eshell-apply-indices'). If the value is a string, return the value for the variable with that name in the current environment. If no variable with that name exists diff --git a/test/lisp/eshell/em-alias-tests.el b/test/lisp/eshell/em-alias-tests.el new file mode 100644 index 0000000000..762f125a78 --- /dev/null +++ b/test/lisp/eshell/em-alias-tests.el @@ -0,0 +1,64 @@ +;;; em-alias-tests.el --- em-alias test suite -*- 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 . + +;;; Commentary: + +;; Tests for Eshell's alias module. + +;;; Code: + +(require 'ert) +(require 'esh-mode) +(require 'eshell) +(require 'em-alias) + +(require 'eshell-tests-helpers + (expand-file-name "eshell-tests-helpers" + (file-name-directory (or load-file-name + default-directory)))) +;;; Tests: + +(ert-deftest em-alias-test/simple-alias () + "Test a simple alias with no arguments" + (with-temp-eshell + (eshell-insert-command "alias say-hi 'echo hi'") + (eshell-command-result-p "say-hi" "hi\n") + (eshell-command-result-p "say-hi bye" "hi\n"))) + +(ert-deftest em-alias-test/alias-arg-vars () + "Test alias with $0, $1, ... variables" + (with-temp-eshell + (eshell-insert-command "alias show-args 'printnl $0 \"$1 $2\"'") + (eshell-command-result-p "show-args one two" "show-args\none two\n"))) + +(ert-deftest em-alias-test/alias-all-args-var () + "Test alias with the $* variable" + (with-temp-eshell + (eshell-insert-command "alias show-all-args 'printnl $*'") + (eshell-command-result-p "show-all-args" "\\`\\'") + (eshell-command-result-p "show-all-args a" "a\n") + (eshell-command-result-p "show-all-args a b c" "a\nb\nc\n"))) + +(ert-deftest em-alias-test/alias-all-args-var-indices () + "Test alias with the $* variable using indices" + (with-temp-eshell + (eshell-insert-command "alias add-pair '+ $*[0] $*[1]'") + (eshell-command-result-p "add-pair 1 2" "3\n"))) + +;; em-alias-tests.el ends here diff --git a/test/lisp/eshell/em-dirs-tests.el b/test/lisp/eshell/em-dirs-tests.el new file mode 100644 index 0000000000..eb27acd208 --- /dev/null +++ b/test/lisp/eshell/em-dirs-tests.el @@ -0,0 +1,72 @@ +;;; em-dirs-tests.el --- em-dirs test suite -*- 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 . + +;;; Commentary: + +;; Tests for Eshell's dirs module. + +;;; Code: + +(require 'ert) +(require 'esh-mode) +(require 'eshell) +(require 'em-dirs) + +(require 'eshell-tests-helpers + (expand-file-name "eshell-tests-helpers" + (file-name-directory (or load-file-name + default-directory)))) +;;; Tests: + +(ert-deftest em-dirs-test/pwd-var () + "Test using the $PWD variable." + (should (equal (eshell-test-command-result "echo $PWD") + (expand-file-name (eshell/pwd))))) + +(ert-deftest em-dirs-test/short-pwd-var () + "Test using the $+ (current directory) variable." + (should (equal (eshell-test-command-result "echo $+") + (expand-file-name (eshell/pwd))))) + +(ert-deftest em-dirs-test/oldpwd-var () + "Test using the $OLDPWD variable." + (let (eshell-last-dir-ring-file-name) + (with-temp-eshell + (eshell-command-result-p "echo $OLDPWD" + "\\`\\'") + (ring-insert eshell-last-dir-ring "/some/path") + (eshell-command-result-p "echo $OLDPWD" + "/some/path\n")))) + +(ert-deftest em-dirs-test/directory-ring-var () + "Test using the $- (directory ring) variable." + (let (eshell-last-dir-ring-file-name) + (with-temp-eshell + (eshell-command-result-p "echo $-" + "\\`\\'") + (ring-insert eshell-last-dir-ring "/some/path") + (ring-insert eshell-last-dir-ring "/other/path") + (eshell-command-result-p "echo $-" + "/other/path\n") + (eshell-command-result-p "echo $-[0]" + "/other/path\n") + (eshell-command-result-p "echo $-[1]" + "/some/path\n")))) + +;; em-dirs-tests.el ends here diff --git a/test/lisp/eshell/em-script-tests.el b/test/lisp/eshell/em-script-tests.el new file mode 100644 index 0000000000..a34f943402 --- /dev/null +++ b/test/lisp/eshell/em-script-tests.el @@ -0,0 +1,62 @@ +;;; em-script-tests.el --- em-script test suite -*- 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 . + +;;; Commentary: + +;; Tests for Eshell's script module. + +;;; Code: + +(require 'ert) +(require 'esh-mode) +(require 'eshell) +(require 'em-script) + +(require 'eshell-tests-helpers + (expand-file-name "eshell-tests-helpers" + (file-name-directory (or load-file-name + default-directory)))) +;;; Tests: + +(ert-deftest em-script-test/source-script () + "Test sourcing script with no argumentss" + (ert-with-temp-file temp-file :text "echo hi" + (with-temp-eshell + (eshell-command-result-p (format "source %s" temp-file) + "hi\n")))) + +(ert-deftest em-script-test/source-script-arg-vars () + "Test sourcing script with $0, $1, ... variables" + (ert-with-temp-file temp-file :text "printnl $0 \"$1 $2\"" + (with-temp-eshell + (eshell-command-result-p (format "source %s one two" temp-file) + (format "%s\none two\n" temp-file))))) + +(ert-deftest em-script-test/source-script-all-args-var () + "Test sourcing script with the $* variable" + (ert-with-temp-file temp-file :text "printnl $*" + (with-temp-eshell + (eshell-command-result-p (format "source %s" temp-file) + "\\`\\'") + (eshell-command-result-p (format "source %s a" temp-file) + "a\n") + (eshell-command-result-p (format "source %s a b c" temp-file) + "a\nb\nc\n")))) + +;; em-script-tests.el ends here diff --git a/test/lisp/eshell/esh-var-tests.el b/test/lisp/eshell/esh-var-tests.el index 3180fe7a5f..955190aee0 100644 --- a/test/lisp/eshell/esh-var-tests.el +++ b/test/lisp/eshell/esh-var-tests.el @@ -487,6 +487,13 @@ inside double-quotes" (should (equal (eshell-test-command-result "echo $COLUMNS") (window-body-width nil 'remap)))) +(ert-deftest esh-var-test/inside-emacs-var () + "Test presence of \"INSIDE_EMACS\" in subprocesses" + (with-temp-eshell + (eshell-command-result-p "env" + (format "INSIDE_EMACS=%s,eshell" + emacs-version)))) + (ert-deftest esh-var-test/last-result-var () "Test using the \"last result\" ($$) variable" (with-temp-eshell @@ -497,12 +504,26 @@ inside double-quotes" "Test using the \"last result\" ($$) variable twice" (with-temp-eshell (eshell-command-result-p "+ 1 2; + $$ $$" - "3\n6\n"))) + "3\n6\n"))) (ert-deftest esh-var-test/last-arg-var () "Test using the \"last arg\" ($_) variable" (with-temp-eshell (eshell-command-result-p "+ 1 2; + $_ 4" - "3\n6\n"))) + "3\n6\n"))) + +(ert-deftest esh-var-test/last-arg-var-indices () + "Test using the \"last arg\" ($_) variable with indices" + (with-temp-eshell + (eshell-command-result-p "+ 1 2; + $_[0] 4" + "3\n5\n") + (eshell-command-result-p "+ 1 2; + $_[1] 4" + "3\n6\n"))) + +(ert-deftest esh-var-test/last-arg-var-split-indices () + "Test using the \"last arg\" ($_) variable with split indices" + (with-temp-eshell + (eshell-command-result-p "concat 01:02 03:04; echo $_[0][: 1]" + "01:0203:04\n2\n"))) ;; esh-var-tests.el ends here diff --git a/test/lisp/eshell/eshell-tests.el b/test/lisp/eshell/eshell-tests.el index ab5d73d479..5dc1877548 100644 --- a/test/lisp/eshell/eshell-tests.el +++ b/test/lisp/eshell/eshell-tests.el @@ -178,13 +178,6 @@ e.g. \"{(+ 1 2)} 3\" => 3" (string-replace "\\" "\\\\" bufname)))) (should (equal (buffer-string) "hi"))))) -(ert-deftest eshell-test/inside-emacs-var () - "Test presence of \"INSIDE_EMACS\" in subprocesses" - (with-temp-eshell - (eshell-command-result-p "env" - (format "INSIDE_EMACS=%s,eshell" - emacs-version)))) - (ert-deftest eshell-test/escape-nonspecial () "Test that \"\\c\" and \"c\" are equivalent when \"c\" is not a special character." commit f62e1f39be4f7da2c78d884db6ecb68a9f5b1982 Author: Lars Ingebrigtsen Date: Tue Jul 12 14:39:52 2022 +0200 Fix buffer-stale-function fix * src/buffer.c (Fmake_indirect_buffer): Kill the local buffer-stale-function variable instead of setting it buffer-locally to the default value. This should have the same effect, but is less confusing. diff --git a/src/buffer.c b/src/buffer.c index a6d3604065..e5fa09a978 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -912,7 +912,7 @@ does not run the hooks `kill-buffer-hook', Fset (intern ("buffer-save-without-query"), Qnil); Fset (intern ("buffer-file-number"), Qnil); if (!NILP (Flocal_variable_p (Qbuffer_stale_function, base_buffer))) - Fset (Qbuffer_stale_function, Qbuffer_stale__default_function); + Fkill_local_variable (Qbuffer_stale_function); /* Cloned buffers need extra setup, to do things such as deep variable copies for list variables that might be mangled due to destructive operations in the indirect buffer. */ @@ -6480,7 +6480,6 @@ will run for `clone-indirect-buffer' calls as well. */); DEFSYM (Qkill_buffer__possibly_save, "kill-buffer--possibly-save"); DEFSYM (Qbuffer_stale_function, "buffer-stale-function"); - DEFSYM (Qbuffer_stale__default_function, "buffer-stale--default-function"); Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt); } commit 227f3842c29f1991388ce518645baac412cf1f56 Author: Po Lu Date: Tue Jul 12 20:02:51 2022 +0800 Reduce syncing when fetching selection names during frame deletion * src/xterm.c (x_preserve_selections): Use XCB to asynchronously fetch the selection owner. diff --git a/src/xterm.c b/src/xterm.c index a13162d61b..6e3a941719 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -27964,6 +27964,11 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost) Atom *names; ptrdiff_t nowners, counter; struct selection_input_event clear; +#ifdef USE_XCB + xcb_get_selection_owner_cookie_t *cookies; + xcb_generic_error_t *error; + xcb_get_selection_owner_reply_t *reply; +#endif new_owner = Qnil; @@ -28006,6 +28011,9 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost) { owners = alloca (sizeof *owners * nowners); names = alloca (sizeof *names * nowners); +#ifdef USE_XCB + cookies = alloca (sizeof *cookies * nowners); +#endif tail = lost; nowners = 0; @@ -28018,8 +28026,30 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost) /* Now check if we still don't own that selection, which can happen if another program set itself as the owner. */ names[counter++] = symbol_to_x_atom (dpyinfo, XCAR (tem)); + +#ifndef USE_XCB owners[nowners++] = XGetSelectionOwner (dpyinfo->display, names[counter - 1]); +#else + cookies[nowners++] + = xcb_get_selection_owner (dpyinfo->xcb_connection, + names[counter - 1]); + } + + nowners = 0; + + FOR_EACH_TAIL_SAFE (tail) + { + reply = xcb_get_selection_owner_reply (dpyinfo->xcb_connection, + cookies[nowners++], &error); + + if (reply) + owners[nowners - 1] = reply->owner; + else + owners[nowners - 1] = None; + + free (reply ? (void *) reply : (void *) error); +#endif if (owners[nowners - 1] != FRAME_X_WINDOW (XFRAME (new_owner))) { commit a3dab1e62132bb82ba943b1e7db0ef86f0c93d28 (refs/remotes/origin/emacs-28) Author: Stefan Kangas Date: Tue Jul 12 13:41:28 2022 +0200 Don't mention cl-cXXXr aliases in cl-lib manual * doc/misc/cl.texi (Lists, List Functions, Efficiency Concerns): Don't mention 'cl-cXXXr' compatibility aliases for built-in 'cXXXr' functions. They shouldn't be used in new code. diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi index 9bace48df4..4eb3d85d2b 100644 --- a/doc/misc/cl.texi +++ b/doc/misc/cl.texi @@ -3668,7 +3668,7 @@ a merged sequence which is (stably) sorted according to The functions described here operate on lists. @menu -* List Functions:: @code{cl-caddr}, @code{cl-first}, @code{cl-list*}, etc. +* List Functions:: @code{cl-first}, @code{cl-list*}, etc. * Substitution of Expressions:: @code{cl-subst}, @code{cl-sublis}, etc. * Lists as Sets:: @code{cl-member}, @code{cl-adjoin}, @code{cl-union}, etc. * Association Lists:: @code{cl-assoc}, @code{cl-acons}, @code{cl-pairlis}, etc. @@ -3681,14 +3681,6 @@ The functions described here operate on lists. This section describes a number of simple operations on lists, i.e., chains of cons cells. -@defun cl-caddr x -This function is equivalent to @code{(car (cdr (cdr @var{x})))}. -Likewise, this package aliases all 24 @code{c@var{xxx}r} functions -where @var{xxx} is up to four @samp{a}s and/or @samp{d}s. -All of these functions are @code{setf}-able, and calls to them -are expanded inline by the byte-compiler for maximum efficiency. -@end defun - @defun cl-first x This function is a synonym for @code{(car @var{x})}. Likewise, the functions @code{cl-second}, @code{cl-third}, @dots{}, through @@ -4465,8 +4457,8 @@ For example, @end example @end ignore -Note that @code{cl-adjoin}, @code{cl-caddr}, and @code{cl-member} all -have built-in compiler macros to optimize them in common cases. +Note that @code{cl-adjoin} and @code{cl-member} have built-in compiler +macros to optimize them in common cases. @end defun @appendixsec Error Checking commit 10646eecf15ada08b52ff1e9878e1451ceb1fc60 Author: Stefan Kangas Date: Tue Jul 12 13:29:32 2022 +0200 Make some rst.el compat aliases obsolete * lisp/textmodes/rst.el (rst-adjust-section-title) (rst-display-adornments-hierarchy, rst-straighten-adornments) (rst-toc-insert-update, rst-goto-section) (rst-toc-mode-goto-section, rst-toc-mode-mouse-goto) (rst-toc-mode-mouse-goto-kill, rst-toc-quit-window): Make compatibility aliases obsolete. diff --git a/lisp/textmodes/rst.el b/lisp/textmodes/rst.el index 10313e9939..c0d4dc68af 100644 --- a/lisp/textmodes/rst.el +++ b/lisp/textmodes/rst.el @@ -2153,8 +2153,8 @@ around the cursor. Then the following cases are distinguished. (end-of-line)) nil))))) -;; Maintain an alias for compatibility. -(defalias 'rst-adjust-section-title 'rst-adjust) +(define-obsolete-function-alias 'rst-adjust-section-title + #'rst-adjust "29.1") (defun rst-adjust-region (demote) ;; testcover: ok. @@ -2205,8 +2205,8 @@ Hierarchy is displayed in a temporary buffer." (insert "\n") (cl-incf level)))))) -;; Maintain an alias for backward compatibility. -(defalias 'rst-display-adornments-hierarchy 'rst-display-hdr-hierarchy) +(define-obsolete-function-alias 'rst-display-adornments-hierarchy + #'rst-display-hdr-hierarchy "29.1") ;; FIXME: Should accept an argument giving the hierarchy level to start with ;; instead of the top of the hierarchy. @@ -2231,8 +2231,8 @@ in order to adapt it to our preferred style." (goto-char marker) nil) (rst-update-section (nth level (rst-Hdr-preferred-adornments)))))) -;; Maintain an alias for compatibility. -(defalias 'rst-straighten-adornments 'rst-straighten-sections) +(define-obsolete-function-alias 'rst-straighten-adornments + #'rst-straighten-sections "29.1") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -2858,8 +2858,8 @@ file-write hook to always make it up-to-date automatically." ;; ;; Disable undo for the write file hook. ;; (let ((buffer-undo-list t)) (rst-toc-update) )) -;; Maintain an alias for compatibility. -(defalias 'rst-toc-insert-update 'rst-toc-update) +(define-obsolete-function-alias 'rst-toc-insert-update + #'rst-toc-update "29.1") (defconst rst-toc-buffer-name "*Table of Contents*" "Name of the Table of Contents buffer.") @@ -2893,8 +2893,8 @@ selecting a section title moves the cursor to that section." (setq rst-toc-mode-return-wincfg wincfg) (goto-char (or target-pos (point-min))))) -;; Maintain an alias for compatibility. -(defalias 'rst-goto-section 'rst-toc-follow-link) +(define-obsolete-function-alias 'rst-goto-section + #'rst-toc-follow-link "29.1") (defun rst-toc-follow-link (link-buf link-pnt kill) ;; testcover: ok. @@ -2919,8 +2919,8 @@ error if there is no working link at the given position." ;; the adornment is always completely visible. (recenter 5))) -;; Maintain an alias for compatibility. -(defalias 'rst-toc-mode-goto-section 'rst-toc-mode-follow-link-kill) +(define-obsolete-function-alias 'rst-toc-mode-goto-section + #'rst-toc-mode-follow-link-kill "29.1") ;; FIXME: Cursor before or behind the list must be handled properly; before the ;; list should jump to the top and behind the list to the last normal @@ -2931,8 +2931,8 @@ error if there is no working link at the given position." (interactive) (rst-toc-follow-link (current-buffer) (point) t)) -;; Maintain an alias for compatibility. -(defalias 'rst-toc-mode-mouse-goto 'rst-toc-mouse-follow-link) +(define-obsolete-function-alias 'rst-toc-mode-mouse-goto + #'rst-toc-mouse-follow-link "29.1") (defun rst-toc-mouse-follow-link (event kill) ;; testcover: uncovered. @@ -2942,8 +2942,8 @@ EVENT is the input event. Kill TOC buffer if KILL." (rst-toc-follow-link (window-buffer (posn-window (event-end event))) (posn-point (event-end event)) kill)) -;; Maintain an alias for compatibility. -(defalias 'rst-toc-mode-mouse-goto-kill 'rst-toc-mode-mouse-follow-link-kill) +(define-obsolete-function-alias 'rst-toc-mode-mouse-goto-kill + #'rst-toc-mode-mouse-follow-link-kill "29.1") (defun rst-toc-mode-mouse-follow-link-kill (event) ;; testcover: uncovered. @@ -2952,8 +2952,8 @@ EVENT is the input event." (interactive "e") (rst-toc-mouse-follow-link event t)) -;; Maintain an alias for compatibility. -(defalias 'rst-toc-quit-window 'rst-toc-mode-return) +(define-obsolete-function-alias 'rst-toc-quit-window + #'rst-toc-mode-return "29.1") (defun rst-toc-mode-return (kill) ;; testcover: ok. commit f83d7cc312b5e8c82052b484998fa26d4af35b36 Author: Stefan Kangas Date: Tue Jul 12 12:11:43 2022 +0200 Make remote-shell-program default to ssh only * lisp/files.el (remote-shell-program): Default to "ssh" only. The other commands in this list have severe security issues, and it is easy enough for users to customize them manually if they want to. See also the discussion in: https://debbugs.gnu.org/56461 diff --git a/lisp/files.el b/lisp/files.el index b99ccf66d8..bdceaefb0f 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -1274,20 +1274,9 @@ Tip: You can use this expansion of remote identifier components ;; It's not clear what the best file for this to be in is, but given ;; it uses custom-initialize-delay, it is easier if it is preloaded ;; rather than autoloaded. -(defcustom remote-shell-program - ;; This used to try various hard-coded places for remsh, rsh, and - ;; rcmd, trying to guess based on location whether "rsh" was - ;; "restricted shell" or "remote shell", but I don't see the point - ;; in this day and age. Almost everyone will use ssh, and have - ;; whatever command they want to use in PATH. - (purecopy - (let ((list '("ssh" "remsh" "rcmd" "rsh"))) - (while (and list - (not (executable-find (car list))) - (setq list (cdr list)))) - (or (car list) "ssh"))) - "Program to use to execute commands on a remote host (e.g. ssh or rsh)." - :version "24.3" ; ssh rather than rsh, etc +(defcustom remote-shell-program (or (executable-find "ssh") "ssh") + "Program to use to execute commands on a remote host (i.e. ssh)." + :version "29.1" :initialize 'custom-initialize-delay :group 'environment :type 'file) commit 2dc3e003413f10ebc8caf99f1cf54fca97d734cb Author: Stefan Kangas Date: Tue Jul 12 12:02:51 2022 +0200 Recognize gemini in thing-at-point * lisp/thingatpt.el (thing-at-point-uri-schemes): Recognize gemini. diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el index b3dca5890f..a7c86fb24f 100644 --- a/lisp/thingatpt.el +++ b/lisp/thingatpt.el @@ -391,6 +391,8 @@ If nil, construct the regexp from `thing-at-point-uri-schemes'.") "telnet://" "tftp://" "tip://" "tn3270://" "udp://" "urn:" "uuid:" "vemmi://" "webcal://" "xri://" "xmlrpc.beep://" "xmlrpc.beeps://" "z39.50r://" "z39.50s://" "xmpp:" + ;; Unofficial + "gemini://" ;; Compatibility "fax:" "man:" "mms://" "mmsh://" "modem:" "prospero:" "snews:" "wais://") commit cae4dcc073de015de4ccfaf65c5051709aadf3bc Author: Stefan Kangas Date: Tue Jul 12 05:55:07 2022 +0200 ; * lisp/completion.el: Remove code commented out since 1990. diff --git a/lisp/completion.el b/lisp/completion.el index fb700954b0..2e486b6a50 100644 --- a/lisp/completion.el +++ b/lisp/completion.el @@ -926,10 +926,6 @@ Each symbol is bound to a single completion entry.") "Return a completion entry." (list string 0 nil current-completion-source)) -;; Obsolete -;;(defmacro cmpl-prefix-entry-symbol (completion-entry) -;; (list 'car (list 'cdr completion-entry))) - ;;----------------------------------------------- commit f209650e41d59356a90b5a602abc60c6783bc7b1 Author: Mattias EngdegÄrd Date: Tue Jul 12 11:08:05 2022 +0200 Better gomoku X colour with bright background * lisp/play/gomoku.el (gomoku-X): Use blue rather than green for crosses on bright background for better legibility. (Red for naughts could be adjusted but seems just about bearable.) diff --git a/lisp/play/gomoku.el b/lisp/play/gomoku.el index f8822c30db..fee242be98 100644 --- a/lisp/play/gomoku.el +++ b/lisp/play/gomoku.el @@ -161,11 +161,12 @@ SHOULD be at least 2 (MUST BE at least 1).") "For making font-lock use the winner's face for the line.") (defface gomoku-O - '((((class color)) (:foreground "red" :weight bold))) + '((((class color)) :foreground "red" :weight bold)) "Face to use for Emacs's O.") (defface gomoku-X - '((((class color)) (:foreground "green" :weight bold))) + '((((background light)) :foreground "blue" :weight bold) + (((class color)) :foreground "green" :weight bold)) "Face to use for your X.") (defvar gomoku-font-lock-keywords commit fe5e789ff84d3b41b2a22cc18fd0a208502fede5 Author: Alan Mackenzie Date: Tue Jul 12 09:31:08 2022 +0000 Expunge unused recompute-lucid-menubar, lucid-menu-bar-dirty-flag This fixes bug #56502. That function and these variables were manipulated by the former file emacs-lisp/lmenu.el that was finally expunged from directory obsolete/ by Stefan Kangas on 2020-05-15. There remain references to them in the *.c, and *.m files. * src/keyboard.c (syms_of_keyboard): Remove declarations of the symbol and variable. * src/haikumenu.c (set_frame_menu_bar) * src/keyboard.c (command_loop_1) * src/nsmenu.m (ns_update_menubar) * src/pgtkmenu.c (set_frame_menubar) * src/xdisp.c (update_menu_bar) * src/xmenu.c (set_frame_menubar): Remove calls to Qrecompute_lucid_menubar contitional on Vlucid_menu_bar_dirty_flag. diff --git a/src/haikumenu.c b/src/haikumenu.c index 3f68eadfd9..929ed95210 100644 --- a/src/haikumenu.c +++ b/src/haikumenu.c @@ -629,8 +629,6 @@ set_frame_menubar (struct frame *f, bool deep_p) /* If it has changed current-menubar from previous value, really recompute the menubar from the value. */ - if (! NILP (Vlucid_menu_bar_dirty_flag)) - call0 (Qrecompute_lucid_menubar); safe_run_hooks (Qmenu_bar_update_hook); fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f))); diff --git a/src/keyboard.c b/src/keyboard.c index 1d505c13be..c729d5dfb3 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1371,12 +1371,6 @@ command_loop_1 (void) } } - /* If it has changed current-menubar from previous value, - really recompute the menubar from the value. */ - if (! NILP (Vlucid_menu_bar_dirty_flag) - && !NILP (Ffboundp (Qrecompute_lucid_menubar))) - call0 (Qrecompute_lucid_menubar); - Vthis_command = Qnil; Vreal_this_command = Qnil; Vthis_original_command = Qnil; @@ -12184,7 +12178,6 @@ syms_of_keyboard (void) apply_modifiers. */ DEFSYM (Qmodifier_cache, "modifier-cache"); - DEFSYM (Qrecompute_lucid_menubar, "recompute-lucid-menubar"); DEFSYM (Qactivate_menubar_hook, "activate-menubar-hook"); DEFSYM (Qpolling_period, "polling-period"); @@ -12665,10 +12658,6 @@ See also `pre-command-hook'. */); Fset (Qecho_area_clear_hook, Qnil); - DEFVAR_LISP ("lucid-menu-bar-dirty-flag", Vlucid_menu_bar_dirty_flag, - doc: /* Non-nil means menu bar, specified Lucid style, needs to be recomputed. */); - Vlucid_menu_bar_dirty_flag = Qnil; - #ifdef USE_LUCID DEFVAR_BOOL ("lucid--menu-grab-keyboard", lucid__menu_grab_keyboard, diff --git a/src/nsmenu.m b/src/nsmenu.m index d02d7bae4b..ae795a0d22 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -207,8 +207,6 @@ /* If it has changed current-menubar from previous value, really recompute the menubar from the value. */ - if (! NILP (Vlucid_menu_bar_dirty_flag)) - call0 (Qrecompute_lucid_menubar); safe_run_hooks (Qmenu_bar_update_hook); fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f))); diff --git a/src/pgtkmenu.c b/src/pgtkmenu.c index 2eabf6ac1b..d147f4b416 100644 --- a/src/pgtkmenu.c +++ b/src/pgtkmenu.c @@ -289,8 +289,6 @@ set_frame_menubar (struct frame *f, bool deep_p) /* If it has changed current-menubar from previous value, really recompute the menubar from the value. */ - if (!NILP (Vlucid_menu_bar_dirty_flag)) - call0 (Qrecompute_lucid_menubar); safe_run_hooks (Qmenu_bar_update_hook); fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f))); diff --git a/src/xdisp.c b/src/xdisp.c index 4089525e10..f205327cc3 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -13468,9 +13468,6 @@ update_menu_bar (struct frame *f, bool save_match_data, bool hooks_run) /* If it has changed current-menubar from previous value, really recompute the menu-bar from the value. */ - if (! NILP (Vlucid_menu_bar_dirty_flag)) - call0 (Qrecompute_lucid_menubar); - safe_run_hooks (Qmenu_bar_update_hook); hooks_run = true; diff --git a/src/xmenu.c b/src/xmenu.c index c006d2bfe2..e5e24b87d1 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -976,8 +976,6 @@ set_frame_menubar (struct frame *f, bool deep_p) /* If it has changed current-menubar from previous value, really recompute the menubar from the value. */ - if (! NILP (Vlucid_menu_bar_dirty_flag)) - call0 (Qrecompute_lucid_menubar); safe_run_hooks (Qmenu_bar_update_hook); fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f))); commit 93b31707e97f8ddf11aa8acbf5c61bc29b5f7528 Author: Po Lu Date: Tue Jul 12 15:14:04 2022 +0800 Fix preserving selections if `x-lost-selection-functions' signals * src/xterm.c (x_preserve_selections): Get selection owner and run lost selection hook separately. diff --git a/src/xterm.c b/src/xterm.c index f86e4708ec..a13162d61b 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -27960,7 +27960,10 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost) { Lisp_Object tail, frame, new_owner, tem; Time timestamp; - Window owner; + Window *owners; + Atom *names; + ptrdiff_t nowners, counter; + struct selection_input_event clear; new_owner = Qnil; @@ -27975,10 +27978,12 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost) } tail = lost; + nowners = 0; FOR_EACH_TAIL_SAFE (tail) { tem = XCAR (tail); + ++nowners; /* The selection is really lost (since we cannot find a new owner), so run the appropriate hooks. */ @@ -27994,13 +27999,54 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost) x_own_selection (XCAR (tem), XCAR (XCDR (tem)), new_owner, XCAR (XCDR (XCDR (XCDR (XCDR (tem))))), timestamp); + } + } + + if (!NILP (new_owner)) + { + owners = alloca (sizeof *owners * nowners); + names = alloca (sizeof *names * nowners); + + tail = lost; + nowners = 0; + counter = 0; + + FOR_EACH_TAIL_SAFE (tail) + { + tem = XCAR (tail); /* Now check if we still don't own that selection, which can happen if another program set itself as the owner. */ - owner = XGetSelectionOwner (dpyinfo->display, - symbol_to_x_atom (dpyinfo, XCAR (tem))); + names[counter++] = symbol_to_x_atom (dpyinfo, XCAR (tem)); + owners[nowners++] = XGetSelectionOwner (dpyinfo->display, + names[counter - 1]); + + if (owners[nowners - 1] != FRAME_X_WINDOW (XFRAME (new_owner))) + { + /* Clear the local selection, since we know we don't own + it any longer. */ + CONS_TO_INTEGER (XCAR (XCDR (XCDR (tem))), Time, timestamp); + + clear.kind = SELECTION_CLEAR_EVENT; + + SELECTION_EVENT_DPYINFO (&clear) = dpyinfo; + SELECTION_EVENT_SELECTION (&clear) = names[nowners - 1]; + SELECTION_EVENT_TIME (&clear) = timestamp; + + x_handle_selection_event (&clear); + } + } + + tail = lost; + nowners = 0; + + FOR_EACH_TAIL_SAFE (tail) + { + tem = XCAR (tail); - if (owner != FRAME_X_WINDOW (XFRAME (new_owner))) + /* If the selection isn't owned by us anymore, note that the + selection was lost. */ + if (owners[nowners++] != FRAME_X_WINDOW (XFRAME (new_owner))) CALLN (Frun_hook_with_args, Qx_lost_selection_functions, XCAR (tem)); }