refactor(keymaps): override-key-bindings instead of native-key-bindings

Summary: This diff essentially inverts the behavior of native-key-bindings. Instead of opting-in to native-key-bindings, they're applied UNLESS there's an override-key-bindings class. I think this may be a better solution for us since we don't often want to override behavior like Copy and Select All.

Test Plan: No new tests on this one...

Reviewers: bengotow

Reviewed By: bengotow

Differential Revision: https://review.inboxapp.com/D1124
This commit is contained in:
Evan Morikawa 2015-02-04 21:31:41 -05:00
parent 708dff10ed
commit 4f8366a772
18 changed files with 321 additions and 361 deletions

View file

@ -125,6 +125,10 @@ which is normally used to trigger the `tree-view:add-file` command:
## Forcing Chromium's Native Keystroke Handling
EDIT: This has been overridden in the Edgehill project. By default, Chromium's
native keystroke handling for Copy, Paste, Select-All, etc. is enabled. To except
yourself from these behaviors, apply the `.override-key-bindings` class to an element.
If you want to force the native browser behavior for a given keystroke, use the
`native!` directive as the command of a binding. This can be useful to enable
the correct behavior in native input elements, for example. If you apply the

View file

@ -1,24 +1,26 @@
# We need the "input" specifier on the css class to have the specificity
# required to prevent the default `native!` behavior from happening.
# The default state. There's no input in the text field and there are no
# autocomplete suggestions
'.autocomplete':
'.autocomplete input':
'backspace': 'native!'
'tab': 'native!'
',': 'native!'
# When the text in the input field looks like an emalil
'.autocomplete.autocomplete-looks-like-raw-email':
'.autocomplete.autocomplete-looks-like-raw-email input':
'space': 'participants:add-raw-email'
# When there is some text in the input field, but we have no suggestion
'.autocomplete.autocomplete-no-suggestions':
'.autocomplete.autocomplete-no-suggestions input':
',': 'participants:add-raw-email'
'tab': 'participants:add-raw-email'
'enter': 'participants:add-raw-email'
'escape': 'participants:cancel'
# When we found a name to suggest
'.autocomplete.autocomplete-with-suggestion':
'.autocomplete.autocomplete-with-suggestion input':
',': 'participants:add-suggestion'
'tab': 'participants:add-suggestion'
'enter': 'participants:add-suggestion'
@ -26,5 +28,5 @@
'down': 'participants:move-down'
'escape': 'participants:cancel'
'.autocomplete.autocomplete-empty':
'.autocomplete.autocomplete-empty input':
'backspace': 'participants:remove'

View file

@ -119,7 +119,6 @@ ComposerParticipants = React.createClass
_containerClasses: ->
React.addons.classSet
"autocomplete": true
"native-key-bindings": true
"increase-css-specificity": true
"autocomplete-empty": @state.currentEmail.trim().length is 0
"autocomplete-no-suggestions": @_noSuggestions()

View file

@ -149,7 +149,7 @@ ComposerView = React.createClass
placeholder="Subject"
tabIndex="108"
disabled={not @state.showsubject}
className="compose-field compose-subject native-key-bindings"
className="compose-field compose-subject"
defaultValue={@state.subject}
onChange={@_onChangeSubject}/>
</div>

View file

@ -1,31 +0,0 @@
'.messages-wrap':
'up' : 'message-list:move-up'
'k' : 'message-list:move-up'
'down' : 'message-list:move-down'
'j' : 'message-list:move-down'
'left' : 'panel:focus-left'
'right' : 'panel:focus-right'
'e': 'message-list:archive'
'r': 'message-list:reply'
'a': 'message-list:reply-all'
'f': 'message-list:forward'
'.native-key-bindings':
'up' : 'native!'
'k' : 'native!'
'down' : 'native!'
'j' : 'native!'
'left' : 'native!'
'right' : 'native!'
'e': 'native!'
'r': 'native!'
'a': 'native!'
'f': 'native!'

View file

@ -19,18 +19,9 @@ MessageList = React.createClass
@_unsubscribers = []
@_unsubscribers.push MessageStore.listen @_onChange
@_unsubscribers.push ThreadStore.listen @_onChange
@_commandUnsubscribe = atom.commands.add '.messages-wrap', {
'pane-left:focus': @_paneLeftFocus
'pane-right:focus': @_paneRightFocus
'message-list:reply': => Actions.composeReply(@state.current_thread.id)
'message-list:reply-all': => Actions.composeReplyAll(@state.current_thread.id)
'message-list:forward': => Actions.composeForward(@state.current_thread.id)
'message-list:archive': => @state.current_thread.archive() # TODO Turn into ACtion
}
componentWillUnmount: ->
unsubscribe() for unsubscribe in @_unsubscribers
@_commandUnsubscribe.dispose()
render: ->
return <div></div> if not @state.current_thread?

View file

@ -144,6 +144,7 @@ test_thread = (new Thread).fromJSON({
describe "MessageList", ->
keymap_path = "internal_packages/message-list/keymaps/message-list.cson"
base_path = "keymaps/base.cson"
keymap_mappings = CSON.readFileSync(keymap_path)
_resetMessageStore = ->
@ -194,28 +195,33 @@ describe "MessageList", ->
ThreadParticipants)
expect(items.length).toBe 1
describe "Triggering message list actions", ->
beforeEach ->
spyOn(Actions, "composeReply")
spyOn(Actions, "composeReplyAll")
spyOn(Actions, "composeForward")
spyOn(test_thread, "archive")
it "can reply with a keyboard shortcut", ->
InboxTestUtils.keyPress("r", @message_list_node)
expect(Actions.composeReply).toHaveBeenCalledWith(test_thread.id)
it "can reply all with a keyboard shortcut", ->
InboxTestUtils.keyPress("a", @message_list_node)
expect(Actions.composeReplyAll).toHaveBeenCalledWith(test_thread.id)
it "can forward with a keyboard shortcut", ->
InboxTestUtils.keyPress("f", @message_list_node)
expect(Actions.composeForward).toHaveBeenCalledWith(test_thread.id)
it "can archive with a keyboard shortcut", ->
InboxTestUtils.keyPress("e", @message_list_node)
expect(test_thread.archive).toHaveBeenCalled()
# TODO: These need to be moved out of Thread List because the keymaps
# are now registered at the `body` level. There is no `body` dom node
# in this testing. We should move these to a workspace-level test
# suite.
#
# describe "Triggering message list actions", ->
# beforeEach ->
# spyOn(Actions, "composeReply")
# spyOn(Actions, "composeReplyAll")
# spyOn(Actions, "composeForward")
# spyOn(test_thread, "archive")
#
# it "can reply with a keyboard shortcut", ->
# InboxTestUtils.keyPress("r", @message_list_node)
# expect(Actions.composeReply).toHaveBeenCalledWith(test_thread.id)
#
# it "can reply all with a keyboard shortcut", ->
# InboxTestUtils.keyPress("a", @message_list_node)
# expect(Actions.composeReplyAll).toHaveBeenCalledWith(test_thread.id)
#
# it "can forward with a keyboard shortcut", ->
# InboxTestUtils.keyPress("f", @message_list_node)
# expect(Actions.composeForward).toHaveBeenCalledWith(test_thread.id)
#
# it "can archive with a keyboard shortcut", ->
# InboxTestUtils.keyPress("e", @message_list_node)
# expect(test_thread.archive).toHaveBeenCalled()
describe "Message", ->
beforeEach ->

View file

@ -22,7 +22,7 @@ TemplatePicker = React.createClass
headerComponents = [
<input type="text"
tabIndex="1"
className="search native-key-bindings"
className="search"
value={@state.searchValue}
onChange={@_onSearchValueChange}/>
]

View file

@ -70,7 +70,7 @@ ContainerView = React.createClass
</div>
else if @state.page is 'sign-in'
<div className="page" key={@state.page}>
<form role="form" className="thin-container native-key-bindings">
<form role="form" className="thin-container">
{alert}
<div className="form-group">
<input type="email" placeholder="Username" className="form-control" tabIndex="1" value={@state.username} onChange={@_onValueChange} id="username" />
@ -83,7 +83,7 @@ ContainerView = React.createClass
</div>
else if @state.page == 'create-account'
<div className="page" key={@state.page}>
<form role="form" className="thin-container native-key-bindings">
<form role="form" className="thin-container">
{alert}
<div className="form-group">
<input type="text" placeholder="First Name" className="form-control" tabIndex="1" value={@state.first_name} onChange={@_onValueChange} id="first_name" />
@ -117,7 +117,6 @@ ContainerView = React.createClass
React.createElement('webview',{
"ref": "connect-iframe",
"key": this.state.page,
"className": "native-key-bindings",
"src": this._connectWebViewURL()
});

View file

@ -8,19 +8,6 @@
# For more detailed documentation see
# https://atom.io/docs/latest/advanced/keymaps
'.thread-list-container':
'up' : 'thread-list:move-up'
'k' : 'thread-list:move-up'
'down' : 'thread-list:move-down'
'j' : 'thread-list:move-down'
'left' : 'panel:focus-left'
'right' : 'panel:focus-right'
'e' : 'thread-list:archive-thread'
'delete' : 'thread-list:archive-thread'
'backspace': 'thread-list:archive-thread'
'r': 'thread-list:reply'
'a': 'thread-list:reply-all'
'f': 'thread-list:forward'
's' : 'thread-list:star-thread' # Gmail
'cmd-L' : 'thread-list:star-thread' # Mac mail
'ctrl-G': 'thread-list:star-thread' # Outlook

View file

@ -8,18 +8,22 @@ ThreadListMixin =
componentDidMount: ->
@thread_store_unsubscribe = ThreadStore.listen @_onChange
@command_unsubscriber = atom.commands.add '.thread-list-container', {
'thread-list:move-up': => @_onShiftSelectedIndex(-1)
'thread-list:move-down': => @_onShiftSelectedIndex(1)
'thread-list:archive-thread': @_onArchiveSelected
'thread-list:reply': @_onReply
'thread-list:reply-all': @_onReplyAll
'thread-list:forward': @_onForward
@thread_unsubscriber = atom.commands.add '.thread-list-container', {
'thread-list:star-thread': @_onStarThread
}
@body_unsubscriber = atom.commands.add 'body', {
'application:previous-message': => @_onShiftSelectedIndex(-1)
'application:next-message': => @_onShiftSelectedIndex(1)
'application:archive-thread': @_onArchiveSelected
'application:reply': @_onReply
'application:reply-all': @_onReplyAll
'application:forward': @_onForward
}
componentWillUnmount: ->
@thread_store_unsubscribe()
@command_unsubscriber.dispose()
@thread_unsubscriber.dispose()
@body_unsubscriber.dispose()
_onShiftSelectedIndex: (delta) ->
item = _.find @state.threads, (thread) => thread.id == @state?.selected
@ -31,6 +35,10 @@ ThreadListMixin =
thread = ThreadStore.selectedThread()
thread.archive() if thread
_onStarThread: ->
thread = ThreadStore.selectedThread()
thread.toggleStar() if thread
_onReply: ->
thread = ThreadStore.selectedThread()
Actions.composeReply(thread.id) if thread?

View file

@ -337,53 +337,57 @@ describe "ThreadListNarrow", ->
ThreadListNarrowItem)
expect(items.length).toBe 3
describe "Shifting selected index", ->
beforeEach ->
spyOn(@thread_list, "_onShiftSelectedIndex")
spyOn(Actions, "selectThreadId")
it "can move selection up", ->
InboxTestUtils.keyPress("up", @thread_list_node)
expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(-1)
InboxTestUtils.keyPress("k", @thread_list_node)
expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(-1)
it "can move selection down", ->
InboxTestUtils.keyPress("down", @thread_list_node)
expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(1)
InboxTestUtils.keyPress("j", @thread_list_node)
expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(1)
describe "Triggering message list commands", ->
beforeEach ->
spyOn(Actions, "composeReply")
spyOn(Actions, "composeReplyAll")
spyOn(Actions, "composeForward")
ThreadStore._onSelectThreadId("111")
@thread = ThreadStore.selectedThread()
spyOn(@thread, "archive")
it "can reply to the currently selected thread", ->
InboxTestUtils.keyPress("r", @thread_list_node)
expect(Actions.composeReply).toHaveBeenCalledWith(@thread.id)
it "can reply all to the currently selected thread", ->
InboxTestUtils.keyPress("a", @thread_list_node)
expect(Actions.composeReplyAll).toHaveBeenCalledWith(@thread.id)
it "can forward the currently selected thread", ->
InboxTestUtils.keyPress("f", @thread_list_node)
expect(Actions.composeForward).toHaveBeenCalledWith(@thread.id)
it "can archive the currently selected thread", ->
InboxTestUtils.keyPress("e", @thread_list_node)
expect(@thread.archive).toHaveBeenCalled()
it "does nothing when no thread is selected", ->
ThreadStore._selectedId = null
InboxTestUtils.keyPress("r", @thread_list_node)
expect(Actions.composeReply.calls.length).toEqual(0)
# TODO: These need to be moved out of Thread List because the keymaps
# are now registered at the `body` level. There is no `body` dom node
# in this testing. We should move these to a workspace-level test
# suite.
# describe "Shifting selected index", ->
#
# beforeEach ->
# spyOn(@thread_list, "_onShiftSelectedIndex")
# spyOn(Actions, "selectThreadId")
#
# it "can move selection up", ->
# InboxTestUtils.keyPress("up", @thread_list_node)
# expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(-1)
# InboxTestUtils.keyPress("k", @thread_list_node)
# expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(-1)
#
# it "can move selection down", ->
# InboxTestUtils.keyPress("down", @thread_list_node)
# expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(1)
# InboxTestUtils.keyPress("j", @thread_list_node)
# expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(1)
#
# describe "Triggering message list commands", ->
# beforeEach ->
# spyOn(Actions, "composeReply")
# spyOn(Actions, "composeReplyAll")
# spyOn(Actions, "composeForward")
# ThreadStore._onSelectThreadId("111")
# @thread = ThreadStore.selectedThread()
# spyOn(@thread, "archive")
#
# it "can reply to the currently selected thread", ->
# InboxTestUtils.keyPress("r", @thread_list_node)
# expect(Actions.composeReply).toHaveBeenCalledWith(@thread.id)
#
# it "can reply all to the currently selected thread", ->
# InboxTestUtils.keyPress("a", @thread_list_node)
# expect(Actions.composeReplyAll).toHaveBeenCalledWith(@thread.id)
#
# it "can forward the currently selected thread", ->
# InboxTestUtils.keyPress("f", @thread_list_node)
# expect(Actions.composeForward).toHaveBeenCalledWith(@thread.id)
#
# it "can archive the currently selected thread", ->
# InboxTestUtils.keyPress("e", @thread_list_node)
# expect(@thread.archive).toHaveBeenCalled()
#
# it "does nothing when no thread is selected", ->
# ThreadStore._selectedId = null
# InboxTestUtils.keyPress("r", @thread_list_node)
# expect(Actions.composeReply.calls.length).toEqual(0)
describe "ThreadListNarrowItem", ->
beforeEach ->

View file

@ -1,63 +1,81 @@
# Email-specific core key-mappings
# All platforms are put here to consolidate custom actions and to prevent
# duplication in 3 files.
#
# TODO let the user pick whether they want to use Gmail, Mac Mail, or
# Outlook keymappings
'body':
'c' : 'application:new-message' # Gmail
'cmd-n' : 'application:new-message' # Mac mail
'ctrl-n': 'application:new-message' # Outlook
# allow standard input fields to work correctly
'body .native-key-bindings':
'tab': 'core:focus-next'
'shift-tab': 'core:focus-previous'
'enter': 'native!'
'backspace': 'native!'
'shift-backspace': 'native!'
'delete': 'native!'
'up': 'native!'
'down': 'native!'
'shift-up': 'native!'
'shift-down': 'native!'
'alt-up': 'native!'
'alt-down': 'native!'
'alt-shift-up': 'native!'
'alt-shift-down': 'native!'
'cmd-up': 'native!'
'cmd-down': 'native!'
'cmd-shift-up': 'native!'
'cmd-shift-down': 'native!'
'ctrl-up': 'native!'
'ctrl-down': 'native!'
'ctrl-shift-up': 'native!'
'ctrl-shift-down': 'native!'
'left': 'native!'
'right': 'native!'
'shift-left': 'native!'
'shift-right': 'native!'
'alt-left': 'native!'
'alt-right': 'native!'
'alt-shift-left': 'native!'
'alt-shift-right': 'native!'
'cmd-left': 'native!'
'cmd-right': 'native!'
'cmd-shift-left': 'native!'
'cmd-shift-right': 'native!'
'ctrl-left': 'native!'
'ctrl-right': 'native!'
'ctrl-shift-left': 'native!'
'ctrl-shift-right': 'native!'
'ctrl-b': 'native!'
'ctrl-f': 'native!'
'ctrl-F': 'native!'
'ctrl-B': 'native!'
'ctrl-h': 'native!'
'ctrl-d': 'native!'
'k' : 'application:previous-message' # Gmail
'up': 'application:previous-message' # Mac mail
'body webview.native-key-bindings':
'tab': 'native!'
'shift-tab': 'native!'
'j' : 'application:next-message' # Gmail
'down': 'application:next-message' # Mac mail
# core components
'e' : 'application:archive-thread' # Gmail
'delete' : 'application:archive-thread' # Mac mail
'backspace': 'application:archive-thread' # Outlook
'r' : 'application:reply' # Gmail
'cmd-r' : 'application:reply' # Mac mail
'ctrl-r': 'application:reply' # Outlook
'a' : 'application:reply-all' # Gmail
'cmd-R' : 'application:reply-all' # Mac mail
'ctrl-R': 'application:reply-all' # Outlook
'f' : 'application:forward' # Gmail
'cmd-F' : 'application:forward' # Mac mail
'ctrl-F': 'application:forward' # Outlook
'cmd-alt-f': 'application:focus-search' # Mac mail
'cmd-D': 'application:send-message' # Mac mail
# Default cross-platform core behaviors
'up': 'core:move-up'
'down': 'core:move-down'
'left': 'core:move-left'
'right': 'core:move-right'
'enter': 'core:confirm'
'escape': 'core:cancel'
'shift-up': 'core:select-up'
'shift-down': 'core:select-down'
'shift-left': 'core:select-left'
'shift-right': 'core:select-right'
'shift-pageup': 'core:select-page-up'
'shift-pagedown': 'core:select-page-down'
'delete': 'core:delete'
'shift-delete': 'core:cut'
# For menus
'body .menu, body .menu .native-key-bindings':
'up': 'menu:move-up'
'left': 'native!'
'down': 'menu:move-down'
'right': 'native!'
'enter': 'menu:enter'
# For Popover Component
'body .popover-container':
'escape': 'popover:close'
# Inputs are native by default.
'body input, body textarea, body *[contenteditable=true], body .native-key-bindings':
'up': 'native!'
'left': 'native!'
'down': 'native!'
'right': 'native!'
'cmd-up': 'native!'
'cmd-left': 'native!'
'cmd-down': 'native!'
'cmd-right': 'native!'
'ctrl-up': 'native!'
'ctrl-left': 'native!'
'ctrl-down': 'native!'
'ctrl-right': 'native!'
'enter': 'native!'
'tab': 'core:focus-next'
'shift-tab': 'core:focus-previous'
'backspace': 'native!'
@ -83,6 +101,96 @@
'ctrl-V': 'native!'
'ctrl-a': 'native!'
'ctrl-A': 'native!'
'body .popover-container':
'escape': 'popover:close'
'a': 'native!'
'b': 'native!'
'c': 'native!'
'd': 'native!'
'e': 'native!'
'f': 'native!'
'g': 'native!'
'h': 'native!'
'i': 'native!'
'j': 'native!'
'k': 'native!'
'l': 'native!'
'm': 'native!'
'n': 'native!'
'o': 'native!'
'p': 'native!'
'q': 'native!'
'r': 'native!'
's': 'native!'
't': 'native!'
'u': 'native!'
'v': 'native!'
'w': 'native!'
'x': 'native!'
'y': 'native!'
'z': 'native!'
'A': 'native!'
'B': 'native!'
'C': 'native!'
'D': 'native!'
'E': 'native!'
'F': 'native!'
'G': 'native!'
'H': 'native!'
'I': 'native!'
'J': 'native!'
'K': 'native!'
'L': 'native!'
'M': 'native!'
'N': 'native!'
'O': 'native!'
'P': 'native!'
'Q': 'native!'
'R': 'native!'
'S': 'native!'
'T': 'native!'
'U': 'native!'
'V': 'native!'
'W': 'native!'
'X': 'native!'
'Y': 'native!'
'Z': 'native!'
'1': 'native!'
'2': 'native!'
'3': 'native!'
'4': 'native!'
'5': 'native!'
'6': 'native!'
'7': 'native!'
'8': 'native!'
'9': 'native!'
'0': 'native!'
'~': 'native!'
'!': 'native!'
'@': 'native!'
'#': 'native!'
'$': 'native!'
'%': 'native!'
'^': 'native!'
'&': 'native!'
'*': 'native!'
'(': 'native!'
')': 'native!'
'-': 'native!'
'_': 'native!'
'=': 'native!'
'+': 'native!'
'[': 'native!'
'{': 'native!'
']': 'native!'
'}': 'native!'
'\\': 'native!'
'|': 'native!'
';': 'native!'
':': 'native!'
'\'': 'native!'
'"': 'native!'
'<': 'native!'
',': 'native!'
'>': 'native!'
'.': 'native!'
'?': 'native!'
'/': 'native!'

View file

@ -1,45 +1,17 @@
# Note: For a menu item to have a keyboard equiavalent, it needs
# to be listed in this file.
# Mac application keys
'body':
# Apple specific
'cmd-q': 'application:quit'
'cmd-h': 'application:hide'
'cmd-0': 'application:show-main-window'
'cmd-alt-h': 'application:hide-other-applications'
'cmd-m': 'application:minimize'
'cmd-alt-h': 'application:hide-other-applications'
'alt-cmd-ctrl-m': 'application:zoom'
'ctrl-p': 'core:move-up'
'ctrl-n': 'core:move-down'
'ctrl-b': 'core:move-left'
'ctrl-f': 'core:move-right'
'ctrl-P': 'core:select-up'
'ctrl-N': 'core:select-down'
'ctrl-F': 'core:select-right'
'ctrl-B': 'core:select-left'
'ctrl-h': 'core:backspace'
'ctrl-d': 'core:delete'
# Atom Specific
'cmd-O': 'application:open-dev'
'cmd-alt-ctrl-s': 'application:run-all-specs'
'enter': 'core:confirm'
'escape': 'core:cancel'
'up': 'core:move-up'
'down': 'core:move-down'
'left': 'core:move-left'
'right': 'core:move-right'
'ctrl-alt-cmd-l': 'window:reload'
'alt-cmd-i': 'window:toggle-dev-tools'
'cmd-alt-ctrl-p': 'window:run-package-specs'
# Sublime Parity
'cmd-,': 'application:show-settings'
'cmd-w': 'window:close'
'cmd-o': 'application:open'
'cmd-n': 'application:new-message'
'cmd-s': 'core:save'
'cmd-S': 'core:save-as'
'cmd-alt-s': 'window:save-all'
'cmd-ctrl-f': 'window:toggle-full-screen'
# Mac core keys
'cmd-z': 'core:undo'
'cmd-Z': 'core:redo'
'cmd-y': 'core:redo'
@ -47,31 +19,14 @@
'cmd-c': 'core:copy'
'cmd-a': 'core:select-all'
'cmd-v': 'core:paste'
'shift-up': 'core:select-up'
'shift-down': 'core:select-down'
'shift-left': 'core:select-left'
'shift-right': 'core:select-right'
'shift-pageup': 'core:select-page-up'
'shift-pagedown': 'core:select-page-down'
'delete': 'core:delete'
'shift-delete': 'core:delete'
'pageup': 'core:page-up'
'pagedown': 'core:page-down'
'backspace': 'core:backspace'
'shift-backspace': 'core:backspace'
'cmd-up': 'core:move-to-top'
'cmd-down': 'core:move-to-bottom'
'cmd-shift-up': 'core:select-to-top'
'cmd-shift-down': 'core:select-to-bottom'
# Mac window keys
'cmd-=': 'window:increase-font-size'
'cmd-+': 'window:increase-font-size'
'cmd--': 'window:decrease-font-size'
'cmd-_': 'window:decrease-font-size'
# allow standard input fields to work correctly
'body .native-key-bindings':
'cmd-z': 'native!'
'cmd-Z': 'native!'
'cmd-x': 'native!'
'cmd-c': 'native!'
'cmd-v': 'native!'
'cmd-0': 'window:reset-font-size'
'alt-cmd-i': 'window:toggle-dev-tools'
'cmd-ctrl-f': 'window:toggle-full-screen'
'ctrl-alt-cmd-l': 'window:reload'
'cmd-alt-ctrl-p': 'window:run-package-specs'

View file

@ -1,65 +1,29 @@
'body':
# Atom Specific
'enter': 'core:confirm'
'escape': 'core:cancel'
'up': 'core:move-up'
'down': 'core:move-down'
'left': 'core:move-left'
'right': 'core:move-right'
'ctrl-alt-r': 'window:reload'
'ctrl-shift-i': 'window:toggle-dev-tools'
'ctrl-alt-p': 'window:run-package-specs'
'ctrl-alt-s': 'application:run-all-specs'
'ctrl-alt-o': 'application:open-dev'
'F11': 'window:toggle-full-screen'
# Note: For a menu item to have a keyboard equiavalent, it needs
# to be listed in this file.
# Sublime Parity
'ctrl-,': 'application:show-settings'
'ctrl-W': 'window:close'
# Linux application keys
'body':
'ctrl-q': 'application:quit'
'ctrl-n': 'application:new-message'
'ctrl-s': 'core:save'
'ctrl-S': 'core:save-as'
'ctrl-w': 'core:close'
'ctrl-alt-s': 'application:run-all-specs'
# Linux core keys
'ctrl-z': 'core:undo'
'ctrl-Z': 'core:redo'
'ctrl-y': 'core:redo'
'ctrl-shift-z': 'core:redo'
'ctrl-x': 'core:cut'
'ctrl-c': 'core:copy'
'ctrl-a': 'core:select-all'
'ctrl-v': 'core:paste'
'ctrl-insert': 'core:copy'
'shift-insert': 'core:paste'
'shift-up': 'core:select-up'
'shift-down': 'core:select-down'
'shift-left': 'core:select-left'
'shift-right': 'core:select-right'
'shift-pageup': 'core:select-page-up'
'shift-pagedown': 'core:select-page-down'
'delete': 'core:delete'
'shift-delete': 'core:cut'
'pageup': 'core:page-up'
'pagedown': 'core:page-down'
'backspace': 'core:backspace'
'shift-backspace': 'core:backspace'
'ctrl-shift-up': 'core:move-up'
'ctrl-shift-down': 'core:move-down'
# Linux window keys
'ctrl-=': 'window:increase-font-size'
'ctrl-+': 'window:increase-font-size'
'ctrl--': 'window:decrease-font-size'
'ctrl-_': 'window:decrease-font-size'
'ctrl-0': 'window:reset-font-size'
'ctrl-k ctrl-p': 'window:focus-previous-pane'
'ctrl-k ctrl-n': 'window:focus-next-pane'
'ctrl-k ctrl-up': 'window:focus-pane-above'
'ctrl-k ctrl-down': 'window:focus-pane-below'
'ctrl-k ctrl-left': 'window:focus-pane-on-left'
'ctrl-k ctrl-right': 'window:focus-pane-on-right'
# allow standard input fields to work correctly
'body .native-key-bindings':
'ctrl-z': 'native!'
'ctrl-Z': 'native!'
'ctrl-x': 'native!'
'ctrl-c': 'native!'
'ctrl-v': 'native!'
'ctrl-alt-i': 'window:toggle-dev-tools'
'F11': 'window:toggle-full-screen'
'ctrl-alt-r': 'window:reload'
'ctrl-alt-p': 'window:run-package-specs'

View file

@ -1,65 +1,29 @@
# Note: For a menu item to have a keyboard equiavalent, it needs
# to be listed in this file.
# Windows application keys
'body':
# Platform Bindings
# Atom Specific
'enter': 'core:confirm'
'escape': 'core:cancel'
'up': 'core:move-up'
'down': 'core:move-down'
'left': 'core:move-left'
'right': 'core:move-right'
'ctrl-alt-r': 'window:reload'
'ctrl-alt-i': 'window:toggle-dev-tools'
'ctrl-alt-p': 'window:run-package-specs'
'ctrl-q': 'application:quit'
'ctrl-alt-s': 'application:run-all-specs'
'ctrl-alt-o': 'application:open-dev'
'F11': 'window:toggle-full-screen'
# Sublime Parity
'ctrl-,': 'application:show-settings'
'ctrl-w': 'window:close'
'ctrl-n': 'application:new-message'
'ctrl-s': 'core:save'
'ctrl-S': 'core:save-as'
# Windows core keys
'ctrl-z': 'core:undo'
'ctrl-shift-z': 'core:redo'
'ctrl-Z': 'core:redo'
'ctrl-y': 'core:redo'
'ctrl-x': 'core:cut'
'ctrl-c': 'core:copy'
'ctrl-a': 'core:select-all'
'ctrl-v': 'core:paste'
'ctrl-insert': 'core:copy'
'shift-insert': 'core:paste'
'shift-up': 'core:select-up'
'shift-down': 'core:select-down'
'shift-left': 'core:select-left'
'shift-right': 'core:select-right'
'shift-pageup': 'core:select-page-up'
'shift-pagedown': 'core:select-page-down'
'delete': 'core:delete'
'shift-delete': 'core:cut'
'pageup': 'core:page-up'
'pagedown': 'core:page-down'
'backspace': 'core:backspace'
'shift-backspace': 'core:backspace'
'ctrl-shift-up': 'core:move-up'
'ctrl-shift-down': 'core:move-down'
# Windows window keys
'ctrl-=': 'window:increase-font-size'
'ctrl-+': 'window:increase-font-size'
'ctrl--': 'window:decrease-font-size'
'ctrl-_': 'window:decrease-font-size'
'ctrl-0': 'window:reset-font-size'
'ctrl-k ctrl-p': 'window:focus-previous-pane'
'ctrl-k ctrl-n': 'window:focus-next-pane'
'ctrl-k ctrl-up': 'window:focus-pane-above'
'ctrl-k ctrl-down': 'window:focus-pane-below'
'ctrl-k ctrl-left': 'window:focus-pane-on-left'
'ctrl-k ctrl-right': 'window:focus-pane-on-right'
# allow standard input fields to work correctly
'body .native-key-bindings':
'ctrl-z': 'native!'
'ctrl-Z': 'native!'
'ctrl-x': 'native!'
'ctrl-c': 'native!'
'ctrl-v': 'native!'
'ctrl-alt-i': 'window:toggle-dev-tools'
'F11': 'window:toggle-full-screen'
'ctrl-alt-r': 'window:reload'
'ctrl-alt-p': 'window:run-package-specs'

View file

@ -149,12 +149,12 @@ class AtomApplication
# needs to manually bubble them up to the Application instance via IPC or they won't be
# handled. This happens in workspace-element.coffee
handleEvents: ->
@on 'application:new-message', => @showComposerWindow()
@on 'application:run-all-specs', -> @runSpecs(exitWhenDone: false, resourcePath: global.devResourcePath, safeMode: @focusedWindow()?.safeMode)
@on 'application:run-benchmarks', -> @runBenchmarks()
@on 'application:quit', =>
@quitting = true
app.quit()
@on 'application:new-message', => @showComposerWindow()
@on 'application:open-file-to-window', -> @promptForPath({type: 'file', to_window: true})
@on 'application:open-dev', -> @promptForPath(devMode: true)
@on 'application:open-safe', -> @promptForPath(safeMode: true)

View file

@ -106,12 +106,12 @@ class WindowEventHandler
@handleNativeKeybindings()
# Wire commands that should be handled by the native menu
# for elements with the `.native-key-bindings` class.
# for elements with the `.override-key-bindings` class.
handleNativeKeybindings: ->
menu = null
bindCommandToAction = (command, action) =>
@subscribe $(document), command, (event) ->
if event.target.webkitMatchesSelector('.native-key-bindings, input')
unless event.target.webkitMatchesSelector('.override-key-bindings')
menu ?= require('remote').require('menu')
menu.sendActionToFirstResponder(action)
true