Skip to content

Commit 5e7f8a2

Browse files
authored
Merge pull request #41 from daimor/viewothers
view others files with shortcut
2 parents 2f97116 + 2a76603 commit 5e7f8a2

File tree

3 files changed

+186
-33
lines changed

3 files changed

+186
-33
lines changed

api/index.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import httpModule = require('http');
2+
import httpsModule = require('https');
3+
4+
import { ClientResponse } from 'http';
5+
6+
export class AtelierAPI {
7+
private http;
8+
private url;
9+
private agent;
10+
private cookies: string[] = [];
11+
constructor(
12+
private host: string,
13+
private port: number,
14+
private username: string,
15+
private password: string,
16+
private ns: string,
17+
private secure: boolean
18+
) {
19+
this.http = secure ? httpsModule : httpModule;
20+
this.agent = new this.http.Agent({ keepAlive: true, maxSockets: 10 });
21+
}
22+
23+
updateCookies(cookies: string[]) {
24+
cookies.forEach(cookie => {
25+
let [cookieName] = cookie.split('=');
26+
let index = this.cookies.findIndex(el => el.startsWith(cookieName));
27+
if (index) {
28+
this.cookies[index] = cookie;
29+
} else {
30+
this.cookies.push(cookie);
31+
}
32+
});
33+
}
34+
35+
request(method: string, path?: string, body?: any): Promise<any> {
36+
const headers = {
37+
Accept: 'application/json',
38+
Cookie: this.cookies
39+
};
40+
method = method.toUpperCase();
41+
if (['PUT', 'POST'].includes(method)) {
42+
headers['Content-Type'] = 'application/json';
43+
}
44+
return new Promise((resolve, reject) => {
45+
const req: httpModule.ClientRequest = this.http
46+
.request(
47+
{
48+
method,
49+
host: this.host,
50+
port: this.port,
51+
path: encodeURI(`/api/atelier/${path || ''}`),
52+
agent: this.agent,
53+
headers,
54+
body
55+
},
56+
(response: ClientResponse) => {
57+
if (response.statusCode < 200 || response.statusCode > 299) {
58+
reject(new Error('Failed to load page "' + path + '", status code: ' + response.statusCode));
59+
}
60+
this.updateCookies(response.headers['set-cookie']);
61+
// temporary data holder
62+
let body: string = '';
63+
response.on('data', chunk => {
64+
body += chunk;
65+
});
66+
response.on('end', () => {
67+
if (response.headers['content-type'].includes('json')) {
68+
body = JSON.parse(body);
69+
}
70+
resolve(body);
71+
});
72+
}
73+
)
74+
.on('error', reject);
75+
if (['PUT', 'POST'].includes(method)) {
76+
req.write(JSON.stringify(body));
77+
}
78+
req.end();
79+
});
80+
}
81+
82+
serverInfo(): Promise<any> {
83+
return this.request('GET');
84+
}
85+
86+
getDocNames({
87+
generated = false,
88+
category = '*',
89+
filter = ''
90+
}: {
91+
generated: boolean;
92+
category: string;
93+
filter: string;
94+
}): Promise<any> {
95+
return this.request(
96+
'GET',
97+
`v2/${this.ns}/docnames/${category}?generated=${generated ? '1' : '0'}&filter=${filter}`
98+
);
99+
}
100+
101+
actionIndex(docs: string[]): Promise<any> {
102+
return this.request('POST', `v2/${this.ns}/action/index`, docs);
103+
}
104+
}

extension.ts

Lines changed: 69 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,62 @@
1-
import vscode = require("vscode");
1+
import vscode = require('vscode');
22
const { workspace, window } = vscode;
3-
import http = require("http");
3+
import http = require('http');
44

5-
const API = require("cos-api4node");
6-
const LOG = require("./log");
7-
const panel = require("./status-bar-panel");
8-
const CmdExport = require("./commands/export");
9-
const { CurrentDoc } = require("./commands/currentdoc");
10-
const IsApiError = require("./is-api-error");
5+
const API = require('cos-api4node');
6+
const LOG = require('./log');
7+
const panel = require('./status-bar-panel');
8+
const CmdExport = require('./commands/export');
9+
const { CurrentDoc } = require('./commands/currentdoc');
10+
const IsApiError = require('./is-api-error');
1111

12-
import { COSExplorerProvider } from "./explorer/explorer";
12+
import { AtelierAPI } from './api';
13+
14+
import { COSExplorerProvider } from './explorer/explorer';
1315
export var cosExplorerProvider: COSExplorerProvider;
1416

1517
export async function activate(context: vscode.ExtensionContext): Promise<void> {
16-
const languages = require(context.asAbsolutePath("./package.json"))["contributes"]["languages"].map(lang => lang.id);
18+
const languages = require(context.asAbsolutePath('./package.json'))['contributes']['languages'].map(lang => lang.id);
1719

1820
const log = LOG(window);
1921

2022
cosExplorerProvider = new COSExplorerProvider();
21-
vscode.window.registerTreeDataProvider("cosExplorer", cosExplorerProvider);
23+
vscode.window.registerTreeDataProvider('cosExplorer', cosExplorerProvider);
2224

2325
const Config = workspace => {
2426
let options = null;
2527
const init = () => {
26-
options = workspace.getConfiguration("cos");
28+
options = workspace.getConfiguration('cos');
2729
};
2830
init();
2931

3032
return {
3133
init,
3234
get: option => options.get(option),
3335
conn: () => {
34-
const _conn = options.get("conn");
35-
_conn.toString = () => JSON.stringify(Object.assign({}, _conn, { password: "***" }), null, 4);
36+
const _conn = options.get('conn');
37+
_conn.toString = () => JSON.stringify(Object.assign({}, _conn, { password: '***' }), null, 4);
3638
return _conn;
3739
},
3840
export: () => {
3941
const root = workspace.rootPath;
40-
return Object.assign({}, options.get("export"), { root });
42+
return Object.assign({}, options.get('export'), { root });
4143
}
4244
};
4345
};
4446

4547
let api;
48+
let atelierApi: AtelierAPI;
4649
const Connect = conn => {
4750
api = API(conn);
51+
atelierApi = new AtelierAPI(conn.host, conn.port, conn.username, conn.password, conn.ns, conn.https);
52+
atelierApi
53+
.serverInfo()
54+
.then(info => {})
55+
.catch(err => {});
4856
api.headServer(err => {
4957
const conn = config.conn();
50-
if (err) return log("Connection FAILED: " + conn, err);
51-
log("Connected " + conn);
58+
if (err) return log('Connection FAILED: ' + conn, err);
59+
log('Connected ' + conn);
5260
panel.set(conn);
5361
});
5462
cosExplorerProvider.setAPI(api, conn.ns);
@@ -77,7 +85,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
7785
); //reload config on event
7886

7987
workspace.onDidSaveTextDocument(file => {
80-
if (!config.get("autoCompile")) {
88+
if (!config.get('autoCompile')) {
8189
return;
8290
}
8391
if (languages.includes(file.languageId)) {
@@ -89,18 +97,18 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
8997

9098
const Save = ({ name, log, fileName }) => (err, data) => {
9199
// IsApiError, ExportDoc - global
92-
const isGetDocError = IsApiError(name, "getDoc", log, window);
100+
const isGetDocError = IsApiError(name, 'getDoc', log, window);
93101
if (isGetDocError({ err, data })) return;
94102

95-
const completed = () => log("Completed.");
103+
const completed = () => log('Completed.');
96104
const exportDoc = ExportDoc({ name, cat: data.result.cat, fileName }, completed);
97105

98106
exportDoc({ err, data });
99107
};
100108

101109
const Export = ({ api, name, log, fileName }) => (err, data) => {
102110
// IsApiError, Save - from upper scope
103-
const isCompileError = IsApiError(name, "compile", log, window);
111+
const isCompileError = IsApiError(name, 'compile', log, window);
104112
if (isCompileError({ err, data })) return;
105113
// after compilation API returns updated storage definition
106114
// but, currently, we don`t have any AST implementation
@@ -113,7 +121,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
113121

114122
const Compile = ({ api, name, log, fileName }) => (err, data) => {
115123
// IsApiError, Export
116-
const isImportError = IsApiError(name, "import", log, window);
124+
const isImportError = IsApiError(name, 'import', log, window);
117125
if (isImportError({ err, data })) return;
118126

119127
const exportCurrent = Export({ api, name, log, fileName });
@@ -134,22 +142,51 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
134142
api.putDoc(name, { enc: false, content }, { ignoreConflict: true }, compile);
135143
};
136144

145+
const viewOther = () => {
146+
const { name, error } = currentDoc();
147+
if (error) return log(error);
148+
149+
const getOthers = info => {
150+
return info.result.content[0].others;
151+
};
152+
153+
atelierApi
154+
.actionIndex([name])
155+
.then(info => {
156+
const listOthers = getOthers(info) || [];
157+
if (!listOthers.length) {
158+
return;
159+
}
160+
if (listOthers.length === 1) {
161+
window.showTextDocument(vscode.Uri.parse(encodeURI(`cos:///${listOthers[0]}`)));
162+
} else {
163+
window.showQuickPick(listOthers).then(item => {
164+
window.showTextDocument(vscode.Uri.parse(encodeURI(`cos:///${item}`)));
165+
});
166+
}
167+
})
168+
.catch(err => {
169+
log('error' + err);
170+
});
171+
};
172+
137173
context.subscriptions.push(
138-
vscode.commands.registerCommand("cos.compile", importCompileExport),
139-
vscode.commands.registerCommand("cos.export", exportAll),
140-
vscode.commands.registerCommand("vscode-cos.explorer.refresh", () => cosExplorerProvider.refresh()),
141-
vscode.commands.registerCommand("vscode-cos.explorer.openClass", vscode.window.showTextDocument),
142-
vscode.commands.registerCommand("vscode-cos.explorer.openRoutine", vscode.window.showTextDocument),
143-
vscode.commands.registerCommand("vscode-cos.explorer.showSystem", () => {
144-
vscode.commands.executeCommand("setContext", "vscode-cos.explorer.showSystem", true);
174+
vscode.commands.registerCommand('cos.compile', importCompileExport),
175+
vscode.commands.registerCommand('cos.export', exportAll),
176+
vscode.commands.registerCommand('vscode-cos.viewother', viewOther),
177+
vscode.commands.registerCommand('vscode-cos.explorer.refresh', () => cosExplorerProvider.refresh()),
178+
vscode.commands.registerCommand('vscode-cos.explorer.openClass', vscode.window.showTextDocument),
179+
vscode.commands.registerCommand('vscode-cos.explorer.openRoutine', vscode.window.showTextDocument),
180+
vscode.commands.registerCommand('vscode-cos.explorer.showSystem', () => {
181+
vscode.commands.executeCommand('setContext', 'vscode-cos.explorer.showSystem', true);
145182
cosExplorerProvider.showSystem = true;
146183
}),
147-
vscode.commands.registerCommand("vscode-cos.explorer.hideSystem", () => {
148-
vscode.commands.executeCommand("setContext", "vscode-cos.explorer.showSystem", false);
184+
vscode.commands.registerCommand('vscode-cos.explorer.hideSystem', () => {
185+
vscode.commands.executeCommand('setContext', 'vscode-cos.explorer.showSystem', false);
149186
cosExplorerProvider.showSystem = false;
150187
}),
151188

152-
vscode.workspace.registerTextDocumentContentProvider("cos", cosExplorerProvider)
189+
vscode.workspace.registerTextDocumentContentProvider('cos', cosExplorerProvider)
153190
);
154191
}
155192

package.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@
5656
],
5757
"extensions": [
5858
".cls",
59-
".mac"
59+
".mac",
60+
".int"
6061
],
6162
"configuration": "./language-configuration.json"
6263
},
@@ -118,13 +119,24 @@
118119
{
119120
"command": "vscode-cos.explorer.openRoutine",
120121
"title": "Open routine"
122+
},
123+
{
124+
"category": "COS",
125+
"command": "vscode-cos.viewother",
126+
"title": "View other"
121127
}
122128
],
123129
"keybindings": [
124130
{
125131
"command": "cos.compile",
126132
"key": "Ctrl+F7",
127133
"mac": "Cmd+F7"
134+
},
135+
{
136+
"command": "vscode-cos.viewother",
137+
"key": "Ctrl+Shift+V",
138+
"mac": "Cmd+Shift+V",
139+
"when": "editorLangId == 'cacheobjectscript'"
128140
}
129141
],
130142
"configuration": {

0 commit comments

Comments
 (0)