-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathextension.ts
220 lines (197 loc) · 8.4 KB
/
extension.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
'use strict';
import * as path from 'path';
import { workspace, ExtensionContext, Hover, MarkdownString, ProviderResult } from 'vscode';
import * as vscode from 'vscode';
import * as solargraph from 'solargraph-utils';
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, Middleware, RequestType, MessageTransports, createClientSocketTransport, Disposable } from 'vscode-languageclient';
import SolargraphDocumentProvider from './SolargraphDocumentProvider';
import { makeLanguageClient } from './language-client';
let socketProvider: solargraph.SocketProvider;
export function activate(context: ExtensionContext) {
let applyConfiguration = function(config:solargraph.Configuration) {
let vsconfig = vscode.workspace.getConfiguration('solargraph');
config.commandPath = vsconfig.commandPath || 'solargraph';
config.useBundler = vsconfig.useBundler || false;
config.bundlerPath = vsconfig.bundlerPath || 'bundle';
config.viewsPath = vscode.extensions.getExtension('castwide.solargraph').extensionPath + '/views';
config.withSnippets = vsconfig.withSnippets || false;
config.workspace = vscode.workspace.rootPath || null;
}
let solargraphConfiguration = new solargraph.Configuration();
applyConfiguration(solargraphConfiguration);
socketProvider = new solargraph.SocketProvider(solargraphConfiguration);
let solargraphDocumentProvider = new SolargraphDocumentProvider();
let languageClient: LanguageClient;
let disposableClient: Disposable;
var startLanguageServer = function() {
socketProvider.start().then(() => {
languageClient = makeLanguageClient(socketProvider);
solargraphDocumentProvider.setLanguageClient(languageClient);
disposableClient = languageClient.start();
context.subscriptions.push(disposableClient);
}).catch((err) => {
console.log('Failed to start language server: ' + err);
});
}
var checkGemVersion = function() {
console.log('Checking gem version');
solargraph.verifyGemIsCurrent(solargraphConfiguration).then((result) => {
if (result) {
console.log('Solargraph gem version is current');
} else {
notifyGemUpdate();
}
}).catch(() => {
console.log('An error occurred checking the Solargraph gem version.');
});
}
// https://css-tricks.com/snippets/javascript/get-url-variables/
var getQueryVariable = function (query, variable) {
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) { return pair[1]; }
}
}
var restartLanguageServer = function (): Promise<void> {
return new Promise((resolve) => {
if (languageClient) {
languageClient.stop().then(() => {
disposableClient.dispose();
socketProvider.restart().then(() => {
languageClient = makeLanguageClient(socketProvider);
solargraphDocumentProvider.setLanguageClient(languageClient);
disposableClient = languageClient.start();
context.subscriptions.push(disposableClient);
resolve();
});
});
} else {
startLanguageServer();
resolve();
}
});
}
function notifyGemUpdate() {
if (vscode.workspace.getConfiguration('solargraph').useBundler && vscode.workspace.rootPath) {
vscode.window.showInformationMessage('A new version of the Solargraph gem is available. Update your Gemfile to install it.');
} else {
vscode.window.showInformationMessage('A new version of the Solargraph gem is available. Run `gem update solargraph` to install it.', 'Update Now').then((item) => {
if (item == 'Update Now') {
solargraph.updateGem(solargraphConfiguration).then(() => {
restartLanguageServer().then(() => {
vscode.window.showInformationMessage('Successfully updated the Solargraph gem.');
});
}).catch(() => {
vscode.window.showErrorMessage('Failed to update the Solargraph gem.');
});
}
});
}
}
// Open command (used internally for browsing documentation pages)
var disposableOpen = vscode.commands.registerCommand('solargraph._openDocument', (uriString: string) => {
var uri = vscode.Uri.parse(uriString);
var label = (uri.path == '/search' ? 'Search for ' : '') + getQueryVariable(uri.query, "query");
vscode.commands.executeCommand('vscode.previewHtml', uri, vscode.ViewColumn.Two, label);
});
context.subscriptions.push(disposableOpen);
// Open URL command (used internally for browsing documentation pages)
var disposableOpenUrl = vscode.commands.registerCommand('solargraph._openDocumentUrl', (uriString: string) => {
var uri = vscode.Uri.parse(uriString);
var label = (uri.path == '/search' ? 'Search for ' : '') + getQueryVariable(uri.query, "query");
vscode.commands.executeCommand('vscode.previewHtml', uri, vscode.ViewColumn.Two, label);
});
context.subscriptions.push(disposableOpenUrl);
// Restart command
var disposableRestart = vscode.commands.registerCommand('solargraph.restart', () => {
restartLanguageServer().then(() => {
vscode.window.showInformationMessage('Solargraph server restarted.');
});
});
context.subscriptions.push(disposableRestart);
// Search command
var disposableSearch = vscode.commands.registerCommand('solargraph.search', () => {
vscode.window.showInputBox({prompt: 'Search Ruby documentation:'}).then(val => {
if (val) {
var uri = 'solargraph:/search?query=' + encodeURIComponent(val);
vscode.commands.executeCommand('solargraph._openDocument', uri);
}
});
});
context.subscriptions.push(disposableSearch);
// Check gem version command
var disposableCheckGemVersion = vscode.commands.registerCommand('solargraph.checkGemVersion', () => {
solargraph.verifyGemIsCurrent(solargraphConfiguration).then((result) => {
if (result) {
vscode.window.showInformationMessage('Solargraph gem is up to date.');
} else {
notifyGemUpdate();
}
}).catch(() => {
console.log('An error occurred checking the Solargraph gem version.');
});
});
context.subscriptions.push(disposableSearch);
// Build gem documentation command
var disposableBuildGemDocs = vscode.commands.registerCommand('solargraph.buildGemDocs', () => {
var disposableStatus = vscode.window.setStatusBarMessage('Building new YARD documentation...')
var cmd = solargraph.commands.yardCommand(['gems'], solargraphConfiguration);
cmd.on('exit', (code) => {
disposableStatus.dispose();
if (code == 0) {
vscode.window.setStatusBarMessage('YARD documentation complete.', 3000);
} else {
vscode.window.setStatusBarMessage('An error occurred during build.', 3000);
}
});
cmd.on('error', (err) => {
disposableStatus.dispose();
vscode.window.setStatusBarMessage('Unable to build documentation.', 3000);
});
});
context.subscriptions.push(disposableBuildGemDocs);
// Rebuild gems documentation command
var disposableRebuildAllGemDocs = vscode.commands.registerCommand('solargraph.rebuildAllGemDocs', () => {
var disposableStatus = vscode.window.setStatusBarMessage('Rebuilding all YARD documentation...')
var cmd = solargraph.commands.yardCommand(['gems', '--rebuild'], solargraphConfiguration);
cmd.on('exit', (code) => {
disposableStatus.dispose();
if (code == 0) {
vscode.window.setStatusBarMessage('YARD documentation rebuild complete.', 3000);
} else {
vscode.window.setStatusBarMessage('An error occurred during rebuild.', 3000);
}
});
cmd.on('error', (err) => {
disposableStatus.dispose();
vscode.window.setStatusBarMessage('Unable to rebuild documentation.', 3000);
});
});
context.subscriptions.push(disposableRebuildAllGemDocs);
solargraph.verifyGemIsInstalled(solargraphConfiguration).then((result) => {
if (result) {
console.log('The Solargraph gem is installed and working.');
if (vscode.workspace.getConfiguration('solargraph').checkGemVersion) {
checkGemVersion();
}
startLanguageServer();
} else {
console.log('The Solargraph gem is not available.');
vscode.window.showErrorMessage('Solargraph gem not found. Run `gem install solargraph` or update your Gemfile.', 'Install Now').then((item) => {
if (item == 'Install Now') {
solargraph.installGem(solargraphConfiguration).then(() => {
vscode.window.showInformationMessage('Successfully installed the Solargraph gem.')
startLanguageServer();
}).catch(() => {
vscode.window.showErrorMessage('Failed to install the Solargraph gem.')
});
}
});
}
});
vscode.workspace.registerTextDocumentContentProvider('solargraph', solargraphDocumentProvider);
}
export function deactivate() {
socketProvider.stop();
}