0

I have to copy my .emacs.d to different computers a lot, so I keep init.el etc in version control and pair it with a batch Elisp script that re-downloads all of my selected packages. I'd like this script to be less noisy, and in particular I'd like it to not bother me with compilation diagnostics for packages that I have no interest in hacking on.

I tried to squelch all the warnings like so:

(package-refresh-contents)
(let ((package-native-compile t)
      (byte-compile-warnings nil)
      (native-comp-async-report-warnings-errors nil))
  (package-install-selected-packages t)

  ;; Block until native compilation has finished.
  (while (or comp-files-queue
             (> (comp-async-runnings) 0))
    (sleep-for 1)))

...but this (specifically, the let-binding of byte-compile-warnings and native-comp-async-report-warnings-errors) appears to have no effect (it's possible that it is suppressing some warnings, but not the particular ones that flood my terminal). What should I be doing instead of, or in addition to, this?

Note: the bootstrap script is not itself byte-compiled, and does not use lexical binding mode.

Note: examples of the warnings I'm still seeing with this code:

json-snatcher.el:222:25: Warning: value returned from (match-end 0) is unused
polymode-core:0: Warning: Not registering prefix "pm".  Affects: (...)
Warning (comp): mime-w3.el:52:45: Warning: reference to free variable ‘w3-mode-map’
Warning (comp): mime-w3.el:62:21: Warning: Use ‘with-current-buffer’ rather than save-excursion+set-buffer
Warning (comp): mime-w3.el:50:12: Warning: the function ‘w3-region’ is not known to be defined.Warning (comp): web-mode.el:11455:36: Warning: Unused lexical variable `end'

P.S. If anyone knows how to cut down the spew generated by package-install itself, that'd also be great. Ideally I would like to see just "Package ‘foo’ installed" for each package, and not the rest of this:

Contacting host: melpa.org:443
Parsing tar file...
Parsing tar file...done
Extracting... \
Extracting...done
  INFO     Scraping files for cython-mode-autoloads.el...
  INFO     Scraping files for cython-mode-autoloads.el...done
Checking .../elpa/cython-mode-20221130.1257...
Compiling .../elpa/cython-mode-20221130.1257/cython-mode-autoloads.el...
Compiling .../elpa/cython-mode-20221130.1257/cython-mode-pkg.el...
Compiling .../elpa/cython-mode-20221130.1257/cython-mode.el...
Done (Total of 1 file compiled, 2 skipped)
Package ‘cython-mode’ installed.
6
  • I tried installing just json-snatcherwith byte-compile-warnings set to t and nil and it certainly makes a difference: there is an extra 16 lines of output (warnings and empty lines) with t as compared with the output when the variable is set to nil. In particular, I don't see the warning in the first line of your example output. I don't have native compilation set up, so I can't test that part.
    – NickD
    Commented Jun 22, 2023 at 21:25
  • If you commit your config to version control in full then you won't get any noise at all. Just clone your config and Emacs is immediately ready -- no other downloading or installing required. This also ensures you actually have the same config on each machine, which can prevent unexpected problems.
    – phils
    Commented Jun 22, 2023 at 22:36
  • @phils You're not seriously telling me to commit .elc and .eln files, are you??? Committing build output has to be item #1 on the hypothetical Big List Of Things Not To Do With Version Control. Also, it won't work, since not all of the computers in question have the same CPU architecture or even the same major version of Emacs.
    – zwol
    Commented Jun 23, 2023 at 15:17
  • .elc files are very portable, so you can commit those if they will be executed on the-same-or-newer version of Emacs, regardless of system architecture. It's a pretty good idea to match your Emacs versions between systems for consistency, in which case you can very safely have your byte-compiled lisp committed. An emacs config isn't (typically) software that lots of people will be using and compiling -- usually it's just for you, and committing the compiled files can make things better for you. I think the "clone and go" benefit is a strong one.
    – phils
    Commented Jun 24, 2023 at 1:19
  • I wasn't thinking of the architecture-specific native-compiled .eln files though (I don't use them, so it slipped my mind). IIRC the filename hashes for those take architecture into account, in which case I suspect you could safely commit them; however by my recollection the .eln binaries are enormous by comparison with .el and .elc files, so I wouldn't personally commit them on that basis. So compilation noise from regenerating those might be inevitable. Mind you, if I did use native-compilation, I might still sync the eln-cache directory some other way.
    – phils
    Commented Jun 24, 2023 at 1:25

1 Answer 1

2

[Not a complete answer: I don't have native compilation set up, so I cannot say anything about that part of it]

I tried the following script:

(message "FOO/")
(require 'package)
(add-to-list 'package-archives
             ;; choose either the stable or the latest git version:
             ;;'("melpa-stable" . "http://melpa-stable.org/packages/")
             '("melpa-unstable" . "http://melpa.org/packages/")
             )

(package-refresh-contents)
(setq package-selected-packages '(json-snatcher))
(message "%S" package-selected-packages)
(let ((byte-compile-warnings nil))       ;; or t
  (package-install-selected-packages t))
(message "/FOO")

and the following command line:

emacs -batch -l /tmp/foo.el

When I tried it with byte-compile-warnings set to t, I get the following output (complete):

FOO/
Importing package-keyring.gpg...
Importing package-keyring.gpg...done
Contacting host: melpa.org:80
Contacting host: melpa.org:80
Package refresh done
Contacting host: elpa.gnu.org:443
Package refresh done
Contacting host: elpa.nongnu.org:443
Package refresh done
(json-snatcher)
Contacting host: melpa.org:80
Parsing tar file... 
Parsing tar file...done
Extracting... \ 
Extracting...done
  INFO     Scraping files for loaddefs... 
  INFO     Scraping files for loaddefs...done
  GEN      json-snatcher-autoloads.el
Checking /home/nick/.config/emacs/elpa/json-snatcher-20200916.1717...
Compiling /home/nick/.config/emacs/elpa/json-snatcher-20200916.1717/json-snatcher-autoloads.el...
Compiling /home/nick/.config/emacs/elpa/json-snatcher-20200916.1717/json-snatcher-pkg.el...
Compiling /home/nick/.config/emacs/elpa/json-snatcher-20200916.1717/json-snatcher.el...

In toplevel form:
json-snatcher.el:79:2: Warning: defvar `jsons-parsed-regions' docstring wider than 80 characters

In jsons-get-path:
json-snatcher.el:205:2: Warning: docstring wider than 80 characters

In jsons-is-number:
json-snatcher.el:225:6: Warning: value from call to ‘match-end’ is unused
json-snatcher.el:229:14: Warning: value from call to ‘match-end’ is unused

In jsons-print-to-buffer:
json-snatcher.el:250:2: Warning: docstring wider than 80 characters

In jsons-print-path-python:
json-snatcher.el:308:2: Warning: docstring wider than 80 characters
Done (Total of 1 file compiled, 2 skipped)
Package ‘json-snatcher’ installed.
/FOO

With byte-compile-warnings set to nil I get this:

FOO/
Importing package-keyring.gpg...
Importing package-keyring.gpg...done
Contacting host: melpa.org:80
Contacting host: melpa.org:80
Package refresh done
Contacting host: elpa.gnu.org:443
Package refresh done
Package refresh done
(json-snatcher)
Contacting host: melpa.org:80
Parsing tar file... 
Parsing tar file...done
Extracting... \ 
Extracting...done
  INFO     Scraping files for loaddefs... 
  INFO     Scraping files for loaddefs...done
  GEN      json-snatcher-autoloads.el
Checking /home/nick/.config/emacs/elpa/json-snatcher-20200916.1717...
Compiling /home/nick/.config/emacs/elpa/json-snatcher-20200916.1717/json-snatcher-autoloads.el...
Compiling /home/nick/.config/emacs/elpa/json-snatcher-20200916.1717/json-snatcher-pkg.el...
Compiling /home/nick/.config/emacs/elpa/json-snatcher-20200916.1717/json-snatcher.el...
Done (Total of 1 file compiled, 2 skipped)
Package ‘json-snatcher’ installed.
/FOO

So it certainly makes a difference. I suspect that the messages you are seeing (in your example) are from native compilation (e.g. the first one about json-snatcher looks different from any of the ones I get from byte compilation), but I can't help with that.

As for the messages from package-install, you might be able to shut them off through Emacs means, but it is easier to use the shell. All of them are produced through message and, in batch mode, they are all redirected to stderr, so you can do something like this to shut them all off:

  emacs -batch -l /tmp/foo.el 2>/dev/null

or if you want to see the installed message, do this:

 emacs -batch -l /tmp/foo.el 2>&1 | grep 'Package .* installed\.'

which produces just this output:

Package ‘json-snatcher’ installed.

You can also play around with the regexp if you want to see a bit more. That's assuming some sort of Unix shell available and I/O redirection to match: I don't know what Emacs does on Windows and whether you can do this in WSL e.g. but it should work fine on Linux and other Unixes (including macOS).

1
  • 1
    This does help a lot, but filtering in shell really won't do in context (I do want to see warnings from the compilation of code I wrote myself, for instance). It makes sense that the byte compilation warnings are easier to suppress than the native compilation warnings, since native compilation uses a concurrency hack that involves re-executing emacs in a subprocess -- it might be more surprising if my let-bindings did carry over.
    – zwol
    Commented Jun 23, 2023 at 15:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.