Skip to content

Commit

Permalink
Merge pull request #79712 from microsoft/isidorn/cursorAccessibility
Browse files Browse the repository at this point in the history
Introduce cursor word accessibilty commands
  • Loading branch information
isidorn committed Aug 26, 2019
2 parents 6d17073 + c5c7503 commit c8c773a
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 3 deletions.
32 changes: 30 additions & 2 deletions src/vs/editor/common/controller/cursorWordOperations.ts
Expand Up @@ -39,7 +39,8 @@ const enum WordType {
export const enum WordNavigationType {
WordStart = 0,
WordStartFast = 1,
WordEnd = 2
WordEnd = 2,
WordAccessibility = 3 // Respect chrome defintion of a word
}

export class WordOperations {
Expand Down Expand Up @@ -202,6 +203,18 @@ export class WordOperations {
return new Position(lineNumber, prevWordOnLine ? prevWordOnLine.start + 1 : 1);
}

if (wordNavigationType === WordNavigationType.WordAccessibility) {
while (
prevWordOnLine
&& prevWordOnLine.wordType === WordType.Separator
) {
// Skip over words made up of only separators
prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, new Position(lineNumber, prevWordOnLine.start + 1));
}

return new Position(lineNumber, prevWordOnLine ? prevWordOnLine.start + 1 : 1);
}

// We are stopping at the ending of words

if (prevWordOnLine && column <= prevWordOnLine.end + 1) {
Expand Down Expand Up @@ -270,6 +283,21 @@ export class WordOperations {
nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1));
}
}
if (nextWordOnLine) {
column = nextWordOnLine.end + 1;
} else {
column = model.getLineMaxColumn(lineNumber);
}
} else if (wordNavigationType === WordNavigationType.WordAccessibility) {

while (
nextWordOnLine
&& nextWordOnLine.wordType === WordType.Separator
) {
// Skip over a word made up of one single separator
nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1));
}

if (nextWordOnLine) {
column = nextWordOnLine.end + 1;
} else {
Expand Down Expand Up @@ -617,4 +645,4 @@ export class WordPartOperations extends WordOperations {

function enforceDefined<T>(arr: Array<T | undefined | null>): T[] {
return <T[]>arr.filter(el => Boolean(el));
}
}
40 changes: 39 additions & 1 deletion src/vs/editor/contrib/wordOperations/test/wordOperations.test.ts
Expand Up @@ -9,7 +9,7 @@ import { EditorCommand } from 'vs/editor/browser/editorExtensions';
import { Position } from 'vs/editor/common/core/position';
import { Selection } from 'vs/editor/common/core/selection';
import { deserializePipePositions, serializePipePositions, testRepeatedActionAndExtractPositions } from 'vs/editor/contrib/wordOperations/test/wordTestUtils';
import { CursorWordEndLeft, CursorWordEndLeftSelect, CursorWordEndRight, CursorWordEndRightSelect, CursorWordLeft, CursorWordLeftSelect, CursorWordRight, CursorWordRightSelect, CursorWordStartLeft, CursorWordStartLeftSelect, CursorWordStartRight, CursorWordStartRightSelect, DeleteWordEndLeft, DeleteWordEndRight, DeleteWordLeft, DeleteWordRight, DeleteWordStartLeft, DeleteWordStartRight } from 'vs/editor/contrib/wordOperations/wordOperations';
import { CursorWordEndLeft, CursorWordEndLeftSelect, CursorWordEndRight, CursorWordEndRightSelect, CursorWordLeft, CursorWordLeftSelect, CursorWordRight, CursorWordRightSelect, CursorWordStartLeft, CursorWordStartLeftSelect, CursorWordStartRight, CursorWordStartRightSelect, DeleteWordEndLeft, DeleteWordEndRight, DeleteWordLeft, DeleteWordRight, DeleteWordStartLeft, DeleteWordStartRight, CursorWordAccessibilityLeft, CursorWordAccessibilityLeftSelect, CursorWordAccessibilityRight, CursorWordAccessibilityRightSelect } from 'vs/editor/contrib/wordOperations/wordOperations';
import { withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';

suite('WordOperations', () => {
Expand All @@ -26,6 +26,10 @@ suite('WordOperations', () => {
const _cursorWordStartRightSelect = new CursorWordStartRightSelect();
const _cursorWordEndRightSelect = new CursorWordEndRightSelect();
const _cursorWordRightSelect = new CursorWordRightSelect();
const _cursorWordAccessibilityLeft = new CursorWordAccessibilityLeft();
const _cursorWordAccessibilityLeftSelect = new CursorWordAccessibilityLeftSelect();
const _cursorWordAccessibilityRight = new CursorWordAccessibilityRight();
const _cursorWordAccessibilityRightSelect = new CursorWordAccessibilityRightSelect();
const _deleteWordLeft = new DeleteWordLeft();
const _deleteWordStartLeft = new DeleteWordStartLeft();
const _deleteWordEndLeft = new DeleteWordEndLeft();
Expand All @@ -39,6 +43,12 @@ suite('WordOperations', () => {
function cursorWordLeft(editor: ICodeEditor, inSelectionMode: boolean = false): void {
runEditorCommand(editor, inSelectionMode ? _cursorWordLeftSelect : _cursorWordLeft);
}
function cursorWordAccessibilityLeft(editor: ICodeEditor, inSelectionMode: boolean = false): void {
runEditorCommand(editor, inSelectionMode ? _cursorWordAccessibilityLeft : _cursorWordAccessibilityLeftSelect);
}
function cursorWordAccessibilityRight(editor: ICodeEditor, inSelectionMode: boolean = false): void {
runEditorCommand(editor, inSelectionMode ? _cursorWordAccessibilityRightSelect : _cursorWordAccessibilityRight);
}
function cursorWordStartLeft(editor: ICodeEditor, inSelectionMode: boolean = false): void {
runEditorCommand(editor, inSelectionMode ? _cursorWordStartLeftSelect : _cursorWordStartLeft);
}
Expand Down Expand Up @@ -326,6 +336,34 @@ suite('WordOperations', () => {
assert.deepEqual(actual, EXPECTED);
});

test('cursorWordAccessibilityLeft', () => {
const EXPECTED = ['| /* |Just |some |more |text |a+= |3 +|5-|3 + |7 */ '].join('\n');
const [text,] = deserializePipePositions(EXPECTED);
const actualStops = testRepeatedActionAndExtractPositions(
text,
new Position(1000, 1000),
ed => cursorWordAccessibilityLeft(ed),
ed => ed.getPosition()!,
ed => ed.getPosition()!.equals(new Position(1, 1))
);
const actual = serializePipePositions(text, actualStops);
assert.deepEqual(actual, EXPECTED);
});

test('cursorWordAccessibilityRight', () => {
const EXPECTED = [' /* Just| some| more| text| a|+= 3| +5|-3| + 7| */ |'].join('\n');
const [text,] = deserializePipePositions(EXPECTED);
const actualStops = testRepeatedActionAndExtractPositions(
text,
new Position(1, 1),
ed => cursorWordAccessibilityRight(ed),
ed => ed.getPosition()!,
ed => ed.getPosition()!.equals(new Position(1, 50))
);
const actual = serializePipePositions(text, actualStops);
assert.deepEqual(actual, EXPECTED);
});

test('deleteWordLeft for non-empty selection', () => {
withTestCodeEditor([
' \tMy First Line\t ',
Expand Down
91 changes: 91 additions & 0 deletions src/vs/editor/contrib/wordOperations/wordOperations.ts
Expand Up @@ -18,6 +18,9 @@ import { ScrollType } from 'vs/editor/common/editorCommon';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { ITextModel } from 'vs/editor/common/model';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { EDITOR_DEFAULTS } from 'vs/editor/common/config/editorOptions';

export interface MoveWordOptions extends ICommandOptions {
inSelectionMode: boolean;
Expand Down Expand Up @@ -170,6 +173,48 @@ export class CursorWordLeftSelect extends WordLeftCommand {
}
}

export class CursorWordAccessibilityLeft extends WordLeftCommand {
constructor() {
super({
inSelectionMode: false,
wordNavigationType: WordNavigationType.WordAccessibility,
id: 'cursorWordAccessibilityLeft',
precondition: undefined,
kbOpts: {
kbExpr: ContextKeyExpr.and(EditorContextKeys.textInputFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED),
primary: KeyMod.CtrlCmd | KeyCode.LeftArrow,
mac: { primary: KeyMod.Alt | KeyCode.LeftArrow },
weight: KeybindingWeight.EditorContrib + 1
}
});
}

protected _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position {
return super._move(getMapForWordSeparators(EDITOR_DEFAULTS.wordSeparators), model, position, wordNavigationType);
}
}

export class CursorWordAccessibilityLeftSelect extends WordLeftCommand {
constructor() {
super({
inSelectionMode: true,
wordNavigationType: WordNavigationType.WordAccessibility,
id: 'cursorWordAccessibilitLeftSelecty',
precondition: undefined,
kbOpts: {
kbExpr: ContextKeyExpr.and(EditorContextKeys.textInputFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED),
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.LeftArrow,
mac: { primary: KeyMod.Alt | KeyMod.Shift | KeyCode.LeftArrow },
weight: KeybindingWeight.EditorContrib + 1
}
});
}

protected _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position {
return super._move(getMapForWordSeparators(EDITOR_DEFAULTS.wordSeparators), model, position, wordNavigationType);
}
}

export class CursorWordStartRight extends WordRightCommand {
constructor() {
super({
Expand Down Expand Up @@ -248,6 +293,48 @@ export class CursorWordRightSelect extends WordRightCommand {
}
}

export class CursorWordAccessibilityRight extends WordRightCommand {
constructor() {
super({
inSelectionMode: false,
wordNavigationType: WordNavigationType.WordAccessibility,
id: 'cursorWordAccessibilityRight',
precondition: undefined,
kbOpts: {
kbExpr: ContextKeyExpr.and(EditorContextKeys.textInputFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED),
primary: KeyMod.CtrlCmd | KeyCode.RightArrow,
mac: { primary: KeyMod.Alt | KeyCode.RightArrow },
weight: KeybindingWeight.EditorContrib + 1
}
});
}

protected _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position {
return super._move(getMapForWordSeparators(EDITOR_DEFAULTS.wordSeparators), model, position, wordNavigationType);
}
}

export class CursorWordAccessibilityRightSelect extends WordRightCommand {
constructor() {
super({
inSelectionMode: true,
wordNavigationType: WordNavigationType.WordAccessibility,
id: 'cursorWordAccessibilityRightSelect',
precondition: undefined,
kbOpts: {
kbExpr: ContextKeyExpr.and(EditorContextKeys.textInputFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED),
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.RightArrow,
mac: { primary: KeyMod.Alt | KeyMod.Shift | KeyCode.RightArrow },
weight: KeybindingWeight.EditorContrib + 1
}
});
}

protected _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position {
return super._move(getMapForWordSeparators(EDITOR_DEFAULTS.wordSeparators), model, position, wordNavigationType);
}
}

export interface DeleteWordOptions extends ICommandOptions {
whitespaceHeuristics: boolean;
wordNavigationType: WordNavigationType;
Expand Down Expand Up @@ -397,6 +484,10 @@ registerEditorCommand(new CursorWordRight());
registerEditorCommand(new CursorWordStartRightSelect());
registerEditorCommand(new CursorWordEndRightSelect());
registerEditorCommand(new CursorWordRightSelect());
registerEditorCommand(new CursorWordAccessibilityLeft());
registerEditorCommand(new CursorWordAccessibilityLeftSelect());
registerEditorCommand(new CursorWordAccessibilityRight());
registerEditorCommand(new CursorWordAccessibilityRightSelect());
registerEditorCommand(new DeleteWordStartLeft());
registerEditorCommand(new DeleteWordEndLeft());
registerEditorCommand(new DeleteWordLeft());
Expand Down

0 comments on commit c8c773a

Please sign in to comment.