From 867fe8deb9e6d77c3f1edcef520c27da8e352e46 Mon Sep 17 00:00:00 2001 From: Jason Manuel Date: Sat, 30 Mar 2024 18:51:24 -0700 Subject: [PATCH 1/4] Add WSL Idris installation compatibility --- lib/idris-model.ts | 14 ++++++++++++-- package-lock.json | 5 +++++ package.json | 9 ++++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/lib/idris-model.ts b/lib/idris-model.ts index 5bdd8a8..d2c5dde 100644 --- a/lib/idris-model.ts +++ b/lib/idris-model.ts @@ -6,6 +6,7 @@ import { CompilerOptions } from './utils/ipkg' import { IDECommand, SExp } from './protocol/ide-protocol' import { ideCommandToSExp } from './protocol/to-sexp' import Logger from './utils/Logger' +import { windowsToWsl } from 'wsl-path' export class IdrisModel { requestId = 0 @@ -130,7 +131,10 @@ export class IdrisModel { } changeDirectory(dir: string) { - return this.interpret(`:cd ${dir}`) + const directory = this.shouldUseWsl ? Rx.Observable.fromPromise(windowsToWsl(dir)) : Rx.Observable.of(dir) + return directory.flatMap((dir) => { + return this.interpret(`:cd ${dir}`) + }) } load(uri: string) { @@ -147,7 +151,9 @@ export class IdrisModel { } })() - return cd.flatMap((_) => { + const platformUri = this.shouldUseWsl ? Rx.Observable.fromPromise(windowsToWsl(uri)) : Rx.Observable.of(uri) + + return cd.zip(platformUri).flatMap(([_, uri]) => { return this.prepareCommand({ type: 'load-file', fileName: uri }) }) } @@ -219,4 +225,8 @@ export class IdrisModel { browseNamespace(namespace: string) { return this.prepareCommand({ type: 'browse-namespace', namespace }) } + + 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", From 8ad3ad62c28c98480e7a194370e27113b2894284 Mon Sep 17 00:00:00 2001 From: Jason Manuel Date: Sat, 30 Mar 2024 23:36:11 -0700 Subject: [PATCH 2/4] Test use of wslpath --- lib/idris-controller.ts | 3 ++- lib/idris-model.ts | 9 +++++---- spec/idris-model-spec.coffee | 30 ++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 spec/idris-model-spec.coffee 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 d2c5dde..631c174 100644 --- a/lib/idris-model.ts +++ b/lib/idris-model.ts @@ -6,7 +6,6 @@ import { CompilerOptions } from './utils/ipkg' import { IDECommand, SExp } from './protocol/ide-protocol' import { ideCommandToSExp } from './protocol/to-sexp' import Logger from './utils/Logger' -import { windowsToWsl } from 'wsl-path' export class IdrisModel { requestId = 0 @@ -15,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) { @@ -131,7 +132,7 @@ export class IdrisModel { } changeDirectory(dir: string) { - const directory = this.shouldUseWsl ? Rx.Observable.fromPromise(windowsToWsl(dir)) : Rx.Observable.of(dir) + const directory = this.shouldUseWsl ? Rx.Observable.fromPromise(this._windowsToWsl(dir)) : Rx.Observable.of(dir) return directory.flatMap((dir) => { return this.interpret(`:cd ${dir}`) }) @@ -151,7 +152,7 @@ export class IdrisModel { } })() - const platformUri = this.shouldUseWsl ? Rx.Observable.fromPromise(windowsToWsl(uri)) : Rx.Observable.of(uri) + const platformUri = this.shouldUseWsl ? Rx.Observable.fromPromise(this._windowsToWsl(uri)) : Rx.Observable.of(uri) return cd.zip(platformUri).flatMap(([_, uri]) => { return this.prepareCommand({ type: 'load-file', fileName: uri }) diff --git a/spec/idris-model-spec.coffee b/spec/idris-model-spec.coffee new file mode 100644 index 0000000..2f7562f --- /dev/null +++ b/spec/idris-model-spec.coffee @@ -0,0 +1,30 @@ +{ IdrisModel } = require "../lib/idris-model" +Rx = require "rx-lite" + +describe "Idris model", -> + it "should use Linux paths 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 use Linux paths 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" + }) From 0fd185ec639f0edb3f1d10cfff1969ae970cfa79 Mon Sep 17 00:00:00 2001 From: Jason Manuel Date: Wed, 17 Apr 2024 21:16:23 -0700 Subject: [PATCH 3/4] Test for when WSL interop is off --- spec/idris-model-spec.coffee | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/spec/idris-model-spec.coffee b/spec/idris-model-spec.coffee index 2f7562f..d235c25 100644 --- a/spec/idris-model-spec.coffee +++ b/spec/idris-model-spec.coffee @@ -2,7 +2,7 @@ Rx = require "rx-lite" describe "Idris model", -> - it "should use Linux paths to change directory when WSL integration is enabled", -> + 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")) @@ -14,7 +14,21 @@ describe "Idris model", -> runs -> expect(interpretSpy).toHaveBeenCalledWith(":cd /wsl/path") - it "should use Linux paths to load file when WSL integration is enabled", -> + 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")) @@ -28,3 +42,20 @@ describe "Idris model", -> 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() From 8ffc02440e25c1ba1bf79be4b3ac989e0aad674d Mon Sep 17 00:00:00 2001 From: Jason Manuel Date: Wed, 17 Apr 2024 21:34:22 -0700 Subject: [PATCH 4/4] Move "should use wslpath" check to one place --- lib/idris-model.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/idris-model.ts b/lib/idris-model.ts index 631c174..adad994 100644 --- a/lib/idris-model.ts +++ b/lib/idris-model.ts @@ -132,8 +132,8 @@ export class IdrisModel { } changeDirectory(dir: string) { - const directory = this.shouldUseWsl ? Rx.Observable.fromPromise(this._windowsToWsl(dir)) : Rx.Observable.of(dir) - return directory.flatMap((dir) => { + const platformDir = this._toPlatformPath(dir) + return platformDir.flatMap((dir) => { return this.interpret(`:cd ${dir}`) }) } @@ -152,7 +152,7 @@ export class IdrisModel { } })() - const platformUri = this.shouldUseWsl ? Rx.Observable.fromPromise(this._windowsToWsl(uri)) : Rx.Observable.of(uri) + const platformUri = this._toPlatformPath(uri) return cd.zip(platformUri).flatMap(([_, uri]) => { return this.prepareCommand({ type: 'load-file', fileName: uri }) @@ -227,7 +227,11 @@ export class IdrisModel { return this.prepareCommand({ type: 'browse-namespace', namespace }) } - get shouldUseWsl(): boolean { + 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') } }