Files
atom/src/app/file.coffee
2013-04-07 16:35:35 +08:00

82 lines
2.1 KiB
CoffeeScript

EventEmitter = require 'event-emitter'
fs = require 'fs'
fsUtils = require 'fs-utils'
pathWatcher = require 'pathwatcher'
_ = require 'underscore'
module.exports =
class File
path: null
cachedContents: null
constructor: (@path, @symlink=false) ->
try
if fs.statSync(@path).isDirectory()
throw new Error("#{@path} is a directory")
setPath: (@path) ->
getPath: -> @path
getBaseName: ->
fsUtils.base(@path)
write: (text) ->
previouslyExisted = @exists()
@cachedContents = text
fsUtils.write(@getPath(), text)
@subscribeToNativeChangeEvents() if not previouslyExisted and @subscriptionCount() > 0
read: (flushCache)->
if not @exists()
@cachedContents = null
else if not @cachedContents? or flushCache
@cachedContents = fsUtils.read(@getPath())
else
@cachedContents
exists: ->
fsUtils.exists(@getPath())
afterSubscribe: ->
@subscribeToNativeChangeEvents() if @exists() and @subscriptionCount() == 1
afterUnsubscribe: ->
@unsubscribeFromNativeChangeEvents() if @subscriptionCount() == 0
handleNativeChangeEvent: (eventType, path) ->
if eventType is "delete"
@unsubscribeFromNativeChangeEvents()
@detectResurrectionAfterDelay()
else if eventType is "rename"
@setPath(path)
@trigger "moved"
else if eventType is "change"
oldContents = @read()
newContents = @read(true)
return if oldContents == newContents
@trigger 'contents-changed'
detectResurrectionAfterDelay: ->
_.delay (=> @detectResurrection()), 50
detectResurrection: ->
if @exists()
@subscribeToNativeChangeEvents()
@handleNativeChangeEvent("change", @getPath())
else
@cachedContents = null
@trigger "removed"
subscribeToNativeChangeEvents: ->
@watchSubscription = pathWatcher.watch @path, (eventType, path) =>
@handleNativeChangeEvent(eventType, path)
unsubscribeFromNativeChangeEvents: ->
if @watchSubscription
@watchSubscription.close()
@watchSubscription = null
_.extend File.prototype, EventEmitter