Change:
Type: <bBug</bStep 1: Create a file named with this content: Step 2: create an empty file named Step 3: Move with a terminal in the folder containing the files and run Step 4: Click on the arrow button and see that it doesn't work ! VS Code version: Code 1.88.1 (, 2024-04-10T17:41:02.734Z) OS version: WindowsNT x64 10.0. Modes: <details<summarySystem Info</summary </details<details<summaryExtensions (38)</summaryExtensionVersion ------ vscode-nginx-conf0.3.5 swagger-viewer3.1.2 freezed0.9.6 ccs-flutter-color1.2.4 dart-code3.86.0 flutter3.86.0 jquerysnippets0.0.1 es7-react-js-snippets4.4.3 vscode-html-css2.0.9 copilot1.180.0 copilot-chat0.14.1 vscode-github-actions0.26.2 vscode-pull-request-github0.86.1 gc-excelviewer4.2.59 todo-tree0.0.226 vscode-nginx-conf-hint0.3.1 latex-workshop9.20.0 vscode-edit-csv0.9.1 plantuml2.18.1 vscode-peacock4.2.2 dotenv1.0.1 vscode-docker1.29.0 debugpy2024.5. isort2023.13. python2024.5. vscode-pylance2024.4.102 remote-containers0.354.0 cpptools1.19.9 vscode-thunder-client2.21.11 nginx-formatter0.0.13 vscode-xml0.26.1 vscode-yaml1.14.0 scala0.5.7 markdown-preview-enhanced0.8.13 even-better-toml0.19.2 vscode-icons12.7.0 vscode-nginx0.7.2 txt-syntax0.2.2 </details
working on this
Oh wow I did not realize this was fixed. I've been working on it and just submitted a PR for a similar issue.
My solution was also very similar.
sorry! It was tricky to fix though.

Discussion:
import { LineRange, LineRangeSet } from 'vs/editor/common/core/lineRange'; import { OffsetRange } from 'vs/editor/common/core/offsetRange'; import { Range } from 'vs/editor/common/core/range'; <del> import { SingleTextEdit, TextEdit } from 'vs/editor/common/core/textEdit'; </del> <ins> import { TextEdit } from 'vs/editor/common/core/textEdit'; </ins> import { DetailedLineRangeMapping } from 'vs/editor/common/diff/rangeMapping'; import { TextModelText } from 'vs/editor/common/model/textModelText'; import { HiddenItemStrategy, MenuWorkbenchToolBar } from 'vs/platform/actions/browser/toolbar';

public computeStagedValue(mapping: DetailedLineRangeMapping): string { const c = mapping.innerChanges ?? []; <del> const edit = new TextEdit(c.map(c => new SingleTextEdit(c.originalRange, this._editors.modifiedModel.get()!.getValueInRange(c.modifiedRange)))); const value = edit.apply(new TextModelText(this._editors.original.getModel()!)); </del> <ins> const modified = new TextModelText(this._editors.modifiedModel.get()!); const original = new TextModelText(this._editors.original.getModel()!); const edit = new TextEdit(c.map(c => c.toTextEdit(modified))); const value = edit.apply(original); </ins> return value; }

return new Range(this.startLineNumber, 1, this.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER); } <ins> /** * @deprecated Using this function is discouraged because it might lead to bugs: The end position is not guaranteed to be a valid position! */ </ins> public toExclusiveRange(): Range { return new Range(this.startLineNumber, 1, this.endLineNumberExclusive, 1); }

import { assert, assertFn, checkAdjacentItems } from 'vs/base/common/assert'; import { BugIndicatingError } from 'vs/base/common/errors'; <ins> import { ISingleEditOperation } from 'vs/editor/common/core/editOperation'; </ins> import { Position } from 'vs/editor/common/core/position'; import { PositionOffsetTransformer } from 'vs/editor/common/core/positionToOffset'; import { Range } from 'vs/editor/common/core/range'; import { TextLength } from 'vs/editor/common/core/textLength'; export class TextEdit { <ins> public static single(originalRange: Range, newText: string): TextEdit { return new TextEdit([new SingleTextEdit(originalRange, newText)]); } </ins> constructor(public readonly edits: readonly SingleTextEdit[]) { assertFn(() => checkAdjacentItems(edits, (a, b) => a.range.getEndPosition().isBeforeOrEqual(b.range.getStartPosition()))); }

static equals(first: SingleTextEdit, second: SingleTextEdit) { return first.range.equalsRange(second.range) && first.text === second.text; } <ins> public toSingleEditOperation(): ISingleEditOperation { return { range: this.range, text: this.text, }; } </ins> } function rangeFromPositions(start: Position, end: Position): Range { <del> if (!start.isBeforeOrEqual(end)) { </del> <ins> if (start.lineNumber === end.lineNumber && start.column === Number.MAX_SAFE_INTEGER) { return Range.fromPositions(end, end); } else if (!start.isBeforeOrEqual(end)) { </ins> throw new BugIndicatingError('start must be before end'); } return new Range(start.lineNumber, start.column, end.lineNumber, end.column);

*  Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ <ins> import { BugIndicatingError } from 'vs/base/common/errors'; </ins> import { LineRange } from 'vs/editor/common/core/lineRange'; import { Range } from 'vs/editor/common/core/range'; <ins> import { AbstractText, SingleTextEdit } from 'vs/editor/common/core/textEdit'; </ins> /** * Maps a line range in the original text model to a line range in the modified text model.

public get changedLineCount() { return Math.max(this.original.length, this.modified.length); } <ins> /** * This method assumes that the LineRangeMapping describes a valid diff! * I.e. if one range is empty, the other range cannot be the entire document. * It avoids various problems when the line range points to non-existing line-numbers. */ public toRangeMapping(): RangeMapping { const origInclusiveRange = this.original.toInclusiveRange(); const modInclusiveRange = this.modified.toInclusiveRange(); if (origInclusiveRange && modInclusiveRange) { return new RangeMapping(origInclusiveRange, modInclusiveRange); } else if (this.original.startLineNumber === 1 || this.modified.startLineNumber === 1) { if (!(this.modified.startLineNumber === 1 && this.original.startLineNumber === 1)) { // If one line range starts at 1, the other one must start at 1 as well. throw new BugIndicatingError('not a valid diff'); } // Because one range is empty and both ranges start at line 1, none of the ranges can cover all lines. // Thus, `endLineNumberExclusive` is a valid line number. return new RangeMapping( new Range(this.original.startLineNumber, 1, this.original.endLineNumberExclusive, 1), new Range(this.modified.startLineNumber, 1, this.modified.endLineNumberExclusive, 1), ); } else { // We can assume here that both startLineNumbers are greater than 1. return new RangeMapping( new Range(this.original.startLineNumber - 1, Number.MAX_SAFE_INTEGER, this.original.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER), new Range(this.modified.startLineNumber - 1, Number.MAX_SAFE_INTEGER, this.modified.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER), ); } } </ins> } /**

} public withInnerChangesFromLineRanges(): DetailedLineRangeMapping { <del> return new DetailedLineRangeMapping(this.original, this.modified, [ new RangeMapping(this.original.toExclusiveRange(), this.modified.toExclusiveRange()), ]); </del> <ins> return new DetailedLineRangeMapping(this.original, this.modified, [this.toRangeMapping()]); </ins> } }

public flip(): RangeMapping { return new RangeMapping(this.modifiedRange, this.originalRange); } <ins> /** * Creates a single text edit that describes the change from the original to the modified text. */ public toTextEdit(modified: AbstractText): SingleTextEdit { const newText = modified.getValueOfRange(this.modifiedRange); return new SingleTextEdit(this.originalRange, newText); } </ins> }