mirror of
https://github.com/atom/atom.git
synced 2026-02-08 05:35:04 -05:00
new keybinder dispatch method
This commit is contained in:
@@ -1,8 +1,5 @@
|
||||
module.exports =
|
||||
class App
|
||||
constructor: ->
|
||||
atom.keybinder.register "app", this
|
||||
|
||||
open: (path) ->
|
||||
OSX.NSApp.open path
|
||||
|
||||
|
||||
@@ -7,10 +7,11 @@ class Document extends Pane
|
||||
|
||||
@handlers: {}
|
||||
@handler: (path) ->
|
||||
for handler, test of Document.handlers
|
||||
return handler if test path
|
||||
@register: (cb) ->
|
||||
Document.handlers[this] = cb
|
||||
for name, {test, handler} of Document.handlers
|
||||
return new handler path if test path
|
||||
null
|
||||
@register: (test) ->
|
||||
Document.handlers[@name] = {test, handler: this}
|
||||
|
||||
open: ->
|
||||
close: ->
|
||||
|
||||
@@ -17,7 +17,6 @@ class Editor extends Document
|
||||
|
||||
constructor: (@path) ->
|
||||
super()
|
||||
atom.keybinder.register "editor", @
|
||||
|
||||
@show()
|
||||
|
||||
|
||||
@@ -9,25 +9,25 @@ class ExtensionManager
|
||||
atom.on 'window:close', @unloadExtensions
|
||||
|
||||
loadExtensions: =>
|
||||
extension.shutdown() for name, extension of @extensions
|
||||
@extensions = {}
|
||||
extension.shutdown() for name, extension of atom.extensions
|
||||
atom.extensions = {}
|
||||
|
||||
extensionPaths = fs.list require.resourcePath + "/extensions"
|
||||
for extensionPath in extensionPaths when fs.isDirectory extensionPath
|
||||
try
|
||||
extension = require extensionPath
|
||||
@extensions[extension.name] = new extension
|
||||
atom.extensions[extension.name] = new extension
|
||||
catch error
|
||||
console.warn "Loading Extension '#{fs.base extensionPath}' failed."
|
||||
console.warn error
|
||||
|
||||
# After all the extensions are created, start them up.
|
||||
for name, extension of @extensions
|
||||
for name, extension of atom.extensions
|
||||
try
|
||||
extension.startup()
|
||||
catch error
|
||||
console.warn "Extension #{extension::name} failed to startup."
|
||||
console.warn "Extension #{extension.constructor.name} failed to startup."
|
||||
console.warn error
|
||||
|
||||
unloadExtensions: =>
|
||||
extension.shutdown() for name, extension of @extensions
|
||||
extension.shutdown() for name, extension of atom.extensions
|
||||
@@ -9,8 +9,6 @@ windowAdditions =
|
||||
path: null
|
||||
|
||||
startup: ->
|
||||
atom.keybinder.register "window", window
|
||||
|
||||
@path = $atomController.path.toString()
|
||||
@setTitle (_.last @path.split '/') or 'Untitled Document'
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ for name, method of atom.event
|
||||
|
||||
atom.keybinder = new KeyBinder
|
||||
atom.settings = new Settings
|
||||
atom.extensions = new ExtensionManager
|
||||
atom.extensions = {}
|
||||
atom.extensionManager = new ExtensionManager
|
||||
atom.app = new App
|
||||
|
||||
# atom.open, atom.close, etc.
|
||||
@@ -30,7 +31,8 @@ for name, method of atom.app
|
||||
atom[name] = atom.app[name]
|
||||
|
||||
atom.path = $atomController.path.toString()
|
||||
atom.document = new Document.handler atom.path
|
||||
atom.document = Document.handler atom.path
|
||||
atom.document ?= new Editor
|
||||
|
||||
require 'window'
|
||||
window.startup()
|
||||
|
||||
@@ -5,18 +5,16 @@ Watcher = require 'watcher'
|
||||
|
||||
module.exports =
|
||||
class KeyBinder
|
||||
# keymaps are name => { binding: method } mappings
|
||||
keymaps: {}
|
||||
|
||||
constructor: ->
|
||||
atom.on 'window:load', ->
|
||||
atom.keybinder.load require.resolve "key-bindings.coffee"
|
||||
if fs.isFile "~/.atomicity/key-bindings.coffee"
|
||||
atom.keybinder.load "~/.atomicity/key-bindings.coffee"
|
||||
|
||||
bindings: {}
|
||||
|
||||
scopes: {}
|
||||
|
||||
register: (name, scope) ->
|
||||
@scopes[name] = scope
|
||||
|
||||
load: (path) ->
|
||||
try
|
||||
@@ -29,47 +27,52 @@ class KeyBinder
|
||||
@load path
|
||||
|
||||
json = CoffeeScript.eval "return " + (fs.read path)
|
||||
for scopeName, bindings of json
|
||||
@create scopeName, binding, method for binding, method of bindings
|
||||
# Iterate in reverse order scopes are declared.
|
||||
# Scope at the top of the file is checked last.
|
||||
for name in _.keys(json).reverse()
|
||||
bindings = json[name]
|
||||
@keymaps[name] ?= {}
|
||||
for binding, method of bindings
|
||||
@keymaps[name][@bindingParser binding] = method
|
||||
catch error
|
||||
console.error "#{@name}: Could not load key bindings at `#{path}`. #{error}"
|
||||
|
||||
create: (scope, binding, method) ->
|
||||
if typeof scope is "string"
|
||||
throw "#{@name}: Unknown scope `#{scope}`" unless @scopes[scope]
|
||||
scope = @scopes[scope]
|
||||
|
||||
callback = if _.isFunction method
|
||||
-> method scope
|
||||
else if scope[method]
|
||||
-> scope[method]()
|
||||
else
|
||||
throw "#{@name}: '#{method}' not found found in scope #{scope}"
|
||||
|
||||
callbacks = @bindings[@bindingParser binding] ?= []
|
||||
|
||||
callbacks.push callback
|
||||
console.error "Can't load key bindings at `#{path}`. #{error}"
|
||||
|
||||
handleEvent: (event) ->
|
||||
keys = []
|
||||
keys.push @modifierKeys.command if event.modifierFlags & OSX.NSCommandKeyMask
|
||||
keys.push @modifierKeys.control if event.modifierFlags & OSX.NSControlKeyMask
|
||||
keys.push @modifierKeys.alt if event.modifierFlags & OSX.NSAlternateKeyMask
|
||||
if event.modifierFlags & OSX.NSCommandKeyMask
|
||||
keys.push @modifierKeys.command
|
||||
if event.modifierFlags & OSX.NSControlKeyMask
|
||||
keys.push @modifierKeys.control
|
||||
if event.modifierFlags & OSX.NSAlternateKeyMask
|
||||
keys.push @modifierKeys.alt
|
||||
keys.push event.charactersIgnoringModifiers.charCodeAt 0
|
||||
|
||||
binding = keys.sort().join "-"
|
||||
|
||||
callbacks = @bindings[binding]
|
||||
return false if not callbacks
|
||||
for scope, bindings of @keymaps
|
||||
break if method = bindings[binding]
|
||||
return false if not method
|
||||
|
||||
# Only use the most recently added binding
|
||||
try
|
||||
_.last(callbacks)()
|
||||
@triggerBinding scope, method
|
||||
catch e
|
||||
console.warn "Failed to run binding #{@bindingFromAscii binding}. #{e}"
|
||||
|
||||
true
|
||||
|
||||
responders: ->
|
||||
_.flatten [ (_.values atom.extensions), atom.document, window, atom ]
|
||||
|
||||
triggerBinding: (scope, method) ->
|
||||
responder = _.detect @responders(), (responder) ->
|
||||
(scope is 'window' and responder is window) or
|
||||
responder.constructor.name.toLowerCase() is scope
|
||||
if responder
|
||||
if _.isFunction method
|
||||
method responder
|
||||
else
|
||||
responder[method]()
|
||||
|
||||
bindingParser: (binding) ->
|
||||
keys = binding.trim().split '-'
|
||||
|
||||
@@ -101,7 +104,7 @@ class KeyBinder
|
||||
asciiKeys = binding.split '-'
|
||||
keys = []
|
||||
|
||||
for asciiKey in asciiKeys
|
||||
for asciiKey in asciiKeys.reverse()
|
||||
key = inverseModifierKeys[asciiKey]
|
||||
key ?= inverseNamedKeys[asciiKey]
|
||||
key ?= String.fromCharCode asciiKey
|
||||
|
||||
Reference in New Issue
Block a user