Skip to content

Allow to filter keyBindings by 'Source'.#43393

Merged
sandy081 merged 13 commits intomicrosoft:masterfrom
shobhitchittora:keyBindingsEditor-filter-by-source
Mar 14, 2018
Merged

Allow to filter keyBindings by 'Source'.#43393
sandy081 merged 13 commits intomicrosoft:masterfrom
shobhitchittora:keyBindingsEditor-filter-by-source

Conversation

@shobhitchittora
Copy link
Contributor

@shobhitchittora shobhitchittora commented Feb 10, 2018

This adds a source filter to the Key Bindings Editor View.
Usage: source: user | source: default

Tasks -

  • source filter working
  • Tests passing
  • Update the test for the file changes

Closes: #43037

@sandy081
Copy link
Member

@shobhitchittora Changes look good. To discover this feature, How about having a context menu with Show Default Keybindings and Show User Keybindings actions?

@sandy081 sandy081 added the keybindings-editor Keybinding editor issues label Feb 14, 2018
@shobhitchittora
Copy link
Contributor Author

@sandy081 Why is the test failing in CI for windows ( /test.bat ) ? I cannot verify the same as my local is on mac.

About this -

To discover this feature, How about having a context menu with Show Default Keybindings and Show User Keybindings actions?

Observation - Currently in Keyboard Shortcuts Tab, when you click on keybindings.json, it open up two tabs - one is Default Keybindings and the other is keybindigs.json ( or user bindings ).

Clarification - on firing action from the context menu ( Show Default Keybindings or Show User Keybindings ) the user should be taken to the Keyboard Shortcuts Tab with the source: selected by default.

@shobhitchittora
Copy link
Contributor Author

@sandy081 Any comments on this ? 😇

@sandy081
Copy link
Member

@shobhitchittora I think we can provide these as secondary actions to the keybindings editor which will be shown as follows:

image

This can be done by implementing getSecondaryActions method in Keybindings editor.

Let me know if you need any help

@shobhitchittora
Copy link
Contributor Author

@sandy081 Thanks! This looks good. So on clicking on any of these actions, the corresponding filter is applied ?

@shobhitchittora
Copy link
Contributor Author

Also more questions -

  • How to create dropdown menus ?
  • How to add items / actions to the dropdown ?
  • Where to create the anchor for the dropdown ?

@sandy081
Copy link
Member

@shobhitchittora You just have to implement getSecondaryActions method in Keybindings Editor. An example here

@shobhitchittora shobhitchittora force-pushed the keyBindingsEditor-filter-by-source branch from 7bfcf57 to b31e4ab Compare March 2, 2018 16:36
1. Adds action constants in preferences.ts
2. Adds showUser and showDefault keybindings actions
3. Adds getSecondaryActions to register context menu actions
@shobhitchittora
Copy link
Contributor Author

@sandy081 I've added secondary actions and pushed tests too. Please have a look.

PS: Apologies for the delay. Was busy with work. 😇

@shobhitchittora
Copy link
Contributor Author

Ping @sandy081

@sandy081
Copy link
Member

sandy081 commented Mar 6, 2018

@shobhitchittora Provided some feedback otherwise it looks good. I guess, we can push this PR once requested changes are handled.

Thanks

@shobhitchittora
Copy link
Contributor Author

@sandy081 I don't see any comments here.

private keybindingFocusContextKey: IContextKey<boolean>;
private searchFocusContextKey: IContextKey<boolean>;
private sortByPrecedence: Checkbox;
private secondaryActions: IAction[];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable is not necessary

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

return focusedElement && focusedElement.templateId === KEYBINDING_ENTRY_TEMPLATE_ID ? <IKeybindingItemEntry>focusedElement : null;
}

setKeybindingSource(searchString: string): TPromise<any> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline this in the action

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return TPromise.as(null);
}

showDefaultKeyBindings(): IAction {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline the action

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

};
}

showUserKeyBindings(): IAction {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline the action

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done for both actions.

}

getSecondaryActions(): IAction[] {
if (!this.secondaryActions) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

storing in secondaryActions is not necessary. Its ok to create the array and return

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool. done.

this.keybindingMatches = keybindingItem.keybinding ? this.matchesKeybinding(keybindingItem.keybinding, searchValue, keybindingWords) : null;
}

private checkForSourceFilter(searchValue: string) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if the label of a command matches source: default? I would parse the search string here and return results based on the parsed value. If it is a source type filter then return corresponding entries otherwise do the existing filtering.

label: localize('showDefaultKeybindings', "Show Default Keybindings"),
enabled: true,
id: KEYBINDINGS_EDITOR_SHOW_DEFAULT_KEYBINDINGS,
run: () => this.setKeybindingSource('source: default')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use following format:

@source: default

This is consistent with filtering in Extensions viewlet

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to use @source:

@sandy081
Copy link
Member

sandy081 commented Mar 7, 2018

@shobhitchittora Sorry forgot to submit

sourceMatches: keybindingMatches.sourceMatches,
whenMatches: keybindingMatches.whenMatches
});
if (sourceFilterApplied) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Is there a better way to push results based on whether @source filter is applied or not?
  2. Can we move refactor it into on method which checks for respective matches and another one which creates the final result array?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shobhitchittora You can have two methods one for filtering based on source and the other does full text search and call either of them by checking the search text. It can look something like follows

if (/@source:/i.test(searchValue)) {
return this.filterBySource(searchValue);
}
return this.filterByText(searchValue);

@bpasero bpasero modified the milestones: February 2018, March 2018 Mar 8, 2018
1. filter By @source:
2. normal text filter
3. @source filter with quotes - @source: "user"
return keybindingItems.map(keybindingItem => ({ id: KeybindingsEditorModel.getId(keybindingItem), keybindingItem, templateId: KEYBINDING_ENTRY_TEMPLATE_ID }));
}

const result: IKeybindingItemEntry[] = [];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if you need this code any more because this is handled by fetchKeybindingItemsByText

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fetchKeybindingItemsByText is called conditionally when no @source: filter is applied.
Otherwise fetchKeybindingItemsBySource will be called.

if (this.isSourceFilterApplied(searchValue)) {
searchValue = this.getSourceFilterValue(searchValue);
searchValue = this.parseSearchValue(searchValue);
return this.fetchKeybindingItemsBySource(sortByPrecedence ? this._keybindingItemsSortedByPrecedence : this._keybindingItems, searchValue, this.quoteAtFirst(searchValue) && this.quoteAtLast(searchValue));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why you need compute quotes here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the same reasons as above.


if (this.isSourceFilterApplied(searchValue)) {
searchValue = this.getSourceFilterValue(searchValue);
searchValue = this.parseSearchValue(searchValue);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to parseSearchValue?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is added to handle the case with quotes and source filter is applied. --> @source: "user" / @source: "default"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shobhitchittora Lets make it simple and support only @source:user or @source:default. I do not think why we need to support quotes. This will make everything much simpler

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I probably over-complicated it, because I saw quotes were also supported. Will simplify it. 💪🏼

}

private filterBySource(keybindingItems: IKeybindingItem[], searchValue: string, completeMatch: boolean): IKeybindingItemEntry[] {
const result: IKeybindingItemEntry[] = [];
Copy link
Member

@sandy081 sandy081 Mar 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shobhitchittora I think we are very good with the changes except for changing filterBySource method a bit. Instead of delegating the filtering to KeybindingItemMatches lets filter keybindingItems by source directly and map them filtered results to IKeybindingItemEntry.

Sorry for providing more comments :(

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sandy081 Don't be sorry. I encourage comments / suggestions till it's the best. 😇

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@sandy081 sandy081 merged commit 4a5e48d into microsoft:master Mar 14, 2018
@sandy081
Copy link
Member

@shobhitchittora Thanks for the PR. Merged.

@github-actions github-actions bot locked and limited conversation to collaborators Mar 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

keybindings-editor Keybinding editor issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request - Keybindings Shortcuts - filter source:user

3 participants