diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi index a0289d1f3cd..66b33316faa 100644 --- a/doc/lispref/searching.texi +++ b/doc/lispref/searching.texi @@ -669,6 +669,10 @@ This matches the hexadecimal digits: @samp{0} through @samp{9}, @samp{a} through @samp{f} and @samp{A} through @samp{F}. @end table +The classes @samp{[:space:]}, @samp{[:word:]} and @samp{[:punct:]} use +the syntax-table of the current buffer but not any overriding syntax +text properties (@pxref{Syntax Properties}). + @node Regexp Backslash @subsubsection Backslash Constructs in Regular Expressions @cindex backslash in regular expressions @@ -1341,6 +1345,9 @@ Match any @acronym{ASCII} character (codes 0--127). Match any non-@acronym{ASCII} character (but not raw bytes). @end table +The classes @code{space}, @code{word} and @code{punct} use the +syntax-table of the current buffer but not any overriding syntax text +properties (@pxref{Syntax Properties}).@* Corresponding string regexp: @samp{[[:@var{class}:]]} @item @code{(syntax @var{syntax})} @@ -1920,7 +1927,8 @@ causing a match to fail early. @item Avoid or-patterns in favor of bracket expressions: write @samp{[ab]} instead of @samp{a\|b}. Recall that @samp{\s-} and @samp{\sw} -are equivalent to @samp{[[:space:]]} and @samp{[[:word:]]}, respectively. +are equivalent to @samp{[[:space:]]} and @samp{[[:word:]]}, respectively, +most of the time. @item Since the last branch of an or-pattern does not add a backtrack point diff --git a/doc/misc/erc.texi b/doc/misc/erc.texi index 2e216629a1d..6d7785a9b54 100644 --- a/doc/misc/erc.texi +++ b/doc/misc/erc.texi @@ -1268,6 +1268,9 @@ settings (@pxref{Sample configuration via Customize}). (erc-server-reconnect-function #'erc-server-delayed-check-reconnect) (erc-server-reconnect-timeout 30) + ;; Show new buffers in the current window instead of a split. + (erc-interactive-display 'buffer) + ;; Insert a newline when I hit at the prompt, and prefer ;; something more deliberate for actually sending messages. :bind (:map erc-mode-map @@ -1391,6 +1394,16 @@ Indeed, you can always get back here by running @kbd{M-x customize-group @key{RET} erc-server @key{RET}} from almost anywhere in Emacs. +To make sure you've got this, try quickly customizing the option +@code{erc-interactive-display}, which lives in the @samp{Erc Buffers} +group (@kbd{M-x customize-group @key{RET} erc-buffers @key{RET}}). As +its doc string explains, the option controls where new buffers show up +when you do @kbd{M-x erc-tls @key{RET}} or issue certain ``slash'' +commands, like @kbd{/JOIN #emacs-beginners @key{RET}}, at ERC's +prompt. Change its value to the symbol @code{buffer} by choosing +@samp{Use current window} (item @kbd{5}) from the option's +@samp{[Value Menu]}. Don't forget to save. + Now it's time to set some key bindings for @code{erc-mode-map}, a major-mode keymap active in all ERC buffers. In general, it's best to do this part either entirely or in conjunction with some lisp code in diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS index a3a8cb086e0..94452514e6d 100644 --- a/etc/ERC-NEWS +++ b/etc/ERC-NEWS @@ -14,29 +14,29 @@ GNU Emacs since Emacs version 22.1. * Changes in ERC 5.6 -** Module 'keep-place' has gained a more flamboyant cousin. -Remember your place in ERC buffers more easily while retaining the -freedom to look around, all with the help of a configurable, visible -indicator. Optionally sync the indicator to any progress made when -you haven't yet caught up to the live stream. See options -'erc-keep-place-indicator-style' and friends, and try M-x +** Module 'keep-place' has a more decorative cousin. +Remember your place in ERC buffers a bit more easily with the help of +a configurable, visible indicator. Optionally sync the indicator to +any progress made while you haven't yet caught up to the live stream. +See options 'erc-keep-place-indicator-style' and friends, and try M-x keep-place-indicator-mode to see it in action. -** Module 'fill' offers a style based on 'visual-line-mode'. -This fill style mimics the "hanging indent" look of 'erc-fill-static' -and provides some movement and editing commands to optionally tame the +** Module 'fill' offers an adaptive style based on 'visual-line-mode'. +This style dynamically wraps messages to a window's width while +mimicking the "hanging indent" look of 'erc-fill-static'. It also +provides some movement and editing commands to optionally tame the less familiar aspects of 'visual-line' behavior. An interactive -helper called 'erc-fill-wrap-nudge' allows for dynamic "refilling" of -buffers on the fly. Set 'erc-fill-function' to 'erc-fill-wrap' to get -started. +helper called 'erc-fill-wrap-nudge' makes easy work of adjusting the +overhang on the fly. Set 'erc-fill-function' to 'erc-fill-wrap' to +get started. ** A module for nickname highlighting has joined ERC. Automatic nickname coloring has come to ERC core. Users familiar with 'erc-hl-nicks', from which this module directly descends, will already be familiar with its suite of handy options. By default, each nickname in an ERC session receives a unique face with a unique (or -evenly dealt) foreground color. Add 'nicks' to 'erc-modules' to get -started. +uniformly dealt) foreground color. Add 'nicks' to 'erc-modules' to +get started. ** A unified interactive entry point. New users are often dismayed to discover that M-x ERC doesn't connect @@ -88,9 +88,9 @@ users to edit the 'erc-modules' widget instead. Users can now add 'bufbar' to 'erc-modules' to achieve the same effect as toggling 'erc-status-sidebar-open' manually at the start of an IRC session. The module has also been outfitted to show channels and -queries under their respective servers by default. To avoid -confusion, the major mode used for the sidebar buffer itself, -'erc-status-sidebar-mode', is no longer available interactively. +queries under their servers by default. To avoid confusion, the major +mode for the actual sidebar buffer itself, 'erc-status-sidebar-mode', +is no longer available interactively. ** A new spin on a classic integration in erc-speedbar. Add 'nickbar' to 'erc-modules' to spawn a dynamically updating side @@ -252,20 +252,19 @@ versions. For starters, the 'cursor-sensor-functions' property no longer contains unique closures and thus no longer proves effective for traversing messages. To compensate, a new property, 'erc-timestamp', -now spans message bodies but not the newlines delimiting them. -Somewhat relatedly, the function 'erc-insert-aligned' has been -deprecated and removed from the primary client code path. -Additionally, the 'stamp' module now merges its 'invisible' property -with existing ones, when present, and it includes all white space -around stamps when doing so. +now spans message bodies but not the newlines delimiting them. Also +affecting the `stamp' module is the deprecation of the function +'erc-insert-aligned' and its removal from client code. Additionally, +the module now merges its 'invisible' property with existing ones and +includes all white space around stamps when doing so. -Moreover, such "propertizing" of surrounding white space now extends -to all 'stamp'-applied properties, like 'field', in all intervening -space between message text and timestamps. This constitutes a +This "propertizing" of surrounding white space also extends to all +'stamp'-applied properties, like 'field', in all intervening space +between message text and timestamps. Technically, this constitutes a breaking change from the perspective of detecting a timestamp's -bounds. For example, ERC has always propertized leading space before +bounds. However, ERC has always propertized leading space before right-sided stamps on the same line as message text but not those -folded onto the next line. This inconsistency made stamp detection +folded onto the next line. Such inconsistency made stamp detection overly complex and produced uneven results when toggling stamp visibility. @@ -317,11 +316,11 @@ third-party code, the key takeaway is that more 'font-lock-face' properties encountered in the wild may be combinations of faces rather than lone ones. -*** Prompt input split before 'erc-pre-send-functions' gets a say. -Hook members are now treated to input whose lines have already been -adjusted to fall within the allowed length limit. For convenience, -third-party code can request that the final input be "re-filled" prior -to being sent. See doc string for details. +*** 'erc-pre-send-functions' visits prompt input post-split. +ERC now adjusts input lines to fall within allowed length limits +before showing hook members the result. For compatibility, +third-party code can request that the final input be adjusted again +prior to being sent. See doc string for details. *** ERC's prompt survives the insertion of user input and messages. Previously, ERC's prompt and its input marker disappeared while @@ -329,18 +328,20 @@ running hooks during message insertion, and the position of its "insert marker" (ERC's per-buffer process mark) was inconsistent during these spells. To make insertion handling more predictable in preparation for incorporating various protocol extensions, the prompt -and its bounding markers have become perennial fixtures. To effect -this change, small behavioral differences in message insertion have -been adopted. Crucially, 'erc-insert-marker' now has an "insertion -type" of t, and 'erc-display-line-1' now calls 'insert' instead of -'insert-before-prompt'. This allows user code to leave its own -markers via 'erc-insert-modify-hook' and 'erc-insert-post-hook' -instead of having to resort to workarounds. Message insertion for -outgoing messages, in 'erc-display-msg', remains as before. In rare -cases, these changes may mean third-party code needs tweaking, for -example, requiring the use of 'insert-before-markers' instead of -'insert'. As always, users feeling unduly inconvenienced by these -changes are encouraged to voice their concerns on the bug list. +and its bounding markers have become perennial fixtures. + +To effect this change, small behavioral differences in message +insertion have been adopted. Crucially, 'erc-insert-marker' now has +an "insertion type" of t, and 'erc-display-line-1' now calls 'insert' +instead of 'insert-before-markers. This allows user code running on +'erc-insert-modify-hook' and 'erc-insert-post-hook' to leave its own +markers at the actual insertion point instead of resorting to +workarounds. Message insertion for outgoing messages, in +'erc-display-msg', remains as before. In rare cases, these changes +may mean third-party code needs tweaking, for example, requiring the +use of 'insert-before-markers' instead of 'insert'. As always, users +feeling unduly inconvenienced by these changes are encouraged to voice +their concerns on the bug list. *** Miscellaneous changes Two helper macros from GNU ELPA's Compat library are now available to diff --git a/lisp/bindings.el b/lisp/bindings.el index dc94c0c4037..c2f593024e2 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -226,9 +226,9 @@ mnemonics of the following coding systems: (put 'mode-line-mule-info 'risky-local-variable t) (defvar mode-line-client - `("" - (:propertize ("" (:eval (if (frame-parameter nil 'client) "@" ""))) - help-echo ,(purecopy "emacsclient frame"))) + `(:eval + (if (frame-parameter nil 'client) + ,(propertize "@" 'help-echo (purecopy "emacsclient frame")))) "Mode line construct for identifying emacsclient frames.") ;; Autoload if this file no longer dumped. ;;;###autoload diff --git a/lisp/doc-view.el b/lisp/doc-view.el index b7f7a862af8..c7edbd6e150 100644 --- a/lisp/doc-view.el +++ b/lisp/doc-view.el @@ -176,7 +176,7 @@ are available (see Info node `(emacs)Document View')." ;; non-MikTeX apps. Was available under: ;; http://blog.miktex.org/post/2005/04/07/Starting-mgsexe-at-the-DOS-Prompt.aspx ((and (executable-find "mgs") - (= 0 (shell-command "mgs -q -dNODISPLAY -c quit"))) + (eql 0 (shell-command "mgs -q -dNODISPLAY -c quit"))) "mgs"))) (t "gs")) "Program to convert PS and PDF files to PNG." @@ -216,7 +216,7 @@ are available (see Info node `(emacs)Document View')." :type 'boolean :version "30.1") -(defcustom doc-view-imenu-enabled (executable-find "mutool") +(defcustom doc-view-imenu-enabled (and (executable-find "mutool") t) "Whether to generate an imenu outline when \"mutool\" is available." :type 'boolean :version "29.1") @@ -577,8 +577,8 @@ Typically \"page-%s.png\".") ;; file. (TODO: We'd like to have something like that also ;; for other types, at least PS, but I don't know a good way ;; to test if a PS file is complete.) - (if (= 0 (call-process "pdfinfo" nil nil nil - doc-view--buffer-file-name)) + (if (eql 0 (call-process "pdfinfo" nil nil nil + doc-view--buffer-file-name)) (revert) (when (called-interactively-p 'interactive) (message "Can't revert right now because the file is corrupted."))) @@ -1962,7 +1962,7 @@ structure is extracted by `doc-view--imenu-subtree'." (let ((outline nil) (fn (expand-file-name fn))) (with-temp-buffer - (unless (= 0 (call-process "mutool" nil (current-buffer) nil "show" fn "outline")) + (unless (eql 0 (call-process "mutool" nil (current-buffer) nil "show" fn "outline")) (imenu-unavailable-error "Unable to create imenu index using `mutool'")) (goto-char (point-min)) (while (re-search-forward doc-view--outline-rx nil t) diff --git a/lisp/erc/erc-fill.el b/lisp/erc/erc-fill.el index 17eb0002f08..e2a82582a3f 100644 --- a/lisp/erc/erc-fill.el +++ b/lisp/erc/erc-fill.el @@ -443,12 +443,13 @@ parties.") (cons (get-text-property m 'erc-timestamp) (get-text-property spr 'erc-speaker))))) (ts (pop props)) + (props) ((not (time-less-p (erc-stamp--current-time) ts))) ((time-less-p (time-subtract (erc-stamp--current-time) ts) erc-fill--wrap-max-lull)) (speaker (next-single-property-change (point-min) 'erc-speaker)) + ((not (eq (get-text-property speaker 'erc-ctcp) 'ACTION))) (nick (get-text-property speaker 'erc-speaker)) - (props) ((erc-nick-equal-p props nick)))) (set-marker erc-fill--wrap-last-msg (point-min)))) diff --git a/lisp/erc/erc-status-sidebar.el b/lisp/erc/erc-status-sidebar.el index b8bd7b0065e..cf3d20aeffa 100644 --- a/lisp/erc/erc-status-sidebar.el +++ b/lisp/erc/erc-status-sidebar.el @@ -45,8 +45,8 @@ ;; Use M-x erc-status-sidebar-kill RET to kill the sidebar buffer and ;; close the sidebar on all frames. -;; In addition to the commands above, you can also try the all-in-one, -;; "DWIM" command, `erc-bufbar-mode'. See its doc string for usage. +;; In addition to the commands above, you can also try the all-in-one +;; entry point `erc-bufbar-mode'. See its doc string for usage. ;; If you want the status sidebar enabled whenever you use ERC, add ;; `bufbar' to `erc-modules'. Note that this library also has a major @@ -130,8 +130,11 @@ buffers, using the functions `erc-status-sidebar-pad-hierarchy' for the above-mentioned purposes. ERC also accepts a list of -functions to preform these roles a la carte. See doc strings for -a description of their expected arguments and return values." +functions to preform these roles a la carte. Since the members +of the above sets aren't really interoperable, we don't offer +them here as customization choices, but you can still specify +them manually. See doc strings for a description of their +expected arguments and return values." :package-version '(ERC . "5.6") ; FIXME sync on release :type '(choice (const channels-only) (const all-mixed) @@ -158,10 +161,12 @@ ACTION parameter." :key-type symbol :value-type (sexp :tag "Value"))))) -(defcustom erc-status-sidebar-singular t - "Whether to show the sidebar on all frames or just one (default)." - :package-version '(ERC . "5.6") ; FIXME sync on release - :type 'boolean) +(defvar erc-status-sidebar--singular-p t + "Whether to restrict the sidebar to a single frame. +This variable only affects `erc-bufbar-mode'. Disabling it does +not arrange for automatically showing the sidebar in all frames. +Rather, disabling it allows for displaying the sidebar in the +selected frame even if it's already showing in some other frame.") (defvar hl-line-mode) (declare-function hl-line-highlight "hl-line" nil) @@ -178,7 +183,7 @@ ACTION parameter." If NO-CREATION is non-nil, the window is not created." (let ((sidebar-window (get-buffer-window erc-status-sidebar-buffer-name - erc-status-sidebar-singular))) + erc-status-sidebar--singular-p))) (unless (or sidebar-window no-creation) (with-current-buffer (erc-status-sidebar-get-buffer) (setq-local vertical-scroll-bar nil)) @@ -214,7 +219,7 @@ The erc-status-sidebar buffer is left alone, but the window containing it on the current frame is closed. See `erc-status-sidebar-kill'." (interactive "P") - (mapcar #'delete-window + (mapcar #'delete-window ; FIXME use `mapc'. (get-buffer-window-list (erc-status-sidebar-get-buffer) nil (if all-frames t)))) @@ -223,10 +228,8 @@ containing it on the current frame is closed. See `(let ((buffer-read-only nil)) ,@body)) -;;;###autoload -(defun erc-status-sidebar-open () - "Open or create a sidebar." - (interactive) +(defun erc-status-sidebar--open () + "Maybe open the sidebar, respecting `erc-status-sidebar--singular-p'." (save-excursion (if (erc-status-sidebar-buffer-exists-p) (erc-status-sidebar-get-window) @@ -237,11 +240,15 @@ containing it on the current frame is closed. See ;;;###autoload(autoload 'erc-bufbar-mode "erc-status-sidebar" nil t) (define-erc-module bufbar nil "Show `erc-track'-like activity in a side window. -When enabling, show the sidebar immediately if called from a -connected ERC buffer. Otherwise, arrange for doing so on connect -or whenever next displaying a new ERC buffer. When disabling, -hide the status window if it's showing. With a negative prefix -arg, also shutdown the session." +When enabling, show the sidebar immediately in the current frame +if called from a connected ERC buffer. Otherwise, arrange for +doing so on connect or whenever next displaying a new ERC buffer. +When disabling, hide the status window in all frames. With a +negative prefix arg, also shutdown the session. Normally, this +module only allows one sidebar window in an Emacs session. To +override this, use `erc-status-sidebar-open' to force creation +and `erc-status-sidebar-close' to hide a single instance on the +current frame only." ((unless erc-track-mode (unless (memq 'track erc-modules) (erc--warn-once-before-connect 'erc-bufbar-mode @@ -249,30 +256,38 @@ arg, also shutdown the session." " This will affect \C-]all\C-] ERC sessions." " Add `track' to `erc-modules' to silence this message.")) (erc-track-mode +1)) - (add-hook 'erc--setup-buffer-hook #'erc-status-sidebar-open) + (add-hook 'erc--setup-buffer-hook #'erc-status-sidebar--open) (unless erc--updating-modules-p (if (erc-with-server-buffer erc-server-connected) - (erc-status-sidebar-open) - (setq erc-bufbar-mode nil) + (erc-status-sidebar--open) (when (derived-mode-p 'erc-mode) (erc-error "Not initializing `erc-bufbar-mode' in %s" (current-buffer)))))) - ((remove-hook 'erc--setup-buffer-hook #'erc-status-sidebar-open) - (erc-status-sidebar-close erc-status-sidebar-singular) + ((remove-hook 'erc--setup-buffer-hook #'erc-status-sidebar--open) + (erc-status-sidebar-close 'all-frames) (when-let ((arg erc--module-toggle-prefix-arg) ((numberp arg)) ((< arg 0))) (erc-status-sidebar-kill)))) +;;;###autoload +(defun erc-status-sidebar-open () + "Open or create a sidebar window in the current frame. +When `erc-bufbar-mode' is active, do this even if one already +exists in another frame." + (interactive) + (let ((erc-status-sidebar--singular-p (not erc-bufbar-mode))) + (erc-status-sidebar--open))) + ;;;###autoload (defun erc-status-sidebar-toggle () "Toggle the sidebar open/closed on the current frame. -Do this regardless of `erc-status-sidebar-singular'." +When opening, and `erc-bufbar-mode' is active, create a sidebar +even if one already exists in another frame." (interactive) (if (get-buffer-window erc-status-sidebar-buffer-name nil) (erc-status-sidebar-close) - (let (erc-status-sidebar-singular) - (erc-status-sidebar-open)))) + (erc-status-sidebar-open))) (defun erc-status-sidebar-get-channame (buffer) "Return name of BUFFER with all leading \"#\" characters removed." @@ -413,11 +428,10 @@ name stand out." erc-status-sidebar-pad-hierarchy)) (v v))) (chanlist (apply sort-fn (funcall list-fn nil) nil)) - (window nil) - (winstart nil)) + (windows nil)) (with-current-buffer (erc-status-sidebar-get-buffer) - (setq window (get-buffer-window nil erc-status-sidebar-singular) - winstart (and window (window-start window))) + (dolist (window (get-buffer-window-list nil nil t)) + (push (cons window (window-start window)) windows)) (erc-status-sidebar-writable (delete-region (point-min) (point-max)) (goto-char (point-min)) @@ -443,9 +457,8 @@ name stand out." 0 cnlen 'help-echo "mouse-1: switch to buffer in other window" channame) (funcall insert-fn channame chanbuf chanlist))) - (when winstart - (set-window-point window winstart) - (with-selected-window window (recenter 0))) + (when windows + (map-apply #'set-window-start windows)) (when (and erc-status-sidebar-highlight-active-buffer (marker-buffer erc-status-sidebar--active-marker)) (goto-char erc-status-sidebar--active-marker) @@ -519,14 +532,28 @@ highlighted." erc-kill-server-hook erc-kick-hook erc-disconnected-hook - erc-quit-hook)) + erc-quit-hook) + "Hooks to refresh the sidebar on. +This may be set locally in the status-sidebar buffer under +various conditions, like when the option +`erc-status-sidebar-highlight-active-buffer' is non-nil.") + +(defvar erc-status-sidebar--highlight-refresh-triggers + '(window-selection-change-functions) + "Triggers enabled with `erc-status-sidebar-highlight-active-buffer'.") + +(defun erc-status-sidebar--refresh-unless-input () + "Run `erc-status-sidebar-refresh' unless there are unread commands. +Also abstain when the user is interacting with the minibuffer." + (unless (or (input-pending-p) (minibuffer-window-active-p (selected-window))) + (erc-status-sidebar-refresh))) (defun erc-status-sidebar--post-refresh (&rest _ignore) "Schedule sidebar refresh for execution after command stack is cleared. Ignore arguments in IGNORE, allowing this function to be added to hooks that invoke it with arguments." - (run-at-time 0 nil #'erc-status-sidebar-refresh)) + (run-at-time 0 nil #'erc-status-sidebar--refresh-unless-input)) (defun erc-status-sidebar-mode--unhook () "Remove hooks installed by `erc-status-sidebar-mode'." @@ -541,7 +568,7 @@ hooks that invoke it with arguments." Note that preserve status needs to be reset when the window is manually resized, so `erc-status-sidebar-mode' adds this function to the `window-configuration-change-hook'." - (when (and (eq (selected-window) (let (erc-status-sidebar-singular) + (when (and (eq (selected-window) (let (erc-status-sidebar--singular-p) (erc-status-sidebar-get-window))) (fboundp 'window-preserve-size)) (unless (eq (window-total-width) (window-min-size nil t)) @@ -563,6 +590,10 @@ to the `window-configuration-change-hook'." (add-hook 'window-configuration-change-hook #'erc-status-sidebar-set-window-preserve-size nil t) + (when erc-status-sidebar-highlight-active-buffer + (setq-local erc-status-sidebar-refresh-triggers + `(,@erc-status-sidebar--highlight-refresh-triggers + ,@erc-status-sidebar-refresh-triggers))) (dolist (hk erc-status-sidebar-refresh-triggers) (add-hook hk #'erc-status-sidebar--post-refresh)) diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el index e4ea95343e0..2b6329fecc3 100644 --- a/lisp/tar-mode.el +++ b/lisp/tar-mode.el @@ -255,15 +255,14 @@ Only attributes that `tar-mode' can grok are mentioned.") (decode-coding-string str coding) str)) -(defvar tar-attr-vector '[nil nil nil nil nil nil nil nil]) +(defvar tar-attr-vector (make-vector 8 nil)) (defun tar-parse-pax-extended-header (pos) "Parse a pax external header of a Posix-format tar file." (let ((end (+ pos 512)) (result tar-attr-vector) (coding 'utf-8-unix) attr value record-len value-len) - (dotimes (i 8) - (aset result i nil)) + (fillarray result nil) (goto-char pos) (while (and (< pos end) (re-search-forward pax-extended-attribute-record-regexp diff --git a/lisp/userlock.el b/lisp/userlock.el index 96de17d54fd..4623608f1db 100644 --- a/lisp/userlock.el +++ b/lisp/userlock.el @@ -141,8 +141,10 @@ You can <\\`q'>uit; don't modify this file.")) ;; modtime in that buffer, to cater to use case where the ;; file is about to be written to from some buffer that ;; doesn't visit any file, like a temporary buffer. - (with-current-buffer (get-file-buffer (file-truename filename)) - (set-visited-file-modtime)) + (let ((buf (get-file-buffer (file-truename filename)))) + (when buf ; If we cannot find the visiting buffer, punt. + (with-current-buffer buf + (set-visited-file-modtime)))) 'unchanged))))) ;;;###autoload diff --git a/test/lisp/erc/erc-fill-tests.el b/test/lisp/erc/erc-fill-tests.el index 67622da9f3d..b81d0c15558 100644 --- a/test/lisp/erc/erc-fill-tests.el +++ b/test/lisp/erc/erc-fill-tests.el @@ -241,6 +241,46 @@ " " " " " " " " " " " " " ") (erc-fill-tests--compare "merge-02-right"))))) +(ert-deftest erc-fill-wrap--merge-action () + :tags '(:unstable) + (unless (>= emacs-major-version 29) + (ert-skip "Emacs version too low, missing `buffer-text-pixel-size'")) + + (erc-fill-tests--wrap-populate + + (lambda () + ;; Set this here so that the first few messages are from 1970 + (let ((erc-fill-tests--time-vals (lambda () 1680332400))) + (erc-fill-tests--insert-privmsg "bob" "zero.") + + (erc-process-ctcp-query + erc-server-process + (make-erc-response + :unparsed ":bob!~u@fake PRIVMSG #chan :\1ACTION one\1" + :sender "bob!~u@fake" :command "PRIVMSG" + :command-args '("#chan" "\1ACTION one\1") :contents "\1ACTION one\1") + "bob" "~u" "fake") + + (erc-fill-tests--insert-privmsg "bob" "two.") + + ;; Compat switch to opt out of overhanging speaker. + (let (erc-fill--wrap-action-dedent-p) + (erc-process-ctcp-query + erc-server-process + (make-erc-response + :unparsed ":bob!~u@fake PRIVMSG #chan :\1ACTION three\1" + :sender "bob!~u@fake" :command "PRIVMSG" + :command-args '("#chan" "\1ACTION three\1") + :contents "\1ACTION three\1") + "bob" "~u" "fake")) + + (erc-fill-tests--insert-privmsg "bob" "four.")) + + (should (= erc-fill--wrap-value 27)) + (erc-fill-tests--wrap-check-prefixes + "*** " " " " " " " "* bob " " " "* " " ") + (erc-fill-tests--compare "merge-wrap-01")))) + (ert-deftest erc-fill-line-spacing () :tags '(:unstable) (unless (>= emacs-major-version 29) diff --git a/test/lisp/erc/resources/fill/snapshots/merge-wrap-01.eld b/test/lisp/erc/resources/fill/snapshots/merge-wrap-01.eld new file mode 100644 index 00000000000..a3d533c87b5 --- /dev/null +++ b/test/lisp/erc/resources/fill/snapshots/merge-wrap-01.eld @@ -0,0 +1 @@ +#("\n\n\n[Thu Jan 1 1970]\n*** This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.[00:00]\n bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n\n[Sat Apr 1 2023]\n zero.[07:00]\n* bob one\n two.\n* bob three\n four.\n" 2 20 (erc-timestamp 0 line-prefix (space :width (- 27 (18))) field erc-timestamp) 20 21 (erc-timestamp 0 field erc-timestamp) 21 183 (erc-timestamp 0 wrap-prefix #2=(space :width 27) line-prefix #3=(space :width (- 27 (4)))) 183 190 (erc-timestamp 0 field erc-timestamp wrap-prefix #2# line-prefix #3# display #1=(#7=(margin right-margin) #("[00:00]" 0 7 (display #1# invisible timestamp font-lock-face erc-timestamp-face)))) 191 192 (erc-timestamp 0 wrap-prefix #2# line-prefix #4=(space :width (- 27 (8))) erc-command PRIVMSG) 192 197 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 197 199 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 199 202 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 202 315 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 315 316 (erc-timestamp 0 erc-command PRIVMSG) 316 348 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 349 350 (erc-timestamp 0 wrap-prefix #2# line-prefix #5=(space :width (- 27 (6))) erc-command PRIVMSG) 350 353 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 353 355 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 355 360 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 360 435 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 436 454 (erc-timestamp 1680332400 line-prefix (space :width (- 27 (18))) field erc-timestamp) 454 455 (erc-timestamp 1680332400 field erc-timestamp) 455 456 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #6=(space :width (- 27 (6))) erc-command PRIVMSG) 456 459 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #6# erc-command PRIVMSG) 459 466 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #6# erc-command PRIVMSG) 466 473 (erc-timestamp 1680332400 field erc-timestamp wrap-prefix #2# line-prefix #6# display #8=(#7# #("[07:00]" 0 7 (display #8# invisible timestamp font-lock-face erc-timestamp-face)))) 474 476 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #9=(space :width (- 27 (6))) erc-ctcp ACTION erc-command PRIVMSG) 476 479 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #9# erc-ctcp ACTION erc-command PRIVMSG) 479 483 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #9# erc-ctcp ACTION erc-command PRIVMSG) 484 485 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #10=(space :width (- 27 (6))) erc-command PRIVMSG) 485 488 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #10# erc-command PRIVMSG) 488 494 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #10# erc-command PRIVMSG) 495 497 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #11=(space :width (- 27 (2))) erc-ctcp ACTION erc-command PRIVMSG) 497 500 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #11# erc-ctcp ACTION erc-command PRIVMSG) 500 506 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #11# erc-ctcp ACTION erc-command PRIVMSG) 507 508 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #12=(space :width (- 27 (6))) erc-command PRIVMSG) 508 511 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #12# erc-command PRIVMSG) 511 518 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #12# erc-command PRIVMSG)) \ No newline at end of file diff --git a/test/lisp/image/image-dired-util-tests.el b/test/lisp/image/image-dired-util-tests.el index 1f3747a82b1..273a32d5dbb 100644 --- a/test/lisp/image/image-dired-util-tests.el +++ b/test/lisp/image/image-dired-util-tests.el @@ -57,20 +57,23 @@ "jpg"))))) (ert-deftest image-dired-thumb-name/per-directory () - (let ((image-dired-thumbnail-storage 'per-directory)) - (should (file-name-absolute-p (image-dired-thumb-name "foo.jpg"))) - (should (file-name-absolute-p (image-dired-thumb-name "/tmp/foo.jpg"))) + (let ((image-dired-thumbnail-storage 'per-directory) + (rel-path "foo.jpg") + (abs-path "/tmp/foo.jpg") + (hash-name (concat (sha1 "foo.jpg") ".jpg"))) + (should (file-name-absolute-p (image-dired-thumb-name rel-path))) + (should (file-name-absolute-p (image-dired-thumb-name abs-path))) (should (equal - (file-name-nondirectory (image-dired-thumb-name "foo.jpg")) - (file-name-nondirectory (image-dired-thumb-name "/tmp/foo.jpg")))) + (file-name-nondirectory (image-dired-thumb-name rel-path)) + (file-name-nondirectory (image-dired-thumb-name abs-path)))) ;; The cdr below avoids the system dependency in the car of the ;; list returned by 'file-name-split': it's "" on Posix systems, ;; but the drive letter on MS-Windows. (should (equal (cdr (file-name-split - (image-dired-thumb-name "/tmp/foo.jpg"))) - '("tmp" ".image-dired" "foo.jpg.thumb.jpg"))) + (image-dired-thumb-name abs-path))) + (list "tmp" ".image-dired" hash-name))) (should (equal (file-name-nondirectory - (image-dired-thumb-name "foo.jpg")) - "foo.jpg.thumb.jpg")))) + (image-dired-thumb-name rel-path)) + hash-name)))) ;;; image-dired-util-tests.el ends here diff --git a/test/lisp/uniquify-tests.el b/test/lisp/uniquify-tests.el index e533c4b644c..224991cb048 100644 --- a/test/lisp/uniquify-tests.el +++ b/test/lisp/uniquify-tests.el @@ -22,6 +22,7 @@ ;;; Code: (require 'ert) +(require 'ert-x) (ert-deftest uniquify-basic () (let (bufs old-names) @@ -58,35 +59,35 @@ (ert-deftest uniquify-dirs () "Check strip-common-suffix and trailing-separator-p work together; bug#47132" - (let* ((root (make-temp-file "emacs-uniquify-tests" 'dir)) - (a-path (file-name-concat root "a/x/y/dir")) - (b-path (file-name-concat root "b/x/y/dir"))) - (make-directory a-path 'parents) - (make-directory b-path 'parents) - (let ((uniquify-buffer-name-style 'forward) - (uniquify-strip-common-suffix t) - (uniquify-trailing-separator-p nil)) - (let ((bufs (list (find-file-noselect a-path) - (find-file-noselect b-path)))) - (should (equal (mapcar #'buffer-name bufs) - '("a/dir" "b/dir"))) - (mapc #'kill-buffer bufs))) - (let ((uniquify-buffer-name-style 'forward) - (uniquify-strip-common-suffix nil) - (uniquify-trailing-separator-p t)) - (let ((bufs (list (find-file-noselect a-path) - (find-file-noselect b-path)))) - (should (equal (mapcar #'buffer-name bufs) - '("a/x/y/dir/" "b/x/y/dir/"))) - (mapc #'kill-buffer bufs))) - (let ((uniquify-buffer-name-style 'forward) - (uniquify-strip-common-suffix t) - (uniquify-trailing-separator-p t)) - (let ((bufs (list (find-file-noselect a-path) - (find-file-noselect b-path)))) - (should (equal (mapcar #'buffer-name bufs) - '("a/dir/" "b/dir/"))) - (mapc #'kill-buffer bufs))))) + (ert-with-temp-directory root + (let ((a-path (file-name-concat root "a/x/y/dir")) + (b-path (file-name-concat root "b/x/y/dir"))) + (make-directory a-path 'parents) + (make-directory b-path 'parents) + (let ((uniquify-buffer-name-style 'forward) + (uniquify-strip-common-suffix t) + (uniquify-trailing-separator-p nil)) + (let ((bufs (list (find-file-noselect a-path) + (find-file-noselect b-path)))) + (should (equal (mapcar #'buffer-name bufs) + '("a/dir" "b/dir"))) + (mapc #'kill-buffer bufs))) + (let ((uniquify-buffer-name-style 'forward) + (uniquify-strip-common-suffix nil) + (uniquify-trailing-separator-p t)) + (let ((bufs (list (find-file-noselect a-path) + (find-file-noselect b-path)))) + (should (equal (mapcar #'buffer-name bufs) + '("a/x/y/dir/" "b/x/y/dir/"))) + (mapc #'kill-buffer bufs))) + (let ((uniquify-buffer-name-style 'forward) + (uniquify-strip-common-suffix t) + (uniquify-trailing-separator-p t)) + (let ((bufs (list (find-file-noselect a-path) + (find-file-noselect b-path)))) + (should (equal (mapcar #'buffer-name bufs) + '("a/dir/" "b/dir/"))) + (mapc #'kill-buffer bufs)))))) (ert-deftest uniquify-home () "uniquify works, albeit confusingly, in the presence of directories named \"~\"" @@ -147,16 +148,18 @@ uniquify-trailing-separator-p is ignored" (project-vc-name "foo1/bar") bufs) (save-excursion - (should (file-exists-p "../README")) - (push (find-file-noselect "../README") bufs) - (push (find-file-noselect "other/README") bufs) - (should (equal (mapcar #'buffer-name bufs) - '("README" "README"))) - (push (find-file-noselect "foo2/bar/README") bufs) - (should (equal (mapcar #'buffer-name bufs) - '("README" "README" "README"))) - (while bufs - (kill-buffer (pop bufs)))))) + (let ((default-directory (expand-file-name "test/" source-directory))) + (should (file-exists-p "../README")) + (push (find-file-noselect "../README") bufs) + (push (find-file-noselect "other/README") bufs) + (should (equal (mapcar #'buffer-name bufs) + '("README" "README"))) + (push (find-file-noselect "foo2/bar/README") bufs) + (should (equal (mapcar #'buffer-name bufs) + '("README" "README" + "README"))) + (while bufs + (kill-buffer (pop bufs))))))) (provide 'uniquify-tests) ;;; uniquify-tests.el ends here diff --git a/test/src/filelock-tests.el b/test/src/filelock-tests.el index 1f055cfebc6..c5e77f70bb2 100644 --- a/test/src/filelock-tests.el +++ b/test/src/filelock-tests.el @@ -38,8 +38,12 @@ Create a test directory and a buffer whose `buffer-file-name' and Finally, delete the buffer and the test directory." (declare (debug (body))) `(ert-with-temp-directory temp-dir - (let ((name (concat (file-name-as-directory temp-dir) - "userfile")) + (let ((name + ;; Use file-truename for when 'temporary-file-directory' + ;; is a symlink, to make sure 'buffer-file-name' is set + ;; below to a real existing file. + (file-truename (concat (file-name-as-directory temp-dir) + "userfile"))) (create-lockfiles t)) (with-temp-buffer (setq buffer-file-name name @@ -184,7 +188,8 @@ the case)." ;; Just changing the file modification on disk doesn't hurt, ;; because file contents in buffer and on disk look equal. - (shell-command (format "touch %s" (buffer-file-name))) + (shell-command (format "touch %s" + (shell-quote-argument (buffer-file-name)))) (insert "bar") (when cl (filelock-tests--should-be-locked)) @@ -198,7 +203,8 @@ the case)." ;; Changing the file contents on disk hurts when buffer is ;; modified. There shall be a query, which we answer. ;; *Messages* buffer is checked for prompt. - (shell-command (format "echo bar >>%s" (buffer-file-name))) + (shell-command (format "echo bar >>%s" + (shell-quote-argument (buffer-file-name)))) (cl-letf (((symbol-function 'read-char-choice) (lambda (prompt &rest _) (message "%s" prompt) ?y))) (ert-with-message-capture captured-messages