Merge remote-tracking branch 'origin/master' into feature/android
This commit is contained in:
commit
be70caa68f
31 changed files with 753 additions and 230 deletions
|
@ -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}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
29
etc/ERC-NEWS
29
etc/ERC-NEWS
|
@ -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
|
||||
|
|
38
etc/NEWS
38
etc/NEWS
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'.")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
19
src/xdisp.c
19
src/xdisp.c
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue