From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: "J.P." Newsgroups: gmane.emacs.bugs Subject: bug#67220: 30.0.50; ERC 5.6: Prefer parameter-driven MODE processing in ERC Date: Tue, 21 Nov 2023 06:30:34 -0800 Message-ID: <87il5vfab9.fsf__46781.5036465012$1700577159$gmane$org@neverwas.me> References: <87pm0aphr2.fsf@neverwas.me> <87zfzcnsg1.fsf@neverwas.me> <87il5yogj7.fsf@neverwas.me> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="31041"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: emacs-erc@gnu.org To: 67220@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Tue Nov 21 15:32:31 2023 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1r5Rnh-0007oc-Mw for geb-bug-gnu-emacs@m.gmane-mx.org; Tue, 21 Nov 2023 15:32:29 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1r5RnF-0002V7-FH; Tue, 21 Nov 2023 09:32:01 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1r5RnD-0002UL-KF for bug-gnu-emacs@gnu.org; Tue, 21 Nov 2023 09:31:59 -0500 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1r5RnD-0005un-Bt for bug-gnu-emacs@gnu.org; Tue, 21 Nov 2023 09:31:59 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1r5RnF-0001LM-OS for bug-gnu-emacs@gnu.org; Tue, 21 Nov 2023 09:32:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: "J.P." Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 21 Nov 2023 14:32:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 67220 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 67220-submit@debbugs.gnu.org id=B67220.17005770735086 (code B ref 67220); Tue, 21 Nov 2023 14:32:01 +0000 Original-Received: (at 67220) by debbugs.gnu.org; 21 Nov 2023 14:31:13 +0000 Original-Received: from localhost ([127.0.0.1]:55580 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1r5RmP-0001Jv-9a for submit@debbugs.gnu.org; Tue, 21 Nov 2023 09:31:13 -0500 Original-Received: from mail-108-mta0.mxroute.com ([136.175.108.0]:42795) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1r5RmK-0001Jf-Hh for 67220@debbugs.gnu.org; Tue, 21 Nov 2023 09:31:08 -0500 Original-Received: from filter006.mxroute.com ([136.175.111.2] filter006.mxroute.com) (Authenticated sender: mN4UYu2MZsgR) by mail-108-mta0.mxroute.com (ZoneMTA) with ESMTPSA id 18bf24a9764000190b.001 for <67220@debbugs.gnu.org> (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384); Tue, 21 Nov 2023 14:30:56 +0000 X-Zone-Loop: dae691f67e5ad6726a10e6b2719a5585e6f9d3e6f865 X-Originating-IP: [136.175.111.2] DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=neverwas.me ; s=x; h=Content-Type:MIME-Version:Message-ID:Date:References:In-Reply-To: Subject:Cc:To:From:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=zICLpbsiJEnNO3AdQagAOYOBAN1eLegESCXSkanjcT8=; b=CLj24fsJENb1qPecGgfbX7u/wB LIsJHC5te30cJ82bLNeJY3HQ3YyInHkC3We98kZctwc1c5ucdad8F0cbxP2Ut1CH46XNyA9iK6hDe iUo2aeRCvRaMcvJsBx6HtmFBx5+Ix+xo8cHRizx+8qpyQIQB2PCFD+tZqpmdEORO6vwMVyMzlNXoC qMjNr9mXzNutdbEdUeh2ZB8hzKjuo/1s47uLDqtEBYDqR4QbJk0pYW73jJzgjKuOd6JY5iAhxe2x7 eJwHeKVXVgxoKI0mtz7K+Uy9mqJB5MJd+IV3tx+5Eqso21yDhs2+MB4HP+dYT0T/Erci67fPbzNqC BBD5hksA==; In-Reply-To: <87il5yogj7.fsf@neverwas.me> (J. P.'s message of "Sat, 18 Nov 2023 14:14:36 -0800") X-Authenticated-Id: masked@neverwas.me X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:274731 Archived-At: --=-=-= Content-Type: text/plain "J.P." writes: > "J.P." writes: > >> v2. Account for nonstandard CHANMODES beyond type D. Make mode-letter >> handling more extensible and modular. Provide convenience macro for >> caching processed data originating from ISUPPORT values. Retain original >> parsed channel-mode data. > > This has been installed as > > cca7956c82d * Favor ISUPPORT params for MODE processing in ERC > > Closing for now. Unfortunately, this latest round of changes messed up a pretty basic but important aspect of channel-mode parsing. As a result, the ERC on HEAD confuses modes that take parameters with those that don't. Worst case is thought to be that strange values may be assigned to the variables `erc-channel-user-limit' and `erc-channel-key'. Fix attached. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-5.6-Don-t-associate-type-D-channel-modes-with-args-i.patch >From 70affab11884917814cd4e86c4266f1feeace9ea Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Mon, 20 Nov 2023 19:45:30 -0800 Subject: [PATCH] [5.6] Don't associate type D channel modes with args in ERC * lisp/erc/erc.el (erc--process-channel-modes): Don't associate args with group 4/D, which are all nullary modes. (erc--user-modes): Simplify slightly by removing likely useless variant for overloaded arg AS-TYPE. This function is new in ERC 5.6. (erc--channel-modes): New function. A higher-level getter for current channel mode representation to complement `erc--user-modes'. (erc--handle-channel-mode): Change model to associate modes of type A with a running plus/minus tally of state changes since joining the channel. * test/lisp/erc/erc-tests.el (erc--update-channel-modes): Update to reflect new running tally associations for type A modes. (erc--channel-modes): New test. (erc--user-modes): Update to reflect parameter simplification. (Bug#67220) --- lisp/erc/erc.el | 58 +++++++++++++++++++++++++++++++------- test/lisp/erc/erc-tests.el | 36 ++++++++++++++++++++--- 2 files changed, 80 insertions(+), 14 deletions(-) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index f4c3f77593c..f8053165b8b 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -6686,7 +6686,8 @@ erc--process-channel-modes (erc--update-membership-prefix (pop args) c (if +p 'on 'off))) ((and-let* ((group (or (aref table c) (and fallbackp ?d)))) (erc--handle-channel-mode group c +p - (and (or (/= group ?c) +p) + (and (/= group ?d) + (or (/= group ?c) +p) (pop args))) t)) ((not fallbackp) @@ -6703,16 +6704,43 @@ erc--user-modes "Return user \"MODE\" letters in a form described by AS-TYPE. When AS-TYPE is the symbol `strings' (plural), return a list of strings. When it's `string' (singular), return the same list -concatenated into a single string. When it's a single char, like -?+, return the same value as `string' but with AS-TYPE prepended. -When AS-TYPE is nil, return a list of chars." +concatenated into a single string. When AS-TYPE is nil, return a +list of chars." (let ((modes (or erc--user-modes (erc-with-server-buffer erc--user-modes)))) (pcase as-type ('strings (mapcar #'char-to-string modes)) ('string (apply #'string modes)) - ((and (pred characterp) c) (apply #'string (cons c modes))) (_ modes)))) +(defun erc--channel-modes (&optional as-type sep) + "Return channel \"MODE\" settings in a form described by AS-TYPE. +When AS-TYPE is the symbol `strings' (plural), return all keys a +list of sorted string. When it's `string' (singular), return +keys as a single string. When it's a number, return a single +string consisting of the concatenated and sorted keys followed by +their corresponding args, separated by SEP, which defaults to a +single space. Otherwise, return a sorted alist of letter/arg +pairs." + (and-let* ((modes erc--channel-modes) + (types (erc--channel-mode-types-table (erc--channel-mode-types)))) + (let (out) + (maphash (lambda (k v) + (unless (eq ?a (aref types k)) + (push (cons k (and (not (eq t v)) v)) out))) + modes) + (setq out (cl-sort out #'< :key #'car)) + (pcase as-type + ('strings (mapcar (lambda (o) (char-to-string (car o))) out)) + ('string (apply #'string (mapcar #'car out))) + ((and (pred natnump) c) + (let (keys vals) + (pcase-dolist (`(,k . ,v) out) + (when v (push (substring v 0 (min c (length v))) vals)) + (push k keys)) + (concat (apply #'string (nreverse keys)) (and vals " ") + (string-join (nreverse vals) (or sep " "))))) + (_ out))))) + (defun erc--parse-user-modes (string &optional current extrap) "Return lists of chars from STRING to add to and drop from CURRENT. Expect STRING to be a so-called \"modestring\", the second @@ -6791,14 +6819,24 @@ erc--handle-channel-mode (erc-log (format "Channel-mode %c (type %s, arg %S) %s" letter type arg (if state 'enabled 'disabled)))) -(cl-defmethod erc--handle-channel-mode :before (_ c state arg) - "Record STATE change and ARG, if enabling, for mode letter C." +(cl-defmethod erc--handle-channel-mode :before (type c state arg) + "Record STATE change for mode letter C. +When STATE is non-nil, add or update C's mapping in +`erc--channel-modes', associating it with ARG if C takes a +parameter and t otherwise. When STATE is nil, forget the +mapping. For type A, add up update a permanent mapping for C, +associating it with an integer indicating a running total of +STATE changes since joining the channel. In most cases, this +won't match the number known to the server." (unless erc--channel-modes (cl-assert (erc--target-channel-p erc--target)) (setq erc--channel-modes (make-hash-table))) - (if state - (puthash c (or arg t) erc--channel-modes) - (remhash c erc--channel-modes))) + (if (= type ?a) + (cl-callf (lambda (s) (+ (or s 0) (if state +1 -1))) + (gethash c erc--channel-modes)) + (if state + (puthash c (or arg t) erc--channel-modes) + (remhash c erc--channel-modes)))) (cl-defmethod erc--handle-channel-mode :before ((_ (eql ?d)) c state _) "Update `erc-channel-modes' for any character C of nullary type D. diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 8dbe44ce5ed..0c03a12864a 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -796,13 +796,42 @@ erc--update-channel-modes (erc--update-channel-modes "+qu" "fool!*@*") (should (equal (pop calls) '(?d ?u t nil))) (should (equal (pop calls) '(?a ?q t "fool!*@*"))) - (should (equal "fool!*@*" (gethash ?q erc--channel-modes))) + (should (equal 1 (gethash ?q erc--channel-modes))) (should (eq t (gethash ?u erc--channel-modes))) (should (equal erc-channel-modes '("u"))) - (should-not (erc-channel-user-owner-p "bob"))) + (should-not (erc-channel-user-owner-p "bob")) + + ;; Remove fool!*@* from list mode "q". + (erc--update-channel-modes "-uq" "fool!*@*") + (should (equal (pop calls) '(?a ?q nil "fool!*@*"))) + (should (equal (pop calls) '(?d ?u nil nil))) + (should-not (gethash ?u erc--channel-modes)) + (should-not erc-channel-modes) + (should (equal 0 (gethash ?q erc--channel-modes)))) (should-not calls)))) +(ert-deftest erc--channel-modes () + (setq erc--isupport-params (make-hash-table) + erc--target (erc--target-from-string "#test") + erc-server-parameters + '(("CHANMODES" . "eIbq,k,flj,CFLMPQRSTcgimnprstuz"))) + + (erc-tests--set-fake-server-process "sleep" "1") + + (cl-letf (((symbol-function 'erc-update-mode-line) #'ignore)) + (erc--update-channel-modes "+bltk" "fool!*@*" "3" "h2")) + + (should (equal (erc--channel-modes 'string) "klt")) + (should (equal (erc--channel-modes 'strings) '("k" "l" "t"))) + (should (equal (erc--channel-modes) '((?k . "h2") (?l . "3") (?t)))) + (should (equal (erc--channel-modes 3 ",") "klt h2,3")) + (should (equal (erc--channel-modes 1 ",") "klt h,3")) + (should (equal (erc--channel-modes 0 ",") "klt ,")) + (should (equal (erc--channel-modes 2) "klt h2 3")) + (should (equal (erc--channel-modes 1) "klt h 3")) + (should (equal (erc--channel-modes 0) "klt "))) ; 2 spaces + (ert-deftest erc--update-user-modes () (let ((erc--user-modes (list ?a))) (should (equal (erc--update-user-modes "+a") '(?a))) @@ -818,8 +847,7 @@ erc--user-modes (let ((erc--user-modes '(?a ?b))) (should (equal (erc--user-modes) '(?a ?b))) (should (equal (erc--user-modes 'string) "ab")) - (should (equal (erc--user-modes 'strings) '("a" "b"))) - (should (equal (erc--user-modes '?+) "+ab")))) + (should (equal (erc--user-modes 'strings) '("a" "b"))))) (ert-deftest erc--parse-user-modes () (should (equal (erc--parse-user-modes "a" '(?a)) '(() ()))) -- 2.41.0 --=-=-=--