Skip to content

Commit 6399d03

Browse files
nikita-rnryut-ikialexdima
authored
Modify "*WordPart*" family of commands to respect kebab-case (resolves microsoft#158667) (microsoft#158672)
* Modify "*WordPart*" family of commands to respect kebab-case * Write new tests for microsoft#158667 instead of modifying existing ones * Fix tests Co-authored-by: nikita-r <[email protected]> Co-authored-by: Alex Dima <[email protected]>
1 parent f4d9b1d commit 6399d03

File tree

3 files changed

+81
-3
lines changed

3 files changed

+81
-3
lines changed

src/vs/editor/common/cursor/cursorWordOperations.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,11 @@ export class WordOperations {
246246
return new Position(lineNumber, column);
247247
}
248248

249+
if (left === CharCode.Dash && right !== CharCode.Dash) {
250+
// kebab-case-variables
251+
return new Position(lineNumber, column);
252+
}
253+
249254
if ((strings.isLowerAsciiLetter(left) || strings.isAsciiDigit(left)) && strings.isUpperAsciiLetter(right)) {
250255
// camelCaseVariables
251256
return new Position(lineNumber, column);
@@ -348,6 +353,11 @@ export class WordOperations {
348353
return new Position(lineNumber, column);
349354
}
350355

356+
if (left !== CharCode.Dash && right === CharCode.Dash) {
357+
// kebab-case-variables
358+
return new Position(lineNumber, column);
359+
}
360+
351361
if ((strings.isLowerAsciiLetter(left) || strings.isAsciiDigit(left)) && strings.isUpperAsciiLetter(right)) {
352362
// camelCaseVariables
353363
return new Position(lineNumber, column);

src/vs/editor/contrib/wordOperations/test/browser/wordTestUtils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { Position } from 'vs/editor/common/core/position';
7-
import { ITestCodeEditor, withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
7+
import { ITestCodeEditor, TestCodeEditorInstantiationOptions, withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
88

99
export function deserializePipePositions(text: string): [string, Position[]] {
1010
let resultText = '';
@@ -58,9 +58,9 @@ export function serializePipePositions(text: string, positions: Position[]): str
5858
return resultText;
5959
}
6060

61-
export function testRepeatedActionAndExtractPositions(text: string, initialPosition: Position, action: (editor: ITestCodeEditor) => void, record: (editor: ITestCodeEditor) => Position, stopCondition: (editor: ITestCodeEditor) => boolean): Position[] {
61+
export function testRepeatedActionAndExtractPositions(text: string, initialPosition: Position, action: (editor: ITestCodeEditor) => void, record: (editor: ITestCodeEditor) => Position, stopCondition: (editor: ITestCodeEditor) => boolean, options: TestCodeEditorInstantiationOptions = {}): Position[] {
6262
const actualStops: Position[] = [];
63-
withTestCodeEditor(text, {}, (editor) => {
63+
withTestCodeEditor(text, options, (editor) => {
6464
editor.setPosition(initialPosition);
6565
while (true) {
6666
action(editor);

src/vs/editor/contrib/wordPartOperations/test/browser/wordPartOperations.test.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,72 @@ suite('WordPartOperations', () => {
212212
const actual = serializePipePositions(text, actualStops);
213213
assert.deepStrictEqual(actual, EXPECTED);
214214
});
215+
216+
test('issue #158667: cursorWordPartLeft stops at "-" even when "-" is not in word separators', () => {
217+
const EXPECTED = [
218+
'|this-|is-|a-|kebab-|case-|var| |THIS-|IS-|CAPS-|KEBAB| |this-|IS|Mixed|Use',
219+
].join('\n');
220+
const [text,] = deserializePipePositions(EXPECTED);
221+
const actualStops = testRepeatedActionAndExtractPositions(
222+
text,
223+
new Position(1000, 1000),
224+
ed => cursorWordPartLeft(ed),
225+
ed => ed.getPosition()!,
226+
ed => ed.getPosition()!.equals(new Position(1, 1)),
227+
{ wordSeparators: "!\"#&'()*+,./:;<=>?@[\\]^`{|}·" } // default characters sans '$-%~' plus '·'
228+
);
229+
const actual = serializePipePositions(text, actualStops);
230+
assert.deepStrictEqual(actual, EXPECTED);
231+
});
232+
233+
test('issue #158667: cursorWordPartRight stops at "-" even when "-" is not in word separators', () => {
234+
const EXPECTED = [
235+
'this|-is|-a|-kebab|-case|-var| |THIS|-IS|-CAPS|-KEBAB| |this|-IS|Mixed|Use|',
236+
].join('\n');
237+
const [text,] = deserializePipePositions(EXPECTED);
238+
const actualStops = testRepeatedActionAndExtractPositions(
239+
text,
240+
new Position(1, 1),
241+
ed => cursorWordPartRight(ed),
242+
ed => ed.getPosition()!,
243+
ed => ed.getPosition()!.equals(new Position(1, 60)),
244+
{ wordSeparators: "!\"#&'()*+,./:;<=>?@[\\]^`{|}·" } // default characters sans '$-%~' plus '·'
245+
);
246+
const actual = serializePipePositions(text, actualStops);
247+
assert.deepStrictEqual(actual, EXPECTED);
248+
});
249+
250+
test('issue #158667: deleteWordPartLeft stops at "-" even when "-" is not in word separators', () => {
251+
const EXPECTED = [
252+
'|this-|is-|a-|kebab-|case-|var| |THIS-|IS-|CAPS-|KEBAB| |this-|IS|Mixed|Use',
253+
].join(' ');
254+
const [text,] = deserializePipePositions(EXPECTED);
255+
const actualStops = testRepeatedActionAndExtractPositions(
256+
text,
257+
new Position(1000, 1000),
258+
ed => deleteWordPartLeft(ed),
259+
ed => ed.getPosition()!,
260+
ed => ed.getValue().length === 0,
261+
{ wordSeparators: "!\"#&'()*+,./:;<=>?@[\\]^`{|}·" } // default characters sans '$-%~' plus '·'
262+
);
263+
const actual = serializePipePositions(text, actualStops);
264+
assert.deepStrictEqual(actual, EXPECTED);
265+
});
266+
267+
test('issue #158667: deleteWordPartRight stops at "-" even when "-" is not in word separators', () => {
268+
const EXPECTED = [
269+
'this|-is|-a|-kebab|-case|-var| |THIS|-IS|-CAPS|-KEBAB| |this|-IS|Mixed|Use|',
270+
].join(' ');
271+
const [text,] = deserializePipePositions(EXPECTED);
272+
const actualStops = testRepeatedActionAndExtractPositions(
273+
text,
274+
new Position(1, 1),
275+
ed => deleteWordPartRight(ed),
276+
ed => new Position(1, text.length - ed.getValue().length + 1),
277+
ed => ed.getValue().length === 0,
278+
{ wordSeparators: "!\"#&'()*+,./:;<=>?@[\\]^`{|}·" } // default characters sans '$-%~' plus '·'
279+
);
280+
const actual = serializePipePositions(text, actualStops);
281+
assert.deepStrictEqual(actual, EXPECTED);
282+
});
215283
});

0 commit comments

Comments
 (0)