An open API service indexing awesome lists of open source software.

https://github.com/d12frosted/homebrew-emacs-plus

Emacs Plus formulae for the Homebrew package manager
https://github.com/d12frosted/homebrew-emacs-plus

brew doom-emacs emacs homebrew spacemacs

Last synced: 20 days ago
JSON representation

Emacs Plus formulae for the Homebrew package manager

Awesome Lists containing this project

README

          

#+begin_html


Banner


Emacs Plus




Build Status


Nightly Status


Cask Build Status

Sponsor


#+end_html

** About

Emacs+ is [[https://www.gnu.org/software/emacs/emacs.html][→ GNU Emacs]] formulae for macOS [[https://brew.sh][→ Homebrew]] package manager. It offers a wide range of extra functionality over regular [[https://formulae.brew.sh/formula/emacs#default][→ Emacs]] package. Emacs+ intent is to give the most of 'plus' stuff by default, leaving only controversial options as opt-in. Please refer to [[#options][→ Options]] section for more information.

#+begin_src bash
$ brew tap d12frosted/emacs-plus

# Pre-built binaries (fast, ~1 min)
$ brew install --cask emacs-plus-app # latest stable
$ brew install --cask emacs-plus-app@master # nightly from master

# Build from source (customizable, ~30 min)
$ brew install emacs-plus [options] # latest stable
$ brew install emacs-plus@master [options] # from master
#+end_src

#+begin_html


Screenshot


#+end_html

Feel free to open an issue or contact me via email if you face any issues, questions or feature requests. I love pull requests, so do send them. You might want to check [[docs/development-guidelines.org][→ Development guidelines]] to have better understanding on how to contribute.

For recent changes, see [[./NEWS.org][→ News]].

** Table of Contents :TOC_3:
- [[#about][About]]
- [[#install][Install]]
- [[#pre-built-binaries-cask][Pre-built binaries (Cask)]]
- [[#build-from-source-formula][Build from source (Formula)]]
- [[#installing-from-feature-branch][Installing from feature branch]]
- [[#reinstall][Reinstall]]
- [[#build-configuration][Build Configuration]]
- [[#available-options][Available Options]]
- [[#native-compilation-environment-cask][Native Compilation Environment (Cask)]]
- [[#emacs-32][Emacs 32]]
- [[#included][Included]]
- [[#options][Options]]
- [[#no-title-bar][No title bar]]
- [[#emacs-31][Emacs 31]]
- [[#included-1][Included]]
- [[#options-1][Options]]
- [[#no-title-bar-1][No title bar]]
- [[#emacs-30][Emacs 30]]
- [[#included-2][Included]]
- [[#options-2][Options]]
- [[#no-title-bar-2][No title bar]]
- [[#emacs-29][Emacs 29]]
- [[#included-3][Included]]
- [[#options-3][Options]]
- [[#no-title-bar-3][No title bar]]
- [[#features-explained][Features explained]]
- [[#injected-path][Injected PATH]]
- [[#detecting-emacs-plus][Detecting Emacs Plus]]
- [[#emacs-clientapp][Emacs Client.app]]
- [[#no-titlebar][No Titlebar]]
- [[#xwidgets-webkit][Xwidgets (webkit)]]
- [[#system-appearance-change][System appearance change]]
- [[#gccemacs][gccemacs]]
- [[#community-features][Community Features]]
- [[#icons][Icons]]
- [[#emacs-configuration][Emacs configuration]]
- [[#known-issues][Known Issues]]
- [[#emacs-dependency-in-other-formulas][=emacs= dependency in other formulas]]
- [[#old-versions][Old versions]]
- [[#emacs-28][Emacs 28]]
- [[#emacs-27][Emacs 27]]
- [[#emacs-26][Emacs 26]]
- [[#faq][FAQ]]
- [[#how-to-pin-a-specific-commit][How to pin a specific commit]]
- [[#screenshots][Screenshots]]
- [[#acknowledgements][Acknowledgements]]

** Install

*** Pre-built binaries (Cask)

For fast installation without compilation (~1 min), pre-built binaries are available:

#+begin_src bash
$ brew tap d12frosted/emacs-plus
$ brew install --cask emacs-plus-app # latest stable
$ brew install --cask emacs-plus-app@master # nightly from master
#+end_src

Cask builds are self-contained applications with all dependencies bundled. They include:

- Native compilation (AOT)
- =xwidgets=, =tree-sitter=, =mailutils=
- =Emacs.app= and =Emacs Client.app=
- Default Emacs icon

*Cask vs Formula:*

| Feature | Cask (=--cask=) | Formula |
|----------------------+------------------------+---------------------------|
| Install time | ~1 minute (download) | ~30 minutes (compile) |
| Custom build options | No | Yes (icons, patches, etc) |
| macOS versions | ARM64: 13+, Intel: 15+ | Any supported |
| Architectures | ARM64 and Intel | Any |

*Note:* Cask builds are architecture and macOS version specific. ARM64 has dedicated builds for Sonoma (14), Sequoia (15), and Tahoe (26); Ventura (13) users get the Sonoma build. Intel has a single Sequoia (15) build.

Use the *formula* if you need custom icons, patches, or specific build options. Use the *cask* for quick installation with sensible defaults.

*** Build from source (Formula)

For custom build options (~30 min compile time):

#+begin_src bash
$ brew tap d12frosted/emacs-plus
$ brew install emacs-plus [options] # latest stable
$ brew install emacs-plus@master [options] # from master
#+end_src

Versioned formulas are also available: =emacs-plus@32=, =emacs-plus@31=, =emacs-plus@30=, =emacs-plus@29=, etc. The =emacs-plus@master= alias points to the current development version (=emacs-plus@32=).

By default, formulas build Cocoa Emacs with =gnutls=, =librsvg=, =libxml2=, =tree-sitter=, =webp=, native compilation, dynamic modules, and multicolor fonts. See [[#options][→ Options]] for customization.

*** Installing from feature branch

Sometimes you might want to install from a feature branch. In that case you can switch the branch in the tap and install Emacs+ again.

Prerequisites are:

- Emacs+ is tapped (e.g. =brew tap d12frosted/emacs-plus=).
- =jq= is available (e.g. =brew install jq=).

Open terminal and type the following commands (don't forget to use correct Emacs+ version, branch and options):

#+begin_src bash
$ brew uninstall emacs-plus@29
$ cd $(brew tap-info --json d12frosted/emacs-plus@29 | jq -r '.[0].path') && git switch BRANCH
$ brew install emacs-plus@29 [OPTIONS]
#+end_src

** Reinstall

If you wish to reinstall =emacs-plus= with you should not use =reinstall= command of =brew= (not related to this formula, it's a general advice). Instead, you should =uninstall= a package and then =install= it with desired options.

Avoid =reinstall= even if you want to =reinstall= with the same set of options, otherwise you will likely to get compilation errors! For example, [[https://github.com/d12frosted/homebrew-emacs-plus/issues/218][#218]] and [[https://github.com/d12frosted/homebrew-emacs-plus/issues/321][#321]].

In short, =brew= doesn't really support options. They break time to time ([[https://github.com/Homebrew/brew/issues/4793][brew#4793]], [[https://github.com/Homebrew/brew/issues/7397][brew#7397]], [[https://github.com/Homebrew/brew/issues/7498][brew#7498]] to show a few).

#+BEGIN_SRC bash
$ brew uninstall emacs-plus
$ brew install emacs-plus [options]
#+END_SRC

** Build Configuration

Emacs+ can be configured using =~/.config/emacs-plus/build.yml=. This file controls options that are applied during installation (formula) or post-installation (cask).

The configuration file is searched in this order:
1. Path specified by =HOMEBREW_EMACS_PLUS_BUILD_CONFIG= environment variable
2. =~/.config/emacs-plus/build.yml=
3. =~/.emacs-plus-build.yml= (fallback)

#+begin_src yaml
# Example build.yml
icon: dragon-plus
patches:
- fix-window-role
inject_path: true
#+end_src

*** Available Options

| Option | Default | Description |
|---------------+---------+------------------------------------------------------------------------------|
| =icon= | /none/ | Custom icon to apply. See [[./community/icons/README.md][→ Icons Gallery]] for available icons. |
| =patches= | /none/ | (Formula only) List of community patches to apply. See [[#community-features][→ Community Features]]. |
| =revision= | /none/ | (Formula only) Pin Emacs source to a specific git revision. |
| =inject_path= | =true= | (Formula only) Inject user's PATH into Emacs.app. See [[#injected-path][→ Injected PATH]]. |

For more customization options, see [[#community-features][→ Community Features]] for patches and [[#icons][→ Icons]] for icon customization.

** Emacs 32

*** Included

By default =emacs-plus@32= uses the following features.

- Injected =PATH= value from user shell (see separate section explaining this feature).
- Cocoa version, e.g. builds =Emacs.app= and =Emacs Client.app= (see [[#emacs-clientapp][→ Emacs Client.app]] for details).
- Unconditional support for =gnutls=, =librsvg=, =webp=, =libxml2=, =little-cms2=, =tree-sitter= and dynamic modules.
- Build with native compilation.

*** Options

| Option | Description |
|---------------------------+---------------------------------------------------------------------------|
| =--with-compress-install= | build with compressed install optimization |
| =--with-dbus= | build with dbus support |
| =--with-debug= | build with debug symbols and debugger friendly optimizations |
| =--with-mailutils= | build with mailutils support |
| =--with-x11= | build with x11 support (disables Cocoa, no =Emacs.app= bundle) |
| =--with-xwidgets= | build [[#xwidgets-webkit][→ with xwidgets]] support |
| =--without-cocoa= | build a non-Cocoa version of Emacs (terminal only, no =Emacs.app= bundle) |

*Note:* Options =--with-x11= and =--without-cocoa= produce terminal/X11 builds that do not include =Emacs.app=. Icon options are ignored for these builds.

*** No title bar
Please note, that ~--with-no-titlebar~ is no longer needed in Emacs 30+, since the same can be achieved natively using [[https://github.com/d12frosted/homebrew-emacs-plus#emacs-29-1][this method]].

** Emacs 31

*** Included

By default =emacs-plus@31= uses the following features.

- Injected =PATH= value from user shell (see separate section explaining this feature).
- Cocoa version, e.g. builds =Emacs.app= and =Emacs Client.app= (see [[#emacs-clientapp][→ Emacs Client.app]] for details).
- Unconditional support for =gnutls=, =librsvg=, =webp=, =libxml2=, =little-cms2=, =tree-sitter= and dynamic modules.
- Build with native compilation.

*** Options

| Option | Description |
|---------------------------+---------------------------------------------------------------------------|
| =--with-compress-install= | build with compressed install optimization |
| =--with-dbus= | build with dbus support |
| =--with-debug= | build with debug symbols and debugger friendly optimizations |
| =--with-mailutils= | build with mailutils support |
| =--with-x11= | build with x11 support (disables Cocoa, no =Emacs.app= bundle) |
| =--with-xwidgets= | build [[#xwidgets-webkit][→ with xwidgets]] support |
| =--without-cocoa= | build a non-Cocoa version of Emacs (terminal only, no =Emacs.app= bundle) |

*Note:* Options =--with-x11= and =--without-cocoa= produce terminal/X11 builds that do not include =Emacs.app=. Icon options are ignored for these builds.

*** No title bar
Please note, that ~--with-no-titlebar~ is no longer needed in Emacs 30+, since the same can be achieved natively using [[https://github.com/d12frosted/homebrew-emacs-plus#emacs-29-1][this method]].

** Emacs 30

*** Included

By default =emacs-plus@30= uses the following features.

- Injected =PATH= value from user shell (see separate section explaining this feature).
- Cocoa version, e.g. builds =Emacs.app= and =Emacs Client.app= (see [[#emacs-clientapp][→ Emacs Client.app]] for details).
- Unconditional support for =gnutls=, =librsvg=, =webp=, =libxml2=, =little-cms2=, =tree-sitter= and dynamic modules.
- Build with native compilation.

*** Options

| Option | Description |
|---------------------------+---------------------------------------------------------------------------|
| =--with-compress-install= | build with compressed install optimization |
| =--with-ctags= | don't remove the ctags executable that Emacs provides |
| =--with-dbus= | build with dbus support |
| =--with-debug= | build with debug symbols and debugger friendly optimizations |
| =--with-imagemagick= | build with =imagemagick= support |
| =--with-mailutils= | build with mailutils support |
| =--with-x11= | build with x11 support (disables Cocoa, no =Emacs.app= bundle) |
| =--with-xwidgets= | build [[#xwidgets-webkit][→ with xwidgets]] support |
| =--without-cocoa= | build a non-Cocoa version of Emacs (terminal only, no =Emacs.app= bundle) |

*Note:* Options =--with-x11= and =--without-cocoa= produce terminal/X11 builds that do not include =Emacs.app=. Icon options are ignored for these builds.

*** No title bar
Please note, that ~--with-no-titlebar~ is no longer needed in Emacs 30, since the same can be achieved natively using [[https://github.com/d12frosted/homebrew-emacs-plus#emacs-29-1][this method]].

** Emacs 29

*** Included

By default =emacs-plus@29= uses the following features.

- Injected =PATH= value from user shell (see separate section explaining this feature).
- Cocoa version, e.g. builds =Emacs.app=.
- Unconditional support for =gnutls=, =librsvg=, =libxml2=, =little-cms2=, =tree-sitter= and dynamic modules.

*** Options

| Option | Description |
|---------------------------+------------------------------------------------------------------------------|
| =--with-compress-install= | build with compressed install optimization |
| =--with-ctags= | don't remove the ctags executable that Emacs provides |
| =--with-dbus= | build with dbus support |
| =--with-debug= | build with debug symbols and debugger friendly optimizations |
| =--with-imagemagick= | build with =imagemagick= support |
| =--with-mailutils= | build with mailutils support |
| =--with-native-comp= | build with native compilation aka [[#gccemacs][→ gccemacs]] |
| =--with-no-frame-refocus= | disables frame re-focus (ie. closing one frame does not refocus another one) |
| =--with-x11= | build with x11 support (disables Cocoa, no =Emacs.app= bundle) |
| =--with-xwidgets= | build [[#xwidgets-webkit][→ with xwidgets]] support |
| =--without-cocoa= | build a non-Cocoa version of Emacs (terminal only, no =Emacs.app= bundle) |

*Note:* Options =--with-x11= and =--without-cocoa= produce terminal/X11 builds that do not include =Emacs.app=. Icon options are ignored for these builds.

*** No title bar
Please note, that ~--with-no-titlebar~ is no longer needed in Emacs 29, since the same can be achieved natively using [[https://github.com/d12frosted/homebrew-emacs-plus#emacs-29-1][this method]].

** Features explained

*** Injected PATH

#+begin_quote
Ever find that a command works in your shell, but not in Emacs?

(c) @purcell
#+end_quote

In macOS applications are started in the login environment, meaning that all user defined environment variables are not available in application process. In the most cases it's not a big deal, but in Emacs it becomes a source of troubles as we want to use binaries from the non-standard locations (for example, those installed via package managers).

There is a wonderful solution to overcome this problem, [[https://github.com/purcell/exec-path-from-shell][purcell/exec-path-from-shell]]. As with any package that is not preinstalled with Emacs, you need to discover it first, and then install it. And while being a well known package and popular package (top 100 on MELPA), not everyone install it. In addition, with =native-comp= feature you might need it's functionality before any package is bootstrapped.

**** Formula builds

For formula builds (=brew install emacs-plus@30=), Emacs+ captures your shell's PATH at install time and injects it into =Emacs.app=. This makes your PATH available whenever you start =Emacs.app= from Finder, Dock, Spotlight, =open= command, or =launchd=. This solves a wide range of problems for GUI users without the need to use [[https://github.com/purcell/exec-path-from-shell][purcell/exec-path-from-shell]].

To disable PATH injection for formula builds, set =inject_path: false= in your =build.yml= and reinstall:

#+begin_src yaml
inject_path: false
#+end_src

In case you have a non-trivial setup relying on specific value of =PATH= inherited from current terminal session, it is advised to start Emacs using =/opt/homebrew/bin/emacs= instead of =open -n -a /path/to/Emacs.app=, because =open= messes around with =PATH= value even without Emacs+ injection. You can find more information in [[https://github.com/d12frosted/homebrew-emacs-plus/issues/469][#469]].

**** Cask builds

For cask builds (=brew install --cask emacs-plus-app=), PATH injection is *not available* due to a Homebrew limitation - cask postflight doesn't have access to the user's shell environment. Native compilation still works because =CC= and =LIBRARY_PATH= are injected.

Cask users who need their shell PATH in Emacs should use [[https://github.com/purcell/exec-path-from-shell][purcell/exec-path-from-shell]]:

#+begin_src elisp
(exec-path-from-shell-initialize)
#+end_src

If you need full PATH injection, use the formula instead of the cask.

*** Detecting Emacs Plus

Starting with =emacs-plus@30=, =emacs-plus@31=, and =emacs-plus@32=, the following variables are defined in =site-start.el=:

| Variable | Description |
|-------------------------------+-----------------------------------------------------------------------|
| =ns-emacs-plus-version= | Major version of Emacs Plus (e.g., 30, 31, or 32) |
| =ns-emacs-plus-injected-path= | Non-nil if user PATH was injected (formula with =inject_path: true=) |

This allows you to detect Emacs Plus and conditionally configure your init.el:

#+begin_src elisp
(when (bound-and-true-p ns-emacs-plus-version)
;; Emacs Plus specific configuration
)

;; Skip exec-path-from-shell if PATH was already injected
(unless (bound-and-true-p ns-emacs-plus-injected-path)
(exec-path-from-shell-initialize))

;; Check specific version
(when (and (bound-and-true-p ns-emacs-plus-version)
(>= ns-emacs-plus-version 31))
;; Emacs Plus 31+ specific
)
#+end_src

This is useful for conditionally enabling features that are specific to Emacs Plus, such as the =ns-system-appearance-change-functions= hook.

*** Emacs Client.app

Starting with =emacs-plus@30=, =emacs-plus@31=, and =emacs-plus@32=, the formula includes a companion application called =Emacs Client.app=. This application provides a user-friendly way to open files in Emacs from Finder, Spotlight, and other macOS applications.

**** When to use Emacs.app vs Emacs Client.app

| Application | Use Case |
|--------------------+---------------------------------------------------------------------------------------------------|
| *Emacs.app* | Launch Emacs directly, start a new Emacs session, or when you want full control over the instance |
| *Emacs Client.app* | Open files from Finder, set as default application for file types, quick file editing |

**** How it works

=Emacs Client.app= connects to an existing Emacs daemon (or starts one automatically) using =emacsclient=. This means:

- *Fast startup* - No need to launch a full Emacs instance for each file
- *Shared session* - All files opened via Emacs Client appear in the same Emacs session
- *Seamless integration* - Works with "Open With" in Finder, drag-and-drop, and can be set as the default application for text files
- *org-protocol support* - Handles =org-protocol://= URLs for org-capture, org-roam, and other integrations

**** Usage

After installation, create aliases in =/Applications= (the formula will suggest these commands in the caveats):

#+begin_src bash
# Get the installation prefix (use emacs-plus@30, emacs-plus@31, or emacs-plus@32)
PREFIX=$(brew --prefix emacs-plus@30)

# Create aliases in /Applications
osascript -e 'tell application "Finder" to make alias file to posix file "'$PREFIX'/Emacs.app" at posix file "/Applications" with properties {name:"Emacs.app"}'
osascript -e 'tell application "Finder" to make alias file to posix file "'$PREFIX'/Emacs Client.app" at posix file "/Applications" with properties {name:"Emacs Client.app"}'
#+end_src

You can then:
- Right-click files in Finder → "Open With" → "Emacs Client"
- Drag files onto the Emacs Client.app icon
- Set Emacs Client as the default application for specific file types
- Launch from Spotlight to create a new Emacs frame
- Use =org-protocol://= URLs from browser extensions (requires =(require 'org-protocol)= in your init file)

The implementation uses AppleScript to properly handle macOS AppleEvents, ensuring files opened from Finder are correctly passed to =emacsclient=. PATH injection works the same as in =Emacs.app= (see [[#injected-path][→ Injected PATH]]).

For more details, see [[file:docs/emacs-client-app.md][→ docs/emacs-client-app.md]].

*** No Titlebar

| square corners | round corners |
|---------------------------------------------------+--------------------------------------------------|
| [[/images/screenshot-no-titlebar-square-corners.png]] | [[/images/screenshot-no-titlebar-round-corners.png]] |

**** Emacs 28 and Emacs 27

This patch is enabled with the =--with-no-titlebar= option for =emacs-plus@27= and =emacs-plus@28=. It is meant for use with window tiling applications like [[https://github.com/koekeishiya/yabai][→ yabai]] or [[https://github.com/ianyh/Amethyst][→ amethyst]] so that the titlebar won't take up screen real estate.

Use =--with-no-titlebar-and-round-corners= option (instead of =--with-no-titlebar=), if you want to keep round corners (for example, to be consistent with other macOS applications).

If you see gaps between your emacs frames and other windows, try this:

#+BEGIN_SRC emacs-lisp
(setq frame-resize-pixelwise t)
#+END_SRC

**** Emacs 29+

In =emacs-plus@29=, =emacs-plus@30=, =emacs-plus@31=, and =emacs-plus@32= this option is not available anymore as you can achieve the same result using Emacs Lisp by adding the following line in your =early-init.el= file:

#+begin_src emacs-lisp
(add-to-list 'default-frame-alist '(undecorated . t))
#+end_src

Add the following line instead for round corners:

#+begin_src emacs-lisp
(add-to-list 'default-frame-alist '(undecorated-round . t))
#+end_src

*** Xwidgets (webkit)

Browse the web in Emacs as in modern browser.

The original [[https://www.emacswiki.org/emacs/EmacsXWidgets][→ Emacs xwidgets]] builds and works on macOS however must be used with X11 and hence not practical option on macOS. This version enables =xwidgets= on native macOS Cocoa via embedding a native webkit window.

More details can be seen here [[https://github.com/veshboo/emacs][→ Veshboo's emacs branch]].

*** System appearance change

This patch is enabled by default and can't be disabled. It adds a hook, =ns-system-appearance-change-functions=, that is called once the system appearance is changed. Functions added to this hook will be called with one argument, a symbol that is either =light= or =dark=. This mainly allows loading a different theme to better match the system appearance.

#+begin_src emacs-lisp
(defun my/apply-theme (appearance)
"Load theme, taking current system APPEARANCE into consideration."
(mapc #'disable-theme custom-enabled-themes)
(pcase appearance
('light (load-theme 'tango t))
('dark (load-theme 'tango-dark t))))

(add-hook 'ns-system-appearance-change-functions #'my/apply-theme)
#+end_src

Note that this hook is also run once when Emacs is initialized, so simply adding the above to your =init.el= will allow matching the system appearance upon startup. You can also determine what the current system appearance is by inspecting the value of the =ns-system-appearance= variable.

The hook is NOT run in TTY Emacs sessions.

*** gccemacs

#+begin_quote
gccemacs is a modified Emacs capable of compiling and running Emacs Lisp as native code in form of re-loadable elf files. As the name suggests this is achieved blending together Emacs and the gcc infrastructure.

[[https://akrl.sdf.org/gccemacs.html][→ Andrea Corallo]]
#+end_quote

While =gccemacs= gives performance boost in many scenarios, this feature is still experimental and might require time and effort from your side for it to work! Use at our own risk :)

Please see official [[https://akrl.sdf.org/gccemacs.html][→ gccemacs documentation]] for more information.

Knows issues:

- =ld: library not found for -lSystem=. This only happens on older versions of =gcc= installed by Homebrew. Please execute =$ brew reinstall gcc libgccjit= to resolve this issue.
- Errors during compilation of your =init.el=. Try running Emacs with =-Q= option and give it some time to compile everything (maybe run =M-x= to force compilation) - you shall see buffer =*Async-native-compile-log*= in the list of buffers.

** Community Features

Emacs+ supports custom patches and icons through a configuration file. This allows you to use community-maintained features or your own external resources.

Create =~/.config/emacs-plus/build.yml=:

#+begin_src yaml
# Use a community icon (see community/registry.json for available options)
icon: modern-purple-flat

# Use an external icon (requires SHA256 verification)
# icon:
# url: https://example.com/my-icon.icns
# sha256: abc123...

# Pin to a specific git revision (version-specific)
# revision:
# "30": abc123def456
# "31": 789abcdef123

# Apply community patches
# patches:
# - patch-name-from-registry
# - my-patch:
# url: https://example.com/external.patch
# sha256: abc123...
# - local-patch:
# url: ~/.config/emacs-plus/my-local.patch
# sha256: abc123...
#+end_src

Then rebuild Emacs:

#+begin_src bash
$ brew reinstall emacs-plus@30
#+end_src

For more information, see [[./community/README.md][→ Community Documentation]].

** Icons

Emacs+ supports 76 custom icons. To use one, add it to your =~/.config/emacs-plus/build.yml=:

#+begin_src yaml
icon: dragon-plus
#+end_src

See the [[./community/icons/README.md][→ Icons Gallery]] for all available icons with previews.

#+begin_quote
*Note*: The =--with-*-icon= command line options are deprecated and will be removed on 2026-03-14. Please migrate to using =build.yml=.
#+end_quote

** Emacs configuration

Emacs is a journey. And for some of you these projects might be inspiring.

- [[https://github.com/purcell/emacs.d][→ Steve Purcell's .emacs.d]]
- [[https://github.com/syl20bnr/spacemacs/][→ Spacemacs]]
- [[https://github.com/hlissner/doom-emacs][→ doom-emacs]]
- [[https://github.com/bbatsov/prelude][→ Prelude]]
- [[https://github.com/seagle0128/.emacs.d][→ Centuar Emacs]]

** Known Issues

Please checkout [[https://github.com/d12frosted/homebrew-emacs-plus/issues][→ Issues]] page for a list of all known issues. But here are several you should be aware of.

*** =emacs= dependency in other formulas

In some cases (like when installing =cask=) regular =emacs= package will be required. In such cases you might want to install all dependencies manually (except for =emacs=) and then install desired package with =--ignore-dependencies= option.

#+BEGIN_SRC bash
$ brew install cask --ignore-dependencies
#+END_SRC

** Old versions

This repository provides formulas for some older version. Feel free to use them, but they are not really supported anymore.

#+begin_src bash
$ brew tap d12frosted/emacs-plus
$ brew install emacs-plus@28 [options] # install Emacs 28
$ brew install emacs-plus@27 [options] # install Emacs 27
$ brew install emacs-plus@26 [options] # install Emacs 26
#+end_src

*** Emacs 28

**** Included

By default =emacs-plus@28= uses the following features.

- Injected =PATH= value from user shell (see separate section explaining this feature).
- Cocoa version, e.g. builds =Emacs.app=.
- Unconditional support for =gnutls=, =librsvg=, =libxml2=, =little-cms2= and dynamic modules.

**** Options

| Option | Description |
|----------------------------------------+------------------------------------------------------------------------------|
| =--with-ctags= | don't remove the ctags executable that Emacs provides |
| =--with-dbus= | build with dbus support |
| =--with-debug= | build with debug symbols and debugger friendly optimizations |
| =--with-mailutils= | build with mailutils support |
| =--with-no-frame-refocus= | disables frame re-focus (ie. closing one frame does not refocus another one) |
| =--with-no-titlebar= | build [[#no-titlebar][→ without titlebar]] |
| =--with-no-titlebar-and-round-corners= | build [[#no-titlebar][→ without titlebar]], but round corners instead of square |
| =--with-x11= | build with x11 support (disables Cocoa, no =Emacs.app= bundle) |
| =--with-xwidgets= | build [[#xwidgets-webkit][→ with xwidgets]] support |
| =--without-cocoa= | build a non-Cocoa version of Emacs (terminal only, no =Emacs.app= bundle) |
| =--with-imagemagick= | build with =imagemagick= support |
| =--HEAD= | build from =emacs-28= branch |
| =--with-native-comp= | build with native compilation aka [[#gccemacs][→ gccemacs]] |
| | |

*Note:* Options =--with-x11= and =--without-cocoa= produce terminal/X11 builds that do not include =Emacs.app=. Icon options are ignored for these builds.

*** Emacs 27

**** Included

By default =emacs-plus@27= uses the following features.

- Cocoa version, e.g. builds =Emacs.app=.
- Unconditional support for =gnutls=, =librsvg=, =libxml2=, =little-cms2= and dynamic modules.

**** Options

| Option | Description |
|---------------------------+------------------------------------------------------------------------------|
| =--with-ctags= | don't remove the ctags executable that Emacs provides |
| =--with-dbus= | build with dbus support |
| =--with-debug= | build with debug symbols and debugger friendly optimizations |
| =--with-mailutils= | build with mailutils support |
| =--with-no-frame-refocus= | disables frame re-focus (ie. closing one frame does not refocus another one) |
| =--with-no-titlebar= | build [[#no-titlebar][→ without titlebar]] |
| =--with-x11= | build with x11 support (disables Cocoa, no =Emacs.app= bundle) |
| =--with-xwidgets= | build [[#xwidgets-webkit][→ with xwidgets]] support |
| =--without-cocoa= | build a non-Cocoa version of Emacs (terminal only, no =Emacs.app= bundle) |
| =--without-imagemagick= | build without =imagemagick= support |
| =--HEAD= | build from =emacs-27= branch |

*Note:* Options =--with-x11= and =--without-cocoa= produce terminal/X11 builds that do not include =Emacs.app=. Icon options are ignored for these builds.

*** Emacs 26

Emacs 26 comes without any available options due to [[https://github.com/d12frosted/homebrew-emacs-plus/issues/195][→ #195]].

** FAQ

*** How to pin a specific commit

Development versions (=emacs-plus@31=, =emacs-plus@32=) are built from their respective branches (=emacs-31=, =master=). Ordinarily, =brew= will update to the latest commit during installation.

As development versions are less stable than official releases, you may want to pin a specific commit. The recommended way is to use =~/.config/emacs-plus/build.yml=:

#+begin_src yaml
revision:
"31": 6abea4d98d1d964c68a78cb9b5321071da851654
"32": abc123def456789
#+end_src

Then install or reinstall:

#+begin_src bash
$ brew reinstall emacs-plus@30
#+end_src

The build will display the pinned revision during installation.

#+begin_quote
*Deprecated*: Environment variables =HOMEBREW_EMACS_PLUS_30_REVISION= and =HOMEBREW_EMACS_PLUS_31_REVISION= still work but are deprecated. Please migrate to =build.yml=.
#+end_quote

** Screenshots

#+BEGIN_HTML




#+END_HTML

#+BEGIN_HTML




#+END_HTML

** Acknowledgements

Many thanks to all [[https://github.com/d12frosted/homebrew-emacs-plus/graphs/contributors][→ contributors]], issue reporters and bottle providers ([[https://github.com/wadkar][→ Sudarshan Wadkar]], [[https://github.com/jonhermansen][→ Jon Hermansen]]).

* Support

If you enjoy this project, you can support its development via [[https://github.com/sponsors/d12frosted][GitHub Sponsors]] or [[https://www.patreon.com/d12frosted][Patreon]].