From 8237aa9272ce1d13a412b2495cbaa90df38d928b Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Sat, 22 May 2021 20:38:51 +0100 Subject: [PATCH] feat(cli): add "emacs" CLI launcher script to Emacs.app/Conents/MacOS/bin This makes setting up a "emacs" terminal command that works with the self-contained Emacs.app bundle much simpler, as you just need to add Emacs.app/Conents/MacOS/bin to your PATH. For example, if you place Emacs.app in /Applications, add this to your shell setup: if [ -d "/Applications/Emacs.app/Contents/MacOS/bin" ]; then export PATH="/Applications/Emacs.app/Contents/MacOS/bin:$PATH" alias emacs="emacs -nw" # Always launch "emacs" in terminal mode. fi The launcher script works by figuring out it's own absolute path on disk, even if you are using a symlink to the script, it will resolve to correct real path. This allows it to execute the main Emacs.app/Contents/MacOS/Emacs executable via the correct path, so it can correctly pick up its dependencies from within the Emacs.app bundle. Fixes #41 --- README.md | 28 ++++++++++++---------------- build-emacs-for-macos | 13 +++++++++++++ helper/emacs-cli.bash | 23 +++++++++++++++++++++++ 3 files changed, 48 insertions(+), 16 deletions(-) create mode 100755 helper/emacs-cli.bash diff --git a/README.md b/README.md index 33b967f..200cf16 100644 --- a/README.md +++ b/README.md @@ -111,29 +111,25 @@ All sources as downloaded as tarballs from the to get a list of tags/branches available to install, simply check said repository. -## Use Self-Contained Emacs.app as `emacs` CLI Tool +## Use Emacs.app as `emacs` CLI Tool -As the application bundle is self-contained, the main executable needs to be run -from within the application bundle. This means a simple symlink to -`Emacs.app/Contents/MacOS/Emacs` will not work. Instead the best approach is to -create a shell alias called `emacs` pointing to the right place. +Builds come with a custom `emacs` shell script launcher for use from the command +line. It makes sure to use the main `Emacs.app/Contents/MacOS/Emacs` executable +from the correct path, ensuring it finds all the relevant dependencies within +the Emacs.app bundle. -Personally I use something similar to this: +To use it, simply add `Emacs.app/Contents/MacOS/bin` to your `PATH`. For +example, if you place Emacs.app in `/Applications`: ```bash -if [ -f "/Applications/Emacs.app/Contents/MacOS/Emacs" ]; then - export EMACS="/Applications/Emacs.app/Contents/MacOS/Emacs" - alias emacs="$EMACS -nw" -fi - -if [ -f "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient" ]; then - alias emacsclient="/Applications/Emacs.app/Contents/MacOS/bin/emacsclient" +if [ -d "/Applications/Emacs.app/Contents/MacOS/bin" ]; then + export PATH="/Applications/Emacs.app/Contents/MacOS/bin:$PATH" + alias emacs="emacs -nw" # Always launch "emacs" in terminal mode. fi ``` -Setting the `EMACS` variable to the binary path seems to be a good idea, as some -tools seems to use it to figure out the path to Emacs' executable, including -[doom-emacs](https://github.com/hlissner/doom-emacs)' `doom` CLI tool. +If you want `emacs` in your terminal to launch a GUI instance of Emacs, don't +use the alias from the above example. ## Native-Comp diff --git a/build-emacs-for-macos b/build-emacs-for-macos index 4cd1ea5..5ddd271 100755 --- a/build-emacs-for-macos +++ b/build-emacs-for-macos @@ -103,6 +103,7 @@ class Build app = compile_source(@source_dir) symlink_internals(app) + add_cli_helper(app) LibEmbedder.new(app, brew_dir, extra_libs).embed GccLibEmbedder.new(app, gcc_info).embed if options[:native_comp] @@ -373,6 +374,18 @@ class Build end end + def add_cli_helper(app) + source = File.join(__dir__, 'helper', 'emacs-cli.bash') + target = File.join(app, 'Contents', 'MacOS', 'bin', 'emacs') + dir = File.dirname(target) + + info "Adding \"emacs\" CLI helper to #{dir}" + + FileUtils.mkdir_p(dir) + FileUtils.cp(source, target) + FileUtils.chmod('+w', target) + end + def archive_filename return @archive_filename if @archive_filename diff --git a/helper/emacs-cli.bash b/helper/emacs-cli.bash new file mode 100755 index 0000000..f8a6ddb --- /dev/null +++ b/helper/emacs-cli.bash @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +resolve_link() { + "$(type -p greadlink readlink | head -1)" "$1" +} + +abs_dirname() { + local path="$1" + local name + local cwd + cwd="$(pwd)" + + while [ -n "$path" ]; do + cd "${path%/*}" || exit 1 + name="${path##*/}" + path="$(resolve_link "$name" || true)" + done + + pwd + cd "$cwd" || exit 1 +} + +exec "$(dirname "$(abs_dirname "$0")")/Emacs" "$@"