| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- import { Emitter } from '../../../../../base/common/event.js';
- import { Disposable } from '../../../../../base/common/lifecycle.js';
- import * as platform from '../../../../../base/common/platform.js';
- function hasModifier(e, modifier) {
- return !!e[modifier];
- }
- /**
- * An event that encapsulates the various trigger modifiers logic needed for go to definition.
- */
- export class ClickLinkMouseEvent {
- constructor(source, opts) {
- this.target = source.target;
- this.hasTriggerModifier = hasModifier(source.event, opts.triggerModifier);
- this.hasSideBySideModifier = hasModifier(source.event, opts.triggerSideBySideModifier);
- this.isNoneOrSingleMouseDown = (source.event.detail <= 1);
- }
- }
- /**
- * An event that encapsulates the various trigger modifiers logic needed for go to definition.
- */
- export class ClickLinkKeyboardEvent {
- constructor(source, opts) {
- this.keyCodeIsTriggerKey = (source.keyCode === opts.triggerKey);
- this.keyCodeIsSideBySideKey = (source.keyCode === opts.triggerSideBySideKey);
- this.hasTriggerModifier = hasModifier(source, opts.triggerModifier);
- }
- }
- export class ClickLinkOptions {
- constructor(triggerKey, triggerModifier, triggerSideBySideKey, triggerSideBySideModifier) {
- this.triggerKey = triggerKey;
- this.triggerModifier = triggerModifier;
- this.triggerSideBySideKey = triggerSideBySideKey;
- this.triggerSideBySideModifier = triggerSideBySideModifier;
- }
- equals(other) {
- return (this.triggerKey === other.triggerKey
- && this.triggerModifier === other.triggerModifier
- && this.triggerSideBySideKey === other.triggerSideBySideKey
- && this.triggerSideBySideModifier === other.triggerSideBySideModifier);
- }
- }
- function createOptions(multiCursorModifier) {
- if (multiCursorModifier === 'altKey') {
- if (platform.isMacintosh) {
- return new ClickLinkOptions(57 /* KeyCode.Meta */, 'metaKey', 6 /* KeyCode.Alt */, 'altKey');
- }
- return new ClickLinkOptions(5 /* KeyCode.Ctrl */, 'ctrlKey', 6 /* KeyCode.Alt */, 'altKey');
- }
- if (platform.isMacintosh) {
- return new ClickLinkOptions(6 /* KeyCode.Alt */, 'altKey', 57 /* KeyCode.Meta */, 'metaKey');
- }
- return new ClickLinkOptions(6 /* KeyCode.Alt */, 'altKey', 5 /* KeyCode.Ctrl */, 'ctrlKey');
- }
- export class ClickLinkGesture extends Disposable {
- constructor(editor) {
- super();
- this._onMouseMoveOrRelevantKeyDown = this._register(new Emitter());
- this.onMouseMoveOrRelevantKeyDown = this._onMouseMoveOrRelevantKeyDown.event;
- this._onExecute = this._register(new Emitter());
- this.onExecute = this._onExecute.event;
- this._onCancel = this._register(new Emitter());
- this.onCancel = this._onCancel.event;
- this._editor = editor;
- this._opts = createOptions(this._editor.getOption(72 /* EditorOption.multiCursorModifier */));
- this._lastMouseMoveEvent = null;
- this._hasTriggerKeyOnMouseDown = false;
- this._lineNumberOnMouseDown = 0;
- this._register(this._editor.onDidChangeConfiguration((e) => {
- if (e.hasChanged(72 /* EditorOption.multiCursorModifier */)) {
- const newOpts = createOptions(this._editor.getOption(72 /* EditorOption.multiCursorModifier */));
- if (this._opts.equals(newOpts)) {
- return;
- }
- this._opts = newOpts;
- this._lastMouseMoveEvent = null;
- this._hasTriggerKeyOnMouseDown = false;
- this._lineNumberOnMouseDown = 0;
- this._onCancel.fire();
- }
- }));
- this._register(this._editor.onMouseMove((e) => this._onEditorMouseMove(new ClickLinkMouseEvent(e, this._opts))));
- this._register(this._editor.onMouseDown((e) => this._onEditorMouseDown(new ClickLinkMouseEvent(e, this._opts))));
- this._register(this._editor.onMouseUp((e) => this._onEditorMouseUp(new ClickLinkMouseEvent(e, this._opts))));
- this._register(this._editor.onKeyDown((e) => this._onEditorKeyDown(new ClickLinkKeyboardEvent(e, this._opts))));
- this._register(this._editor.onKeyUp((e) => this._onEditorKeyUp(new ClickLinkKeyboardEvent(e, this._opts))));
- this._register(this._editor.onMouseDrag(() => this._resetHandler()));
- this._register(this._editor.onDidChangeCursorSelection((e) => this._onDidChangeCursorSelection(e)));
- this._register(this._editor.onDidChangeModel((e) => this._resetHandler()));
- this._register(this._editor.onDidChangeModelContent(() => this._resetHandler()));
- this._register(this._editor.onDidScrollChange((e) => {
- if (e.scrollTopChanged || e.scrollLeftChanged) {
- this._resetHandler();
- }
- }));
- }
- _onDidChangeCursorSelection(e) {
- if (e.selection && e.selection.startColumn !== e.selection.endColumn) {
- this._resetHandler(); // immediately stop this feature if the user starts to select (https://github.com/microsoft/vscode/issues/7827)
- }
- }
- _onEditorMouseMove(mouseEvent) {
- this._lastMouseMoveEvent = mouseEvent;
- this._onMouseMoveOrRelevantKeyDown.fire([mouseEvent, null]);
- }
- _onEditorMouseDown(mouseEvent) {
- // We need to record if we had the trigger key on mouse down because someone might select something in the editor
- // holding the mouse down and then while mouse is down start to press Ctrl/Cmd to start a copy operation and then
- // release the mouse button without wanting to do the navigation.
- // With this flag we prevent goto definition if the mouse was down before the trigger key was pressed.
- this._hasTriggerKeyOnMouseDown = mouseEvent.hasTriggerModifier;
- this._lineNumberOnMouseDown = mouseEvent.target.position ? mouseEvent.target.position.lineNumber : 0;
- }
- _onEditorMouseUp(mouseEvent) {
- const currentLineNumber = mouseEvent.target.position ? mouseEvent.target.position.lineNumber : 0;
- if (this._hasTriggerKeyOnMouseDown && this._lineNumberOnMouseDown && this._lineNumberOnMouseDown === currentLineNumber) {
- this._onExecute.fire(mouseEvent);
- }
- }
- _onEditorKeyDown(e) {
- if (this._lastMouseMoveEvent
- && (e.keyCodeIsTriggerKey // User just pressed Ctrl/Cmd (normal goto definition)
- || (e.keyCodeIsSideBySideKey && e.hasTriggerModifier) // User pressed Ctrl/Cmd+Alt (goto definition to the side)
- )) {
- this._onMouseMoveOrRelevantKeyDown.fire([this._lastMouseMoveEvent, e]);
- }
- else if (e.hasTriggerModifier) {
- this._onCancel.fire(); // remove decorations if user holds another key with ctrl/cmd to prevent accident goto declaration
- }
- }
- _onEditorKeyUp(e) {
- if (e.keyCodeIsTriggerKey) {
- this._onCancel.fire();
- }
- }
- _resetHandler() {
- this._lastMouseMoveEvent = null;
- this._hasTriggerKeyOnMouseDown = false;
- this._onCancel.fire();
- }
- }
|