Skip to content

Commit d861df5

Browse files
Merge pull request #24 from gjsjohnmurray/enh-23
Support adding servers from quickpick
2 parents b512b93 + 3652769 commit d861df5

File tree

3 files changed

+141
-7
lines changed

3 files changed

+141
-7
lines changed

src/api/addServer.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import * as vscode from "vscode";
2+
import { getServerNames } from "./getServerNames";
3+
4+
export async function addServer(scope?: vscode.ConfigurationScope): Promise<string | undefined> {
5+
const serverNames = getServerNames(scope);
6+
const spec = { webServer: { scheme: "", host: "", port: 0 } };
7+
return await vscode.window
8+
.showInputBox({
9+
placeHolder: "Name of new server definition",
10+
validateInput: (value) => {
11+
if (value === "") {
12+
return "Required";
13+
}
14+
if (serverNames.filter((server) => server.name === value).length) {
15+
return "Name already exists";
16+
}
17+
if (!value.match(/^[a-z0-9-._~]+$/)) {
18+
return "Can only contain a-z, 0-9 and punctuation -._~";
19+
}
20+
return null;
21+
},
22+
})
23+
.then(
24+
async (name): Promise<string | undefined> => {
25+
if (name) {
26+
const host = await vscode.window.showInputBox({
27+
placeHolder: "Hostname or IP address of web server",
28+
validateInput: (value) => {
29+
return value.length ? undefined : "Required";
30+
},
31+
});
32+
if (host) {
33+
spec.webServer.host = host;
34+
const portString = await vscode.window.showInputBox({
35+
placeHolder: "Port of web server",
36+
validateInput: (value) => {
37+
const port = +value;
38+
return value.match(/\d+/) &&
39+
port.toString() === value &&
40+
port > 0 &&
41+
port < 65536
42+
? undefined
43+
: "Required, 1-65535";
44+
},
45+
});
46+
if (portString) {
47+
spec.webServer.port = +portString;
48+
const scheme = await vscode.window.showQuickPick(
49+
["http", "https"],
50+
{ placeHolder: "Confirm connection type, then definition will be stored in your User Settings. 'Escape' to cancel.", }
51+
);
52+
if (scheme) {
53+
spec.webServer.scheme = scheme;
54+
try {
55+
const config = vscode.workspace.getConfiguration(
56+
"intersystems",
57+
scope
58+
);
59+
// For simplicity we always add to the user-level (aka Global) settings
60+
const servers: any =
61+
config.inspect("servers")?.globalValue || {};
62+
servers[name] = spec;
63+
await config.update("servers", servers, true);
64+
return name;
65+
} catch (error) {
66+
vscode.window.showErrorMessage(
67+
"Failed to store server definition"
68+
);
69+
return undefined;
70+
}
71+
}
72+
}
73+
}
74+
}
75+
}
76+
);
77+
}

src/api/pickServer.ts

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as vscode from 'vscode';
2+
import { addServer } from './addServer';
23
import { getServerNames } from './getServerNames';
34

45
export async function pickServer(scope?: vscode.ConfigurationScope, options: vscode.QuickPickOptions = {}): Promise<string | undefined> {
@@ -13,7 +14,63 @@ export async function pickServer(scope?: vscode.ConfigurationScope, options: vsc
1314
names.forEach(element => {
1415
qpItems.push({label: element.name, description: element.description, detail: options?.matchOnDetail ? element.detail : undefined});
1516
});
16-
return await vscode.window.showQuickPick(qpItems, options).then(item => {
17-
return item ? item.label : undefined;
17+
18+
return await new Promise<string | undefined>((resolve, reject) => {
19+
var result:string
20+
var resolveOnHide = true;
21+
const quickPick = vscode.window.createQuickPick();
22+
quickPick.title = "Choose server or use '+' to add one" ;
23+
quickPick.placeholder = options.placeHolder;
24+
quickPick.matchOnDescription = options.matchOnDescription || true;
25+
quickPick.matchOnDetail = options.matchOnDetail || false;
26+
quickPick.items = qpItems;
27+
const btnAdd: vscode.QuickInputButton = { iconPath: new vscode.ThemeIcon('add'), tooltip: 'Define New Server' }
28+
quickPick.buttons = [btnAdd];
29+
30+
async function addAndResolve() {
31+
resolveOnHide = false;
32+
// Add a new server
33+
await addServer(scope)
34+
.then((value) => {
35+
if (value) {
36+
// Resolve the pickServer quickpick promise and tidy it up
37+
resolve(value);
38+
quickPick.hide();
39+
quickPick.dispose();
40+
}
41+
});
42+
}
43+
44+
quickPick.onDidChangeSelection((items) => {
45+
result = items[0].label;
46+
});
47+
48+
quickPick.onDidChangeValue(value => {
49+
if (value === '+') {
50+
addAndResolve();
51+
}
52+
})
53+
54+
quickPick.onDidTriggerButton((button) => {
55+
if (button === btnAdd) {
56+
addAndResolve();
57+
}
58+
});
59+
60+
quickPick.onDidAccept(() => {
61+
resolve(result);
62+
quickPick.hide();
63+
quickPick.dispose();
64+
});
65+
66+
quickPick.onDidHide(() => {
67+
// flag used by addAndResolve to prevent resolve here
68+
if (resolveOnHide) {
69+
resolve(undefined);
70+
}
71+
quickPick.dispose();
72+
});
73+
74+
quickPick.show();
1875
});
1976
}

src/extension.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@ export interface ServerName {
1414
}
1515

1616
export interface WebServerSpec {
17-
scheme: string,
17+
scheme?: string,
1818
host: string,
1919
port: number,
20-
pathPrefix: string
20+
pathPrefix?: string
2121
}
2222

2323
export interface ServerSpec {
2424
name: string,
2525
webServer: WebServerSpec,
26-
username: string,
27-
password: string,
28-
description: string
26+
username?: string,
27+
password?: string,
28+
description?: string
2929
}
3030

3131
export function activate(context: vscode.ExtensionContext) {

0 commit comments

Comments
 (0)