Emacs: Difference between revisions

From NixOS Wiki
imported>Aarmn
mNo edit summary
imported>LoganWalls
Re-organized page and added additional info about installing Emacs, the community overlay, and managing packages
Line 1: Line 1:
{{Expansion|This article is incomplete.}}
{{Expansion|This article is incomplete.}}
== About ==
Emacs is an interactive graphical emacs lisp interpreter that comes with many applications, but is primarily used as a text and code editor.  It has one of the largest repositories of packages of any similar code editor such as [[vim]] or its fork [[neovim]].


For reference use [https://nixos.org/nixos/manual/index.html#module-services-emacs the emacs chapter in the nixos manual].
== About ==
Emacs is an interactive graphical emacs lisp interpreter that comes with many applications, but is primarily used as a text and code editor.  It has one of the largest repositories of packages of any similar code editor such as {{ic|vim}} or its fork {{ic|neovim}}.
=== Features ===
=== Features ===
Emacs is often valued as a general purpose programming environment. Its power comes from its  
Emacs is often valued as a general purpose programming environment. Its power comes from its  
Line 13: Line 12:
* potential for reproducible portable literate configurations
* potential for reproducible portable literate configurations


{{tip|Emacs, much like NixOS can rebuild and re-fetch all of its packages based on its initialization file alone, if one chooses to use an extension called {{ic|(use-package)}}. Such a configuration file can be version controlled and used in all compatible operating systems.}}
=== Doom Emacs ===
The [https://github.com/hlissner/doom-emacs Doom Emacs] project provides a framework with a more beginner-friendly default configuration, and pre-configured modules for popular features (e.g. IDE-like features, note-taking, and time management). Since it uses pinning in its configuration for dependencies, it is possible to package Doom Emacs with nix (see [https://github.com/nix-community/nix-doom-emacs nix-doom-emacs])
 
== Installation ==
{{warning| Certain issues are possible, when mixing different versions of Emacs, in particular a configuration file tailored towards emacs with native compilation, may misbehave on non-native compiling versions, unless only the emacs lisp code is shared between them.}}
{{warning| Certain issues are possible, when mixing different versions of Emacs, in particular a configuration file tailored towards emacs with native compilation, may misbehave on non-native compiling versions, unless only the emacs lisp code is shared between them.}}


==== Emacs or emacs-gtk ====
Several stable versions of emacs are available by default in nixpkgs, and unstable branches are also available via the community overaly. Also, see the [https://nixos.org/manual/nixos/stable/index.html#module-services-emacs NixOS manual entry for Emacs] for additional details about installation and configuration.
 
=== With Home-Manager ===
{{file|home.nix|nix|<nowiki>
{
  programs.emacs = {
    enable = true;
    package = pkgs.emacs;  # replace with pkgs.emacs-gtk, or a version provided by the community overlay if desired.
    extraConfig = ''
      (setq standard-indent 2)
    '';
  };
}
</nowiki>}}
See the [https://rycee.gitlab.io/home-manager/options.html#opt-programs.emacs.enable Home-Manager manual] for a full list of options.
 
=== Without Home-Manager ===
Emacs can be installed in the same way as other packages:
{{file|configuration.nix|nix|<nowiki>
{
  environment.systemPackages = with pkgs; [
    emacs # replace with emacs-gtk, or a version provided by the community overlay if desired.
  ];
}
</nowiki>}}
 
=== Enabling the Emacs daemon ===
Many Emacs users run [https://www.emacswiki.org/emacs/EmacsAsDaemon Emacs as a daemon] and access Emacs via the <code>emacsclient</code> command. NixOS provides a <code>systemd</code> service to facilitate this, which you can enable by adding the following to your <code>configuration.nix</code>:
{{file|configuration.nix|nix|<nowiki>
{
  services.emacs = {
    enable = true;
    package = pkgs.emacs; # replace with emacs-gtk, or a version provided by the community overlay if desired.
  };
}
</nowiki>}}


Note that [https://github.com/NixOS/nixpkgs/pull/189543 since 2022-09], the package called <code>emacs</code> is now installing the lucid toolkit instead of gtk. The reason is that emacs is less stable with gtk especially in daemon mode. However, the lucid flavor of emacs will not take into account the gtk theme (since it is not even gtk) and looks quite… ugly (see comparisons [https://emacs.stackexchange.com/questions/33065/on-linux-why-should-one-choose-lucid-over-gtk-gui-for-emacs here]). If you still prefer the gtk version of emacs, you can install instead <code>emacs-gtk</code> (before 2022-09 this package does not exist and emacs defaults to the gtk version)


==== Unstable branches ====
==== Available Emacs variants ====
===== Stable (nixpkgs) =====
Emacs is available in nixpkgs under the names <code>emacs</code> and <code>emacs-gtk</code>.
[https://github.com/NixOS/nixpkgs/pull/189543 Since 2022-09], the package called <code>emacs</code> now installs the lucid toolkit instead of gtk. The reason is that emacs is less stable with gtk especially in daemon mode. However, the lucid flavor of emacs will not take into account the gtk theme (since it is not even gtk) and looks quite… ugly (see comparisons [https://emacs.stackexchange.com/questions/33065/on-linux-why-should-one-choose-lucid-over-gtk-gui-for-emacs here]). If you still prefer the gtk version of emacs, you can instead install <code>emacs-gtk</code> (before 2022-09 this package does not exist and emacs defaults to the gtk version).


As of July 2021, the Nix community offers [https://github.com/nix-community/emacs-overlay/blob/f177e5d14ad2e1edceb63f3ab8aa9748ebe6383c/default.nix#L104 7 variants of GNU Emacs] as overlays: emacsGit, emacsNativeComp ([https://github.com/nix-community/emacs-overlay/pull/223 formerly] emacsGcc), emacsPgtk, emacsPgtkNativeComp ([https://github.com/nix-community/emacs-overlay/pull/223 formerly] emacsPgtkGcc), emacsUnstable, emacsGit-nox, and emacsUnstable-nox.  
===== Unstable (community overlay) =====
The [https://github.com/nix-community/emacs-overlay community overlay] provides nightly versions of the Emacs unstable branches, ELPA / MELPA packages, and [https://github.com/ch11ng/exwm EXWM] + its dependencies. '''To use these, first apply the overlay (instructions below), which will make the packages available in nixpkgs.''' Then you can follow the normal nixpkgs installation instructions (above), but use your package of choice from the overlay (e.g. <code>pkgs.emacsGit</code>) in place of <code>pkgs.emacs</code>. See the [https://github.com/nix-community/emacs-overlay#emacs-overlay README] for a complete list of packages provided, and their differences.


===== Pure GTK =====
====== With flakes ======
Offers better integration with wayland compositors, in particular, there's better support for sharing the kill ring contents with the system clipboard.
Using a system flake, one can specify the specific revision of the overlay as a flake input, for example:


===== GCC =====
inputs.emacs-overlay.url = "github:nix-community/emacs-overlay/da2f552d133497abd434006e0cae996c0a282394";
Branches offer a means for automatic, asynchronous native compilation of emacs lisp into native code, that is then transparently used whenver the original versions of the functions are requested.


== Installation ==
This can then be used in the system configuration by using the {{ic|self}} argument:
nixpkgs.overlays = [ (import self.inputs.emacs-overlay) ];


=== Emacs overlay ===
======  Without flakes ======
For installing one of the unstable branches of emacs, add the following lines to {{ic|/etc/nixos/configuration.nix}} (replace emacsPgtkNativeComp with the variant of your choice).
For installing one of the unstable branches of emacs, add the following lines to {{ic|/etc/nixos/configuration.nix}}
{{file|configuration.nix|nix|<nowiki>
{{file|configuration.nix|nix|<nowiki>
{
{
  services.emacs.package = pkgs.emacsPgtkGcc;
   nixpkgs.overlays = [
   nixpkgs.overlays = [
     (import (builtins.fetchGit {
     (import (builtins.fetchGit {
Line 44: Line 82:
       rev = "bfc8f6edcb7bcf3cf24e4a7199b3f6fed96aaecf"; # change the revision
       rev = "bfc8f6edcb7bcf3cf24e4a7199b3f6fed96aaecf"; # change the revision
     }))
     }))
  ];
  environment.systemPackages = with pkgs; [
    emacsPgtkNativeComp
   ];
   ];
}
}
</nowiki>}}
</nowiki>}}


==== Flakes ====
== Installing packages ==
Using a system flake, one can specify the specific revision of the overlay as a flake input, for example:
{{tip|Emacs, much like NixOS can rebuild and re-fetch all of its packages based on its initialization file alone, if one chooses to use an extension called {{ic|(use-package)}}. Such a configuration file can be version controlled and used in all compatible operating systems.}}
 
inputs.emacs-overlay.url = "github:nix-community/emacs-overlay/da2f552d133497abd434006e0cae996c0a282394";
 
This can then be used in the system configuration by using the {{ic|self}} argument:
nixpkgs.overlays = [ (import self.inputs.emacs-overlay) ];
 
=== Doom Emacs ===
 
The [https://github.com/hlissner/doom-emacs Doom Emacs] project provides a framework with a better default configuration and modules for different programming languages. Since it uses pinning in its configuration for dependencies, it is possible to package Doom Emacs with nix (see [https://github.com/nix-community/nix-doom-emacs nix-doom-emacs])
 
=== Packages ===
One can mix and match whether Emacs packages are installed by Nix or Emacs. This can be particularly useful for Emacs packages that need to be built, such as vterm. One way to install Emacs packages through Nix is by the following, replacing {{ic|emacsPgtkNativeComp}} with the variant in use:
One can mix and match whether Emacs packages are installed by Nix or Emacs. This can be particularly useful for Emacs packages that need to be built, such as vterm. One way to install Emacs packages through Nix is by the following, replacing {{ic|emacsPgtkNativeComp}} with the variant in use:


Line 77: Line 100:


Note that some packages may have strange characters like <code>+</code> that would be considered as a syntax error by nix. To avoid that, make sure to write it in quotes and to prepend it with the package set that you want l (even if you used <code>with epkgs; …</code>) like <code>epkgs."ido-completing-read+"</code>.
Note that some packages may have strange characters like <code>+</code> that would be considered as a syntax error by nix. To avoid that, make sure to write it in quotes and to prepend it with the package set that you want l (even if you used <code>with epkgs; …</code>) like <code>epkgs."ido-completing-read+"</code>.
=== Automatic package management ===
If you use <code>use-package</code> or <code>leaf</code> in your configuration, the community overlay can manage your Emacs packages automatically by using <code>emacsWithPackagesFromUsePackage</code>. First, install the overlay (instructions above), then add the following to your <code>configuration.nix</code>:
<syntaxhighlight lang="nix">
{
  environment.systemPackages = [
    (pkgs.emacsWithPackagesFromUsePackage {
      package = pkgs.emacsGit;  # replace with pkgs.emacsPgtk, or another version if desired.
      config = path/to/your/config.el;
      # config = path/to/your/config.org; # Org-Babel configs also supported
      # Optionally provide extra packages not in the configuration file.
      extraEmacsPackages = epkgs: [
        epkgs.use-package;
      ];
      # Optionally override derivations.
      override = epkgs: epkgs // {
        somePackage = epkgs.melpaPackages.somePackage.overrideAttrs(old: {
          # Apply fixes here
        });
      };
    })
  ];
}
</syntaxhighlight>
See the [https://github.com/nix-community/emacs-overlay#extra-library-functionality overlay README] for a full list of options.
=== Adding packages from outside ELPA / MELPA ===
Some packages may require more sophisticated derivation, but the following is a good starting point for adding external packages:
{{file|lambda-line.nix|nix|<nowiki>
{
  trivialBuild,
  fetchFromGitHub,
  all-the-icons,
}:
trivialBuild rec {
  pname = "lambda-line";
  version = "main-23-11-2022";
  src = fetchFromGitHub {
    owner = "Lambda-Emacs";
    repo = "lambda-line";
    rev = "22186321a7442f1bd3b121f739007bd809cb38f8";
    hash = "sha256-2tOXMqpmd14ohzmrRoV5Urf0HlnRPV1EVHm/d8OBSGE=";
  };
  # elisp dependencies
  propagatedUserEnvPkgs = [
    all-the-icons
  ];
  buildInputs = propagatedUserEnvPkgs;
}
</nowiki>}}
You can then use the new package with automatic package management like so:
{{file|configuration.nix|nix|<nowiki>
{
  environment.systemPackages = [
    (pkgs.emacsWithPackagesFromUsePackage {
      ...
      override = epkgs: epkgs // {
        lambda-line = callPackage ./lambda-line.nix {
          inherit (pkgs) fetchFromGitHub;
          inherit (epkgs) trivialBuild all-the-icons;
        };
      };
    })
  ];
}
</nowiki>}}
or manual package management like so:
{{file|configuration.nix|nix|<nowiki>
{
  environment.systemPackages = with pkgs;
    [ ...
      ((emacsPackagesFor emacsPgtkNativeComp).emacsWithPackages (epkgs: [
          epkgs.vterm
          (callPackage ./lambda-line.nix {
            inherit (pkgs) fetchFromGitHub;
            inherit (epkgs) trivialBuild all-the-icons;
          };)
      ]))
      ...
    ];
}
</nowiki>}}


[[Category:NixOS]]
[[Category:NixOS]]
[[Category:Incomplete]]
[[Category:Incomplete]]
[[Category:Applications]]
[[Category:Applications]]

Revision as of 17:41, 1 January 2023

About

Emacs is an interactive graphical emacs lisp interpreter that comes with many applications, but is primarily used as a text and code editor. It has one of the largest repositories of packages of any similar code editor such as vim or its fork neovim.

Features

Emacs is often valued as a general purpose programming environment. Its power comes from its

  • Extensibility
  • Automatic self-documenting behaviour
  • Flexibility
  • Syntax awareness
  • language server protocol support
  • potential for reproducible portable literate configurations

Doom Emacs

The Doom Emacs project provides a framework with a more beginner-friendly default configuration, and pre-configured modules for popular features (e.g. IDE-like features, note-taking, and time management). Since it uses pinning in its configuration for dependencies, it is possible to package Doom Emacs with nix (see nix-doom-emacs)

Installation

Warning: Certain issues are possible, when mixing different versions of Emacs, in particular a configuration file tailored towards emacs with native compilation, may misbehave on non-native compiling versions, unless only the emacs lisp code is shared between them.

Several stable versions of emacs are available by default in nixpkgs, and unstable branches are also available via the community overaly. Also, see the NixOS manual entry for Emacs for additional details about installation and configuration.

With Home-Manager

home.nix
{
  programs.emacs = {
    enable = true;
    package = pkgs.emacs;  # replace with pkgs.emacs-gtk, or a version provided by the community overlay if desired.
    extraConfig = ''
      (setq standard-indent 2)
    '';
  };
}

See the Home-Manager manual for a full list of options.

Without Home-Manager

Emacs can be installed in the same way as other packages:

configuration.nix
{
  environment.systemPackages = with pkgs; [
    emacs # replace with emacs-gtk, or a version provided by the community overlay if desired.
  ];
}

Enabling the Emacs daemon

Many Emacs users run Emacs as a daemon and access Emacs via the emacsclient command. NixOS provides a systemd service to facilitate this, which you can enable by adding the following to your configuration.nix:

configuration.nix
{
  services.emacs = {
    enable = true;
    package = pkgs.emacs; # replace with emacs-gtk, or a version provided by the community overlay if desired.
  };
}


Available Emacs variants

Stable (nixpkgs)

Emacs is available in nixpkgs under the names emacs and emacs-gtk. Since 2022-09, the package called emacs now installs the lucid toolkit instead of gtk. The reason is that emacs is less stable with gtk especially in daemon mode. However, the lucid flavor of emacs will not take into account the gtk theme (since it is not even gtk) and looks quite… ugly (see comparisons here). If you still prefer the gtk version of emacs, you can instead install emacs-gtk (before 2022-09 this package does not exist and emacs defaults to the gtk version).

Unstable (community overlay)

The community overlay provides nightly versions of the Emacs unstable branches, ELPA / MELPA packages, and EXWM + its dependencies. To use these, first apply the overlay (instructions below), which will make the packages available in nixpkgs. Then you can follow the normal nixpkgs installation instructions (above), but use your package of choice from the overlay (e.g. pkgs.emacsGit) in place of pkgs.emacs. See the README for a complete list of packages provided, and their differences.

With flakes

Using a system flake, one can specify the specific revision of the overlay as a flake input, for example:

inputs.emacs-overlay.url = "github:nix-community/emacs-overlay/da2f552d133497abd434006e0cae996c0a282394";

This can then be used in the system configuration by using the self argument:

nixpkgs.overlays = [ (import self.inputs.emacs-overlay) ];
Without flakes

For installing one of the unstable branches of emacs, add the following lines to /etc/nixos/configuration.nix

configuration.nix
{
  nixpkgs.overlays = [
    (import (builtins.fetchGit {
      url = "https://github.com/nix-community/emacs-overlay.git";
      ref = "master";
      rev = "bfc8f6edcb7bcf3cf24e4a7199b3f6fed96aaecf"; # change the revision
    }))
  ];
}

Installing packages

One can mix and match whether Emacs packages are installed by Nix or Emacs. This can be particularly useful for Emacs packages that need to be built, such as vterm. One way to install Emacs packages through Nix is by the following, replacing emacsPgtkNativeComp with the variant in use:

environment.systemPackages = with pkgs;
  [ ...
    ((emacsPackagesFor emacsPgtkNativeComp).emacsWithPackages (epkgs: [ epkgs.vterm ]))
    ...
  ];

To make the packages available to emacsclient, one can do the following:

services.emacs.package = with pkgs; ((emacsPackagesFor emacsPgtkNativeComp).emacsWithPackages (epkgs: [ epkgs.vterm ]));

Note that some packages may have strange characters like + that would be considered as a syntax error by nix. To avoid that, make sure to write it in quotes and to prepend it with the package set that you want l (even if you used with epkgs; …) like epkgs."ido-completing-read+".

Automatic package management

If you use use-package or leaf in your configuration, the community overlay can manage your Emacs packages automatically by using emacsWithPackagesFromUsePackage. First, install the overlay (instructions above), then add the following to your configuration.nix:

{
  environment.systemPackages = [
    (pkgs.emacsWithPackagesFromUsePackage {
      package = pkgs.emacsGit;  # replace with pkgs.emacsPgtk, or another version if desired.
      config = path/to/your/config.el;
      # config = path/to/your/config.org; # Org-Babel configs also supported

      # Optionally provide extra packages not in the configuration file.
      extraEmacsPackages = epkgs: [
        epkgs.use-package;
      ];

      # Optionally override derivations.
      override = epkgs: epkgs // {
        somePackage = epkgs.melpaPackages.somePackage.overrideAttrs(old: {
           # Apply fixes here
        });
      };
    })
  ];
}

See the overlay README for a full list of options.

Adding packages from outside ELPA / MELPA

Some packages may require more sophisticated derivation, but the following is a good starting point for adding external packages:

lambda-line.nix
{
  trivialBuild,
  fetchFromGitHub,
  all-the-icons,
}:
trivialBuild rec {
  pname = "lambda-line";
  version = "main-23-11-2022";
  src = fetchFromGitHub {
    owner = "Lambda-Emacs";
    repo = "lambda-line";
    rev = "22186321a7442f1bd3b121f739007bd809cb38f8";
    hash = "sha256-2tOXMqpmd14ohzmrRoV5Urf0HlnRPV1EVHm/d8OBSGE=";
  };
  # elisp dependencies
  propagatedUserEnvPkgs = [
    all-the-icons
  ];
  buildInputs = propagatedUserEnvPkgs;
}

You can then use the new package with automatic package management like so:

configuration.nix
{
  environment.systemPackages = [
    (pkgs.emacsWithPackagesFromUsePackage {
      ...
      override = epkgs: epkgs // {
        lambda-line = callPackage ./lambda-line.nix {
          inherit (pkgs) fetchFromGitHub;
          inherit (epkgs) trivialBuild all-the-icons;
        };
      };
    })
  ];
}

or manual package management like so:

configuration.nix
{
  environment.systemPackages = with pkgs;
    [ ...
      ((emacsPackagesFor emacsPgtkNativeComp).emacsWithPackages (epkgs: [ 
          epkgs.vterm 
          (callPackage ./lambda-line.nix {
            inherit (pkgs) fetchFromGitHub;
            inherit (epkgs) trivialBuild all-the-icons;
          };) 
       ]))
      ...
    ];
}