2025-08-21
       Tags: emacs
 (IMG) image
       
       I have  a slight problem wherein every time  I  start up a game  of
       NetHack,  I completely lose touch with my surroundings for hours on
       end.
       Thankfully  The  DevTeam Thinks Of  Everything  [1]  and  there's a
       solution that allows communication with the outside  world  without
       breaking immersion: the mail daemon!
       
       If compiled with `-DMAIL` and `OPTIONS=mail` is
       set in  your runtime configuration (the default on Linux),  NetHack
       will   periodically    check   a    user    specified   mbox   file
       (`MAIL`) for new mail, and upon receiving an email a mail
       daemon will spawn in and deliver a scroll of mail to the player.
       Upon reading this  scroll a mail  program  (`MAILREADER`)
       will be executed, which hopefully allows you to read your mail.
       
       I use the Lisp  window  port  [2]  to  play NetHack  (the  way  God
       intended), and I really don't like leaving Emacs, so let's
       figure out how to integrate this feature with mu4e.
       `mu`  uses maildir  [3]), not  mbox [4],  so  I
       decided  to write a cron  job that periodically converts my maildir
       to mbox format.
       
       An important insight is that NetHack  never checks the  contents of
       the mailbox file, just the `mtime`.
       Therefore  all  our script  needs  to  do is  check  if our maildir
       contains any messages received within the last n minutes, and if so
       `touch` the mbox file.
       import os
       import mailbox
       from datetime import datetime, timedelta
       import pathlib
       
       MAILDIR = os.path.expanduser("~/Mail/personal/INBOX")
       MBOX = "/tmp/nh.mbox"
       
       maildir = mailbox.Maildir(MAILDIR)
       for msg in maildir:
           if datetime.fromtimestamp(msg.get_date()) > datetime.now() - timedelta(minutes=5):
               pathlib.Path(MBOX).touch()
               break
       maildir.close()
       
       Next, we need a script that will open up mu4e.
       emacsclient -n --eval "(progn (require 'mu4e) (mu4e-context-switch nil \"Personal\") (mu4e-search-bookmark \"maildir:/personal/INBOX AND flag:unread\"))"
       
       I'm using `emacsclient`  instead of  plain  old
       `emacs` partly because  only one process  at  a
       time can hold the lock on `mu`'s database, so I
       don't want to spin up another Emacs process.
       It's       also        worth        mentioning        that       my
       `emacsclient` is wrapped such  that it  opens a
       new frame if invoked outside of Emacs and  reuses the current frame
       if invoked from within Emacs, so this behaves as you  would expect,
       even if I'm using e.g. the curses port in a separate terminal.
       export _t='-c'
       exec "/nix/store/...-emacs/bin/.emacsclient-wrapped"  "${_t/${INSIDE_EMACS:+*}/-u}" -a /nix/store/...-emacs/Applications/Emacs.app/Contents/MacOS/Emacs "$@"
       
       Here's some riveting gameplay footage of dungeon level 1:
 (GIF) image
       
       
       References:
 (HTM)   [1] The DevTeam Thinks Of Everything
 (HTM)   [2] Lisp window port
 (HTM)   [3] maildir
 (HTM)   [4] mbox
       >=================================================================<
       
 (DIR) Blog
 (DIR) Writeups
 (DIR) jp
       
       copyright 2026 George Huebner
 (HTM) email