UNPKG

monaco-editor

Version:
88 lines (85 loc) 3.34 kB
import { safeIntl } from '../../../base/common/date.js'; import { LRUCache } from '../../../base/common/map.js'; import { CharacterClassifier } from './characterClassifier.js'; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ class WordCharacterClassifier extends CharacterClassifier { constructor(wordSeparators, intlSegmenterLocales) { super(0 /* WordCharacterClass.Regular */); this._segmenter = null; this._cachedLine = null; this._cachedSegments = []; this.intlSegmenterLocales = intlSegmenterLocales; if (this.intlSegmenterLocales.length > 0) { this._segmenter = safeIntl.Segmenter(this.intlSegmenterLocales, { granularity: 'word' }); } else { this._segmenter = null; } for (let i = 0, len = wordSeparators.length; i < len; i++) { this.set(wordSeparators.charCodeAt(i), 2 /* WordCharacterClass.WordSeparator */); } this.set(32 /* CharCode.Space */, 1 /* WordCharacterClass.Whitespace */); this.set(9 /* CharCode.Tab */, 1 /* WordCharacterClass.Whitespace */); } findPrevIntlWordBeforeOrAtOffset(line, offset) { let candidate = null; for (const segment of this._getIntlSegmenterWordsOnLine(line)) { if (segment.index > offset) { break; } candidate = segment; } return candidate; } findNextIntlWordAtOrAfterOffset(lineContent, offset) { for (const segment of this._getIntlSegmenterWordsOnLine(lineContent)) { if (segment.index < offset) { continue; } return segment; } return null; } _getIntlSegmenterWordsOnLine(line) { if (!this._segmenter) { return []; } // Check if the line has changed from the previous call if (this._cachedLine === line) { return this._cachedSegments; } // Update the cache with the new line this._cachedLine = line; this._cachedSegments = this._filterWordSegments(this._segmenter.value.segment(line)); return this._cachedSegments; } _filterWordSegments(segments) { const result = []; for (const segment of segments) { if (this._isWordLike(segment)) { result.push(segment); } } return result; } _isWordLike(segment) { if (segment.isWordLike) { return true; } return false; } } const wordClassifierCache = new LRUCache(10); function getMapForWordSeparators(wordSeparators, intlSegmenterLocales) { const key = `${wordSeparators}/${intlSegmenterLocales.join(',')}`; let result = wordClassifierCache.get(key); if (!result) { result = new WordCharacterClassifier(wordSeparators, intlSegmenterLocales); wordClassifierCache.set(key, result); } return result; } export { WordCharacterClassifier, getMapForWordSeparators };