mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-20 12:00:24 -04:00
88 lines
3.0 KiB
TypeScript
88 lines
3.0 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import { SelectionRangeProvider, SelectionRange } from 'vs/editor/common/modes';
|
|
import { ITextModel } from 'vs/editor/common/model';
|
|
import { Position } from 'vs/editor/common/core/position';
|
|
import { Range } from 'vs/editor/common/core/range';
|
|
import { CharCode } from 'vs/base/common/charCode';
|
|
import { isUpperAsciiLetter, isLowerAsciiLetter } from 'vs/base/common/strings';
|
|
|
|
export class WordSelectionRangeProvider implements SelectionRangeProvider {
|
|
|
|
provideSelectionRanges(model: ITextModel, positions: Position[]): SelectionRange[][] {
|
|
const result: SelectionRange[][] = [];
|
|
for (const position of positions) {
|
|
const bucket: SelectionRange[] = [];
|
|
result.push(bucket);
|
|
this._addInWordRanges(bucket, model, position);
|
|
this._addWordRanges(bucket, model, position);
|
|
this._addWhitespaceLine(bucket, model, position);
|
|
bucket.push({ range: model.getFullModelRange() });
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private _addInWordRanges(bucket: SelectionRange[], model: ITextModel, pos: Position): void {
|
|
const obj = model.getWordAtPosition(pos);
|
|
if (!obj) {
|
|
return;
|
|
}
|
|
|
|
let { word, startColumn } = obj;
|
|
let offset = pos.column - startColumn;
|
|
let start = offset;
|
|
let end = offset;
|
|
let lastCh: number = 0;
|
|
|
|
// LEFT anchor (start)
|
|
for (; start >= 0; start--) {
|
|
let ch = word.charCodeAt(start);
|
|
if ((start !== offset) && (ch === CharCode.Underline || ch === CharCode.Dash)) {
|
|
// foo-bar OR foo_bar
|
|
break;
|
|
} else if (isLowerAsciiLetter(ch) && isUpperAsciiLetter(lastCh)) {
|
|
// fooBar
|
|
break;
|
|
}
|
|
lastCh = ch;
|
|
}
|
|
start += 1;
|
|
|
|
// RIGHT anchor (end)
|
|
for (; end < word.length; end++) {
|
|
let ch = word.charCodeAt(end);
|
|
if (isUpperAsciiLetter(ch) && isLowerAsciiLetter(lastCh)) {
|
|
// fooBar
|
|
break;
|
|
} else if (ch === CharCode.Underline || ch === CharCode.Dash) {
|
|
// foo-bar OR foo_bar
|
|
break;
|
|
}
|
|
lastCh = ch;
|
|
}
|
|
|
|
if (start < end) {
|
|
bucket.push({ range: new Range(pos.lineNumber, startColumn + start, pos.lineNumber, startColumn + end) });
|
|
}
|
|
}
|
|
|
|
private _addWordRanges(bucket: SelectionRange[], model: ITextModel, pos: Position): void {
|
|
const word = model.getWordAtPosition(pos);
|
|
if (word) {
|
|
bucket.push({ range: new Range(pos.lineNumber, word.startColumn, pos.lineNumber, word.endColumn) });
|
|
}
|
|
}
|
|
|
|
private _addWhitespaceLine(bucket: SelectionRange[], model: ITextModel, pos: Position): void {
|
|
if (model.getLineLength(pos.lineNumber) > 0
|
|
&& model.getLineFirstNonWhitespaceColumn(pos.lineNumber) === 0
|
|
&& model.getLineLastNonWhitespaceColumn(pos.lineNumber) === 0
|
|
) {
|
|
bucket.push({ range: new Range(pos.lineNumber, 1, pos.lineNumber, model.getLineMaxColumn(pos.lineNumber)) });
|
|
}
|
|
}
|
|
}
|