提交 eedf704b 编写于 作者: J Johannes Rieken 提交者: meganrogge

add config option to disable whitespace select

上级 68da44da
......@@ -23,6 +23,9 @@ import { WordSelectionRangeProvider } from 'vs/editor/contrib/smartSelect/wordSe
import { BracketSelectionRangeProvider } from 'vs/editor/contrib/smartSelect/bracketSelections';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { onUnexpectedExternalError } from 'vs/base/common/errors';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfigurationService';
import { ConfigurationScope, Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
import { Registry } from 'vs/platform/registry/common/platform';
class SelectionRanges {
......@@ -59,7 +62,10 @@ class SmartSelectController implements IEditorContribution {
private _selectionListener?: IDisposable;
private _ignoreSelection: boolean = false;
constructor(editor: ICodeEditor) {
constructor(
editor: ICodeEditor,
@ITextResourceConfigurationService private readonly _configService: ITextResourceConfigurationService,
) {
this._editor = editor;
}
......@@ -83,7 +89,10 @@ class SmartSelectController implements IEditorContribution {
let promise: Promise<void> = Promise.resolve(undefined);
if (!this._state) {
promise = provideSelectionRanges(model, selections.map(s => s.getPosition()), CancellationToken.None).then(ranges => {
const selectLeadingAndTrailingWhitespace = this._configService.getValue<boolean>(model.uri, 'editor.smartSelect.selectLeadingAndTrailingWhitespace') ?? true;
promise = provideSelectionRanges(model, selections.map(s => s.getPosition()), { selectLeadingAndTrailingWhitespace }, CancellationToken.None).then(ranges => {
if (!arrays.isNonEmptyArray(ranges) || ranges.length !== selections.length) {
// invalid result
return;
......@@ -177,6 +186,21 @@ class GrowSelectionAction extends AbstractSmartSelect {
}
}
//todo@jrieken use proper editor config instead. however, to keep the number
// of changes low use the quick config definition
Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfiguration({
id: 'editor',
properties: {
'editor.smartSelect.selectLeadingAndTrailingWhitespace': {
scope: ConfigurationScope.LANGUAGE_OVERRIDABLE,
description: nls.localize('selectLeadingAndTrailingWhitespace', "Weather leading and trailing whitespace should always be selected."),
default: true,
type: 'boolean'
}
}
});
// renamed command id
CommandsRegistry.registerCommandAlias('editor.action.smartSelect.grow', 'editor.action.smartSelect.expand');
......@@ -213,7 +237,11 @@ registerEditorAction(ShrinkSelectionAction);
// word selection
modes.SelectionRangeRegistry.register('*', new WordSelectionRangeProvider());
export function provideSelectionRanges(model: ITextModel, positions: Position[], token: CancellationToken): Promise<Range[][]> {
export interface SelectionRangesOptions {
selectLeadingAndTrailingWhitespace: boolean
}
export function provideSelectionRanges(model: ITextModel, positions: Position[], options: SelectionRangesOptions, token: CancellationToken): Promise<Range[][]> {
const providers = modes.SelectionRangeRegistry.all(model);
......@@ -277,6 +305,10 @@ export function provideSelectionRanges(model: ITextModel, positions: Position[],
}
}
if (!options.selectLeadingAndTrailingWhitespace) {
return oneRanges;
}
// add ranges that expand trivia at line starts and ends whenever a range
// wraps onto the a new line
let oneRangesWithTrivia: Range[] = [oneRanges[0]];
......@@ -304,5 +336,5 @@ export function provideSelectionRanges(model: ITextModel, positions: Position[],
registerModelCommand('_executeSelectionRangeProvider', function (model, ...args) {
const [positions] = args;
return provideSelectionRanges(model, positions, CancellationToken.None);
return provideSelectionRanges(model, positions, { selectLeadingAndTrailingWhitespace: true }, CancellationToken.None);
});
......@@ -60,10 +60,10 @@ suite('SmartSelect', () => {
mode.dispose();
});
async function assertGetRangesToPosition(text: string[], lineNumber: number, column: number, ranges: Range[]): Promise<void> {
async function assertGetRangesToPosition(text: string[], lineNumber: number, column: number, ranges: Range[], selectLeadingAndTrailingWhitespace = true): Promise<void> {
let uri = URI.file('test.js');
let model = modelService.createModel(text.join('\n'), new StaticLanguageSelector(mode.getLanguageIdentifier()), uri);
let [actual] = await provideSelectionRanges(model, [new Position(lineNumber, column)], CancellationToken.None);
let [actual] = await provideSelectionRanges(model, [new Position(lineNumber, column)], { selectLeadingAndTrailingWhitespace }, CancellationToken.None);
let actualStr = actual!.map(r => new Range(r.startLineNumber, r.startColumn, r.endLineNumber, r.endColumn).toString());
let desiredStr = ranges.reverse().map(r => String(r));
......@@ -97,6 +97,28 @@ suite('SmartSelect', () => {
]);
});
test('config: selectLeadingAndTrailingWhitespace', async () => {
await assertGetRangesToPosition([
'aaa',
'\tbbb',
''
], 2, 3, [
new Range(1, 1, 3, 1), // all
new Range(2, 1, 2, 5), // line w/ triva
new Range(2, 2, 2, 5), // bbb
], true);
await assertGetRangesToPosition([
'aaa',
'\tbbb',
''
], 2, 3, [
new Range(1, 1, 3, 1), // all
new Range(2, 2, 2, 5), // () inside
], false);
});
test('getRangesToPosition #56886. Skip empty lines correctly.', () => {
return assertGetRangesToPosition([
......
......@@ -1170,7 +1170,7 @@ suite('ExtHostLanguageFeatures', function () {
await rpcProtocol.sync();
provideSelectionRanges(model, [new Position(1, 17)], CancellationToken.None).then(ranges => {
provideSelectionRanges(model, [new Position(1, 17)], { selectLeadingAndTrailingWhitespace: true }, CancellationToken.None).then(ranges => {
assert.equal(ranges.length, 1);
assert.ok(ranges[0].length >= 2);
});
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册