Skip to content

Commit 1b34b1d

Browse files
committed
Fix microsoft#29828, Fix microsoft#29843, Fix microsoft#29876. Enter in the middle of content should not adjust cursor position.
1 parent 01cbc6d commit 1b34b1d

2 files changed

Lines changed: 221 additions & 27 deletions

File tree

src/vs/editor/common/controller/cursorTypeOperations.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,8 @@ export class TypeOperations {
312312
let indentation = strings.getLeadingWhitespace(lineText).substring(0, range.startColumn - 1);
313313

314314
if (ir) {
315-
let isSelectionEmpty = range.isEmpty();
316-
let oldEndColumn = CursorColumns.visibleColumnFromColumn2(config, model, range.getEndPosition());
317-
if (!config.insertSpaces) {
318-
oldEndColumn = Math.ceil(oldEndColumn / config.tabSize) + 1;
319-
}
315+
let oldEndViewColumn = CursorColumns.visibleColumnFromColumn2(config, model, range.getEndPosition());
316+
let oldEndColumn = range.endColumn;
320317

321318
let beforeText = '\n';
322319
if (indentation !== config.normalizeIndentation(ir.beforeEnter)) {
@@ -335,7 +332,13 @@ export class TypeOperations {
335332
if (keepPosition) {
336333
return new ReplaceCommandWithoutChangingPosition(range, beforeText + config.normalizeIndentation(ir.afterEnter), true);
337334
} else {
338-
let offset = isSelectionEmpty ? oldEndColumn - config.normalizeIndentation(ir.afterEnter).length - 1 : 0;
335+
let offset = 0;
336+
if (oldEndColumn <= firstNonWhitespace + 1) {
337+
if (!config.insertSpaces) {
338+
oldEndViewColumn = Math.ceil(oldEndViewColumn / config.tabSize);
339+
}
340+
offset = Math.min(oldEndViewColumn + 1 - config.normalizeIndentation(ir.afterEnter).length - 1, 0);
341+
}
339342
return new ReplaceCommandWithOffsetCursorState(range, beforeText + config.normalizeIndentation(ir.afterEnter), 0, offset, true);
340343
}
341344

src/vs/editor/test/common/controller/cursor.test.ts

Lines changed: 212 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2498,27 +2498,218 @@ suite('Editor Controller - Indentation Rules', () => {
24982498
});
24992499
});
25002500

2501-
// test('Enter supports intentional indentation', () => {
2502-
// usingCursor({
2503-
// text: [
2504-
// '\tif (true) {',
2505-
// '\t\tswitch(true) {',
2506-
// '\t\t\tcase true:',
2507-
// '\t\t\t\tbreak;',
2508-
// '\t\t}',
2509-
// '\t}'
2510-
// ],
2511-
// languageIdentifier: mode.getLanguageIdentifier(),
2512-
// modelOpts: { insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }
2513-
// }, (model, cursor) => {
2514-
// moveTo(cursor, 5, 4, false);
2515-
// assertCursor(cursor, new Selection(5, 4, 5, 4));
2516-
2517-
// cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard');
2518-
// assert.equal(model.getLineContent(5), '\t\t}');
2519-
// assertCursor(cursor, new Selection(6, 3, 6, 3));
2520-
// });
2521-
// });
2501+
test('Enter supports intentional indentation', () => {
2502+
usingCursor({
2503+
text: [
2504+
'\tif (true) {',
2505+
'\t\tswitch(true) {',
2506+
'\t\t\tcase true:',
2507+
'\t\t\t\tbreak;',
2508+
'\t\t}',
2509+
'\t}'
2510+
],
2511+
languageIdentifier: mode.getLanguageIdentifier(),
2512+
modelOpts: { insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }
2513+
}, (model, cursor) => {
2514+
moveTo(cursor, 5, 4, false);
2515+
assertCursor(cursor, new Selection(5, 4, 5, 4));
2516+
2517+
cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard');
2518+
assert.equal(model.getLineContent(5), '\t\t}');
2519+
assertCursor(cursor, new Selection(6, 3, 6, 3));
2520+
});
2521+
});
2522+
2523+
test('Enter should not adjust cursor position when press enter in the middle of a line 1', () => {
2524+
usingCursor({
2525+
text: [
2526+
'if (true) {',
2527+
'\tif (true) {',
2528+
'\t\treturn true;',
2529+
'\t}a}'
2530+
],
2531+
languageIdentifier: mode.getLanguageIdentifier(),
2532+
modelOpts: { insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }
2533+
}, (model, cursor) => {
2534+
moveTo(cursor, 3, 9, false);
2535+
assertCursor(cursor, new Selection(3, 9, 3, 9));
2536+
2537+
cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard');
2538+
assertCursor(cursor, new Selection(4, 3, 4, 3));
2539+
assert.equal(model.getLineContent(4), '\t\t true;', '001');
2540+
});
2541+
});
2542+
2543+
test('Enter should not adjust cursor position when press enter in the middle of a line 2', () => {
2544+
usingCursor({
2545+
text: [
2546+
'if (true) {',
2547+
'\tif (true) {',
2548+
'\t\treturn true;',
2549+
'\t}a}'
2550+
],
2551+
languageIdentifier: mode.getLanguageIdentifier(),
2552+
modelOpts: { insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }
2553+
}, (model, cursor) => {
2554+
moveTo(cursor, 3, 3, false);
2555+
assertCursor(cursor, new Selection(3, 3, 3, 3));
2556+
2557+
cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard');
2558+
assertCursor(cursor, new Selection(4, 3, 4, 3));
2559+
assert.equal(model.getLineContent(4), '\t\treturn true;', '001');
2560+
});
2561+
});
2562+
2563+
test('Enter should not adjust cursor position when press enter in the middle of a line 3', () => {
2564+
usingCursor({
2565+
text: [
2566+
'if (true) {',
2567+
' if (true) {',
2568+
' return true;',
2569+
' }a}'
2570+
],
2571+
languageIdentifier: mode.getLanguageIdentifier(),
2572+
modelOpts: { insertSpaces: true, tabSize: 2, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }
2573+
}, (model, cursor) => {
2574+
moveTo(cursor, 3, 11, false);
2575+
assertCursor(cursor, new Selection(3, 11, 3, 11));
2576+
2577+
cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard');
2578+
assertCursor(cursor, new Selection(4, 5, 4, 5));
2579+
assert.equal(model.getLineContent(4), ' true;', '001');
2580+
});
2581+
});
2582+
2583+
test('Enter should adjust cursor position when press enter in the middle of leading whitespaces 1', () => {
2584+
usingCursor({
2585+
text: [
2586+
'if (true) {',
2587+
'\tif (true) {',
2588+
'\t\treturn true;',
2589+
'\t}a}'
2590+
],
2591+
languageIdentifier: mode.getLanguageIdentifier(),
2592+
modelOpts: { insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }
2593+
}, (model, cursor) => {
2594+
moveTo(cursor, 3, 2, false);
2595+
assertCursor(cursor, new Selection(3, 2, 3, 2));
2596+
2597+
cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard');
2598+
assertCursor(cursor, new Selection(4, 2, 4, 2));
2599+
assert.equal(model.getLineContent(4), '\t\treturn true;', '001');
2600+
2601+
moveTo(cursor, 4, 1, false);
2602+
assertCursor(cursor, new Selection(4, 1, 4, 1));
2603+
2604+
cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard');
2605+
assertCursor(cursor, new Selection(5, 1, 5, 1));
2606+
assert.equal(model.getLineContent(5), '\t\treturn true;', '002');
2607+
});
2608+
});
2609+
2610+
test('Enter should adjust cursor position when press enter in the middle of leading whitespaces 2', () => {
2611+
usingCursor({
2612+
text: [
2613+
'\tif (true) {',
2614+
'\t\tif (true) {',
2615+
'\t \treturn true;',
2616+
'\t\t}a}'
2617+
],
2618+
languageIdentifier: mode.getLanguageIdentifier(),
2619+
modelOpts: { insertSpaces: false, tabSize: 4, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }
2620+
}, (model, cursor) => {
2621+
moveTo(cursor, 3, 4, false);
2622+
assertCursor(cursor, new Selection(3, 4, 3, 4));
2623+
2624+
cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard');
2625+
assertCursor(cursor, new Selection(4, 3, 4, 3));
2626+
assert.equal(model.getLineContent(4), '\t\t\treturn true;', '001');
2627+
2628+
moveTo(cursor, 4, 1, false);
2629+
assertCursor(cursor, new Selection(4, 1, 4, 1));
2630+
2631+
cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard');
2632+
assertCursor(cursor, new Selection(5, 1, 5, 1));
2633+
assert.equal(model.getLineContent(5), '\t\t\treturn true;', '002');
2634+
});
2635+
});
2636+
2637+
test('Enter should adjust cursor position when press enter in the middle of leading whitespaces 3', () => {
2638+
usingCursor({
2639+
text: [
2640+
'if (true) {',
2641+
' if (true) {',
2642+
' return true;',
2643+
'}a}'
2644+
],
2645+
languageIdentifier: mode.getLanguageIdentifier(),
2646+
modelOpts: { insertSpaces: true, tabSize: 2, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }
2647+
}, (model, cursor) => {
2648+
moveTo(cursor, 3, 2, false);
2649+
assertCursor(cursor, new Selection(3, 2, 3, 2));
2650+
2651+
cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard');
2652+
assertCursor(cursor, new Selection(4, 2, 4, 2));
2653+
assert.equal(model.getLineContent(4), ' return true;', '001');
2654+
2655+
moveTo(cursor, 4, 3, false);
2656+
cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard');
2657+
assertCursor(cursor, new Selection(5, 3, 5, 3));
2658+
assert.equal(model.getLineContent(5), ' return true;', '002');
2659+
});
2660+
});
2661+
2662+
test('Enter should adjust cursor position when press enter in the middle of leading whitespaces 4', () => {
2663+
usingCursor({
2664+
text: [
2665+
'if (true) {',
2666+
' if (true) {',
2667+
'\t return true;',
2668+
'}a}',
2669+
'',
2670+
'if (true) {',
2671+
' if (true) {',
2672+
'\t return true;',
2673+
'}a}'
2674+
],
2675+
languageIdentifier: mode.getLanguageIdentifier(),
2676+
modelOpts: { insertSpaces: true, tabSize: 2, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }
2677+
}, (model, cursor) => {
2678+
moveTo(cursor, 3, 3, false);
2679+
assertCursor(cursor, new Selection(3, 3, 3, 3));
2680+
2681+
cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard');
2682+
assertCursor(cursor, new Selection(4, 4, 4, 4));
2683+
assert.equal(model.getLineContent(4), ' return true;', '001');
2684+
2685+
moveTo(cursor, 9, 4, false);
2686+
cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard');
2687+
assertCursor(cursor, new Selection(10, 5, 10, 5));
2688+
assert.equal(model.getLineContent(10), ' return true;', '001');
2689+
});
2690+
});
2691+
2692+
test('Enter should adjust cursor position when press enter in the middle of leading whitespaces 5', () => {
2693+
usingCursor({
2694+
text: [
2695+
'if (true) {',
2696+
' if (true) {',
2697+
' return true;',
2698+
' return true;',
2699+
''
2700+
],
2701+
languageIdentifier: mode.getLanguageIdentifier(),
2702+
modelOpts: { insertSpaces: true, tabSize: 2, detectIndentation: false, defaultEOL: DefaultEndOfLine.LF, trimAutoWhitespace: true }
2703+
}, (model, cursor) => {
2704+
moveTo(cursor, 3, 5, false);
2705+
moveTo(cursor, 4, 3, true);
2706+
assertCursor(cursor, new Selection(3, 5, 4, 3));
2707+
2708+
cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard');
2709+
assertCursor(cursor, new Selection(4, 3, 4, 3));
2710+
assert.equal(model.getLineContent(4), ' return true;', '001');
2711+
});
2712+
});
25222713

25232714
test('issue Microsoft/monaco-editor#108 part 1/2: Auto indentation on Enter with selection is half broken', () => {
25242715
usingCursor({

0 commit comments

Comments
 (0)