Merge remote-tracking branch 'origin/master' into feature/android

This commit is contained in:
Po Lu 2023-07-23 08:53:22 +08:00
commit be70caa68f
31 changed files with 753 additions and 230 deletions

View file

@ -2093,10 +2093,11 @@ Otherwise, Emacs uses @command{ssh}.
@end enumerate
@cindex disabling remote files
@cindex inhibit-remote-files
@noindent
You can entirely turn off the remote file name feature by setting the
variable @code{tramp-mode} to @code{nil}. You can turn off the
feature in individual cases by quoting the file name with @samp{/:}
You can entirely turn off the remote file name feature by running
@kbd{M-x inhibit-remote-files}. You can turn off the feature in
individual cases by quoting the file name with @samp{/:}
(@pxref{Quoted File Names}).
@cindex @code{ange-ftp}

View file

@ -2983,6 +2983,17 @@ If @var{whole} is non-@code{nil}, the @var{x} coordinate is relative
to the entire window area including scroll bars, margins and fringes.
@end defun
@defopt mouse-prefer-closest-glyph
If this variable is non-@code{nil}, the @code{posn-point} of a mouse
position list will be set to the position of the glyph whose leftmost
edge is the closest to the mouse click, as opposed to the position of
the glyph underneath the mouse pointer itself. For example, if
@code{posn-at-x-y} is called with @var{x} set to @code{9}, which is
contained within a character of width 10 displayed at column 0, the
point saved within the mouse position list will be @emph{after} that
character, not @emph{before} it.
@end defopt
@node Accessing Scroll
@subsection Accessing Scroll Bar Events
@cindex scroll bar events, data in

View file

@ -3698,6 +3698,17 @@ between consecutive checks. For example:
@end example
@end defopt
@defmac without-remote-files body@dots{}
The @code{without-remote-files} macro evaluates the @var{body} forms
with deactivated file name handlers for remote files. Those file
names would be handled literally.
The macro should be used only in forms where it is obvious, that
remote files cannot appear or where it is intended not to handle
remote file names. It also reduces checks with
@code{file-name-handler-alist}, resulting in more performant code.
@end defmac
@node Format Conversion
@section File Format Conversion

View file

@ -5851,16 +5851,6 @@ If you want to enable Ange FTP's syntax, add the following form:
(tramp-change-syntax 'simplified)
@end lisp
@item
@vindex tramp-mode
To disable both @value{tramp} (and Ange FTP), set @code{tramp-mode} to
@code{nil} in @file{.emacs}. @strong{Note}, that we don't use
@code{customize-set-variable}, in order to avoid loading @value{tramp}.
@lisp
(setq tramp-mode nil)
@end lisp
@item
@vindex tramp-ignored-file-name-regexp
To deactivate @value{tramp} for some look-alike remote file names, set
@ -5877,6 +5867,29 @@ This is needed, if you mount for example a virtual file system on your
local host's root directory as @file{/ssh:example.com:}.
@item
@findex inhibit-remote-files
To disable both @value{tramp} (and Ange FTP), type @kbd{M-x
inhibit-remote-files @key{RET}}. You can also add this to your
@file{.emacs}.
@lisp
(inhibit-remote-files)
@end lisp
@item
@findex without-remote-files
If you write code, which is intended to run only for local files, you
can use the @code{without-remote-files} macro.
@lisp
(without-remote-files @dots{})
@end lisp
This improves performance, because many primitive file name operations
don't check any longer for Tramp file name regexps then.
@item
@findex tramp-unload-tramp
To unload @value{tramp}, type @kbd{M-x tramp-unload-tramp @key{RET}}.
Unloading @value{tramp} resets Ange FTP plugins also.
@end itemize

View file

@ -29,10 +29,9 @@ problem, particularly on Mac OS. See github#1228 and github#1226.
** Fixed "onTypeFormatting" feature
This feature wasn't triggered for the 'newline' command because
language servers often expect 10 (linefeed) to be the trigger
character, but 'newline' emits 13 (carriage return). Also made this
feature less chatty in the mode-line and messages buffer.
For 'newline' commands, Eglot sometimes sent the wrong character code
to the server. Also made this feature less chatty in the mode-line
and messages buffer.
* Changes in Eglot 1.15 (29/4/2023)

View file

@ -103,11 +103,8 @@ side window. Hit '<RET>' over a nick to spawn a "/QUERY" or a
** The option 'erc-timestamp-use-align-to' is more versatile.
While this option has always offered to right-align stamps via the
'display' text property, it's now more effective at doing so when set
to a number indicating an offset from the right edge. And when set to
the symbol 'margin', it displays stamps in the right margin, although,
at the moment, this is mostly intended for use by other modules, such
as 'fill-wrap', described above. For both these variants, users of
the 'log' module may want to customize 'erc-log-filter-function' to
to a number indicating an offset from the right edge. Users of the
'log' module may want to customize 'erc-log-filter-function' to
'erc-stamp-prefix-log-filter' to avoid ragged right-hand stamps
appearing in their saved logs.
@ -228,7 +225,8 @@ Chiefly, 'rear-sticky' has been replaced by 'erc-command', which
records the IRC command (or numeric) associated with a message. Less
impactfully, the value of the 'field' property for ERC's prompt has
changed from 't' to the more useful 'erc-prompt', although the
property of the same name has been retained.
property of the same name has been retained and now has a value of
'hidden' when disconnected.
*** Members of insert- and send-related hooks have been reordered.
Built-in and third-party modules rely on certain hooks for adjusting
@ -261,6 +259,16 @@ 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.
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
breaking change from the perspective of detecting a timestamp's
bounds. For example, 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
overly complex and produced uneven results when toggling stamp
visibility.
*** The role of a module's Custom group is now more clearly defined.
Associating built-in modules with Custom groups and provided library
features has improved. More specifically, a module's group now enjoys
@ -287,6 +295,15 @@ The 'fill' module is now defined by 'define-erc-module'. The same
goes for ERC's imenu integration, which has 'imenu' now appearing in
the default value of 'erc-modules'.
*** Hidden messages contain a preceding rather than trailing newline.
ERC has traditionally only offered to hide messages involving fools,
but plans are to make hiding more powerful. Anyone depending on the
existing behavior should be aware that hidden messages now start and
end one character earlier, so that hidden line endings precede rather
than follow accompanying text. However, an escape hatch is available
in the variable 'erc-legacy-invisible-bounds-p'. It reinstates the
old behavior, which is unsupported by newer modules and features.
*** 'erc-display-message' optionally combines faces.
Users may notice that ERC now inserts some important error messages in
a combination of 'erc-error-face' and 'erc-notice-face'. This is

View file

@ -110,11 +110,12 @@ When this minor mode is enabled, buttons representing modifier keys
are displayed along the tool bar.
** cl-print
*** You can expand the "..." truncation everywhere.
The code that allowed "..." to be expanded in the *Backtrace* should
now work anywhere the data is generated by `cl-print`.
*** hash-tables' contents can be expanded via the ellipsis
*** You can expand the "..." truncation everywhere.
The code that allowed "..." to be expanded in the "*Backtrace*" buffer
should now work anywhere the data is generated by 'cl-print'.
*** hash-tables' contents can be expanded via the ellipsis.
** Modeline elements can now be right-aligned.
Anything following the symbol 'mode-line-format-right-align' in
@ -149,6 +150,17 @@ confirmation.
It controls the placement of point and the region after duplicating a
region with 'duplicate-dwim'.
+++
** New user option 'mouse-prefer-closest-glyph'.
When enabled, clicking or dragging with the mouse will put the point
or start the drag in front of the buffer position corresponding to the
glyph with the closest X coordinate to the click or start of the drag.
In other words, if the mouse pointer is in the right half of a glyph,
point will be put after the buffer position corresponding to that glyph,
whereas if the mouse pointer is in the left half of a glyph, point
will be put in front the buffer position corresponding to that glyph.
By default this is disabled.
* Changes in Specialized Modes and Packages in Emacs 30.1
@ -288,6 +300,8 @@ docstring, or a comment, or (re)indents the surrounding defun if
point is not in a comment or a string. It is by default bound to
'M-q' in 'prog-mode' and all its descendants.
** Which Function Mode
+++
*** Which Function Mode can now display function names on the header line.
The new user option 'which-func-display' allows choosing where the
@ -324,6 +338,19 @@ sessions, respectively.
It allows to kill only selected remote buffers, controlled by user
option 'tramp-cleanup-some-buffers-hook'.
+++
*** New command 'inhibit-remote-files'.
This command disables the handling of file names with the special
remote file name syntax. It should be applied only when remote files
won't be used in this Emacs instance. It provides a slightly improved
performance of file name handling in Emacs.
+++
*** New macro 'without-remote-files'.
This macro could wrap code which handles local files only. Due to the
temporary deactivation of remote files, it results in a slightly
improved performance of file name handling in Emacs.
** EWW
+++
@ -632,7 +659,7 @@ behavior back for any other reason, you can do that using the
'coding-system-put' function. For example, the following restores the
previous behavior of showing 'U' in the mode line for 'koi8-u':
(coding-system-put 'koi8-u :mnemonic ?U)
(coding-system-put 'koi8-u :mnemonic ?U)
+++
** Infinities and NaNs no longer act as symbols on non-IEEE platforms.
@ -641,6 +668,7 @@ tokens like 0.0e+NaN and 1.0e+INF are no longer read as symbols.
Instead, the Lisp reader approximates an infinity with the nearest
finite value, and a NaN with some other non-numeric object that
provokes an error if used numerically.
* Lisp Changes in Emacs 30.1

View file

@ -231,6 +231,7 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of
(inverse-video display boolean)
(visible-bell display boolean)
(no-redraw-on-reenter display boolean)
(mouse-prefer-closest-glyph display boolean)
;; doc.c
(text-quoting-style display

View file

@ -1045,13 +1045,25 @@ Conditionally try to reconnect and take appropriate action."
;; unexpected disconnect
(erc-process-sentinel-2 event buffer))))
(cl-defmethod erc--reveal-prompt ()
(remove-text-properties erc-insert-marker erc-input-marker
'(display nil)))
(cl-defmethod erc--conceal-prompt ()
(add-text-properties erc-insert-marker (1- erc-input-marker)
`(display ,erc-prompt-hidden)))
(defun erc--prompt-hidden-p ()
(and (marker-position erc-insert-marker)
(eq (get-text-property erc-insert-marker 'erc-prompt) 'hidden)))
(defun erc--unhide-prompt ()
(remove-hook 'pre-command-hook #'erc--unhide-prompt-on-self-insert t)
(when (and (marker-position erc-insert-marker)
(marker-position erc-input-marker))
(with-silent-modifications
(remove-text-properties erc-insert-marker erc-input-marker
'(display nil)))))
(put-text-property erc-insert-marker (1- erc-input-marker) 'erc-prompt t)
(erc--reveal-prompt))))
(defun erc--unhide-prompt-on-self-insert ()
(when (and (eq this-command #'self-insert-command)
@ -1059,6 +1071,8 @@ Conditionally try to reconnect and take appropriate action."
(erc--unhide-prompt)))
(defun erc--hide-prompt (proc)
"Hide prompt in all buffers of server.
Change value of property `erc-prompt' from t to `hidden'."
(erc-with-all-buffers-of-server proc nil
(when (and erc-hide-prompt
(or (eq erc-hide-prompt t)
@ -1072,8 +1086,9 @@ Conditionally try to reconnect and take appropriate action."
(marker-position erc-input-marker)
(get-text-property erc-insert-marker 'erc-prompt))
(with-silent-modifications
(add-text-properties erc-insert-marker (1- erc-input-marker)
`(display ,erc-prompt-hidden)))
(put-text-property erc-insert-marker (1- erc-input-marker)
'erc-prompt 'hidden)
(erc--conceal-prompt))
(add-hook 'pre-command-hook #'erc--unhide-prompt-on-self-insert 91 t))))
(defun erc-process-sentinel (cproc event)

View file

@ -418,7 +418,7 @@ If START or END is negative, it counts from the end."
(require 'url-irc)
(let* ((url (url-generic-parse-url string))
(url-irc-function
(if (function-equal url-irc-function 'url-irc-erc)
(if (eq url-irc-function 'url-irc-erc)
(lambda (host port chan user pass)
(erc-handle-irc-url host port chan user pass (url-type url)))
url-irc-function)))

View file

@ -116,6 +116,25 @@ Set to nil to disable."
"The column at which a filled paragraph is broken."
:type 'integer)
(defcustom erc-fill-wrap-margin-width nil
"Starting width in columns of dedicated stamp margin.
When nil, ERC normally pretends its value is one column greater
than the `string-width' of the formatted `erc-timestamp-format'.
However, when `erc-fill-wrap-margin-side' is `left' or
\"resolves\" to `left', ERC uses the width of the prompt if it's
wider on MOTD's end, which really only matters when `erc-prompt'
is a function."
:package-version '(ERC . "5.6") ; FIXME sync on release
:type '(choice (const nil) integer))
(defcustom erc-fill-wrap-margin-side nil
"Margin side to use with `erc-fill-wrap-mode'.
A value of nil means ERC should decide based on the value of
`erc-insert-timestamp-function', which does not work for
user-defined functions."
:package-version '(ERC . "5.6") ; FIXME sync on release
:type '(choice (const nil) (const left) (const right)))
(defcustom erc-fill-line-spacing nil
"Extra space between messages on graphical displays.
This may need adjusting depending on how your faces are
@ -253,9 +272,9 @@ messages less than a day apart."
(goto-char erc-input-marker)
;; Mimic what `move-beginning-of-line' does with invisible text.
(when-let ((erc-fill-wrap-merge)
(empty (get-text-property (point) 'display))
((string-empty-p empty)))
(goto-char (text-property-not-all (point) (pos-eol) 'display empty)))))
(prop (get-text-property (point) 'display))
((or (equal prop "") (eq 'margin (car-safe (car-safe prop))))))
(goto-char (text-property-not-all (point) (pos-eol) 'display prop)))))
(defun erc-fill--wrap-end-of-line (arg)
"Defer to `move-end-of-line' or `end-of-visual-line'."
@ -278,21 +297,44 @@ is 0, reset to value of `erc-fill-wrap-visual-keys'."
('non-input nil))))
(message "erc-fill-wrap movement: %S" erc-fill--wrap-visual-keys))
(defun erc-fill-wrap-toggle-truncate-lines (arg)
"Toggle `truncate-lines' and maybe reinstate `visual-line-mode'."
(interactive "P")
(let ((wantp (if arg
(natnump (prefix-numeric-value arg))
(not truncate-lines)))
(buffer (current-buffer)))
(if wantp
(setq truncate-lines t)
(walk-windows (lambda (window)
(when (eq buffer (window-buffer window))
(set-window-hscroll window 0)))
nil t)
(visual-line-mode +1)))
(force-mode-line-update))
(defvar-keymap erc-fill-wrap-mode-map ; Compat 29
:doc "Keymap for ERC's `fill-wrap' module."
:parent visual-line-mode-map
"<remap> <kill-line>" #'erc-fill--wrap-kill-line
"<remap> <move-end-of-line>" #'erc-fill--wrap-end-of-line
"<remap> <move-beginning-of-line>" #'erc-fill--wrap-beginning-of-line
"<remap> <toggle-truncate-lines>" #'erc-fill-wrap-toggle-truncate-lines
"C-c a" #'erc-fill-wrap-cycle-visual-movement
;; Not sure if this is problematic because `erc-bol' takes no args.
"<remap> <erc-bol>" #'erc-fill--wrap-beginning-of-line)
(defvar erc-match-mode)
(defvar erc-button-mode)
(defvar erc-match--hide-fools-offset-bounds)
(defvar erc-legacy-invisible-bounds-p)
(defun erc-fill--wrap-ensure-dependencies ()
(with-suppressed-warnings ((obsolete erc-legacy-invisible-bounds-p))
(when erc-legacy-invisible-bounds-p
(erc--warn-once-before-connect 'erc-fill-wrap-mode
"Module `fill-wrap' is incompatible with the obsolete compatibility"
" flag `erc-legacy-invisible-bounds-p'. Disabling locally in %s."
(current-buffer))
(setq-local erc-legacy-invisible-bounds-p nil)))
(let (missing-deps)
(unless erc-fill-mode
(push 'fill missing-deps)
@ -319,42 +361,54 @@ is 0, reset to value of `erc-fill-wrap-visual-keys'."
"Fill style leveraging `visual-line-mode'.
This local module displays nicks overhanging leftward to a common
offset, as determined by the option `erc-fill-static-center'. It
depends on the `fill' and `button' modules and assumes the option
`erc-insert-timestamp-function' is `erc-insert-timestamp-right'
or the default `erc-insert-timestamp-left-and-right', so that it
can display right-hand stamps in the right margin. A value of
`erc-insert-timestamp-left' is unsupported. To use it, either
include `fill-wrap' in `erc-modules' or set `erc-fill-function'
to `erc-fill-wrap' (recommended). You can also manually invoke
one of the minor-mode toggles if really necessary."
depends on the `fill', `stamp', and `button' modules and assumes
users who've defined their own `erc-insert-timestamp-function'
have also customized the option `erc-fill-wrap-margin-side' to an
explicit side. To use this module, either include `fill-wrap' in
`erc-modules' or set `erc-fill-function' to `erc-fill-wrap'.
Manually invoking one of the minor-mode toggles is not
recommended.
This module imposes various restrictions on the appearance of
timestamps. Most notably, it insists on displaying them in the
margins. Users preferring left-sided stamps may notice that ERC
also displays the prompt in the left margin, possibly truncating
or padding it to constrain it to the margin's width. When stamps
appear in the right margin, which they do by default, users may
find that ERC actually appends them to copy-as-killed messages
without an intervening space. This normally poses at most a
minor inconvenience, however users of the `log' module may prefer
a workaround provided by `erc-stamp-prefix-log-filter', which
strips trailing stamps from logged messages and instead prepends
them to every line."
((erc-fill--wrap-ensure-dependencies)
;; Restore or initialize local state variables.
(erc--restore-initialize-priors erc-fill-wrap-mode
erc-fill--wrap-visual-keys erc-fill-wrap-visual-keys
erc-fill--wrap-value erc-fill-static-center)
erc-fill--wrap-value erc-fill-static-center
erc-stamp--margin-width erc-fill-wrap-margin-width
left-margin-width left-margin-width
right-margin-width right-margin-width)
(setq erc-stamp--margin-left-p
(or (eq erc-fill-wrap-margin-side 'left)
(eq (default-value 'erc-insert-timestamp-function)
#'erc-insert-timestamp-left)))
(setq erc-fill--function #'erc-fill-wrap)
;; Internal integrations.
(add-function :after (local 'erc-stamp--insert-date-function)
#'erc-fill--wrap-stamp-insert-prefixed-date)
(when (or erc-stamp-mode (memq 'stamp erc-modules))
(erc-stamp--display-margin-mode +1))
(when (or (bound-and-true-p erc-match-mode) (memq 'match erc-modules))
(require 'erc-match)
(setq erc-match--hide-fools-offset-bounds t))
(when erc-fill-wrap-merge
(add-hook 'erc-button--prev-next-predicate-functions
#'erc-fill--wrap-merged-button-p nil t))
(erc-stamp--display-margin-mode +1)
(visual-line-mode +1))
((when erc-stamp--display-margin-mode
(erc-stamp--display-margin-mode -1))
((visual-line-mode -1)
(erc-stamp--display-margin-mode -1)
(kill-local-variable 'erc-fill--wrap-value)
(kill-local-variable 'erc-fill--function)
(kill-local-variable 'erc-fill--wrap-visual-keys)
(remove-hook 'erc-button--prev-next-predicate-functions
#'erc-fill--wrap-merged-button-p t)
(remove-function (local 'erc-stamp--insert-date-function)
#'erc-fill--wrap-stamp-insert-prefixed-date)
(visual-line-mode -1))
#'erc-fill--wrap-stamp-insert-prefixed-date))
'local)
(defvar-local erc-fill--wrap-length-function nil
@ -381,18 +435,21 @@ parties.")
(widen)
(when (eq 'erc-timestamp (field-at-pos m))
(set-marker m (field-end m)))
(and (eq 'PRIVMSG (get-text-property m 'erc-command))
(not (eq (get-text-property m 'erc-ctcp) 'ACTION))
(cons (get-text-property m 'erc-timestamp)
(get-text-property (1+ m) 'erc-data)))))
(and-let*
(((eq 'PRIVMSG (get-text-property m 'erc-command)))
((not (eq (get-text-property m 'erc-ctcp)
'ACTION)))
(spr (next-single-property-change m 'erc-speaker)))
(cons (get-text-property m 'erc-timestamp)
(get-text-property spr 'erc-speaker)))))
(ts (pop 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))
(nick (buffer-substring-no-properties
(1+ (point-min)) (- (point) 2)))
(speaker (next-single-property-change (point-min) 'erc-speaker))
(nick (get-text-property speaker 'erc-speaker))
(props)
((erc-nick-equal-p (car props) nick))))
((erc-nick-equal-p props nick))))
(set-marker erc-fill--wrap-last-msg (point-min))))
(defun erc-fill--wrap-stamp-insert-prefixed-date (&rest args)
@ -476,8 +533,8 @@ Offer to repeat command in a manner similar to
\\`=' Increase indentation by one column
\\`-' Decrease indentation by one column
\\`0' Reset indentation to the default
\\`+' Shift right margin rightward (shrink) by one column
\\`_' Shift right margin leftward (grow) by one column
\\`+' Shift margin boundary rightward by one column
\\`_' Shift margin boundary leftward by one column
\\`)' Reset the right margin to the default
Note that misalignment may occur when messages contain
@ -489,6 +546,7 @@ decorations applied by third-party modules."
(unless (get-buffer-window)
(user-error "Command called in an undisplayed buffer"))
(let* ((total (erc-fill--wrap-nudge arg))
(leftp erc-stamp--margin-left-p)
(win-ratio (/ (float (- (window-point) (window-start)))
(- (window-end nil t) (window-start)))))
(when (zerop arg)
@ -509,18 +567,20 @@ decorations applied by third-party modules."
(dolist (key '(?\) ?_ ?+))
(let ((a (pcase key
(?\) 0)
(?_ (- (abs arg)))
(?+ (abs arg)))))
(?_ (if leftp (abs arg) (- (abs arg))))
(?+ (if leftp (- (abs arg)) (abs arg))))))
(define-key map (vector (list key))
(lambda ()
(interactive)
(erc-stamp--adjust-right-margin (- a))
(erc-stamp--adjust-margin (- a) (zerop a))
(when leftp (erc-stamp--refresh-left-margin-prompt))
(recenter (round (* win-ratio (window-height))))))))
map)
t
(lambda ()
(message "Fill prefix: %d (%+d col%s)"
erc-fill--wrap-value total (if (> (abs total) 1) "s" "")))
(message "Fill prefix: %d (%+d col%s); Margin: %d"
erc-fill--wrap-value total (if (> (abs total) 1) "s" "")
(if leftp left-margin-width right-margin-width)))
"Use %k for further adjustment"
1)
(recenter (round (* win-ratio (window-height))))))
@ -536,6 +596,7 @@ decorations applied by third-party modules."
"Get length of timestamp if inserted left."
(if (and (boundp 'erc-timestamp-format)
erc-timestamp-format
;; FIXME use a more robust test than symbol equivalence.
(eq erc-insert-timestamp-function 'erc-insert-timestamp-left)
(not erc-hide-timestamps))
(length (format-time-string erc-timestamp-format))

View file

@ -655,24 +655,10 @@ See `erc-log-match-format'."
(get-buffer (car buffer-cons))))))
(switch-to-buffer buffer-name)))
(defvar-local erc-match--hide-fools-offset-bounds nil)
(defun erc-hide-fools (match-type _nickuserhost _message)
"Hide comments from designated fools."
(when (eq match-type 'fool)
(erc-match--hide-message)))
(defun erc-match--hide-message ()
(progn ; FIXME raise sexp
(if erc-match--hide-fools-offset-bounds
(let ((beg (point-min))
(end (point-max)))
(save-restriction
(widen)
(erc--merge-prop (1- beg) (1- end) 'invisible 'erc-match)))
;; Before ERC 5.6, this also used to add an `intangible'
;; property, but the docs say it's now obsolete.
(erc--merge-prop (point-min) (point-max) 'invisible 'erc-match))))
(erc--hide-message 'match-fools)))
(defun erc-beep-on-match (match-type _nickuserhost _message)
"Beep when text matches.
@ -682,19 +668,31 @@ This function is meant to be called from `erc-text-matched-hook'."
(defun erc-match--modify-invisibility-spec ()
"Add an `erc-match' property to the local spec."
;; Hopefully, this will be extended to do the same for other
;; invisible properties managed by this module.
(if erc-match-mode
(add-to-invisibility-spec 'erc-match)
(erc-match-toggle-hidden-fools +1)
(erc-with-all-buffers-of-server nil nil
(remove-from-invisibility-spec 'erc-match))))
(erc-match-toggle-hidden-fools -1))))
(defun erc-match-toggle-hidden-fools ()
(defun erc-match-toggle-hidden-fools (arg)
"Toggle fool visibility.
Expect `erc-hide-fools' or a function that does something similar
to be in `erc-text-matched-hook'."
(interactive)
(if (memq 'erc-match (ensure-list buffer-invisibility-spec))
(remove-from-invisibility-spec 'erc-match)
(add-to-invisibility-spec 'erc-match)))
Expect the function `erc-hide-fools' or similar to be present in
`erc-text-matched-hook'."
(interactive "P")
(erc-match--toggle-hidden 'match-fools arg))
(defun erc-match--toggle-hidden (prop arg)
"Toggle invisibility for spec member PROP.
Treat ARG in a manner similar to mode toggles defined by
`define-minor-mode'."
(when arg
(setq arg (prefix-numeric-value arg)))
(if (memq prop (ensure-list buffer-invisibility-spec))
(unless (natnump arg)
(remove-from-invisibility-spec prop))
(when (or (not arg) (natnump arg))
(add-to-invisibility-spec prop))))
(provide 'erc-match)

View file

@ -281,49 +281,60 @@ This option only matters when `erc-insert-timestamp-function' is
set to `erc-insert-timestamp-right' or that option's default,
`erc-insert-timestamp-left-and-right'. If the value is a
positive integer, alignment occurs that many columns from the
right edge. If the value is `margin', the stamp appears in the
right margin when visible.
right edge.
Enabling this option produces a side effect in that stamps aren't
indented in saved logs. When its value is an integer, this
option adds a space after the end of a message if the stamp
doesn't already start with one. And when its value is t, it adds
a single space, unconditionally. And while this option never
adds a space when its value is `margin', ERC does offer a
workaround in `erc-stamp-prefix-log-filter', which strips
trailing stamps from messages and puts them before every line."
:type '(choice boolean integer (const margin))
a single space, unconditionally."
:type '(choice boolean integer)
:package-version '(ERC . "5.6")) ; FIXME sync on release
(defcustom erc-stamp-right-margin-width nil
"Width in columns of the right margin.
When this option is nil, pretend its value is one column greater
than the `string-width' of the formatted `erc-timestamp-format'.
This option only matters when `erc-timestamp-use-align-to' is set
to `margin'."
:package-version '(ERC . "5.6") ; FIXME sync on release
:type '(choice (const nil) integer))
(defvar-local erc-stamp--margin-width nil
"Width in columns of margin for `erc-stamp--display-margin-mode'.
Only consulted when resetting or initializing margin.")
(defun erc-stamp--display-margin-force (orig &rest r)
(let ((erc-timestamp-use-align-to 'margin))
(apply orig r)))
(defvar-local erc-stamp--margin-left-p nil
"Whether `erc-stamp--display-margin-mode' uses the left margin.
During initialization, the mode respects this variable's existing
value if it already has a local binding. Otherwise, modules can
bind this to any value while enabling the mode. If it's nil, ERC
will check to see if `erc-insert-timestamp-function' is
`erc-insert-timestamp-left', interpreting the latter as a non-nil
value. It'll then coerce any non-nil value to t.")
(defun erc-stamp--adjust-right-margin (cols)
"Adjust right margin by COLS.
When COLS is zero, reset width to `erc-stamp-right-margin-width'
or one col more than the `string-width' of
`erc-timestamp-format'."
(let ((width
(if (zerop cols)
(or erc-stamp-right-margin-width
(1+ (string-width (or erc-timestamp-last-inserted-right
(erc-format-timestamp
(current-time)
erc-timestamp-format)))))
(+ right-margin-width cols))))
(setq right-margin-width width)
(defun erc-stamp--init-margins-on-connect (&rest _)
(let ((existing (if erc-stamp--margin-left-p
left-margin-width
right-margin-width)))
(erc-stamp--adjust-margin existing 'resetp)))
(defun erc-stamp--adjust-margin (cols &optional resetp)
"Adjust managed margin by increment COLS.
With RESETP, set margin's width to COLS. However, if COLS is
zero, set the width to a non-nil `erc-stamp--margin-width'.
Otherwise, go with the `string-width' of `erc-timestamp-format'.
However, when `erc-stamp--margin-left-p' is non-nil and the
prompt is wider, use its width instead."
(let* ((leftp erc-stamp--margin-left-p)
(width
(if resetp
(or (and (not (zerop cols)) cols)
erc-stamp--margin-width
(max (if leftp (string-width (erc-prompt)) 0)
(1+ (string-width
(or (if leftp
erc-timestamp-last-inserted
erc-timestamp-last-inserted-right)
(erc-format-timestamp
(current-time) erc-timestamp-format))))))
(+ (if leftp left-margin-width right-margin-width) cols))))
(set (if leftp 'left-margin-width 'right-margin-width) width)
(when (eq (current-buffer) (window-buffer))
(set-window-margins nil left-margin-width width))))
(set-window-margins nil
(if leftp width left-margin-width)
(if leftp right-margin-width width)))))
;;;###autoload
(defun erc-stamp-prefix-log-filter (text)
@ -348,39 +359,100 @@ non-nil."
(zerop (forward-line))))
"")
(defvar erc-stamp--inherited-props '(line-prefix wrap-prefix))
(declare-function erc--remove-text-properties "erc" (string))
;; If people want to use this directly, we can convert it into
;; a local module.
;; Currently, `erc-insert-timestamp-right' hard codes its display
;; property to use `right-margin', and `erc-insert-timestamp-left'
;; does the same for `left-margin'. However, there's no reason a
;; trailing stamp couldn't be displayed on the left and vice versa.
(define-minor-mode erc-stamp--display-margin-mode
"Internal minor mode for built-in modules integrating with `stamp'.
It binds `erc-timestamp-use-align-to' to `margin' around calls to
`erc-insert-timestamp-function' in the current buffer, and sets
the right window margin to `erc-stamp-right-margin-width'. It
also arranges to remove most text properties when a user kills
message text so that stamps will be visible when yanked."
Arranges for displaying stamps in a single margin, with the
variable `erc-stamp--margin-left-p' controlling which one.
Provides `erc-stamp--margin-width' and `erc-stamp--adjust-margin'
to help manage the chosen margin's width. Also removes `display'
properties in killed text to reveal stamps. The invoking module
should set controlling variables, like `erc-stamp--margin-width'
and `erc-stamp--margin-left-p', before activating the mode."
:interactive nil
(if erc-stamp--display-margin-mode
(progn
(setq fringes-outside-margins t)
(when (eq (current-buffer) (window-buffer))
(set-window-buffer (selected-window) (current-buffer)))
(erc-stamp--adjust-right-margin 0)
(setq erc-stamp--margin-left-p (and erc-stamp--margin-left-p t))
(if (or erc-server-connected (not (functionp erc-prompt)))
(erc-stamp--init-margins-on-connect)
(add-hook 'erc-after-connect
#'erc-stamp--init-margins-on-connect nil t))
(add-function :filter-return (local 'filter-buffer-substring-function)
#'erc--remove-text-properties)
(add-function :around (local 'erc-insert-timestamp-function)
#'erc-stamp--display-margin-force))
(add-hook 'erc--setup-buffer-hook
#'erc-stamp--refresh-left-margin-prompt nil t)
(when erc-stamp--margin-left-p
(add-hook 'erc--refresh-prompt-hook
#'erc-stamp--display-prompt-in-left-margin nil t)))
(remove-function (local 'filter-buffer-substring-function)
#'erc--remove-text-properties)
(remove-function (local 'erc-insert-timestamp-function)
#'erc-stamp--display-margin-force)
(kill-local-variable 'right-margin-width)
(remove-hook 'erc-after-connect
#'erc-stamp--init-margins-on-connect t)
(remove-hook 'erc--refresh-prompt-hook
#'erc-stamp--display-prompt-in-left-margin t)
(remove-hook 'erc--setup-buffer-hook
#'erc-stamp--refresh-left-margin-prompt t)
(kill-local-variable (if erc-stamp--margin-left-p
'left-margin-width
'right-margin-width))
(kill-local-variable 'fringes-outside-margins)
(kill-local-variable 'erc-stamp--margin-left-p)
(kill-local-variable 'erc-stamp--margin-width)
(when (eq (current-buffer) (window-buffer))
(set-window-margins nil left-margin-width nil)
(set-window-buffer (selected-window) (current-buffer)))))
(defun erc-insert-timestamp-left (string)
(defvar-local erc-stamp--last-prompt nil)
(defun erc-stamp--display-prompt-in-left-margin ()
"Show prompt in the left margin with padding."
(when (or (not erc-stamp--last-prompt) (functionp erc-prompt)
(> (string-width erc-stamp--last-prompt) left-margin-width))
(let ((s (buffer-substring erc-insert-marker (1- erc-input-marker))))
;; Prevent #("abc" n m (display ((...) #("abc" p q (display...))))
(remove-text-properties 0 (length s) '(display nil) s)
(when (and erc-stamp--last-prompt
(>= (string-width erc-stamp--last-prompt) left-margin-width))
(let ((sm (truncate-string-to-width s (1- left-margin-width) 0 nil t)))
;; This papers over a subtle off-by-1 bug here.
(unless (equal sm s)
(setq s (concat sm (substring s -1))))))
(setq erc-stamp--last-prompt (string-pad s left-margin-width nil t))))
(put-text-property erc-insert-marker (1- erc-input-marker)
'display `((margin left-margin) ,erc-stamp--last-prompt))
erc-stamp--last-prompt)
(defun erc-stamp--refresh-left-margin-prompt ()
"Forcefully-recompute display property of prompt in left margin."
(with-silent-modifications
(unless (functionp erc-prompt)
(setq erc-stamp--last-prompt nil))
(erc--refresh-prompt)))
(cl-defmethod erc--reveal-prompt
(&context (erc-stamp--display-margin-mode (eql t))
(erc-stamp--margin-left-p (eql t)))
(put-text-property erc-insert-marker (1- erc-input-marker)
'display `((margin left-margin) ,erc-stamp--last-prompt)))
(cl-defmethod erc--conceal-prompt
(&context (erc-stamp--display-margin-mode (eql t))
(erc-stamp--margin-left-p (eql t)))
(let ((prompt (string-pad erc-prompt-hidden left-margin-width nil 'start)))
(put-text-property erc-insert-marker (1- erc-input-marker)
'display `((margin left-margin) ,prompt))))
(cl-defmethod erc-insert-timestamp-left (string)
"Insert timestamps at the beginning of the line."
(goto-char (point-min))
(let* ((ignore-p (and erc-timestamp-only-if-changed-flag
@ -392,6 +464,22 @@ message text so that stamps will be visible when yanked."
(erc-put-text-property 0 len 'invisible erc-stamp--invisible-property s)
(insert s)))
(cl-defmethod erc-insert-timestamp-left
(string &context (erc-stamp--display-margin-mode (eql t)))
(unless (and erc-timestamp-only-if-changed-flag
(string-equal string erc-timestamp-last-inserted))
(goto-char (point-min))
(insert-before-markers-and-inherit
(setq erc-timestamp-last-inserted string))
(dolist (p erc-stamp--inherited-props)
(when-let ((v (get-text-property (point) p)))
(put-text-property (point-min) (point) p v)))
(erc-put-text-property (point-min) (point) 'invisible
erc-stamp--invisible-property)
(put-text-property (point-min) (point) 'field 'erc-timestamp)
(put-text-property (point-min) (point)
'display `((margin left-margin) ,string))))
(defun erc-insert-aligned (string pos)
"Insert STRING at the POSth column.
@ -408,7 +496,11 @@ property to get to the POSth column."
;; Silence byte-compiler
(defvar erc-fill-column)
(defvar erc-stamp--inherited-props '(line-prefix wrap-prefix))
(defvar erc-stamp--omit-properties-on-folded-lines nil
"Skip properties before right stamps occupying their own line.
This escape hatch restores pre-5.6 behavior that left leading
white space alone (unpropertized) for right-sided stamps folded
onto their own line.")
(defun erc-insert-timestamp-right (string)
"Insert timestamp on the right side of the screen.
@ -465,6 +557,9 @@ printed just after each line's text (no alignment)."
;; For compatibility reasons, the `erc-timestamp' field includes
;; intervening white space unless a hard break is warranted.
(pcase erc-timestamp-use-align-to
((guard erc-stamp--display-margin-mode)
(put-text-property 0 (length string)
'display `((margin right-margin) ,string) string))
((and 't (guard (< col pos)))
(insert " ")
(put-text-property from (point) 'display `(space :align-to ,pos)))
@ -475,11 +570,8 @@ printed just after each line's text (no alignment)."
(let ((s (+ erc-timestamp-use-align-to (string-width string))))
(put-text-property from (point) 'display
`(space :align-to (- right ,s)))))
('margin
(put-text-property 0 (length string)
'display `((margin right-margin) ,string)
string))
((guard (>= col pos)) (newline) (indent-to pos) (setq from (point)))
((guard (>= col pos)) (newline) (indent-to pos)
(when erc-stamp--omit-properties-on-folded-lines (setq from (point))))
(_ (indent-to pos)))
(insert string)
(dolist (p erc-stamp--inherited-props)

View file

@ -2879,19 +2879,23 @@ this option to nil."
(cl-assert (< erc-insert-marker erc-input-marker))
(cl-assert (= (field-end erc-insert-marker) erc-input-marker)))))
(defvar erc--refresh-prompt-hook nil)
(defun erc--refresh-prompt ()
"Re-render ERC's prompt when the option `erc-prompt' is a function."
(erc--assert-input-bounds)
(when (functionp erc-prompt)
(save-excursion
(goto-char erc-insert-marker)
(set-marker-insertion-type erc-insert-marker nil)
;; Avoid `erc-prompt' (the named function), which appends a
;; space, and `erc-display-prompt', which propertizes all but
;; that space.
(insert-and-inherit (funcall erc-prompt))
(set-marker-insertion-type erc-insert-marker t)
(delete-region (point) (1- erc-input-marker)))))
(unless (erc--prompt-hidden-p)
(when (functionp erc-prompt)
(save-excursion
(goto-char erc-insert-marker)
(set-marker-insertion-type erc-insert-marker nil)
;; Avoid `erc-prompt' (the named function), which appends a
;; space, and `erc-display-prompt', which propertizes all but
;; that space.
(insert-and-inherit (funcall erc-prompt))
(set-marker-insertion-type erc-insert-marker t)
(delete-region (point) (1- erc-input-marker))))
(run-hooks 'erc--refresh-prompt-hook)))
(defun erc-display-line-1 (string buffer)
"Display STRING in `erc-mode' BUFFER.
@ -3007,22 +3011,51 @@ If STRING is nil, the function does nothing."
(defvar erc--compose-text-properties nil
"Non-nil when `erc-put-text-property' defers to `erc--merge-prop'.")
;; To save space, we could maintain a map of all readable property
;; values and optionally dispense archetypal constants in their place
;; in order to ensure all occurrences of some list (a b) across all
;; text-properties in all ERC buffers are actually the same object.
(defun erc--merge-prop (from to prop val &optional object)
"Compose existing PROP values with VAL between FROM and TO in OBJECT.
"Combine existing PROP values with VAL between FROM and TO in OBJECT.
For spans where PROP is non-nil, cons VAL onto the existing
value, ensuring a proper list. Otherwise, just set PROP to VAL.
See also `erc-button-add-face'."
When VAL is itself a list, prepend its members onto an existing
value. See also `erc-button-add-face'."
(let ((old (get-text-property from prop object))
(pos from)
(end (next-single-property-change from prop object to))
new)
(while (< pos to)
(setq new (if old (cons val (ensure-list old)) val))
(setq new (if old
(if (listp val)
(append val (ensure-list old))
(cons val (ensure-list old)))
val))
(put-text-property pos end prop new object)
(setq pos end
old (get-text-property pos prop object)
end (next-single-property-change pos prop object to)))))
(defvar erc-legacy-invisible-bounds-p nil
"Whether to hide trailing rather than preceding newlines.
Beginning in ERC 5.6, invisibility extends from a message's
preceding newline to its last non-newline character.")
(make-obsolete-variable 'erc-legacy-invisible-bounds-p
"decremented interval now permanent" "30.1")
(defun erc--hide-message (value)
"Apply `invisible' text-property with VALUE to current message.
Expect to run in a narrowed buffer during message insertion."
(if erc-legacy-invisible-bounds-p
;; Before ERC 5.6, this also used to add an `intangible'
;; property, but the docs say it's now obsolete.
(erc--merge-prop (point-min) (point-max) 'invisible value)
(let ((beg (point-min))
(end (point-max)))
(save-restriction
(widen)
(erc--merge-prop (1- beg) (1- end) 'invisible value)))))
(defun erc-display-message-highlight (type string)
"Highlight STRING according to TYPE, where erc-TYPE-face is an ERC face.
@ -4804,7 +4837,7 @@ If FACE is non-nil, it will be used to propertize the prompt. If it is nil,
;; shall remain part of the prompt.
(setq prompt (propertize prompt
'rear-nonsticky t
'erc-prompt t
'erc-prompt t ; t or `hidden'
'field 'erc-prompt
'front-sticky t
'read-only t))

View file

@ -2972,6 +2972,25 @@ whether HANDLER is to be called. Add operations defined in
(put #'tramp-unload-file-name-handlers 'tramp-autoload t)
(add-hook 'tramp-unload-hook #'tramp-unload-file-name-handlers)
;;;###autoload
(progn (defun inhibit-remote-files ()
"Deactivate remote file names."
(interactive)
(when (fboundp 'tramp-cleanup-all-connections)
(funcall 'tramp-cleanup-all-connections))
(tramp-unload-file-name-handlers)
(setq tramp-mode nil)))
;;;###autoload
(progn (defmacro without-remote-files (&rest body)
"Deactivate remote file names temporarily.
Run BODY."
(declare (indent 0) (debug ((form body) body)))
`(let ((file-name-handler-alist (copy-tree file-name-handler-alist))
tramp-mode)
(tramp-unload-file-name-handlers)
,@body)))
;;; File name handler functions for completion mode:
;; This function takes action since Emacs 28.1, when

View file

@ -2447,18 +2447,16 @@ buffer."
(defun eglot--post-self-insert-hook ()
"Set `eglot--last-inserted-char', maybe call on-type-formatting."
(setq eglot--last-inserted-char last-input-event)
(let ((ot-provider (eglot--server-capable :documentOnTypeFormattingProvider))
;; transform carriage return into line-feed
(adjusted-ie (if (= last-input-event 13) 10 last-input-event)))
(setq eglot--last-inserted-char last-command-event)
(let ((ot-provider (eglot--server-capable :documentOnTypeFormattingProvider)))
(when (and ot-provider
(ignore-errors ; github#906, some LS's send empty strings
(or (eq adjusted-ie
(or (eq eglot--last-inserted-char
(seq-first (plist-get ot-provider :firstTriggerCharacter)))
(cl-find adjusted-ie
(cl-find eglot--last-inserted-char
(plist-get ot-provider :moreTriggerCharacter)
:key #'seq-first))))
(eglot-format (point) nil adjusted-ie))))
(eglot-format (point) nil eglot--last-inserted-char))))
(defvar eglot--workspace-symbols-cache (make-hash-table :test #'equal)
"Cache of `workspace/Symbol' results used by `xref-find-definitions'.")

View file

@ -250,7 +250,8 @@ Prefer the enclosing string with fallback on sexp at point.
(goto-char (nth 8 ppss))
(cons (point) (progn (forward-sexp) (point))))
;; At the beginning of the string
(if (eq (char-syntax (char-after)) ?\")
(if (let ((ca (char-after)))
(and ca (eq (char-syntax ca) ?\")))
(let ((bound (bounds-of-thing-at-point 'sexp)))
(and bound
(<= (car bound) (point)) (< (point) (cdr bound))
@ -359,6 +360,10 @@ E.g.:
(and (file-exists-p filename)
filename)))
(put 'existing-filename 'bounds-of-thing-at-point
(lambda ()
(and (thing-at-point 'existing-filename)
(bounds-of-thing-at-point 'filename))))
(put 'existing-filename 'thing-at-point 'thing-at-point-file-at-point)
;; Faces

View file

@ -140,7 +140,7 @@ make the mail indicator stand out on a color display."
:type '(choice (const :tag "None" nil) face))
(defface display-time-date-and-time
'((t (:inherit mode-line)))
'((t nil))
"Face for `display-time-format'."
:group 'mode-line-faces
:version "30.1")

View file

@ -2157,7 +2157,8 @@ the earlier input."
;; `widget-setup' is called.
(overlay (cons (make-marker) (make-marker))))
(widget-put widget :field-overlay overlay)
(insert value)
(when value
(insert value))
(and size
(< (length value) size)
(insert-char ?\s (- size (length value))))
@ -3685,7 +3686,9 @@ match-alternatives: %S"
value
(widget-get widget :match)
(widget-get widget :match-alternatives))
:warning))
:warning)
;; Make sure we will `read' a string.
(setq value (prin1-to-string value)))
(read value)))
(defun widget-restricted-sexp-match (widget value)
@ -4015,7 +4018,8 @@ current choice is inline."
nil)
((= (length args) 1)
(nth 0 args))
((and (= (length args) 2)
((and widget-choice-toggle
(= (length args) 2)
(memq old args))
(if (eq old (nth 0 args))
(nth 1 args)

View file

@ -5656,6 +5656,15 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
argument is ZV to prevent move_it_in_display_line from matching
based on buffer positions. */
move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X);
if (mouse_prefer_closest_glyph)
{
int next_x = it.current_x + it.pixel_width;
int before_dx = to_x - it.current_x;
int after_dx = next_x - to_x;
if (before_dx > after_dx)
move_it_in_display_line (&it, ZV, next_x, MOVE_TO_X);
}
bidi_unshelve_cache (itdata, 0);
Fset_buffer (old_current_buffer);
@ -6848,6 +6857,14 @@ predicates which report frame's specific UI-related capabilities. */);
DEFVAR_BOOL ("cursor-in-echo-area", cursor_in_echo_area,
doc: /* Non-nil means put cursor in minibuffer, at end of any message there. */);
DEFVAR_BOOL ("mouse-prefer-closest-glyph", mouse_prefer_closest_glyph,
doc: /* Non-nil means mouse click position is taken from glyph closest to click.
When non-nil, mouse position lists will report buffer position set to
the position of the glyph that is the closest to the mouse pointer
at the time of the click, instead of the glyph immediately under it. */);
mouse_prefer_closest_glyph = false;
DEFVAR_LISP ("glyph-table", Vglyph_table,
doc: /* Table defining how to output a glyph code to the frame.
If not nil, this is a vector indexed by glyph code to define the glyph.

View file

@ -4203,7 +4203,7 @@ mark_specpdl (union specbinding *first, union specbinding *ptr)
void
get_backtrace (Lisp_Object array)
{
union specbinding *pdl = backtrace_next (backtrace_top ());
union specbinding *pdl = backtrace_top ();
ptrdiff_t i = 0, asize = ASIZE (array);
/* Copy the backtrace contents into working memory. */

View file

@ -47,6 +47,9 @@
/* Make syntax table lookup grant data in gl_state. */
#define SYNTAX(c) syntax_property (c, 1)
/* Explicit syntax lookup using the buffer-local table. */
#define BUFFER_SYNTAX(c) syntax_property (c, 0)
#define RE_MULTIBYTE_P(bufp) ((bufp)->multibyte)
#define RE_TARGET_MULTIBYTE_P(bufp) ((bufp)->target_multibyte)
#define RE_STRING_CHAR(p, multibyte) \
@ -132,18 +135,22 @@
#define ISLOWER(c) lowercasep (c)
#define ISUPPER(c) uppercasep (c)
/* The following predicates use the buffer-local syntax table and
ignore syntax properties, for consistency with the up-front
assumptions made at compile time. */
#define ISPUNCT(c) (IS_REAL_ASCII (c) \
? ((c) > ' ' && (c) < 0177 \
&& !(((c) >= 'a' && (c) <= 'z') \
|| ((c) >= 'A' && (c) <= 'Z') \
|| ((c) >= '0' && (c) <= '9'))) \
: SYNTAX (c) != Sword)
: BUFFER_SYNTAX (c) != Sword)
#define ISSPACE(c) (SYNTAX (c) == Swhitespace)
#define ISSPACE(c) (BUFFER_SYNTAX (c) == Swhitespace)
#define ISUPPER(c) uppercasep (c)
#define ISWORD(c) (SYNTAX (c) == Sword)
#define ISWORD(c) (BUFFER_SYNTAX (c) == Sword)
/* Use alloca instead of malloc. This is because using malloc in
re_search* or re_match* could cause memory leaks when C-g is used
@ -2048,13 +2055,6 @@ regex_compile (re_char *pattern, ptrdiff_t size,
is_xdigit, since they can only match ASCII characters.
We don't need to handle them for multibyte. */
/* Setup the gl_state object to its buffer-defined value.
This hardcodes the buffer-global syntax-table for ASCII
chars, while the other chars will obey syntax-table
properties. It's not ideal, but it's the way it's been
done until now. */
SETUP_BUFFER_SYNTAX_TABLE ();
for (c = 0; c < 0x80; ++c)
if (re_iswctype (c, cc))
{

View file

@ -2759,6 +2759,7 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
enum window_part part;
enum glyph_row_area area;
int x, y, width, height;
int original_gx;
if (mouse_fine_grained_tracking)
{
@ -2769,6 +2770,8 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
/* Try to determine frame pixel position and size of the glyph under
frame pixel coordinates X/Y on frame F. */
original_gx = gx;
if (window_resize_pixelwise)
{
width = height = 1;
@ -2984,6 +2987,15 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
gy += WINDOW_TOP_EDGE_Y (w);
store_rect:
if (mouse_prefer_closest_glyph)
{
int half_width = width / 2;
width = half_width;
int bisection = gx + half_width;
if (original_gx > bisection)
gx = bisection;
}
STORE_NATIVE_RECT (*rect, gx, gy, width, height);
/* Visible feedback for debugging. */
@ -37724,9 +37736,12 @@ may be more familiar to users. */);
display_raw_bytes_as_hex = false;
DEFVAR_BOOL ("mouse-fine-grained-tracking", mouse_fine_grained_tracking,
doc: /* Non-nil for pixel-wise mouse-movement.
doc: /* Non-nil for pixelwise mouse-movement.
When nil, mouse-movement events will not be generated as long as the
mouse stays within the extent of a single glyph (except for images). */);
mouse stays within the extent of a single glyph (except for images).
When nil and `mouse-prefer-closest-glyph' is non-nil, mouse-movement
events will instead not be generated as long as the mouse stays within
the extent of a single left/right half glyph (except for images). */);
mouse_fine_grained_tracking = false;
DEFVAR_BOOL ("tab-bar--dragging-in-progress", tab_bar__dragging_in_progress,

View file

@ -340,4 +340,41 @@
(should (search-backward "ERC> " nil t))
(execute-kbd-macro "\C-a")))))
(ert-deftest erc-fill--left-hand-stamps ()
:tags '(:unstable)
(unless (>= emacs-major-version 29)
(ert-skip "Emacs version too low, missing `buffer-text-pixel-size'"))
(let ((erc-timestamp-only-if-changed-flag nil)
(erc-insert-timestamp-function #'erc-insert-timestamp-left))
(erc-fill-tests--wrap-populate
(lambda ()
(should (= 8 left-margin-width))
(pcase-let ((`((margin left-margin) ,displayed)
(get-text-property erc-insert-marker 'display)))
(should (equal-including-properties
displayed #(" ERC>" 4 8
( read-only t
front-sticky t
field erc-prompt
erc-prompt t
rear-nonsticky t
font-lock-face erc-prompt-face)))))
(erc-fill-tests--compare "stamps-left-01")
(ert-info ("Shrink left margin by 1 col")
(erc-stamp--adjust-margin -1)
(with-silent-modifications (erc--refresh-prompt))
(should (= 7 left-margin-width))
(pcase-let ((`((margin left-margin) ,displayed)
(get-text-property erc-insert-marker 'display)))
(should (equal-including-properties
displayed #(" ERC>" 3 7
( read-only t
front-sticky t
field erc-prompt
erc-prompt t
rear-nonsticky t
font-lock-face erc-prompt-face))))))))))
;;; erc-fill-tests.el ends here

View file

@ -62,11 +62,15 @@
'erc-current-nick-face))))))
;; When hacking on tests that use this fixture, it's best to run it
;; interactively, and check for wierdness before and after doing
;; M-: (remove-from-invisibility-spec 'erc-match) RET.
;; interactively, and visually inspect the output with various
;; combinations of:
;;
;; M-x erc-match-toggle-hidden-fools RET
;; M-x erc-toggle-timestamps RET
;;
(defun erc-scenarios-match--invisible-stamp (hiddenp visiblep)
(unless noninteractive
(kill-new "(remove-from-invisibility-spec 'erc-match)"))
(kill-new "erc-match-toggle-hidden-fools"))
(erc-scenarios-common-with-cleanup
((erc-scenarios-common-dialog "join/legacy")
@ -128,11 +132,11 @@
;; Leading stamp has combined `invisible' property value.
(should (equal (get-text-property (pos-bol) 'invisible)
'(timestamp erc-match)))
'(timestamp match-fools)))
;; Message proper has the `invisible' property `erc-match'.
;; Message proper has the `invisible' property `match-fools'.
(let ((msg-beg (next-single-property-change (pos-bol) 'invisible)))
(should (eq (get-text-property msg-beg 'invisible) 'erc-match))
(should (eq (get-text-property msg-beg 'invisible) 'match-fools))
(should (>= (next-single-property-change msg-beg 'invisible nil)
(pos-eol)))))
@ -147,19 +151,29 @@
(= (next-single-property-change msg-beg 'invisible nil (pos-eol))
(pos-eol))))))))
(defun erc-scenarios-match--find-bol ()
(save-excursion
(should (get-text-property (1- (point)) 'erc-command))
(goto-char (should (previous-single-property-change (point) 'erc-command)))
(pos-bol)))
(defun erc-scenarios-match--find-eol ()
(save-excursion
(goto-char (next-single-property-change (point) 'erc-command))
(if-let ((next (next-single-property-change (point) 'erc-command)))
(goto-char next)
;; We're already at the end of the message.
(should (get-text-property (1- (point)) 'erc-command)))
(pos-eol)))
;; In most cases, `erc-hide-fools' makes line endings invisible.
(ert-deftest erc-scenarios-match--stamp-right-fools-invisible ()
(defun erc-scenarios-match--stamp-right-fools-invisible ()
:tags '(:expensive-test)
(let ((erc-insert-timestamp-function #'erc-insert-timestamp-right))
(erc-scenarios-match--invisible-stamp
(lambda ()
(let ((end (erc-scenarios-match--find-eol)))
(let ((beg (erc-scenarios-match--find-bol))
(end (erc-scenarios-match--find-eol)))
;; The end of the message is a newline.
(should (= ?\n (char-after end)))
@ -168,19 +182,23 @@
;; Stamps have a combined `invisible' property value.
(should (equal (get-text-property (1- end) 'invisible)
'(timestamp erc-match)))
'(timestamp match-fools)))
;; The final newline is hidden by `match', not `stamps'
(should (equal (get-text-property end 'invisible) 'erc-match))
(with-suppressed-warnings ((obsolete erc-legacy-invisible-bounds-p))
(if erc-legacy-invisible-bounds-p
(should (eq (get-text-property end 'invisible) 'match-fools))
(should (eq (get-text-property beg 'invisible) 'match-fools))
(should-not (get-text-property end 'invisible))))
;; The message proper has the `invisible' property `erc-match',
;; The message proper has the `invisible' property `match-fools',
;; and it starts after the preceding newline.
(should (eq (get-text-property (pos-bol) 'invisible) 'erc-match))
(should (eq (get-text-property (pos-bol) 'invisible) 'match-fools))
;; It ends just before the timestamp.
(let ((msg-end (next-single-property-change (pos-bol) 'invisible)))
(should (equal (get-text-property msg-end 'invisible)
'(timestamp erc-match)))
'(timestamp match-fools)))
;; Stamp's `invisible' property extends throughout the stamp
;; and ends before the trailing newline.
@ -197,6 +215,17 @@
(should (eq (get-text-property inv-beg 'invisible)
'timestamp))))))))
(ert-deftest erc-scenarios-match--stamp-right-fools-invisible ()
:tags '(:expensive-test)
(erc-scenarios-match--stamp-right-fools-invisible))
(ert-deftest erc-scenarios-match--stamp-right-fools-invisible--nooffset ()
:tags '(:expensive-test)
(with-suppressed-warnings ((obsolete erc-legacy-invisible-bounds-p))
(should-not erc-legacy-invisible-bounds-p)
(let ((erc-legacy-invisible-bounds-p t))
(erc-scenarios-match--stamp-right-fools-invisible))))
;; This asserts that when `erc-fill-wrap-mode' is enabled, ERC hides
;; the preceding message's line ending.
(ert-deftest erc-scenarios-match--stamp-right-invisible-fill-wrap ()
@ -215,16 +244,16 @@
;; Stamps have a combined `invisible' property value.
(should (equal (get-text-property (1- (pos-eol)) 'invisible)
'(timestamp erc-match)))
'(timestamp match-fools)))
;; The message proper has the `invisible' property `erc-match',
;; The message proper has the `invisible' property `match-fools',
;; which starts at the preceding newline...
(should (eq (get-text-property (1- (pos-bol)) 'invisible) 'erc-match))
(should (eq (get-text-property (1- (pos-bol)) 'invisible) 'match-fools))
;; ... and ends just before the timestamp.
(let ((msgend (next-single-property-change (1- (pos-bol)) 'invisible)))
(should (equal (get-text-property msgend 'invisible)
'(timestamp erc-match)))
'(timestamp match-fools)))
;; The newline before `erc-insert-marker' is still visible.
(should-not (get-text-property (pos-eol) 'invisible))
@ -242,8 +271,7 @@
(let ((inv-beg (next-single-property-change (1- (pos-bol)) 'invisible)))
(should (eq (get-text-property inv-beg 'invisible) 'timestamp)))))))
(ert-deftest erc-scenarios-match--stamp-both-invisible-fill-static ()
:tags '(:expensive-test)
(defun erc-scenarios-match--stamp-both-invisible-fill-static ()
(should (eq erc-insert-timestamp-function
#'erc-insert-timestamp-left-and-right))
@ -265,8 +293,8 @@
(search-forward "[23:59]"))))
(ert-info ("Line endings in Bob's messages are invisible")
;; The message proper has the `invisible' property `erc-match'.
(should (eq (get-text-property (pos-bol) 'invisible) 'erc-match))
;; The message proper has the `invisible' property `match-fools'.
(should (eq (get-text-property (pos-bol) 'invisible) 'match-fools))
(let* ((mbeg (next-single-property-change (pos-bol) 'erc-command))
(mend (next-single-property-change mbeg 'erc-command)))
@ -283,9 +311,13 @@
(should (= (next-single-property-change (pos-bol) 'erc-timestamp)
mend))
;; Line ending has the `invisible' property `erc-match'.
;; Line ending has the `invisible' property `match-fools'.
(should (= (char-after mend) ?\n))
(should (eq (get-text-property mend'invisible) 'erc-match))))
(with-suppressed-warnings ((obsolete erc-legacy-invisible-bounds-p))
(if erc-legacy-invisible-bounds-p
(should (eq (get-text-property mend 'invisible) 'match-fools))
(should (eq (get-text-property mbeg 'invisible) 'match-fools))
(should-not (get-text-property mend 'invisible))))))
;; Only the message right after Alice speaks contains stamps.
(when (= 1 bob-utterance-counter)
@ -298,7 +330,7 @@
;; Date stamp has a combined `invisible' property value
;; that extends until the start of the message proper.
(should (equal (get-text-property (point) 'invisible)
'(timestamp erc-match)))
'(timestamp match-fools)))
(should (= (next-single-property-change (point) 'invisible)
(1+ (pos-eol))))))
@ -314,7 +346,7 @@
(let ((msgend (next-single-property-change (pos-bol) 'invisible)))
;; Stamp has a combined `invisible' property value.
(should (equal (get-text-property msgend 'invisible)
'(timestamp erc-match)))
'(timestamp match-fools)))
;; Combined `invisible' property spans entire timestamp.
(should (= (next-single-property-change msgend 'invisible)
@ -331,4 +363,15 @@
(should-not (eq (field-at-pos (1- (pos-eol))) 'erc-timestamp))
(should-not (next-single-property-change (pos-bol) 'invisible))))))
(ert-deftest erc-scenarios-match--stamp-both-invisible-fill-static ()
:tags '(:expensive-test)
(erc-scenarios-match--stamp-both-invisible-fill-static))
(ert-deftest erc-scenarios-match--stamp-both-invisible-fill-static--nooffset ()
:tags '(:expensive-test)
(with-suppressed-warnings ((obsolete erc-legacy-invisible-bounds-p))
(should-not erc-legacy-invisible-bounds-p)
(let ((erc-legacy-invisible-bounds-p t))
(erc-scenarios-match--stamp-both-invisible-fill-static))))
;;; erc-scenarios-match.el ends here

View file

@ -56,7 +56,7 @@
(advice-remove 'erc-format-timestamp
'ert-deftest--erc-timestamp-use-align-to)))
(ert-deftest erc-timestamp-use-align-to--nil ()
(defun erc-stamp-tests--use-align-to--nil (compat)
(erc-stamp-tests--insert-right
(lambda ()
@ -83,12 +83,20 @@
(erc-display-message nil 'notice (current-buffer)
"twenty characters"))
(should (search-forward-regexp (rx bol (+ "\t") (* " ") "[") nil t))
;; Field excludes leading whitespace (arguably undesirable).
(should (eql ?\[ (char-after (field-beginning (point)))))
;; Field includes leading whitespace.
(should (eql (if compat ?\[ ?\n)
(char-after (field-beginning (point)))))
;; Timestamp extends to the end of the line.
(should (eql ?\n (char-after (field-end (point)))))))))
(ert-deftest erc-timestamp-use-align-to--t ()
(ert-deftest erc-timestamp-use-align-to--nil ()
(ert-info ("Field starts on stamp text (compat)")
(let ((erc-stamp--omit-properties-on-folded-lines t))
(erc-stamp-tests--use-align-to--nil 'compat)))
(ert-info ("Field includes leaidng white space")
(erc-stamp-tests--use-align-to--nil nil)))
(defun erc-stamp-tests--use-align-to--t (compat)
(erc-stamp-tests--insert-right
(lambda ()
@ -110,10 +118,17 @@
(erc-display-message nil nil (current-buffer) msg)))
;; Indented to pos (this is arguably a bug).
(should (search-forward-regexp (rx bol (+ "\t") (* " ") "[") nil t))
;; Field starts *after* leading space (arguably bad).
(should (eql ?\[ (char-after (field-beginning (point)))))
;; Field includes leading space.
(should (eql (if compat ?\[ ?\n) (char-after (field-beginning (point)))))
(should (eql ?\n (char-after (field-end (point)))))))))
(ert-deftest erc-timestamp-use-align-to--t ()
(ert-info ("Field starts on stamp text (compat)")
(let ((erc-stamp--omit-properties-on-folded-lines t))
(erc-stamp-tests--use-align-to--t 'compat)))
(ert-info ("Field includes leaidng white space")
(erc-stamp-tests--use-align-to--t nil)))
(ert-deftest erc-timestamp-use-align-to--integer ()
(erc-stamp-tests--insert-right
(lambda ()
@ -140,7 +155,7 @@
(should (eql ?\s (char-after (field-beginning (point)))))
(should (eql ?\n (char-after (field-end (point)))))))))
(ert-deftest erc-timestamp-use-align-to--margin ()
(ert-deftest erc-stamp--display-margin-mode--right ()
(erc-stamp-tests--insert-right
(lambda ()
(erc-stamp--display-margin-mode +1)

View file

@ -219,6 +219,7 @@
(setq erc-hide-prompt '(server))
(with-current-buffer "ServNet"
(erc--hide-prompt erc-server-process)
(should (eq (get-text-property erc-insert-marker 'erc-prompt) 'hidden))
(should (string= ">" (get-text-property erc-insert-marker 'display))))
(with-current-buffer "#chan"
@ -229,6 +230,7 @@
(with-current-buffer "ServNet"
(erc--unhide-prompt)
(should (eq (get-text-property erc-insert-marker 'erc-prompt) t))
(should-not (get-text-property erc-insert-marker 'display))))
(ert-info ("Value: channel")
@ -242,7 +244,9 @@
(with-current-buffer "#chan"
(should (string= ">" (get-text-property erc-insert-marker 'display)))
(should (eq (get-text-property erc-insert-marker 'erc-prompt) 'hidden))
(erc--unhide-prompt)
(should (eq (get-text-property erc-insert-marker 'erc-prompt) t))
(should-not (get-text-property erc-insert-marker 'display))))
(ert-info ("Value: query")
@ -253,7 +257,9 @@
(with-current-buffer "bob"
(should (string= ">" (get-text-property erc-insert-marker 'display)))
(should (eq (get-text-property erc-insert-marker 'erc-prompt) 'hidden))
(erc--unhide-prompt)
(should (eq (get-text-property erc-insert-marker 'erc-prompt) t))
(should-not (get-text-property erc-insert-marker 'display)))
(with-current-buffer "#chan"
@ -1272,6 +1278,50 @@
(should-not calls))))))
(defmacro erc-tests--equal-including-properties (a b)
(list (if (< emacs-major-version 29)
'ert-equal-including-properties
'equal-including-properties)
a b))
(ert-deftest erc--merge-prop ()
(with-current-buffer (get-buffer-create "*erc-test*")
;; Baseline.
(insert "abc\n")
(erc--merge-prop 1 3 'erc-test 'x)
(should (erc-tests--equal-including-properties
(buffer-substring 1 4) #("abc" 0 2 (erc-test x))))
(erc--merge-prop 1 3 'erc-test 'y)
(should (erc-tests--equal-including-properties
(buffer-substring 1 4) #("abc" 0 2 (erc-test (y x)))))
;; Multiple intervals.
(goto-char (point-min))
(insert "def\n")
(erc--merge-prop 1 2 'erc-test 'x)
(erc--merge-prop 2 3 'erc-test 'y)
(should (erc-tests--equal-including-properties
(buffer-substring 1 4)
#("def" 0 1 (erc-test x) 1 2 (erc-test y))))
(erc--merge-prop 1 3 'erc-test 'z)
(should (erc-tests--equal-including-properties
(buffer-substring 1 4)
#("def" 0 1 (erc-test (z x)) 1 2 (erc-test (z y)))))
;; New val as list.
(goto-char (point-min))
(insert "ghi\n")
(erc--merge-prop 2 3 'erc-test '(y z))
(should (erc-tests--equal-including-properties
(buffer-substring 1 4) #("ghi" 1 2 (erc-test (y z)))))
(erc--merge-prop 1 3 'erc-test '(w x))
(should (erc-tests--equal-including-properties
(buffer-substring 1 4)
#("ghi" 0 1 (erc-test (w x)) 1 2 (erc-test (w x y z)))))
(when noninteractive
(kill-buffer))))
(ert-deftest erc--split-string-shell-cmd ()
;; Leading and trailing space
@ -1488,12 +1538,6 @@
(kill-buffer "ExampleNet")
(kill-buffer "#chan")))
(defmacro erc-tests--equal-including-properties (a b)
(list (if (< emacs-major-version 29)
'ert-equal-including-properties
'equal-including-properties)
a b))
(ert-deftest erc-format-privmessage ()
;; Basic PRIVMSG
(should (erc-tests--equal-including-properties

View file

@ -0,0 +1 @@
#("\n\n[00:00]*** 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.\n[00:00]<alice> 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[00:00]<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 9 (erc-timestamp 0 display (#4=(margin left-margin) #("[00:00]" 0 7 (invisible timestamp font-lock-face erc-timestamp-face))) field erc-timestamp wrap-prefix #1=(space :width 27) line-prefix #2=(space :width (- 27 (4)))) 9 171 (erc-timestamp 0 wrap-prefix #1# line-prefix #2#) 172 179 (erc-timestamp 0 display (#4# #("[00:00]" 0 7 (invisible timestamp font-lock-face erc-timestamp-face))) field erc-timestamp wrap-prefix #1# line-prefix #3=(space :width (- 27 (8)))) 179 180 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 180 185 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 185 187 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 187 190 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 190 303 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 303 304 (erc-timestamp 0 erc-command PRIVMSG) 304 336 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 337 344 (erc-timestamp 0 display (#4# #("[00:00]" 0 7 (invisible timestamp font-lock-face erc-timestamp-face))) field erc-timestamp wrap-prefix #1# line-prefix #5=(space :width (- 27 (6)))) 344 345 (erc-timestamp 0 wrap-prefix #1# line-prefix #5# erc-command PRIVMSG) 345 348 (erc-timestamp 0 wrap-prefix #1# line-prefix #5# erc-command PRIVMSG) 348 350 (erc-timestamp 0 wrap-prefix #1# line-prefix #5# erc-command PRIVMSG) 350 355 (erc-timestamp 0 wrap-prefix #1# line-prefix #5# erc-command PRIVMSG) 355 430 (erc-timestamp 0 wrap-prefix #1# line-prefix #5# erc-command PRIVMSG))

View file

@ -988,6 +988,20 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
code tae tramp-archive-test-file-archive
(concat tramp-archive-test-archive "foo"))))))))))
(ert-deftest tramp-archive-test49-without-remote-files ()
"Check that Tramp can be suppressed."
(skip-unless tramp-archive-enabled)
(should (file-exists-p tramp-archive-test-archive))
(should-not (without-remote-files (file-exists-p tramp-archive-test-archive)))
(should (file-exists-p tramp-archive-test-archive))
(inhibit-remote-files)
(should-not (file-exists-p tramp-archive-test-archive))
(tramp-register-file-name-handlers)
(setq tramp-mode t)
(should (file-exists-p tramp-archive-test-archive)))
(ert-deftest tramp-archive-test99-libarchive-tests ()
"Run tests of libarchive test files."
:tags '(:expensive-test :unstable)

View file

@ -8009,7 +8009,22 @@ process sentinels. They shall not disturb each other."
(mapconcat #'shell-quote-argument load-path " -L ")
(shell-quote-argument code)))))))
(ert-deftest tramp-test49-unload ()
(ert-deftest tramp-test49-without-remote-files ()
"Check that Tramp can be suppressed."
(skip-unless (tramp--test-enabled))
(should (file-remote-p ert-remote-temporary-file-directory))
(should-not
(without-remote-files (file-remote-p ert-remote-temporary-file-directory)))
(should (file-remote-p ert-remote-temporary-file-directory))
(inhibit-remote-files)
(should-not (file-remote-p ert-remote-temporary-file-directory))
(tramp-register-file-name-handlers)
(setq tramp-mode t)
(should (file-remote-p ert-remote-temporary-file-directory)))
(ert-deftest tramp-test50-unload ()
"Check that Tramp and its subpackages unload completely.
Since it unloads Tramp, it shall be the last test to run."
:tags '(:expensive-test)

View file

@ -949,4 +949,20 @@ This evaluates the TESTS test cases from glibc."
(should (equal (smatch "a\\=*b" "ab") 0))
))
(ert-deftest regex-emacs-syntax-properties ()
;; Verify absence of character class syntax property ghost matching bug.
(let ((re "\\s-[[:space:]]")
(s (concat "a"
(propertize "b" 'syntax-table '(0)) ; whitespace
"éz"))
(parse-sexp-lookup-properties t))
;; Test matching in a string...
(should (equal (string-match re s) nil))
;; ... and in a buffer.
(should (equal (with-temp-buffer
(insert s)
(goto-char (point-min))
(re-search-forward re nil t))
nil))))
;;; regex-emacs-tests.el ends here