Skip to content

Commit e7d854a

Browse files
committed
Frontend driven indexing
1 parent 09b6299 commit e7d854a

File tree

4 files changed

+262
-123
lines changed

4 files changed

+262
-123
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@
6363
"@jupyterlab/filebrowser": "^4.2.5",
6464
"@jupyterlab/services": "^7.2.5",
6565
"@jupyterlab/settingregistry": "^4.2.5",
66-
"@jupyterlab/translation": "^4.2.5"
66+
"@jupyterlab/translation": "^4.2.5",
67+
"minimatch": "^10.0.1"
6768
},
6869
"devDependencies": {
6970
"@jupyterlab/builder": "^4.0.0",

src/index.ts

Lines changed: 11 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -3,125 +3,13 @@ import {
33
JupyterFrontEndPlugin
44
} from '@jupyterlab/application';
55
import { ICommandPalette, ModalCommandPalette } from '@jupyterlab/apputils';
6-
import { URLExt, PathExt } from '@jupyterlab/coreutils';
6+
import { PathExt } from '@jupyterlab/coreutils';
77
import { IDocumentManager } from '@jupyterlab/docmanager';
8-
import { ServerConnection } from '@jupyterlab/services';
98
import { ISettingRegistry } from '@jupyterlab/settingregistry';
10-
import { FileBrowser, IDefaultFileBrowser } from '@jupyterlab/filebrowser';
9+
import { IDefaultFileBrowser } from '@jupyterlab/filebrowser';
1110
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
1211
import { CommandRegistry } from '@lumino/commands';
13-
import { ReadonlyPartialJSONObject } from '@lumino/coreutils';
14-
import { Message } from '@lumino/messaging';
15-
import { ISignal, Signal } from '@lumino/signaling';
16-
import { CommandPalette } from '@lumino/widgets';
17-
18-
/** Structure of the JSON response from the server */
19-
interface IQuickOpenResponse {
20-
readonly contents: { [key: string]: string[] };
21-
readonly scanSeconds: number;
22-
}
23-
24-
/** Makes a HTTP request for the server-side quick open scan */
25-
async function fetchContents(
26-
path: string,
27-
excludes: string[]
28-
): Promise<IQuickOpenResponse> {
29-
const query = excludes
30-
.map(exclude => {
31-
return 'excludes=' + encodeURIComponent(exclude);
32-
})
33-
.join('&');
34-
35-
const settings = ServerConnection.makeSettings();
36-
const fullUrl =
37-
URLExt.join(settings.baseUrl, 'jupyterlab-quickopen', 'api', 'files') +
38-
'?' +
39-
query +
40-
'&path=' +
41-
path;
42-
const response = await ServerConnection.makeRequest(
43-
fullUrl,
44-
{ method: 'GET' },
45-
settings
46-
);
47-
if (response.status !== 200) {
48-
throw new ServerConnection.ResponseError(response);
49-
}
50-
return await response.json();
51-
}
52-
53-
/**
54-
* Shows files nested under directories in the root notebooks directory configured on the server.
55-
*/
56-
class QuickOpenWidget extends CommandPalette {
57-
private _pathSelected = new Signal<this, string>(this);
58-
private _settings: ReadonlyPartialJSONObject;
59-
private _fileBrowser: FileBrowser;
60-
61-
constructor(
62-
defaultBrowser: IDefaultFileBrowser,
63-
settings: ReadonlyPartialJSONObject,
64-
options: CommandPalette.IOptions
65-
) {
66-
super(options);
67-
68-
this.id = 'jupyterlab-quickopen';
69-
this.title.iconClass = 'jp-SideBar-tabIcon jp-SearchIcon';
70-
this.title.caption = 'Quick Open';
71-
72-
this._settings = settings;
73-
this._fileBrowser = defaultBrowser;
74-
}
75-
76-
/** Signal when a selected path is activated. */
77-
get pathSelected(): ISignal<this, string> {
78-
return this._pathSelected;
79-
}
80-
81-
/** Current extension settings */
82-
set settings(settings: ReadonlyPartialJSONObject) {
83-
this._settings = settings;
84-
}
85-
86-
/**
87-
* Refreshes the widget with the paths of files on the server.
88-
*/
89-
protected async onActivateRequest(msg: Message): Promise<void> {
90-
super.onActivateRequest(msg);
91-
92-
// Fetch the current contents from the server
93-
const path = this._settings.relativeSearch
94-
? this._fileBrowser.model.path
95-
: '';
96-
const response = await fetchContents(
97-
path,
98-
this._settings.excludes as string[]
99-
);
100-
101-
// Remove all paths from the view
102-
this.clearItems();
103-
104-
for (const category in response.contents) {
105-
for (const fn of response.contents[category]) {
106-
// Creates commands that are relative file paths on the server
107-
const command = `${category}/${fn}`;
108-
if (!this.commands.hasCommand(command)) {
109-
// Only add the command to the registry if it does not yet exist TODO: Track disposables
110-
// and remove
111-
this.commands.addCommand(command, {
112-
label: fn,
113-
execute: () => {
114-
// Emit a selection signal
115-
this._pathSelected.emit(command);
116-
}
117-
});
118-
}
119-
// Make the file visible under its parent directory heading
120-
this.addItem({ command, category });
121-
}
122-
}
123-
}
124-
}
12+
import { QuickOpenWidget } from './quickopen';
12513

12614
/**
12715
* Initialization data for the jupyterlab-quickopen extension.
@@ -144,13 +32,14 @@ const extension: JupyterFrontEndPlugin<void> = {
14432
const settings: ISettingRegistry.ISettings = await settingRegistry.load(
14533
extension.id
14634
);
147-
const widget: QuickOpenWidget = new QuickOpenWidget(
148-
defaultFileBrowser,
149-
settings.composite,
150-
{
151-
commands
152-
}
153-
);
35+
const widget: QuickOpenWidget = new QuickOpenWidget({
36+
defaultBrowser: defaultFileBrowser,
37+
settings: settings.composite,
38+
commandPaletteOptions: { commands },
39+
contents: app.serviceManager.contents,
40+
// TODO: remove
41+
useServer: false
42+
});
15443

15544
// Listen for path selection signals and show the selected files in the appropriate
15645
// editor/viewer

0 commit comments

Comments
 (0)