     @sendLocalEvent @localSave(editor.project, file, buffer)
 
   onCoreConfirm: (event) ->
-    @syncAdditions()
-    @syncMoves()
-
-  onTreeViewRemove: (event) ->
-    {target} = event
-    path = target.dataset.path || target.firstChild.dataset.path
-    return if fs.existsSync(path)
-
-    @sendLocalEvent @localRemove(path)
-
-  onTreeViewAdd: (event) =>
-    @recentTreeViewCommand = event.type
-    @listTreeAtAdd = fs.listTreeSync(@projectPath)
-
-  onTreeViewMove: (event) =>
-    {target, type} = event
-    @recentTreeViewCommand = type
-    @listTreeAtMove = fs.listTreeSync(@projectPath)
-    @pathAtMove = target.dataset.path || target.firstChild.dataset.path
-
-  syncAdditions: ->
-    prevEntries = @listTreeAtAdd
-    @listTreeAtAdd = null
-
-    return unless @recentTreeViewCommand.match(/tree-view:add/)
-    @recentTreeViewCommand = null
+    setTimeout =>
+      @syncAdditions()
+      @syncMoves()
+      @syncDuplication()
+    , 10
+
+  onTreeViewRemove: (event) =>
+    @syncRemovals()
+
+  onTreeViewWillDispatch: (event) =>
+    {type, target} = event
+    @pathAtWillDispatch = target.dataset.path || target.firstChild.dataset.path
+    @willDispatchCommand = type
+    @entriesAtWillDispatch = fs.listTreeSync(@projectPath)
+
+  purgeTreeViewEvent: =>
+    @pathAtWillDispatch = null
+    @willDispatchCommand = null
+    @entriesAtWillDispatch = null
+
+  syncRemovals: =>
+    prevEntries = @entriesAtWillDispatch
+
+    return unless @willDispatchCommand is 'tree-view:remove'
+    @purgeTreeViewEvent()
+
+    removedEntries = _.difference(prevEntries, fs.listTreeSync(@projectPath))
+    return unless removedEntries.length
+
+    _.each removedEntries, (entry) => @sendLocalEvent @localRemove(entry)
+
+  syncAdditions: =>
+    prevEntries = @entriesAtWillDispatch
+
+    return unless @willDispatchCommand?.match(/tree-view:add/)
+    @purgeTreeViewEvent()
 
     return unless prevEntries?
 

        when 'tree-view:remove' then @onTreeViewRemove(event)

    atom.workspace.observeTextEditors (editor) =>
      editor.onDidSave =>
        @onSave(editor)
      editor.onDidChangePath ->
        console.log 'PATH CHANGED'

    atom.workspace.onDidOpen ({uri, item, pane, index}) ->
      console.log 'OPENED ' + uri

  onSave: (editor) =>
    @convertLineEndings(editor)

    @sendLocalEvent @localAddFile(deepestPath) if fs.isFileSync(deepestPath)
    @sendLocalEvent @localAddFolder(deepestPath) if fs.isDirectorySync(deepestPath)

  syncMoves: =>
    source = @pathAtWillDispatch
    prevEntries = @entriesAtWillDispatch

    return unless @willDispatchCommand is 'tree-view:move'
    @purgeTreeViewEvent()

    return unless source? and prevEntries?

    newEntries = _.difference(fs.listTreeSync(@projectPath), prevEntries)
    return unless newEntries.length

    target = _.max(newEntries, (entry) -> entry.length)
    @sendLocalEvent @localMove(source, target)

  syncDuplication: =>
    source = @pathAtWillDispatch
    prevEntries = @entriesAtWillDispatch

    return unless @willDispatchCommand is 'tree-view:duplicate'
    @purgeTreeViewEvent()

    return unless source? and prevEntries?

    newEntries = _.difference(fs.listTreeSync(@projectPath), prevEntries)
    return unless newEntries.length

    target = _.max(newEntries, (entry) -> entry.length)
    @sendLocalEvent @localDuplicate(source, target)

  sendLocalEvent: (payload) ->
    ipc.send 'fs-local-event', JSON.stringify(payload)
