things got a little out of hand

This commit is contained in:
Corey Johnson
2011-10-27 17:45:42 -07:00
parent 197b911b44
commit 3c976e37f3
13 changed files with 229 additions and 126 deletions

View File

@@ -1,4 +1,4 @@
//
//
// JSCocoa.m
// JSCocoa
//

View File

@@ -1,24 +0,0 @@
$ = require 'jquery'
Pane = require 'pane'
module.exports =
class EditorPane extends Pane
position: 'main'
html: $ '<div id="editor"></div>'
# You know what I don't like? This constructor.
constructor: (@window, @editor) ->
super @window
# Resize editor when panes are added/removed
el = document.body
el.addEventListener 'DOMNodeInsertedIntoDocument', => @resize()
el.addEventListener 'DOMNodeRemovedFromDocument', => @resize()
resize: (timeout=1) ->
setTimeout =>
@editor.ace.focus()
@editor.ace.resize()
, timeout

View File

@@ -1 +0,0 @@
module.exports = require 'editor/editor'

View File

@@ -59,13 +59,19 @@
<body>
<div id='app-horizontal'>
<div id='app-vertical'>
<div class='main'></div>
<div class='main'>
<div id='ace-editor'></div>
</div>
</div>
</div>
</body>
<script src='src/require.js'></script>
<script>
window.onerror = function() {
atomController.webView.inspector.showConsole(true)
}
require('startup');
</script>

View File

@@ -5,11 +5,7 @@ module.exports =
class App
@startup: ->
KeyBinder.register "app", @
window.startup()
KeyBinder.load "#{@root}/static/key-bindings.coffee"
KeyBinder.load "~/.atomicity/key-bindings.coffee"
@quit: ->
OSX.NSApp.terminate OSX.NSApp

View File

@@ -1,39 +1,39 @@
_ = require 'underscore'
File = require 'fs'
Chrome = require 'chrome'
Extension = require 'extension'
EditorPane = require 'editor/editor-pane'
{bindKey} = require 'keybinder'
fs = require 'fs'
ace = require 'ace/ace'
Event = require 'event'
KeyBinder = require 'key-binder'
Native = require 'native'
{EditSession} = require 'ace/edit_session'
{UndoManager} = require 'ace/undomanager'
module.exports =
class Editor extends Extension
class Editor
filename: null
keymap: ->
# Maybe these don't go here?
'Command-S' : 'save'
'Command-Shift-S' : 'saveAs'
sessions: {}
# These are cool though.
'Command-C' : 'copy'
'Command-X' : 'cut'
'Command-R' : 'eval'
'Command-/' : 'toggleComment'
'Command-[' : 'outdent'
'Command-]' : 'indent'
'Alt-F' : 'forwardWord'
'Alt-B' : 'backWord'
'Alt-D' : 'deleteWord'
'Alt-Shift-,' : 'home'
'Alt-Shift-.' : 'end'
'Ctrl-L' : 'consolelog'
constructor: ->
KeyBinder.register "editor", @
# Resize editor when panes are added/removed
el = document.body
el.addEventListener 'DOMNodeInsertedIntoDocument', => @resize()
el.addEventListener 'DOMNodeRemovedFromDocument', => @resize()
@ace = ace.edit "ace-editor"
# This stuff should all be grabbed from the .atomicity dir
@ace.setTheme require "ace/theme/twilight"
@ace.getSession().setUseSoftTabs true
@ace.getSession().setTabSize 2
@ace.setShowInvisibles(true)
@ace.setPrintMarginColumn 78
#@ace.getSession().on 'change', -> @window.setDirty true
Event.on 'window:open', (e) => @open e.details
Event.on 'window:close', (e) => @close e.details
modeMap:
js: 'javascript'
@@ -45,27 +45,6 @@ class Editor extends Extension
cs: 'csharp'
rb: 'ruby'
sessions: {}
constructor: (args...) ->
super(args...)
@pane = new EditorPane @window
@pane.add()
@ace = ace.edit "editor"
# This stuff should all be grabbed from the .atomicity dir
@ace.setTheme require "ace/theme/twilight"
@ace.getSession().setUseSoftTabs true
@ace.getSession().setTabSize 2
@ace.setShowInvisibles(true)
@ace.setPrintMarginColumn 78
@ace.getSession().on 'change', -> @window.setDirty true
@window.on 'open', ({filename}) => @open filename
@window.on 'close', ({filename}) => @close filename
modeForLanguage: (language) ->
language = language.toLowerCase()
modeName = @modeMap[language] or language
@@ -76,45 +55,36 @@ class Editor extends Extension
null
setMode: ->
if mode = @modeForLanguage _.last @filename.split '.'
if mode = @modeForLanguage _.last @activePath.split '.'
@ace.getSession().setMode new mode
save: ->
return @saveAs() if not @filename
return @saveAs() if not @activePath
@removeTrailingWhitespace()
File.write @filename, @code()
@sessions[@filename] = @ace.getSession()
@window.setDirty false
@window._emit 'save', { filename: @filename }
fs.write @activePath, @code()
@sessions[@activePath] = @ace.getSession()
#@window.setDirty false
#@window._emit 'save', { filename: @activePath }
open: (path) ->
path = Chrome.openPanel() if not path
return if not path
@filename = path
return unless fs.isFile path
@activePath = path
if File.isDirectory @filename
File.changeWorkingDirectory @filename
@window.setTitle _.last @filename.split '/'
@ace.setSession @newSession()
@window.setDirty false
else
if /png|jpe?g|gif/i.test @filename
Chrome.openURL @filename
else
@window.setTitle _.last @filename.split '/'
@sessions[@filename] or= @newSession File.read @filename
@ace.setSession @sessions[@filename]
@window.setDirty false
@setMode()
@sessions[@activePath] ?= @newSession fs.read @activePath
@ace.setSession @sessions[@activePath]
@setMode()
close: (path) ->
@deleteSession path
@activePath = null if path is @activePath
delete @sessions[path]
@ace.setSession @newSession()
saveAs: ->
if file = Chrome.savePanel()
@filename = file
@window.setTitle _.last @filename.split '/'
if path = Native.savePanel()
@activePath = path
#@window.setTitle _.last @activePath.split '/'
@save()
code: ->
@@ -127,12 +97,6 @@ class Editor extends Extension
regExp: true
wrap: true
deleteSession: (path) ->
if path is @filename
@filename = null
delete @sessions[path]
@ace.setSession @newSession()
newSession: (code) ->
doc = new EditSession code or ''
doc.setUndoManager new UndoManager
@@ -148,15 +112,21 @@ class Editor extends Extension
match = /^( +)[^*]/im.exec code || @code()
match?[1].length or 2
resize: (timeout=1) ->
setTimeout =>
@editor.ace.focus()
@editor.ace.resize()
, timeout
copy: ->
editor = @ace
text = editor.getSession().doc.getTextRange editor.getSelectionRange()
Chrome.writeToPasteboard text
Native.writeToPasteboard text
cut: ->
editor = @ace
text = editor.getSession().doc.getTextRange editor.getSelectionRange()
Chrome.writeToPasteboard text
Native.writeToPasteboard text
editor.session.remove editor.getSelectionRange()
eval: ->

24
src/event.coffee Normal file
View File

@@ -0,0 +1,24 @@
# Using the DOM event system, and copying the JQuery Event API
# https://developer.mozilla.org/en/DOM/Creating_and_triggering_events
module.exports =
class Event
@events: {}
@on: (name, callback) ->
window.document.addEventListener name, callback
callback
@off: (name, callback) ->
window.document.removeEventListener name, callback
@trigger: (name, data) ->
event = @events[name]
if not event
event = window.document.createEvent "CustomEvent"
event.initCustomEvent name, true, true, null
@events[name] = event
event.details = data
window.document.dispatchEvent event
null

View File

@@ -9,11 +9,13 @@ module.exports =
# Make the given path absolute by resolving it against the
# current working directory.
absolute: (path) ->
path = OSX.NSString.stringWithString(path).stringByStandardizingPath.toString()
return path if path[0] == "/"
path = OSX.NSString.stringWithString(path).stringByStandardizingPath
return path if path.toString()[0] == "/"
resolvedString = OSX.NSString.stringWithString(@workingDirectory)
resolvedString.stringByAppendingPath(path).stringByStandardizingPath.toString()
resolvedString = OSX.NSString.stringWithString(@workingDirectory())
resolvedString = resolvedString.stringByAppendingPathComponent(path).stringByStandardizingPath
resolvedString.toString()
# Return the basename of the given path. That is the path with
# any leading directory components removed. If specified, also
@@ -28,12 +30,13 @@ module.exports =
# Returns true if the file specified by path exists
exists: (path) ->
exists = OSX.NSFileManager.defaultManager.
fileExistsAtPath_isDirectory path, null
console.log "exists"
OSX.NSFileManager.defaultManager.fileExistsAtPath_isDirectory path, null
# Returns true if the file specified by path exists and is a
# directory.
isDirectory: (path) ->
console.log "dir"
isDir = new jscocoa.outArgument
exists = OSX.NSFileManager.defaultManager.
fileExistsAtPath_isDirectory path, isDir

34
src/native.coffee Normal file
View File

@@ -0,0 +1,34 @@
module.exports =
class Native
# path - Optional. The String path to the file to base it on.
@newWindow: (path) ->
controller = OSX.NSApp.createController
controller.window
controller.window.makeKeyAndOrderFront null
# Returns null or a file path.
@openPanel: ->
panel = OSX.NSOpenPanel.openPanel
panel.setCanChooseDirectories true
if panel.runModal isnt OSX.NSFileHandlingPanelOKButton
return null
filename = panel.filenames.lastObject
localStorage.lastOpenedPath = filename
filename.toString()
@openURL: (url) ->
window.location = url
App = require 'app'
App.activeWindow.setTitle _.last url.replace(/\/$/,'').split '/'
# Returns null or a file path.
@savePanel: ->
panel = OSX.NSSavePanel.savePanel
if panel.runModal isnt OSX.NSFileHandlingPanelOKButton
return null
panel.filenames.lastObject
@writeToPasteboard: (text) ->
pb = OSX.NSPasteboard.generalPasteboard
pb.declareTypes_owner [OSX.NSStringPboardType], null
pb.setString_forType text, OSX.NSStringPboardType

39
src/pane.coffee Normal file
View File

@@ -0,0 +1,39 @@
$ = require 'jquery'
module.exports =
class Pane
position: null
html: null
showing: false
add: ->
verticalDiv = $('#app-vertical')
horizontalDiv = $('#app-horizontal')
el = $ "<div>"
el.addClass "pane " + @position
el.append @html
switch @position
when 'main'
$('.main').replaceWith el
when 'top'
verticalDiv.prepend el
when 'left'
horizontalDiv.prepend el
when 'bottom'
verticalDiv.append el
when 'right'
horizontalDiv.append el
else
throw "I DON'T KNOW HOW TO DEAL WITH #{@position}"
toggle: ->
if @showing
@html.parent().detach()
else
@add this
@showing = not @showing

View File

@@ -34,7 +34,7 @@ class Watcher
switch notification.toString()
when "UKKQueueFileRenamedNotification"
raise "Doesn't handle this yet"
throw "Doesn't handle this yet"
when "UKKQueueFileDeletedNotification"
@watchedPaths[path] = null
@queue.removePathFromQueue path

View File

@@ -1,16 +1,51 @@
Editor = require 'editor'
Event = require 'event'
KeyBinder = require 'key-binder'
Native = require 'native'
fs = require 'fs'
# This file is a weirdo. We don't create a Window class, we just add stuff to
# the DOM window.
windowAdditions =
editor: null
extensions: []
appRoot: OSX.NSBundle.mainBundle.resourcePath
path: localStorage.lastOpenedPath ? fs.workingDirectory()
startup: ->
KeyBinder.register "window", window
@path = localStorage.lastOpenedPath ? File.workingDirectory()
@appPath = OSX.NSBundle.mainBundle.resourcePath
@editor = new Editor()
@loadExtensions()
KeyBinder.load "#{@appRoot}/static/key-bindings.coffee"
KeyBinder.load "~/.atomicity/key-bindings.coffee"
loadExtensions: ->
extension.shutdown() for extension in @extensions
@extensions = []
extensionPaths = fs.list(@appRoot + "/extensions")
for extensionPath in extensionPaths when fs.isDirectory extensionPath
try
extension = require extensionPath
extensions.push new Extension()
catch error
console.warn "window: Loading Extension #{fs.base extensionPath} failed."
console.warn error
# After all the extensions are created, start them up.
for extension in @extensions
try
extension.startup()
catch error
console.warn "window: Extension #{extension.constructor.name} failed to startup."
console.warn error
handleKeyEvent: ->
KeyBinder.handleEvent.apply KeyBinder, arguments
@@ -18,6 +53,10 @@ windowAdditions =
showConsole: ->
atomController.webView.inspector.showConsole true
open: (path) ->
path = Native.openPanel() if not path
Event.trigger 'window:open', path if path
for key, value of windowAdditions
raise "DOMWindow already has a key named #{key}" if window[key]
console.warn "DOMWindow already has a key named `#{key}`" if window[key]
window[key] = value

View File

@@ -1,6 +1,23 @@
app:
"cmd-q": (app) -> app.quit()
"cmd-j": (app) -> console.log "OMG YOU TOUCHED THE LETTER J!"
'cmd-q': (app) -> app.quit()
'cmd-j': (app) -> console.log "OMG YOU TOUCHED THE LETTER J!"
window:
"cmd-shift-i": (window) -> window.showConsole()
'cmd-shift-i': (window) -> window.showConsole()
'cmd-o': (window) -> window.open()
editor:
'cmd-s': 'save'
'cmd-shift-s': 'saveAs'
'cmd-c': 'copy'
'cmd-x': 'cut'
'cmd-r': 'eval'
'cmd-/': 'toggleComment'
'cmd-[': 'outdent'
'cmd-]': 'indent'
'alt-f': 'forwardWord'
'alt-b': 'backWord'
'alt-d': 'deleteWord'
'alt-shift-,': 'home'
'alt-shift-.': 'end'
'ctrl-l': 'consolelog'