about summary refs log tree commit diff
path: root/pkgs/applications/editors/emacs
diff options
context:
space:
mode:
authorAnderson Torres <torres.anderson.85@protonmail.com>2023-05-28 19:00:48 -0300
committerAnderson Torres <torres.anderson.85@protonmail.com>2023-05-29 22:16:45 -0300
commitc4e48ded591c380c3c5b9b15077fe31263c0870a (patch)
tree41161d06ba2ce85924fddef4a48cffcea11f74de /pkgs/applications/editors/emacs
parent6d93b7783264d34b424b6ef7c6271775d8bbe7aa (diff)
downloadnixlib-c4e48ded591c380c3c5b9b15077fe31263c0870a.tar
nixlib-c4e48ded591c380c3c5b9b15077fe31263c0870a.tar.gz
nixlib-c4e48ded591c380c3c5b9b15077fe31263c0870a.tar.bz2
nixlib-c4e48ded591c380c3c5b9b15077fe31263c0870a.tar.lz
nixlib-c4e48ded591c380c3c5b9b15077fe31263c0870a.tar.xz
nixlib-c4e48ded591c380c3c5b9b15077fe31263c0870a.tar.zst
nixlib-c4e48ded591c380c3c5b9b15077fe31263c0870a.zip
emacs: a huge refactor
A list of modifications:

- The calling handles at `top-level/all-packages.nix` were transferred to
`pkgs/applications/editors/emacs/default.nix` (the good old `recurseIntoAttrs`
design pattern);
- The files `macport.nix` and `28.nix` were removed, replaced by the bigger and
better `sources.nix`;
- Aliases for the most important derivations were put on `all-packages.nix`;
- The file `generic.nix` was refactored. Among its changes, the most noticeable:
  - `pname` is decorated according to the selected UI options;
  - Environment variables are explicitly under `env` set;
  - The `null` defaults and (in)equality tests were removed;
    - It obliged the addition of some Boolean flag guards;
  - The flag `noGui` was added, allowing easier override for `emacs-nox`.

With this huge refactor, the emacs build functions become more sane and
maintainable, allowing future additions.
Diffstat (limited to 'pkgs/applications/editors/emacs')
-rw-r--r--pkgs/applications/editors/emacs/28.nix4
-rw-r--r--pkgs/applications/editors/emacs/default.nix44
-rw-r--r--pkgs/applications/editors/emacs/generic.nix438
-rw-r--r--pkgs/applications/editors/emacs/macport.nix6
-rw-r--r--pkgs/applications/editors/emacs/sources.nix29
5 files changed, 364 insertions, 157 deletions
diff --git a/pkgs/applications/editors/emacs/28.nix b/pkgs/applications/editors/emacs/28.nix
deleted file mode 100644
index b6abb4c4cdb5..000000000000
--- a/pkgs/applications/editors/emacs/28.nix
+++ /dev/null
@@ -1,4 +0,0 @@
-import ./generic.nix (rec {
-  version = "28.2";
-  sha256 = "sha256-4oSLcUDR0MOEt53QOiZSVU8kPJ67GwugmBxdX3F15Ag=";
-})
diff --git a/pkgs/applications/editors/emacs/default.nix b/pkgs/applications/editors/emacs/default.nix
new file mode 100644
index 000000000000..373570f10fb6
--- /dev/null
+++ b/pkgs/applications/editors/emacs/default.nix
@@ -0,0 +1,44 @@
+{ lib, pkgs }:
+
+lib.makeScope pkgs.newScope (self:
+  let
+    gconf = pkgs.gnome2.GConf;
+    inherit (self) callPackage;
+  in {
+    sources = import ./sources.nix {
+      inherit lib;
+      inherit (pkgs)
+        fetchFromBitbucket
+        fetchFromSavannah;
+    };
+
+    emacs28 = callPackage (self.sources.emacs28) {
+      inherit gconf;
+
+      inherit (pkgs.darwin) sigtool;
+      inherit (pkgs.darwin.apple_sdk.frameworks)
+        AppKit Carbon Cocoa GSS ImageCaptureCore ImageIO IOKit OSAKit Quartz
+        QuartzCore WebKit;
+    };
+
+    emacs28-gtk2 = self.emacs28.override {
+      withGTK2 = true;
+    };
+
+    emacs28-gtk3 = self.emacs28.override {
+      withGTK3 = true;
+    };
+
+    emacs28-nox = pkgs.lowPrio (self.emacs28.override {
+      noGui = true;
+    });
+
+    emacs-macport = callPackage (self.sources.emacs-macport) {
+      inherit gconf;
+
+      inherit (pkgs.darwin) sigtool;
+      inherit (pkgs.darwin.apple_sdk.frameworks)
+        AppKit Carbon Cocoa GSS ImageCaptureCore ImageIO IOKit OSAKit Quartz
+        QuartzCore WebKit;
+    };
+  })
diff --git a/pkgs/applications/editors/emacs/generic.nix b/pkgs/applications/editors/emacs/generic.nix
index 53043294539a..b42d5e8a1ae6 100644
--- a/pkgs/applications/editors/emacs/generic.nix
+++ b/pkgs/applications/editors/emacs/generic.nix
@@ -1,66 +1,126 @@
-{
-  version
-  , sha256
-  , versionModifier ? ""
-  , pname ? "emacs"
-  , name ? "emacs-${version}${versionModifier}"
-  , patches ? _: [ ]
-  , macportVersion ? null
+{ pname ? "emacs"
+, version
+, versionModifier ? ""
+, name ? "emacs-${version}${versionModifier}"
+, variant
+, src
+, patches ? _: [ ]
 }:
-{ stdenv, llvmPackages_6, lib, fetchurl, fetchpatch, substituteAll, ncurses, libXaw, libXpm
-, Xaw3d, libXcursor,  pkg-config, gettext, libXft, dbus, libpng, libjpeg, giflib
-, libtiff, librsvg, libwebp, gconf, libxml2, imagemagick, gnutls, libselinux
-, alsa-lib, cairo, acl, gpm, m17n_lib, libotf
-, sigtool, jansson, harfbuzz, sqlite, nixosTests
-, recurseIntoAttrs, emacsPackagesFor
-, libgccjit, makeWrapper # native-comp params
-, fetchFromSavannah, fetchFromBitbucket
-
-  # macOS dependencies for NS and macPort
-, AppKit, Carbon, Cocoa, IOKit, OSAKit, Quartz, QuartzCore, WebKit
-, ImageCaptureCore, GSS, ImageIO # These may be optional
-
-, withX ? !stdenv.isDarwin && !withPgtk
-, withNS ? stdenv.isDarwin && !withMacport
-, withMacport ? macportVersion != null
-, withGTK2 ? false, gtk2-x11 ? null
-, withGTK3 ? withPgtk, gtk3-x11 ? null, gsettings-desktop-schemas ? null
-, withXwidgets ? false, webkitgtk ? null, wrapGAppsHook ? null, glib-networking ? null
-, withMotif ? false, motif ? null
-, withSQLite3 ? false
-, withCsrc ? true
-, withWebP ? false
-, srcRepo ? true, autoreconfHook ? null, texinfo ? null
-, siteStart ? ./site-start.el
+
+{ lib
+, stdenv
+, Xaw3d
+, acl
+, alsa-lib
+, autoreconfHook
+, cairo
+, dbus
+, emacsPackagesFor
+, fetchpatch
+, gconf
+, gettext
+, giflib
+, glib-networking
+, gnutls
+, gpm
+, gsettings-desktop-schemas
+, gtk2-x11
+, gtk3
+, gtk3-x11
+, harfbuzz
+, imagemagick
+, jansson
+, libXaw
+, libXcursor
+, libXft
+, libXpm
+, libgccjit
+, libjpeg
+, libotf
+, libpng
+, librsvg
+, libselinux
+, libtiff
+, libwebp
+, libxml2
+, llvmPackages_6
+, m17n_lib
+, makeWrapper
+, motif
+, ncurses
+, nixosTests
+, pkg-config
+, recurseIntoAttrs
+, sigtool
+, sqlite
+, substituteAll
+, systemd
+, tree-sitter
+, texinfo
+, webkitgtk
+, wrapGAppsHook
+
+# macOS dependencies for NS and macPort
+, AppKit
+, Carbon
+, Cocoa
+, GSS
+, IOKit
+, ImageCaptureCore
+, ImageIO
+, OSAKit
+, Quartz
+, QuartzCore
+, WebKit
+
+# Boolean flags
 , nativeComp ? true
+, noGui ? false
+, srcRepo ? true
+, withAcl ? false
+, withAlsaLib ? false
 , withAthena ? false
+, withCsrc ? true
+, withGTK2 ? false
+, withGTK3 ? withPgtk && !noGui
+, withGconf ? false
+, withGpm ? stdenv.isLinux
+, withImageMagick ? lib.versionOlder version "27" && (withX || withNS)
+, withMotif ? false
+, withNS ? stdenv.isDarwin && !(variant == "macport" || noGui)
+, withPgtk ? false
+, withSQLite3 ? false
+, withSystemd ? lib.meta.availableOn stdenv.hostPlatform systemd
 , withToolkitScrollBars ? true
-, withPgtk ? false, gtk3 ? null
+, withTreeSitter ? lib.versionAtLeast version "29"
+, withWebP ? false
+, withX ? !(stdenv.isDarwin || noGui || withPgtk)
 , withXinput2 ? withX && lib.versionAtLeast version "29"
-, withImageMagick ? lib.versionOlder version "27" && (withX || withNS)
+, withXwidgets ? false
+
+# Options
+, siteStart ? ./site-start.el
 , toolkit ? (
   if withGTK2 then "gtk2"
   else if withGTK3 then "gtk3"
   else if withMotif then "motif"
   else if withAthena then "athena"
   else "lucid")
-, withSystemd ? lib.meta.availableOn stdenv.hostPlatform systemd, systemd
-, withTreeSitter ? lib.versionAtLeast version "29", tree-sitter ? null
 }:
 
-assert (libXft != null) -> libpng != null;      # probably a bug
-assert stdenv.isDarwin -> libXaw != null;       # fails to link otherwise
-assert withNS -> !withX;
-assert withNS -> stdenv.isDarwin;
-assert withMacport -> !withNS;
-assert (withGTK2 && !withNS && !withMacport) -> withX;
-assert (withGTK3 && !withNS && !withMacport) -> withX || withPgtk;
-assert withGTK2 -> !withGTK3 && gtk2-x11 != null && !withPgtk;
-assert withGTK3 -> !withGTK2 && ((gtk3-x11 != null) || withPgtk);
-assert withPgtk -> withGTK3 && !withX && gtk3 != null;
-assert withXwidgets -> withGTK3 && webkitgtk != null;
-assert withTreeSitter -> tree-sitter != null;
+assert (withGTK2 && !withNS && variant != "macport") -> withX;
+assert (withGTK3 && !withNS && variant != "macport") -> withX || withPgtk;
 
+assert noGui -> !(withX || withGTK2 || withGTK3 || withNS || variant == "macport");
+assert withAcl -> stdenv.isLinux;
+assert withAlsaLib -> stdenv.isLinux;
+assert withGTK2 -> !(withGTK3 || withPgtk);
+assert withGTK3 -> !withGTK2 || withPgtk;
+assert withGconf -> withX;
+assert withGpm -> stdenv.isLinux;
+assert withNS -> stdenv.isDarwin && !(withX || variant == "macport");
+assert withPgtk -> withGTK3 && !withX;
+assert withXwidgets -> withGTK3;
 
 let
   libGccJitLibraryPaths = [
@@ -69,14 +129,27 @@ let
   ] ++ lib.optionals (stdenv.cc?cc.libgcc) [
     "${lib.getLib stdenv.cc.cc.libgcc}/lib"
   ];
+
+  inherit (if variant == "macport"
+           then llvmPackages_6.stdenv
+           else stdenv) mkDerivation;
 in
-(if withMacport then llvmPackages_6.stdenv else stdenv).mkDerivation (finalAttrs: (lib.optionalAttrs nativeComp {
-  NATIVE_FULL_AOT = "1";
-  LIBRARY_PATH = lib.concatStringsSep ":" libGccJitLibraryPaths;
+mkDerivation (finalAttrs: (lib.optionalAttrs nativeComp {
+  env = {
+    NATIVE_FULL_AOT = "1";
+    LIBRARY_PATH = lib.concatStringsSep ":" libGccJitLibraryPaths;
+  };
 } // {
-  pname = pname + lib.optionalString ( !withX && !withNS && !withMacport && !withGTK2 && !withGTK3 ) "-nox";
+  pname = pname
+          + (if noGui then "-nox"
+             else if withPgtk then "-pgtk"
+             else if withGTK3 then "-gtk3"
+             else if withGTK2 then "-gtk2"
+             else "");
   inherit version;
 
+  inherit src;
+
   patches = patches fetchpatch ++ lib.optionals nativeComp [
     (substituteAll {
       src = if lib.versionOlder finalAttrs.version "29"
@@ -95,27 +168,14 @@ in
     })
   ];
 
-  src = if macportVersion != null then fetchFromBitbucket {
-    owner = "mituharu";
-    repo = "emacs-mac";
-    rev = macportVersion;
-    inherit sha256;
-  } else fetchFromSavannah {
-    repo = "emacs";
-    rev = version;
-    inherit sha256;
-  };
-
-  enableParallelBuilding = true;
-
   postPatch = lib.concatStringsSep "\n" [
     (lib.optionalString srcRepo ''
       rm -fr .git
     '')
 
     # Add the name of the wrapped gvfsd
-    # This used to be carried as a patch but it often got out of sync with upstream
-    # and was hard to maintain for emacs-overlay.
+    # This used to be carried as a patch but it often got out of sync with
+    # upstream and was hard to maintain for emacs-overlay.
     (lib.concatStrings (map (fn: ''
       sed -i 's#(${fn} "gvfs-fuse-daemon")#(${fn} "gvfs-fuse-daemon") (${fn} ".gvfsd-fuse-wrapped")#' lisp/net/tramp-gvfs.el
     '') [
@@ -130,81 +190,150 @@ in
     ''
 
     ''
-    substituteInPlace lisp/international/mule-cmds.el \
-      --replace /usr/share/locale ${gettext}/share/locale
+      substituteInPlace lisp/international/mule-cmds.el \
+        --replace /usr/share/locale ${gettext}/share/locale
 
-    for makefile_in in $(find . -name Makefile.in -print); do
-      substituteInPlace $makefile_in --replace /bin/pwd pwd
-    done
+      for makefile_in in $(find . -name Makefile.in -print); do
+        substituteInPlace $makefile_in --replace /bin/pwd pwd
+      done
     ''
 
     ""
   ];
 
-  nativeBuildInputs = [ pkg-config makeWrapper ]
-    ++ lib.optionals (srcRepo || withMacport) [ texinfo ]
-    ++ lib.optionals srcRepo [ autoreconfHook ]
-    ++ lib.optional (withPgtk || withX && (withGTK3 || withXwidgets)) wrapGAppsHook;
-
-  buildInputs =
-    [ ncurses gconf libxml2 gnutls gettext jansson harfbuzz.dev ]
-    ++ lib.optionals stdenv.isLinux [ dbus libselinux alsa-lib acl gpm ]
-    ++ lib.optionals withSystemd [ systemd ]
-    ++ lib.optionals withX
-      [ libXaw Xaw3d gconf cairo ]
-    ++ lib.optionals (withX || withPgtk)
-      [ libXpm libpng libjpeg giflib libtiff ]
-    ++ lib.optionals (withX || withNS || withPgtk ) [ librsvg ]
-    ++ lib.optionals withImageMagick [ imagemagick ]
-    ++ lib.optionals (stdenv.isLinux && withX) [ m17n_lib libotf ]
-    ++ lib.optional (withX && withGTK2) gtk2-x11
-    ++ lib.optional (withX && withGTK3) gtk3-x11
-    ++ lib.optional (!stdenv.isDarwin && withGTK3) gsettings-desktop-schemas
-    ++ lib.optional withPgtk gtk3
-    ++ lib.optional (withX && withMotif) motif
-    ++ lib.optional withSQLite3 sqlite
-    ++ lib.optional withWebP libwebp
-    ++ lib.optionals (withX && withXwidgets) [ webkitgtk glib-networking ]
-    ++ lib.optionals withNS [ AppKit GSS ImageIO ]
-    ++ lib.optionals withMacport [
-      AppKit Carbon Cocoa IOKit OSAKit Quartz QuartzCore WebKit
-      # TODO are these optional?
-      ImageCaptureCore GSS ImageIO
-    ]
-    ++ lib.optionals stdenv.isDarwin [ sigtool ]
-    ++ lib.optionals nativeComp [ libgccjit ]
-    ++ lib.optionals withTreeSitter [ tree-sitter ];
+  nativeBuildInputs = [
+    makeWrapper
+    pkg-config
+  ] ++ lib.optionals (variant == "macport") [
+    texinfo
+  ] ++ lib.optionals srcRepo [
+    autoreconfHook
+    texinfo
+  ] ++ lib.optional (withPgtk || withX && (withGTK3 || withXwidgets)) wrapGAppsHook;
+
+  buildInputs = [
+    gettext
+    gnutls
+    harfbuzz.dev
+    jansson
+    libxml2
+    ncurses
+  ] ++ lib.optionals withGconf [
+    gconf
+  ] ++ lib.optionals withAcl [
+    acl
+  ] ++ lib.optionals withAlsaLib [
+    alsa-lib
+  ] ++ lib.optionals withGpm [
+    gpm
+  ] ++ lib.optionals stdenv.isLinux [
+    dbus
+    libselinux
+  ] ++ lib.optionals (!stdenv.isDarwin && withGTK3) [
+    gsettings-desktop-schemas
+  ] ++ lib.optionals (stdenv.isLinux && withX) [
+    libotf
+    m17n_lib
+  ] ++ lib.optionals (withX && withGTK2) [
+    gtk2-x11
+  ] ++ lib.optionals (withX && withGTK3) [
+    gtk3-x11
+  ] ++ lib.optionals (withX && withMotif) [
+    motif
+  ] ++ lib.optionals (withX && withXwidgets) [
+    glib-networking
+    webkitgtk
+  ] ++ lib.optionals nativeComp [
+    libgccjit
+  ] ++ lib.optionals withImageMagick [
+    imagemagick
+  ] ++ lib.optionals withPgtk [
+    giflib
+    gtk3
+    libXpm
+    libjpeg
+    libpng
+    librsvg
+    libtiff
+  ] ++ lib.optionals withSQLite3 [
+    sqlite
+  ] ++ lib.optionals withSystemd [
+    systemd
+  ] ++ lib.optionals withTreeSitter [
+    tree-sitter
+  ] ++ lib.optionals withWebP [
+    libwebp
+  ] ++ lib.optionals withX [
+    Xaw3d
+    cairo
+
+    giflib
+    libXaw
+    libXpm
+    libjpeg
+    libpng
+    librsvg
+    libtiff
+  ] ++ lib.optionals stdenv.isDarwin [
+    sigtool
+  ] ++ lib.optionals withNS [
+    librsvg
+    AppKit
+    GSS
+    ImageIO
+  ] ++ lib.optionals (variant == "macport") [
+    AppKit
+    Carbon
+    Cocoa
+    IOKit
+    OSAKit
+    Quartz
+    QuartzCore
+    WebKit
+    # TODO are these optional?
+    GSS
+    ImageCaptureCore
+    ImageIO
+  ];
 
   hardeningDisable = [ "format" ];
 
   configureFlags = [
     "--disable-build-details" # for a (more) reproducible build
     "--with-modules"
-  ] ++
-    (lib.optional stdenv.isDarwin
-      (lib.withFeature withNS "ns")) ++
-    (if withNS
-      then [ "--disable-ns-self-contained" ]
-    else if withX
-      then [ "--with-x-toolkit=${toolkit}" "--with-xft" "--with-cairo" ]
-    else if withPgtk
-      then [ "--with-pgtk" ]
-    else [ "--with-x=no" "--with-xpm=no" "--with-jpeg=no" "--with-png=no"
-           "--with-gif=no" "--with-tiff=no" ])
-    ++ lib.optionals withMacport [
-      "--with-mac"
-      "--enable-mac-app=$$out/Applications"
-      "--with-xml2=yes"
-      "--with-gnutls=yes"
-    ]
-    ++ lib.optional withXwidgets "--with-xwidgets"
-    ++ lib.optional nativeComp "--with-native-compilation"
-    ++ lib.optional withImageMagick "--with-imagemagick"
-    ++ lib.optional withXinput2 "--with-xinput2"
-    ++ lib.optional (!withToolkitScrollBars) "--without-toolkit-scroll-bars"
-    ++ lib.optional withTreeSitter "--with-tree-sitter"
+  ] ++ (if withNS then [
+    "--disable-ns-self-contained"
+  ] else if withX then [
+    "--with-x-toolkit=${toolkit}"
+    "--with-xft"
+    "--with-cairo"
+  ] else if withPgtk then [
+    "--with-pgtk"
+  ] else [
+    "--with-gif=no"
+    "--with-jpeg=no"
+    "--with-png=no"
+    "--with-tiff=no"
+    "--with-x=no"
+    "--with-xpm=no"
+  ])
+  ++ lib.optionals (variant == "macport") [
+    "--enable-mac-app=$$out/Applications"
+    "--with-gnutls=yes"
+    "--with-mac"
+    "--with-xml2=yes"
+  ]
+  ++ (lib.optional stdenv.isDarwin (lib.withFeature withNS "ns"))
+  ++ lib.optional (!withToolkitScrollBars) "--without-toolkit-scroll-bars"
+  ++ lib.optional nativeComp "--with-native-compilation"
+  ++ lib.optional withImageMagick "--with-imagemagick"
+  ++ lib.optional withTreeSitter "--with-tree-sitter"
+  ++ lib.optional withXinput2 "--with-xinput2"
+  ++ lib.optional withXwidgets "--with-xwidgets"
   ;
 
+  enableParallelBuilding = true;
+
   installTargets = [ "tags" "install" ];
 
   postInstall = ''
@@ -227,7 +356,7 @@ in
   '' + lib.optionalString withNS ''
     mkdir -p $out/Applications
     mv nextstep/Emacs.app $out/Applications
-  '' + lib.optionalString (nativeComp && (withNS || withMacport)) ''
+  '' + lib.optionalString (nativeComp && (withNS || variant == "macport")) ''
     ln -snf $out/lib/emacs/*/native-lisp $out/Applications/Emacs.app/Contents/native-lisp
   '' + lib.optionalString nativeComp ''
     echo "Generating native-compiled trampolines..."
@@ -256,29 +385,44 @@ in
     tests = { inherit (nixosTests) emacs-daemon; };
   };
 
-  meta = with lib; {
-    description = "The extensible, customizable GNU text editor" + optionalString withMacport " with Mitsuharu Yamamoto's macport patches";
-    homepage    = if withMacport then "https://bitbucket.org/mituharu/emacs-mac/" else "https://www.gnu.org/software/emacs/";
-    license     = licenses.gpl3Plus;
-    maintainers = with maintainers; [ lovek323 jwiegley adisbladis matthewbauer atemu ];
-    platforms   = if withMacport then platforms.darwin else platforms.all;
-    broken      = !(stdenv.buildPlatform.canExecute stdenv.hostPlatform);
-
+  meta = {
+    homepage = if variant == "macport"
+               then "https://bitbucket.org/mituharu/emacs-mac/"
+               else "https://www.gnu.org/software/emacs/";
+    description = "The extensible, customizable GNU text editor"
+                  + lib.optionalString (variant == "macport") " - with macport patches";
     longDescription = ''
-      GNU Emacs is an extensible, customizable text editor—and more.  At its
-      core is an interpreter for Emacs Lisp, a dialect of the Lisp
-      programming language with extensions to support text editing.
+      GNU Emacs is an extensible, customizable text editor—and more. At its
+      core is an interpreter for Emacs Lisp, a dialect of the Lisp programming
+      language with extensions to support text editing.
 
       The features of GNU Emacs include: content-sensitive editing modes,
       including syntax coloring, for a wide variety of file types including
       plain text, source code, and HTML; complete built-in documentation,
       including a tutorial for new users; full Unicode support for nearly all
-      human languages and their scripts; highly customizable, using Emacs
-      Lisp code or a graphical interface; a large number of extensions that
-      add other functionality, including a project planner, mail and news
-      reader, debugger interface, calendar, and more.  Many of these
-      extensions are distributed with GNU Emacs; others are available
-      separately.
+      human languages and their scripts; highly customizable, using Emacs Lisp
+      code or a graphical interface; a large number of extensions that add other
+      functionality, including a project planner, mail and news reader, debugger
+      interface, calendar, and more. Many of these extensions are distributed
+      with GNU Emacs; others are available separately.
+    ''
+    + lib.optionalString (variant == "macport") ''
+
+      This release is built from Mitsuharu Yamamoto's patched, MacOS X-specific
+      source code.
     '';
+    license = lib.licenses.gpl3Plus;
+    maintainers = with lib.maintainers; [
+      AndersonTorres
+      adisbladis
+      atemu
+      jwiegley
+      lovek323
+      matthewbauer
+    ];
+    platforms = if variant == "macport"
+                then lib.platforms.darwin
+                else lib.platforms.all;
+    broken = !(stdenv.buildPlatform.canExecute stdenv.hostPlatform);
   };
 }))
diff --git a/pkgs/applications/editors/emacs/macport.nix b/pkgs/applications/editors/emacs/macport.nix
deleted file mode 100644
index 9a30b2b5b408..000000000000
--- a/pkgs/applications/editors/emacs/macport.nix
+++ /dev/null
@@ -1,6 +0,0 @@
-import ./generic.nix rec {
-  pname = "emacs-mac";
-  version = "28.2";
-  macportVersion = "emacs-${version}-mac-9.1";
-  sha256 = "sha256-Ne2jQ2nVLNiQmnkkOXVc5AkLVkTpm8pFC7VNY2gQjPE=";
-}
diff --git a/pkgs/applications/editors/emacs/sources.nix b/pkgs/applications/editors/emacs/sources.nix
new file mode 100644
index 000000000000..3e1de723b730
--- /dev/null
+++ b/pkgs/applications/editors/emacs/sources.nix
@@ -0,0 +1,29 @@
+{ lib
+, fetchFromBitbucket
+, fetchFromSavannah
+}:
+
+{
+  emacs28 = import ./generic.nix {
+    pname = "emacs";
+    version = "28.2";
+    variant = "mainline";
+    src = fetchFromSavannah {
+      repo = "emacs";
+      rev = "28.2";
+      hash = "sha256-4oSLcUDR0MOEt53QOiZSVU8kPJ67GwugmBxdX3F15Ag=";
+    };
+  };
+
+  emacs-macport = import ./generic.nix {
+    pname = "emacs-mac";
+    version = "28.2";
+    variant = "macport";
+    src = fetchFromBitbucket {
+      owner = "mituharu";
+      repo = "emacs-mac";
+      rev = "emacs-28.2-mac-9.1";
+      hash = "sha256-Ne2jQ2nVLNiQmnkkOXVc5AkLVkTpm8pFC7VNY2gQjPE=";
+    };
+  };
+}