@@ -18,13 +18,18 @@ use crossbeam::channel::Sender;
18
18
use crossbeam:: select;
19
19
use harp:: exec:: RFunction ;
20
20
use harp:: exec:: RFunctionExt ;
21
+ use harp:: RObject ;
22
+ use libr:: R_NilValue ;
23
+ use libr:: SEXP ;
21
24
use log:: info;
22
25
use log:: trace;
23
26
use log:: warn;
24
27
use stdext:: spawn;
25
28
26
29
use crate :: help:: message:: HelpEvent ;
30
+ use crate :: help:: message:: ShowHelpUrlKind ;
27
31
use crate :: help:: message:: ShowHelpUrlParams ;
32
+ use crate :: interface:: RMain ;
28
33
use crate :: r_task;
29
34
30
35
/**
@@ -182,27 +187,37 @@ impl RHelp {
182
187
/// coming through here has already been verified to look like a help URL with
183
188
/// `is_help_url()`, so if we get an unexpected prefix, that's an error.
184
189
fn handle_show_help_url ( & self , params : ShowHelpUrlParams ) -> anyhow:: Result < ( ) > {
185
- let url = params. url ;
190
+ let url = params. url . clone ( ) ;
186
191
187
- if !Self :: is_help_url ( url. as_str ( ) , self . r_port ) {
188
- let prefix = Self :: help_url_prefix ( self . r_port ) ;
189
- return Err ( anyhow ! (
190
- "Help URL '{url}' doesn't have expected prefix '{prefix}'."
191
- ) ) ;
192
- }
192
+ let url = match params. kind {
193
+ ShowHelpUrlKind :: HelpProxy => {
194
+ if !Self :: is_help_url ( url. as_str ( ) , self . r_port ) {
195
+ let prefix = Self :: help_url_prefix ( self . r_port ) ;
196
+ return Err ( anyhow ! (
197
+ "Help URL '{url}' doesn't have expected prefix '{prefix}'."
198
+ ) ) ;
199
+ }
193
200
194
- // Re-direct the help event to our help proxy server.
195
- let r_prefix = Self :: help_url_prefix ( self . r_port ) ;
196
- let proxy_prefix = Self :: help_url_prefix ( self . proxy_port ) ;
201
+ // Re-direct the help event to our help proxy server.
202
+ let r_prefix = Self :: help_url_prefix ( self . r_port ) ;
203
+ let proxy_prefix = Self :: help_url_prefix ( self . proxy_port ) ;
197
204
198
- let proxy_url = url. replace ( r_prefix. as_str ( ) , proxy_prefix. as_str ( ) ) ;
205
+ url. replace ( r_prefix. as_str ( ) , proxy_prefix. as_str ( ) )
206
+ } ,
207
+ ShowHelpUrlKind :: External => {
208
+ // The URL is not a help URL; just use it as-is.
209
+ url
210
+ } ,
211
+ } ;
199
212
200
213
log:: trace!(
201
- "Sending frontend event `ShowHelp` with R url '{url}' and proxy url '{proxy_url}'"
214
+ "Sending frontend event `ShowHelp` with R url '{}' and proxy url '{}'" ,
215
+ params. url,
216
+ url
202
217
) ;
203
218
204
219
let msg = HelpFrontendEvent :: ShowHelp ( ShowHelpParams {
205
- content : proxy_url ,
220
+ content : url ,
206
221
kind : ShowHelpKind :: Url ,
207
222
focus : true ,
208
223
} ) ;
@@ -232,3 +247,15 @@ impl RHelp {
232
247
. and_then ( |x| x. try_into ( ) )
233
248
}
234
249
}
250
+
251
+ #[ harp:: register]
252
+ pub unsafe extern "C-unwind" fn ps_help_browse_external_url (
253
+ url : SEXP ,
254
+ ) -> Result < SEXP , anyhow:: Error > {
255
+ RMain :: get ( ) . send_help_event ( HelpEvent :: ShowHelpUrl ( ShowHelpUrlParams {
256
+ url : RObject :: view ( url) . to :: < String > ( ) ?,
257
+ kind : ShowHelpUrlKind :: External ,
258
+ } ) ) ?;
259
+
260
+ Ok ( R_NilValue )
261
+ }
0 commit comments