@@ -16,56 +16,86 @@ import {
16
16
Uri ,
17
17
ViewColumn ,
18
18
window ,
19
+ workspace ,
19
20
} from 'vscode' ;
20
21
import { ProvideCompletionItemsSignature , ProvideHoverSignature } from 'vscode-languageclient' ;
21
22
22
23
export namespace DocsBrowser {
23
24
'use strict' ;
24
25
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 ) ;
41
+
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
+ } ) ;
49
+
50
+ const encoded = encodeURIComponent ( JSON . stringify ( { hackageUri : hackageUri , inWebView : true } ) ) ;
51
+ const hackageCmd = 'command:haskell.openDocumentationOnHackage?' + encoded ;
52
+
53
+ const bytes = await workspace . fs . readFile ( Uri . parse ( localPath ) ) ;
54
+
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
+
25
74
// registers the browser in VSCode infrastructure
26
75
export function registerDocsBrowser ( ) : Disposable {
27
- return commands . registerCommand (
28
- 'haskell.showDocumentation' ,
29
- async ( { title, localPath, hackageUri } : { title : string ; localPath : string ; hackageUri : string } ) => {
30
- const arr = localPath . match ( / ( [ ^ \/ ] + ) \. [ ^ . ] + $ / ) ;
31
- const ttl = arr !== null && arr . length === 2 ? arr [ 1 ] . replace ( / - / gi, '.' ) : title ;
32
- const documentationDirectory = dirname ( localPath ) ;
33
- let panel ;
34
- try {
35
- // Make sure to use Uri.parse here, as path will already have 'file:///' in it
36
- panel = window . createWebviewPanel ( 'haskell.showDocumentationPanel' , ttl , ViewColumn . Beside , {
37
- localResourceRoots : [ Uri . parse ( documentationDirectory ) ] ,
38
- enableFindWidget : true ,
39
- enableCommandUris : true ,
40
- } ) ;
41
- const uri = panel . webview . asWebviewUri ( Uri . parse ( localPath ) ) ;
42
-
43
- const encoded = encodeURIComponent ( JSON . stringify ( { hackageUri } ) ) ;
44
- const hackageCmd = 'command:haskell.openDocumentationOnHackage?' + encoded ;
76
+ return commands . registerCommand ( 'haskell.showDocumentation' , showDocumentation ) ;
77
+ }
45
78
46
- panel . webview . html = `<div><a href="${ hackageCmd } ">Open on Hackage</a></div>
47
- <div><iframe src="${ uri } " frameBorder = "0" style = "background: white; width: 100%; height: 100%; position:absolute; left: 0; right: 0; bottom: 0; top: 30px;"/></div>` ;
48
- } catch ( e ) {
49
- await window . showErrorMessage ( e ) ;
50
- }
51
- return panel ;
79
+ async function openDocumentationOnHackage ( {
80
+ hackageUri,
81
+ inWebView = false ,
82
+ } : {
83
+ hackageUri : string ;
84
+ inWebView : boolean ;
85
+ } ) {
86
+ try {
87
+ // open on Hackage and close the original webview in VS code
88
+ await env . openExternal ( Uri . parse ( hackageUri ) ) ;
89
+ if ( inWebView ) {
90
+ await commands . executeCommand ( 'workbench.action.closeActiveEditor' ) ;
52
91
}
53
- ) ;
92
+ } catch ( e ) {
93
+ await window . showErrorMessage ( e ) ;
94
+ }
54
95
}
55
96
56
97
export function registerDocsOpenOnHackage ( ) : Disposable {
57
- return commands . registerCommand (
58
- 'haskell.openDocumentationOnHackage' ,
59
- async ( { hackageUri } : { hackageUri : string } ) => {
60
- try {
61
- // open on Hackage and close the original webview in VS code
62
- await env . openExternal ( Uri . parse ( hackageUri ) ) ;
63
- await commands . executeCommand ( 'workbench.action.closeActiveEditor' ) ;
64
- } catch ( e ) {
65
- await window . showErrorMessage ( e ) ;
66
- }
67
- }
68
- ) ;
98
+ return commands . registerCommand ( 'haskell.openDocumentationOnHackage' , openDocumentationOnHackage ) ;
69
99
}
70
100
71
101
export function hoverLinksMiddlewareHook (
@@ -109,17 +139,39 @@ export namespace DocsBrowser {
109
139
}
110
140
111
141
function processLink ( ms : MarkdownString | MarkedString ) : string | MarkdownString {
142
+ const openDocsInHackage = workspace . getConfiguration ( 'haskell' ) . get ( 'openDocumentationInHackage' ) ;
143
+ const openSourceInHackage = workspace . getConfiguration ( 'haskell' ) . get ( 'openSourceInHackage' ) ;
112
144
function transform ( s : string ) : string {
113
145
return s . replace (
114
- / \[ ( .+ ) \] \( ( f i l e : .+ \/ d o c \/ (?: .* h t m l \/ l i b r a r i e s \/ ) ? ( [ ^ \/ ] + ) \/ ( s r c \/ ) ? ( .+ \. h t m l # ? .* ) ) \) / gi,
115
- ( all , title , localPath , packageName , maybeSrcDir , fileAndAnchor ) => {
116
- if ( ! maybeSrcDir ) {
117
- maybeSrcDir = '' ;
146
+ / \[ ( .+ ) \] \( ( f i l e : .+ \/ d o c \/ (?: .* h t m l \/ l i b r a r i e s \/ ) ? ( [ ^ \/ ] + ) \/ (?: .* \/ ) ? ( .+ \. h t m l # ? .* ) ) \) / gi,
147
+ ( all , title , localPath , packageName , fileAndAnchor ) => {
148
+ let hackageUri : string ;
149
+ if ( title == 'Documentation' ) {
150
+ hackageUri = `https://hackage.haskell.org/package/${ packageName } /docs/${ fileAndAnchor } ` ;
151
+ const encoded = encodeURIComponent ( JSON . stringify ( { title, localPath, hackageUri } ) ) ;
152
+ let cmd : string ;
153
+ if ( openDocsInHackage ) {
154
+ cmd = 'command:haskell.openDocumentationOnHackage?' + encoded ;
155
+ } else {
156
+ cmd = 'command:haskell.showDocumentation?' + encoded ;
157
+ }
158
+ return `[${ title } ](${ cmd } )` ;
159
+ } else if ( title == 'Source' ) {
160
+ hackageUri = `https://hackage.haskell.org/package/${ packageName } /docs/src/${ fileAndAnchor . replace (
161
+ / - / gi,
162
+ '.'
163
+ ) } `;
164
+ const encoded = encodeURIComponent ( JSON . stringify ( { title, localPath, hackageUri } ) ) ;
165
+ let cmd : string ;
166
+ if ( openSourceInHackage ) {
167
+ cmd = 'command:haskell.openDocumentationOnHackage?' + encoded ;
168
+ } else {
169
+ cmd = 'command:haskell.showDocumentation?' + encoded ;
170
+ }
171
+ return `[${ title } ](${ cmd } )` ;
172
+ } else {
173
+ return s ;
118
174
}
119
- const hackageUri = `https://hackage.haskell.org/package/${ packageName } /docs/${ maybeSrcDir } ${ fileAndAnchor } ` ;
120
- const encoded = encodeURIComponent ( JSON . stringify ( { title, localPath, hackageUri } ) ) ;
121
- const cmd = 'command:haskell.showDocumentation?' + encoded ;
122
- return `[${ title } ](${ cmd } )` ;
123
175
}
124
176
) ;
125
177
}
0 commit comments