Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Remove Brackets Command #160270

Merged
merged 11 commits into from
Mar 3, 2023
Merged
46 changes: 46 additions & 0 deletions src/vs/editor/contrib/bracketMatching/browser/bracketMatching.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,25 @@ class SelectToBracketAction extends EditorAction {
BracketMatchingController.get(editor)?.selectToBracket(selectBrackets);
}
}
class RemoveBracketsAction extends EditorAction {
constructor() {
super({
id: 'editor.action.removeBrackets',
label: nls.localize('smartSelect.removeBrackets', "Remove Brackets"),
alias: 'Remove Brackets',
precondition: undefined,
kbOpts: {
kbExpr: EditorContextKeys.editorTextFocus,
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Backspace,
weight: KeybindingWeight.EditorContrib
}
});
}

public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
BracketMatchingController.get(editor)?.removeBrackets(this.id);
}
}

type Brackets = [Range, Range];

Expand Down Expand Up @@ -251,6 +270,32 @@ export class BracketMatchingController extends Disposable implements IEditorCont
this._editor.revealRange(newSelections[0]);
}
}
public removeBrackets(editSource?: string): void {
if (!this._editor.hasModel()) {
return;
}

const model = this._editor.getModel();
this._editor.getSelections().forEach((selection) => {
const position = selection.getPosition();

let brackets = model.bracketPairs.matchBracket(position);
if (!brackets) {
brackets = model.bracketPairs.findEnclosingBrackets(position);
}
if (brackets) {
this._editor.pushUndoStop();
this._editor.executeEdits(
editSource,
[
{ range: brackets[0], text: '' },
{ range: brackets[1], text: '' }
]
);
this._editor.pushUndoStop();
}
});
}

private static readonly _DECORATION_OPTIONS_WITH_OVERVIEW_RULER = ModelDecorationOptions.register({
description: 'bracket-match-overview',
Expand Down Expand Up @@ -359,6 +404,7 @@ export class BracketMatchingController extends Disposable implements IEditorCont
registerEditorContribution(BracketMatchingController.ID, BracketMatchingController, EditorContributionInstantiation.AfterFirstRender);
registerEditorAction(SelectToBracketAction);
registerEditorAction(JumpToBracketAction);
registerEditorAction(RemoveBracketsAction);

// Go to menu
MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,27 @@ suite('bracket matching', () => {
new Selection(1, 19, 1, 16)
]);
});

test('Removes brackets', () => {
const editor = createCodeEditorWithBrackets('var x = (3 + (5-7)); y();');
const bracketMatchingController = disposables.add(editor.registerAndInstantiateContribution(BracketMatchingController.ID, BracketMatchingController));
function removeBrackets() {
bracketMatchingController.removeBrackets();
}

// position before the bracket
editor.setPosition(new Position(1, 9));
removeBrackets();
assert.deepStrictEqual(editor.getModel().getValue(), 'var x = 3 + (5-7); y();');
editor.getModel().setValue('var x = (3 + (5-7)); y();');

// position between brackets
editor.setPosition(new Position(1, 16));
removeBrackets();
assert.deepStrictEqual(editor.getModel().getValue(), 'var x = (3 + 5-7); y();');
removeBrackets();
assert.deepStrictEqual(editor.getModel().getValue(), 'var x = 3 + 5-7; y();');
removeBrackets();
assert.deepStrictEqual(editor.getModel().getValue(), 'var x = 3 + 5-7; y();');
});
});