@@ -11,6 +11,7 @@ import { KeyCode } from 'vs/base/common/keyCodes';
11
11
import { generateUuid } from 'vs/base/common/uuid' ;
12
12
import { DisposableStore } from 'vs/base/common/lifecycle' ;
13
13
import { HistoryNavigator2 } from 'vs/base/common/history' ;
14
+ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent' ;
14
15
import { useStateRef } from 'vs/base/browser/ui/react/useStateRef' ;
15
16
import { IEditorOptions } from 'vs/editor/common/config/editorOptions' ;
16
17
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget' ;
@@ -26,7 +27,6 @@ import { IInputHistoryEntry } from 'vs/workbench/contrib/executionHistory/common
26
27
import { SelectionClipboardContributionID } from 'vs/workbench/contrib/codeEditor/browser/selectionClipboard' ;
27
28
import { usePositronConsoleContext } from 'vs/workbench/contrib/positronConsole/browser/positronConsoleContext' ;
28
29
import { RuntimeCodeFragmentStatus } from 'vs/workbench/services/languageRuntime/common/languageRuntimeService' ;
29
- import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent' ;
30
30
31
31
// ConsoleReplLiveInputProps interface.
32
32
export interface ConsoleReplLiveInputProps {
@@ -51,6 +51,26 @@ export const ConsoleReplLiveInput = forwardRef<HTMLDivElement, ConsoleReplLiveIn
51
51
const [ , setCurrentCodeFragment , refCurrentCodeFragment ] = useStateRef < string | undefined > ( undefined ) ;
52
52
const [ , setCodeEditorWidth , refCodeEditorWidth ] = useStateRef ( props . width ) ;
53
53
54
+ /**
55
+ * Updates the code editor widget position to such that the cursor
56
+ * appers on the last line and the last column.
57
+ */
58
+ const updateCodeEditorWidgetPositionToEnd = ( ) => {
59
+ // Get the model. If it isn't null (which it won't be), set the code editor widget
60
+ // position.
61
+ const textModel = refCodeEditorWidget . current . getModel ( ) ;
62
+ if ( textModel ) {
63
+ const lineNumber = textModel . getLineCount ( ) ;
64
+ refCodeEditorWidget . current . setPosition ( {
65
+ lineNumber,
66
+ column : textModel . getLineContent ( lineNumber ) . length + 1
67
+ } ) ;
68
+
69
+ // Ensure that the code editor widget is scrolled into view.
70
+ refContainer . current ?. scrollIntoView ( { behavior : 'auto' } ) ;
71
+ }
72
+ } ;
73
+
54
74
// Memoize the key down event handler.
55
75
const keyDownHandler = useCallback ( async ( e : IKeyboardEvent ) => {
56
76
if ( e . keyCode === KeyCode . UpArrow ) {
@@ -65,8 +85,8 @@ export const ConsoleReplLiveInput = forwardRef<HTMLDivElement, ConsoleReplLiveIn
65
85
// Get the current history entry, set it as the value of the code editor widget, and move to the previous entry.
66
86
const inputHistoryEntry = refHistoryNavigator . current . current ( ) ;
67
87
refCodeEditorWidget . current . setValue ( inputHistoryEntry . input ) ;
68
- refCodeEditorWidget . current . setPosition ( { lineNumber : 1 , column : inputHistoryEntry . input . length + 1 } ) ;
69
88
refHistoryNavigator . current . previous ( ) ;
89
+ updateCodeEditorWidgetPositionToEnd ( ) ;
70
90
}
71
91
72
92
// Eat the event.
@@ -79,15 +99,17 @@ export const ConsoleReplLiveInput = forwardRef<HTMLDivElement, ConsoleReplLiveIn
79
99
if ( refHistoryNavigator . current . isAtEnd ( ) ) {
80
100
if ( refCurrentCodeFragment . current !== undefined ) {
81
101
refCodeEditorWidget . current . setValue ( refCurrentCodeFragment . current ) ;
82
- refCodeEditorWidget . current . setPosition ( { lineNumber : 1 , column : refCurrentCodeFragment . current . length + 1 } ) ;
102
+ // refCodeEditorWidget.current.setPosition({ lineNumber: 1, column: refCurrentCodeFragment.current.length + 1 });
83
103
setCurrentCodeFragment ( undefined ) ;
84
104
}
85
105
} else {
86
106
// Move to the next history entry and set it as the value of the code editor widget.
87
107
const inputHistoryEntry = refHistoryNavigator . current . next ( ) ;
88
108
refCodeEditorWidget . current . setValue ( inputHistoryEntry . input ) ;
89
- refCodeEditorWidget . current . setPosition ( { lineNumber : 1 , column : inputHistoryEntry . input . length + 1 } ) ;
109
+ // refCodeEditorWidget.current.setPosition({ lineNumber: 1, column: inputHistoryEntry.input.length + 1 });
90
110
}
111
+
112
+ updateCodeEditorWidgetPositionToEnd ( ) ;
91
113
}
92
114
93
115
// Eat the event.
@@ -133,13 +155,8 @@ export const ConsoleReplLiveInput = forwardRef<HTMLDivElement, ConsoleReplLiveIn
133
155
134
156
// If we're supposed to execute the code fragment, do it.
135
157
if ( executeCode ) {
136
- // // Execute the code.
137
- // const id = `fragment-${generateUuid()}`;
138
- // props.positronConsoleInstance.runtime.execute(
139
- // codeFragment,
140
- // id,
141
- // RuntimeCodeExecutionMode.Interactive,
142
- // RuntimeErrorBehavior.Continue);
158
+ // Execute the code fragment.
159
+ props . executeCode ( codeFragment ) ;
143
160
144
161
// If the code fragment contains more than whitespace characters, add it to the history navigator.
145
162
if ( codeFragment . trim ( ) . length ) {
@@ -157,11 +174,13 @@ export const ConsoleReplLiveInput = forwardRef<HTMLDivElement, ConsoleReplLiveIn
157
174
}
158
175
}
159
176
160
- props . executeCode ( codeFragment ) ;
161
-
162
177
// Reset the model for the next input.
163
178
refCodeEditorWidget . current . setValue ( '' ) ;
164
179
}
180
+
181
+ // Eat the event.
182
+ e . preventDefault ( ) ;
183
+ e . stopPropagation ( ) ;
165
184
}
166
185
} , [ ] ) ;
167
186
@@ -180,6 +199,24 @@ export const ConsoleReplLiveInput = forwardRef<HTMLDivElement, ConsoleReplLiveIn
180
199
setHistoryNavigator ( new HistoryNavigator2 < IInputHistoryEntry > ( inputHistoryEntries . slice ( - 1000 ) , 1000 ) ) ; // TODO@softwarenerd - get 1000 from settings.
181
200
}
182
201
202
+ // Create the resource URI.
203
+ const uri = URI . from ( {
204
+ scheme : Schemas . inMemory ,
205
+ path : `/repl-${ props . positronConsoleInstance . runtime . metadata . languageId } -${ generateUuid ( ) } `
206
+ } ) ;
207
+
208
+ // Create language selection.
209
+ const languageSelection = positronConsoleContext . languageService . createById ( props . positronConsoleInstance . runtime . metadata . languageId ) ;
210
+
211
+ // Create text model; this is the backing store for the Monaco editor that receives
212
+ // the user's input.
213
+ const textModel = positronConsoleContext . modelService . createModel (
214
+ '' , // initial value
215
+ languageSelection , // language selection
216
+ uri , // resource URI
217
+ false // this widget is not simple
218
+ ) ;
219
+
183
220
// Create the code editor widget.
184
221
const codeEditorWidget = positronConsoleContext . instantiationService . createInstance (
185
222
CodeEditorWidget ,
@@ -205,25 +242,6 @@ export const ConsoleReplLiveInput = forwardRef<HTMLDivElement, ConsoleReplLiveIn
205
242
disposableStore . add ( codeEditorWidget ) ;
206
243
setCodeEditorWidget ( codeEditorWidget ) ;
207
244
208
- // Create the resource URI.
209
- const uri = URI . from ( {
210
- scheme : Schemas . inMemory ,
211
- path : `/repl-${ props . positronConsoleInstance . runtime . metadata . languageId } -${ generateUuid ( ) } `
212
- } ) ;
213
-
214
- // Create language selection.
215
- // const languageId = positronConsoleContext.languageService.getLanguageIdByLanguageName(props.positronConsoleInstance.runtime.metadata.language);
216
- const languageSelection = positronConsoleContext . languageService . createById ( props . positronConsoleInstance . runtime . metadata . languageId ) ;
217
-
218
- // Create text model; this is the backing store for the Monaco editor that receives
219
- // the user's input.
220
- const textModel = positronConsoleContext . modelService . createModel (
221
- '' , // initial value
222
- languageSelection , // language selection
223
- uri , // resource URI
224
- false // this widget is not simple
225
- ) ;
226
-
227
245
// Attach the text model.
228
246
codeEditorWidget . setModel ( textModel ) ;
229
247
0 commit comments