branch: externals/keymap-popup
commit 9feef671b94240b6f7f8defa8d7682612b005179
Author: Thanos Apollo <[email protected]>
Commit: Thanos Apollo <[email protected]>

    build: Replace Guix workflow with Nix flake
---
 .elpaignore     |   4 +-
 Makefile        |  41 +++++++++++--------
 README.org      |  21 ++++++++++
 flake.lock      |  27 +++++++++++++
 flake.nix       | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 guix.scm        |  89 ----------------------------------------
 keymap-popup.el |   2 +-
 7 files changed, 199 insertions(+), 108 deletions(-)

diff --git a/.elpaignore b/.elpaignore
index 2d08a06a9da..28daabfea75 100644
--- a/.elpaignore
+++ b/.elpaignore
@@ -1,8 +1,8 @@
 CONTRIBUTING.org
 LICENSE
 Makefile
-manifest.scm
-guix.scm
+flake.lock
+flake.nix
 
 tests
 
diff --git a/Makefile b/Makefile
index 74d34326e0e..bb5b08b57e2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,53 +1,59 @@
 .POSIX:
 
-ifndef EMACS_CMD
-GUIX := $(shell command -v guix 2>/dev/null)
-ifdef GUIX
-GUIX_SHELL := guix shell --pure -D -f guix.scm emacs-next --
-EMACS_CMD := $(GUIX_SHELL) emacs
-else
-GUIX_SHELL :=
-EMACS_CMD := emacs
+NIX := $(shell command -v nix 2>/dev/null)
+USE_NIX ?= 1
+
+ENV_MAKE = $(MAKE) --no-print-directory
+ifeq ($(USE_NIX),1)
+ifeq ($(IN_NIX_SHELL),)
+ifneq ($(NIX),)
+ENV_MAKE = nix develop path:. --command $(MAKE) --no-print-directory USE_NIX=0
+endif
 endif
 endif
 
-GUIX_WRAP = $(if $(GUIX_SHELL),$(GUIX_SHELL) $(MAKE) --no-print-directory 
EMACS_CMD=emacs,$(MAKE) --no-print-directory)
+EMACS_CMD ?= emacs
+EMACS_OPTS ?= -Q --batch
 
 SRCS = keymap-popup.el
 TESTS = tests/keymap-popup-tests.el
-BATCH = $(EMACS_CMD) -Q --batch
+BATCH = $(EMACS_CMD) $(EMACS_OPTS)
 
 ORG = docs/keymap-popup.org
 TEXI = docs/keymap-popup.texi
 INFO = docs/keymap-popup.info
 
-.PHONY: all compile do-compile test do-test lint do-lint doc do-doc clean dev 
load
+.PHONY: all compile do-compile test do-test lint do-lint doc do-doc clean dev 
do-dev load
 
 all: compile
 
 compile:
-       @$(GUIX_WRAP) do-compile
+       @$(ENV_MAKE) do-compile
 
 do-compile:
        @echo "Compiling $(SRCS)..."
        @$(BATCH) -f batch-byte-compile $(SRCS)
 
 test:
-       @$(GUIX_WRAP) do-test
+       @$(ENV_MAKE) do-test
 
 do-test:
        @echo "Testing $(TESTS)..."
        @$(BATCH) -l ert -l $(SRCS) -l $(TESTS) -f ert-run-tests-batch-and-exit
 
 lint:
-       @$(GUIX_WRAP) do-lint
+       @$(ENV_MAKE) do-lint
 
 do-lint:
        @echo "Running checkdoc..."
        @$(BATCH) --eval '(checkdoc-file "$(SRCS)")'
+       @echo "Running package-lint..."
+       @$(BATCH) --eval '(package-initialize)' \
+         --eval '(require (quote package-lint))' \
+         -f package-lint-batch-and-exit $(SRCS)
 
 doc:
-       @$(GUIX_WRAP) do-doc
+       @$(ENV_MAKE) do-doc
 
 do-doc: $(INFO)
 
@@ -57,7 +63,10 @@ $(INFO): $(ORG)
          --eval "(with-current-buffer (find-file \"$(ORG)\") 
(org-texinfo-export-to-info))" \
          --kill
 
-dev: compile lint test
+dev:
+       @$(ENV_MAKE) do-dev
+
+do-dev: do-compile do-lint do-test
 
 load:
        @emacsclient --eval "(progn \
diff --git a/README.org b/README.org
index 9373544fac6..96bfae30b89 100644
--- a/README.org
+++ b/README.org
@@ -69,3 +69,24 @@ Full usage -- special bindings, sub-menus, annotating 
keymaps like
 =dired-mode-map=, display backends, customization -- lives in the
 [[file:docs/keymap-popup.org][user manual]], also available as an Info
 manual (=make doc=).
+
+** Development
+
+The repository flake pins Nixpkgs and provides Emacs, GNU Make,
+Texinfo, and package-lint.  Public Make targets enter the development
+shell automatically when Nix is available:
+
+#+begin_src sh
+make dev
+make doc
+#+end_src
+
+Enter the same environment manually with =nix develop=.  Run the
+sandboxed package build, tests, lint checks, and manual build with:
+
+#+begin_src sh
+nix flake check
+#+end_src
+
+Set =USE_NIX=0= to run a Make target directly in the current
+environment.
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 00000000000..8e8f6d5a590
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,27 @@
+{
+  "nodes": {
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1783776592,
+        "narHash": "sha256-UgCQzxeWI75XM8G+hPrPh+MKzEPjG3SpAj7dtqSbksA=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "e7a3ca8092b61ff85b6a45bf863ea2b2d6a661b3",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "root": {
+      "inputs": {
+        "nixpkgs": "nixpkgs"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 00000000000..7972432d4e2
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,123 @@
+{
+  description = "Described keymaps with popup help";
+
+  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+
+  outputs = { nixpkgs, ... }:
+    let
+      systems = [
+        "x86_64-linux"
+        "aarch64-linux"
+        "x86_64-darwin"
+        "aarch64-darwin"
+      ];
+
+      forAllSystems = nixpkgs.lib.genAttrs systems;
+
+      mkProject = system:
+        let
+          pkgs = import nixpkgs { inherit system; };
+          lib = pkgs.lib;
+          emacs = pkgs.emacs30 or pkgs.emacs29 or pkgs.emacs;
+          emacsPackages = pkgs.emacsPackagesFor emacs;
+
+          versionLine = lib.findFirst
+            (line: lib.hasPrefix ";; Version: " line)
+            (throw "keymap-popup.el has no Version header")
+            (lib.splitString "\n" (builtins.readFile ./keymap-popup.el));
+          version = lib.removePrefix ";; Version: " versionLine;
+
+          source = lib.cleanSourceWith {
+            src = ./.;
+            filter = path: type:
+              let
+                name = baseNameOf path;
+              in
+              lib.cleanSourceFilter path type
+              && !(builtins.elem name [ ".direnv" ".test-results" "refs" 
"result" ]
+                || lib.hasSuffix ".elc" name
+                || lib.hasSuffix ".info" name
+                || lib.hasSuffix ".texi" name
+                || lib.hasSuffix "~" name);
+          };
+
+          emacsWithPackages = emacsPackages.emacsWithPackages (epkgs: [
+            epkgs.package-lint
+          ]);
+
+          package = emacsPackages.trivialBuild {
+            pname = "keymap-popup";
+            inherit version;
+            src = source;
+            packageRequires = [ ];
+          };
+
+          check = pkgs.stdenvNoCC.mkDerivation {
+            pname = "keymap-popup-checks";
+            inherit version;
+            src = source;
+            nativeBuildInputs = [
+              emacsWithPackages
+              pkgs.gnumake
+              pkgs.texinfo
+            ];
+            dontConfigure = true;
+
+            buildPhase = ''
+              runHook preBuild
+              export HOME="$TMPDIR/home"
+              export XDG_CACHE_HOME="$TMPDIR/cache"
+              export XDG_CONFIG_HOME="$TMPDIR/config"
+              export XDG_DATA_HOME="$TMPDIR/share"
+              export XDG_STATE_HOME="$TMPDIR/state"
+              mkdir -p "$HOME" "$XDG_CACHE_HOME" "$XDG_CONFIG_HOME" \
+                "$XDG_DATA_HOME" "$XDG_STATE_HOME"
+              make USE_NIX=0 EMACS_CMD=emacs do-dev do-doc
+              runHook postBuild
+            '';
+
+            installPhase = ''
+              runHook preInstall
+              mkdir -p $out
+              touch $out/tests-passed
+              runHook postInstall
+            '';
+          };
+        in
+        {
+          inherit check emacsWithPackages package pkgs;
+        };
+    in
+    {
+      packages = forAllSystems (system:
+        let
+          project = mkProject system;
+        in
+        {
+          default = project.package;
+        });
+
+      checks = forAllSystems (system:
+        let
+          project = mkProject system;
+        in
+        {
+          default = project.check;
+          package = project.package;
+        });
+
+      devShells = forAllSystems (system:
+        let
+          project = mkProject system;
+        in
+        {
+          default = project.pkgs.mkShellNoCC {
+            packages = [
+              project.emacsWithPackages
+              project.pkgs.gnumake
+              project.pkgs.texinfo
+            ];
+          };
+        });
+    };
+}
diff --git a/guix.scm b/guix.scm
deleted file mode 100644
index 991b8ebe9e8..00000000000
--- a/guix.scm
+++ /dev/null
@@ -1,89 +0,0 @@
-;;; guix.scm --- Build keymap-popup from the current working tree.
-;;
-;; Usage:
-;;
-;;   One-shot install into the user profile:
-;;       guix package -f guix.scm
-;;
-;;   Development shell with all dependencies:
-;;       guix shell -D -f guix.scm
-;;
-;;   Run tests inside Guix:
-;;       guix shell -D -f guix.scm -- make test
-
-(use-modules (gnu packages emacs)
-             (gnu packages texinfo)
-             (guix build-system emacs)
-             ((guix licenses) #:prefix license:)
-             (guix packages)
-             (guix gexp)
-             (ice-9 popen)
-             (ice-9 rdelim))
-
-(define %source-dir (dirname (current-filename)))
-
-(define (git-output . args)
-  "Run `git -C %source-dir ARGS...' and return trimmed stdout, or #f
-if the command fails."
-  (let* ((port (apply open-pipe* OPEN_READ "git" "-C" %source-dir args))
-         (line (read-line port)))
-    (close-pipe port)
-    (if (eof-object? line) #f line)))
-
-(define %version
-  (or (git-output "describe" "--tags" "--always" "--dirty")
-      (and=> (git-output "rev-parse" "--short" "HEAD")
-             (lambda (hash) (string-append "0.1.0-" hash)))
-      "0.1.0-git"))
-
-(define (source-file? file stat)
-  "Include everything except VCS metadata and build artifacts."
-  (let ((name (basename file)))
-    (not (or (string-prefix? "." name)
-             (string-contains file "/refs/")
-             (string-suffix? ".elc" file)
-             (string-suffix? ".info" file)
-             (string-suffix? ".texi" file)
-             (string-suffix? "~" file)))))
-
-(define-public emacs-keymap-popup-git
-  (package
-    (name "emacs-keymap-popup-git")
-    (version %version)
-    (source (local-file %source-dir
-                        "keymap-popup-checkout"
-                        #:recursive? #t
-                        #:select? source-file?))
-    (build-system emacs-build-system)
-    (arguments
-     (list
-      #:phases
-      #~(modify-phases %standard-phases
-          (add-after 'unpack 'build-info-manual
-            (lambda _
-              (invoke "emacs" "-Q" "--batch"
-                      "--load" "org"
-                      "--eval" "(with-current-buffer (find-file 
\"docs/keymap-popup.org\") (org-texinfo-export-to-info))"
-                      "--kill")))
-          (replace 'check
-            (lambda* (#:key tests? #:allow-other-keys)
-              (when tests?
-                (invoke "emacs" "-Q" "--batch"
-                        "-l" "ert"
-                        "-l" "keymap-popup.el"
-                        "-l" "tests/keymap-popup-tests.el"
-                        "-f" "ert-run-tests-batch-and-exit"))))
-          (add-after 'install 'install-info-manual
-            (lambda _
-              (install-file "docs/keymap-popup.info"
-                            (string-append #$output "/share/info")))))))
-    (native-inputs (list texinfo))
-    (home-page "https://codeberg.org/thanosapollo/emacs-forgejo";)
-    (synopsis "Described keymaps with popup help")
-    (description
-     "A single macro that produces both a real Emacs keymap (for direct
-key dispatch) and stored descriptions (for a popup help window).
-One definition, two uses.  No EIEIO, no OOP, no infix arguments.")
-    (license license:gpl3+)))
-
-emacs-keymap-popup-git
diff --git a/keymap-popup.el b/keymap-popup.el
index 303381d9fea..a6e2da29aee 100644
--- a/keymap-popup.el
+++ b/keymap-popup.el
@@ -288,7 +288,7 @@ Each row is a list of group plists with :name and :entries."
           (keymap-popup--split-groups bindings)))
 
 (defun keymap-popup--if-allows-p (plist)
-  "Return non-nil when PLIST has no :if, or its :if predicate returns non-nil."
+  "Return non-nil when PLIST has no :if or its :if predicate is non-nil."
   (let ((pred (plist-get plist :if)))
     (or (null pred) (funcall pred))))
 

Reply via email to