Change:
<!-- Do Not Delete This! featurerequesttemplate --<!-- Please read our Rules of Conduct: --<!-- Please search existing issues to avoid creating duplicates. --<!-- Describe the feature you'd like. --four cells from the interactive window input box, e.g. , , , reexecute multiple commands from earlier in your history, e.g. and use via the up arrow executing an entry from earlier in the history e.g. , scroll position resets to the bottom of the history, and you have to start over and scroll up from the most recent command (4 -3 - 2 -1). This can be frustrating for users who are trying to reexecute multiple commands. Note also that the original interactive window used to preserve your scroll history in the interactive window so that you didn't have to scroll back up through the entire history, and users have complained about this behavior change:
The expectation is that the interactive window input behaves just like a REPL. would address this. Per discussion with we should have shared logic for handing history traversal.
Any news on that? I agree with the PR that the current behavior is quite frustrating and deserves further attention.
Yes this is one of my main frustrations with the IW still. At minimum I just want the up arrow to go to the last executed code, not have cycle through like 20 cells every time I need to re-run something. And it did used to work this way ~1.5 yrs ago.

Discussion:
return; } <ins> historyService.replaceLast(notebookDocument.uri, value); </ins> historyService.addToHistory(notebookDocument.uri, ''); textModel.setValue('');

const historyService = accessor.get(IInteractiveHistoryService); const editorControl = editorService.activeEditorPane?.getControl() as { notebookEditor: NotebookEditorWidget | undefined; codeEditor: CodeEditorWidget } | undefined; if (editorControl && editorControl.notebookEditor && editorControl.codeEditor) { const notebookDocument = editorControl.notebookEditor.textModel; const textModel = editorControl.codeEditor.getModel();

const textModel = editorControl.codeEditor.getModel(); if (notebookDocument && textModel) { <del> const previousValue = historyService.getNextValue(notebookDocument.uri); if (previousValue) { textModel.setValue(previousValue); </del> <ins> const nextValue = historyService.getNextValue(notebookDocument.uri); if (nextValue !== null) { textModel.setValue(nextValue); </ins> } } }

this._widgetDisposableStore.add(editorModel.onDidChangeContent(() => { const value = editorModel.getValue(); <del> if (this.input?.resource && value !== '') { (this.input as InteractiveEditorInput).historyService.replaceLast(this.input.resource, value); </del> <ins> if (this.input?.resource) { const historyService = (this.input as InteractiveEditorInput).historyService; if (!historyService.matchesCurrent(this.input.resource, value)) { historyService.replaceLast(this.input.resource, value); } </ins> } }));

export interface IInteractiveHistoryService { readonly _serviceBrand: undefined; <ins> matchesCurrent(uri: URI, value: string): boolean; </ins> addToHistory(uri: URI, value: string): void; getPreviousValue(uri: URI): string | null; getNextValue(uri: URI): string | null;

this._history = new ResourceMap<HistoryNavigator2<string>>(); } <ins> matchesCurrent(uri: URI, value: string): boolean { const history = this._history.get(uri); if (!history) { return false; } return history.current() === value; } </ins> addToHistory(uri: URI, value: string): void { <del> if (!this._history.has(uri)) { </del> <ins> const history = this._history.get(uri); if (!history) { </ins> this._history.set(uri, new HistoryNavigator2<string>([value], 50)); return; } <del> const history = this._history.get(uri)!; </del> history.resetCursor(); <del> if (history?.current() !== value) { history?.add(value); } </del> <ins> history.add(value); </ins> } getPreviousValue(uri: URI): string | null { const history = this._history.get(uri); return history?.previous() ?? null;

} replaceLast(uri: URI, value: string) { <del> if (!this._history.has(uri)) { </del> <ins> const history = this._history.get(uri); if (!history) { </ins> this._history.set(uri, new HistoryNavigator2<string>([value], 50)); return; } else { <del> const history = this._history.get(uri); if (history?.current() !== value) { history?.replaceLast(value); } </del> <ins> history.replaceLast(value); history.resetCursor(); </ins> } } clearHistory(uri: URI) {

return; } <del> historyService.addToHistory(notebookDocument.uri, value); </del> <ins> historyService.replaceLast(notebookDocument.uri, value); historyService.addToHistory(notebookDocument.uri, ''); </ins> textModel.setValue(''); notebookDocument.cells[index].resetTextBuffer(textModel.getTextBuffer());

this._widgetDisposableStore.add(editorModel.onDidChangeContent(() => { const value = editorModel.getValue(); if (this.input?.resource && value !== '') { <del> (this.input as ReplEditorInput).historyService.replaceLast(this.input.resource, value); </del> <ins> const historyService = (this.input as ReplEditorInput).historyService; if (!historyService.matchesCurrent(this.input.resource, value)) { historyService.replaceLast(this.input.resource, value); } </ins> } }));