@@ -51,6 +51,10 @@ import { ExtensionHost } from "../../host";
5151import { hasHooks } from "../../host/hooks" ;
5252import { isKnitrDocument } from "../../host/executors" ;
5353import { commands } from "vscode" ;
54+ import { virtualDocForCode , withVirtualDocUri } from "../../vdoc/vdoc" ;
55+ import { embeddedLanguage } from "../../vdoc/languages" ;
56+ import { Uri } from "vscode" ;
57+ import { StatementRange } from "positron" ;
5458
5559export function cellCommands ( host : ExtensionHost , engine : MarkdownEngine ) : Command [ ] {
5660 return [
@@ -348,17 +352,40 @@ class RunCurrentCommand extends RunCommand implements Command {
348352 await activateIfRequired ( editor ) ;
349353 }
350354 }
351-
352355 } else {
353- // if the selection is empty take the whole line, otherwise take the selected text exactly
354356 let action : CodeViewSelectionAction | undefined ;
355- if ( selection . length <= 0 ) {
356- if ( activeBlock ) {
357- selection = lines ( activeBlock . code ) [ context . selection . start . line ] ;
357+
358+ // if the selection is empty and we are in Positron:
359+ // try to get the statement's range and use that as the selection
360+ if ( selection . length <= 0 && activeBlock && hasHooks ( ) ) {
361+ const language = embeddedLanguage ( activeBlock . language ) ;
362+ const vdoc = virtualDocForCode ( lines ( activeBlock . code ) , language ! ) ;
363+ const parentUri = Uri . file ( editor . document . fileName ) ;
364+ if ( vdoc ) {
365+ const result = await withVirtualDocUri ( vdoc , parentUri , "statementRange" , async ( uri ) => {
366+ return await commands . executeCommand < StatementRange > (
367+ "vscode.executeStatementRangeProvider" ,
368+ uri ,
369+ context . selection . start
370+ ) ;
371+ } ) ;
372+ const { range : { start, end } } = result
373+ const slicedLines = lines ( activeBlock . code ) . slice ( start . line , end . line + 1 )
374+ slicedLines [ 0 ] = slicedLines [ 0 ] . slice ( start . character )
375+ slicedLines [ slicedLines . length - 1 ] = slicedLines [ slicedLines . length - 1 ] . slice ( 0 , end . character )
376+
377+ selection = slicedLines . join ( '\n' )
358378 action = "nextline" ;
359379 }
360380 }
361381
382+ // if the selection is still empty:
383+ // take the whole line as the selection
384+ if ( selection . length <= 0 && activeBlock ) {
385+ selection = lines ( activeBlock . code ) [ context . selection . start . line ] ;
386+ action = "nextline" ;
387+ }
388+
362389 // run code
363390 const executor = await this . cellExecutorForLanguage ( context . activeLanguage , editor . document , this . engine_ ) ;
364391 if ( executor ) {
0 commit comments