@@ -49,6 +49,10 @@ import { ExtensionHost } from "../../host";
4949import { hasHooks } from "../../host/hooks" ;
5050import { isKnitrDocument } from "../../host/executors" ;
5151import { commands } from "vscode" ;
52+ import { virtualDocForCode , withVirtualDocUri } from "../../vdoc/vdoc" ;
53+ import { embeddedLanguage } from "../../vdoc/languages" ;
54+ import { Uri } from "vscode" ;
55+ import { StatementRange } from "positron" ;
5256
5357export function cellCommands ( host : ExtensionHost , engine : MarkdownEngine ) : Command [ ] {
5458 return [
@@ -345,17 +349,40 @@ class RunCurrentCommand extends RunCommand implements Command {
345349 await activateIfRequired ( editor ) ;
346350 }
347351 }
348-
349352 } else {
350- // if the selection is empty take the whole line, otherwise take the selected text exactly
351353 let action : CodeViewSelectionAction | undefined ;
352- if ( selection . length <= 0 ) {
353- if ( activeBlock ) {
354- selection = lines ( activeBlock . code ) [ context . selection . start . line ] ;
354+
355+ // if the selection is empty and we are in Positron:
356+ // try to get the statement's range and use that as the selection
357+ if ( selection . length <= 0 && activeBlock && hasHooks ( ) ) {
358+ const language = embeddedLanguage ( activeBlock . language ) ;
359+ const vdoc = virtualDocForCode ( lines ( activeBlock . code ) , language ! ) ;
360+ const parentUri = Uri . file ( editor . document . fileName ) ;
361+ if ( vdoc ) {
362+ const result = await withVirtualDocUri ( vdoc , parentUri , "statementRange" , async ( uri ) => {
363+ return await commands . executeCommand < StatementRange > (
364+ "vscode.executeStatementRangeProvider" ,
365+ uri ,
366+ context . selection . start
367+ ) ;
368+ } ) ;
369+ const { range : { start, end } } = result
370+ const slicedLines = lines ( activeBlock . code ) . slice ( start . line , end . line + 1 )
371+ slicedLines [ 0 ] = slicedLines [ 0 ] . slice ( start . character )
372+ slicedLines [ slicedLines . length - 1 ] = slicedLines [ slicedLines . length - 1 ] . slice ( 0 , end . character )
373+
374+ selection = slicedLines . join ( '\n' )
355375 action = "nextline" ;
356376 }
357377 }
358378
379+ // if the selection is still empty:
380+ // take the whole line as the selection
381+ if ( selection . length <= 0 && activeBlock ) {
382+ selection = lines ( activeBlock . code ) [ context . selection . start . line ] ;
383+ action = "nextline" ;
384+ }
385+
359386 // run code
360387 const executor = await this . cellExecutorForLanguage ( context . activeLanguage , editor . document , this . engine_ ) ;
361388 if ( executor ) {
0 commit comments