Skip to content

Commit

Permalink
Enable word selection with a key modifier.
Browse files Browse the repository at this point in the history
  • Loading branch information
manuelxmarquez committed Nov 7, 2022
1 parent 0c12170 commit 24a3957
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 44 deletions.
10 changes: 10 additions & 0 deletions src/vs/editor/browser/view/viewController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ export class ViewController {
}
}

private _hasWordSelectionModifier(data: IMouseDispatchData): boolean {
return this.configuration.options.get(EditorOption.wordSelection) && this._hasNonMulticursorModifier(data);
}

public dispatchMouse(data: IMouseDispatchData): void {
const options = this.configuration.options;
const selectionClipboardIsOn = (platform.isLinux && options.get(EditorOption.selectionClipboard));
Expand Down Expand Up @@ -192,6 +196,12 @@ export class ViewController {
}
}
}
} else if (this._hasWordSelectionModifier(data)) {
if (data.inSelectionMode) {
this._wordSelectDrag(data.position, data.revealType);
} else {
this._wordSelect(data.position, data.revealType);
}
} else {
if (data.inSelectionMode) {
if (data.altKey) {
Expand Down
10 changes: 10 additions & 0 deletions src/vs/editor/common/config/editorOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,11 @@ export interface IEditorOptions {
* Defaults to 'spread'.
*/
multiCursorPaste?: 'spread' | 'full';
/**
* Enable word selection with the mouse and a key modifier. This replaces the click link to gesture feature.
* Defaults to false
*/
wordSelection?: boolean;
/**
* Configure the editor's accessibility support.
* Defaults to 'auto'. It is best to leave this to 'auto'.
Expand Down Expand Up @@ -4724,6 +4729,7 @@ export const enum EditorOption {
unusualLineTerminators,
useShadowDOM,
useTabStops,
wordSelection,
wordSeparators,
wordWrap,
wordWrapBreakAfterCharacters,
Expand Down Expand Up @@ -5101,6 +5107,10 @@ export const EditorOptions = {
markdownDescription: nls.localize('multiCursorPaste', "Controls pasting when the line count of the pasted text matches the cursor count.")
}
)),
wordSelection: register(new EditorBooleanOption(
EditorOption.wordSelection, 'wordSelection', false,
{ description: nls.localize('wordSelection', "Enable word selection with the mouse and a key modifier. This replaces the click link to gesture feature.") }
)),
occurrencesHighlight: register(new EditorBooleanOption(
EditorOption.occurrencesHighlight, 'occurrencesHighlight', true,
{ description: nls.localize('occurrencesHighlight', "Controls whether the editor should highlight semantic symbol occurrences.") }
Expand Down
33 changes: 17 additions & 16 deletions src/vs/editor/common/standalone/standaloneEnums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,22 +291,23 @@ export enum EditorOption {
unusualLineTerminators = 116,
useShadowDOM = 117,
useTabStops = 118,
wordSeparators = 119,
wordWrap = 120,
wordWrapBreakAfterCharacters = 121,
wordWrapBreakBeforeCharacters = 122,
wordWrapColumn = 123,
wordWrapOverride1 = 124,
wordWrapOverride2 = 125,
wrappingIndent = 126,
wrappingStrategy = 127,
showDeprecated = 128,
inlayHints = 129,
editorClassName = 130,
pixelRatio = 131,
tabFocusMode = 132,
layoutInfo = 133,
wrappingInfo = 134
wordSelection = 119,
wordSeparators = 120,
wordWrap = 121,
wordWrapBreakAfterCharacters = 122,
wordWrapBreakBeforeCharacters = 123,
wordWrapColumn = 124,
wordWrapOverride1 = 125,
wordWrapOverride2 = 126,
wrappingIndent = 127,
wrappingStrategy = 128,
showDeprecated = 129,
inlayHints = 130,
editorClassName = 131,
pixelRatio = 132,
tabFocusMode = 133,
layoutInfo = 134,
wrappingInfo = 135
}

/**
Expand Down
32 changes: 20 additions & 12 deletions src/vs/editor/contrib/gotoSymbol/browser/link/clickLinkGesture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class ClickLinkMouseEvent {
this.isLeftClick = source.event.leftButton;
this.isMiddleClick = source.event.middleButton;
this.isRightClick = source.event.rightButton;
this.hasTriggerModifier = hasModifier(source.event, opts.triggerModifier);
this.hasTriggerModifier = hasModifier(source.event, opts.triggerModifier) && !opts.isWordSelectionEnabled;
this.hasSideBySideModifier = hasModifier(source.event, opts.triggerSideBySideModifier);
this.isNoneOrSingleMouseDown = (source.event.detail <= 1);
}
Expand All @@ -50,9 +50,9 @@ export class ClickLinkKeyboardEvent {
public readonly hasTriggerModifier: boolean;

constructor(source: IKeyboardEvent, opts: ClickLinkOptions) {
this.keyCodeIsTriggerKey = (source.keyCode === opts.triggerKey);
this.keyCodeIsTriggerKey = (source.keyCode === opts.triggerKey && !opts.isWordSelectionEnabled);
this.keyCodeIsSideBySideKey = (source.keyCode === opts.triggerSideBySideKey);
this.hasTriggerModifier = hasModifier(source, opts.triggerModifier);
this.hasTriggerModifier = hasModifier(source, opts.triggerModifier) && !opts.isWordSelectionEnabled;
}
}
export type TriggerModifier = 'ctrlKey' | 'shiftKey' | 'altKey' | 'metaKey';
Expand All @@ -63,17 +63,20 @@ export class ClickLinkOptions {
public readonly triggerModifier: TriggerModifier;
public readonly triggerSideBySideKey: KeyCode;
public readonly triggerSideBySideModifier: TriggerModifier;
public readonly isWordSelectionEnabled: boolean;

constructor(
triggerKey: KeyCode,
triggerModifier: TriggerModifier,
triggerSideBySideKey: KeyCode,
triggerSideBySideModifier: TriggerModifier
triggerSideBySideModifier: TriggerModifier,
isWordSelectionEnabled: boolean
) {
this.triggerKey = triggerKey;
this.triggerModifier = triggerModifier;
this.triggerSideBySideKey = triggerSideBySideKey;
this.triggerSideBySideModifier = triggerSideBySideModifier;
this.isWordSelectionEnabled = isWordSelectionEnabled;
}

public equals(other: ClickLinkOptions): boolean {
Expand All @@ -82,22 +85,23 @@ export class ClickLinkOptions {
&& this.triggerModifier === other.triggerModifier
&& this.triggerSideBySideKey === other.triggerSideBySideKey
&& this.triggerSideBySideModifier === other.triggerSideBySideModifier
&& this.isWordSelectionEnabled === other.isWordSelectionEnabled
);
}
}

function createOptions(multiCursorModifier: 'altKey' | 'ctrlKey' | 'metaKey'): ClickLinkOptions {
function createOptions(multiCursorModifier: 'altKey' | 'ctrlKey' | 'metaKey', isWordSelectionEnabled: boolean): ClickLinkOptions {
if (multiCursorModifier === 'altKey') {
if (platform.isMacintosh) {
return new ClickLinkOptions(KeyCode.Meta, 'metaKey', KeyCode.Alt, 'altKey');
return new ClickLinkOptions(KeyCode.Meta, 'metaKey', KeyCode.Alt, 'altKey', isWordSelectionEnabled);
}
return new ClickLinkOptions(KeyCode.Ctrl, 'ctrlKey', KeyCode.Alt, 'altKey');
return new ClickLinkOptions(KeyCode.Ctrl, 'ctrlKey', KeyCode.Alt, 'altKey', isWordSelectionEnabled);
}

if (platform.isMacintosh) {
return new ClickLinkOptions(KeyCode.Alt, 'altKey', KeyCode.Meta, 'metaKey');
return new ClickLinkOptions(KeyCode.Alt, 'altKey', KeyCode.Meta, 'metaKey', isWordSelectionEnabled);
}
return new ClickLinkOptions(KeyCode.Alt, 'altKey', KeyCode.Ctrl, 'ctrlKey');
return new ClickLinkOptions(KeyCode.Alt, 'altKey', KeyCode.Ctrl, 'ctrlKey', isWordSelectionEnabled);
}

export class ClickLinkGesture extends Disposable {
Expand All @@ -124,15 +128,19 @@ export class ClickLinkGesture extends Disposable {

this._editor = editor;
this._alwaysFireExecuteOnMouseUp = alwaysFireOnMouseUp;
this._opts = createOptions(this._editor.getOption(EditorOption.multiCursorModifier));
this._opts = createOptions(this._editor.getOption(EditorOption.multiCursorModifier), this._editor.getOption(EditorOption.wordSelection));

this._lastMouseMoveEvent = null;
this._hasTriggerKeyOnMouseDown = false;
this._lineNumberOnMouseDown = 0;

if (this._editor.getOption(EditorOption.wordSelection)) {
return;
}

this._register(this._editor.onDidChangeConfiguration((e) => {
if (e.hasChanged(EditorOption.multiCursorModifier)) {
const newOpts = createOptions(this._editor.getOption(EditorOption.multiCursorModifier));
if (e.hasChanged(EditorOption.multiCursorModifier) || e.hasChanged(EditorOption.wordSelection)) {
const newOpts = createOptions(this._editor.getOption(EditorOption.multiCursorModifier), this._editor.getOption(EditorOption.wordSelection));
if (this._opts.equals(newOpts)) {
return;
}
Expand Down
39 changes: 23 additions & 16 deletions src/vs/monaco.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3217,6 +3217,11 @@ declare namespace monaco.editor {
* Defaults to 'spread'.
*/
multiCursorPaste?: 'spread' | 'full';
/**
* Enable word selection with the mouse and a key modifier. This replaces the click link to gesture feature.
* Defaults to false
*/
wordSelection?: boolean;
/**
* Configure the editor's accessibility support.
* Defaults to 'auto'. It is best to leave this to 'auto'.
Expand Down Expand Up @@ -4540,22 +4545,23 @@ declare namespace monaco.editor {
unusualLineTerminators = 116,
useShadowDOM = 117,
useTabStops = 118,
wordSeparators = 119,
wordWrap = 120,
wordWrapBreakAfterCharacters = 121,
wordWrapBreakBeforeCharacters = 122,
wordWrapColumn = 123,
wordWrapOverride1 = 124,
wordWrapOverride2 = 125,
wrappingIndent = 126,
wrappingStrategy = 127,
showDeprecated = 128,
inlayHints = 129,
editorClassName = 130,
pixelRatio = 131,
tabFocusMode = 132,
layoutInfo = 133,
wrappingInfo = 134
wordSelection = 119,
wordSeparators = 120,
wordWrap = 121,
wordWrapBreakAfterCharacters = 122,
wordWrapBreakBeforeCharacters = 123,
wordWrapColumn = 124,
wordWrapOverride1 = 125,
wordWrapOverride2 = 126,
wrappingIndent = 127,
wrappingStrategy = 128,
showDeprecated = 129,
inlayHints = 130,
editorClassName = 131,
pixelRatio = 132,
tabFocusMode = 133,
layoutInfo = 134,
wrappingInfo = 135
}

export const EditorOptions: {
Expand Down Expand Up @@ -4633,6 +4639,7 @@ declare namespace monaco.editor {
multiCursorMergeOverlapping: IEditorOption<EditorOption.multiCursorMergeOverlapping, boolean>;
multiCursorModifier: IEditorOption<EditorOption.multiCursorModifier, 'altKey' | 'metaKey' | 'ctrlKey'>;
multiCursorPaste: IEditorOption<EditorOption.multiCursorPaste, 'spread' | 'full'>;
wordSelection: IEditorOption<EditorOption.wordSelection, boolean>;
occurrencesHighlight: IEditorOption<EditorOption.occurrencesHighlight, boolean>;
overviewRulerBorder: IEditorOption<EditorOption.overviewRulerBorder, boolean>;
overviewRulerLanes: IEditorOption<EditorOption.overviewRulerLanes, number>;
Expand Down

0 comments on commit 24a3957

Please sign in to comment.