@@ -46,6 +46,7 @@ import {
4646 codeWithoutOptionsFromBlock ,
4747 executeInteractive ,
4848 executeSelectionInteractive ,
49+ executionSelectionAtPositionInteractive ,
4950} from "./executors" ;
5051import { ExtensionHost } from "../../host" ;
5152import { tryAcquirePositronApi } from "@posit-dev/positron" ;
@@ -265,15 +266,7 @@ class RunPreviousCellCommand extends RunCommand implements Command {
265266
266267// More permissive type than `Position` so its easier to construct via a literal
267268type LineAndCharPos = { line : number , character : number ; } ;
268- // More permissive type than `Range` so its easier to construct via a literal
269- type LineAndCharRange = { start : LineAndCharPos , end : LineAndCharPos ; } ;
270-
271- function extractRangeFromCode ( code : string , range : LineAndCharRange ) : string {
272- const extractedRange = lines ( code ) . slice ( range . start . line , range . end . line + 1 ) ;
273- extractedRange [ 0 ] = extractedRange [ 0 ] . slice ( range . start . character ) ;
274- extractedRange [ extractedRange . length - 1 ] = extractedRange [ extractedRange . length - 1 ] . slice ( 0 , range . end . character ) ;
275- return extractedRange . join ( '\n' ) ;
276- }
269+
277270
278271// Run the code at the cursor
279272class RunCurrentCommand extends RunCommand implements Command {
@@ -355,14 +348,6 @@ class RunCurrentCommand extends RunCommand implements Command {
355348 const selection = context . selectedText ;
356349 const activeBlock = context . blocks . find ( block => block . active ) ;
357350
358- const exec = async ( action : CodeViewSelectionAction , selection : string ) => {
359- const executor = await this . cellExecutorForLanguage ( context . activeLanguage , editor . document , this . engine_ ) ;
360- if ( executor ) {
361- await executeInteractive ( executor , [ selection ] , editor . document ) ;
362- await editor . setBlockSelection ( context , action ) ;
363- }
364- } ;
365-
366351 // if in Positron
367352 if ( isPositron ) {
368353 if ( activeBlock && selection . length <= 0 ) {
@@ -376,43 +361,23 @@ class RunCurrentCommand extends RunCommand implements Command {
376361 new Position ( p . line + injectedLines , p . character ) ;
377362 const positionOutOfVdoc = ( p : LineAndCharPos ) =>
378363 new Position ( p . line - injectedLines , p . character ) ;
379- const rangeOutOfVdoc = ( r : Range ) : LineAndCharRange => ( {
380- start : positionOutOfVdoc ( r . start ) ,
381- end : positionOutOfVdoc ( r . end )
382- } ) ;
383- const getStatementRange = async ( pos : LineAndCharPos ) => {
384- const result = await withVirtualDocUri ( vdoc , parentUri , "statementRange" , async ( uri ) => {
385- return await commands . executeCommand < StatementRange > (
386- "vscode.executeStatementRangeProvider" ,
364+
365+ const executor = await this . cellExecutorForLanguage ( context . activeLanguage , editor . document , this . engine_ ) ;
366+ if ( executor ) {
367+ const nextStatementPos = await withVirtualDocUri (
368+ vdoc ,
369+ parentUri ,
370+ "executeSelectionAtPositionInteractive" ,
371+ ( uri ) => executionSelectionAtPositionInteractive (
372+ executor ,
387373 uri ,
388- positionIntoVdoc ( pos )
389- ) ;
390- } ) ;
391- return rangeOutOfVdoc ( result . range ) ;
392- } ;
393-
394- const range = await getStatementRange ( context . selection . start ) ;
395- const code = extractRangeFromCode ( activeBlock . code , range ) ;
396-
397- // BEGIN ref: https://github.com/posit-dev/positron/blob/main/src/vs/workbench/contrib/positronConsole/browser/positronConsoleActions.ts#L428
398- // strategy from Positron using `StatementRangeProvider` to find range of next statement
399- // and move cursor based on that.
400- if ( range . end . line + 1 <= codeLines . length ) {
401- // get range of statement at line after current statement)
402- const nextRange = await getStatementRange ( new Position ( range . end . line + 1 , 1 ) ) ;
403-
404- if ( nextRange . start . line > range . end . line ) {
405- exec ( nextRange . start , code ) ;
406- // the next statement range may start before & end after the current statement if e.g. inside a function:
407- } else if ( nextRange . end . line > range . end . line ) {
408- exec ( nextRange . end , code ) ;
409- } else {
410- exec ( "nextline" , code ) ;
374+ positionIntoVdoc ( context . selection . start )
375+ )
376+ ) ;
377+ if ( nextStatementPos !== undefined ) {
378+ await editor . setBlockSelection ( context , positionOutOfVdoc ( nextStatementPos ) ) ;
411379 }
412- } else {
413- exec ( "nextline" , code ) ;
414380 }
415- // END ref.
416381 }
417382 }
418383 // if not in Positron
@@ -427,11 +392,18 @@ class RunCurrentCommand extends RunCommand implements Command {
427392 }
428393 }
429394 } else {
430- if ( selection . length > 0 ) {
431- exec ( "nextline" , selection ) ;
432- } else if ( activeBlock ) { // if the selection is empty take the whole line as the selection
433- exec ( "nextline" , lines ( activeBlock . code ) [ context . selection . start . line ] ) ;
395+ const executor = await this . cellExecutorForLanguage ( context . activeLanguage , editor . document , this . engine_ ) ;
396+ if ( executor ) {
397+ if ( selection . length > 0 ) {
398+ await executeInteractive ( executor , [ selection ] , editor . document ) ;
399+ await editor . setBlockSelection ( context , "nextline" ) ;
400+ } else if ( activeBlock ) { // if the selection is empty take the whole line as the selection
401+ await executeInteractive ( executor , [ lines ( activeBlock . code ) [ context . selection . start . line ] ] , editor . document ) ;
402+ await editor . setBlockSelection ( context , "nextline" ) ;
403+ }
404+
434405 }
406+
435407 }
436408 }
437409 }
0 commit comments