From debbugs-submit-bounces@debbugs.gnu.org Fri Jul 08 09:26:53 2022 Received: (at submit) by debbugs.gnu.org; 8 Jul 2022 13:26:53 +0000 Received: from localhost ([127.0.0.1]:59112 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1o9o0R-0003MC-Uz for submit@debbugs.gnu.org; Fri, 08 Jul 2022 09:26:53 -0400 Received: from lists.gnu.org ([209.51.188.17]:51806) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1o9o0M-0003Lw-4Z for submit@debbugs.gnu.org; Fri, 08 Jul 2022 09:26:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:35844) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o9o0L-0004ht-PL for bug-gnu-emacs@gnu.org; Fri, 08 Jul 2022 09:26:45 -0400 Received: from mail-108-mta198.mxroute.com ([136.175.108.198]:33339) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1o9o0I-0007GK-EG for bug-gnu-emacs@gnu.org; Fri, 08 Jul 2022 09:26:45 -0400 Received: from filter006.mxroute.com ([140.82.40.27] filter006.mxroute.com) (Authenticated sender: mN4UYu2MZsgR) by mail-108-mta198.mxroute.com (ZoneMTA) with ESMTPSA id 181ddf9063e0000261.001 for (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256); Fri, 08 Jul 2022 13:21:33 +0000 X-Zone-Loop: 89f11f25c7b0c41bc8be009eea305d949672e650ccfa X-Originating-IP: [140.82.40.27] 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:Subject:To:From:Sender: Reply-To:Cc:Content-Transfer-Encoding:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=X626Ls6/SD4Swx75aIs1sF7D43e6E6Q+O16lxBntzkQ=; b=cdVOeWfdDq8SDDq7gBcnbq9jVC DRU/cwagnMMwWBG/HRqRNAXCB42AQwV78NToxoDxZ4HKBuMMz4wvoeqVGClOBty3/EIUDw0SuqJWB 2X73crg8WBMLBTuJquMNRLzp3P7FzkPOQYUaffnq0d1rJQuE8ZArES2KzjPGET8mYKv8fi4ZF9htm HV6tlMBLrN9fWbQTKE9i0SJWw+P08JIz7y5CHG4k03rd+3mbOMUbjBdxB0b5JWgWuy3aPra4xN2i0 ncmneUgpgkCBO+CSi57UstiuId36YEftvQmkQBqcqqhjln8KwJFZBtMpFqUJjdSMUaZW6Mk/VvO3H rXlac0dw==; From: "J.P." To: bug-gnu-emacs@gnu.org Subject: 29.0.50; Revisit target shortcuts in erc-message X-Debbugs-CC: emacs-erc@gnu.org Date: Fri, 08 Jul 2022 06:21:29 -0700 Message-ID: <87mtdj68py.fsf@neverwas.me> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-AuthUser: masked@neverwas.me Received-SPF: pass client-ip=136.175.108.198; envelope-from=jp@neverwas.me; helo=mail-108-mta198.mxroute.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-Spam-Score: -1.4 (-) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.4 (--) --=-=-= Content-Type: text/plain Tags: patch The purpose of the function `erc-message' is to provide a "target shortcut" option to a handful of "slash" commands, mostly ones emitting a PRIVMSG. When a user invoking such a command supplies a period or a comma instead of a channel or a nick, whatever's stored in the relevant slot of `erc-server-last-peers' gets substituted in the outgoing message. IOW, issuing a ERC> /MSG , hi recalls the last nick to speak over a given connection. And ERC> /MSG . hi reuses the target (channel or query) from the last `erc-message' invocation, which may have been something like ERC> /MSG bob hi with no actual shortcut present. As it happens, these targets are stashed in the default value shared across all connections, which is almost certainly undesirable. But attempting to fix it forces us to confront some basic usability concerns that vary based on whatever we deem to be the feature's intended "scope": 1. Network (patch) The name of the variable in question, `erc-server-last-peers', may suggest that this feature should be scoped per IRC connection. But what's the point of blindly addressing the last speaker among all of a network's buffers without knowing exactly who you're engaging? 2. Buffer-local Using a "," for PM'ing the last speaker in a target buffer may lead to a surprise if anyone else speaks before you've submitted the input. As with (1), only the logs know for sure. Also, the "." form is only useful so long as you refrain from speaking. For now, I propose temporarily adopting (1) by confining shared values to server buffers. As far as attempting to renovate this feature goes (rather than, say, tacitly retiring it), I think it's worth considering that nick completion and abbrevs have long provided capable alternatives. In that vein, the last patch below claims to offer a compromise that somewhat extends the existing pcomplete integration for the affected slash commands so that dots and commas expand to their relevant targets in the input area. This reduces potential targeting errors by offering visual confirmation. IOW, if the last person to speak was Alice, typing ERC> /m ,[TAB] would expand to ERC> /m alice _ And while this demo is built atop (1), the idea could easily be adapted for (2) or another variant. BTW, if anyone has experience with pcomplete, I'm pretty sure I committed an epic faceplant in trying to apply the API. If we end up going with this, please help. But, for now, the door remains wide open, and alternative solutions are more than welcome. Thanks, J.P. P.S. This bug isn't (yet) claimed by any particular ERC release. In GNU Emacs 29.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.34, cairo version 1.17.6) of 2022-07-06 built on localhost Repository revision: e6504c3eda12c72268d2db6598764f043b74c24d Repository branch: master Windowing system distributor 'The X.Org Foundation', version 11.0.12014000 System Description: Fedora Linux 36 (Workstation Edition) Configured using: 'configure --enable-check-lisp-object-type --enable-checking=yes,glyphs 'CFLAGS=-O0 -g3' PKG_CONFIG_PATH=:/usr/lib64/pkgconfig:/usr/share/pkgconfig' Configured features: ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 M17N_FLT MODULES NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS WEBP X11 XDBE XIM XINPUT2 XPM GTK3 ZLIB Important settings: value of $LANG: en_US.UTF-8 value of $XMODIFIERS: @im=ibus locale-coding-system: utf-8-unix Major mode: Lisp Interaction Minor modes in effect: tooltip-mode: t global-eldoc-mode: t eldoc-mode: t show-paren-mode: t electric-indent-mode: t mouse-wheel-mode: t tool-bar-mode: t menu-bar-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-mode: t line-number-mode: t indent-tabs-mode: t transient-mark-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t Load-path shadows: None found. Features: (shadow sort mail-extr emacsbug message mailcap yank-media puny dired dired-loaddefs rfc822 mml mml-sec password-cache epa derived epg rfc6068 epg-config gnus-util text-property-search time-date subr-x mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader cl-loaddefs cl-lib sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils rmc iso-transl tooltip eldoc paren electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe tabulated-list replace newcomment text-mode lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch easymenu timer select scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors frame minibuffer nadvice seq simple cl-generic indonesian philippine cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european ethiopic indian cyrillic chinese composite emoji-zwj charscript charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs faces cus-face macroexp files window text-properties overlay sha1 md5 base64 format env code-pages mule custom widget keymap hashtable-print-readable backquote threads dbusbind inotify lcms2 dynamic-setting system-font-setting font-render-setting cairo move-toolbar gtk x-toolkit xinput2 x multi-tty make-network-process emacs) Memory information: ((conses 16 35545 5688) (symbols 48 5073 0) (strings 32 13303 1546) (string-bytes 1 429956) (vectors 16 9197) (vector-slots 8 145428 11407) (floats 8 21 25) (intervals 56 214 0) (buffers 992 10)) --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Demo-mutating-default-value-of-erc-server-last-peers.patch >From 803064a22318abcbcc3fe700884186c51b6fd039 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Wed, 6 Jul 2022 00:40:42 -0700 Subject: [PATCH 1/3] ; Demo mutating default value of `erc-server-last-peers' --- test/lisp/erc/erc-tests.el | 88 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 4971d0e194..373f5f16b0 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -893,4 +893,92 @@ erc-process-input-line (should-not calls)))))) +;; Note: if adding an erc-backend-tests.el, please relocate this there. + +(ert-deftest erc-message () + (unless (equal erc-server-last-peers '(nil . nil)) + (setq erc-server-last-peers (cons nil nil))) + (let (server-proc + calls + erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook) + (cl-letf (((symbol-function 'erc-display-message) + (lambda (_ _ _ line) (push line calls))) + ((symbol-function 'erc-server-send) + (lambda (line _) (push line calls))) + ((symbol-function 'erc-server-buffer) + (lambda () (process-buffer server-proc)))) + (with-current-buffer (get-buffer-create "ExampleNet") + (erc-mode) + (setq erc-server-current-nick "tester" + server-proc (start-process "sleep" (current-buffer) "sleep" "1") + erc-server-process server-proc + erc-server-last-peers (cons nil nil) + erc-server-users (make-hash-table :test 'equal) + erc-network 'ExampleNet) + (set-process-query-on-exit-flag erc-server-process nil)) + + (with-current-buffer (get-buffer-create "#chan") + (erc-mode) + (setq erc-server-process (buffer-local-value 'erc-server-process + (get-buffer "ExampleNet")) + erc-default-recipients '("#chan") + erc-channel-users (make-hash-table :test 'equal) + erc-network 'ExampleNet) + (erc-update-current-channel-member "alice" "alice") + (erc-update-current-channel-member "tester" "tester")) + + (with-current-buffer "ExampleNet" + (erc-server-PRIVMSG erc-server-process + (make-erc-response + :sender "alice!~u@fsf.org" + :command "PRIVMSG" + :command-args '("#chan" "hi") + :unparsed ":alice!~u@fsf.org PRIVMSG #chan :hi")) + (should (equal erc-server-last-peers '("alice"))) + (should (string-match "" (pop calls)))) + + (with-current-buffer "#chan" + (ert-info ("Shortcuts unusable in target buffers") + (should-not (local-variable-p 'erc-server-last-peers)) + (should (equal erc-server-last-peers '(nil . nil))) + (erc-message "PRIVMSG" ". hi") + (should (equal erc-server-last-peers '(nil . nil))) + (should (eq 'no-target (pop calls))) + (erc-message "PRIVMSG" ", hi") + (should (equal erc-server-last-peers '(nil . nil))) + (should (eq 'no-target (pop calls))))) + + (with-current-buffer "ExampleNet" + (ert-info ("Shortcuts local in server bufs") + (should (equal erc-server-last-peers '("alice"))) + (erc-message "PRIVMSG" ", hi") + (should (equal erc-server-last-peers '("alice" . "alice"))) + (should (string-match "PRIVMSG alice :hi" (pop calls))) + (setcdr erc-server-last-peers "bob") + (erc-message "PRIVMSG" ". hi") + (should (equal erc-server-last-peers '("alice" . "bob"))) + (should (string-match "PRIVMSG bob :hi" (pop calls))))) + + (with-current-buffer "#chan" + (ert-info ("Non-shortcuts affect global default") + (should-not (local-variable-p 'erc-server-last-peers)) + (should (equal erc-server-last-peers '(nil . nil))) + (erc-message "PRIVMSG" "#chan hola") + (should (equal erc-server-last-peers '(nil . "#chan"))) + (should (equal (default-value 'erc-server-last-peers) + '(nil . "#chan"))) + (should (string-match "hola" (pop calls)))) + + (ert-info ("Dot shortcut now usable in target buffers") + (erc-message "PRIVMSG" ". how") + (should (equal erc-server-last-peers '(nil . "#chan"))) + (should (string-match "how" (pop calls)))))) + + (should (equal (default-value 'erc-server-last-peers) '(nil . "#chan"))) + (setq erc-server-last-peers (cons nil nil)) + (should (equal erc-server-last-peers '(nil . nil))) + (should-not calls) + (kill-buffer "ExampleNet") + (kill-buffer "#chan"))) + ;;; erc-tests.el ends here -- 2.36.1 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0002-SQUASH-Avoid-mutating-default-value-of-erc-server-la.patch >From 93233064285554d24df1a3137194bae4edd1ec06 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Wed, 29 Jun 2022 04:05:52 -0700 Subject: [PATCH 2/3] [SQUASH] Avoid mutating default value of erc-server-last-peers * lisp/erc/erc-backend.el (erc-server-last-peers): Define as nil instead of a quoted constant. (erc-server-connect): Initialize `erc-server-last-peers' to a new value local to a server buffer. (erc--message-shortcut): New function to store and recall senders and receivers for the current connection when processing "." and "," shortcuts. (erc-message): Delegate to `erc--message-shortcut' to handle shortcuts. (erc-server-PRIVMSG): Create a new `erc-server-last-peers' for every message received to make for easier testing. --- lisp/erc/erc-backend.el | 31 +++++++++++++++-------------- test/lisp/erc/erc-tests.el | 40 ++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index bc7a7d14dc..ea1891da0b 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -230,7 +230,7 @@ erc-server-error-occurred (defvar-local erc-server-lines-sent nil "Line counter.") -(defvar-local erc-server-last-peers '(nil . nil) +(defvar-local erc-server-last-peers nil "Last peers used, both sender and receiver. Those are used for /MSG destination shortcuts.") @@ -562,7 +562,7 @@ erc-server-connect (setq erc-server-last-received-time time)) (setq erc-server-lines-sent 0) ;; last peers (sender and receiver) - (setq erc-server-last-peers '(nil . nil))) + (setq erc-server-last-peers (cons nil nil))) ;; we do our own encoding and decoding (when (fboundp 'set-process-coding-system) (set-process-coding-system process 'raw-text)) @@ -931,29 +931,30 @@ erc-server-send-queue (run-at-time (+ 0.2 erc-server-flood-penalty) nil #'erc-server-send-queue buffer))))))) +(defun erc--message-shortcut (arg &optional commit) + (let* ((buffer (erc-server-buffer)) + (peers (buffer-local-value 'erc-server-last-peers buffer)) + (tgt (pcase arg ("," (car peers)) ("." (cdr peers)) (_ arg)))) + (when tgt + (when commit + (with-current-buffer buffer + (setq erc-server-last-peers (cons (car peers) tgt)))) + tgt))) + (defun erc-message (message-command line &optional force) "Send LINE to the server as a privmsg or a notice. MESSAGE-COMMAND should be either \"PRIVMSG\" or \"NOTICE\". If the target is \",\", the last person you've got a message from will be used. If the target is \".\", the last person you've sent a message -to will be used." +to will be used. Note that as of ERC 5.6, this syntax is considered +deprecated. See the pcomplete module for similar functionality." (cond ((string-match "^\\s-*\\(\\S-+\\) ?\\(.*\\)" line) - (let ((tgt (match-string 1 line)) + (let ((tgt (erc--message-shortcut (match-string 1 line) 'commit)) (s (match-string 2 line))) (erc-log (format "cmd: MSG(%s): [%s] %s" message-command tgt s)) - (cond - ((string= tgt ",") - (if (car erc-server-last-peers) - (setq tgt (car erc-server-last-peers)) - (setq tgt nil))) - ((string= tgt ".") - (if (cdr erc-server-last-peers) - (setq tgt (cdr erc-server-last-peers)) - (setq tgt nil)))) (cond (tgt - (setcdr erc-server-last-peers tgt) (erc-server-send (format "%s %s :%s" message-command tgt s) force)) (t @@ -1550,7 +1551,7 @@ define-erc-response-handler (erc-process-ctcp-reply proc parsed nick login host (match-string 1 msg))))) (t - (setcar erc-server-last-peers nick) + (setq erc-server-last-peers (cons nick (cdr erc-server-last-peers))) (setq s (erc-format-privmessage (or fnick nick) msg ;; If buffer is a query buffer, diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 373f5f16b0..0f222edacf 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -896,8 +896,7 @@ erc-process-input-line ;; Note: if adding an erc-backend-tests.el, please relocate this there. (ert-deftest erc-message () - (unless (equal erc-server-last-peers '(nil . nil)) - (setq erc-server-last-peers (cons nil nil))) + (should-not erc-server-last-peers) (let (server-proc calls erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook) @@ -938,19 +937,19 @@ erc-message (should (string-match "" (pop calls)))) (with-current-buffer "#chan" - (ert-info ("Shortcuts unusable in target buffers") + (ert-info ("Shortcuts usable in target buffers") (should-not (local-variable-p 'erc-server-last-peers)) - (should (equal erc-server-last-peers '(nil . nil))) + (should-not erc-server-last-peers) (erc-message "PRIVMSG" ". hi") - (should (equal erc-server-last-peers '(nil . nil))) + (should-not erc-server-last-peers) (should (eq 'no-target (pop calls))) (erc-message "PRIVMSG" ", hi") - (should (equal erc-server-last-peers '(nil . nil))) - (should (eq 'no-target (pop calls))))) + (should-not erc-server-last-peers) + (should (string-match "alice :hi" (pop calls))))) (with-current-buffer "ExampleNet" (ert-info ("Shortcuts local in server bufs") - (should (equal erc-server-last-peers '("alice"))) + (should (equal erc-server-last-peers '("alice" . "alice"))) (erc-message "PRIVMSG" ", hi") (should (equal erc-server-last-peers '("alice" . "alice"))) (should (string-match "PRIVMSG alice :hi" (pop calls))) @@ -960,23 +959,18 @@ erc-message (should (string-match "PRIVMSG bob :hi" (pop calls))))) (with-current-buffer "#chan" - (ert-info ("Non-shortcuts affect global default") + (ert-info ("Non-shortcuts are local to server buffer") (should-not (local-variable-p 'erc-server-last-peers)) - (should (equal erc-server-last-peers '(nil . nil))) + (should-not erc-server-last-peers) (erc-message "PRIVMSG" "#chan hola") - (should (equal erc-server-last-peers '(nil . "#chan"))) - (should (equal (default-value 'erc-server-last-peers) - '(nil . "#chan"))) - (should (string-match "hola" (pop calls)))) - - (ert-info ("Dot shortcut now usable in target buffers") - (erc-message "PRIVMSG" ". how") - (should (equal erc-server-last-peers '(nil . "#chan"))) - (should (string-match "how" (pop calls)))))) - - (should (equal (default-value 'erc-server-last-peers) '(nil . "#chan"))) - (setq erc-server-last-peers (cons nil nil)) - (should (equal erc-server-last-peers '(nil . nil))) + (should-not erc-server-last-peers) + (should-not (default-value 'erc-server-last-peers)) + (should (equal (buffer-local-value 'erc-server-last-peers + (get-buffer "ExampleNet")) + '("alice" . "#chan"))) + (should (string-match "hola" (pop calls)))))) + + (should-not erc-server-last-peers) (should-not calls) (kill-buffer "ExampleNet") (kill-buffer "#chan"))) -- 2.36.1 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0003-POC-FIXME-Add-erc-message-shortcuts-to-erc-pcomplete.patch >From 87426c1a071c498b1780b1e2ef2a98c6ec90b2eb Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Thu, 7 Jul 2022 02:04:40 -0700 Subject: [PATCH 3/3] [POC/FIXME] Add erc-message shortcuts to erc-pcomplete * lisp/erc/erc-pcomplete.el (pcomplete/erc-mode/MSG): Intercept a "." or a "," shortcut and possibly expand it in place, almost like an abbrev, to a target stored in `erc-server-last-peers'. This should probably be done elsewhere, such as during initial command-line parsing. Someone familiar with pcomplete please help! --- lisp/erc/erc-pcomplete.el | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lisp/erc/erc-pcomplete.el b/lisp/erc/erc-pcomplete.el index af8528dbc3..be733f17e9 100644 --- a/lisp/erc/erc-pcomplete.el +++ b/lisp/erc/erc-pcomplete.el @@ -144,6 +144,12 @@ pcomplete/erc-mode/SAY (while (pcomplete-here (pcomplete-erc-nicks)))) (defun pcomplete/erc-mode/MSG () + (when-let* (((= 1 pcomplete-index pcomplete-last)) + (a (pcomplete-arg 1 1)) + ((member a '("." ","))) + (s (erc--message-shortcut a))) + (with-silent-modifications (delete-char -1)) + (pcomplete-here (list s) "")) (pcomplete-here (append (pcomplete-erc-all-nicks) (pcomplete-erc-channels))) (while (pcomplete-here (pcomplete-erc-nicks)))) @@ -152,6 +158,7 @@ pcomplete/erc-mode/NAMES (while (pcomplete-here (pcomplete-erc-channels)))) (defalias 'pcomplete/erc-mode/NOTICE #'pcomplete/erc-mode/MSG) +(defalias 'pcomplete/erc-mode/M #'pcomplete/erc-mode/MSG) (defun pcomplete/erc-mode/OP () (while (pcomplete-here (pcomplete-erc-not-ops)))) -- 2.36.1 --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Tue Jul 12 04:11:13 2022 Received: (at 56449) by debbugs.gnu.org; 12 Jul 2022 08:11:13 +0000 Received: from localhost ([127.0.0.1]:41576 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oBAzB-00060i-4Q for submit@debbugs.gnu.org; Tue, 12 Jul 2022 04:11:13 -0400 Received: from mail-108-mta104.mxroute.com ([136.175.108.104]:34055) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oBAz9-00060U-3C for 56449@debbugs.gnu.org; Tue, 12 Jul 2022 04:11:11 -0400 Received: from filter006.mxroute.com ([140.82.40.27] filter006.mxroute.com) (Authenticated sender: mN4UYu2MZsgR) by mail-108-mta104.mxroute.com (ZoneMTA) with ESMTPSA id 181f176275d0000261.001 for <56449@debbugs.gnu.org> (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256); Tue, 12 Jul 2022 08:11:01 +0000 X-Zone-Loop: 6d27f9976d3086cb85f5c491011c0d5151d413af0b69 X-Originating-IP: [140.82.40.27] 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:In-Reply-To:Date:References: 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=nrvKmqVP0sxeiFCCbT9djC/MQsqN8Oaj10tbIB8TX8Y=; b=DbpbkHS65Q1vVEthhkhzY3mtyF Tl56a340dTvRAM+vEQa3YfkpinldPVwEZkPJ8WzcxQUdhZPiZVeC8nRL6upqPArHp/4X+snQXWBbM hlylwnXQKYQ1xtrNRpP/vg4HXBdXBGLg43Jr9Pi5GzbAlwP8pVBIkAHYAurVGSkT8v7SpbPBgtiQb N/FiuHyoBbzyd3N1uEd7Vjb6aDsFMJ/IOk8l7+6HzjX1nFDshTuIX3HfI3qjgeg8wzBGEGDXaiWMU d/ppHQF7TuCtsDU1qAeJkOJP3iSwPpexGQwVNuu32YlIGL2NTowQE7djaeMq2APdacPEllDPcuLZd FQ7VeKEQ==; From: "J.P." To: 56449@debbugs.gnu.org Subject: Re: bug#56449: 29.0.50; Revisit target shortcuts in erc-message References: <87mtdj68py.fsf@neverwas.me> Date: Tue, 12 Jul 2022 01:10:58 -0700 In-Reply-To: <87mtdj68py.fsf@neverwas.me> (J. P.'s message of "Fri, 08 Jul 2022 06:21:29 -0700") Message-ID: <87r12qbvjh.fsf@neverwas.me> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-AuthUser: masked@neverwas.me X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 56449 Cc: emacs-erc@gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain "J.P." writes: > IOW, issuing a > > ERC> /MSG , hi > > recalls the last nick to speak over a given connection. And > > ERC> /MSG . hi > > reuses the target (channel or query) from the last `erc-message' > invocation Actually, thinking on this a bit has revealed that these two state items (last received vs. last sent) may be less symmetrical than originally believed in terms of use case and function: the "." form always expands to a substring of something already typed, IOW "previous input", while the "," form may well produce something novel. So, if the dot form is more akin to everyday command-history recall, then ERC may have an easier time providing a useful substitute by improving upon its existing offering, namely, erc-ring. Indeed, adopting in-house variants of the more powerful history-traversing commands seen elsewhere in Emacs, such as `previous-complete-history-element' and (in some sense) `previous-matching-history-element', wouldn't be the worst call (IMO). > For now, I propose temporarily adopting (1) by confining shared values > to server buffers. ... and stopping there rather than further complicating the situation for little perceived gain, convenience wise, by fiddling with imperfect alternatives to niche features. As for the comma form, in case the above wasn't clear, I'm in favor of dialing things back and shelving the notion of enhanced recipient recall. (In the future, we could conceivably retrieve candidates by searching backward through text-properties to gather the most recent speakers in a target buffer. These could be presented via completing read, perhaps anchored by a transient to offer unified access to various scopes, like buffer, network, etc.) For the sake of completeness, I have attached the surviving changes, minor as they are, and will be adding them or similar to ERC by week's end unless anyone has additional insights. Thanks. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Avoid-mutating-default-value-of-erc-server-last-peer.patch >From 9e0a581227ea94d97833056d8735b280ed753e52 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Wed, 6 Jul 2022 00:40:42 -0700 Subject: [PATCH] Avoid mutating default value of erc-server-last-peers * lisp/erc/erc-backend.el (erc-server-last-peers): Leave default as nil instead of a quoted constant. (erc-server-connect): Initialize `erc-server-last-peers' to a new value local to a server buffer. (erc-message): Operate on server's local `erc-server-last-peers' value instead of the global default. Prefer replacing value instead of mutating CDR to make for easier testing. (erc-server-PRIVMSG): Create a new `erc-server-last-peers' instead of mutating to make for easier testing. --- lisp/erc/erc-backend.el | 23 +++++------ test/lisp/erc/erc-tests.el | 82 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 12 deletions(-) diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index bc7a7d14dc..5af63e976c 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -230,7 +230,7 @@ erc-server-error-occurred (defvar-local erc-server-lines-sent nil "Line counter.") -(defvar-local erc-server-last-peers '(nil . nil) +(defvar-local erc-server-last-peers nil "Last peers used, both sender and receiver. Those are used for /MSG destination shortcuts.") @@ -562,7 +562,7 @@ erc-server-connect (setq erc-server-last-received-time time)) (setq erc-server-lines-sent 0) ;; last peers (sender and receiver) - (setq erc-server-last-peers '(nil . nil))) + (setq erc-server-last-peers (cons nil nil))) ;; we do our own encoding and decoding (when (fboundp 'set-process-coding-system) (set-process-coding-system process 'raw-text)) @@ -939,21 +939,20 @@ erc-message to will be used." (cond ((string-match "^\\s-*\\(\\S-+\\) ?\\(.*\\)" line) - (let ((tgt (match-string 1 line)) - (s (match-string 2 line))) + (let* ((tgt (match-string 1 line)) + (s (match-string 2 line)) + (server-buffer (erc-server-buffer)) + (peers (buffer-local-value 'erc-server-last-peers server-buffer))) (erc-log (format "cmd: MSG(%s): [%s] %s" message-command tgt s)) (cond ((string= tgt ",") - (if (car erc-server-last-peers) - (setq tgt (car erc-server-last-peers)) - (setq tgt nil))) + (setq tgt (car peers))) ((string= tgt ".") - (if (cdr erc-server-last-peers) - (setq tgt (cdr erc-server-last-peers)) - (setq tgt nil)))) + (setq tgt (cdr peers)))) (cond (tgt - (setcdr erc-server-last-peers tgt) + (with-current-buffer server-buffer + (setq erc-server-last-peers (cons (car peers) tgt))) (erc-server-send (format "%s %s :%s" message-command tgt s) force)) (t @@ -1550,7 +1549,7 @@ define-erc-response-handler (erc-process-ctcp-reply proc parsed nick login host (match-string 1 msg))))) (t - (setcar erc-server-last-peers nick) + (setq erc-server-last-peers (cons nick (cdr erc-server-last-peers))) (setq s (erc-format-privmessage (or fnick nick) msg ;; If buffer is a query buffer, diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 4971d0e194..0f222edacf 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -893,4 +893,86 @@ erc-process-input-line (should-not calls)))))) +;; Note: if adding an erc-backend-tests.el, please relocate this there. + +(ert-deftest erc-message () + (should-not erc-server-last-peers) + (let (server-proc + calls + erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook) + (cl-letf (((symbol-function 'erc-display-message) + (lambda (_ _ _ line) (push line calls))) + ((symbol-function 'erc-server-send) + (lambda (line _) (push line calls))) + ((symbol-function 'erc-server-buffer) + (lambda () (process-buffer server-proc)))) + (with-current-buffer (get-buffer-create "ExampleNet") + (erc-mode) + (setq erc-server-current-nick "tester" + server-proc (start-process "sleep" (current-buffer) "sleep" "1") + erc-server-process server-proc + erc-server-last-peers (cons nil nil) + erc-server-users (make-hash-table :test 'equal) + erc-network 'ExampleNet) + (set-process-query-on-exit-flag erc-server-process nil)) + + (with-current-buffer (get-buffer-create "#chan") + (erc-mode) + (setq erc-server-process (buffer-local-value 'erc-server-process + (get-buffer "ExampleNet")) + erc-default-recipients '("#chan") + erc-channel-users (make-hash-table :test 'equal) + erc-network 'ExampleNet) + (erc-update-current-channel-member "alice" "alice") + (erc-update-current-channel-member "tester" "tester")) + + (with-current-buffer "ExampleNet" + (erc-server-PRIVMSG erc-server-process + (make-erc-response + :sender "alice!~u@fsf.org" + :command "PRIVMSG" + :command-args '("#chan" "hi") + :unparsed ":alice!~u@fsf.org PRIVMSG #chan :hi")) + (should (equal erc-server-last-peers '("alice"))) + (should (string-match "" (pop calls)))) + + (with-current-buffer "#chan" + (ert-info ("Shortcuts usable in target buffers") + (should-not (local-variable-p 'erc-server-last-peers)) + (should-not erc-server-last-peers) + (erc-message "PRIVMSG" ". hi") + (should-not erc-server-last-peers) + (should (eq 'no-target (pop calls))) + (erc-message "PRIVMSG" ", hi") + (should-not erc-server-last-peers) + (should (string-match "alice :hi" (pop calls))))) + + (with-current-buffer "ExampleNet" + (ert-info ("Shortcuts local in server bufs") + (should (equal erc-server-last-peers '("alice" . "alice"))) + (erc-message "PRIVMSG" ", hi") + (should (equal erc-server-last-peers '("alice" . "alice"))) + (should (string-match "PRIVMSG alice :hi" (pop calls))) + (setcdr erc-server-last-peers "bob") + (erc-message "PRIVMSG" ". hi") + (should (equal erc-server-last-peers '("alice" . "bob"))) + (should (string-match "PRIVMSG bob :hi" (pop calls))))) + + (with-current-buffer "#chan" + (ert-info ("Non-shortcuts are local to server buffer") + (should-not (local-variable-p 'erc-server-last-peers)) + (should-not erc-server-last-peers) + (erc-message "PRIVMSG" "#chan hola") + (should-not erc-server-last-peers) + (should-not (default-value 'erc-server-last-peers)) + (should (equal (buffer-local-value 'erc-server-last-peers + (get-buffer "ExampleNet")) + '("alice" . "#chan"))) + (should (string-match "hola" (pop calls)))))) + + (should-not erc-server-last-peers) + (should-not calls) + (kill-buffer "ExampleNet") + (kill-buffer "#chan"))) + ;;; erc-tests.el ends here -- 2.36.1 --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Wed Jul 27 08:54:26 2022 Received: (at control) by debbugs.gnu.org; 27 Jul 2022 12:54:26 +0000 Received: from localhost ([127.0.0.1]:55334 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oGgYU-0000XO-4W for submit@debbugs.gnu.org; Wed, 27 Jul 2022 08:54:26 -0400 Received: from mail-108-mta202.mxroute.com ([136.175.108.202]:44391) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oGgYQ-0000X6-DM for control@debbugs.gnu.org; Wed, 27 Jul 2022 08:54:25 -0400 Received: from filter006.mxroute.com ([140.82.40.27] filter006.mxroute.com) (Authenticated sender: mN4UYu2MZsgR) by mail-108-mta202.mxroute.com (ZoneMTA) with ESMTPSA id 1823fb8d19d0000261.001 for (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256); Wed, 27 Jul 2022 12:54:13 +0000 X-Zone-Loop: 6f48583bf6aa9c4da29e66522126f24e9359c8e88ba6 X-Originating-IP: [140.82.40.27] 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:Subject:To:From:Sender: Reply-To:Cc:Content-Transfer-Encoding:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=hoY0yBU+Kk+tmWQP5YGwPrN6zPSDkvnZX6cvKjmKLCw=; b=CrJZPXgTCA9rZSZPbfCkzG9c6L Mj91i17QJ2dhK9HPb++Mn+cPzgAR9at6MZ8iFmUjISJVhNJQ/8rngNsF94bvZl1jQi/Z5lEKChGwW IIcT4ceI9Kk1WePQHr9rlejvjK89W8SntibpoyHQwlZItkXw8dDPRpJSLMDNMn2yJml9JjgVpOJ1K 1dpwh/n58ZHcAQ/FqtEmVYVHl3y/ma+7Mf4ofeuNtANi2UVpysMf6ov3+VDvfHIVSL0EhjJe79xc7 mkWMvf+/wkn9kqdpnZ2lFwfWcfucv71lS/6+J9//vd6ygHN/2J+agNOj46G9qZRl5aDAnAejW8Ymk llj+70AA==; From: "J.P." To: control@debbugs.gnu.org Subject: control message for bug #56449 Date: Wed, 27 Jul 2022 05:54:09 -0700 Message-ID: <87h732d8cu.fsf@neverwas.me> MIME-Version: 1.0 Content-Type: text/plain X-AuthUser: masked@neverwas.me X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) close 56449 29.1 quit From unknown Fri Sep 05 08:21:47 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Thu, 25 Aug 2022 11:24:07 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator