diff options
| -rw-r--r-- | lisp/erc/erc-common.el | 76 | ||||
| -rw-r--r-- | test/lisp/erc/erc-tests.el | 7 |
2 files changed, 49 insertions, 34 deletions
diff --git a/lisp/erc/erc-common.el b/lisp/erc/erc-common.el index 6c015c71ff9..708cdb0c422 100644 --- a/lisp/erc/erc-common.el +++ b/lisp/erc/erc-common.el | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | (defvar erc-dbuf) | 32 | (defvar erc-dbuf) |
| 33 | (defvar erc-log-p) | 33 | (defvar erc-log-p) |
| 34 | (defvar erc-modules) | 34 | (defvar erc-modules) |
| 35 | (defvar erc-server-process) | ||
| 35 | (defvar erc-server-users) | 36 | (defvar erc-server-users) |
| 36 | (defvar erc-session-server) | 37 | (defvar erc-session-server) |
| 37 | 38 | ||
| @@ -40,6 +41,9 @@ | |||
| 40 | (declare-function erc-server-buffer "erc" nil) | 41 | (declare-function erc-server-buffer "erc" nil) |
| 41 | (declare-function widget-apply-action "wid-edit" (widget &optional event)) | 42 | (declare-function widget-apply-action "wid-edit" (widget &optional event)) |
| 42 | (declare-function widget-at "wid-edit" (&optional pos)) | 43 | (declare-function widget-at "wid-edit" (&optional pos)) |
| 44 | (declare-function widget-create-child-and-convert "wid-edit" | ||
| 45 | (parent type &rest args)) | ||
| 46 | (declare-function widget-default-format-handler "wid-edit" (widget escape)) | ||
| 43 | (declare-function widget-get-sibling "wid-edit" (widget)) | 47 | (declare-function widget-get-sibling "wid-edit" (widget)) |
| 44 | (declare-function widget-move "wid-edit" (arg &optional suppress-echo)) | 48 | (declare-function widget-move "wid-edit" (arg &optional suppress-echo)) |
| 45 | (declare-function widget-type "wid-edit" (widget)) | 49 | (declare-function widget-type "wid-edit" (widget)) |
| @@ -195,16 +199,6 @@ instead of a `set' state, which precludes any actual saving." | |||
| 195 | (throw 'found found))) | 199 | (throw 'found found))) |
| 196 | 'erc)) | 200 | 'erc)) |
| 197 | 201 | ||
| 198 | (defun erc--neuter-custom-variable-state (variable) | ||
| 199 | "Lie to Customize about VARIABLE's true state. | ||
| 200 | Do so by always returning its standard value, namely nil." | ||
| 201 | ;; Make a module's global minor-mode toggle blind to Customize, so | ||
| 202 | ;; that `customize-variable-state' never sees it as "changed", | ||
| 203 | ;; regardless of its value. This snippet is | ||
| 204 | ;; `custom--standard-value' from Emacs 28+. | ||
| 205 | (cl-assert (null (eval (car (get variable 'standard-value)) t))) | ||
| 206 | nil) | ||
| 207 | |||
| 208 | ;; This exists as a separate, top-level function to prevent the byte | 202 | ;; This exists as a separate, top-level function to prevent the byte |
| 209 | ;; compiler from warning about widget-related dependencies not being | 203 | ;; compiler from warning about widget-related dependencies not being |
| 210 | ;; loaded at runtime. | 204 | ;; loaded at runtime. |
| @@ -230,25 +224,42 @@ Do so by always returning its standard value, namely nil." | |||
| 230 | (substitute-command-keys "\\[Custom-set]") | 224 | (substitute-command-keys "\\[Custom-set]") |
| 231 | (substitute-command-keys "\\[Custom-save]")))) | 225 | (substitute-command-keys "\\[Custom-save]")))) |
| 232 | 226 | ||
| 227 | ;; This stands apart to avoid needing forward declarations for | ||
| 228 | ;; `wid-edit' functions in every file requiring `erc-common'. | ||
| 229 | (defun erc--make-show-me-widget (widget escape &rest plist) | ||
| 230 | (if (eq escape ?i) | ||
| 231 | (apply #'widget-create-child-and-convert widget 'push-button plist) | ||
| 232 | (widget-default-format-handler widget escape))) | ||
| 233 | |||
| 233 | (defun erc--prepare-custom-module-type (name) | 234 | (defun erc--prepare-custom-module-type (name) |
| 234 | `(let* ((name (erc--normalize-module-symbol ',name)) | 235 | `(let* ((name (erc--normalize-module-symbol ',name)) |
| 235 | (fmtd (format " `%s' " name))) | 236 | (fmtd (format " `%s' " name))) |
| 236 | `(boolean | 237 | `(boolean |
| 237 | :button-face '(custom-variable-obsolete custom-button) | 238 | :format "%{%t%}: %i %[Deprecated Toggle%] %v \n%h\n" |
| 238 | :format "%{%t%}: %[Deprecated Toggle%] \n%h\n" | 239 | :format-handler |
| 240 | ,(lambda (widget escape) | ||
| 241 | (erc--make-show-me-widget | ||
| 242 | widget escape | ||
| 243 | :button-face '(custom-variable-obsolete custom-button) | ||
| 244 | :tag "Show Me" | ||
| 245 | :action (apply-partially #'erc--tick-module-checkbox name) | ||
| 246 | :help-echo (lambda (_) | ||
| 247 | (let ((hasp (memq name erc-modules))) | ||
| 248 | (concat (if hasp "Remove" "Add") fmtd | ||
| 249 | (if hasp "from" "to") | ||
| 250 | " `erc-modules'."))))) | ||
| 251 | :action widget-toggle-action | ||
| 239 | :documentation-property | 252 | :documentation-property |
| 240 | ,(lambda (_) | 253 | ,(lambda (_) |
| 241 | (let ((hasp (memq name erc-modules))) | 254 | (let ((hasp (memq name erc-modules))) |
| 242 | (concat "Setting a module's minor-mode variable is " | 255 | (concat |
| 243 | (propertize "ineffective" 'face 'error) | 256 | "Setting a module's minor-mode variable is " |
| 244 | ".\nPlease " (if hasp "remove" "add") fmtd | 257 | (propertize "ineffective" 'face 'error) |
| 245 | (if hasp "from" "to") " `erc-modules' directly instead.\n" | 258 | ".\nPlease " (if hasp "remove" "add") fmtd |
| 246 | "You can do so now by clicking the scary button above."))) | 259 | (if hasp "from" "to") " `erc-modules' directly instead.\n" |
| 247 | :help-echo ,(lambda (_) | 260 | "You can do so now by clicking " |
| 248 | (let ((hasp (memq name erc-modules))) | 261 | (propertize "Show Me" 'face 'custom-variable-obsolete) |
| 249 | (concat (if hasp "Remove" "Add") fmtd | 262 | " above.")))))) |
| 250 | (if hasp "from" "to") " `erc-modules'."))) | ||
| 251 | :action ,(apply-partially #'erc--tick-module-checkbox name)))) | ||
| 252 | 263 | ||
| 253 | (defun erc--fill-module-docstring (&rest strings) | 264 | (defun erc--fill-module-docstring (&rest strings) |
| 254 | (with-temp-buffer | 265 | (with-temp-buffer |
| @@ -264,6 +275,12 @@ Do so by always returning its standard value, namely nil." | |||
| 264 | (goto-char (point-min)) | 275 | (goto-char (point-min)) |
| 265 | (nth 3 (read (current-buffer))))) | 276 | (nth 3 (read (current-buffer))))) |
| 266 | 277 | ||
| 278 | (defmacro erc--find-feature (name alias) | ||
| 279 | `(pcase (erc--find-group ',name ,(and alias (list 'quote alias))) | ||
| 280 | ('erc (and-let* ((file (or (macroexp-file-name) buffer-file-name))) | ||
| 281 | (intern (file-name-base file)))) | ||
| 282 | (v v))) | ||
| 283 | |||
| 267 | (defmacro define-erc-module (name alias doc enable-body disable-body | 284 | (defmacro define-erc-module (name alias doc enable-body disable-body |
| 268 | &optional local-p) | 285 | &optional local-p) |
| 269 | "Define a new minor mode using ERC conventions. | 286 | "Define a new minor mode using ERC conventions. |
| @@ -310,7 +327,7 @@ if ARG is omitted or nil. | |||
| 310 | \n%s" name name doc)) | 327 | \n%s" name name doc)) |
| 311 | :global ,(not local-p) | 328 | :global ,(not local-p) |
| 312 | :group (erc--find-group ',name ,(and alias (list 'quote alias))) | 329 | :group (erc--find-group ',name ,(and alias (list 'quote alias))) |
| 313 | ,@(unless local-p '(:get #'erc--neuter-custom-variable-state)) | 330 | ,@(unless local-p `(:require ',(erc--find-feature name alias))) |
| 314 | ,@(unless local-p `(:type ,(erc--prepare-custom-module-type name))) | 331 | ,@(unless local-p `(:type ,(erc--prepare-custom-module-type name))) |
| 315 | (if ,mode | 332 | (if ,mode |
| 316 | (,enable) | 333 | (,enable) |
| @@ -371,12 +388,13 @@ If no server buffer exists, return nil." | |||
| 371 | (not (cdr body)) | 388 | (not (cdr body)) |
| 372 | (special-variable-p (car body)))) | 389 | (special-variable-p (car body)))) |
| 373 | (buffer (make-symbol "buffer"))) | 390 | (buffer (make-symbol "buffer"))) |
| 374 | `(let ((,buffer (erc-server-buffer))) | 391 | `(when-let* (((processp erc-server-process)) |
| 375 | (when (buffer-live-p ,buffer) | 392 | (,buffer (process-buffer erc-server-process)) |
| 376 | ,(if varp | 393 | ((buffer-live-p ,buffer))) |
| 377 | `(buffer-local-value ',(car body) ,buffer) | 394 | ,(if varp |
| 378 | `(with-current-buffer ,buffer | 395 | `(buffer-local-value ',(car body) ,buffer) |
| 379 | ,@body)))))) | 396 | `(with-current-buffer ,buffer |
| 397 | ,@body))))) | ||
| 380 | 398 | ||
| 381 | (defmacro erc-with-all-buffers-of-server (process pred &rest forms) | 399 | (defmacro erc-with-all-buffers-of-server (process pred &rest forms) |
| 382 | "Execute FORMS in all buffers which have same process as this server. | 400 | "Execute FORMS in all buffers which have same process as this server. |
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 5aaf7e499e3..bafe418f0cd 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el | |||
| @@ -1289,15 +1289,12 @@ | |||
| 1289 | (erc-default-recipients '("#chan")) | 1289 | (erc-default-recipients '("#chan")) |
| 1290 | calls) | 1290 | calls) |
| 1291 | (with-temp-buffer | 1291 | (with-temp-buffer |
| 1292 | (erc-tests--set-fake-server-process "sleep" "1") | ||
| 1292 | (cl-letf (((symbol-function 'erc-cmd-MSG) | 1293 | (cl-letf (((symbol-function 'erc-cmd-MSG) |
| 1293 | (lambda (line) | 1294 | (lambda (line) |
| 1294 | (push line calls) | 1295 | (push line calls) |
| 1295 | (should erc--called-as-input-p) | 1296 | (should erc--called-as-input-p) |
| 1296 | (funcall orig-erc-cmd-MSG line))) | 1297 | (funcall orig-erc-cmd-MSG line))) |
| 1297 | ((symbol-function 'erc-server-buffer) | ||
| 1298 | (lambda () (current-buffer))) | ||
| 1299 | ((symbol-function 'erc-server-process-alive) | ||
| 1300 | (lambda () t)) | ||
| 1301 | ((symbol-function 'erc-server-send-queue) | 1298 | ((symbol-function 'erc-server-send-queue) |
| 1302 | #'ignore)) | 1299 | #'ignore)) |
| 1303 | 1300 | ||
| @@ -2018,7 +2015,7 @@ ARG is omitted or nil. | |||
| 2018 | Some docstring." | 2015 | Some docstring." |
| 2019 | :global t | 2016 | :global t |
| 2020 | :group (erc--find-group 'mname 'malias) | 2017 | :group (erc--find-group 'mname 'malias) |
| 2021 | :get #'erc--neuter-custom-variable-state | 2018 | :require 'nil |
| 2022 | :type "mname" | 2019 | :type "mname" |
| 2023 | (if erc-mname-mode | 2020 | (if erc-mname-mode |
| 2024 | (erc-mname-enable) | 2021 | (erc-mname-enable) |