Skip to content

Commit

Permalink
Improve leiningen project search
Browse files Browse the repository at this point in the history
I have a problem when I use Calva's Jack In command - I have to run to
open my project.clj file in the root of the repo before I Jack In. If
I run the command when I have any source files open in the editor, the
Jack In fails.

The reason for this is that Calva will search from the directory
containing the current file down to the workspace root.

There are many projects named `project.clj` in the main CircleCI repo,
since a project one of our core domain objects:

```
marc@blaster ~/dev/circleci/circle $ find . -name project.clj
./project.clj
./src/circle/project.clj
./src/circle/http/api/v1/v1_0/project.clj
./src/circle/http/api/v1/v1_1/project.clj
./src/circle/http/api/v1/shared/project.clj
./src/circle/http/api/v2/insights/project.clj
./src/circle/http/api/v2/project.clj
./src/circle/http/api/v2/entities/insights/project.clj
./src/circle/http/api/v2/entities/project.clj
./src/circle/model/project.clj
./src/circle/model/api/project.clj
```

If I have any file open in `src/circle`, (which is the location of all
source files), Calva will find `src/circle/project.clj` before it
considers the project.clj in the root. As far as I understand, this is a
desirable search behaviour, since it allows folks to use Calva in
projects that contain multiple leiningen projects.

This change alters the search behaviour to only consider files that
don't begin with the string `(ns ` when attempting the determine the
project path.

Fixes #871
  • Loading branch information
marcomorain committed Nov 30, 2021
1 parent 6952885 commit 1fb466d
Showing 1 changed file with 15 additions and 6 deletions.
21 changes: 15 additions & 6 deletions src/state.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as vscode from 'vscode';
import Analytics from './analytics';
import * as util from './utilities';
import * as filesCache from './files-cache'
import * as path from 'path';
import * as os from 'os';
import * as fs from 'fs';
Expand Down Expand Up @@ -140,14 +141,20 @@ export async function initProjectDir(uri?: vscode.Uri): Promise<void> {
}
}

async function findLocalProjectRoot(projectFileNames, doc, workspaceFolder): Promise<void> {
function isNamespace(path: string): boolean {
const content = filesCache.content(path);
const hasNsDecl = /^\(ns /.test(content);
return hasNsDecl;
}

async function findLocalProjectRoot(projectFileNames: string[], doc: vscode.TextDocument, workspaceFolder: vscode.WorkspaceFolder): Promise<void> {
if (workspaceFolder) {
let rootPath: string = path.resolve(workspaceFolder.uri.fsPath);
setStateValue(PROJECT_DIR_KEY, rootPath);
setStateValue(PROJECT_DIR_URI_KEY, workspaceFolder.uri);

let d = null;
let prev = null;
let d: string = null;
let prev: string = null;
if (doc && path.dirname(doc.uri.fsPath) !== '.') {
d = path.dirname(doc.uri.fsPath);
} else {
Expand All @@ -156,7 +163,7 @@ async function findLocalProjectRoot(projectFileNames, doc, workspaceFolder): Pro
while (d !== prev) {
for (let projectFile in projectFileNames) {
const p = path.resolve(d, projectFileNames[projectFile]);
if (fs.existsSync(p)) {
if (fs.existsSync(p) && !isNamespace(p)) {
rootPath = d;
break;
}
Expand Down Expand Up @@ -192,8 +199,10 @@ async function findProjectRootUri(projectFileNames, doc, workspaceFolder): Promi
const u = vscode.Uri.joinPath(searchUri, projectFileNames[projectFile]);
try {
await vscode.workspace.fs.stat(u);
setStateValue(PROJECT_DIR_URI_KEY, searchUri);
return;
if (!isNamespace(u.fsPath)) {
setStateValue(PROJECT_DIR_URI_KEY, searchUri);
return;
}
}
catch { }
}
Expand Down

0 comments on commit 1fb466d

Please sign in to comment.