mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
Retain client's own user in erc-server-users
* lisp/erc/erc-backend.el (erc-server-KICK, erc-server-PART): Use new function `erc--remove-channel-user-but' instead of `erc-remove-channel-users'. In `erc-server-KICK', remove sender's channel membership data after displaying the message so that nicks are buttonized. Return nil. In `erc-server-PART', don't run `erc-remove-channel-member' when the client itself has parted. * lisp/erc/erc-common.el (erc--remove-user-from-targets): New function. * lisp/erc/erc.el (erc-remove-server-user): Redo doc string. (erc--forget-server-user-function): New variable. (erc--forget-server-user): New function. (erc--forget-server-user-ignoring-queries): New function, the default value of `erc--forget-server-user-function'. (erc-remove-channel-user): Defer to `erc--forget-server-user-function' to do the actual removal. (erc-remove-user): Defer to `erc--remove-user-from-targets'. (erc-remove-channel-users): Redo doc (erc--remove-channel-users-but): New function. The only use case thus far is for protecting the client's own `erc-server-users' entry from removal when draining `erc-channel-members' tables after the client leaves a target buffer or quits. (erc-kill-buffer-function): Don't remove own user from `erc-server-users'. * test/lisp/erc/erc-scenarios-base-renick.el (erc-scenarios-base-renick-queries-solo): Assert own client parting its only channel doesn't remove own user from server. Also assert that another user parting their only channel removes them from all queries. (Bug#70928)
This commit is contained in:
parent
04477cf97b
commit
5f84213c98
4 changed files with 93 additions and 45 deletions
|
|
@ -581,13 +581,7 @@ Ensure targets with an entry in `erc-server-users' are present in
|
|||
erc-server-process))
|
||||
|
||||
(defun erc-remove-server-user (nick)
|
||||
"This function is for internal use only.
|
||||
|
||||
Removes the user with nickname NICK from the `erc-server-users'
|
||||
hash table. This user is not removed from the
|
||||
`erc-channel-users' lists of other buffers.
|
||||
|
||||
See also: `erc-remove-user'."
|
||||
"Remove NICK from the session's `erc-server-users' table."
|
||||
(erc-with-server-buffer
|
||||
(remhash (erc-downcase nick) erc-server-users)))
|
||||
|
||||
|
|
@ -610,15 +604,29 @@ other buffers are also changed."
|
|||
(puthash (erc-downcase new-nick) cdata
|
||||
erc-channel-users)))))))
|
||||
|
||||
(defvar erc--forget-server-user-function
|
||||
#'erc--forget-server-user-ignoring-queries
|
||||
"Function to conditionally remove a user from `erc-server-users'.
|
||||
Called with a nick and its `erc-server-user' object.")
|
||||
|
||||
(defun erc--forget-server-user (nick user)
|
||||
"Remove NICK's USER from server table if they're not in any target buffers."
|
||||
(unless (erc-server-user-buffers user)
|
||||
(erc-remove-server-user nick)))
|
||||
|
||||
(defun erc--forget-server-user-ignoring-queries (nick user)
|
||||
"Remove NICK's USER from `erc-server-users' if they've parted all channels."
|
||||
(let ((buffers (erc-server-user-buffers user)))
|
||||
(when (or (null buffers)
|
||||
(and (not erc--decouple-query-and-channel-membership-p)
|
||||
(cl-every #'erc-query-buffer-p buffers)))
|
||||
(when buffers
|
||||
(erc--remove-user-from-targets (erc-downcase nick) buffers))
|
||||
(erc-remove-server-user nick))))
|
||||
|
||||
(defun erc-remove-channel-user (nick)
|
||||
"This function is for internal use only.
|
||||
|
||||
Removes the user with nickname NICK from the `erc-channel-users'
|
||||
list for this channel. If this user is not in the
|
||||
`erc-channel-users' list of any other buffers, the user is also
|
||||
removed from the server's `erc-server-users' list.
|
||||
|
||||
See also: `erc-remove-server-user' and `erc-remove-user'."
|
||||
"Remove NICK from the current target buffer's `erc-channel-members'.
|
||||
If this was their only target, also remove them from `erc-server-users'."
|
||||
(let ((channel-data (erc-get-channel-user nick)))
|
||||
(when channel-data
|
||||
(let ((user (car channel-data)))
|
||||
|
|
@ -626,32 +634,19 @@ See also: `erc-remove-server-user' and `erc-remove-user'."
|
|||
(delq (current-buffer)
|
||||
(erc-server-user-buffers user)))
|
||||
(remhash (erc-downcase nick) erc-channel-users)
|
||||
(if (null (erc-server-user-buffers user))
|
||||
(erc-remove-server-user nick))))))
|
||||
(funcall erc--forget-server-user-function nick user)))))
|
||||
|
||||
(defun erc-remove-user (nick)
|
||||
"This function is for internal use only.
|
||||
|
||||
Removes the user with nickname NICK from the `erc-server-users'
|
||||
list as well as from all `erc-channel-users' lists.
|
||||
|
||||
See also: `erc-remove-server-user' and
|
||||
`erc-remove-channel-user'."
|
||||
"Remove NICK from the server and all relevant channels tables."
|
||||
(let ((user (erc-get-server-user nick)))
|
||||
(when user
|
||||
(let ((buffers (erc-server-user-buffers user)))
|
||||
(dolist (buf buffers)
|
||||
(if (buffer-live-p buf)
|
||||
(with-current-buffer buf
|
||||
(remhash (erc-downcase nick) erc-channel-users)
|
||||
(run-hooks 'erc-channel-members-changed-hook)))))
|
||||
(erc--remove-user-from-targets (erc-downcase nick)
|
||||
(erc-server-user-buffers user))
|
||||
(erc-remove-server-user nick))))
|
||||
|
||||
(defun erc-remove-channel-users ()
|
||||
"This function is for internal use only.
|
||||
|
||||
Removes all users in the current channel. This is called by
|
||||
`erc-server-PART' and `erc-server-QUIT'."
|
||||
"Drain current buffer's `erc-channel-members' table.
|
||||
Also remove members from the server table if this was their only buffer."
|
||||
(when (erc--target-channel-p erc--target)
|
||||
(setf (erc--target-channel-joined-p erc--target) nil))
|
||||
(when (and erc-server-connected
|
||||
|
|
@ -662,6 +657,19 @@ Removes all users in the current channel. This is called by
|
|||
erc-channel-users)
|
||||
(clrhash erc-channel-users)))
|
||||
|
||||
(defun erc--remove-channel-users-but (nick)
|
||||
"Drain channel users and remove from server, sparing NICK."
|
||||
(when-let ((users (erc-with-server-buffer erc-server-users))
|
||||
(my-user (gethash (erc-downcase nick) users))
|
||||
(original-function erc--forget-server-user-function)
|
||||
(erc--forget-server-user-function
|
||||
(if erc--decouple-query-and-channel-membership-p
|
||||
erc--forget-server-user-function
|
||||
(lambda (nick user)
|
||||
(unless (eq user my-user)
|
||||
(funcall original-function nick user))))))
|
||||
(erc-remove-channel-users)))
|
||||
|
||||
(defmacro erc--define-channel-user-status-compat-getter (name c d)
|
||||
"Define a gv getter for historical `erc-channel-user' status slot NAME.
|
||||
Expect NAME to be a string, C to be its traditionally associated
|
||||
|
|
@ -9691,7 +9699,9 @@ one of the following hooks:
|
|||
`erc-kill-channel-hook' if a channel buffer was killed,
|
||||
or `erc-kill-buffer-hook' if any other buffer."
|
||||
(when (eq major-mode 'erc-mode)
|
||||
(erc-remove-channel-users)
|
||||
(when-let ((erc--target)
|
||||
(nick (erc-current-nick)))
|
||||
(erc--remove-channel-users-but nick))
|
||||
(cond
|
||||
((eq (erc-server-buffer) (current-buffer))
|
||||
(run-hooks 'erc-kill-server-hook))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue