Repository: microsoft/vscode (TypeScript)
Date: 2022-03-25 17:52:27+00:00
Task type: Bug Fix

Issue:
up arrow mishandles word wrap

Issue Type: <b>Bug</b>

since the lsat version, when using up arrow to go through a document... if you get to a place where word-wrapforces the cursor to jump to the right (because the cursor is at the left margin & word-wrap is indented)... when the cursor should go to the beginning of the wrapped line, it instead jumps tot he end of the previous line

VS Code version: Code 1.64.2 (f80445acd5a3dadef24aa209168452a3d97cc326, 2022-02-09T22:02:28.252Z)
OS version: Windows_NT x64 10.0.22000
Restricted Mode: No

<details>
<summary>System Info</summary>

|Item|Value|
|---|---|
|CPUs|Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz (8 x 1800)|
|GPU Status|2d_canvas: enabled<br>gpu_compositing: enabled<br>multiple_raster_threads: enabled_on<br>oop_rasterization: enabled<br>opengl: enabled_on<br>rasterization: enabled<br>skia_renderer: enabled_on<br>video_decode: enabled<br>vulkan: disabled_off<br>webgl: enabled<br>webgl2: enabled|
|Load (avg)|undefined|
|Memory (System)|31.89GB (17.59GB free)|
|Process Argv|--file-uri file:///c%3A/src/AF4JM.code-workspace --crash-reporter-id 06338080-eec2-498d-98e0-cf3111dc1cde|
|Screen Reader|no|
|VM|0%|
</details><details><summary>Extensions (105)</summary>

Extension|Author (truncated)|Version
---|---|---
html-snippets|abu|0.2.1
vscode-icalendar|af4|1.0.1
vscode-m3u|af4|1.0.0
vscode-caniuse|aga|0.5.0
case-change|Aka|1.0.2
Bookmarks|ale|13.2.4
rtf|ale|2.4.0
vscode-sqlite|ale|0.14.0
swagger-viewer|Arj|3.1.2
spellright|ban|3.0.60
armview|ben|0.4.6
markdown-checkbox|bie|0.3.2
markdown-emoji|bie|0.2.1
markdown-footnotes|bie|0.0.7
markdown-mermaid|bie|1.13.2
markdown-yaml-preamble|bie|0.1.0
vscode-tldr|bmu|1.0.0
mermaid-markdown-syntax-highlighting|bpr|1.2.2
npm-intellisense|chr|1.4.1
gitignore|cod|0.7.0
disableligatures|Coe|0.0.10
vscode-markdownlint|Dav|0.46.0
jshint|dba|0.11.0
vscode-eslint|dba|2.2.2
dendron-snippet-maker|den|0.1.6
rushcore|Dev|1.0.2
rushnav|Dev|1.0.2
githistory|don|0.6.19
xml|Dot|2.5.1
escaping-characters|drp|1.0.0
vscode-babel-coloring|dza|0.0.4
gitlens|eam|11.7.0
EditorConfig|Edi|0.16.4
vscode-npm-script|eg2|0.3.24
vscode-macros|EXC|1.3.0
git-project-manager|fel|1.8.2
scriptcsRunner|fil|0.1.0
vscode-firefox-debug|fir|2.9.6
vscode-npm|fkn|3.3.0
shell-format|fox|7.2.2
macros|ged|1.2.1
matlab|Gim|2.3.1
vscode-pull-request-github|Git|0.36.2
gc-excelviewer|Gra|4.0.50
beautify|Hoo|1.5.0
vscode-favorites|how|1.10.2
rest-client|hum|0.24.6
path-autocomplete|ion|1.18.0
mediawiki|jak|2.1.0
markdown-katex|jef|0.1.4
nuget-reverse-package-search|jes|0.1.68
vscode-nuget-package-manager|jmr|1.1.6
vscode-peacock|joh|4.0.0
gpg|jva|0.1.2
docomment|k--|0.1.30
vscode-liquid-snippets|kil|2.0.3
gnuplot|mam|1.0.5
markdown-shortcuts|mdi|0.12.0
openapi-lint|mer|1.2.0
HTMLHint|mka|0.10.0
azure-pipelines|ms-|1.195.0
vscode-azureappservice|ms-|0.23.1
vscode-azurefunctions|ms-|1.6.0
vscode-azureresourcegroups|ms-|0.4.0
vscode-azurestorage|ms-|0.13.0
vscode-azurevirtualmachines|ms-|0.5.0
vscode-bicep|ms-|0.4.1272
vscode-cosmosdb|ms-|0.18.1
csharp|ms-|1.24.0
vscode-dotnet-runtime|ms-|1.5.0
python|ms-|2022.0.1814523869
vscode-pylance|ms-|2022.2.4
jupyter|ms-|2022.1.1301854968
jupyter-keymap|ms-|1.0.0
jupyter-renderers|ms-|1.0.6
vscode-ai-remote|ms-|0.7.0
remote-containers|ms-|0.217.4
remote-ssh|ms-|0.74.0
remote-ssh-edit|ms-|0.74.0
vscode-remote-extensionpack|ms-|0.21.0
azure-account|ms-|0.10.0
azurecli|ms-|0.5.0
live-server|ms-|0.2.12
mono-debug|ms-|0.16.2
powershell|ms-|2021.12.0
vscode-node-azure-pack|ms-|0.2.1
vscode-typescript-tslint-plugin|ms-|1.3.3
azurerm-vscode-tools|msa|0.15.6
debugger-for-edge|msj|1.0.15
language-liquid|nei|0.1.1
bib|phr|0.3.0
vscode-commons|red|0.0.6
vscode-yaml|red|1.4.0
kuskus-kusto-language-server|ros|1.0.22
kuskus-kusto-syntax-highlighting|ros|1.1.20
vscode-hexdump|sle|1.8.1
vscode-zipexplorer|sle|0.3.1
addDocComments|ste|0.0.8
msbuild-project-tools|tin|0.4.3
shell-launcher|Tyr|0.4.1
vscodeintellicode|Vis|1.2.17
nanoid-generator|vk-|0.1.2
vscode-icons|vsc|11.10.0
JavaScriptSnippets|xab|1.8.0
t4-support|zbe|0.5.0


</details><details>
<summary>A/B Experiments</summary>

```
vsliv368:30146709
vsreu685:30147344
python383:30185418
vspor879:30202332
vspor708:30202333
vspor363:30204092
vswsl492:30256859
pythonvspyl392cf:30425750
pythontb:30283811
pythonptprofiler:30281270
vshan820:30294714
vstes263:30335439
vscorecescf:30442554
pythondataviewer:30285071
vscod805cf:30301675
pythonvspyt200:30340761
binariesv615:30325510
bridge0708:30335490
bridge0723:30353136
vsaa593cf:30376535
vsc1dst:30438360
pythonvs932:30410667
wslgetstarted:30433507
vsclayoutctrc:30437038
vsrem710:30416614
vscop841:30438915
dsvsc009:30440023
pythonvsnew555:30442236
vsbas813:30436447
vscscmwlcmc:30438804
helix:30440343

```

</details>

<!-- generated by issue reporter -->
up arrow mishandles word wrap

Issue Type: <b>Bug</b>

since the lsat version, when using up arrow to go through a document... if you get to a place where word-wrapforces the cursor to jump to the right (because the cursor is at the left margin & word-wrap is indented)... when the cursor should go to the beginning of the wrapped line, it instead jumps tot he end of the previous line

VS Code version: Code 1.64.2 (f80445acd5a3dadef24aa209168452a3d97cc326, 2022-02-09T22:02:28.252Z)
OS version: Windows_NT x64 10.0.22000
Restricted Mode: No

<details>
<summary>System Info</summary>

|Item|Value|
|---|---|
|CPUs|Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz (8 x 1800)|
|GPU Status|2d_canvas: enabled<br>gpu_compositing: enabled<br>multiple_raster_threads: enabled_on<br>oop_rasterization: enabled<br>opengl: enabled_on<br>rasterization: enabled<br>skia_renderer: enabled_on<br>video_decode: enabled<br>vulkan: disabled_off<br>webgl: enabled<br>webgl2: enabled|
|Load (avg)|undefined|
|Memory (System)|31.89GB (17.59GB free)|
|Process Argv|--file-uri file:///c%3A/src/AF4JM.code-workspace --crash-reporter-id 06338080-eec2-498d-98e0-cf3111dc1cde|
|Screen Reader|no|
|VM|0%|
</details><details><summary>Extensions (105)</summary>

Extension|Author (truncated)|Version
---|---|---
html-snippets|abu|0.2.1
vscode-icalendar|af4|1.0.1
vscode-m3u|af4|1.0.0
vscode-caniuse|aga|0.5.0
case-change|Aka|1.0.2
Bookmarks|ale|13.2.4
rtf|ale|2.4.0
vscode-sqlite|ale|0.14.0
swagger-viewer|Arj|3.1.2
spellright|ban|3.0.60
armview|ben|0.4.6
markdown-checkbox|bie|0.3.2
markdown-emoji|bie|0.2.1
markdown-footnotes|bie|0.0.7
markdown-mermaid|bie|1.13.2
markdown-yaml-preamble|bie|0.1.0
vscode-tldr|bmu|1.0.0
mermaid-markdown-syntax-highlighting|bpr|1.2.2
npm-intellisense|chr|1.4.1
gitignore|cod|0.7.0
disableligatures|Coe|0.0.10
vscode-markdownlint|Dav|0.46.0
jshint|dba|0.11.0
vscode-eslint|dba|2.2.2
dendron-snippet-maker|den|0.1.6
rushcore|Dev|1.0.2
rushnav|Dev|1.0.2
githistory|don|0.6.19
xml|Dot|2.5.1
escaping-characters|drp|1.0.0
vscode-babel-coloring|dza|0.0.4
gitlens|eam|11.7.0
EditorConfig|Edi|0.16.4
vscode-npm-script|eg2|0.3.24
vscode-macros|EXC|1.3.0
git-project-manager|fel|1.8.2
scriptcsRunner|fil|0.1.0
vscode-firefox-debug|fir|2.9.6
vscode-npm|fkn|3.3.0
shell-format|fox|7.2.2
macros|ged|1.2.1
matlab|Gim|2.3.1
vscode-pull-request-github|Git|0.36.2
gc-excelviewer|Gra|4.0.50
beautify|Hoo|1.5.0
vscode-favorites|how|1.10.2
rest-client|hum|0.24.6
path-autocomplete|ion|1.18.0
mediawiki|jak|2.1.0
markdown-katex|jef|0.1.4
nuget-reverse-package-search|jes|0.1.68
vscode-nuget-package-manager|jmr|1.1.6
vscode-peacock|joh|4.0.0
gpg|jva|0.1.2
docomment|k--|0.1.30
vscode-liquid-snippets|kil|2.0.3
gnuplot|mam|1.0.5
markdown-shortcuts|mdi|0.12.0
openapi-lint|mer|1.2.0
HTMLHint|mka|0.10.0
azure-pipelines|ms-|1.195.0
vscode-azureappservice|ms-|0.23.1
vscode-azurefunctions|ms-|1.6.0
vscode-azureresourcegroups|ms-|0.4.0
vscode-azurestorage|ms-|0.13.0
vscode-azurevirtualmachines|ms-|0.5.0
vscode-bicep|ms-|0.4.1272
vscode-cosmosdb|ms-|0.18.1
csharp|ms-|1.24.0
vscode-dotnet-runtime|ms-|1.5.0
python|ms-|2022.0.1814523869
vscode-pylance|ms-|2022.2.4
jupyter|ms-|2022.1.1301854968
jupyter-keymap|ms-|1.0.0
jupyter-renderers|ms-|1.0.6
vscode-ai-remote|ms-|0.7.0
remote-containers|ms-|0.217.4
remote-ssh|ms-|0.74.0
remote-ssh-edit|ms-|0.74.0
vscode-remote-extensionpack|ms-|0.21.0
azure-account|ms-|0.10.0
azurecli|ms-|0.5.0
live-server|ms-|0.2.12
mono-debug|ms-|0.16.2
powershell|ms-|2021.12.0
vscode-node-azure-pack|ms-|0.2.1
vscode-typescript-tslint-plugin|ms-|1.3.3
azurerm-vscode-tools|msa|0.15.6
debugger-for-edge|msj|1.0.15
language-liquid|nei|0.1.1
bib|phr|0.3.0
vscode-commons|red|0.0.6
vscode-yaml|red|1.4.0
kuskus-kusto-language-server|ros|1.0.22
kuskus-kusto-syntax-highlighting|ros|1.1.20
vscode-hexdump|sle|1.8.1
vscode-zipexplorer|sle|0.3.1
addDocComments|ste|0.0.8
msbuild-project-tools|tin|0.4.3
shell-launcher|Tyr|0.4.1
vscodeintellicode|Vis|1.2.17
nanoid-generator|vk-|0.1.2
vscode-icons|vsc|11.10.0
JavaScriptSnippets|xab|1.8.0
t4-support|zbe|0.5.0


</details><details>
<summary>A/B Experiments</summary>

```
vsliv368:30146709
vsreu685:30147344
python383:30185418
vspor879:30202332
vspor708:30202333
vspor363:30204092
vswsl492:30256859
pythonvspyl392cf:30425750
pythontb:30283811
pythonptprofiler:30281270
vshan820:30294714
vstes263:30335439
vscorecescf:30442554
pythondataviewer:30285071
vscod805cf:30301675
pythonvspyt200:30340761
binariesv615:30325510
bridge0708:30335490
bridge0723:30353136
vsaa593cf:30376535
vsc1dst:30438360
pythonvs932:30410667
wslgetstarted:30433507
vsclayoutctrc:30437038
vsrem710:30416614
vscop841:30438915
dsvsc009:30440023
pythonvsnew555:30442236
vsbas813:30436447
vscscmwlcmc:30438804
helix:30440343

```

</details>

<!-- generated by issue reporter -->


Issue discussion:
by "last version" I meant 1.64... same version that made a mess of snippet matching (#142290)
@af4jm Could you please create a screen recording, or an annotated screenshot with a specific example, I'm not sure I understand where exactly the cursor should be at the beginning in order to reproduce.
hopefully this helps... with the cursor as captured, before the "4", prior to 1.64 the next 2 up arrows to follow the green marks I added... but since 1.64 they follow the red ones (technically, the lower green & lower red are the same place if I start typing... but if I'm renumbering my list or changing between bullets & numbers, it throws things off)

![image](https://user-images.githubusercontent.com/849948/156036545-a8734dbb-1cbe-4972-800f-01388c591e10.png)

relevant excerpt from settings:
``` json
{
    "editor.wordWrap": "on",
    "editor.wrappingIndent": "indent"
}
```
I tried the same thing, with the same file, in Obsidian... their editor (I don't know what it's based on since they're not open source) also jumps to the end of the line with "3." on the first up arrow (lower red mark), but then to the beginning of that same line on the second one (upper green mark). That behavior would also work for me... either way, going from "4." to "3." should be up arrow twice because it's the second line above
Thanks for the extra information. I could reproduce and after doing bisect found that 98450a89e7185a1eaedf75230199edf5cae5ad24 is the first bad commit.


by "last version" I meant 1.64... same version that made a mess of snippet matching (#142290)
@af4jm Could you please create a screen recording, or an annotated screenshot with a specific example, I'm not sure I understand where exactly the cursor should be at the beginning in order to reproduce.
hopefully this helps... with the cursor as captured, before the "4", prior to 1.64 the next 2 up arrows to follow the green marks I added... but since 1.64 they follow the red ones (technically, the lower green & lower red are the same place if I start typing... but if I'm renumbering my list or changing between bullets & numbers, it throws things off)

![image](https://user-images.githubusercontent.com/849948/156036545-a8734dbb-1cbe-4972-800f-01388c591e10.png)

relevant excerpt from settings:
``` json
{
    "editor.wordWrap": "on",
    "editor.wrappingIndent": "indent"
}
```
I tried the same thing, with the same file, in Obsidian... their editor (I don't know what it's based on since they're not open source) also jumps to the end of the line with "3." on the first up arrow (lower red mark), but then to the beginning of that same line on the second one (upper green mark). That behavior would also work for me... either way, going from "4." to "3." should be up arrow twice because it's the second line above
Thanks for the extra information. I could reproduce and after doing bisect found that 98450a89e7185a1eaedf75230199edf5cae5ad24 is the first bad commit.



Solution patch:
diff --git a/src/vs/editor/common/cursor/cursorMoveOperations.ts b/src/vs/editor/common/cursor/cursorMoveOperations.ts
--- a/src/vs/editor/common/cursor/cursorMoveOperations.ts
+++ b/src/vs/editor/common/cursor/cursorMoveOperations.ts
@@ -197,7 +197,7 @@ export class MoveOperations {
 	}
 
 	public static down(config: CursorConfiguration, model: ICursorSimpleModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnLastLine: boolean): CursorPosition {
-		return this.vertical(config, model, lineNumber, column, leftoverVisibleColumns, lineNumber + count, allowMoveOnLastLine, PositionAffinity.Right);
+		return this.vertical(config, model, lineNumber, column, leftoverVisibleColumns, lineNumber + count, allowMoveOnLastLine, PositionAffinity.RightOfInjectedText);
 	}
 
 	public static moveDown(config: CursorConfiguration, model: ICursorSimpleModel, cursor: SingleCursorState, inSelectionMode: boolean, linesCount: number): SingleCursorState {
@@ -233,7 +233,7 @@ export class MoveOperations {
 	}
 
 	public static up(config: CursorConfiguration, model: ICursorSimpleModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnFirstLine: boolean): CursorPosition {
-		return this.vertical(config, model, lineNumber, column, leftoverVisibleColumns, lineNumber - count, allowMoveOnFirstLine, PositionAffinity.Left);
+		return this.vertical(config, model, lineNumber, column, leftoverVisibleColumns, lineNumber - count, allowMoveOnFirstLine, PositionAffinity.LeftOfInjectedText);
 	}
 
 	public static moveUp(config: CursorConfiguration, model: ICursorSimpleModel, cursor: SingleCursorState, inSelectionMode: boolean, linesCount: number): SingleCursorState {
diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts
--- a/src/vs/editor/common/model.ts
+++ b/src/vs/editor/common/model.ts
@@ -1270,6 +1270,16 @@ export const enum PositionAffinity {
 	 * No preference.
 	*/
 	None = 2,
+
+	/**
+	 * If the given position is on injected text, prefers the position left of it.
+	*/
+	LeftOfInjectedText = 3,
+
+	/**
+	 * If the given position is on injected text, prefers the position right of it.
+	*/
+	RightOfInjectedText = 4,
 }
 
 /**
diff --git a/src/vs/editor/common/modelLineProjectionData.ts b/src/vs/editor/common/modelLineProjectionData.ts
--- a/src/vs/editor/common/modelLineProjectionData.ts
+++ b/src/vs/editor/common/modelLineProjectionData.ts
@@ -229,7 +229,7 @@ export class ModelLineProjectionData {
 
 				return result;
 			}
-		} else if (affinity === PositionAffinity.Right) {
+		} else if (affinity === PositionAffinity.Right || affinity === PositionAffinity.RightOfInjectedText) {
 			let result = injectedText.offsetInInputWithInjections + injectedText.length;
 			let index = injectedText.injectedTextIndex;
 			// traverse all injected text that touch each other
@@ -238,7 +238,7 @@ export class ModelLineProjectionData {
 				index++;
 			}
 			return result;
-		} else if (affinity === PositionAffinity.Left) {
+		} else if (affinity === PositionAffinity.Left || affinity === PositionAffinity.LeftOfInjectedText) {
 			// affinity is left
 			let result = injectedText.offsetInInputWithInjections;
 			let index = injectedText.injectedTextIndex;
diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts
--- a/src/vs/editor/common/standalone/standaloneEnums.ts
+++ b/src/vs/editor/common/standalone/standaloneEnums.ts
@@ -707,7 +707,15 @@ export enum PositionAffinity {
 	/**
 	 * No preference.
 	*/
-	None = 2
+	None = 2,
+	/**
+	 * If the given position is on injected text, prefers the position left of it.
+	*/
+	LeftOfInjectedText = 3,
+	/**
+	 * If the given position is on injected text, prefers the position right of it.
+	*/
+	RightOfInjectedText = 4
 }
 
 export enum RenderLineNumbersType {
diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts
--- a/src/vs/monaco.d.ts
+++ b/src/vs/monaco.d.ts
@@ -2096,7 +2096,15 @@ declare namespace monaco.editor {
 		/**
 		 * No preference.
 		*/
-		None = 2
+		None = 2,
+		/**
+		 * If the given position is on injected text, prefers the position left of it.
+		*/
+		LeftOfInjectedText = 3,
+		/**
+		 * If the given position is on injected text, prefers the position right of it.
+		*/
+		RightOfInjectedText = 4
 	}
 
 	/**


Test patch:
diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts
--- a/src/vs/editor/test/browser/controller/cursor.test.ts
+++ b/src/vs/editor/test/browser/controller/cursor.test.ts
@@ -468,6 +468,120 @@ suite('Editor Controller - Cursor', () => {
 		});
 	});
 
+	test('issue #144041: Cursor up/down works', () => {
+		let model = createTextModel(
+			[
+				'Word1 Word2 Word3 Word4',
+				'Word5 Word6 Word7 Word8',
+			].join('\n')
+		);
+
+		withTestCodeEditor(model, { wrappingIndent: 'indent', wordWrap: 'wordWrapColumn', wordWrapColumn: 20 }, (editor, viewModel) => {
+			viewModel.setSelections('test', [new Selection(1, 1, 1, 1)]);
+
+			let cursorPositions: any[] = [];
+			function reportCursorPosition() {
+				cursorPositions.push(viewModel.getCursorStates()[0].viewState.position.toString());
+			}
+
+			reportCursorPosition();
+			CoreNavigationCommands.CursorDown.runEditorCommand(null, editor, null);
+			reportCursorPosition();
+			CoreNavigationCommands.CursorDown.runEditorCommand(null, editor, null);
+			reportCursorPosition();
+			CoreNavigationCommands.CursorDown.runEditorCommand(null, editor, null);
+			reportCursorPosition();
+			CoreNavigationCommands.CursorDown.runEditorCommand(null, editor, null);
+
+			reportCursorPosition();
+			CoreNavigationCommands.CursorUp.runEditorCommand(null, editor, null);
+			reportCursorPosition();
+			CoreNavigationCommands.CursorUp.runEditorCommand(null, editor, null);
+			reportCursorPosition();
+			CoreNavigationCommands.CursorUp.runEditorCommand(null, editor, null);
+			reportCursorPosition();
+			CoreNavigationCommands.CursorUp.runEditorCommand(null, editor, null);
+			reportCursorPosition();
+
+			assert.deepStrictEqual(cursorPositions, [
+				'(1,1)',
+				'(2,5)',
+				'(3,1)',
+				'(4,5)',
+				'(4,10)',
+				'(3,1)',
+				'(2,5)',
+				'(1,1)',
+				'(1,1)',
+			]);
+		});
+
+		model.dispose();
+	});
+
+	test('issue #140195: Cursor up/down makes progress', () => {
+		let model = createTextModel(
+			[
+				'Word1 Word2 Word3 Word4',
+				'Word5 Word6 Word7 Word8',
+			].join('\n')
+		);
+
+		withTestCodeEditor(model, { wrappingIndent: 'indent', wordWrap: 'wordWrapColumn', wordWrapColumn: 20 }, (editor, viewModel) => {
+			editor.deltaDecorations([], [
+				{
+					range: new Range(1, 22, 1, 22),
+					options: {
+						showIfCollapsed: true,
+						description: 'test',
+						after: {
+							content: 'some very very very very very very very very long text',
+						}
+					}
+				}
+			]);
+			viewModel.setSelections('test', [new Selection(1, 1, 1, 1)]);
+
+			let cursorPositions: any[] = [];
+			function reportCursorPosition() {
+				cursorPositions.push(viewModel.getCursorStates()[0].viewState.position.toString());
+			}
+
+			reportCursorPosition();
+			CoreNavigationCommands.CursorDown.runEditorCommand(null, editor, null);
+			reportCursorPosition();
+			CoreNavigationCommands.CursorDown.runEditorCommand(null, editor, null);
+			reportCursorPosition();
+			CoreNavigationCommands.CursorDown.runEditorCommand(null, editor, null);
+			reportCursorPosition();
+			CoreNavigationCommands.CursorDown.runEditorCommand(null, editor, null);
+
+			reportCursorPosition();
+			CoreNavigationCommands.CursorUp.runEditorCommand(null, editor, null);
+			reportCursorPosition();
+			CoreNavigationCommands.CursorUp.runEditorCommand(null, editor, null);
+			reportCursorPosition();
+			CoreNavigationCommands.CursorUp.runEditorCommand(null, editor, null);
+			reportCursorPosition();
+			CoreNavigationCommands.CursorUp.runEditorCommand(null, editor, null);
+			reportCursorPosition();
+
+			assert.deepStrictEqual(cursorPositions, [
+				'(1,1)',
+				'(2,5)',
+				'(5,19)',
+				'(6,1)',
+				'(7,5)',
+				'(6,1)',
+				'(2,8)',
+				'(1,1)',
+				'(1,1)',
+			]);
+		});
+
+		model.dispose();
+	});
+
 	// --------- move to beginning of line
 
 	test('move to beginning of line', () => {