Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
48ea4db
Unit test toggleGitPanelFocus()
smashwilson Dec 9, 2016
c90e8b6
Focus, blur, and toggle GitPanel
smashwilson Dec 12, 2016
7537c4b
Keymap for git panel focus and visibility
smashwilson Dec 12, 2016
cf40112
Recall and preserve focus within GitPanel
smashwilson Dec 13, 2016
b5daaf7
Swap ctrl-9 and ctrl-shift-9 <_< >_>
smashwilson Dec 13, 2016
eba5ce4
:hocho: openAndFocusGitPanel()
smashwilson Dec 13, 2016
c5da482
Bind event handling methods once
smashwilson Dec 13, 2016
5a0d10a
Blur GitPanel on core:cancel
smashwilson Dec 13, 2016
f9b3b9c
`panelRoot` is unnecessary
smashwilson Dec 13, 2016
063ec84
Refactor navigation tests into a describe()
smashwilson Dec 13, 2016
3574568
Fixture with files in each staging group
smashwilson Dec 13, 2016
0b5b45e
Advance selections in StagingView
smashwilson Dec 13, 2016
4f4d64b
Test activatePreviousList why not
smashwilson Dec 13, 2016
6cc1ef5
Unit test cycling among lists and editor
smashwilson Dec 13, 2016
445d91d
Use onFocusNext to advance list focus
smashwilson Dec 13, 2016
80473a3
.focus() and .isFocused() methods for CommitView
smashwilson Dec 13, 2016
f8be65d
Rename the focus event to be git-specific
smashwilson Dec 13, 2016
54b369e
Tiny typo tweak
smashwilson Dec 13, 2016
3cbf1ee
Test and implement activateLastSelection()
smashwilson Dec 13, 2016
2455e68
Select the final item of the final nonempty list
smashwilson Dec 13, 2016
d08a922
Retreat focus through GitPanel elements
smashwilson Dec 13, 2016
db52f2d
Shift-tab in the commit editor retreats focus
smashwilson Dec 14, 2016
dd69b04
Change status from select(Next|Previous)Item()
smashwilson Dec 14, 2016
7f0c556
Fire a prop callback when selecting past end
smashwilson Dec 14, 2016
254323a
Pass commandRegistry into StagingView
smashwilson Dec 14, 2016
c9dc86b
Down arrow moves from StagingView to CommitView
smashwilson Dec 14, 2016
21f26db
Fire a callback on move-up on the first commit message line
smashwilson Dec 14, 2016
c4fce35
Move focus to StagingView from CommitView on :arrow_up:
smashwilson Dec 14, 2016
6d7c8da
:fire: console debugging lines
smashwilson Dec 14, 2016
a544c18
Always pass a CommandRegistry to StagingView
smashwilson Dec 14, 2016
60166a3
Use core:focus-(next|previous) instead of bespoke events
smashwilson Dec 14, 2016
23aba66
StagingView callbacks for "diveIn" actions
smashwilson Dec 14, 2016
3c81234
Ambient typo fix
smashwilson Dec 14, 2016
6eec7d7
Show and focus the FilePatchView
smashwilson Dec 14, 2016
01868ff
Show and focus a merge conflict file
smashwilson Dec 14, 2016
61368d0
Correct fake parameter in spec description
smashwilson Dec 14, 2016
3e25a4c
Pass staging status to diveIntoFilePatch callback
smashwilson Dec 14, 2016
be80549
Whitespace for :eyeglasses:
smashwilson Dec 14, 2016
96958c5
Accept a CommandRegistry from props
smashwilson Dec 14, 2016
a76e974
Pass CommandRegistry through FilePatchController
smashwilson Dec 14, 2016
c92d797
FilePatchView calls a callback on core:move-right
smashwilson Dec 14, 2016
87507d1
Left a .only in the tests
smashwilson Dec 14, 2016
dcbbb5d
Support didSurfaceFile at the FilePatchController level
smashwilson Dec 14, 2016
2e298ac
We'll need the staging status as well
smashwilson Dec 14, 2016
6ab587c
Select an item within the StagingView
smashwilson Dec 14, 2016
0f1ef6c
Link FilePatchView surface events to the GitPanel
smashwilson Dec 14, 2016
a466ae2
Keymap resolver prefers `ctrl-(`
smashwilson Dec 14, 2016
1ca4dd9
:hocho: debugging artifacts
smashwilson Dec 14, 2016
c88e97d
Use `tool-panel:unfocus` instead of `core:cancel`
smashwilson Dec 14, 2016
c32165d
Merge remote-tracking branch 'origin/master' into aw-keyboard-shortcuts
kuychaco Dec 16, 2016
831cc60
Fix tests broken by merge
kuychaco Dec 16, 2016
91cb9ac
Stub focusGitPanel() and gitPanelHasFocus()
smashwilson Dec 16, 2016
910f9b6
Pass didMoveUpOnFirstLine callback through CommitViewController
smashwilson Dec 16, 2016
04e2d21
Unnecessary softcoding--
smashwilson Dec 16, 2016
9d9fc27
Remove more unnecessary guard clauses
smashwilson Dec 16, 2016
81d6fa1
Leave a FIXME for `atom.views` reference
smashwilson Dec 16, 2016
0ddfd4e
Rename GitPanelView handler methods
smashwilson Dec 16, 2016
66df825
Rename more GitPanelView handler methods
smashwilson Dec 16, 2016
d182619
My placeholder was showing
smashwilson Dec 16, 2016
62dc539
Remove an unnecessary Promise
smashwilson Dec 16, 2016
f62d9e0
Rename focusOnStagingItem() to focusAndSelectStagingItem()
smashwilson Dec 16, 2016
4429cac
:hocho: unnecessary `etch.update(this)` call
smashwilson Dec 16, 2016
2926acb
Use a plain for loop instead of for ... of
smashwilson Dec 16, 2016
7214862
Use clearer temporary variable names
smashwilson Dec 16, 2016
9e83c10
`each` :point_right: `item`
smashwilson Dec 16, 2016
e7dc708
Reconstruct repo-each-staging-group with better filenames
smashwilson Dec 16, 2016
4801d79
Use the new-and-improved test fixture filenames
smashwilson Dec 16, 2016
7bfb154
Improve doctored filenames in test case
smashwilson Dec 16, 2016
454e567
Remove specs for `up` and `down` navigation
smashwilson Dec 16, 2016
8c115bf
Remove `up` and `down` navigation between StagingView and CommitView
smashwilson Dec 16, 2016
9663341
Destroy atomEnvironments created in tests
smashwilson Dec 16, 2016
b1ecf84
Change spec name to match actual behavior
smashwilson Dec 16, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions keymaps/git.cson
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
'.platform-darwin':
'cmd-shift-c': 'github:toggle-git-panel'

'.platform-win32, .platform-linux':
'alt-shift-c': 'github:toggle-git-panel'
'.workspace':
'ctrl-9': 'github:toggle-git-panel'
'ctrl-(': 'github:toggle-git-panel-focus' # ctrl-shift-9

'.github-StagingView':
'left': 'github:focus-diff-view'
'tab': 'core:focus-next'
'shift-tab': 'core:focus-previous'

'.github-CommitView-editor atom-text-editor:not([mini])':
'cmd-enter': 'github:commit'
'ctrl-enter': 'github:commit'
'shift-tab': 'core:focus-previous'

'.github-FilePatchView':
'/': 'github:toggle-patch-selection-mode'
'tab': 'github:select-next-hunk'
'shift-tab': 'github:select-previous-hunk'
'right': 'github:focus-git-panel'
'right': 'core:move-right'

'.github-Prompt-input':
'enter': 'core:confirm'
'esc': 'core:cancel'
'esc': 'tool-panel:unfocus'
9 changes: 9 additions & 0 deletions lib/controllers/commit-view-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export default class CommitViewController {
isAmending={this.props.isAmending}
lastCommit={this.props.lastCommit}
onChangeMessage={this.handleMessageChange}
didMoveUpOnFirstLine={this.props.didMoveUpOnFirstLine}
/>
);
}
Expand All @@ -82,6 +83,14 @@ export default class CommitViewController {
etch.update(this);
}

focus() {
this.refs.commitView.focus();
}

isFocused() {
return this.refs.commitView.isFocused();
}

destroy() {
this.repoStateRegistry.save();
return etch.destroy(this);
Expand Down
9 changes: 9 additions & 0 deletions lib/controllers/file-patch-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default class FilePatchController {

this.attemptHunkStageOperation = this.attemptHunkStageOperation.bind(this);
this.attemptLineStageOperation = this.attemptLineStageOperation.bind(this);
this.didSurfaceFile = this.didSurfaceFile.bind(this);

etch.initialize(this);
}
Expand Down Expand Up @@ -44,7 +45,9 @@ export default class FilePatchController {
<div className="github-PaneView pane-item">
<FilePatchView
ref="filePatchView"
commandRegistry={this.props.commandRegistry}
attemptLineStageOperation={this.attemptLineStageOperation}
didSurfaceFile={this.didSurfaceFile}
attemptHunkStageOperation={this.attemptHunkStageOperation}
hunks={hunks}
stagingStatus={this.props.stagingStatus}
Expand Down Expand Up @@ -152,6 +155,12 @@ export default class FilePatchController {
return this.emitter.on('did-destroy', callback);
}

didSurfaceFile() {
if (this.props.didSurfaceFile) {
this.props.didSurfaceFile(this.props.filePatch.getPath(), this.props.stagingStatus);
}
}

didUpdateFilePatch() {
// FilePatch was mutated so all we need to do is re-render
return etch.update(this);
Expand Down
50 changes: 39 additions & 11 deletions lib/controllers/git-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,22 @@ export default class GitController extends React.Component {
});

this.showFilePatchForPath = this.showFilePatchForPath.bind(this);
this.diveIntoFilePatchForPath = this.diveIntoFilePatchForPath.bind(this);
this.surfaceFromFileAtPath = this.surfaceFromFileAtPath.bind(this);
this.showMergeConflictFileForPath = this.showMergeConflictFileForPath.bind(this);
this.diveIntoMergeConflictFileForPath = this.diveIntoMergeConflictFileForPath.bind(this);
this.didChangeAmending = this.didChangeAmending.bind(this);
this.onRepoRefresh = this.onRepoRefresh.bind(this);
this.toggleGitPanel = this.toggleGitPanel.bind(this);
this.openAndFocusGitPanel = this.openAndFocusGitPanel.bind(this);
this.toggleGitPanelFocus = this.toggleGitPanelFocus.bind(this);
this.focusFilePatchView = this.focusFilePatchView.bind(this);
this.focusGitPanel = this.focusGitPanel.bind(this);

this.subscriptions = new CompositeDisposable();
this.subscriptions.add(
props.commandRegistry.add('atom-workspace', {
'github:toggle-git-panel': this.toggleGitPanel.bind(this),
'github:focus-git-panel': this.openAndFocusGitPanel.bind(this),
'github:toggle-git-panel': this.toggleGitPanel,
'github:toggle-git-panel-focus': this.toggleGitPanelFocus,
}),
);

Expand Down Expand Up @@ -133,7 +137,9 @@ export default class GitController extends React.Component {
repository={this.props.repository}
isAmending={this.state.amending}
didSelectFilePath={this.showFilePatchForPath}
didDiveIntoFilePath={this.diveIntoFilePatchForPath}
didSelectMergeConflictFile={this.showMergeConflictFileForPath}
didDiveIntoMergeConflictPath={this.diveIntoMergeConflictFileForPath}
didChangeAmending={this.didChangeAmending}
focusFilePatchView={this.focusFilePatchView}
/>
Expand All @@ -152,9 +158,11 @@ export default class GitController extends React.Component {
<EtchWrapper ref={c => { this.filePatchController = c; }} reattachDomNode={false}>
<FilePatchController
repository={this.props.repository}
commandRegistry={this.props.commandRegistry}
filePatch={this.state.filePatch}
stagingStatus={this.state.stagingStatus}
onRepoRefresh={this.onRepoRefresh}
didSurfaceFile={this.surfaceFromFileAtPath}
/>
</EtchWrapper>
</PaneItem>
Expand Down Expand Up @@ -190,6 +198,17 @@ export default class GitController extends React.Component {
}
}

async diveIntoFilePatchForPath(filePath, stagingStatus, {amending} = {}) {
await this.showFilePatchForPath(filePath, stagingStatus, {activate: true, amending});
this.focusFilePatchView();
}

surfaceFromFileAtPath(filePath, stagingStatus) {
if (this.gitPanelController) {
this.gitPanelController.getWrappedComponent().focusAndSelectStagingItem(filePath, stagingStatus);
}
}

onRepoRefresh() {
return this.showFilePatchForPath(this.state.filePath, this.state.stagingStatus, {amending: this.state.amending});
}
Expand All @@ -204,6 +223,10 @@ export default class GitController extends React.Component {
}
}

diveIntoMergeConflictFileForPath(relativeFilePath) {
return this.showMergeConflictFileForPath(relativeFilePath, {focus: true});
}

didChangeAmending(isAmending) {
this.setState({amending: isAmending});
return this.showFilePatchForPath(this.state.filePath, this.state.stagingStatus, {amending: isAmending});
Expand All @@ -213,23 +236,28 @@ export default class GitController extends React.Component {
this.setState(state => ({gitPanelActive: !state.gitPanelActive}));
}

openAndFocusGitPanel() {
toggleGitPanelFocus() {
if (!this.state.gitPanelActive) {
this.setState({gitPanelActive: true}, () => this.focusGitPanel());
this.setState({gitPanelActive: true}, () => this.toggleGitPanelFocus());
return;
}

if (this.gitPanelHasFocus()) {
this.props.workspace.getActivePane().activate();
} else {
this.focusGitPanel();
}
}

focusGitPanel() {
if (this.gitPanelController) {
this.gitPanelController.getWrappedComponent().focus();
}
this.gitPanelController.getWrappedComponent().focus();
}

gitPanelHasFocus() {
return this.gitPanelController.getWrappedComponent().isFocused();
}

focusFilePatchView() {
if (this.filePatchController) {
this.filePatchController.getWrappedComponent().focus();
}
this.filePatchController.getWrappedComponent().focus();
}
}
14 changes: 11 additions & 3 deletions lib/controllers/git-panel-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ export default class GitPanelController {
commandRegistry={this.props.commandRegistry}
notificationManager={this.props.notificationManager}
didSelectFilePath={this.props.didSelectFilePath}
didDiveIntoFilePath={this.props.didDiveIntoFilePath}
didSelectMergeConflictFile={this.props.didSelectMergeConflictFile}
didDiveIntoMergeConflictPath={this.props.didDiveIntoMergeConflictPath}
focusFilePatchView={this.props.focusFilePatchView}
stageFilePatch={this.stageFilePatch}
unstageFilePatch={this.unstageFilePatch}
Expand Down Expand Up @@ -210,8 +212,14 @@ export default class GitPanelController {
}

focus() {
if (this.refs.gitPanel) {
this.refs.gitPanel.focus();
}
this.refs.gitPanel.focus();
}

focusAndSelectStagingItem(filePath, stagingStatus) {
return this.refs.gitPanel.focusAndSelectStagingItem(filePath, stagingStatus);
}

isFocused() {
return this.refs.gitPanel.isFocused();
}
}
15 changes: 14 additions & 1 deletion lib/views/commit-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,22 @@ const COMMIT_GRAMMAR_SCOPE = 'text.git-commit';
export default class CommitView {
constructor(props) {
this.props = props;

this.commit = this.commit.bind(this);
this.abortMerge = this.abortMerge.bind(this);
this.handleAmendBoxClick = this.handleAmendBoxClick.bind(this);
this.commit = this.commit.bind(this);
this.abortMerge = this.abortMerge.bind(this);
etch.initialize(this);

this.editor = this.refs.editor;
// FIXME Use props-injected view registry instead of the Atom global
this.editorElement = atom.views.getView(this.editor);
this.editor.setText(this.props.message || '');
this.subscriptions = new CompositeDisposable(
this.editor.onDidChange(() => this.props.onChangeMessage && this.props.onChangeMessage(this.editor.getText())),
this.editor.onDidChangeCursorPosition(() => { etch.update(this); }),
props.commandRegistry.add(this.element, {'github:commit': () => this.commit()}),
props.commandRegistry.add(this.element, {'github:commit': this.commit}),
);

const grammar = atom.grammars.grammarForScopeName(COMMIT_GRAMMAR_SCOPE);
Expand Down Expand Up @@ -146,4 +151,12 @@ export default class CommitView {
}
}
}

focus() {
this.editorElement.focus();
}

isFocused() {
return this.element === document.activeElement || this.element.contains(document.activeElement);
}
}
28 changes: 28 additions & 0 deletions lib/views/composite-list-selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,16 @@ export default class CompositeListSelection {
return false;
}

activateLastSelection() {
for (let i = this.selections.length - 1; i >= 0; i--) {
if (this.selections[i].getItems().length > 0) {
this.activeSelectionIndex = i;
return true;
}
}
return false;
}

selectItem(item, preserveTail = false) {
const selection = this.selectionForItem(item);
if (!selection) { throw new Error(`No item found: ${item}`); }
Expand Down Expand Up @@ -160,23 +170,41 @@ export default class CompositeListSelection {
if (!preserveTail && this.getActiveSelection().getHeadItem() === this.getActiveSelection().getLastItem()) {
if (this.activateNextSelection()) {
this.getActiveSelection().selectFirstItem();
return true;
} else {
this.getActiveSelection().selectLastItem();
return false;
}
} else {
this.getActiveSelection().selectNextItem(preserveTail);
return true;
}
}

selectPreviousItem(preserveTail = false) {
if (!preserveTail && this.getActiveSelection().getHeadItem() === this.getActiveSelection().getItems()[0]) {
if (this.activatePreviousSelection()) {
this.getActiveSelection().selectLastItem();
return true;
} else {
this.getActiveSelection().selectFirstItem();
return false;
}
} else {
this.getActiveSelection().selectPreviousItem(preserveTail);
return true;
}
}

findItem(predicate) {
for (let i = 0; i < this.selections.length; i++) {
const selection = this.selections[i];
const key = this.keysBySelection.get(selection);
const found = selection.getItems().find(item => predicate(item, key));
if (found !== undefined) {
return found;
}
}
return null;
}
}
15 changes: 12 additions & 3 deletions lib/views/file-patch-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ export default class FilePatchView {
this.props = props;
this.selection = new FilePatchSelection(this.props.hunks);
this.fontSize = atom.config.get('editor.fontSize');

this.mouseSelectionInProgress = false;

this.mousedownOnLine = this.mousedownOnLine.bind(this);
this.mousemoveOnLine = this.mousemoveOnLine.bind(this);
this.mouseup = this.mouseup.bind(this);

window.addEventListener('mouseup', this.mouseup);
this.disposables = new CompositeDisposable();
this.disposables.add(new Disposable(() => window.removeEventListener('mouseup', this.mouseup)));
Expand All @@ -27,11 +28,13 @@ export default class FilePatchView {
}));

etch.initialize(this);
this.disposables.add(atom.commands.add(this.element, {
'github:toggle-patch-selection-mode': this.togglePatchSelectionMode.bind(this),

this.disposables.add(this.props.commandRegistry.add(this.element, {
Copy link
Contributor

Choose a reason for hiding this comment

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

ooh good catch 👍

'github:toggle-patch-selection-mode': () => this.togglePatchSelectionMode(),
'core:confirm': () => this.didConfirm(),
'core:move-up': () => this.selectPrevious(),
'core:move-down': () => this.selectNext(),
'core:move-right': () => this.didMoveRight(),
'core:move-to-top': () => this.selectFirst(),
'core:move-to-bottom': () => this.selectLast(),
'core:select-up': () => this.selectToPrevious(),
Expand Down Expand Up @@ -205,6 +208,12 @@ export default class FilePatchView {
return this.props.attemptLineStageOperation(this.selection.getSelectedLines());
}

didMoveRight() {
if (this.props.didSurfaceFile) {
this.props.didSurfaceFile();
}
}

focus() {
this.element.focus();
}
Expand Down
Loading