624125dc06
I run two instances of Emacs on my MacOS laptop ... one for "work" and another for IRC, et.al. This explains some of what I'm doing.
220 lines
7.1 KiB
Org Mode
220 lines
7.1 KiB
Org Mode
#+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
|
||
#+end_src
|
||
And the following for “work”:
|
||
#+begin_src sh
|
||
brew install emacs-plus@29 --with-native-comp
|
||
#+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
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||
<plist version="1.0">
|
||
<dict>
|
||
<key>KeepAlive</key>
|
||
<true/>
|
||
<key>Label</key>
|
||
<string>gnu.emacs</string>
|
||
<key>ProgramArguments</key>
|
||
<array>
|
||
<string>/opt/homebrew/bin/emacs</string>
|
||
<string>--fg-dæmon</string>
|
||
</array>
|
||
<key>RunAtLoad</key>
|
||
<true/>
|
||
<key>StandardErrorPath</key>
|
||
<string>/tmp/gnu-emacs-dæmon.log</string>
|
||
<key>StandardOutPath</key>
|
||
<string>/tmp/gnu-emacs-dæmon.log</string>
|
||
<key>UserName</key>
|
||
<string>howard</string>
|
||
</dict>
|
||
</plist>
|
||
#+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
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||
<plist version="1.0">
|
||
<dict>
|
||
<key>KeepAlive</key>
|
||
<true/>
|
||
<key>Label</key>
|
||
<string>periodic.mbsync</string>
|
||
<key>ProgramArguments</key>
|
||
<array>
|
||
<string>/Users/USERNAME/.bin/mbsync-task</string>
|
||
</array>
|
||
|
||
<key>StandardOutPath</key>
|
||
<string>/tmp/mbsync-task.log</string>
|
||
|
||
<key>StandardErrorPath</key>
|
||
<string>/tmp/mbsync-task.log</string>
|
||
|
||
<key>ThrottleInterval</key>
|
||
<integer>180</integer>
|
||
|
||
<key>RunAtLoad</key>
|
||
<true/>
|
||
|
||
<key>UserName</key>
|
||
<string>howard</string>
|
||
</dict>
|
||
</plist>
|
||
#+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
|