DarwinAwardWinner / with-simulated-input

Test your interactive elisp functions non-interactively!
GNU General Public License v3.0
38 stars 4 forks source link

with-simulated-input causes unused variable warnings #9

Closed nbfalcon closed 3 years ago

nbfalcon commented 3 years ago

When calling with-simulated-input inside a let-form, there are byte-compile warnings stating that they aren't used.

Here is an example:

(defun foo ()
  (let ((f #'identity))
    (with-simulated-input "RET"
      (funcall f))))

When evaluating the following snippet (scratch C-x C-e), the warning can be observed.

(byte-compile
 '(defun foo ()
    (let ((f #'identity))
      (with-simulated-input "RET"
        (funcall f)))))

This issue is somewhat bugging me because it causes the only two warnings in my otherwise error and warning free package (ptemplate).

Additional information:

nbfalcon commented 3 years ago

I found out how to do what I wanted without with-simulated-input, so you can ignore this issue if you want (I don't use it anymore).

This package definitely needs a refactor. For anyone wondering how it works:

  1. Temporarily bind a function that runs BODY to a random keybinding in overriding-terminal-local-map, the keymap with the highest precedence
  2. Run execute-kbd-macro with that keybinding and the keys of the user concatenated (remember to use kbd). That function allows input when calling functions which would otherwise block.

My approach was slightly different, and even simpler: Run execute-kbd-macro with the desired keybinding, with COUNT=1 and specify LOOPFUNC as a lambda that calls what you need. That isn't much more code (+ 1 line) without this package. execute-kbd-macro's signature is (keys count loopfunc).

DarwinAwardWinner commented 3 years ago

I agree the package needs refactoring. One thing is, the current solution works in both interactive and noninteractive (i.e. batch mode) Emacs, which is important for the main use case (automated testing). The LOOPFUNC trick you describe looks interesting. Would you mind sharing the code you used?

nbfalcon commented 3 years ago

@DarwinAwardWinner here is the relevant commit: https://github.com/nbfalcon/ptemplate/commit/044859f0c8d754d6e1d1f58ca0c8edf6bf0552b4.

It works in the case of automated testing (ert-runner in my case).

The issue with your code is the entire lexenv stuff, which should be dropped in favor of lambdas constructed directly in the macro; this would make your package independent of Emacs' implementation details, and it would remove byte-compile warnings.

nbfalcon commented 3 years ago

Also, as a side note, please try to calculate as much as possible at compile time in macros; there is a handy plugin called "macrostep" which allows to interactively expand macros. If the output of them is simple, they are easier to understand and as such learning their underlying tricks becomes easier. It's also faster when compiled: things like

(cl-letf ((keylist (if (listp keylist) keylist (list keylist)))

can be done at expand-time, so that they won't even show up in the expansion result.

DarwinAwardWinner commented 3 years ago

Fixed by #12, which I have merged most of.