From 4121b2076e99dfdad19d0ee9c4f4d30e4ead7f47 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 5 Jan 2012 11:01:17 -0800 Subject: [PATCH 1/9] Display relative paths in the file finder --- spec/atom/root-view-spec.coffee | 25 ++++++++++++++++++++++--- src/atom/root-view.coffee | 5 +++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/spec/atom/root-view-spec.coffee b/spec/atom/root-view-spec.coffee index 3ba05cfba..5cd656b69 100644 --- a/spec/atom/root-view-spec.coffee +++ b/spec/atom/root-view-spec.coffee @@ -4,11 +4,13 @@ RootView = require 'root-view' describe "RootView", -> rootView = null + project = null url = null beforeEach -> url = require.resolve 'fixtures/dir/a' rootView = RootView.build {url} + project = rootView.project describe "initialize", -> describe "when called with a url that references a file", -> @@ -49,11 +51,17 @@ describe "RootView", -> rootView.toggleFileFinder() expect(rootView.find('.file-finder')).not.toExist() - it "shows all urls for the current project", -> + fit "shows all relative file paths for the current project", -> waitsForPromise -> rootView.toggleFileFinder() - runs -> - expect(rootView.fileFinder.urlList.children('li').length).toBe 3 + + waitsForPromise -> + project.getFilePaths().done (paths) -> + expect(rootView.fileFinder.urlList.children('li').length).toBe paths.length + + for path in paths + relativePath = path.replace(project.url, '') + expect(rootView.fileFinder.urlList.find("li:contains(#{relativePath}):not(:contains(#{project.url}))")).toExist() describe "when there is no project", -> beforeEach -> @@ -65,3 +73,14 @@ describe "RootView", -> rootView.toggleFileFinder() expect(rootView.find('.file-finder')).not.toExist() + fdescribe "when a path is selected in the file finder", -> + it "opens the file associated with that path in the editor", -> + waitsForPromise -> rootView.toggleFileFinder() + runs -> + firstLi = rootView.fileFinder.find('li:first') + rootView.fileFinder.select() + expect(rootView.editor.buffer.url).toBe(project.url + firstLi.text()) + + + + diff --git a/src/atom/root-view.coffee b/src/atom/root-view.coffee index 69c5ce40f..15d088aee 100644 --- a/src/atom/root-view.coffee +++ b/src/atom/root-view.coffee @@ -37,7 +37,8 @@ class RootView extends Template @fileFinder.remove() @fileFinder = null else - @project.getFilePaths().done (urls) => - @fileFinder = FileFinder.build({urls, selected: (url) => @editor.open(url)}) + @project.getFilePaths().done (paths) => + relativePaths = (path.replace(@project.url, "") for path in paths) + @fileFinder = FileFinder.build({urls: relativePaths, selected: (relativePath) => @editor.open(@project.url + relativePath)}) @addPane(@fileFinder) @fileFinder.input.focus() From aee7df0b9f01c46d3ec27465e51f1f0f7ffb23e9 Mon Sep 17 00:00:00 2001 From: Corey Johnson & Nathan Sobo Date: Thu, 5 Jan 2012 11:13:55 -0800 Subject: [PATCH 2/9] Add Editor.setBuffer --- spec/atom/editor-spec.coffee | 15 +++++++++++++++ spec/atom/root-view-spec.coffee | 4 ++-- src/atom/editor.coffee | 7 ++++--- src/atom/root-view.coffee | 4 +++- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/spec/atom/editor-spec.coffee b/spec/atom/editor-spec.coffee index 5e03e9f72..094077dea 100644 --- a/spec/atom/editor-spec.coffee +++ b/spec/atom/editor-spec.coffee @@ -1,3 +1,4 @@ +Buffer = require 'buffer' Editor = require 'editor' $ = require 'jquery' ck = require 'coffeekup' @@ -29,6 +30,20 @@ describe "Editor", -> editor.destroy() expect(editor.aceEditor.destroy).toHaveBeenCalled() + describe "setBuffer(buffer)", -> + it "sets the document on the aceSession", -> + buffer = new Buffer filePath + editor.setBuffer buffer + + fileContents = fs.read(filePath) + expect(editor.getAceSession().getValue()).toBe fileContents + + it "sets the language mode based on the file extension", -> + buffer = new Buffer "something.js" + editor.setBuffer buffer + + expect(editor.getAceSession().getMode().name).toBe 'javascript' + describe "open(url)", -> describe "when called with a url", -> it "loads a buffer for the given url into the editor", -> diff --git a/spec/atom/root-view-spec.coffee b/spec/atom/root-view-spec.coffee index 5cd656b69..a2d3ee5a8 100644 --- a/spec/atom/root-view-spec.coffee +++ b/spec/atom/root-view-spec.coffee @@ -51,7 +51,7 @@ describe "RootView", -> rootView.toggleFileFinder() expect(rootView.find('.file-finder')).not.toExist() - fit "shows all relative file paths for the current project", -> + it "shows all relative file paths for the current project", -> waitsForPromise -> rootView.toggleFileFinder() @@ -73,7 +73,7 @@ describe "RootView", -> rootView.toggleFileFinder() expect(rootView.find('.file-finder')).not.toExist() - fdescribe "when a path is selected in the file finder", -> + describe "when a path is selected in the file finder", -> it "opens the file associated with that path in the editor", -> waitsForPromise -> rootView.toggleFileFinder() runs -> diff --git a/src/atom/editor.coffee b/src/atom/editor.coffee index 7d9a7a7dd..9cf6f3fe7 100644 --- a/src/atom/editor.coffee +++ b/src/atom/editor.coffee @@ -12,7 +12,6 @@ class Editor extends Template viewProperties: aceEditor: null buffer: null - editorElement: null initialize: () -> @buildAceEditor() @@ -24,11 +23,13 @@ class Editor extends Template destroy: -> @aceEditor.destroy() - open: (url) -> - @buffer = new Buffer(url) + setBuffer: (@buffer) -> session = new EditSession(@buffer.aceDocument, @buffer.getMode()) @aceEditor.setSession(session) + open: (url) -> + @setBuffer(new Buffer(url)) + buildAceEditor: -> @aceEditor = ace.edit this[0] @aceEditor.setTheme(require "ace/theme/twilight") diff --git a/src/atom/root-view.coffee b/src/atom/root-view.coffee index 15d088aee..6e51e798f 100644 --- a/src/atom/root-view.coffee +++ b/src/atom/root-view.coffee @@ -39,6 +39,8 @@ class RootView extends Template else @project.getFilePaths().done (paths) => relativePaths = (path.replace(@project.url, "") for path in paths) - @fileFinder = FileFinder.build({urls: relativePaths, selected: (relativePath) => @editor.open(@project.url + relativePath)}) + @fileFinder = FileFinder.build + urls: relativePaths + selected: (relativePath) => @editor.open(@project.url + relativePath) @addPane(@fileFinder) @fileFinder.input.focus() From b5b1ac67fa07b4f9331f8d05a9eb8d60a2f0382d Mon Sep 17 00:00:00 2001 From: Corey Johnson & Nathan Sobo Date: Thu, 5 Jan 2012 11:20:18 -0800 Subject: [PATCH 3/9] Remove slow specs --- spec/atom/app-spec.coffee | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/spec/atom/app-spec.coffee b/spec/atom/app-spec.coffee index 91f4da67c..61d7d01c7 100644 --- a/spec/atom/app-spec.coffee +++ b/spec/atom/app-spec.coffee @@ -14,30 +14,14 @@ describe "App", -> describe "open", -> describe "when opening a filePath", -> - it "displays it in a new window", -> + it "displays it in a new window with the contents of the file loaded", -> filePath = require.resolve 'fixtures/sample.txt' expect(app.windows().length).toBe 0 app.open filePath expect(app.windows().length).toBe 1 - - it "loads a buffer with filePath contents", -> - filePath = require.resolve 'fixtures/sample.txt' - - app.open filePath - newWindow = app.windows()[0] expect(newWindow.rootView.editor.buffer.url).toEqual filePath expect(newWindow.rootView.editor.buffer.getText()).toEqual fs.read(filePath) - describe "when opening a dirPath", -> - it "loads an empty buffer", -> - dirPath = require.resolve 'fixtures' - - app.open dirPath - - newWindow = app.windows()[0] - expect(newWindow.rootView.editor.buffer.url).toBeUndefined - expect(newWindow.rootView.editor.buffer.getText()).toBe "" - From 1c24ad0fddfc9233d1b05071f9d16e422a94ceee Mon Sep 17 00:00:00 2001 From: Corey Johnson & Nathan Sobo Date: Thu, 5 Jan 2012 11:26:14 -0800 Subject: [PATCH 4/9] Eliminate Editor.open --- spec/atom/editor-spec.coffee | 35 ++++++----------------------------- src/atom/editor.coffee | 5 +---- src/atom/root-view.coffee | 7 +++++-- 3 files changed, 12 insertions(+), 35 deletions(-) diff --git a/spec/atom/editor-spec.coffee b/spec/atom/editor-spec.coffee index 094077dea..f47649201 100644 --- a/spec/atom/editor-spec.coffee +++ b/spec/atom/editor-spec.coffee @@ -13,7 +13,6 @@ describe "Editor", -> beforeEach -> filePath = require.resolve 'fixtures/sample.txt' tempFilePath = '/tmp/temp.txt' - spyOn(Editor.prototype.viewProperties, 'open').andCallThrough() editor = Editor.build() afterEach -> @@ -44,41 +43,19 @@ describe "Editor", -> expect(editor.getAceSession().getMode().name).toBe 'javascript' - describe "open(url)", -> - describe "when called with a url", -> - it "loads a buffer for the given url into the editor", -> - editor.open(filePath) - fileContents = fs.read(filePath) - expect(editor.getAceSession().getValue()).toBe fileContents - expect(editor.buffer.url).toBe(filePath) - expect(editor.buffer.getText()).toEqual fileContents - - it "sets the mode on the session based on the file extension", -> - editor.open('something.js') - expect(editor.getAceSession().getMode().name).toBe 'javascript' - - editor.open('something.text') - expect(editor.getAceSession().getMode().name).toBe 'text' - - describe "when called with null", -> - it "loads an empty buffer with no url", -> - editor.open() - expect(editor.getAceSession().getValue()).toBe "" - expect(editor.buffer.url).toBeUndefined() - expect(editor.buffer.getText()).toEqual "" - describe "when the text is changed via the ace editor", -> it "updates the buffer text", -> - editor.open(filePath) - expect(editor.buffer.getText()).not.toMatch /^.ooo/ + buffer = new Buffer(filePath) + editor.setBuffer(buffer) + expect(buffer.getText()).not.toMatch /^.ooo/ editor.getAceSession().insert {row: 0, column: 1}, 'ooo' - expect(editor.buffer.getText()).toMatch /^.ooo/ + expect(buffer.getText()).toMatch /^.ooo/ describe "save", -> describe "when the current buffer has a url", -> beforeEach -> - editor.open tempFilePath - expect(editor.buffer.url).toBe tempFilePath + buffer = new Buffer(tempFilePath) + editor.setBuffer(buffer) it "saves the current buffer to disk", -> editor.buffer.setText 'Edited buffer!' diff --git a/src/atom/editor.coffee b/src/atom/editor.coffee index 9cf6f3fe7..13e387560 100644 --- a/src/atom/editor.coffee +++ b/src/atom/editor.coffee @@ -15,7 +15,7 @@ class Editor extends Template initialize: () -> @buildAceEditor() - @open() + @setBuffer(new Buffer) shutdown: -> @destroy() @@ -27,9 +27,6 @@ class Editor extends Template session = new EditSession(@buffer.aceDocument, @buffer.getMode()) @aceEditor.setSession(session) - open: (url) -> - @setBuffer(new Buffer(url)) - buildAceEditor: -> @aceEditor = ace.edit this[0] @aceEditor.setTheme(require "ace/theme/twilight") diff --git a/src/atom/root-view.coffee b/src/atom/root-view.coffee index 6e51e798f..4c1af06de 100644 --- a/src/atom/root-view.coffee +++ b/src/atom/root-view.coffee @@ -2,6 +2,7 @@ $ = require 'jquery' fs = require 'fs' Template = require 'template' +Buffer = require 'buffer' Editor = require 'editor' FileFinder = require 'file-finder' Project = require 'project' @@ -23,7 +24,7 @@ class RootView extends Template if url @project = new Project(fs.directory(url)) - @editor.open(url) if fs.isFile(url) + @editor.setBuffer(new Buffer(url)) if fs.isFile(url) addPane: (view) -> pane = $('
') @@ -41,6 +42,8 @@ class RootView extends Template relativePaths = (path.replace(@project.url, "") for path in paths) @fileFinder = FileFinder.build urls: relativePaths - selected: (relativePath) => @editor.open(@project.url + relativePath) + selected: (relativePath) => + buffer = new Buffer(@project.url + relativePath) + @editor.setBuffer buffer @addPane(@fileFinder) @fileFinder.input.focus() From 5293ba746942ccabdff6fe61f79715b38d17cd9c Mon Sep 17 00:00:00 2001 From: Corey Johnson & Nathan Sobo Date: Thu, 5 Jan 2012 12:01:55 -0800 Subject: [PATCH 5/9] Add fs.join --- spec/stdlib/fs-spec.coffee | 6 ++++++ src/stdlib/fs.coffee | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/spec/stdlib/fs-spec.coffee b/spec/stdlib/fs-spec.coffee index 66ce34e1b..7c8875b30 100644 --- a/spec/stdlib/fs-spec.coffee +++ b/spec/stdlib/fs-spec.coffee @@ -11,6 +11,12 @@ describe "fs", -> expect(fs.directory(require.resolve('fixtures/dir'))).toBe require.resolve('fixtures/dir/') expect(fs.directory(require.resolve('fixtures/dir/'))).toBe require.resolve('fixtures/dir/') + describe ".join(paths...)", -> + it "concatenates the given paths with the directory seperator", -> + expect(fs.join('a')).toBe 'a' + expect(fs.join('a', 'b', 'c')).toBe 'a/b/c' + expect(fs.join('/a/b/', 'c', 'd')).toBe '/a/b/c/d' + expect(fs.join('a', 'b/c/', 'd/')).toBe 'a/b/c/d/' describe ".async", -> describe ".listFiles(directoryPath, recursive)", -> diff --git a/src/stdlib/fs.coffee b/src/stdlib/fs.coffee index 0950232e9..614da994f 100644 --- a/src/stdlib/fs.coffee +++ b/src/stdlib/fs.coffee @@ -35,6 +35,11 @@ module.exports = exists: (path) -> OSX.NSFileManager.defaultManager.fileExistsAtPath_isDirectory path, null + join: (paths...) -> + return paths[0] if paths.length == 1 + [first, rest...] = paths + first.replace(/\/?$/, "/") + @join(rest...) + # Returns true if the file specified by path exists and is a # directory. isDirectory: (path) -> From 23c3cbf85fe9e6fbd7d4178973e79208cd6d3672 Mon Sep 17 00:00:00 2001 From: Corey Johnson & Nathan Sobo Date: Thu, 5 Jan 2012 12:02:25 -0800 Subject: [PATCH 6/9] Add Project.open, which returns a buffer for an absolute/relative path. --- spec/atom/project-spec.coffee | 13 +++++++++++++ src/atom/project.coffee | 10 ++++++++++ 2 files changed, 23 insertions(+) diff --git a/spec/atom/project-spec.coffee b/spec/atom/project-spec.coffee index 39f6517a6..72032caa0 100644 --- a/spec/atom/project-spec.coffee +++ b/spec/atom/project-spec.coffee @@ -14,3 +14,16 @@ describe "Project", -> project.getFilePaths().done (result) -> expect(result).toEqual(expectedPaths) + describe ".open(path)", -> + absolutePath = null + beforeEach -> + absolutePath = require.resolve('fixtures/dir/a') + + describe "when given an absolute path", -> + it "returns a buffer for the given path", -> + expect(project.open(absolutePath).url).toBe absolutePath + + describe "when given a relative path", -> + it "returns a buffer for the given path (relative to the project root)", -> + expect(project.open('a').url).toBe absolutePath + diff --git a/src/atom/project.coffee b/src/atom/project.coffee index b6a91a791..ca0369f3d 100644 --- a/src/atom/project.coffee +++ b/src/atom/project.coffee @@ -1,4 +1,5 @@ fs = require 'fs' +Buffer = require 'buffer' module.exports = @@ -8,3 +9,12 @@ class Project getFilePaths: -> fs.async.listFiles(@url, true) + open: (filePath) -> + new Buffer(@resolve(filePath)) + + resolve: (filePath) -> + if filePath[0] == '/' + filePath + else + fs.join(@url, filePath) + From 8446b6c751ec4bd2f6d73a847f73d7d1f5c5c382 Mon Sep 17 00:00:00 2001 From: Corey Johnson & Nathan Sobo Date: Thu, 5 Jan 2012 13:08:55 -0800 Subject: [PATCH 7/9] Open buffers with Project.open --- src/atom/root-view.coffee | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/atom/root-view.coffee b/src/atom/root-view.coffee index 4c1af06de..127a1748a 100644 --- a/src/atom/root-view.coffee +++ b/src/atom/root-view.coffee @@ -24,7 +24,7 @@ class RootView extends Template if url @project = new Project(fs.directory(url)) - @editor.setBuffer(new Buffer(url)) if fs.isFile(url) + @editor.setBuffer(@project.open(url)) if fs.isFile(url) addPane: (view) -> pane = $('
') @@ -42,8 +42,6 @@ class RootView extends Template relativePaths = (path.replace(@project.url, "") for path in paths) @fileFinder = FileFinder.build urls: relativePaths - selected: (relativePath) => - buffer = new Buffer(@project.url + relativePath) - @editor.setBuffer buffer + selected: (relativePath) => @editor.setBuffer(@project.open(relativePath)) @addPane(@fileFinder) @fileFinder.input.focus() From 12cf511a407bc4e9c24343f2b6a00b72dea9f43d Mon Sep 17 00:00:00 2001 From: Corey Johnson & Nathan Sobo Date: Thu, 5 Jan 2012 13:10:00 -0800 Subject: [PATCH 8/9] :lipstick: --- src/atom/root-view.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atom/root-view.coffee b/src/atom/root-view.coffee index 127a1748a..eaf4a5bcc 100644 --- a/src/atom/root-view.coffee +++ b/src/atom/root-view.coffee @@ -43,5 +43,5 @@ class RootView extends Template @fileFinder = FileFinder.build urls: relativePaths selected: (relativePath) => @editor.setBuffer(@project.open(relativePath)) - @addPane(@fileFinder) + @addPane @fileFinder @fileFinder.input.focus() From 18b9782b166e186557d760274c6fea8139a8b9ed Mon Sep 17 00:00:00 2001 From: Corey Johnson & Nathan Sobo Date: Thu, 5 Jan 2012 16:33:53 -0800 Subject: [PATCH 9/9] Opening a previously opened url restores the same buffer and session. --- spec/atom/editor-spec.coffee | 12 ++++++++++++ spec/atom/project-spec.coffee | 12 ++++++++++++ spec/stdlib/fs-spec.coffee | 6 ++---- src/atom/editor.coffee | 7 +++++-- src/atom/project.coffee | 12 +++++++----- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/spec/atom/editor-spec.coffee b/spec/atom/editor-spec.coffee index f47649201..9f4f80611 100644 --- a/spec/atom/editor-spec.coffee +++ b/spec/atom/editor-spec.coffee @@ -37,6 +37,18 @@ describe "Editor", -> fileContents = fs.read(filePath) expect(editor.getAceSession().getValue()).toBe fileContents + it "restores the ace edit session for a previously assigned buffer", -> + buffer = new Buffer filePath + editor.setBuffer buffer + + aceSession = editor.getAceSession() + + editor.setBuffer new Buffer(tempFilePath) + expect(editor.getAceSession()).not.toBe(aceSession) + + editor.setBuffer(buffer) + expect(editor.getAceSession()).toBe aceSession + it "sets the language mode based on the file extension", -> buffer = new Buffer "something.js" editor.setBuffer buffer diff --git a/spec/atom/project-spec.coffee b/spec/atom/project-spec.coffee index 72032caa0..9d50de015 100644 --- a/spec/atom/project-spec.coffee +++ b/spec/atom/project-spec.coffee @@ -19,6 +19,11 @@ describe "Project", -> beforeEach -> absolutePath = require.resolve('fixtures/dir/a') + it "always returns the same buffer for the same canonical path", -> + buffer = project.open(absolutePath) + expect(project.open(absolutePath)).toBe buffer + expect(project.open('a')).toBe buffer + describe "when given an absolute path", -> it "returns a buffer for the given path", -> expect(project.open(absolutePath).url).toBe absolutePath @@ -27,3 +32,10 @@ describe "Project", -> it "returns a buffer for the given path (relative to the project root)", -> expect(project.open('a').url).toBe absolutePath + describe ".resolve(path)", -> + it "returns an absolute path based on the project's root", -> + absolutePath = require.resolve('fixtures/dir/a') + expect(project.resolve('a')).toBe absolutePath + expect(project.resolve(absolutePath + '/../a')).toBe absolutePath + expect(project.resolve('a/../a')).toBe absolutePath + diff --git a/spec/stdlib/fs-spec.coffee b/spec/stdlib/fs-spec.coffee index 7c8875b30..1e43de342 100644 --- a/spec/stdlib/fs-spec.coffee +++ b/spec/stdlib/fs-spec.coffee @@ -25,15 +25,13 @@ describe "fs", -> describe "when recursive is true", -> it "returns a promise that resolves to the recursive contents of that directory that are files", -> - waitsFor (complete) -> + waitsForPromise -> fs.async.listFiles(directoryPath, true).done (result) -> expect(result).toEqual (path for path in fs.list(directoryPath, true) when fs.isFile(path)) - complete() describe "when recursive is false", -> it "returns a promise that resolves to the contents of that directory that are files", -> - waitsFor (complete) -> + waitsForPromise -> fs.async.listFiles(directoryPath).done (result) -> expect(result).toEqual (path for path in fs.list(directoryPath) when fs.isFile(path)) - complete() diff --git a/src/atom/editor.coffee b/src/atom/editor.coffee index 13e387560..aafd81c5a 100644 --- a/src/atom/editor.coffee +++ b/src/atom/editor.coffee @@ -14,6 +14,7 @@ class Editor extends Template buffer: null initialize: () -> + @aceSessions = {} @buildAceEditor() @setBuffer(new Buffer) @@ -24,8 +25,10 @@ class Editor extends Template @aceEditor.destroy() setBuffer: (@buffer) -> - session = new EditSession(@buffer.aceDocument, @buffer.getMode()) - @aceEditor.setSession(session) + @aceEditor.setSession @getAceSessionForBuffer(buffer) + + getAceSessionForBuffer: (buffer) -> + @aceSessions[@buffer.url] ?= new EditSession(@buffer.aceDocument, @buffer.getMode()) buildAceEditor: -> @aceEditor = ace.edit this[0] diff --git a/src/atom/project.coffee b/src/atom/project.coffee index ca0369f3d..8e0e134cf 100644 --- a/src/atom/project.coffee +++ b/src/atom/project.coffee @@ -4,17 +4,19 @@ Buffer = require 'buffer' module.exports = class Project + buffers: null + constructor: (@url) -> + @buffers = {} getFilePaths: -> fs.async.listFiles(@url, true) open: (filePath) -> - new Buffer(@resolve(filePath)) + filePath = @resolve filePath + @buffers[filePath] ?= new Buffer(filePath) resolve: (filePath) -> - if filePath[0] == '/' - filePath - else - fs.join(@url, filePath) + filePath = fs.join(@url, filePath) unless filePath[0] == '/' + fs.absolute filePath