src/vs/editor/common/core/wordHelper.ts/getWordAtText
export function getWordAtText(column: number, wordDefinition: RegExp, text: string, textOffset: number, config?: IGetWordAtTextConfig): IWordAtPosition | null {

	if (!config) {
		config = Iterable.first(_defaultConfig)!;
	}

	if (text.length > config.maxLen) {
		// don't throw strings that long at the regexp
		// but use a sub-string in which a word must occur
		let start = column - config.maxLen / 2;
		if (start < 0) {
			start = 0;
		} else {
			textOffset += start;
		}
		text = text.substring(start, column + config.maxLen / 2);
		return getWordAtText(column, wordDefinition, text, textOffset, config);
	}

	const t1 = Date.now();
	const pos = column - 1 - textOffset;

	let prevRegexIndex = -1;
	let match: RegExpMatchArray | null = null;

	for (let i = 1; ; i++) {
		// check time budget
		if (Date.now() - t1 >= config.timeBudget) {
			break;
		}

		// reset the index at which the regexp should start matching, also know where it
		// should stop so that subsequent search don't repeat previous searches
		const regexIndex = pos - config.windowSize * i;
		wordDefinition.lastIndex = Math.max(0, regexIndex);
		const thisMatch = _findRegexMatchEnclosingPosition(wordDefinition, text, pos, prevRegexIndex);

		if (!thisMatch && match) {
			// stop: we have something
			break;
		}

		match = thisMatch;

		// stop: searched at start
		if (regexIndex <= 0) {
			break;
		}
		prevRegexIndex = regexIndex;
	}

	if (match) {
		const result = {
			word: match[0],
			startColumn: textOffset + 1 + match.index!,
			endColumn: textOffset + 1 + match.index! + match[0].length
		};
		wordDefinition.lastIndex = 0;
		return result;
	}

	return null;
}