#+title: Installing Emacs on MacOS #+author: Howard X. Abrams #+email: howard.abrams@gmail.com #+date: 2022-09-02 September #+tags: emacs macos These instructions originally came from [[https://jherrlin.github.io/posts/emacs-on-macos-monterey/][this essay]], as it runs Emacs as dæmon with LaunchAgent. Also fetch mails periodically with =mbsync= via LaunchAgent. * Install Best success comes from using the [[https://github.com/d12frosted/homebrew-emacs-plus][emacs-plus]] installation from [[https://brew.sh/][Homebrew]]. To begin, add the /cask/: #+begin_src sh brew tap d12frosted/emacs-plus #+end_src I find that I need to … at least, on my work computer, install two different versions of Emacs that I use to distinguish one for “work” and the other for other activities, like IRC and [[file:ha-feed-reader.org][elfeed]]. To that end, I run the following commands to install Emacs: #+begin_src sh brew install emacs-plus@28 --with-native-comp --with-mailutils --with-imagemagick --with-elrumo2-icon #+end_src And the following for “work”: #+begin_src sh brew install emacs-plus@29 --with-native-comp --with-elrumo1-icon #+end_src * Supporting Packages Now install all the extras: #+begin_src sh brew install mu brew install isync brew install gpg #+end_src ** Mu4a See [[file:ha-email.org][ha-email]] for better instructions. #+begin_src sh mkdir -p ~/.mail/work ~/.mail/gmail mu init --maildir=~/.mail --my-address=howard.abrams@gmail.com --my-address=howard@howardabrams.com mu index mbsync -Va mu index #+end_src ** Mbsync config See [[file:ha-email.org][ha-email]] for better instructions. #+begin_src sh cat ~/.mbsyncrc #+end_src Basic configuration, that I actually supersede. #+begin_src conf # ========== Gmail ========== IMAPAccount gmail Host imap.gmail.com User username@gmail.com PassCmd "/opt/homebrew/bin/gpg --quiet --for-your-eyes-only --no-tty --decrypt ~/.password-store/mbsync/gmail.gpg" AuthMechs LOGIN SSLType IMAPS IMAPStore gmail-remote Account gmail MaildirStore gmail-local Subfolders Verbatim Path ~/.mail/gmail/ Inbox ~/.mail/gmail/Inbox Channel gmail Far :gmail-remote: Near :gmail-local: Patterns * ![Gmail]* "[Gmail]/Sent Mail" "[Gmail]/Starred" "[Gmail]/All Mail" Expunge None CopyArrivalDate yes Sync All Create Near SyncState * # ========== Gmail ========== #+end_src * Dæmon Processes On the Mac, =cron= has been removed and replaced with =LaunchAgent=. I find my [[file:ha-capturing-notes.org::*Push MacOS-Specific Content][ICanHazShortcut]] process pretty simple to start Emacs, so I’m not sure about this dæmon, but … ** Emacs dæmon via LaunchAgent Notice that =UserName= section should be your =$USER= value. #+begin_src xml :tangle ~/Library/LaunchAgents/gnu.emacs.plist KeepAlive Label gnu.emacs ProgramArguments /opt/homebrew/bin/emacs --fg-dæmon RunAtLoad StandardErrorPath /tmp/gnu-emacs-dæmon.log StandardOutPath /tmp/gnu-emacs-dæmon.log UserName howard #+end_src Verify that the plist file is correct. #+begin_src sh plutil -lint ~/Library/LaunchAgents/gnu.emacs.plist #+end_src Start, stop and list service. #+begin_src sh launchctl load -w /Users/USERNAME/Library/LaunchAgents/gnu.emacs.plist launchctl unload /Users/USERNAME/Library/LaunchAgents/gnu.emacs.plist launchctl list #+end_src ** Fetch mails periodically Let’s make another dæmon for fetching mail. Again, replace =UserName= with your user account name. #+begin_src xml :tangle ~/Library/LaunchAgents/periodic.mbsync.plist KeepAlive Label periodic.mbsync ProgramArguments /Users/USERNAME/.bin/mbsync-task StandardOutPath /tmp/mbsync-task.log StandardErrorPath /tmp/mbsync-task.log ThrottleInterval 180 RunAtLoad UserName howard #+end_src Verify that the plist file is correct. #+begin_src sh plutil -lint ~/Library/LaunchAgents/periodic.mbsync.plist #+end_src Start, stop and list service. #+begin_src sh launchctl load -w /Users/USERNAME/Library/LaunchAgents/periodic.mbsync.plist launchctl unload /Users/USERNAME/Library/LaunchAgents/periodic.mbsync.plist launchctl list #+end_src Script that fetches mails and updates the mail index. #+begin_src sh :tangle ~/.bin/mbsync-task :shebang #!/bin/bash echo "" echo "Running $(date +"%Y-%m-%d %H:%M")" /opt/homebrew/bin/mbsync -Va echo "Exit code:" echo $? /opt/homebrew/bin/emacsclient -e '(mu4e-update-index)' echo "Exit code:" echo $? #+end_src * Emacsclient Simple /Automator/ script that's wrapped into an application and placed in the =Applications= folder. Select *New Document*, then select *Application*. Open the *Library*, and drag the *Run Shell Script* to the /workflow/. In the box, add this: #+begin_src sh /usr/local/bin/emacsclient -nc --socket-name work $* #+end_src Change the *Pass Input* to =as arguments=. Select to *Save* as =Emacsclient= into the *Applications* folder. ** Utils Convert a plist XML file into a JSON file. Not sure why this is important to know… #+begin_src sh plutil -convert json -r ~/Library/LaunchAgents/gnu.emacs.plist #+end_src Which should look a bit like: #+begin_src js { "KeepAlive" : true, "Label" : "gnu.emacs", "ProgramArguments" : [ "\/opt\/homebrew\/bin\/emacs", "--fg-dæmon" ], "RunAtLoad" : true, "StandardErrorPath" : "\/tmp\/gnu-emacs-dæmon.log", "StandardOutPath" : "\/tmp\/gnu-emacs-dæmon.log", "UserName" : "USERNAME" } #+end_src Convert it back to XML #+begin_src sh plutil -convert xml1 ~/Library/LaunchAgents/gnu.emacs.plist #+end_src ** Resources #+begin_src sh man launchd man launchctl man launchd.plist man plutil man plist #+end_src #+DESCRIPTION: A literate programming file for installing a dæmon version of Emacs on MacOS. #+PROPERTY: header-args:sh :tangle no #+PROPERTY: header-args:emacs-lisp :tangle no #+PROPERTY: header-args :results none :eval no-export :comments no #+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil date:nil #+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil #+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js