diff --git a/lib/idris-controller.ts b/lib/idris-controller.ts index 73c9f66..b5aebc1 100644 --- a/lib/idris-controller.ts +++ b/lib/idris-controller.ts @@ -18,10 +18,11 @@ import { Pane, WorkspaceOpenOptions, } from 'atom' +import { windowsToWsl } from 'wsl-path' export class IdrisController { errorMarkers: Array = [] - model: IdrisModel = new IdrisModel() + model: IdrisModel = new IdrisModel(windowsToWsl) messages: MessagePanelView = new MessagePanelView({ title: 'Idris Messages', }) diff --git a/lib/idris-model.ts b/lib/idris-model.ts index 5bdd8a8..adad994 100644 --- a/lib/idris-model.ts +++ b/lib/idris-model.ts @@ -14,9 +14,11 @@ export class IdrisModel { warnings: any = {} compilerOptions: CompilerOptions = { pkgs: [] } oldCompilerOptions: CompilerOptions = { pkgs: [] } + private _windowsToWsl: (path: string) => Promise - constructor() { + constructor(windowsToWsl: (path: string) => Promise) { this.handleCommand = this.handleCommand.bind(this) + this._windowsToWsl = windowsToWsl } ideMode(compilerOptions: any) { @@ -130,7 +132,10 @@ export class IdrisModel { } changeDirectory(dir: string) { - return this.interpret(`:cd ${dir}`) + const platformDir = this._toPlatformPath(dir) + return platformDir.flatMap((dir) => { + return this.interpret(`:cd ${dir}`) + }) } load(uri: string) { @@ -147,7 +152,9 @@ export class IdrisModel { } })() - return cd.flatMap((_) => { + const platformUri = this._toPlatformPath(uri) + + return cd.zip(platformUri).flatMap(([_, uri]) => { return this.prepareCommand({ type: 'load-file', fileName: uri }) }) } @@ -219,4 +226,12 @@ export class IdrisModel { browseNamespace(namespace: string) { return this.prepareCommand({ type: 'browse-namespace', namespace }) } + + private _toPlatformPath(path: string): Rx.Observable { + return this._shouldUseWsl ? Rx.Observable.fromPromise(this._windowsToWsl(path)) : Rx.Observable.of(path) + } + + private get _shouldUseWsl(): boolean { + return atom.config.get('language-idris.idrisInWsl') + } } diff --git a/package-lock.json b/package-lock.json index 966c49e..2feb850 100644 --- a/package-lock.json +++ b/package-lock.json @@ -292,6 +292,11 @@ "requires": { "underscore": "^1.9.1" } + }, + "wsl-path": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/wsl-path/-/wsl-path-3.0.4.tgz", + "integrity": "sha512-HWlboAWRgn+qoUfvYxfr2I1PcF5FAY3PQIwSOPisAIP1JjHKsC5L2SrnGxQBCTuSmR9QwZWo8Q5pRczERTaUIg==" } } } diff --git a/package.json b/package.json index fa5ff40..48f0288 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,12 @@ "type": "boolean", "default": false, "description": "Enable ligatures in the various idris panels" + }, + "idrisInWsl": { + "title": "Integrate with an Idris installation in WSL", + "type": "boolean", + "default": false, + "description": "Enable this if you installed Idris in WSL but run the editor in Windows" } }, "providedServices": { @@ -84,7 +90,8 @@ "preact": "10.4.4", "rx-lite": "4.0.8", "tslib": "1.11.1", - "typescript": "3.9.2" + "typescript": "3.9.2", + "wsl-path": "^3.0.1" }, "devDependencies": { "@types/atom": "1.40.4", diff --git a/spec/idris-model-spec.coffee b/spec/idris-model-spec.coffee new file mode 100644 index 0000000..d235c25 --- /dev/null +++ b/spec/idris-model-spec.coffee @@ -0,0 +1,61 @@ +{ IdrisModel } = require "../lib/idris-model" +Rx = require "rx-lite" + +describe "Idris model", -> + it "should use wsl-path to change directory when WSL integration is enabled", -> + finished = false + spyOn(atom.config, "get").andReturn true + idrisModel = new IdrisModel(-> Promise.resolve("/wsl/path")) + interpretSpy = spyOn(idrisModel, "interpret").andReturn Rx.Observable.of(null) + runs -> + idrisModel.changeDirectory("C:\\windows\\path").subscribe -> + finished = true + waitsFor (-> finished), "changeDirectory should complete", 500 + runs -> + expect(interpretSpy).toHaveBeenCalledWith(":cd /wsl/path") + + it "should not use wsl-path to change directory when WSL integration is disabled", -> + finished = false + spyOn(atom.config, "get").andReturn false + wslPathSpy = jasmine.createSpy("windowsToWsl") + idrisModel = new IdrisModel(wslPathSpy) + interpretSpy = spyOn(idrisModel, "interpret").andReturn Rx.Observable.of(null) + runs -> + idrisModel.changeDirectory("C:\\windows\\path").subscribe -> + finished = true + waitsFor (-> finished), "changeDirectory should complete", 500 + runs -> + expect(interpretSpy).toHaveBeenCalledWith(":cd C:\\windows\\path") + expect(wslPathSpy).not.toHaveBeenCalled() + + it "should use wsl-path to load file when WSL integration is enabled", -> + finished = false + spyOn(atom.config, "get").andReturn true + idrisModel = new IdrisModel(-> Promise.resolve("/wsl/path")) + prepareCommandSpy = spyOn(idrisModel, "prepareCommand").andReturn Rx.Observable.of(null) + runs -> + idrisModel.load("C:\\windows\\path").subscribe -> + finished = true + waitsFor (-> finished), "load should complete", 500 + runs -> + expect(prepareCommandSpy).toHaveBeenCalledWith({ + type: "load-file" + fileName: "/wsl/path" + }) + + it "should not use wsl-path to load file when WSL integration is disabled", -> + finished = false + spyOn(atom.config, "get").andReturn false + wslPathSpy = jasmine.createSpy("windowsToWsl") + idrisModel = new IdrisModel(wslPathSpy) + prepareCommandSpy = spyOn(idrisModel, "prepareCommand").andReturn Rx.Observable.of(null) + runs -> + idrisModel.load("C:\\windows\\path").subscribe -> + finished = true + waitsFor (-> finished), "load should complete", 500 + runs -> + expect(prepareCommandSpy).toHaveBeenCalledWith({ + type: "load-file" + fileName: "C:\\windows\\path" + }) + expect(wslPathSpy).not.toHaveBeenCalled()