Subject: [PATCH 39/39] gnu: rust-analyzer: Make it out of box.

From: Z572 <[email-masked]>
Date: Wed, 12 Jan 2022 23:27:59 +0800

* gnu/packages/rust-apps.scm (rust-src): New variable.
(rust-analyzer): [arguments]: <#:phases>: Add wrap-program phase.
[inputs]: Add rust-src.
---
 gnu/packages/rust-apps.scm | 44 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/gnu/packages/rust-apps.scm b/gnu/packages/rust-apps.scm
index 2831b1401f..f7604ec546 100644
--- a/gnu/packages/rust-apps.scm
+++ b/gnu/packages/rust-apps.scm
@@ -33,6 +33,7 @@
 (define-module (gnu packages rust-apps)
   #:use-module ((guix licenses) #:prefix license:)
   #:use-module (guix build-system cargo)
+  #:use-module (guix build-system copy)
   #:use-module (guix download)
   #:use-module (guix git-download)
   #:use-module (guix packages)
@@ -1158,6 +1159,24 @@ (define-public watchexec
 runs a command whenever it detects modifications.")
     (license license:asl2.0)))
 
+(define-public rust-src
+  (hidden-package
+   (package
+     (inherit rust-1.57)
+     (name "rust-src")
+     (build-system copy-build-system)
+     (native-inputs '())
+     (inputs '())
+     (native-search-paths '())
+     (outputs '("out"))
+     (arguments
+      `(#:install-plan
+        '(("library" "lib/rustlib/src/rust/library")
+          ("src" "lib/rustlib/src/rust/src"))))
+     (synopsis "Source code for the Rust standard library")
+     (description "This package provide source code for the Rust standard
+library, only use by rust-analyzer, make rust-analyzer out of box."))))
+
 (define-public rust-analyzer
   (package
     (name "rust-analyzer")
@@ -1290,6 +1309,30 @@ (define-public rust-analyzer
          (add-before 'install 'chdir
            (lambda _
              (chdir "crates/rust-analyzer")))
+         (add-after 'install 'wrap-program
+           (lambda* (#:key inputs outputs #:allow-other-keys)
+             (let* ((out (assoc-ref outputs "out"))
+                    (bin (string-append out "/bin"))
+                    (rust-src-path (search-input-directory
+                                    inputs "/lib/rustlib/src/rust/library")))
+               ;; if not get environment variable RUST_SRC_PATH, set it,
+               ;; make rust-analyzer out of box.
+               (with-directory-excursion bin
+                 (let* ((prog "rust-analyzer")
+                        (wrapped-file (string-append (dirname prog)
+                                                     "/." (basename prog) "-real"))
+                        (prog-tmp (string-append wrapped-file "-tmp")))
+                   (link prog wrapped-file)
+                   (call-with-output-file prog-tmp
+                     (lambda (port)
+                       (format port "#!~a
+if test -z \"${RUST_SRC_PATH}\";then export RUST_SRC_PATH=~S;fi;
+exec -a \"$0\" \"~a\" \"$@\""
+                               (which "bash")
+                               rust-src-path
+                               (canonicalize-path wrapped-file))))
+                   (chmod prog-tmp #o755)
+                   (rename-file prog-tmp prog))))))
          (replace 'install-license-files
            (lambda* (#:key outputs #:allow-other-keys)
              (let* ((out (assoc-ref outputs "out"))
@@ -1298,6 +1341,7 @@ (define-public rust-analyzer
                (chdir "../..")
                (install-file "LICENSE-MIT" doc)
                (install-file "LICENSE-APACHE" doc)))))))
+    (inputs (list rust-src))
     (home-page "https://rust-analyzer.github.io/")
     (synopsis "Experimental Rust compiler front-end for IDEs")
     (description "Rust-analyzer is a modular compiler frontend for the Rust
-- 
2.34.0