emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/haskell-tng-mode dbcef71 235/385: workaround the env file


From: ELPA Syncer
Subject: [nongnu] elpa/haskell-tng-mode dbcef71 235/385: workaround the env file situation
Date: Tue, 5 Oct 2021 23:59:38 -0400 (EDT)

branch: elpa/haskell-tng-mode
commit dbcef7179301cedd88bded7b07801808497f1809
Author: Tseen She <ts33n.sh3@gmail.com>
Commit: Tseen She <ts33n.sh3@gmail.com>

    workaround the env file situation
---
 README.md                      |  8 +++-
 haskell-tng-contrib-company.el |  3 +-
 haskell-tng-hsinspect.el       | 83 +++++++++++++++++++++++-------------------
 3 files changed, 54 insertions(+), 40 deletions(-)

diff --git a/README.md b/README.md
index 2723450..d31d2a2 100644
--- a/README.md
+++ b/README.md
@@ -67,7 +67,7 @@ Built-in navigation commands such as `forward-symbol`, 
`forward-sexp` and `imenu
 
 The optional command line tool `hsinspect` provides semantic information by 
using the `ghc` api.
 
-`hsinspect` must be installed separately for each version of `ghc` that you 
are using.
+<!-- `hsinspect` must be installed separately for each version of `ghc` that 
you are using. -->
 
 At the moment only one version of `ghc` is supported at a time (change 
`ghc-8.4.4` to your current `ghc` version):
 
@@ -92,6 +92,12 @@ with recommended binding
     ("C-c C-i s" . haskell-tng-fqn-at-point))
 ```
 
+### Known Problems
+
+To use `hsinspect` commands, generate a `.hsinspect.env` file by running `M-x 
haskell-tng-hsinspect` for a project. This is only needed when the dependencies 
change, but the project must be compilable.
+
+See [the gory details](https://gitlab.com/tseenshe/hsinspect) for more 
information and known caveats. Hopefully there will be no need for 
`haskell-tng-hsinspect` in a future release.
+
 ## Contrib
 
 Integrations are provided for common libraries and external applications 
(installed separately), enable them from `use-package` with
diff --git a/haskell-tng-contrib-company.el b/haskell-tng-contrib-company.el
index c53baae..06e50cc 100644
--- a/haskell-tng-contrib-company.el
+++ b/haskell-tng-contrib-company.el
@@ -26,8 +26,7 @@
 
 (defcustom haskell-tng-company-backends
   '(company-files
-    (company-dabbrev-code company-keywords)
-    haskell-tng--company-hsinspect)
+    (haskell-tng--company-hsinspect company-dabbrev-code company-keywords))
   "The company mode backends to use for haskell files"
   :type 'listp
   :group 'haskell-tng)
diff --git a/haskell-tng-hsinspect.el b/haskell-tng-hsinspect.el
index f6fbbae..fbc905a 100644
--- a/haskell-tng-hsinspect.el
+++ b/haskell-tng-hsinspect.el
@@ -13,23 +13,8 @@
 
 (require 'haskell-tng-compile)
 
-;; TODO automatically installing hsinspect under hsinspect-ghc-X
-
-(defcustom haskell-tng-hsinspect
-  ;; TODO https://github.com/haskell/cabal/issues/6182
-  ;;
-  ;; all flags (optimisations, compiler, tests, etc) must match what the user
-  ;; typed or else local packages aren't visible.
-  ;;'("cabal" "v2-exec" "-v0" "-O0" "--enable-tests" "--")
-  '() ;; best to use environment files, less fragile
-  "Launch command for the `hsinspect' external tool."
-  :type 'listp
-  :group 'haskell-tng)
-
 (defvar-local haskell-tng-hsinspect-langexts nil)
 ;; TODO improve the validity checker
-;;;###autoload
-(put 'haskell-tng-hsinspect-langexts 'safe-local-variable #'listp)
 
 ;;;###autoload
 (defun haskell-tng-fqn-at-point ()
@@ -44,7 +29,27 @@ name of the symbol at point in the minibuffer."
       (message "%s" (car (last found)))
     (message "<not imported>")))
 
-;; FIXME implement the `.hsinspect.env' hack and document the workflow
+(defvar haskell-tng-hsinspect
+  (concat
+   ;; no need to compile tests, use O0 so it is faster
+   "hsinspect-init () {\n"
+   "  cabal v2-build -O0 :all &&\n"
+   "  cabal v2-exec -O0 -- sh -c 'cat $GHC_ENVIRONMENT > .hsinspect.env'\n"
+   "}\n"
+   "hsinspect-init"))
+;;;###autoload
+(defun haskell-tng-hsinspect ()
+  "Required (for now) to initialise a project for use with `hsinspect'.
+Only needs to be performed once every time the dependencies
+change."
+  (interactive)
+  (when-let ((default-directory
+               (or
+                ;; prefer the full project before packages
+                (locate-dominating-file "project.cabal" "project.cabal.local")
+                (haskell-tng--util-locate-dominating-file
+                 haskell-tng--compile-dominating-file))))
+    (async-shell-command haskell-tng-hsinspect)))
 
 ;; TODO invalidate cache when imports section has changed
 ;; TODO is there a way to tell Emacs not to render this in `C-h v'?
@@ -58,27 +63,31 @@ t means the process failed.")
         haskell-tng--hsinspect-imports)
     (setq haskell-tng--hsinspect-imports t) ;; avoid races
     (ignore-errors (kill-buffer "*hsinspect*"))
-    (let ((default-directory
-            (or
-             (haskell-tng--util-locate-dominating-file
-              haskell-tng--compile-dominating-file)
-             default-directory)))
-      (if (/= 0 (apply
-                 #'call-process
-                 ;; TODO launching the correct hsinspect-ghc-X version
-                 ;; TODO is there a way to pipe into a string not a buffer?
-                 ;; TODO async
-                 "hsinspect"
-                 nil "*hsinspect*" nil
-                 (append `("imports" ,buffer-file-name)
-                         haskell-tng-hsinspect-langexts)))
-          (user-error "`hsinspect' failed. See the *hsinspect* buffer for more 
information")
-        (setq haskell-tng--hsinspect-imports
-              (with-current-buffer "*hsinspect*"
-                (goto-char (point-min))
-                (re-search-forward (rx bol "(") nil t) ;; sometimes there is 
junk from the launcher
-                (goto-char (match-beginning 0))
-                (or (ignore-errors (read (current-buffer))) t)))))))
+    (let ((envdir (locate-dominating-file default-directory ".hsinspect.env")))
+      (if (not envdir)
+          (user-error "could not find `.hsinspect.env'. Run `M-x 
haskell-tng-hsinspect'")
+        (if (/= 0
+                (let* ((ghcenv
+                        (concat "GHC_ENVIRONMENT="
+                                (expand-file-name envdir) ".hsinspect.env"))
+                       (process-environment
+                        (cons ghcenv process-environment)))
+                  (apply
+                   #'call-process
+                   ;; TODO launching the correct hsinspect-ghc-X version
+                   ;; TODO is there a way to pipe into a string not a buffer?
+                   ;; TODO async
+                   "hsinspect"
+                   nil "*hsinspect*" nil
+                   (append `("imports" ,buffer-file-name)
+                           haskell-tng-hsinspect-langexts))))
+            (user-error "`hsinspect' failed. See the *hsinspect* buffer for 
more information")
+          (setq haskell-tng--hsinspect-imports
+                (with-current-buffer "*hsinspect*"
+                  (goto-char (point-min))
+                  (re-search-forward (rx bol "(") nil t) ;; sometimes there is 
junk from the launcher
+                  (goto-char (match-beginning 0))
+                  (or (ignore-errors (read (current-buffer))) t))))))))
 
 (provide 'haskell-tng-hsinspect)
 ;;; haskell-tng-hsinspect.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]