diff --git a/CHANGELOG.md b/CHANGELOG.md index eb08f6851..a3e68f4a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Changes to Calva. ## [Unreleased] +- [Add option to manually specify project root directory](https://github.com/BetterThanTomorrow/calva/issues/579) ## [2.0.80] - 2020-03-07 - Fix so that Paredit treats symbols containing the quote character correctly. diff --git a/docs/readthedocs/source/connect-sequences.md b/docs/readthedocs/source/connect-sequences.md index 515260bf8..e02af2fe8 100644 --- a/docs/readthedocs/source/connect-sequences.md +++ b/docs/readthedocs/source/connect-sequences.md @@ -16,6 +16,7 @@ A connect sequence configures the following: * `projectType`: (required) This is either "Leiningen”, ”Clojure-CLI”, or ”shadow-cljs”. * `nReplPortFile`: An array of path segments with the project root-relative path to the nREPL port file for this connect sequence. E.g. For shadow-cljs this would be `[".shadow-cljs", "nrepl.port"]`. * `afterCLJReplJackInCode`: Here you can give Calva some Clojure code to evaluate in the CLJ REPL, once it has been created. +* `projectRootDir`: The root directory to execute the Jack-in command from. This will override the default behavior for determining the root directory relative to the current open file. This is useful for working in monorepos. * `cljsType`: This can be either "Figwheel Main", "lein-figwheel", "shadow-cljs", "Nashorn", or a dictionary configuring a custom type. If omitted, Calva will skip connecting a ClojureScript repl. A custom type has the following fields: * `dependsOn`: (required) Calva will use this to determine which dependencies it will add when starting the project (Jacking in). This can be either "Figwheel Main", "lein-figwheel", "shadow-cljs", "Nashorn", or ”User provided”. If it is "User provided", then you need to provide the dependencies in the project, or launch with an alias (deps.edn), profile (Leiningen), or build (shadow-cljs) that provides the dependencies needed. * `isStarted`: Boolean. For CLJS REPLs that Calva does not need to start, set this to true. (If you base your custom cljs repl on a shadow-cljs workflow, for instance.) diff --git a/package.json b/package.json index 9ec29eb4a..f71c9c149 100644 --- a/package.json +++ b/package.json @@ -375,6 +375,11 @@ "description": "Here you can give Calva some Clojure code to evaluate in the CLJ REPL, once it has been created.", "required": false }, + "projectRootDir": { + "type": "string", + "descripion": "The root directory to execute the Jack-in command from. This will override the default behavior for determining the root directory relative to the current open file. This is useful for working in monorepos.", + "required": false + }, "menuSelections": { "type": "object", "description": "Pre-selected menu options. If a slection is made here. Calva won't prompt for it.", diff --git a/src/nrepl/connectSequence.ts b/src/nrepl/connectSequence.ts index 7acec0e09..5bfa81643 100644 --- a/src/nrepl/connectSequence.ts +++ b/src/nrepl/connectSequence.ts @@ -38,13 +38,14 @@ interface MenuSelections { leinAlias?: string, cljAliases?: string[], cljsLaunchBuilds?: string[], - cljsDefaultBuild?: string + cljsDefaultBuild?: string, } interface ReplConnectSequence { name: string, projectType: ProjectTypes, afterCLJReplJackInCode?: string, + projectRootDir?: string, cljsType: CljsTypes | CljsTypeConfig, menuSelections?: MenuSelections, nReplPortFile?: string[] @@ -242,4 +243,4 @@ export { CljsTypes, ReplConnectSequence, CljsTypeConfig -} \ No newline at end of file +} diff --git a/src/nrepl/jack-in.ts b/src/nrepl/jack-in.ts index 089f1f9a8..1ca445bfe 100644 --- a/src/nrepl/jack-in.ts +++ b/src/nrepl/jack-in.ts @@ -26,7 +26,7 @@ vscode.tasks.onDidEndTask(((e) => { if(e.execution.task.name == TASK_NAME) { JackinExecution = undefined; connector.default.disconnect(); - // make sure everything is set back + // make sure everything is set back // even if the task failed to connect // to the repl server. utilities.setLaunchingState(null); @@ -36,11 +36,17 @@ vscode.tasks.onDidEndTask(((e) => { function cancelJackInTask() { setTimeout(() => { - calvaJackout(); + calvaJackout(); }, 1000); } async function executeJackInTask(projectType: projectTypes.ProjectType, projectTypeSelection: any, executable: string, args: any, cljTypes: string[], outputChannel: vscode.OutputChannel, connectSequence: ReplConnectSequence) { + // If the connection sequence specifies a project root dir, override the existing project dir + const projectRootDir = connectSequence?.projectRootDir; + if(projectRootDir) { + state.setProjectRoot(projectRootDir); + } + utilities.setLaunchingState(projectTypeSelection); statusbar.update(); const nReplPortFile = projectTypes.nreplPortFile(connectSequence); diff --git a/src/state.ts b/src/state.ts index 949baf3ea..04d3af8bb 100644 --- a/src/state.ts +++ b/src/state.ts @@ -156,6 +156,10 @@ export function getProjectRoot(useCache = true): string { } } +export function setProjectRoot(rootPath: string) { + cursor.set(PROJECT_DIR_KEY, rootPath); +} + export function getProjectWsFolder(): vscode.WorkspaceFolder { const doc = util.getDocument({}); return doc ? vscode.workspace.getWorkspaceFolder(doc.uri) : null; @@ -223,7 +227,7 @@ export async function initProjectDir(): Promise { for (let projectFile in projectFileNames) { const p = path.resolve(rootPath, projectFileNames[projectFile]); if (fs.existsSync(p)) { - cursor.set(PROJECT_DIR_KEY, rootPath); + setProjectRoot(rootPath); return; } }