@@ -18,13 +18,18 @@ use crossbeam::channel::Sender;
1818use crossbeam:: select;
1919use harp:: exec:: RFunction ;
2020use harp:: exec:: RFunctionExt ;
21+ use harp:: RObject ;
22+ use libr:: R_NilValue ;
23+ use libr:: SEXP ;
2124use log:: info;
2225use log:: trace;
2326use log:: warn;
2427use stdext:: spawn;
2528
2629use crate :: help:: message:: HelpEvent ;
30+ use crate :: help:: message:: ShowHelpUrlKind ;
2731use crate :: help:: message:: ShowHelpUrlParams ;
32+ use crate :: interface:: RMain ;
2833use crate :: r_task;
2934
3035/**
@@ -182,27 +187,37 @@ impl RHelp {
182187 /// coming through here has already been verified to look like a help URL with
183188 /// `is_help_url()`, so if we get an unexpected prefix, that's an error.
184189 fn handle_show_help_url ( & self , params : ShowHelpUrlParams ) -> anyhow:: Result < ( ) > {
185- let url = params. url ;
190+ let url = params. url . clone ( ) ;
186191
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+ }
193200
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 ) ;
197204
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+ } ;
199212
200213 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
202217 ) ;
203218
204219 let msg = HelpFrontendEvent :: ShowHelp ( ShowHelpParams {
205- content : proxy_url ,
220+ content : url ,
206221 kind : ShowHelpKind :: Url ,
207222 focus : true ,
208223 } ) ;
@@ -232,3 +247,15 @@ impl RHelp {
232247 . and_then ( |x| x. try_into ( ) )
233248 }
234249}
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