Merge branch 'master' into global-find

Conflicts:
	spec/extensions/command-panel-spec.coffee
	src/app/buffer.coffee
	src/extensions/command-panel/command-panel.coffee
	src/extensions/command-panel/keymap.coffee
This commit is contained in:
Nathan Sobo
2012-07-24 17:44:24 -06:00
parent 66f80c2dd8
commit 454557b502
18 changed files with 293 additions and 68 deletions

View File

@@ -5,6 +5,4 @@ requireExtension 'tree-view'
requireExtension 'command-panel'
requireExtension 'keybindings-view'
requireExtension 'snippets'
# status-bar is a bit broken until webkit gets a decent flexbox implementation
# requireExtension 'status-bar'
requireExtension 'status-bar'

View File

@@ -2,7 +2,7 @@
#import "include/cef_v8.h"
#import <Foundation/Foundation.h>
typedef void (^WatchCallback)(NSArray *);
typedef void (^WatchCallback)(NSString *, NSString *);
@interface PathWatcher : NSObject {
int _kq;

View File

@@ -2,6 +2,7 @@
#import <sys/event.h>
#import <sys/time.h>
#import <sys/param.h>
#import <fcntl.h>
static NSMutableArray *gPathWatchers;
@@ -11,6 +12,8 @@ static NSMutableArray *gPathWatchers;
- (void)watchFileDescriptor:(int)fd;
- (NSString *)watchPath:(NSString *)path callback:(WatchCallback)callback callbackId:(NSString *)callbackId;
- (void)stopWatching;
- (void)reassignFileDescriptorFor:(NSString *)path to:(NSString *)newPath;
- (bool)isAtomicWrite:(struct kevent)event;
@end
@implementation PathWatcher
@@ -125,8 +128,10 @@ static NSMutableArray *gPathWatchers;
if (!fdNumber) {
NSString *message = [NSString stringWithFormat:@"Trying to unwatch %@, which we aren't watching", path];
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:message, NSLocalizedDescriptionKey, nil];
NSError *e = [NSError errorWithDomain:@"PathWatcher" code:0 userInfo:userInfo];
*error = e;
if (error) {
NSError *e = [NSError errorWithDomain:@"PathWatcher" code:0 userInfo:userInfo];
*error = e;
}
return;
}
@@ -162,7 +167,7 @@ static NSMutableArray *gPathWatchers;
struct kevent event;
int filter = EVFILT_VNODE;
int flags = EV_ADD | EV_ENABLE | EV_CLEAR;
int filterFlags = NOTE_WRITE | NOTE_DELETE | NOTE_ATTRIB | NOTE_EXTEND | NOTE_RENAME | NOTE_REVOKE;
int filterFlags = NOTE_WRITE | NOTE_DELETE | NOTE_RENAME;
EV_SET(&event, fd, filter, flags, filterFlags, 0, 0);
kevent(_kq, &event, 1, NULL, 0, &timeout);
}
@@ -193,33 +198,44 @@ static NSMutableArray *gPathWatchers;
}
NSNumber *fdNumber = [NSNumber numberWithInt:event.ident];
NSMutableArray *eventFlags = [NSMutableArray array];
NSString *eventFlag = nil;
NSString *path = [self pathForFileDescriptor:fdNumber];
if (event.fflags & NOTE_WRITE) {
[eventFlags addObject:@"modified"];
eventFlag = @"contents-change";
}
else if ([self isAtomicWrite:event]) {
eventFlag = @"contents-change";
// The fd for the path has changed. Remove references to old fd and
// make sure the path and callbacks are linked with new fd.
@synchronized(self) {
NSDictionary *callbacks = [NSDictionary dictionaryWithDictionary:[_callbacksByFileDescriptor objectForKey:fdNumber]];
NSString *path = [self pathForFileDescriptor:fdNumber];
NSDictionary *callbacks = [NSDictionary dictionaryWithDictionary:[_callbacksByFileDescriptor objectForKey:fdNumber]];
[self unwatchPath:path callbackId:nil error:nil];
for (NSString *callbackId in [callbacks allKeys]) {
[self watchPath:path callback:[callbacks objectForKey:callbackId] callbackId:callbackId];
}
[eventFlags addObject:@"modified"];
}
}
}
else if (event.fflags & NOTE_DELETE) {
eventFlag = @"remove";
}
else if (event.fflags & NOTE_RENAME) {
eventFlag = @"move";
char pathBuffer[MAXPATHLEN];
fcntl((int)event.ident, F_GETPATH, &pathBuffer);
NSString *newPath = [NSString stringWithUTF8String:pathBuffer];
[self reassignFileDescriptorFor:path to:newPath];
path = newPath;
}
@synchronized(self) {
NSDictionary *callbacks = [_callbacksByFileDescriptor objectForKey:fdNumber];
for (NSString *key in callbacks) {
WatchCallback callback = [callbacks objectForKey:key];
dispatch_async(dispatch_get_main_queue(), ^{
callback(eventFlags);
callback(eventFlag, path);
});
}
}
@@ -241,4 +257,12 @@ static NSMutableArray *gPathWatchers;
return NO;
}
- (void)reassignFileDescriptorFor:(NSString *)path to:(NSString *)newPath {
@synchronized(self) {
NSNumber *fdNumber = [_fileDescriptorsByPath objectForKey:path];
[_fileDescriptorsByPath removeObjectForKey:path];
[_fileDescriptorsByPath setObject:fdNumber forKey:newPath];
}
}
@end

View File

@@ -319,19 +319,15 @@ bool NativeHandler::Execute(const CefString& name,
CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext();
WatchCallback callback = ^(NSArray *eventList) {
WatchCallback callback = ^(NSString *eventType, NSString *path) {
context->Enter();
CefV8ValueList args;
CefRefPtr<CefV8Value> retval;
CefRefPtr<CefV8Exception> e;
CefRefPtr<CefV8Value> eventObject = CefV8Value::CreateObject(NULL, NULL);
for (NSString *event in eventList) {
eventObject->SetValue([event UTF8String], CefV8Value::CreateBool(true), V8_PROPERTY_ATTRIBUTE_NONE);
}
args.push_back(eventObject);
args.push_back(CefV8Value::CreateString(std::string([eventType UTF8String], [eventType lengthOfBytesUsingEncoding:NSUTF8StringEncoding])));
args.push_back(CefV8Value::CreateString(std::string([path UTF8String], [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding])));
function->ExecuteFunction(function, args, retval, e, true);
context->Exit();

View File

@@ -3,7 +3,8 @@ require 'fileutils'
$ATOM_ARGS = []
ENV['PATH'] = "#{ENV['PATH']}:/usr/local/bin/"
BUILD_DIR = '/tmp/atom-build'
BUILD_DIR = 'atom-build'
mkdir_p BUILD_DIR
desc "Build Atom via `xcodebuild`"
task :build => :"verify-prerequisites" do

View File

@@ -0,0 +1,84 @@
<!DOCTYPE html>
<html>
<head>
<title>wtf</title>
<link href="static/reset.css" rel="stylesheet">
<style>
html, body {
height: 100%;
width: 100%;
background-color: black;
display: -webkit-box;
-webkit-box-flex: 1;
-webkit-box-orient: vertical;
}
.row {
background-color: green;
display: -webkit-box;
-webkit-box-flex: 1;
-webkit-box-orient: horizontal;
overflow: hidden;
}
.column {
background-color: red;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-flex: 1;
overflow: hidden;
}
.top {
background-color: orange;
height: 200px;
}
.left {
background-color: purple;
width: 100px;
}
.middle {
background-color: blue;
display: -webkit-box;
-webkit-box-flex: 1;
}
.right {
width: 200px;
}
.bottom {
height: 100px;
}
.i {
overflow: scroll;
}
.full-height-child {
background: black;
color: white;
display: -webkit-box;
-webkit-box-flex: 1;
}
</style>
</head>
<body>
<div class='column'>
<div class='i top'>Keffiyeh mustache pickled post-ironic, lomo vegan food truck helvetica direct trade nostrud. Assumenda odio brunch, DIY non anim delectus sunt aliqua organic VHS nihil pork belly accusamus. Bushwick vice high life tumblr mumblecore ullamco. High life pop-up lomo, pariatur exercitation odio helvetica food truck ex williamsburg stumptown hoodie ea polaroid jean shorts. Keytar sed sapiente, mumblecore fixie +1 cred occaecat accusamus. Fanny pack authentic dolor, id four loko dolore ex +1 pop-up. Thundercats cliche aliqua, fugiat irony marfa chambray banksy kogi organic selvage VHS DIY. Id mumblecore nisi, brunch narwhal nostrud vegan squid before they sold out. Sriracha laborum nesciunt, in salvia you probably haven't heard of them mustache VHS commodo squid proident williamsburg. Magna vero gentrify labore, non american apparel occaecat put a bird on it mlkshk DIY occupy eu pinterest aute cliche. Nihil delectus commodo voluptate nostrud. Tattooed tempor skateboard, sed tumblr nostrud chambray put a bird on it non salvia helvetica consectetur mcsweeney's incididunt. Est semiotics ut yr, fanny pack leggings voluptate carles. Ea odd future hoodie cred. Ex small batch wayfarers sartorial. Delectus mumblecore skateboard, kogi esse keytar vinyl sriracha before they sold out typewriter marfa odd future viral mollit. Polaroid biodiesel street art viral cupidatat art party, post-ironic minim. Irony qui reprehenderit, put a bird on it eiusmod iphone labore skateboard. Craft beer keffiyeh echo park, 3 wolf moon thundercats gentrify dolor beard VHS ullamco cillum post-ironic qui chambray. Sartorial cred ex, aliqua trust fund est consectetur put a bird on it in nisi cupidatat sapiente art party freegan. Mlkshk authentic velit laborum. Est tattooed hella pickled qui flexitarian. Mustache wes anderson food truck, cardigan selvage organic wayfarers VHS irure typewriter irony. Kale chips pitchfork four loko before they sold out. Quis blog proident jean shorts voluptate, photo booth high life post-ironic odio hella whatever. Vinyl 3 wolf moon qui, officia non artisan et helvetica cosby sweater velit street art proident quinoa reprehenderit. Odd future fap put a bird on it laboris, kale chips tempor duis velit. Voluptate mlkshk brooklyn nihil. Hoodie sustainable excepteur next level. Anim qui aliqua officia keffiyeh semiotics. Est brooklyn pop-up photo booth, jean shorts banksy mumblecore. Consequat typewriter ennui put a bird on it odio. Reprehenderit narwhal master cleanse, messenger bag sed wayfarers vinyl adipisicing ex nesciunt. Mollit carles ethnic craft beer shoreditch, incididunt veniam laboris small batch authentic dreamcatcher proident you probably haven't heard of them seitan. Id art party narwhal assumenda farm-to-table brooklyn. Seitan artisan adipisicing put a bird on it aute lomo. Next level letterpress pitchfork, master cleanse Austin small batch scenester mlkshk trust fund hella accusamus laboris iphone lo-fi. Minim consectetur fanny pack occupy, lo-fi twee cupidatat nostrud laborum sint. Master cleanse consectetur excepteur enim food truck banksy. Qui nisi truffaut helvetica excepteur. Quinoa banksy non four loko tattooed keffiyeh pickled, ex semiotics quis odd future consectetur flexitarian. Quis readymade 8-bit nisi. </div>
<div class='row'>
<div class='i left'>Keffiyeh mustache pickled post-ironic, lomo vegan food truck helvetica direct trade nostrud. Assumenda odio brunch, DIY non anim delectus sunt aliqua organic VHS nihil pork belly accusamus. Bushwick vice high life tumblr mumblecore ullamco. High life pop-up lomo, pariatur exercitation odio helvetica food truck ex williamsburg stumptown hoodie ea polaroid jean shorts. Keytar sed sapiente, mumblecore fixie +1 cred occaecat accusamus. Fanny pack authentic dolor, id four loko dolore ex +1 pop-up. Thundercats cliche aliqua, fugiat irony marfa chambray banksy kogi organic selvage VHS DIY. Id mumblecore nisi, brunch narwhal nostrud vegan squid before they sold out. Sriracha laborum nesciunt, in salvia you probably haven't heard of them mustache VHS commodo squid proident williamsburg. Magna vero gentrify labore, non american apparel occaecat put a bird on it mlkshk DIY occupy eu pinterest aute cliche. Nihil delectus commodo voluptate nostrud. Tattooed tempor skateboard, sed tumblr nostrud chambray put a bird on it non salvia helvetica consectetur mcsweeney's incididunt. Est semiotics ut yr, fanny pack leggings voluptate carles. Ea odd future hoodie cred. Ex small batch wayfarers sartorial. Delectus mumblecore skateboard, kogi esse keytar vinyl sriracha before they sold out typewriter marfa odd future viral mollit. Polaroid biodiesel street art viral cupidatat art party, post-ironic minim. Irony qui reprehenderit, put a bird on it eiusmod iphone labore skateboard. Craft beer keffiyeh echo park, 3 wolf moon thundercats gentrify dolor beard VHS ullamco cillum post-ironic qui chambray. Sartorial cred ex, aliqua trust fund est consectetur put a bird on it in nisi cupidatat sapiente art party freegan. Mlkshk authentic velit laborum. Est tattooed hella pickled qui flexitarian. Mustache wes anderson food truck, cardigan selvage organic wayfarers VHS irure typewriter irony. Kale chips pitchfork four loko before they sold out. Quis blog proident jean shorts voluptate, photo booth high life post-ironic odio hella whatever. Vinyl 3 wolf moon qui, officia non artisan et helvetica cosby sweater velit street art proident quinoa reprehenderit. Odd future fap put a bird on it laboris, kale chips tempor duis velit. Voluptate mlkshk brooklyn nihil. Hoodie sustainable excepteur next level. Anim qui aliqua officia keffiyeh semiotics. Est brooklyn pop-up photo booth, jean shorts banksy mumblecore. Consequat typewriter ennui put a bird on it odio. Reprehenderit narwhal master cleanse, messenger bag sed wayfarers vinyl adipisicing ex nesciunt. Mollit carles ethnic craft beer shoreditch, incididunt veniam laboris small batch authentic dreamcatcher proident you probably haven't heard of them seitan. Id art party narwhal assumenda farm-to-table brooklyn. Seitan artisan adipisicing put a bird on it aute lomo. Next level letterpress pitchfork, master cleanse Austin small batch scenester mlkshk trust fund hella accusamus laboris iphone lo-fi. Minim consectetur fanny pack occupy, lo-fi twee cupidatat nostrud laborum sint. Master cleanse consectetur excepteur enim food truck banksy. Qui nisi truffaut helvetica excepteur. Quinoa banksy non four loko tattooed keffiyeh pickled, ex semiotics quis odd future consectetur flexitarian. Quis readymade 8-bit nisi. </div>
<div class='i middle'>
<div class="full-height-child">
I am a child of a flexbox item. My height should be exactly the height of my container.
</div>
</div>
<div class='i right'>Keffiyeh mustache pickled post-ironic, lomo vegan food truck helvetica direct trade nostrud. Assumenda odio brunch, DIY non anim delectus sunt aliqua organic VHS nihil pork belly accusamus. Bushwick vice high life tumblr mumblecore ullamco. High life pop-up lomo, pariatur exercitation odio helvetica food truck ex williamsburg stumptown hoodie ea polaroid jean shorts. Keytar sed sapiente, mumblecore fixie +1 cred occaecat accusamus. Fanny pack authentic dolor, id four loko dolore ex +1 pop-up. Thundercats cliche aliqua, fugiat irony marfa chambray banksy kogi organic selvage VHS DIY. Id mumblecore nisi, brunch narwhal nostrud vegan squid before they sold out. Sriracha laborum nesciunt, in salvia you probably haven't heard of them mustache VHS commodo squid proident williamsburg. Magna vero gentrify labore, non american apparel occaecat put a bird on it mlkshk DIY occupy eu pinterest aute cliche. Nihil delectus commodo voluptate nostrud. Tattooed tempor skateboard, sed tumblr nostrud chambray put a bird on it non salvia helvetica consectetur mcsweeney's incididunt. Est semiotics ut yr, fanny pack leggings voluptate carles. Ea odd future hoodie cred. Ex small batch wayfarers sartorial. Delectus mumblecore skateboard, kogi esse keytar vinyl sriracha before they sold out typewriter marfa odd future viral mollit. Polaroid biodiesel street art viral cupidatat art party, post-ironic minim. Irony qui reprehenderit, put a bird on it eiusmod iphone labore skateboard. Craft beer keffiyeh echo park, 3 wolf moon thundercats gentrify dolor beard VHS ullamco cillum post-ironic qui chambray. Sartorial cred ex, aliqua trust fund est consectetur put a bird on it in nisi cupidatat sapiente art party freegan. Mlkshk authentic velit laborum. Est tattooed hella pickled qui flexitarian. Mustache wes anderson food truck, cardigan selvage organic wayfarers VHS irure typewriter irony. Kale chips pitchfork four loko before they sold out. Quis blog proident jean shorts voluptate, photo booth high life post-ironic odio hella whatever. Vinyl 3 wolf moon qui, officia non artisan et helvetica cosby sweater velit street art proident quinoa reprehenderit. Odd future fap put a bird on it laboris, kale chips tempor duis velit. Voluptate mlkshk brooklyn nihil. Hoodie sustainable excepteur next level. Anim qui aliqua officia keffiyeh semiotics. Est brooklyn pop-up photo booth, jean shorts banksy mumblecore. Consequat typewriter ennui put a bird on it odio. Reprehenderit narwhal master cleanse, messenger bag sed wayfarers vinyl adipisicing ex nesciunt. Mollit carles ethnic craft beer shoreditch, incididunt veniam laboris small batch authentic dreamcatcher proident you probably haven't heard of them seitan. Id art party narwhal assumenda farm-to-table brooklyn. Seitan artisan adipisicing put a bird on it aute lomo. Next level letterpress pitchfork, master cleanse Austin small batch scenester mlkshk trust fund hella accusamus laboris iphone lo-fi. Minim consectetur fanny pack occupy, lo-fi twee cupidatat nostrud laborum sint. Master cleanse consectetur excepteur enim food truck banksy. Qui nisi truffaut helvetica excepteur. Quinoa banksy non four loko tattooed keffiyeh pickled, ex semiotics quis odd future consectetur flexitarian. Quis readymade 8-bit nisi. </div>
</div>
<div class='i bottom'>Keffiyeh mustache pickled post-ironic, lomo vegan food truck helvetica direct trade nostrud. Assumenda odio brunch, DIY non anim delectus sunt aliqua organic VHS nihil pork belly accusamus. Bushwick vice high life tumblr mumblecore ullamco. High life pop-up lomo, pariatur exercitation odio helvetica food truck ex williamsburg stumptown hoodie ea polaroid jean shorts. Keytar sed sapiente, mumblecore fixie +1 cred occaecat accusamus. Fanny pack authentic dolor, id four loko dolore ex +1 pop-up. Thundercats cliche aliqua, fugiat irony marfa chambray banksy kogi organic selvage VHS DIY. Id mumblecore nisi, brunch narwhal nostrud vegan squid before they sold out. Sriracha laborum nesciunt, in salvia you probably haven't heard of them mustache VHS commodo squid proident williamsburg. Magna vero gentrify labore, non american apparel occaecat put a bird on it mlkshk DIY occupy eu pinterest aute cliche. Nihil delectus commodo voluptate nostrud. Tattooed tempor skateboard, sed tumblr nostrud chambray put a bird on it non salvia helvetica consectetur mcsweeney's incididunt. Est semiotics ut yr, fanny pack leggings voluptate carles. Ea odd future hoodie cred. Ex small batch wayfarers sartorial. Delectus mumblecore skateboard, kogi esse keytar vinyl sriracha before they sold out typewriter marfa odd future viral mollit. Polaroid biodiesel street art viral cupidatat art party, post-ironic minim. Irony qui reprehenderit, put a bird on it eiusmod iphone labore skateboard. Craft beer keffiyeh echo park, 3 wolf moon thundercats gentrify dolor beard VHS ullamco cillum post-ironic qui chambray. Sartorial cred ex, aliqua trust fund est consectetur put a bird on it in nisi cupidatat sapiente art party freegan. Mlkshk authentic velit laborum. Est tattooed hella pickled qui flexitarian. Mustache wes anderson food truck, cardigan selvage organic wayfarers VHS irure typewriter irony. Kale chips pitchfork four loko before they sold out. Quis blog proident jean shorts voluptate, photo booth high life post-ironic odio hella whatever. Vinyl 3 wolf moon qui, officia non artisan et helvetica cosby sweater velit street art proident quinoa reprehenderit. Odd future fap put a bird on it laboris, kale chips tempor duis velit. Voluptate mlkshk brooklyn nihil. Hoodie sustainable excepteur next level. Anim qui aliqua officia keffiyeh semiotics. Est brooklyn pop-up photo booth, jean shorts banksy mumblecore. Consequat typewriter ennui put a bird on it odio. Reprehenderit narwhal master cleanse, messenger bag sed wayfarers vinyl adipisicing ex nesciunt. Mollit carles ethnic craft beer shoreditch, incididunt veniam laboris small batch authentic dreamcatcher proident you probably haven't heard of them seitan. Id art party narwhal assumenda farm-to-table brooklyn. Seitan artisan adipisicing put a bird on it aute lomo. Next level letterpress pitchfork, master cleanse Austin small batch scenester mlkshk trust fund hella accusamus laboris iphone lo-fi. Minim consectetur fanny pack occupy, lo-fi twee cupidatat nostrud laborum sint. Master cleanse consectetur excepteur enim food truck banksy. Qui nisi truffaut helvetica excepteur. Quinoa banksy non four loko tattooed keffiyeh pickled, ex semiotics quis odd future consectetur flexitarian. Quis readymade 8-bit nisi. </div>
</div>
</body>
</html>

View File

@@ -42,14 +42,40 @@ describe 'Buffer', ->
expect(buffer.getText()).toBe ""
describe "path-change event", ->
afterEach ->
fs.remove("/tmp/moo.text") if fs.exists("/tmp/moo.text")
[path, newPath, bufferToChange, eventHandler] = []
it "emits path-change event when path is changed", ->
beforeEach ->
path = fs.join(require.resolve("fixtures/"), "atom-manipulate-me")
newPath = "#{path}-i-moved"
fs.write(path, "")
bufferToChange = new Buffer(path)
eventHandler = jasmine.createSpy('eventHandler')
buffer.on 'path-change', eventHandler
buffer.saveAs("/tmp/moo.text")
expect(eventHandler).toHaveBeenCalledWith(buffer)
bufferToChange.on 'path-change', eventHandler
afterEach ->
bufferToChange.destroy()
fs.remove(path) if fs.exists(path)
fs.remove(newPath) if fs.exists(newPath)
it "triggers a `path-change` event when path is changed", ->
bufferToChange.saveAs(newPath)
expect(eventHandler).toHaveBeenCalledWith(bufferToChange)
it "triggers a `path-change` event when the file is moved", ->
fs.remove(newPath) if fs.exists(newPath)
fs.move(path, newPath)
waitsFor "buffer path change", ->
eventHandler.callCount > 0
runs ->
expect(eventHandler).toHaveBeenCalledWith(bufferToChange)
it "triggers a `path-change` event when the file is removed", ->
fs.remove(path)
waitsFor "buffer path change", ->
eventHandler.callCount > 0
describe "when the buffer's file is modified (via another process)", ->
path = null
@@ -105,6 +131,18 @@ describe 'Buffer', ->
runs ->
expect(buffer.isModifiedOnDisk()).toBeTruthy()
describe "when the buffer's file is deleted (via another process)", ->
it "no longer has a path", ->
path = "/tmp/atom-file-to-delete.txt"
fs.write(path, '')
bufferToDelete = new Buffer(path)
expect(bufferToDelete.getPath()).toBe path
fs.remove(path)
waitsFor "file to be removed", ->
not bufferToDelete.getPath()
describe ".isModified()", ->
it "returns true when user changes buffer", ->
expect(buffer.isModified()).toBeFalsy()

View File

@@ -2,25 +2,24 @@ File = require 'file'
fs = require 'fs'
describe 'File', ->
file = null
[path, file] = []
beforeEach ->
path = fs.join(require.resolve('fixtures'), "temp.txt")
path = fs.join(require.resolve('fixtures'), "atom-file-test.txt") # Don't put in /tmp because /tmp symlinks to /private/tmp and screws up the rename test
fs.remove(path) if fs.exists(path)
fs.write(path, "this is old!")
file = new File(path)
afterEach ->
file.off()
fs.remove(file.getPath()) if fs.exists(file.getPath())
fs.remove(path) if fs.exists(path)
describe "when the contents of the file change", ->
it "triggers 'contents-change' event handlers", ->
changeHandler = null
runs ->
changeHandler = jasmine.createSpy('changeHandler')
file.on 'contents-change', changeHandler
fs.write(file.getPath(), "this is new!")
changeHandler = jasmine.createSpy('changeHandler')
file.on 'contents-change', changeHandler
fs.write(file.getPath(), "this is new!")
waitsFor "change event", ->
changeHandler.callCount > 0
@@ -31,3 +30,56 @@ describe 'File', ->
waitsFor "second change event", ->
changeHandler.callCount > 0
describe "when the file is removed", ->
it "triggers 'remove' event handlers", ->
removeHandler = null
removeHandler = jasmine.createSpy('removeHandler')
file.on 'remove', removeHandler
fs.remove(file.getPath())
waitsFor "remove event", ->
removeHandler.callCount > 0
describe "when a file is moved (via the filesystem)", ->
newPath = null
beforeEach ->
newPath = fs.join(fs.directory(path), "atom-file-was-moved-test.txt")
afterEach ->
fs.remove(newPath) if fs.exists(newPath)
it "it updates its path", ->
moveHandler = null
moveHandler = jasmine.createSpy('moveHandler')
file.on 'move', moveHandler
fs.move(path, newPath)
waitsFor "move event", ->
moveHandler.callCount > 0
runs ->
expect(file.getPath()).toBe newPath
it "maintains 'contents-change' events set on previous path", ->
moveHandler = null
moveHandler = jasmine.createSpy('moveHandler')
file.on 'move', moveHandler
changeHandler = null
changeHandler = jasmine.createSpy('changeHandler')
file.on 'contents-change', changeHandler
fs.move(path, newPath)
waitsFor "move event", ->
moveHandler.callCount > 0
runs ->
expect(changeHandler).not.toHaveBeenCalled()
fs.write(file.getPath(), "this is new!")
waitsFor "change event", ->
changeHandler.callCount > 0

View File

@@ -29,7 +29,6 @@ describe "CommandPanel", ->
newRootView.remove()
describe "when command-panel:close is triggered on the command panel", ->
it "detaches the command panel", ->
commandPanel.attach()

View File

@@ -610,14 +610,17 @@ describe "TreeView", ->
describe "when the directories along the new path don't exist", ->
it "creates the target directory before moving the file", ->
runs ->
newPath = fs.join(rootDirPath, 'new/directory', 'renamed-test-file.txt')
moveDialog.miniEditor.setText(newPath)
#rootView.project.destroy() # Ensure there are no open buffers (renaming a file asynchronously updates the buffer's path, this causes the afterEach block to unwatch the previous path, which no longer exists.)
moveDialog.trigger 'tree-view:confirm'
newPath = fs.join(rootDirPath, 'new/directory', 'renamed-test-file.txt')
moveDialog.miniEditor.setText(newPath)
expect(fs.exists(newPath)).toBeTruthy()
expect(fs.exists(filePath)).toBeFalsy()
moveDialog.trigger 'tree-view:confirm'
expect(fs.exists(newPath)).toBeTruthy()
expect(fs.exists(filePath)).toBeFalsy()
waits 50 # temporary hack (maybe).
describe "when a file or directory already exists at the target path", ->
it "shows an error message and does not close the dialog", ->

View File

@@ -60,6 +60,13 @@ class Buffer
@setText(fs.read(@file.getPath()))
@modified = false
@file.on "remove", =>
@file = null
@trigger "path-change", this
@file.on "move", =>
@trigger "path-change", this
reload: ->
@setText(fs.read(@file.getPath()))
@modified = false

View File

@@ -29,8 +29,8 @@ class Directory
@unsubscribeFromNativeChangeEvents() if @subscriptionCount() == 0
subscribeToNativeChangeEvents: ->
@watchId = $native.watchPath @path, (eventTypes) =>
@trigger 'contents-change' if eventTypes.modified?
@watchId = $native.watchPath @path, (eventType) =>
@trigger "contents-change" if eventType is "contents-change"
unsubscribeFromNativeChangeEvents: ->
$native.unwatchPath(@path, @watchId)

View File

@@ -12,6 +12,8 @@ class File
throw "Creating file with path that is not a file: #{@path}" unless fs.isFile(@path)
@updateMd5()
setPath: (@path) ->
getPath: ->
@path
@@ -28,9 +30,17 @@ class File
@unsubscribeFromNativeChangeEvents() if @subscriptionCount() == 0
subscribeToNativeChangeEvents: ->
@watchId = $native.watchPath @path, (eventTypes) =>
newMd5 = fs.md5ForPath(@getPath())
if eventTypes.modified? and newMd5 != @md5
@watchId = $native.watchPath @path, (eventType, path) =>
if eventType is "remove"
@trigger "remove"
@off()
else if eventType is "move"
@setPath(path)
@trigger "move"
else if eventType is "contents-change"
newMd5 = fs.md5ForPath(@getPath())
return if newMd5 == @md5
@md5 = newMd5
@trigger 'contents-change'

View File

@@ -18,7 +18,8 @@ class RootView extends View
@content: ->
@div id: 'root-view', tabindex: -1, =>
@div id: 'horizontal', outlet: 'horizontal', =>
@div id: 'panes', outlet: 'panes'
@div id: 'vertical', outlet: 'vertical', =>
@div id: 'panes', outlet: 'panes'
@deserialize: ({ projectPath, panesViewState, extensionStates }) ->
rootView = new RootView(projectPath, extensionStates: extensionStates, suppressOpen: true)

View File

@@ -85,7 +85,7 @@ class CommandPanel extends View
@miniEditor.focus()
attach: (text='') ->
@rootView.append(this)
@rootView.vertical.append(this)
@miniEditor.focus()
@miniEditor.setText(text)
@miniEditor.setCursorBufferPosition([0, Infinity])

View File

@@ -8,7 +8,6 @@ body {
}
#root-view {
height: 100%;
height: 100%;
overflow-y: auto;
position: relative;
@@ -16,26 +15,36 @@ body {
}
#root-view #horizontal {
display: -webkit-flexbox;
display: -webkit-box;
height: 100%;
}
#root-view #vertical {
-webkit-box-flex: 1;
display: -webkit-box;
-webkit-box-orient: vertical;
}
#root-view #panes {
height: 100%;
width: -webkit-flex(1 0);
-webkit-box-flex: 1;
position: relative;
}
#root-view #panes .column {
position: absolute;
width: 100%;
height: 100%;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow-y: hidden;
}
#root-view #panes .row {
position: absolute;
width: 100%;
height: 100%;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow-x: hidden;
}
@@ -43,8 +52,10 @@ body {
position: absolute;
display: -webkit-box;
-webkit-box-orient: vertical;
width: 100%;
height: 100%;
top: 0;
bottom: 0;
left: 0;
right: 0;
box-sizing: border-box;
}

View File

@@ -1,6 +1,4 @@
.command-panel {
position: absolute;
bottom: 0;
width: 100%;
background: #515151;
padding: 3px;

View File

@@ -9,13 +9,17 @@
position: relative;
}
.editor.mini {
height: auto;
}
.editor .flexbox {
display: -webkit-flexbox;
display: -webkit-box;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.editor .gutter {
@@ -51,8 +55,7 @@
.editor .scroll-view {
overflow-x: auto;
overflow-y: hidden;
width: -webkit-flex(1);
height: 100%;
-webkit-box-flex: 1;
}
.editor.mini .scroll-view {