tidalcycles / Tidal

Pattern language
http://tidalcycles.org/
GNU General Public License v3.0
2.27k stars 256 forks source link

tidal.el fails to infer `tidal-boot-script-path` on new GHC and Cabal #583

Closed xmacex closed 4 years ago

xmacex commented 4 years ago

Describe the bug The Emacs mode tidal.el fails to infer where BootTidal.el is, and so C-c C-s leads to error in the Haskell comint window rather than a successful connection with SuperCollider.

To Reproduce Steps to reproduce the behavior:

  1. Get SuperCollider running.
  2. Press C-x C-f where-were-you-in-92.tidal.
  3. Tidal mode loads and all seems to be well.
  4. Press C-c C-s (tidal-start-haskell) in the hopes of connecting to SuperCollider.
  5. Variable not in scope errors for ghc, pkg and others.

Expected behavior

Basically

Screenshots

The following Comint window between Emacs and Haskell, with errors.

GHCi, version 8.8.1: https://www.haskell.org/ghc/  :? for help
Loaded package environment from /Users/maco/.ghc/x86_64-darwin-8.8.1/environments/default
Prelude> syntax:  :script <filename>
Prelude> 
<interactive>:2:1: error: Variable not in scope: ghc

<interactive>:2:5: error: Variable not in scope: pkg

<interactive>:2:10: error: Variable not in scope: command :: [a]

<interactive>:2:18: error:
    • Variable not in scope: line :: t0 -> ([Char] -> a0) -> [a]
    • Perhaps you meant ‘lines’ (imported from Prelude)

<interactive>:2:23: error: Variable not in scope: syntax
Prelude> 
<interactive>:3:27: error:
    • Syntax error on 'ghc
      Perhaps you intended to use TemplateHaskell or TemplateHaskellQuotes
    • In the Template Haskell quotation 'ghc
Prelude> 

Environment (please complete the following information):

Additional context I looked into tidal.el and what is going on there. I searched for those two variables which are out of scope, namely ghc and pkg. This led me to investigate the value of tidal-boot-script-path which surprisingly has the following, 3-line value:

"ghc-pkg: cannot find package tidal
ghc-pkg: command-line syntax error
For usage information see 'ghc-pkg --help'./BootTidal.el

Ok so the lines 60 to 76 try to infer where BootTidal.el recides.

https://github.com/tidalcycles/Tidal/blob/bdbe6ee9e43ed7f66d79432522e85a99c1dc4d4e/tidal.el#L60

(defvar tidal-boot-script-path
  (let ((filepath
         (cond
          ((string-equal system-type "windows-nt")
           '(("path" . "echo off && for /f %a in ('ghc-pkg latest tidal') do (for /f \"tokens=2\" %i in ('ghc-pkg describe %a ^| findstr data-dir') do (echo %i))")
             ("separator" . "\\")
             ))
          ((or (string-equal system-type "darwin") (string-equal system-type "gnu/linux"))
           '(("path" . "ghc-pkg describe $(ghc-pkg latest tidal) | grep data-dir | cut -f2 -d' '")
             ("separator" . "/")
             ))
          )
         ))
    (concat (substring (shell-command-to-string (cdr (assoc "path" filepath))) 0 -1) (cdr (assoc "separator" filepath)) "BootTidal.hs")
  )
  "*Full path to BootTidal.hs (inferred by introspecting ghc-pkg package db)."
)

This inference fails, because apparently new GHC and Cabal do not find installed libraries, as things have changed over there (see https://gitlab.haskell.org/ghc/ghc/issues/17341). Using the -f switch to point Cabal to package.db is necessary, and I can verify this because ghc-pkg list tidal says Tidal is not installed, but ghc-pkg list -f ~/.cabal/store/ghc-8.8.1/package.db tidal tells me, correctly, that Tidal 1.4.5 is indeed installed.

The documentation for ghc-pkg's -f is

-f FILE/DIR --package-db=FILE/DIR use the specified package database

Ok now with the new wisdom, in Emacs if I M-: (setq tidal-boot-script-path "/Users/maco/.cabal/store/ghc-8.8.1/tdl-1.4.5-64a02384/share/BootTidal.hs") and then C-c C-s in my tidal-mode buffer, it is ravetime.

Sorry I do not even understand basically at all how GHC, Cabal and Stack keep track of my packages, what gets installed where and it is all a mess to be honest. However, the above documents both the issue I encounter and provides a solution which works for me, namely manually setting tidal-boot-script-path to point to my BootTidal.hs.

I see the following options.

  1. Add -f ~/.cabal/store/ GHC version here /package.db to line https://github.com/tidalcycles/Tidal/blob/bdbe6ee9e43ed7f66d79432522e85a99c1dc4d4e/tidal.el#L68
  2. Have ghc-pkg without -f and an argument.
  3. Redesign the tidal-boot-script-path inference on lines 60-76 to not rely on ghc-pkg.

This Cabal stuff is being discussed, in general terms, also in #572.

yaxu commented 4 years ago

Thanks for this! I've been meaning to look into this for a while.

I think it's best to base this inference on the first list from the following:

ghc-pkg field tidal data-dir

Ideally rather than using cut to remove the data-dir: prefix, that would be done in elisp. Then it would work under windows, too. This is how it's done in the atom plugin: https://github.com/tidalcycles/atom-tidalcycles/blob/1d8b5f351fe0d86669bfaba038a056f58e631b2b/lib/ghc.js#L42

It would also be good to be able to override this path in .emacs, I've not even managed that though.. I have no elisp skills unfortunately!

yaxu commented 4 years ago

I swear this was working for me before, but now tidal-boot-script-path returns this:

"/home/alex/.cabal/store/ghc-8.6.5/tidal-1.4.6-785fe771b94c3a2a9a978fca85addbe349e689c334915c9d8e6b0bdc4203b3a4/share
data-dir/BootTidal.hs"

I.e. the correct value but with \n data-dir inserted in the path. I have no idea how that happens! Any idea @xmacex ?

yaxu commented 4 years ago

Never mind, I restarted emacs and it seems happier now. Odd.

KonVas commented 3 years ago

I still getting this.

marcora commented 3 years ago

Same here!