Skip to content

Commit b282def

Browse files
committed
Add openDocumentationInHackage config option.
- Refactor showDocumentation and openDocumentationOnHackage functions.
1 parent 3aede0a commit b282def

File tree

3 files changed

+77
-50
lines changed

3 files changed

+77
-50
lines changed

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@
9393
"default": "ormolu",
9494
"description": "The formatter to use when formatting a document or range. Ensure the plugin is enabled."
9595
},
96+
"haskell.openDocumentationInHackage": {
97+
"scope": "resource",
98+
"type": "boolean",
99+
"default": false,
100+
"description": "When opening 'Documentation' for external libraries, open in vscode by default. Set to true to instead open in hackage."
101+
},
96102
"haskell.trace.server": {
97103
"scope": "resource",
98104
"type": "string",

src/docsBrowser.ts

Lines changed: 69 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -23,63 +23,83 @@ import { ProvideCompletionItemsSignature, ProvideHoverSignature } from 'vscode-l
2323
export namespace DocsBrowser {
2424
'use strict';
2525

26-
// registers the browser in VSCode infrastructure
27-
export function registerDocsBrowser(): Disposable {
28-
return commands.registerCommand(
29-
'haskell.showDocumentation',
30-
async ({ title, localPath, hackageUri }: { title: string; localPath: string; hackageUri: string }) => {
31-
const arr = localPath.match(/([^\/]+)\.[^.]+$/);
32-
const ttl = arr !== null && arr.length === 2 ? arr[1].replace(/-/gi, '.') : title;
33-
const documentationDirectory = dirname(localPath);
34-
let panel;
35-
try {
36-
// Make sure to use Uri.parse here, as path will already have 'file:///' in it
37-
panel = window.createWebviewPanel('haskell.showDocumentationPanel', ttl, ViewColumn.Beside, {
38-
localResourceRoots: [Uri.parse(documentationDirectory)],
39-
enableFindWidget: true,
40-
enableCommandUris: true,
41-
enableScripts: true,
42-
});
26+
async function showDocumentation({
27+
title,
28+
localPath,
29+
hackageUri,
30+
}: {
31+
title: string;
32+
localPath: string;
33+
hackageUri: string;
34+
}) {
35+
const arr = localPath.match(/([^\/]+)\.[^.]+$/);
36+
const ttl = arr !== null && arr.length === 2 ? arr[1].replace(/-/gi, '.') : title;
37+
const documentationDirectory = dirname(localPath);
38+
let panel;
39+
try {
40+
const docUri = Uri.parse(documentationDirectory);
4341

44-
const encoded = encodeURIComponent(JSON.stringify({ hackageUri }));
45-
const hackageCmd = 'command:haskell.openDocumentationOnHackage?' + encoded;
42+
// Make sure to use Uri.parse here, as path will already have 'file:///' in it
43+
panel = window.createWebviewPanel('haskell.showDocumentationPanel', ttl, ViewColumn.Beside, {
44+
localResourceRoots: [docUri],
45+
enableFindWidget: true,
46+
enableCommandUris: true,
47+
enableScripts: true,
48+
});
4649

47-
const bytes = await workspace.fs.readFile(Uri.parse(localPath));
50+
const encoded = encodeURIComponent(JSON.stringify({ hackageUri: hackageUri, inWebView: true }));
51+
const hackageCmd = 'command:haskell.openDocumentationOnHackage?' + encoded;
4852

49-
const addBase = `
50-
<base href="${panel.webview.asWebviewUri(Uri.parse(documentationDirectory))}/">
51-
`;
53+
const bytes = await workspace.fs.readFile(Uri.parse(localPath));
5254

53-
panel.webview.html = `
54-
<html>
55-
${addBase}
56-
<body>
57-
<div><a href="${hackageCmd}">Open on Hackage</a></div>
58-
${bytes.toString()}
59-
</body>
60-
</html>
61-
`;
62-
} catch (e) {
63-
await window.showErrorMessage(e);
64-
}
65-
return panel;
55+
const addBase = `
56+
<base href="${panel.webview.asWebviewUri(Uri.parse(documentationDirectory))}/">
57+
`;
58+
59+
panel.webview.html = `
60+
<html>
61+
${addBase}
62+
<body>
63+
<div><a href="${hackageCmd}">Open on Hackage</a></div>
64+
${bytes.toString()}
65+
</body>
66+
</html>
67+
`;
68+
} catch (e) {
69+
await window.showErrorMessage(e);
70+
}
71+
return panel;
72+
}
73+
74+
// registers the browser in VSCode infrastructure
75+
export function registerDocsBrowser(alwaysOpenInHackage: boolean): Disposable {
76+
if (alwaysOpenInHackage) {
77+
return commands.registerCommand('haskell.showDocumentation', openDocumentationOnHackage);
78+
} else {
79+
return commands.registerCommand('haskell.showDocumentation', showDocumentation);
80+
}
81+
}
82+
83+
async function openDocumentationOnHackage({
84+
hackageUri,
85+
inWebView = false,
86+
}: {
87+
hackageUri: string;
88+
inWebView: boolean;
89+
}) {
90+
try {
91+
// open on Hackage and close the original webview in VS code
92+
await env.openExternal(Uri.parse(hackageUri));
93+
if (inWebView) {
94+
await commands.executeCommand('workbench.action.closeActiveEditor');
6695
}
67-
);
96+
} catch (e) {
97+
await window.showErrorMessage(e);
98+
}
6899
}
69100

70101
export function registerDocsOpenOnHackage(): Disposable {
71-
return commands.registerCommand(
72-
'haskell.openDocumentationOnHackage',
73-
async ({ hackageUri }: { hackageUri: string }) => {
74-
try {
75-
// open on Hackage and close the original webview in VS code
76-
await env.openExternal(Uri.parse(hackageUri));
77-
await commands.executeCommand('workbench.action.closeActiveEditor');
78-
} catch (e) {
79-
await window.showErrorMessage(e);
80-
}
81-
}
82-
);
102+
return commands.registerCommand('haskell.openDocumentationOnHackage', openDocumentationOnHackage);
83103
}
84104

85105
export function hoverLinksMiddlewareHook(

src/extension.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ export async function activate(context: ExtensionContext) {
9090
context.subscriptions.push(ImportIdentifier.registerCommand());
9191

9292
// Set up the documentation browser.
93-
const docsDisposable = DocsBrowser.registerDocsBrowser();
93+
const openInHackage = workspace.getConfiguration('haskell').openDocumentationInHackage;
94+
const docsDisposable = DocsBrowser.registerDocsBrowser(openInHackage);
9495
context.subscriptions.push(docsDisposable);
9596

9697
const openOnHackageDisposable = DocsBrowser.registerDocsOpenOnHackage();

0 commit comments

Comments
 (0)