mishoo / elisp-reader.el

Customizable reader for Emacs Lisp
72 stars 7 forks source link

Make use of the reader customizable #4

Open sellout opened 1 year ago

sellout commented 1 year ago

Rather than simply a progn at the end of elisp-reader, how about making it possible to enable/disable, then it could maybe be scoped for reading certain things.

(defvar er--original-read (symbol-function 'read))
(defvar er--original-read-from-string (symbol-function 'read-from-string))
(defvar er--original-load-read-function load-read-function)

(defun er-enable ()
  (interactive)
  (setq er--original-read (symbol-function 'read)
        er--original-read-from-string (symbol-function 'read-from-string)
        er--original-load-read-function load-read-function)
  (fset 'read (symbol-function 'er-read))
  (fset 'read-from-string (symbol-function 'er-read-from-string))
  (setq load-read-function (symbol-function 'er-read)))

(defun er-disable ()
  (interactive)
  (fset 'read er-original-read)
  (fset 'read-from-string er--original-read-from-string)
  (setq load-read-function er--original-load-read-function))

(defcustom er-enabled nil
  "Whether to use the extensible elisp-reader when reading elisp."
  :set
  (lambda (option new-value)
    (if new-value (er-enable) (er-disable))))
nagy commented 5 months ago

Unfortunately, disabling of the reader is still sometimes needed yet. For example, when I attempt to inspect the variable browse-url-handlers with the helpful package, I receive an error when I have this elisp reader implementation active.

To add to your functions above, I did:

(defun er-enabled-p ()
  (eq (symbol-function 'read) (symbol-function 'er-read)))

(defun without-er-reader-a (orig-fn &rest args)
  "An advice to disable elisp-reader for this function only.

To be used with `advice-add' and `:around'."
  (let ((was-enabled (er-enabled-p)))
    (unwind-protect
        (progn
          (when was-enabled (er-disable))
          (apply orig-fn args))
      (when was-enabled (er-enable)))))

;; `helpful-update' has some problems with the new elisp reader.
(advice-add 'helpful-update :around #'without-er-reader-a)

This disables the reader only for this particular function.

Just for reference, this is the stacktrace, that I receive but this is unrelated to this bug report:

Stacktrace
Debugger entered--Lisp error: (error "Unexpected error whilst reading /nix/store/rajkyxn1ssi2pi17wf0imw7s289f3bg5-emacs-gtk3-29.3/share/emacs/29.3/lisp/net/browse-url.el.gz position 69913: (error End of file during parsing)")
  (error "Unexpected error whilst reading %s position %s: %s" "/nix/store/rajkyxn1ssi2pi17wf0imw7s289f3bg5-emacs-gtk3-29.3/share/emacs/29.3/lisp/net/browse-url.el.gz" 69913 (error "End of file during parsing"))
  (elisp-refs--read-all-buffer-forms # nil)
  (elisp-refs--read-and-find # browse-url-handlers elisp-refs--variable-p)
  (#f(compiled-function (buf) #) #)
  (elisp-refs--search-1 (#) #f(compiled-function (buf) #))
  (helpful--reference-positions browse-url-handlers nil #)
  (helpful--calculate-references browse-url-handlers nil "/nix/store/rajkyxn1ssi2pi17wf0imw7s289f3bg5-emacs-gtk3-29.3/share/emacs/29.3/lisp/net/browse-url.el.gz")
  (#)
  (apply # nil)
  (progn (apply orig-fn args))
  (unwind-protect (progn (apply orig-fn args)))
  (let ((was-enabled (er-enabled-p))) (unwind-protect (progn (apply orig-fn args))))
  (without-er-reader #)
  (apply without-er-reader # nil)
  (helpful-update)
  (helpful--update-and-switch-buffer browse-url-handlers nil)
  (helpful-variable browse-url-handlers)
  (funcall-interactively helpful-variable browse-url-handlers)
  (command-execute helpful-variable)