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. --I would like an option to virtually prevent vscode from pushing down the current focused line when new lines are automatically . For example, when I click to automatically add an import, vscode adds the import line and the current focused line is scrolled down. This causes a distraction because the line I'm working on is moved away even tho I didn't want to scroll. Here is a gif showing how IntelliJ behavior when new lines are automatically above the current selected line. Note that after the import statement is the current line is virtually kept the same (the line number do change, of course, but the scroll is set to a new position in order to respect the old position): ! The next gif show how vscode pushes down the code and loses the previous virtual position: ! Would be possible to add an option to vscode behavior like IntelliJ in this situation?
Technically, the editor does not scroll. The scrollTop is maintained. It just happens that everything is pushed down by the auto-import which inserts a line at the top of the file. This can be done from the outside if you know there are edits unrelated to the current cursor position in the suggestion e.g.:
I'd like to help out with this! Any additional pointers would be appreciated.
This is where the first potential edit happens: and this is where it is done: So, those two places should be used to capture and restore the scroll state
to verify: down a bit a typescript suggestion that adds an import sure that the scroll position stays stable (lines aren't pushed down)

Discussion:
visiblePositionScrollDelta = editor.getScrollTop() - visiblePositionScrollTop; } } <del> return new StableEditorScrollState(visiblePosition, visiblePositionScrollDelta); </del> <ins> return new StableEditorScrollState(visiblePosition, visiblePositionScrollDelta, editor.getPosition()); </ins> } constructor( private readonly _visiblePosition: Position | null, <del> private readonly _visiblePositionScrollDelta: number </del> <ins> private readonly _visiblePositionScrollDelta: number, private readonly _cursorPosition: Position | null </ins> ) { }

editor.setScrollTop(visiblePositionScrollTop + this._visiblePositionScrollDelta); } } <ins> public restoreRelativeVerticalPositionOfCursor(editor: ICodeEditor): void { const currentCursorPosition = editor.getPosition(); if (!this._cursorPosition || !currentCursorPosition) { return; } const offset = editor.getTopForLineNumber(currentCursorPosition.lineNumber) - editor.getTopForLineNumber(this._cursorPosition.lineNumber); editor.setScrollTop(editor.getScrollTop() + offset); } </ins> }

import { onUnexpectedError } from 'vs/base/common/errors'; import { KeyCode, KeyMod, SimpleKeybinding } from 'vs/base/common/keyCodes'; import { dispose, IDisposable, DisposableStore, toDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; <ins> import { StableEditorScrollState } from 'vs/editor/browser/core/editorState'; </ins> import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, EditorCommand, registerEditorAction, registerEditorCommand, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { EditOperation } from 'vs/editor/common/core/editOperation';

// keep item in memory this._memoryService.memorize(model, this.editor.getPosition(), item); <ins> const scrollState = StableEditorScrollState.capture(this.editor); </ins> if (Array.isArray(suggestion.additionalTextEdits)) { this.editor.executeEdits('suggestController.additionalTextEdits', suggestion.additionalTextEdits.map(edit => EditOperation.replace(Range.lift(edit.range), edit.text))); }

adjustWhitespace: !(suggestion.insertTextRules! & CompletionItemInsertTextRule.KeepWhitespace) }); <ins> scrollState.restoreRelativeVerticalPositionOfCursor(this.editor); </ins> if (!(flags & InsertFlags.NoAfterUndoStop)) { this.editor.pushUndoStop(); }