hamacs/README-Linux.org
Howard Abrams 988c0dac2e Decided I like lowercase headers better
Oh, and let's fix the FILETAGS. Thank goodness for woccurrrrrr.
2024-03-06 20:02:25 -08:00

8.5 KiB
Raw Blame History

Installing Emacs on Ubuntu

These instructions originally came from this essay.

To get the native compilation for Emacs working, first install all the pre-reqs, and we seem to need a lot of them:

  sudo apt update
  sudo apt upgrade
  # Instead of this:
  sudo apt install -y build-essential autoconf
  # We can not just call this:
  sudo apt build-dep -y emacs

  # We will build using the GTK and related libraries,
  # instead of good ol' X11:
  sudo apt install -y libc6-dev libgtk-3-dev xaw3dg-dev \
       zlib1g-dev libice-dev libsm-dev libx11-dev libxext-dev

  # Nifty new stuff supported in Emacs needs libraries:
  sudo apt install -y libjansson4 libjansson-dev \
       gnutls-bin libtree-sitter-dev

  # I am not sure if/why we need these guys, but ...
  sudo apt install -y libxi-dev libxmu-dev libxmuu-dev \
       libxrandr-dev libxt-dev libxtst-dev libxv-dev \
       libattr1-dev

  # And install all the image libraries (otherwise, we need
  # the venerable imagemagick library):
  sudo apt install -y  libtiff5-dev libgif-dev  \
    libpng-dev libxpm-dev libncurses-dev libtiff-dev \
    libwebkit2gtk-4.0-dev libjpeg-dev
  # Or do we want the specific: libjpeg62-dev

Oh, and if we are still building with ImageMagick, install that too:

sudo apt-get install texinfo imagemagick

We need libgccjit that matches the GCC installed, e.g. 12:

GCC_VERSION=$(gcc --version | head -1 | cut -d' ' -f4 | cut -d. -f1)
sudo apt install libgccjit-${GCC_VERSION}-dev

Clone the Emacs repo, and jump on the latest, almost-released branch:

mkdir -p ~/other ; cd ~/other
git clone git://git.sv.gnu.org/emacs emacs
cd emacs

git checkout -b emacs29

Then lets build it:

./autogen.sh

./configure --with-native-compilation --with-cairo --with-json \
  --with-xml2 --with-mailutils --with-tree-sitter --with-pgtk \
  --with-gnutls=ifavailable --with-tiff=ifavailable \
  --program-suffix=30 \
    CFLAGS="-O3 -mtune=native -march=native -fomit-frame-pointer"

make -j$(nproc)  && sudo make install

Supporting Packages

Now install all the extras:

  sudo apt install -y libvterm-dev
  sudo apt install -y git-delta
  sudo apt install -y mu4e isync
  sudo apt install -y gpg

Mu4a

See ha-email for better instructions.

  mkdir -p ~/.mail/work ~/.mail/gmail
  mu init --maildir=~/.mail   mu index
  mbsync -Va
  mu index

Mbsync config

See ha-email for better instructions.

  cat ~/.mbsyncrc

Basic configuration, that I actually supersede.

  # ========== Gmail ==========
  IMAPAccount gmail
  Host imap.gmail.com
  User username@gmail.com
  PassCmd "/usr/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 ==========

Dæmon Processes

According to this essay, we have several ways to launch Emacs as a daemon during startup. Since systemd is the init daemon in v20+, we register Emacs as a service under systemd to be launched during startup. Systemd will monitor this service and restart if the service crashes for any reason. To configure the service, we first create the file ~/.config/systemd/user/emacs.service and copy the below:

[Unit]
Description=Emacs text editor
Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/

[Service]
Type=forking
ExecStart=/usr/local/bin/emacs --daemon
ExecStop=/usr/local/bin/emacsclient --eval "(kill-emacs)"
Environment=SSH_AUTH_SOCK=%t/keyring/ssh
Restart=on-failure

[Install]
WantedBy=default.target

Then run the following in the terminal:

systemctl enable --user emacs
systemctl start --user emacs

Verify that the emacs service is running by using:

systemctl status --user emacs

Now, we only use emacsclient. We have these terminal alias:

  • e: Open a terminal version
  • ee: Open an Emacs frame

Fetch mails periodically

Lets make another dæmon for fetching mail. Perhaps we should use gnubiff instead.

  [Unit]
  Description=Mbsync Mail Fetcher
  Documentation=https://www.systutorials.com/docs/linux/man/1-mbsync/

  [Service]
  Type=forking
  ExecStart=/usr/bin/mbsync --daemon
  ExecStop=/usr/bin/mbsync --eval "(kill-mbsync)"
  Environment=SSH_AUTH_SOCK=%t/keyring/ssh
  Restart=on-failure

  [Install]
  WantedBy=default.target
  <?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>

Verify that the plist file is correct.

  plutil -lint ~/Library/LaunchAgents/periodic.mbsync.plist

Start, stop and list service.

  launchctl load -w /Users/USERNAME/Library/LaunchAgents/periodic.mbsync.plist
  launchctl unload /Users/USERNAME/Library/LaunchAgents/periodic.mbsync.plist
  launchctl list

Script that fetches mails and updates the mail index.

  echo ""
  echo "Running $(date +"%Y-%m-%d %H:%M")"
  /usr/bin/mbsync -Va
  echo "Exit code:"
  echo $?
  /usr/local/bin/emacsclient -e '(mu4e-update-index)'
  echo "Exit code:"
  echo $?

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:

  /usr/local/bin/emacsclient -nc --socket-name work $*

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…

  plutil -convert json -r ~/Library/LaunchAgents/gnu.emacs.plist

Which should look a bit like:

  {
      "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"
  }

Convert it back to XML

  plutil -convert xml1 ~/Library/LaunchAgents/gnu.emacs.plist

Resources

  man launchd
  man launchctl
  man launchd.plist
  man plutil
  man plist