src/vs/editor/contrib/suggest/suggestModel.ts/SuggestModel/_onCursorChange
class SuggestModel:	private _onCursorChange(e: ICursorSelectionChangedEvent): void {

		if (!this._editor.hasModel()) {
			return;
		}

		const model = this._editor.getModel();
		const prevSelection = this._currentSelection;
		this._currentSelection = this._editor.getSelection();

		if (!e.selection.isEmpty()
			|| (e.reason !== CursorChangeReason.NotSet && e.reason !== CursorChangeReason.Explicit)
			|| (e.source !== 'keyboard' && e.source !== 'deleteLeft')
		) {
			// Early exit if nothing needs to be done!
			// Leave some form of early exit check here if you wish to continue being a cursor position change listener ;)
			this.cancel();
			return;
		}

		if (!CompletionProviderRegistry.has(model)) {
			return;
		}

		if (this._state === State.Idle && e.reason === CursorChangeReason.NotSet) {

			if (this._editor.getOption(EditorOption.quickSuggestions) === false) {
				// not enabled
				return;
			}

			if (!prevSelection.containsRange(this._currentSelection) && !prevSelection.getEndPosition().isBeforeOrEqual(this._currentSelection.getPosition())) {
				// cursor didn't move RIGHT
				return;
			}

			if (this._editor.getOption(EditorOption.suggest).snippetsPreventQuickSuggestions && SnippetController2.get(this._editor).isInSnippet()) {
				// no quick suggestion when in snippet mode
				return;
			}

			this.cancel();

			this._triggerQuickSuggest.cancelAndSet(() => {
				if (this._state !== State.Idle) {
					return;
				}
				if (!LineContext.shouldAutoTrigger(this._editor)) {
					return;
				}
				if (!this._editor.hasModel()) {
					return;
				}
				const model = this._editor.getModel();
				const pos = this._editor.getPosition();
				// validate enabled now
				const quickSuggestions = this._editor.getOption(EditorOption.quickSuggestions);
				if (quickSuggestions === false) {
					return;
				} else if (quickSuggestions === true) {
					// all good
				} else {
					// Check the type of the token that triggered this
					model.tokenizeIfCheap(pos.lineNumber);
					const lineTokens = model.getLineTokens(pos.lineNumber);
					const tokenType = lineTokens.getStandardTokenType(lineTokens.findTokenIndexAtOffset(Math.max(pos.column - 1 - 1, 0)));
					const inValidScope = quickSuggestions.other && tokenType === StandardTokenType.Other
						|| quickSuggestions.comments && tokenType === StandardTokenType.Comment
						|| quickSuggestions.strings && tokenType === StandardTokenType.String;

					if (!inValidScope) {
						return;
					}
				}

				if (shouldPreventQuickSuggest(this._contextKeyService, this._configurationService)) {
					// do not trigger quick suggestions if inline suggestions are shown
					return;
				}

				// we made it till here -> trigger now
				this.trigger({ auto: true, shy: false });

			}, this._quickSuggestDelay);


		} else if (this._state !== State.Idle && e.reason === CursorChangeReason.Explicit) {
			// suggest is active and something like cursor keys are used to move
			// the cursor. this means we can refilter at the new position
			this._refilterCompletionItems();
		}
	}