Skip to content

Instantly share code, notes, and snippets.

@zk
Last active July 29, 2023 12:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zk/30fc8403733f7f99f3fbacf148cd6807 to your computer and use it in GitHub Desktop.
Save zk/30fc8403733f7f99f3fbacf148cd6807 to your computer and use it in GitHub Desktop.
redbean single-file distributable web server: how to edit as archive in emacs

Hack to edit redbean files as archives in Emacs

Redbean is an insanely cool ball of hacks that result in a single binary webserver that is fast, contains a dynamic language interpreter (Lua), and can serve files out of itself by acting like a zip file. Mind blowing.

Unfortunately Emacs' archive-mode, which allows you to manipulate the files in a zip as if it were a filesystem tree doesn't know how to open redbean files.

Here's a quick hack to enable this:

  1. Download redbean curl https://redbean.dev/redbean-latest.com >redbean.com
  2. Open in Emacs emacs ./redbean.com
  3. Try to force archive mode: M-: (archive-mode) RET -> breaks
  4. M-x find-function RET archive-mode RET
  5. Edit archive-mode:
(defun archive-mode (&optional force)
  "Major mode for viewing an archive file in a dired-like way.
You can move around using the usual cursor motion commands.
Letters no longer insert themselves.\\<archive-mode-map>
Type \\[archive-extract] to pull a file out of the archive and into its own buffer;
or click mouse-2 on the file's line in the archive mode buffer.

If you edit a sub-file of this archive (as with the \\[archive-extract] command) and
save it, the contents of that buffer will be saved back into the
archive.

\\{archive-mode-map}"
  ;; This is not interactive because you shouldn't be turning this
  ;; mode on and off.  You can corrupt things that way.
  (if (zerop (buffer-size))
      ;; At present we cannot create archives from scratch
      (funcall (or (default-value 'major-mode) #'fundamental-mode))
    (if (and (not force) archive-files) nil
      (kill-all-local-variables)
      (let* ((type (archive-find-type)) <--- HERE
	     (typename (capitalize (symbol-name type))))
	(setq-local archive-subtype type)
  ...
  1. Change line <--- HERE to (let* ((type 'zip)
  2. M-x eval-defun RET
  3. Open redbean.com buffer
  4. M-: (archive-mode) RET

This should open a dired-style buffer and let you visit and modify any file in the redbean.

Don't forget to undo your changes to archive-mode when you're done.

Have fun!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment