Subject: bug#56340: 29.0.50; [PATCH] Don't ask people to order requires.

From: [email-masked]
Date: Fri, 01 Jul 2022 11:23:30 -0400

>From 2a5b0e418d8182378929e902fb35cf53f25de94d Mon Sep 17 00:00:00 2001
From: dickmao <[email-masked]>
Date: Fri, 1 Jul 2022 11:06:51 -0400
Subject: [PATCH] Don't do this.

Asking people to order require's is about as effective
as asking kids to keep off the grass.

* lisp/erc/erc-backend.el (erc-networks--id, erc-reuse-buffers,
erc-kill-server-buffer-on-quit, erc-insert-marker, erc-input-marker,
erc-hide-prompt, erc-default-recipients, erc-prompt-hidden,
erc-channel-users, erc-invitation, erc-nick-change-attempt-count,
erc--target, erc-nick, erc-default-nicks, erc-kill-buffer-on-part,
erc-verbose-server-ping, erc-minibuffer-ignored, erc-auto-query,
erc-join-buffer, erc-format-nick-function,
erc-format-query-as-channel-p, erc-channel-list,
erc-whowas-on-nosuchnick, erc-prompt-for-channel-key,
erc-active-buffer, erc-session-password, erc-format-message,
erc-networks--id-given, erc-open, erc-set-active-buffer,
erc-update-mode-line, erc-server-buffer, erc-log-irc-protocol,
define-erc-module, erc-with-all-buffers-of-server, erc-default-target,
erc-buffer-filter, erc-login, erc-with-server-buffer,
erc-emacs-time-to-erc-time, erc-display-message, erc-get-buffer,
erc-with-buffer, erc-current-nick, erc-channel-begin-receiving-names,
erc-add-default-channel, erc--open-target, erc-current-nick-p,
erc-parse-user, erc-delete-default-channel, erc-remove-channel-users,
erc-remove-channel-member, erc-trim-string, erc-channel-p, erc-log,
erc-handle-user-status-change, erc-networks--id-reload, erc-network,
erc-set-current-nick, erc-update-user-nick, erc-get-buffer-create,
erc--target-from-string, erc-buffer-list-with-nick,
erc-banlist-update, erc-update-modes, erc-time-diff, erc-current-time,
erc-query-buffer-p, erc-format-privmessage, erc-process-ctcp-reply,
erc-is-message-ctcp-and-not-action-p, erc-ignored-reply-p,
erc-ignored-user-p, erc-process-ctcp-query, erc-is-message-ctcp-p,
erc-get-channel-user, erc-update-channel-member, erc-make-notice,
erc-wash-quit-reason, erc-remove-user, erc-handle-login,
erc-connection-established, erc-update-mode-line-buffer,
erc-set-modes, erc-display-server-message,
erc-process-away, erc-sec-to-time, erc-update-channel-topic,
erc-channel-receive-names, erc-channel-end-receiving-names,
erc-nickname-in-use, erc-cmd-JOIN, erc-display-error-notice):
Forward declares and macro repositioning.
(erc--with-memoization):
Defalias was a kung-fu I've never seen before.
* lisp/erc/erc-goodies.el (erc, erc-backend, erc--target,
erc-reuse-buffers, erc-rename-buffers, erc-input-marker,
erc-insert-marker, erc-kill-server-hook, erc-kill-buffer-hook,
erc-modules, erc-controls-highlight-regexp,
erc-controls-remove-regexp, erc-beg-of-input-line,
erc-extract-command-from-line, erc-input-string,
erc-send-distinguish-noncommands, erc-log, erc-error,
erc-buffer-list): Forward declares and macro repositioning.
* lisp/erc/erc-networks.el (erc, erc-backend, erc--target,
erc-reuse-buffers, erc-rename-buffers, erc-insert-marker,
erc-kill-server-hook, erc-kill-buffer-hook, erc-modules,
erc-obsolete-var, erc--target-channel-local-p, erc--target-symbol,
erc--target-string, erc--default-target, erc-buffer-filter,
erc-downcase, erc-current-nick, erc-server-buffer, erc-error,
erc-display-error-notice, erc-get-buffer, erc-set-active-buffer):
Forward declares and macro repositioning.
* lisp/erc/erc.el (erc-networks, erc-goodies, erc-session-password,
erc-with-server-buffer, define-erc-module):
* test/lisp/erc/erc-networks-tests.el (erc-networks, erc):
Defalias was a kung-fu I've never seen before.
---
 lisp/erc/erc-backend.el             | 246 ++++++++++++++++++++++++++--
 lisp/erc/erc-goodies.el             |  23 ++-
 lisp/erc/erc-networks.el            |  23 ++-
 lisp/erc/erc.el                     | 139 +---------------
 test/lisp/erc/erc-networks-tests.el |   2 +-
 5 files changed, 277 insertions(+), 156 deletions(-)

diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el
index bee2551d76e..a550ddaaad2 100644
--- a/lisp/erc/erc-backend.el
+++ b/lisp/erc/erc-backend.el
@@ -99,13 +99,40 @@
 ;;; Code:
 
 (eval-when-compile (require 'cl-lib))
-;; There's a fairly strong mutual dependency between erc.el and erc-backend.el.
-;; Luckily, erc.el does not need erc-backend.el for macroexpansion whereas the
-;; reverse is true:
-(require 'erc)
+(require 'subr-x)
 
 ;;;; Variables and options
 
+(defvar erc-networks--id)
+(defvar erc-reuse-buffers)
+(defvar erc-kill-server-buffer-on-quit)
+(defvar erc-insert-marker)
+(defvar erc-input-marker)
+(defvar erc-hide-prompt)
+(defvar erc-default-recipients)
+(defvar erc-prompt-hidden)
+(defvar erc-channel-users)
+(defvar erc-invitation)
+(defvar erc-default-recipients)
+(defvar erc-nick-change-attempt-count)
+(defvar erc--target)
+(defvar erc-nick)
+(defvar erc-default-nicks)
+(defvar erc-kill-buffer-on-part)
+(defvar erc-verbose-server-ping)
+(defvar erc-minibuffer-ignored)
+(defvar erc-auto-query)
+(defvar erc-join-buffer)
+(defvar erc-format-nick-function)
+(defvar erc-format-query-as-channel-p)
+(defvar erc-channel-list)
+(defvar erc-whowas-on-nosuchnick)
+(defvar erc-prompt-for-channel-key)
+(defvar erc-active-buffer)
+
+(defvar-local erc-session-password nil
+  "The password used for the current session.")
+
 (defvar erc-server-responses (make-hash-table :test #'equal)
   "Hash table mapping server responses to their handler hooks.")
 
@@ -532,6 +559,7 @@ erc-open-network-stream
   (let ((p (plist-put parameters :nowait t)))
     (apply #'open-network-stream name buffer host service p)))
 
+(declare-function erc-format-message "erc")
 (defun erc-server-connect (server port buffer &optional client-certificate)
   "Perform the connection and login using the specified SERVER and PORT.
 We will store server variables in the buffer given by BUFFER.
@@ -582,6 +610,11 @@ erc-server-connect
       (message "%s...done" msg)
       (erc-login)) ))
 
+(declare-function erc-networks--id-given "erc")
+(declare-function erc-open "erc")
+(declare-function erc-set-active-buffer "erc")
+(declare-function erc-update-mode-line "erc")
+(declare-function erc-server-buffer "erc")
 (defun erc-server-reconnect ()
   "Reestablish the current IRC connection.
 Make sure you are in an ERC buffer when running this."
@@ -611,6 +644,7 @@ erc-server-delayed-reconnect
     (with-current-buffer buffer
       (erc-server-reconnect))))
 
+(declare-function erc-log-irc-protocol "erc")
 (defun erc-server-filter-function (process string)
   "The process filter for the ERC server."
   (with-current-buffer (process-buffer process)
@@ -728,6 +762,89 @@ erc--unhide-prompt-on-self-insert
              (or (eobp) (= (point) erc-input-marker)))
     (erc--unhide-prompt)))
 
+(defmacro define-erc-module (name alias doc enable-body disable-body
+                                  &optional local-p)
+  "Define a new minor mode using ERC conventions.
+Symbol NAME is the name of the module.
+Symbol ALIAS is the alias to use, or nil.
+DOC is the documentation string to use for the minor mode.
+ENABLE-BODY is a list of expressions used to enable the mode.
+DISABLE-BODY is a list of expressions used to disable the mode.
+If LOCAL-P is non-nil, the mode will be created as a buffer-local
+mode, rather than a global one.
+
+This will define a minor mode called erc-NAME-mode, possibly
+an alias erc-ALIAS-mode, as well as the helper functions
+erc-NAME-enable, and erc-NAME-disable.
+
+Example:
+
+  ;;;###autoload(autoload \\='erc-replace-mode \"erc-replace\")
+  (define-erc-module replace nil
+    \"This mode replaces incoming text according to `erc-replace-alist'.\"
+    ((add-hook \\='erc-insert-modify-hook
+               #\\='erc-replace-insert))
+    ((remove-hook \\='erc-insert-modify-hook
+                  #\\='erc-replace-insert)))"
+  (declare (doc-string 3) (indent defun))
+  (let* ((sn (symbol-name name))
+         (mode (intern (format "erc-%s-mode" (downcase sn))))
+         (group (intern (format "erc-%s" (downcase sn))))
+         (enable (intern (format "erc-%s-enable" (downcase sn))))
+         (disable (intern (format "erc-%s-disable" (downcase sn)))))
+    `(progn
+       (define-minor-mode
+        ,mode
+        ,(format "Toggle ERC %S mode.
+With a prefix argument ARG, enable %s if ARG is positive,
+and disable it otherwise.  If called from Lisp, enable the mode
+if ARG is omitted or nil.
+%s" name name doc)
+        ;; FIXME: We don't know if this group exists, so this `:group' may
+        ;; actually just silence a valid warning about the fact that the var
+        ;; is not associated with any group.
+        :global ,(not local-p) :group (quote ,group)
+        (if ,mode
+            (,enable)
+          (,disable)))
+       (defun ,enable ()
+         ,(format "Enable ERC %S mode."
+                  name)
+         (interactive)
+         (add-to-list 'erc-modules (quote ,name))
+         (setq ,mode t)
+         ,@enable-body)
+       (defun ,disable ()
+         ,(format "Disable ERC %S mode."
+                  name)
+         (interactive)
+         (setq erc-modules (delq (quote ,name) erc-modules))
+         (setq ,mode nil)
+         ,@disable-body)
+       ,(when (and alias (not (eq name alias)))
+          `(defalias
+             ',(intern
+                (format "erc-%s-mode"
+                        (downcase (symbol-name alias))))
+             #',mode))
+       ;; For find-function and find-variable.
+       (put ',mode    'definition-name ',name)
+       (put ',enable  'definition-name ',name)
+       (put ',disable 'definition-name ',name))))
+
+(defmacro erc-with-all-buffers-of-server (process pred &rest forms)
+  "Execute FORMS in all buffers which have same process as this server.
+FORMS will be evaluated in all buffers having the process PROCESS and
+where PRED matches or in all buffers of the server process if PRED is
+nil."
+  (declare (indent 1) (debug (form form body)))
+  (macroexp-let2 nil pred pred
+    `(erc-buffer-filter (lambda ()
+                          (when (or (not ,pred) (funcall ,pred))
+                            ,@forms))
+                        ,process)))
+
+(declare-function erc-default-target "erc")
 (defun erc--hide-prompt (proc)
   (erc-with-all-buffers-of-server
       proc nil ; sorta wish this was indent 2
@@ -748,6 +865,8 @@ erc--hide-prompt
                                `(display ,erc-prompt-hidden)))
         (add-hook 'pre-command-hook #'erc--unhide-prompt-on-self-insert 0 t))))
 
+(declare-function erc-buffer-filter "erc")
+(declare-function erc-login "erc")
 (defun erc-process-sentinel (cproc event)
   "Sentinel function for ERC process."
   (let ((buf (process-buffer cproc)))
@@ -821,6 +940,17 @@ erc-send-line
           (funcall display-fn))
         (erc-split-line text)))
 
+(declare-function erc-server-buffer "erc")
+(defmacro erc-with-server-buffer (&rest body)
+  "Execute BODY in the current ERC server buffer.
+If no server buffer exists, return nil."
+  (declare (indent 0) (debug (body)))
+  (let ((buffer (make-symbol "buffer")))
+    `(let ((,buffer (erc-server-buffer)))
+       (when (buffer-live-p ,buffer)
+         (with-current-buffer ,buffer
+           ,@body)))))
+
 ;; From Circe, with modifications
 (defun erc-server-send (string &optional force target)
   "Send STRING to the current server.
@@ -890,6 +1020,7 @@ erc-server-send-ping
         (setcdr timer nil)))))
 
 ;; From Circe
+(declare-function erc-emacs-time-to-erc-time "erc")
 (defun erc-server-send-queue (buffer)
   "Send messages in `erc-server-flood-queue'.
 See `erc-server-flood-margin' for an explanation of the flood
@@ -931,6 +1062,7 @@ erc-server-send-queue
                 (run-at-time (+ 0.2 erc-server-flood-penalty)
                              nil #'erc-server-send-queue buffer)))))))
 
+(declare-function erc-display-message "erc")
 (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\".
@@ -1147,6 +1279,40 @@ erc-handle-unknown-server-response
                                  " "))))
     (erc-display-message parsed 'notice proc line)))
 
+(declare-function erc-get-buffer "erc")
+(defmacro erc-with-buffer (spec &rest body)
+  "Execute BODY in the buffer associated with SPEC.
+
+SPEC should have the form
+
+ (TARGET [PROCESS])
+
+If TARGET is a buffer, use it.  Otherwise, use the buffer
+matching TARGET in the process specified by PROCESS.
+
+If PROCESS is nil, use the current `erc-server-process'.
+See `erc-get-buffer' for details.
+
+See also `with-current-buffer'.
+
+\(fn (TARGET [PROCESS]) BODY...)"
+  (declare (indent 1) (debug ((form &optional form) body)))
+  (let ((buf (make-symbol "buf"))
+        (proc (make-symbol "proc"))
+        (target (make-symbol "target"))
+        (process (make-symbol "process")))
+    `(let* ((,target ,(car spec))
+            (,process ,(cadr spec))
+            (,buf (if (bufferp ,target)
+                      ,target
+                    (let ((,proc (or ,process
+                                     (and (processp erc-server-process)
+                                          erc-server-process))))
+                      (if (and ,target ,proc)
+                          (erc-get-buffer ,target ,proc))))))
+       (when (buffer-live-p ,buf)
+         (with-current-buffer ,buf
+           ,@body)))))
 
 (cl-defmacro define-erc-response-handler ((name &rest aliases)
                                           &optional extra-fn-doc extra-var-doc
@@ -1307,6 +1473,7 @@ define-erc-response-handler
    parsed 'error nil 'ERROR
    ?s (erc-response.sender parsed) ?c (erc-response.contents parsed)))
 
+(declare-function erc-current-nick "erc")
 (define-erc-response-handler (INVITE)
   "Handle invitation messages."
   nil
@@ -1320,6 +1487,11 @@ define-erc-response-handler
          parsed 'notice 'active
          'INVITE ?n nick ?u login ?h host ?c chnl)))))
 
+(declare-function erc-channel-begin-receiving-names "erc")
+(declare-function erc-add-default-channel "erc")
+(declare-function erc--open-target "erc")
+(declare-function erc-current-nick-p "erc")
+(declare-function erc-parse-user "erc")
 (define-erc-response-handler (JOIN)
   "Handle join messages."
   nil
@@ -1357,6 +1529,10 @@ define-erc-response-handler
           ;;(set-buffer ob)
           (erc-display-message parsed nil buffer str))))))
 
+(declare-function erc-delete-default-channel "erc")
+(declare-function erc-remove-channel-users "erc")
+(declare-function erc-remove-channel-member "erc")
+(declare-function erc-trim-string "erc")
 (define-erc-response-handler (KICK)
   "Handle kick messages received from the server." nil
   (let* ((ch (nth 0 (erc-response.command-args parsed)))
@@ -1386,6 +1562,9 @@ define-erc-response-handler
              parsed 'notice buffer
              'KICK ?k tgt ?n nick ?u login ?h host ?c ch ?r reason))))))
 
+(declare-function erc-active-buffer "erc")
+(declare-function erc-channel-p "erc")
+(declare-function erc-log "erc")
 (define-erc-response-handler (MODE)
   "Handle server mode changes." nil
   (let ((tgt (car (erc-response.command-args parsed)))
@@ -1412,6 +1591,16 @@ define-erc-response-handler
                                  ?h host ?t tgt ?m mode)))
       (erc-banlist-update proc parsed))))
 
+(declare-function erc-handle-user-status-change "erc")
+(declare-function erc-networks--id-reload "erc-networks")
+(declare-function erc-network "erc-networks")
+(declare-function erc-set-current-nick "erc")
+(declare-function erc-update-user-nick "erc")
+(declare-function erc-get-buffer-create "erc")
+(declare-function erc--target-from-string "erc")
+(declare-function erc-buffer-list-with-nick "erc")
+(declare-function erc-banlist-update "erc")
+(declare-function erc-update-modes "erc")
 (define-erc-response-handler (NICK)
   "Handle nick change messages." nil
   (let ((nn (erc-response.contents parsed))
@@ -1479,6 +1668,8 @@ define-erc-response-handler
         (when erc-kill-buffer-on-part
           (kill-buffer buffer))))))
 
+(declare-function erc-time-diff "erc")
+(declare-function erc-current-time "erc")
 (define-erc-response-handler (PING)
   "Handle ping messages." nil
   (let ((pinger (car (erc-response.command-args parsed))))
@@ -1503,6 +1694,17 @@ define-erc-response-handler
          ?s (if (/= erc-server-lag 1) "s" "")))
       (erc-update-mode-line))))
 
+(declare-function erc-query-buffer-p "erc")
+(declare-function erc-format-privmessage "erc")
+(declare-function erc-process-ctcp-reply "erc")
+(declare-function erc-is-message-ctcp-and-not-action-p "erc")
+(declare-function erc-ignored-reply-p "erc")
+(declare-function erc-ignored-user-p "erc")
+(declare-function erc-process-ctcp-query "erc")
+(declare-function erc-is-message-ctcp-p "erc")
+(declare-function erc-get-channel-user "erc")
+(declare-function erc-update-channel-member "erc")
+(declare-function erc-make-notice "erc")
 (define-erc-response-handler (PRIVMSG NOTICE)
   "Handle private messages, including messages in channels." nil
   (let ((sender-spec (erc-response.sender parsed))
@@ -1569,6 +1771,8 @@ define-erc-response-handler
                  'erc-echo-notice-hook s parsed buffer nick))
             (erc-display-message parsed nil buffer s)))))))
 
+(declare-function erc-wash-quit-reason "erc")
+(declare-function erc-remove-user "erc")
 (define-erc-response-handler (QUIT)
   "Another user has quit IRC." nil
   (let ((reason (erc-response.contents parsed))
@@ -1615,6 +1819,7 @@ define-erc-response-handler
   (erc-display-message
    parsed 'notice 'active (erc-response.contents parsed)))
 
+(declare-function erc-handle-login "erc")
 (define-erc-response-handler (MOTD 002 003 371 372 374 375)
   "Display the server's message of the day." nil
   (erc-handle-login)
@@ -1622,11 +1827,13 @@ define-erc-response-handler
    parsed 'notice (if erc-server-connected 'active proc)
    (erc-response.contents parsed)))
 
+(declare-function erc-connection-established "erc")
 (define-erc-response-handler (376 422)
   "End of MOTD/MOTD is missing." nil
   (erc-server-MOTD proc parsed)
   (erc-connection-established proc parsed))
 
+(declare-function erc-update-mode-line-buffer "erc")
 (define-erc-response-handler (004)
   "Display the server's identification." nil
   (pcase-let ((`(,server-name ,server-version)
@@ -1673,12 +1880,15 @@ erc--parse-isupport-value
          (split-string value ",")
        (list value)))))
 
-;; FIXME move to erc-compat (once we decide how to load it)
-(defalias 'erc--with-memoization
-  (cond
-   ((fboundp 'with-memoization) #'with-memoization) ; 29.1
-   ((fboundp 'cl--generic-with-memoization) #'cl--generic-with-memoization)
-   (t (lambda (_ v) v))))
+(defmacro erc--with-memoization (table &rest forms)
+  "Adapter to be migrated to erc-compat."
+  (declare (indent defun))
+  `(cond
+    ((fboundp 'with-memoization)
+     (with-memoization ,table ,@forms)) ; 29.1
+    ((fboundp 'cl--generic-with-memoization)
+     (cl--generic-with-memoization ,table ,@forms))
+    (t ,@forms)))
 
 (defun erc--get-isupport-entry (key &optional single)
   "Return an item for \"ISUPPORT\" token KEY, a symbol.
@@ -1732,6 +1942,7 @@ erc--get-isupport-entry
     (erc-display-message parsed 'notice proc line)
     nil))
 
+(declare-function erc-set-modes "erc")
 (define-erc-response-handler (221)
   "Display the current user modes." nil
   (let* ((nick (car (erc-response.command-args parsed)))
@@ -1755,6 +1966,7 @@ erc--get-isupport-entry
   (erc-display-message parsed 'notice 'active 's254
                        ?i (cadr (erc-response.command-args parsed))))
 
+(declare-function erc-display-server-message "erc")
 (define-erc-response-handler (250 251 255 256 257 258 259 265 266 377 378)
   "Generic display of server messages as notices.
 
@@ -1785,6 +1997,7 @@ erc--get-isupport-entry
   (erc-display-message parsed 'notice 'active 's303
                        ?n (cadr (erc-response.command-args parsed))))
 
+(declare-function erc-process-away "erc")
 (define-erc-response-handler (305)
   "Return from AWAYness." nil
   (erc-process-away proc nil)
@@ -1840,6 +2053,7 @@ erc--get-isupport-entry
   "End of WHO/WHOIS/LIST/WHOWAS notices." nil
   (ignore proc parsed))
 
+(declare-function erc-sec-to-time "erc")
 (define-erc-response-handler (317)
   "IDLE notice." nil
   (pcase-let ((`(,nick ,seconds-idle ,on-since ,time)
@@ -1880,6 +2094,7 @@ erc-server-321-message
   nil)
 (add-hook 'erc-server-321-functions #'erc-server-321-message t)
 
+(declare-function erc-update-channel-topic "erc")
 (define-erc-response-handler (322)
   "LIST notice." nil
   (let ((topic (erc-response.contents parsed)))
@@ -1987,6 +2202,7 @@ erc-server-322-message
                            ?c channel ?n nick ?a away-flag
                            ?u user ?h host ?f full-name))))
 
+(declare-function erc-channel-receive-names "erc")
 (define-erc-response-handler (353)
   "NAMES notice." nil
   (let ((channel (nth 2 (erc-response.command-args parsed)))
@@ -1997,6 +2213,7 @@ erc-server-322-message
     (erc-with-buffer (channel proc)
       (erc-channel-receive-names users))))
 
+(declare-function erc-channel-end-receiving-names "erc")
 (define-erc-response-handler (366)
   "End of NAMES." nil
   (erc-with-buffer ((cadr (erc-response.command-args parsed)) proc)
@@ -2084,10 +2301,11 @@ erc-server-322-message
   (erc-display-message parsed '(notice error) 'active 's432
                        ?n (cadr (erc-response.command-args parsed))))
 
+(declare-function erc-nickname-in-use "erc")
 (define-erc-response-handler (433)
-  "Login-time \"nick in use\"." nil
-  (erc-nickname-in-use (cadr (erc-response.command-args parsed))
-                       "already in use"))
+                             "Login-time \"nick in use\"." nil
+                             (erc-nickname-in-use (cadr (erc-response.command-args parsed))
+                                                  "already in use"))
 
 (define-erc-response-handler (437)
   "Nick temporarily unavailable (on IRCnet)." nil
@@ -2121,6 +2339,7 @@ erc-server-322-message
                                        (erc-response.command parsed)))
                        ?c (cadr (erc-response.command-args parsed))))
 
+(declare-function erc-cmd-JOIN "erc")
 (define-erc-response-handler (475)
   "Channel key needed." nil
   (erc-display-message parsed '(notice error) nil 's475
@@ -2154,6 +2373,7 @@ erc-server-322-message
     (erc-display-message parsed 'notice 'active 's671
                          ?n nick ?a securemsg)))
 
+(declare-function erc-display-error-notice "erc")
 (define-erc-response-handler (431 445 446 451 462 463 464 481 483 484 485
                                   491 501 502)
   ;; 431 - No nickname given
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 8fef23945d4..73746bcbaeb 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -29,10 +29,20 @@
 
 ;;; Code:
 
-(require 'erc)
-
 ;;; Imenu support
 
+(require 'erc-backend)
+(defvar erc--target)
+(defvar erc-reuse-buffers)
+(defvar erc-rename-buffers)
+(defvar erc-input-marker)
+(defvar erc-insert-marker)
+(defvar erc-kill-server-hook)
+(defvar erc-kill-buffer-hook)
+(defvar erc-modules)
+(defvar erc-controls-highlight-regexp)
+(defvar erc-controls-remove-regexp)
+
 (defun erc-imenu-setup ()
   "Setup Imenu support in an ERC buffer."
   (setq-local imenu-create-index-function #'erc-create-imenu-index))
@@ -146,6 +156,7 @@ keep-place
   ((add-hook 'erc-insert-pre-hook  #'erc-keep-place))
   ((remove-hook 'erc-insert-pre-hook  #'erc-keep-place)))
 
+(declare-function erc-beg-of-input-line "erc")
 (defun erc-keep-place (_ignored)
   "Move point away from the last line in a non-selected ERC buffer."
   (when (and (not (eq (window-buffer (selected-window))
@@ -186,6 +197,8 @@ noncommands
   ((add-hook 'erc-pre-send-functions #'erc-send-distinguish-noncommands))
   ((remove-hook 'erc-pre-send-functions #'erc-send-distinguish-noncommands)))
 
+(declare-function erc-extract-command-from-line "erc")
+(declare-function erc-input-string "erc")
 (defun erc-send-distinguish-noncommands (state)
   "If STR is an ERC non-command, set `insertp' in STATE to nil."
   (let* ((string (erc-input-string state))
@@ -196,7 +209,8 @@ erc-send-distinguish-noncommands
                (not (string-match "\n.+$" string))
                (memq cmd-fun erc-noncommands-list))
       ;; Inhibit sending this string.
-      (setf (erc-input-insertp state) nil))))
+      (with-no-warnings ;how to declare-function a cl-defmethod?
+        (setf (erc-input-insertp state) nil)))))
 
 ;;; IRC control character processing.
 (defgroup erc-control-characters nil
@@ -339,6 +353,8 @@ bg:erc-color-face15
   "ERC face."
   :group 'erc-faces)
 
+(declare-function erc-log "erc")
+(declare-function erc-error "erc")
 (defun erc-get-bg-color-face (n)
   "Fetches the right face for background color N (0-15)."
   (if (stringp n) (setq n (string-to-number n)))
@@ -582,6 +598,7 @@ erc-unmorse
       (unmorse-region (point-min) (point-max)))))
 
 ;;; erc-occur
+(declare-function erc-buffer-list "erc")
 (defun erc-occur (string &optional proc)
   "Search for STRING in all buffers related to current server.
 If called interactively and prefix argument is given, search on all connected
diff --git a/lisp/erc/erc-networks.el b/lisp/erc/erc-networks.el
index 091b8aa92d7..f1192ea2f16 100644
--- a/lisp/erc/erc-networks.el
+++ b/lisp/erc/erc-networks.el
@@ -39,8 +39,15 @@
 
 ;;; Code:
 
-(require 'erc)
 (eval-when-compile (require 'cl-lib))
+(require 'erc-backend)
+(defvar erc--target)
+(defvar erc-reuse-buffers)
+(defvar erc-rename-buffers)
+(defvar erc-insert-marker)
+(defvar erc-kill-server-hook)
+(defvar erc-kill-buffer-hook)
+(defvar erc-modules)
 
 ;; Variables
 
@@ -813,7 +820,7 @@ erc-networks--id-given
   (erc-networks--id-symbol nid))
 
 (cl-generic-define-context-rewriter erc-obsolete-var (var spec)
-  `((with-suppressed-warnings ((obsolete ,var)) ,var) ,spec))
+  `((with-suppressed-warnings ((obsolete ,var) (free-vars ,var)) ,var) ,spec))
 
 ;; As a catch-all, derive the symbol from the unquoted printed repr.
 (cl-defgeneric erc-networks--id-create (id)
@@ -1089,6 +1096,13 @@ erc-networks-shrink-ids-and-buffer-names
 connection is active."
   (erc-networks--shrink-ids-and-buffer-names))
 
+(declare-function erc--target-channel-local-p "erc")
+(declare-function erc--target-symbol "erc")
+(declare-function erc--target-string "erc")
+(declare-function erc--default-target "erc")
+(declare-function erc-buffer-filter "erc")
+(declare-function erc-downcase "erc")
+(declare-function erc-current-nick "erc")
 (defun erc-networks--examine-targets (identity target on-dupe on-collision)
   "Visit all ERC target buffers with the same TARGET.
 Call ON-DUPE when a buffer's identity belongs to a network
@@ -1212,6 +1226,7 @@ erc-determine-network
 		  do (cl-return name)))
        'Unknown))))
 
+(declare-function erc-server-buffer "erc")
 (defun erc-network ()
   "Return the value of `erc-network' for the current server."
   (or erc-network (erc-with-server-buffer erc-network)))
@@ -1245,6 +1260,8 @@ erc-networks--determine
                  ((intern vanity))))
       erc-networks--name-missing-sentinel))
 
+(declare-function erc-error "erc")
+(declare-function erc-display-error-notice "erc")
 (defun erc-networks--set-name (_proc parsed)
   "Set `erc-network' to the value returned by `erc-networks--determine'.
 Signal an error when the network cannot be determined."
@@ -1298,6 +1315,7 @@ erc-networks--insert-transplanted-content
 
 ;; This should run whenever a network identity is updated.
 
+(declare-function erc-get-buffer "erc")
 (defun erc-networks--reclaim-orphaned-target-buffers (new-proc nid announced)
   "Visit disowned buffers for same NID and associate with NEW-PROC.
 ANNOUNCED is the server's reported host name."
@@ -1384,6 +1402,7 @@ erc-networks--init-identity
   ;;
   nil)
 
+(declare-function erc-set-active-buffer "erc")
 (defun erc-networks--rename-server-buffer (new-proc &optional _parsed)
   "Rename a server buffer based on its network identity.
 Assume that the current buffer is a server buffer, either one
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 239d8ebdcb6..18d0710d56f 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -60,6 +60,8 @@
 
 (load "erc-loaddefs" 'noerror 'nomessage)
 
+(require 'erc-networks)
+(require 'erc-goodies)
 (require 'cl-lib)
 (require 'format-spec)
 (require 'pp)
@@ -347,9 +349,6 @@ erc-channel-hide-list
   :group 'erc-ignore
   :type 'erc-message-type)
 
-(defvar-local erc-session-password nil
-  "The password used for the current session.")
-
 (defcustom erc-disconnected-hook nil
   "Run this hook with arguments (NICK IP REASON) when disconnected.
 This happens before automatic reconnection.  Note, that
@@ -449,16 +448,6 @@ erc-downcase
                             erc--casemapping-rfc1459))
         (buffer-string)))))
 
-(defmacro erc-with-server-buffer (&rest body)
-  "Execute BODY in the current ERC server buffer.
-If no server buffer exists, return nil."
-  (declare (indent 0) (debug (body)))
-  (let ((buffer (make-symbol "buffer")))
-    `(let ((,buffer (erc-server-buffer)))
-       (when (buffer-live-p ,buffer)
-         (with-current-buffer ,buffer
-           ,@body)))))
-
 (cl-defstruct (erc-server-user (:type vector) :named)
   ;; User data
   nickname host login full-name info
@@ -1375,76 +1364,6 @@ erc-debug-log-file
 
 (defvar-local erc-dbuf nil)
 
-(defmacro define-erc-module (name alias doc enable-body disable-body
-                                  &optional local-p)
-  "Define a new minor mode using ERC conventions.
-Symbol NAME is the name of the module.
-Symbol ALIAS is the alias to use, or nil.
-DOC is the documentation string to use for the minor mode.
-ENABLE-BODY is a list of expressions used to enable the mode.
-DISABLE-BODY is a list of expressions used to disable the mode.
-If LOCAL-P is non-nil, the mode will be created as a buffer-local
-mode, rather than a global one.
-
-This will define a minor mode called erc-NAME-mode, possibly
-an alias erc-ALIAS-mode, as well as the helper functions
-erc-NAME-enable, and erc-NAME-disable.
-
-Example:
-
-  ;;;###autoload(autoload \\='erc-replace-mode \"erc-replace\")
-  (define-erc-module replace nil
-    \"This mode replaces incoming text according to `erc-replace-alist'.\"
-    ((add-hook \\='erc-insert-modify-hook
-               #\\='erc-replace-insert))
-    ((remove-hook \\='erc-insert-modify-hook
-                  #\\='erc-replace-insert)))"
-  (declare (doc-string 3) (indent defun))
-  (let* ((sn (symbol-name name))
-         (mode (intern (format "erc-%s-mode" (downcase sn))))
-         (group (intern (format "erc-%s" (downcase sn))))
-         (enable (intern (format "erc-%s-enable" (downcase sn))))
-         (disable (intern (format "erc-%s-disable" (downcase sn)))))
-    `(progn
-       (define-minor-mode
-        ,mode
-        ,(format "Toggle ERC %S mode.
-With a prefix argument ARG, enable %s if ARG is positive,
-and disable it otherwise.  If called from Lisp, enable the mode
-if ARG is omitted or nil.
-%s" name name doc)
-        ;; FIXME: We don't know if this group exists, so this `:group' may
-        ;; actually just silence a valid warning about the fact that the var
-        ;; is not associated with any group.
-        :global ,(not local-p) :group (quote ,group)
-        (if ,mode
-            (,enable)
-          (,disable)))
-       (defun ,enable ()
-         ,(format "Enable ERC %S mode."
-                  name)
-         (interactive)
-         (add-to-list 'erc-modules (quote ,name))
-         (setq ,mode t)
-         ,@enable-body)
-       (defun ,disable ()
-         ,(format "Disable ERC %S mode."
-                  name)
-         (interactive)
-         (setq erc-modules (delq (quote ,name) erc-modules))
-         (setq ,mode nil)
-         ,@disable-body)
-       ,(when (and alias (not (eq name alias)))
-          `(defalias
-             ',(intern
-                (format "erc-%s-mode"
-                        (downcase (symbol-name alias))))
-             #',mode))
-       ;; For find-function and find-variable.
-       (put ',mode    'definition-name ',name)
-       (put ',enable  'definition-name ',name)
-       (put ',disable 'definition-name ',name))))
-
 ;; The rationale for favoring inheritance here (nicer dispatch) is
 ;; kinda flimsy since there aren't yet any actual methods.
 
@@ -1838,40 +1757,6 @@ erc-member-ignore-case
           (throw 'result list)
         (setq list (cdr list))))))
 
-(defmacro erc-with-buffer (spec &rest body)
-  "Execute BODY in the buffer associated with SPEC.
-
-SPEC should have the form
-
- (TARGET [PROCESS])
-
-If TARGET is a buffer, use it.  Otherwise, use the buffer
-matching TARGET in the process specified by PROCESS.
-
-If PROCESS is nil, use the current `erc-server-process'.
-See `erc-get-buffer' for details.
-
-See also `with-current-buffer'.
-
-\(fn (TARGET [PROCESS]) BODY...)"
-  (declare (indent 1) (debug ((form &optional form) body)))
-  (let ((buf (make-symbol "buf"))
-        (proc (make-symbol "proc"))
-        (target (make-symbol "target"))
-        (process (make-symbol "process")))
-    `(let* ((,target ,(car spec))
-            (,process ,(cadr spec))
-            (,buf (if (bufferp ,target)
-                      ,target
-                    (let ((,proc (or ,process
-                                     (and (processp erc-server-process)
-                                          erc-server-process))))
-                      (if (and ,target ,proc)
-                          (erc-get-buffer ,target ,proc))))))
-       (when (buffer-live-p ,buf)
-         (with-current-buffer ,buf
-           ,@body)))))
-
 (defun erc-get-buffer (target &optional proc)
   "Return the buffer matching TARGET in the process PROC.
 If PROC is not supplied, all processes are searched."
@@ -1918,18 +1803,6 @@ erc-buffer-list
     (setq predicate (lambda () t)))
   (erc-buffer-filter predicate proc))
 
-(defmacro erc-with-all-buffers-of-server (process pred &rest forms)
-  "Execute FORMS in all buffers which have same process as this server.
-FORMS will be evaluated in all buffers having the process PROCESS and
-where PRED matches or in all buffers of the server process if PRED is
-nil."
-  (declare (indent 1) (debug (form form body)))
-  (macroexp-let2 nil pred pred
-    `(erc-buffer-filter (lambda ()
-                          (when (or (not ,pred) (funcall ,pred))
-                            ,@forms))
-                        ,process)))
-
 (define-obsolete-function-alias 'erc-iswitchb #'erc-switch-to-buffer "25.1")
 (defun erc--switch-to-buffer (&optional arg)
   (read-buffer "Switch to ERC buffer: "
@@ -7459,12 +7332,4 @@ erc-handle-irc-url
 
 (provide 'erc)
 
-(require 'erc-backend)
-
-;; Deprecated. We might eventually stop requiring the goodies automatically.
-;; IMPORTANT: This require must appear _after_ the above (provide 'erc) to
-;; avoid a recursive require error when byte-compiling the entire package.
-(require 'erc-goodies)
-(require 'erc-networks)
-
 ;;; erc.el ends here
diff --git a/test/lisp/erc/erc-networks-tests.el b/test/lisp/erc/erc-networks-tests.el
index 66a334b7091..32bdfa11ff7 100644
--- a/test/lisp/erc/erc-networks-tests.el
+++ b/test/lisp/erc/erc-networks-tests.el
@@ -20,7 +20,7 @@
 ;;; Code:
 
 (require 'ert-x) ; cl-lib
-(require 'erc-networks)
+(require 'erc)
 
 (defun erc-networks-tests--create-dead-proc (&optional buf)
   (let ((p (start-process "true" (or buf (current-buffer)) "true")))
-- 
2.36.1

In Commercial Emacs 0.3.1snapshot 5de4c3d in dev (upstream 29.0.50, x86_64-pc-linux-gnu) built on dick
Repository revision: 5de4c3deabbd44bd3b9e1aaa52e23237af9c7f3e
Repository branch: dev
Windowing system distributor 'The X.Org Foundation', version 11.0.12013000
System Description: Ubuntu 20.04.4 LTS

Configured using:
 'configure --prefix=/home/dick/.local --with-tree-sitter'
Configured features:
CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG JSON
TREE_SITTER LCMS2 LIBSELINUX LIBXML2 MODULES NOTIFY INOTIFY PDUMPER PNG
RSVG SECCOMP SOUND THREADS TIFF TOOLKIT_SCROLL_BARS WEBP X11 XDBE XIM
XINPUT2 XPM GTK3 ZLIB
Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Magit Log

Minor modes in effect:
  global-git-commit-mode: t
  shell-dirtrack-mode: t
  projectile-mode: t
  flx-ido-mode: t
  override-global-mode: t
  global-hl-line-mode: t
  hl-line-mode: t
  winner-mode: t
  tooltip-mode: t
  show-paren-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  buffer-read-only: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
/home/dick/gomacro-mode/gomacro-mode hides /home/dick/.emacs.d/elpa/gomacro-mode-20200326.1103/gomacro-mode
/home/dick/.emacs.d/elpa/go-rename-20190805.2101/go-rename hides /home/dick/.emacs.d/elpa/go-mode-1.6.0/go-rename
/home/dick/.emacs.d/elpa/go-guru-20181012.330/go-guru hides /home/dick/.emacs.d/elpa/go-mode-1.6.0/go-guru
/home/dick/org-gcal.el/org-gcal hides /home/dick/.emacs.d/elpa/org-gcal-0.3/org-gcal
/home/dick/.emacs.d/elpa/request-deferred-0.2.0/request-deferred hides /home/dick/.emacs.d/elpa/request-0.3.3/request-deferred
/home/dick/.emacs.d/elpa/chess-2.0.5/_pkg hides /home/dick/.local/share/emacs/site-lisp/_pkg
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-pos hides /home/dick/.local/share/emacs/site-lisp/chess-pos
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-module hides /home/dick/.local/share/emacs/site-lisp/chess-module
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ucb hides /home/dick/.local/share/emacs/site-lisp/chess-ucb
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-scid hides /home/dick/.local/share/emacs/site-lisp/chess-scid
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-puzzle hides /home/dick/.local/share/emacs/site-lisp/chess-puzzle
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-irc hides /home/dick/.local/share/emacs/site-lisp/chess-irc
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-network hides /home/dick/.local/share/emacs/site-lisp/chess-network
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-autosave hides /home/dick/.local/share/emacs/site-lisp/chess-autosave
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-engine hides /home/dick/.local/share/emacs/site-lisp/chess-engine
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-tutorial hides /home/dick/.local/share/emacs/site-lisp/chess-tutorial
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-german hides /home/dick/.local/share/emacs/site-lisp/chess-german
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-file hides /home/dick/.local/share/emacs/site-lisp/chess-file
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-random hides /home/dick/.local/share/emacs/site-lisp/chess-random
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-stockfish hides /home/dick/.local/share/emacs/site-lisp/chess-stockfish
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-pgn hides /home/dick/.local/share/emacs/site-lisp/chess-pgn
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-kibitz hides /home/dick/.local/share/emacs/site-lisp/chess-kibitz
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-eco hides /home/dick/.local/share/emacs/site-lisp/chess-eco
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-display hides /home/dick/.local/share/emacs/site-lisp/chess-display
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-var hides /home/dick/.local/share/emacs/site-lisp/chess-var
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-test hides /home/dick/.local/share/emacs/site-lisp/chess-test
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ply hides /home/dick/.local/share/emacs/site-lisp/chess-ply
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-message hides /home/dick/.local/share/emacs/site-lisp/chess-message
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ics1 hides /home/dick/.local/share/emacs/site-lisp/chess-ics1
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-phalanx hides /home/dick/.local/share/emacs/site-lisp/chess-phalanx
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-game hides /home/dick/.local/share/emacs/site-lisp/chess-game
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-log hides /home/dick/.local/share/emacs/site-lisp/chess-log
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-plain hides /home/dick/.local/share/emacs/site-lisp/chess-plain
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-perft hides /home/dick/.local/share/emacs/site-lisp/chess-perft
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-glaurung hides /home/dick/.local/share/emacs/site-lisp/chess-glaurung
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ai hides /home/dick/.local/share/emacs/site-lisp/chess-ai
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-fruit hides /home/dick/.local/share/emacs/site-lisp/chess-fruit
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-uci hides /home/dick/.local/share/emacs/site-lisp/chess-uci
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-epd hides /home/dick/.local/share/emacs/site-lisp/chess-epd
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-database hides /home/dick/.local/share/emacs/site-lisp/chess-database
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-link hides /home/dick/.local/share/emacs/site-lisp/chess-link
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-transport hides /home/dick/.local/share/emacs/site-lisp/chess-transport
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-none hides /home/dick/.local/share/emacs/site-lisp/chess-none
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-polyglot hides /home/dick/.local/share/emacs/site-lisp/chess-polyglot
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-crafty hides /home/dick/.local/share/emacs/site-lisp/chess-crafty
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-chat hides /home/dick/.local/share/emacs/site-lisp/chess-chat
/home/dick/.emacs.d/elpa/chess-2.0.5/chess hides /home/dick/.local/share/emacs/site-lisp/chess
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-images hides /home/dick/.local/share/emacs/site-lisp/chess-images
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-gnuchess hides /home/dick/.local/share/emacs/site-lisp/chess-gnuchess
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-fen hides /home/dick/.local/share/emacs/site-lisp/chess-fen
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ics hides /home/dick/.local/share/emacs/site-lisp/chess-ics
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ics2 hides /home/dick/.local/share/emacs/site-lisp/chess-ics2
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-common hides /home/dick/.local/share/emacs/site-lisp/chess-common
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-input hides /home/dick/.local/share/emacs/site-lisp/chess-input
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-announce hides /home/dick/.local/share/emacs/site-lisp/chess-announce
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-clock hides /home/dick/.local/share/emacs/site-lisp/chess-clock
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-sound hides /home/dick/.local/share/emacs/site-lisp/chess-sound
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-sjeng hides /home/dick/.local/share/emacs/site-lisp/chess-sjeng
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-algebraic hides /home/dick/.local/share/emacs/site-lisp/chess-algebraic
/home/dick/.emacs.d/elpa/transient-0.3.7snapshot/transient hides /home/dick/.local/share/emacs/0.3.1/lisp/transient

Features:
(mode-local elpaso elpaso-admin elpaso-milky elpaso-defs shortdoc
supercite regi shr-color rect pulse ivy delsel colir ivy-overlay ffap
dumb-jump gravatar dns ag vc-svn find-dired markdown-mode edit-indirect
flow-fill nndoc org-element avl-tree ol-eww eww xdg ol-rmail ol-mhe
ol-irc ol-info ol-gnus nnselect ol-docview doc-view image-mode exif
ol-bibtex ol-bbdb ol-w3m ol-doi org-link-doi org-tempo tempo org
org-macro org-footnote org-pcomplete org-list org-faces org-entities
org-version ob-R ob-emacs-lisp ob-ein ein-cell ein-shared-output
ein-output-area ein-kernel ein-ipdb ein-query ein-events ein-websocket
websocket bindat ein-node ewoc ein-log ein-classes ein-core ein
ein-utils deferred ob ob-tangle org-src ob-ref ob-lob ob-table ob-exp
ob-comint ob-core ob-eval org-table oc-basic bibtex ol org-keys oc
org-compat org-macs org-loaddefs cal-menu calendar cal-loaddefs
whitespace cl-print debug backtrace goto-addr magit-extras mule-util
display-line-numbers debbugs-gnu debbugs-compat debbugs soap-client
rng-xsd rng-dt rng-util xsd-regexp jka-compr gnus-html url-queue
help-fns radix-tree vc cc-mode cc-fonts cc-guess cc-menus cc-cmds
cc-styles cc-align cc-engine cc-vars cc-defs eudc-capf eudc eudc-vars
shadow bbdb-message footnote emacsbug texinfo texinfo-loaddefs
face-remap magit-patch-changelog magit-patch magit-submodule
magit-obsolete magit-blame magit-stash magit-reflog magit-bisect
magit-push magit-pull magit-fetch magit-clone magit-remote magit-commit
magit-sequence magit-notes magit-worktree magit-tag magit-merge
magit-branch magit-reset magit-files magit-refs magit-status magit
magit-repos magit-apply magit-wip magit-log which-func imenu magit-diff
smerge-mode diff git-commit log-edit pcvs-util add-log magit-core
magit-margin magit-transient magit-process with-editor server magit-mode
transient misearch multi-isearch vc-git diff-mode vc-dispatcher
bug-reference tramp-archive tramp-gvfs tramp-cache zeroconf textsec
uni-scripts idna-mapping ucs-normalize uni-confusable textsec-check sort
smiley mm-archive mail-extr qp gnus-async gnus-ml gnus-notifications
gnus-fun notifications gnus-kill gnus-dup disp-table utf-7 blamer a
tramp tramp-loaddefs trampver tramp-integration cus-start files-x
tramp-compat shell pcomplete ls-lisp url-cache benchmark nnrss nnfolder
nndiscourse rbenv nnhackernews nntwitter nntwitter-api bbdb-gnus
gnus-demon nntp nnmairix nnml nnreddit gnus-topic url-http url-auth
url-gw network-stream nsm request virtualenvwrapper gud s json-rpc
python gnus-score score-mode gnus-bcklg gnus-srvr gnus-cite anaphora
bbdb-mua bbdb-com bbdb bbdb-site timezone gnus-delay gnus-draft
gnus-cache gnus-agent gnus-msg gnus-art mm-uu mml2015 mm-view mml-smime
smime gnutls dig gnus-sum shr pixel-fill kinsoku url-file url-dired svg
dom nndraft nnmh gnus-group mm-url gnus-undo use-package
use-package-delight use-package-diminish gnus-start gnus-dbus dbus xml
gnus-cloud nnimap nnmail mail-source utf7 netrc nnoo parse-time iso8601
gnus-spec gnus-int gnus-range message sendmail yank-media puny dired-x
dired dired-loaddefs rfc822 mml mml-sec epa epg rfc6068 epg-config
mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045
ietf-drums mailabbrev gmm-utils mailheader gnus-win paredit-ext paredit
inf-ruby ruby-mode smie company pcase haskell-interactive-mode
haskell-presentation-mode haskell-process haskell-session
haskell-compile haskell-mode haskell-cabal haskell-utils
haskell-font-lock haskell-indentation haskell-string
haskell-sort-imports haskell-lexeme haskell-align-imports
haskell-complete-module haskell-ghc-support noutline outline
flymake-proc flymake warnings etags fileloop generator dabbrev
haskell-customize hydra lv use-package-ensure solarized-theme
solarized-definitions projectile lisp-mnt ibuf-ext ibuffer
ibuffer-loaddefs thingatpt magit-autorevert autorevert filenotify
magit-git magit-base magit-section format-spec crm dash rx compat-27
compat-26 compat grep compile comint ansi-color gnus nnheader range
mail-utils mm-util mail-prsvr gnus-util text-property-search time-date
flx-ido flx google-translate-default-ui google-translate-core-ui
facemenu color ido google-translate-core google-translate-tk
google-translate-backend use-package-bind-key bind-key auto-complete
easy-mmode advice edmacro kmacro popup cus-edit pp cus-load wid-edit
emms-player-mplayer emms-player-simple emms emms-compat cl-extra
help-mode xref project use-package-core derived hl-line winner ring
debbugs-autoloads eglot-autoloads elpaso-disc-autoloads elpaso-autoloads
find-func finder-inf go-mode-autoloads json-reformat-autoloads
json-snatcher-autoloads projectile-autoloads sml-mode-autoloads
epl-autoloads tornado-template-mode-autoloads typescript-mode-autoloads
request-autoloads info package browse-url url url-proxy url-privacy
url-expand url-methods url-history url-cookie generate-lisp-file
url-domsuf url-util mailcap url-handlers url-parse auth-source cl-seq
eieio eieio-core cl-macs eieio-loaddefs password-cache json subr-x map
byte-opt gv bytecomp byte-compile cconv cldefs url-vars cl-loaddefs
cl-lib 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
tree-sitter 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 2291654 278813)
 (symbols 48 57591 99)
 (strings 32 325470 81126)
 (string-bytes 1 10675600)
 (vectors 16 166031)
 (vector-slots 8 4028354 252813)
 (floats 8 3841 3992)
 (intervals 56 226408 5693)
 (buffers 1000 92))