forked from lisongx/atom-tidal
/
ghc.js
111 lines (95 loc) · 3.38 KB
/
ghc.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
'use babel'
const path = require('path')
const fs = require('fs')
const os = require('os')
const Process = require('./process')
const child_process = require('child_process');
const ghciPathProperty = 'tidalcycles.ghciPath'
const interpreterProperty = 'tidalcycles.interpreter'
const stackPrefix = 'stack exec --package tidal'
const nixPrefix = 'nix-shell -p "haskellPackages.ghcWithPackages (pkgs: [pkgs.tidal])" --run'
export default class Ghc {
constructor(consoleView) {
this.consoleView = consoleView;
}
init() {
switch (atom.config.get(interpreterProperty)) {
case 'stack':
this.interactivePath = `${stackPrefix} ghci`
this.pkgPath = `${stackPrefix} ghc-pkg`
break;
case 'nix':
this.interactivePath = `${nixPrefix} ghci`
this.pkgPath = `${nixPrefix} "ghc-pkg"`
break;
default:
let basePath = this.ghcBasePath();
this.consoleView.flushLog()
if (basePath.startsWith('stack') || basePath.startsWith('nix-shell')) {
this.interactivePath = basePath + "ghci"
this.pkgPath = basePath + "ghc-pkg"
} else {
this.interactivePath = path.join(basePath, "ghci")
this.pkgPath = path.join(basePath, "ghc-pkg")
}
}
this.consoleView
.logStdout(`Ghci command: ${this.interactivePath}\nGhc-pkg command: ${this.pkgPath}`)
}
interactive() {
return Process.ghci(this.wrappedInteractivePath());
}
browseTidal(callback) {
child_process.exec(`echo ":browse Sound.Tidal.Context" | ${this.wrappedInteractivePath()}`,
(error, stdout) => {
if (error) {
this.consoleView.logStderr(`Cannot browse tidal to obtain informations for autocomplete: ${error}`)
} else {
callback(stdout)
}
})
}
pkg(args) {
let command = ((interpreter => {
switch(interpreter) {
case 'stack': return `${stackPrefix} ghc-pkg ${args}`
case 'nix': return `${nixPrefix} "ghc-pkg ${args}"`
default: return `"${this.pkgPath}" ${args}`
}
}))(atom.config.get(interpreterProperty));
return child_process
.execSync(command)
.toString().trim()
}
tidalDataDir() {
let dataDir = this.pkg('field tidal data-dir').trim()
return dataDir.substring(dataDir.indexOf(' ') + 1)
}
ghcBasePath() {
let propertyValue = atom.config.get(ghciPathProperty)
this.consoleView.appendLog(`Choose <b>ghc</b> base path`)
if (propertyValue) {
this.consoleView.appendLog(`<b> * custom path configured</b>`)
let resolvedPropertyValue = propertyValue.replace('~', os.homedir())
return resolvedPropertyValue.endsWith('ghci')
? resolvedPropertyValue.substring(0, resolvedPropertyValue.length - 4)
: resolvedPropertyValue
} else {
this.consoleView.appendLog(` > no custom path configured`)
let ghcupPath = path.join(os.homedir(), ".ghcup", "bin")
if (fs.existsSync(ghcupPath)) {
this.consoleView.appendLog(`<b> * use ghcup default path</b>`)
return ghcupPath
} else {
this.consoleView.appendLog(` > ghcup not found`)
this.consoleView.appendLog(`<b> * using default GHC system path definition</b>`)
return ""
}
}
}
wrappedInteractivePath() {
return atom.config.get(interpreterProperty) === 'default'
? `"${this.interactivePath}"`
: `${this.interactivePath}`
}
}