From be03b7c747d4146ae812f286908ebb07c47c7b63 Mon Sep 17 00:00:00 2001 From: David Logie Date: Fri, 22 Dec 2023 00:21:19 +0000 Subject: [PATCH] Add shebang support for files using flakes. Docs: https://nixos.org/manual/nix/stable/command-ref/new-cli/nix.html#shebang-interpreter This is slightly more complicated than nix-shell detection due to the `#!nix ...` not appearing directly after the shebang, so re-search-forward is used to find the matching line. This does mean that opening a huge file may slow down emacs while the search is running. There are two mitigations for that: 1. nix-shebang will try to parse the nix-shell line first. 2. Users can keep `nix-shell -i ...` as the second line in your nix script. This won't affect the script at runtime (i.e. it will still use flakes) and keeps the old detection behavior. 3. An option could be added to disable flake support entirely. --- nix-shebang.el | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/nix-shebang.el b/nix-shebang.el index a1b69c9..9e5e566 100644 --- a/nix-shebang.el +++ b/nix-shebang.el @@ -11,6 +11,9 @@ ;; This detects file headers that look like: ;; #!/usr/bin/env nix-shell ;; #!nix-shell -i bash +;; As well as: +;; #!/usr/bin/env nix +;; #! nix shell nixpkgs#bash nixpkgs#hello nixpkgs#cowsay --command bash ;; and correctly detects their file modes. @@ -20,14 +23,19 @@ (defvar nix-shebang-interpreter-regexp "#!\s*nix-shell -i \\([^ \t\n]+\\)" "Regexp for nix-shell -i header.") +(defvar nix-shebang-flake-interpreter-regexp "^#!\s*nix .*--command \\(.*\\)" + "Regexp for nix shell script using flakes.") (defun nix-shebang-get-interpreter () - "Get interpreter string from nix-shell -i file." + "Get interpreter string" (save-excursion (goto-char (point-min)) - (forward-line 1) - (when (looking-at nix-shebang-interpreter-regexp) - (match-string 1)))) + (forward-line 1) + (if (looking-at nix-shebang-interpreter-regexp) + (match-string 1) + (if (and (re-search-forward nix-shebang-flake-interpreter-regexp nil t) + (looking-back nix-shebang-flake-interpreter-regexp)) + (match-string 1))))) (defun nix-shebang-mode () "Detect and run file’s interpreter mode."