From 6c4294dda92d33802b7f543175208ed041a5dab8 Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Wed, 10 Apr 2013 16:59:12 -0700 Subject: [PATCH 01/19] fix typo --- src/app/pane.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/pane.coffee b/src/app/pane.coffee index 166fd7e90..371bd6095 100644 --- a/src/app/pane.coffee +++ b/src/app/pane.coffee @@ -163,7 +163,7 @@ class Pane extends View uri = item.getUri() atom.confirm( "'#{item.getTitle?() ? item.getUri()}' has changes, do you want to save them?" - "Your changes will be lost if close this item without saving." + "Your changes will be lost if you close this item without saving." "Save", => @saveItem(item, nextAction) "Cancel", cancelAction "Don't Save", nextAction From 1ae878c00067007c181a9566037ec1ecdf45d9d8 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 10 Apr 2013 17:32:46 -0700 Subject: [PATCH 02/19] Fire will-be-removed event from beforeRemove() --- spec/app/editor-spec.coffee | 12 ++++++++++++ src/app/editor.coffee | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index 868226f5f..5e6ed1c5d 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -2563,3 +2563,15 @@ describe "Editor", -> editor.trigger('editor:scroll-to-cursor') expect(editor.getFirstVisibleScreenRow()).toBe 0 expect(editor.getLastVisibleScreenRow()).toBe 2 + + describe "when the editor is removed", -> + it "fires a editor:will-be-removed event", -> + window.rootView = new RootView + rootView.open('sample.js') + rootView.attachToDom() + editor = rootView.getActiveView() + + willBeRemovedHandler = jasmine.createSpy('fileChange') + editor.on 'editor:will-be-removed', willBeRemovedHandler + editor.getPane().destroyActiveItem() + expect(willBeRemovedHandler).toHaveBeenCalled() diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 1f66b8a42..9645585d7 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -676,11 +676,11 @@ class Editor extends View remove: (selector, keepData) -> return super if keepData or @removed - @trigger 'editor:will-be-removed' super rootView?.focus() beforeRemove: -> + @trigger 'editor:will-be-removed' @removed = true @activeEditSession?.destroy() $(window).off(".editor-#{@id}") From 99e573006e1e18dc8b274728ba5cf1929fc2db24 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 10 Apr 2013 21:54:54 -0700 Subject: [PATCH 03/19] Upgrade to pathwatcher 0.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fda9c4579..bcecc183c 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "async": "0.2.6", "nak": "0.2.12", "spellchecker": "0.3.0", - "pathwatcher": "0.1.5", + "pathwatcher": "0.3.0", "plist": "git://github.com/nathansobo/node-plist.git", "space-pen": "git://github.com/nathansobo/space-pen.git" }, From 89b0d7efdbfe7e7a34fba9b155ecfaa16b3c20db Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 10 Apr 2013 22:17:14 -0700 Subject: [PATCH 04/19] :lipstick: --- src/packages/git-diff/lib/git-diff-view.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/packages/git-diff/lib/git-diff-view.coffee b/src/packages/git-diff/lib/git-diff-view.coffee index bff48f146..fc1fc070f 100644 --- a/src/packages/git-diff/lib/git-diff-view.coffee +++ b/src/packages/git-diff/lib/git-diff-view.coffee @@ -54,13 +54,13 @@ class GitDiffView hunks = @diffs[@editor.getPath()] ? [] linesHighlighted = 0 - for hunk in hunks - if hunk.oldLines is 0 and hunk.newLines > 0 - for row in [hunk.newStart...hunk.newStart + hunk.newLines] + for {oldStart, newStart, oldLines, newLines} in hunks + if oldLines is 0 and newLines > 0 + for row in [newStart...newStart + newLines] linesHighlighted += @gutter.find(".line-number[lineNumber=#{row - 1}]").addClass('git-line-added').length - else if hunk.newLines is 0 and hunk.oldLines > 0 - linesHighlighted += @gutter.find(".line-number[lineNumber=#{hunk.newStart - 1}]").addClass('git-line-removed').length + else if newLines is 0 and oldLines > 0 + linesHighlighted += @gutter.find(".line-number[lineNumber=#{newStart - 1}]").addClass('git-line-removed').length else - for row in [hunk.newStart...hunk.newStart + hunk.newLines] + for row in [newStart...newStart + newLines] linesHighlighted += @gutter.find(".line-number[lineNumber=#{row - 1}]").addClass('git-line-modified').length @gutter.hasGitLineDiffs = linesHighlighted > 0 From 26a4ff912174b0188f375c3705e23ba7f8d8fcd6 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 10 Apr 2013 22:20:21 -0700 Subject: [PATCH 05/19] DRY up how diffs are generated and rendered --- .../git-diff/lib/git-diff-view.coffee | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/packages/git-diff/lib/git-diff-view.coffee b/src/packages/git-diff/lib/git-diff-view.coffee index fc1fc070f..2256ca7f2 100644 --- a/src/packages/git-diff/lib/git-diff-view.coffee +++ b/src/packages/git-diff/lib/git-diff-view.coffee @@ -13,10 +13,10 @@ class GitDiffView @editor.on 'editor:display-updated', => @renderDiffs() git.on 'statuses-changed', => @diffs = {} - @scheduleDiffs() + @scheduleUpdate() git.on 'status-changed', (path) => delete @diffs[path] - @scheduleDiffs() if path is @editor.getPath() + @scheduleUpdate() if path is @editor.getPath() @subscribeToBuffer() @@ -28,15 +28,15 @@ class GitDiffView @buffer = null if @buffer = @editor.getBuffer() - @scheduleDiffs() unless @diffs[@buffer.getPath()]? - @buffer.on 'contents-modified.git-diff', => - @generateDiffs() - @renderDiffs() + @scheduleUpdate() unless @diffs[@buffer.getPath()]? + @buffer.on 'contents-modified.git-diff', => @updateDiffs() - scheduleDiffs: -> - _.nextTick => - @generateDiffs() - @renderDiffs() + scheduleUpdate: -> + _.nextTick => @updateDiffs() + + updateDiffs: -> + @generateDiffs() + @renderDiffs() generateDiffs: -> if path = @buffer.getPath() From 2e6735ecd002c2db861b0024d7924246391458c9 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 10 Apr 2013 22:23:17 -0700 Subject: [PATCH 06/19] Extend Subscriber from GitDiffView --- src/packages/git-diff/lib/git-diff-view.coffee | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/packages/git-diff/lib/git-diff-view.coffee b/src/packages/git-diff/lib/git-diff-view.coffee index 2256ca7f2..1172e0c95 100644 --- a/src/packages/git-diff/lib/git-diff-view.coffee +++ b/src/packages/git-diff/lib/git-diff-view.coffee @@ -1,4 +1,5 @@ _ = require 'underscore' +Subscriber = require 'subscriber' module.exports = class GitDiffView @@ -9,17 +10,20 @@ class GitDiffView @gutter = @editor.gutter @diffs = {} - @editor.on 'editor:path-changed', => @subscribeToBuffer() - @editor.on 'editor:display-updated', => @renderDiffs() - git.on 'statuses-changed', => + @subscribe @editor, 'editor:path-changed', => @subscribeToBuffer() + @subscribe @editor, 'editor:display-updated', => @renderDiffs() + @subscribe git, 'statuses-changed', => @diffs = {} @scheduleUpdate() - git.on 'status-changed', (path) => + @subscribe git, 'status-changed', (path) => delete @diffs[path] @scheduleUpdate() if path is @editor.getPath() @subscribeToBuffer() + beforeRemove: -> + @unsubscribe() + subscribeToBuffer: -> if @buffer? @removeDiffs() @@ -64,3 +68,5 @@ class GitDiffView for row in [newStart...newStart + newLines] linesHighlighted += @gutter.find(".line-number[lineNumber=#{row - 1}]").addClass('git-line-modified').length @gutter.hasGitLineDiffs = linesHighlighted > 0 + +_.extend GitDiffView.prototype, Subscriber From 461aaa83b0383f51376e4dd0b2ea38f93f6fafae Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 11 Apr 2013 08:53:01 -0700 Subject: [PATCH 07/19] Unsubscribe correctly from buffers in packages Previously namespaces were used to off() when a buffer was unsubscribed from which affected other views in the same package also listening to the current buffer. Now event namespaces are no longer used and instead off() is called with the callbacks originally registered for the given event name. --- .../git-diff/lib/git-diff-view.coffee | 22 ++++++++++-------- .../spell-check/lib/spell-check-view.coffee | 23 +++++++++---------- .../status-bar/lib/status-bar-view.coffee | 22 ++++++++++++------ 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/packages/git-diff/lib/git-diff-view.coffee b/src/packages/git-diff/lib/git-diff-view.coffee index 1172e0c95..f4fe50089 100644 --- a/src/packages/git-diff/lib/git-diff-view.coffee +++ b/src/packages/git-diff/lib/git-diff-view.coffee @@ -10,8 +10,8 @@ class GitDiffView @gutter = @editor.gutter @diffs = {} - @subscribe @editor, 'editor:path-changed', => @subscribeToBuffer() - @subscribe @editor, 'editor:display-updated', => @renderDiffs() + @subscribe @editor, 'editor:path-changed', @subscribeToBuffer + @subscribe @editor, 'editor:display-updated', @renderDiffs @subscribe git, 'statuses-changed', => @diffs = {} @scheduleUpdate() @@ -23,22 +23,26 @@ class GitDiffView beforeRemove: -> @unsubscribe() + @unsubscribeFromBuffer() - subscribeToBuffer: -> + unsubscribeFromBuffer: -> if @buffer? @removeDiffs() delete @diffs[@buffer.getPath()] if @buffer.destroyed - @buffer.off '.git-diff' + @buffer.off 'contents-modified', @updateDiffs @buffer = null + subscribeToBuffer: => + @unsubscribeFromBuffer() + if @buffer = @editor.getBuffer() @scheduleUpdate() unless @diffs[@buffer.getPath()]? - @buffer.on 'contents-modified.git-diff', => @updateDiffs() + @buffer.on 'contents-modified', @updateDiffs scheduleUpdate: -> - _.nextTick => @updateDiffs() + _.nextTick(@updateDiffs) - updateDiffs: -> + updateDiffs: => @generateDiffs() @renderDiffs() @@ -46,12 +50,12 @@ class GitDiffView if path = @buffer.getPath() @diffs[path] = git?.getLineDiffs(path, @buffer.getText()) - removeDiffs: -> + removeDiffs: => if @gutter.hasGitLineDiffs @gutter.find('.line-number').removeClass('git-line-added git-line-modified git-line-removed') @gutter.hasGitLineDiffs = false - renderDiffs: -> + renderDiffs: => return unless @gutter.isVisible() @removeDiffs() diff --git a/src/packages/spell-check/lib/spell-check-view.coffee b/src/packages/spell-check/lib/spell-check-view.coffee index 3f5bba2d6..40f856802 100644 --- a/src/packages/spell-check/lib/spell-check-view.coffee +++ b/src/packages/spell-check/lib/spell-check-view.coffee @@ -11,27 +11,30 @@ class SpellCheckView extends View views: [] initialize: (@editor) -> - @subscribe @editor, 'editor:path-changed', => @subscribeToBuffer() - @subscribe @editor, 'editor:grammar-changed', => @subscribeToBuffer() - @observeConfig 'editor.fontSize', => @subscribeToBuffer() - @observeConfig 'spell-check.grammars', => @subscribeToBuffer() + @subscribe @editor, 'editor:path-changed', @subscribeToBuffer + @subscribe @editor, 'editor:grammar-changed', @subscribeToBuffer + @observeConfig 'editor.fontSize', @subscribeToBuffer + @observeConfig 'spell-check.grammars', @subscribeToBuffer @subscribeToBuffer() + beforeRemove: -> + @unsubscribeFromBuffer() + unsubscribeFromBuffer: -> @destroyViews() @task?.abort() if @buffer? - @buffer.off '.spell-check' + @buffer.off 'contents-modified', @updateMisspellings @buffer = null - subscribeToBuffer: -> + subscribeToBuffer: => @unsubscribeFromBuffer() if @spellCheckCurrentGrammar() @buffer = @editor.getBuffer() - @buffer.on 'contents-modified.spell-check', => @updateMisspellings() + @buffer.on 'contents-modified', @updateMisspellings @updateMisspellings() spellCheckCurrentGrammar: -> @@ -49,11 +52,7 @@ class SpellCheckView extends View @views.push(view) @append(view) - updateMisspellings: -> - unless @editor.activeEditSession? - @unsubscribeFromBuffer() - return - + updateMisspellings: => @task?.abort() callback = (misspellings) => diff --git a/src/packages/status-bar/lib/status-bar-view.coffee b/src/packages/status-bar/lib/status-bar-view.coffee index 7a2f95a8a..50897f1e7 100644 --- a/src/packages/status-bar/lib/status-bar-view.coffee +++ b/src/packages/status-bar/lib/status-bar-view.coffee @@ -35,23 +35,31 @@ class StatusBarView extends View if git? @subscribe git, 'status-changed', (path, status) => @updateStatusBar() if path is @getActiveItemPath() - @subscribe git, 'statuses-changed', => - @updateStatusBar() + @subscribe git, 'statuses-changed', @updateStatusBar @subscribeToBuffer() + beforeRemove: -> + @unsubscribeFromBuffer() + getActiveItemPath: -> @pane.activeItem?.getPath?() + unsubscribeFromBuffer: -> + if @buffer? + @buffer.off 'modified-status-changed', @updateBufferHasModifiedText + @buffer.off 'saved', @updateStatusBar + @buffer = null + subscribeToBuffer: -> - @buffer?.off '.status-bar' + @unsubscribeFromBuffer() if @buffer = @pane.activeItem.getBuffer?() - @buffer.on 'modified-status-changed.status-bar', (isModified) => @updateBufferHasModifiedText(isModified) - @buffer.on 'saved.status-bar', => @updateStatusBar() + @buffer.on 'modified-status-changed', @updateBufferHasModifiedText + @buffer.on 'saved', @updateStatusBar @updateStatusBar() - updateStatusBar: -> + updateStatusBar: => @updateGrammarText() @updateBranchText() @updateBufferHasModifiedText(@buffer?.isModified()) @@ -65,7 +73,7 @@ class StatusBarView extends View else @grammarName.text(grammar.name).show() - updateBufferHasModifiedText: (isModified)-> + updateBufferHasModifiedText: (isModified) => if isModified @bufferModified.text('*') unless @isModified @isModified = true From 4e596057285c6fd1662c57aab818c0b74f63423d Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 11 Apr 2013 10:39:19 -0700 Subject: [PATCH 08/19] Don't bubble move-to-top/bottom events This will cause the editor to scroll as well when a select list is a child of an editor such as in the autocomplete view. --- spec/app/select-list-spec.coffee | 14 ++++++++++++-- src/app/select-list.coffee | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/spec/app/select-list-spec.coffee b/spec/app/select-list-spec.coffee index 5702fe546..0e3dec287 100644 --- a/spec/app/select-list-spec.coffee +++ b/spec/app/select-list-spec.coffee @@ -169,14 +169,24 @@ describe "SelectList", -> expect(selectList.detach).toHaveBeenCalled() describe "the core:move-to-top event", -> - it "scrolls to the top and selects the first element", -> + it "scrolls to the top, selects the first element, and does not bubble the event", -> + selectList.attachToDom() + moveToTopHandler = jasmine.createSpy("moveToTopHandler") + selectList.parent().on 'core:move-to-top', moveToTopHandler + selectList.trigger 'core:move-down' expect(list.find('li:eq(1)')).toHaveClass 'selected' selectList.trigger 'core:move-to-top' expect(list.find('li:first')).toHaveClass 'selected' + expect(moveToTopHandler).not.toHaveBeenCalled() describe "the core:move-to-bottom event", -> - it "scrolls to the bottom and selects the last element", -> + it "scrolls to the bottom, selects the last element, and does not bubble the event", -> + selectList.attachToDom() + moveToBottomHandler = jasmine.createSpy("moveToBottomHandler") + selectList.parent().on 'core:move-to-bottom', moveToBottomHandler + expect(list.find('li:first')).toHaveClass 'selected' selectList.trigger 'core:move-to-bottom' expect(list.find('li:last')).toHaveClass 'selected' + expect(moveToBottomHandler).not.toHaveBeenCalled() diff --git a/src/app/select-list.coffee b/src/app/select-list.coffee index 9dbbd077a..4051a4fff 100644 --- a/src/app/select-list.coffee +++ b/src/app/select-list.coffee @@ -29,9 +29,11 @@ class SelectList extends View @on 'core:move-to-top', => @selectItem(@list.find('li:first')) @list.scrollToTop() + false @on 'core:move-to-bottom', => @selectItem(@list.find('li:last')) @list.scrollToBottom() + false @on 'core:confirm', => @confirmSelection() @on 'core:cancel', => @cancel() From b1e79b4634a658570b505c42e3ab6f22458790a3 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 11 Apr 2013 12:53:32 -0600 Subject: [PATCH 09/19] Run `rake clean` on prebuild to clear out node_modules --- script/constructicon/prebuild | 1 + 1 file changed, 1 insertion(+) diff --git a/script/constructicon/prebuild b/script/constructicon/prebuild index b759683d2..9bc18eb97 100755 --- a/script/constructicon/prebuild +++ b/script/constructicon/prebuild @@ -4,4 +4,5 @@ set -ex cd "$(dirname "$0")/../.." export PATH="/usr/local/Cellar/node/0.8.21/bin:/usr/local/bin:${PATH}" export VERSION=$VERSION +rake clean rake setup-codesigning create-xcode-project From 7967dada4b1677f2839761ef2469dd4b3fc959da Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 11 Apr 2013 13:07:16 -0600 Subject: [PATCH 10/19] Make script/bootstrap exit on subprocess errors --- script/bootstrap | 3 +++ 1 file changed, 3 insertions(+) diff --git a/script/bootstrap b/script/bootstrap index a2898082a..023f52c80 100755 --- a/script/bootstrap +++ b/script/bootstrap @@ -1,5 +1,8 @@ #!/bin/sh +# exit on subprocess errors +set -o errexit + exit_unless_xcode_exists() { if [ ! -d /Applications/Xcode.app ]; then echo "ERROR: Atom requires Xcode" From 78dc676f0f1c220c611789d605880d2e7f69e90f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 11 Apr 2013 12:31:38 -0700 Subject: [PATCH 11/19] Exclude .less/.cson/.coffee files at root of src Previously the rsync exclude rules required files to be two-levels deep to be excluded which would keep the window-bootstrap.coffee in the bundle since it was at the root of the src folder. Now if cson, less, or coffee files end up in src/ they will be correctly excluded from the bundle when synced. --- script/copy-files-to-bundle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script/copy-files-to-bundle b/script/copy-files-to-bundle index e3f6de315..586db807f 100755 --- a/script/copy-files-to-bundle +++ b/script/copy-files-to-bundle @@ -8,8 +8,8 @@ RESOUCES_PATH="$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH" # Copy non-coffee files into bundle rsync --archive --recursive \ - --exclude="src/**/*.coffee" --exclude="src/**/*.cson" \ - --exclude="src/**/*.less" --exclude="static/*.less" \ + --exclude="src/**.coffee" --exclude="src/**.cson" \ + --exclude="src/**.less" --exclude="static/**.less" \ --exclude="node_modules/less" \ node_modules src static vendor spec benchmark themes dot-atom atom.sh \ "${COMPILED_SOURCES_DIR}/" "$RESOUCES_PATH" From ee7a90184b4e8afed41b09345e734be85edbeda9 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 11 Apr 2013 14:18:22 -0700 Subject: [PATCH 12/19] Make autocomplete wide enough to not scroll --- .../autocomplete/lib/autocomplete-view.coffee | 14 ++++++++++++-- .../autocomplete/spec/autocomplete-spec.coffee | 9 +++++++++ .../autocomplete/stylesheets/autocomplete.less | 12 ++++++++++++ static/popover-list.less | 3 ++- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/packages/autocomplete/lib/autocomplete-view.coffee b/src/packages/autocomplete/lib/autocomplete-view.coffee index e559e7a97..5fd19d29e 100644 --- a/src/packages/autocomplete/lib/autocomplete-view.coffee +++ b/src/packages/autocomplete/lib/autocomplete-view.coffee @@ -1,3 +1,4 @@ +$ = require 'jquery' {$$} = require 'space-pen' Range = require 'range' SelectList = require 'select-list' @@ -22,7 +23,8 @@ class AutocompleteView extends SelectList itemForElement: (match) -> $$ -> - @li match.word + @li => + @span match.word handleEvents: -> @editor.on 'editor:path-changed', => @setCurrentBuffer(@editor.getBuffer()) @@ -156,7 +158,15 @@ class AutocompleteView extends SelectList {prefix, suffix} + afterAttach: (onDom) -> + if onDom + widestCompletion = 0 + @list.find('span').each -> + widestCompletion = Math.max(widestCompletion, $(this).outerWidth()) + @list.width(widestCompletion) + @width(@list.outerWidth()) + populateList: -> - super() + super @setPosition() diff --git a/src/packages/autocomplete/spec/autocomplete-spec.coffee b/src/packages/autocomplete/spec/autocomplete-spec.coffee index 0bc25a3f0..f91cfb16b 100644 --- a/src/packages/autocomplete/spec/autocomplete-spec.coffee +++ b/src/packages/autocomplete/spec/autocomplete-spec.coffee @@ -416,3 +416,12 @@ describe "AutocompleteView", -> editor.trigger 'core:move-up' expect(editor.getCursorBufferPosition().row).toBe 0 + + it "sets the width of the view to be wide enough to contain the longest completion without scrolling", -> + editor.attachToDom() + editor.insertText('thisIsAReallyReallyReallyLongCompletion ') + editor.moveCursorToBottom() + editor.insertNewline + editor.insertText('t') + autocomplete.attach() + expect(autocomplete.list.prop('scrollWidth')).toBe autocomplete.list.width() diff --git a/src/packages/autocomplete/stylesheets/autocomplete.less b/src/packages/autocomplete/stylesheets/autocomplete.less index 9142f6a5e..1c7a332e7 100644 --- a/src/packages/autocomplete/stylesheets/autocomplete.less +++ b/src/packages/autocomplete/stylesheets/autocomplete.less @@ -8,3 +8,15 @@ overflow-y: scroll; max-height: 200px; } + +.select-list.autocomplete ol li { + padding-top: 5px; + padding-bottom: 5px; + padding-left: 0px; + padding-right: 0px; +} + +.autocomplete span { + padding-left: 5px; + padding-right: 5px; +} diff --git a/static/popover-list.less b/static/popover-list.less index 005b4a36a..4d33416e9 100644 --- a/static/popover-list.less +++ b/static/popover-list.less @@ -1,5 +1,6 @@ .select-list.popover-list { width: 200px; + min-width: 200px; border: 2px solid #222; -webkit-box-shadow: 0 0 3px 3px rgba(0, 0, 0, .5); margin-left: 0px; @@ -14,4 +15,4 @@ .select-list.popover-list ol li { padding: 5px; -} \ No newline at end of file +} From 75da75158a39a5f6fff5894422707914880fdc5e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 11 Apr 2013 14:24:40 -0700 Subject: [PATCH 13/19] Default width to min-width property --- src/packages/autocomplete/lib/autocomplete-view.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/autocomplete/lib/autocomplete-view.coffee b/src/packages/autocomplete/lib/autocomplete-view.coffee index 5fd19d29e..c34f75c43 100644 --- a/src/packages/autocomplete/lib/autocomplete-view.coffee +++ b/src/packages/autocomplete/lib/autocomplete-view.coffee @@ -160,7 +160,7 @@ class AutocompleteView extends SelectList afterAttach: (onDom) -> if onDom - widestCompletion = 0 + widestCompletion = parseInt(@css('min-width')) or 0 @list.find('span').each -> widestCompletion = Math.max(widestCompletion, $(this).outerWidth()) @list.width(widestCompletion) From 224e01102c3a50d371126f99f9238965e0f81951 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 11 Apr 2013 14:37:25 -0700 Subject: [PATCH 14/19] Use path.join() of fsUtils.join() --- .../symbols-view/lib/load-tags-handler.coffee | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/packages/symbols-view/lib/load-tags-handler.coffee b/src/packages/symbols-view/lib/load-tags-handler.coffee index c29957822..bf5c5a38f 100644 --- a/src/packages/symbols-view/lib/load-tags-handler.coffee +++ b/src/packages/symbols-view/lib/load-tags-handler.coffee @@ -1,16 +1,17 @@ ctags = require 'ctags' fsUtils = require 'fs-utils' +path = require 'path' module.exports = - getTagsFile: (path) -> - tagsFile = fsUtils.join(path, "tags") + getTagsFile: (tagsFilePath) -> + tagsFile = path.join(tagsFilePath, "tags") return tagsFile if fsUtils.isFile(tagsFile) - tagsFile = fsUtils.join(path, "TAGS") + tagsFile = path.join(tagsFilePath, "TAGS") return tagsFile if fsUtils.isFile(tagsFile) - loadTags: (path) -> - tagsFile = @getTagsFile(path) + loadTags: (tagsFilePath) -> + tagsFile = @getTagsFile(tagsFilePath) if tagsFile callTaskMethod("tagsLoaded", ctags.getTags(tagsFile)) else From 235cd1fbff374243958b458dac4d17f4462fb3cd Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 11 Apr 2013 15:31:59 -0700 Subject: [PATCH 15/19] Add initial .nakignore file --- .nakignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .nakignore diff --git a/.nakignore b/.nakignore new file mode 100644 index 000000000..660678d6b --- /dev/null +++ b/.nakignore @@ -0,0 +1,3 @@ +tags +node_modules +vendor/packages From 9a3821b97e5efadded7407ab7767bafebb01b295 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 12 Apr 2013 10:20:14 -0700 Subject: [PATCH 16/19] Quit message loop when last browser is closed Previously CefShutdown() was called after closing the windows which would prevent them from running their beforeunload callbacks and saving state properly when cmd-Q the application. Now the number of open browsers is tracked and the message loop is quit and the windows are autoreleased only after the browser is ready to be closed. Closes #493 --- native/atom_application.mm | 6 ++-- native/atom_cef_client.cpp | 12 ++++++-- native/atom_cef_client.h | 3 ++ native/atom_cef_client_mac.mm | 9 +++++- native/atom_main_mac.mm | 1 + native/atom_window_controller.mm | 52 ++++++++++++++++++-------------- 6 files changed, 55 insertions(+), 28 deletions(-) diff --git a/native/atom_application.mm b/native/atom_application.mm index 9c9824579..5fbc1b9db 100644 --- a/native/atom_application.mm +++ b/native/atom_application.mm @@ -265,11 +265,13 @@ } } -- (void)applicationWillTerminate:(NSNotification *)notification { +- (NSApplicationTerminateReply)applicationShouldTerminate: + (NSApplication *)sender { for (NSWindow *window in [self windows]) { [window performClose:self]; } - CefShutdown(); + + return NSTerminateCancel; } # pragma mark CefAppProtocol diff --git a/native/atom_cef_client.cpp b/native/atom_cef_client.cpp index 8c697fba8..c142206c4 100644 --- a/native/atom_cef_client.cpp +++ b/native/atom_cef_client.cpp @@ -1,6 +1,7 @@ #include #include #include +#include "include/cef_app.h" #include "include/cef_path_util.h" #include "include/cef_process_util.h" #include "include/cef_task.h" @@ -14,7 +15,9 @@ #define REQUIRE_IO_THREAD() assert(CefCurrentlyOn(TID_IO)); #define REQUIRE_FILE_THREAD() assert(CefCurrentlyOn(TID_FILE)); -AtomCefClient::AtomCefClient(){ +static int numberOfOpenBrowsers = 0; + +AtomCefClient::AtomCefClient() { } AtomCefClient::AtomCefClient(bool handlePasteboardCommands, bool ignoreTitleChanges) { @@ -167,17 +170,22 @@ bool AtomCefClient::OnKeyEvent(CefRefPtr browser, void AtomCefClient::OnBeforeClose(CefRefPtr browser) { // REQUIRE_UI_THREAD(); // When uncommented this fails when app is terminated m_Browser = NULL; + numberOfOpenBrowsers--; + if (numberOfOpenBrowsers == 0) { + CefQuitMessageLoop(); + } } void AtomCefClient::OnAfterCreated(CefRefPtr browser) { REQUIRE_UI_THREAD(); AutoLock lock_scope(this); - if (!m_Browser.get()) { + if (!m_Browser.get()) { m_Browser = browser; } GetBrowser()->GetHost()->SetFocus(true); + numberOfOpenBrowsers++; } void AtomCefClient::OnLoadError(CefRefPtr browser, diff --git a/native/atom_cef_client.h b/native/atom_cef_client.h index 0e49194b5..6ca5c7e87 100644 --- a/native/atom_cef_client.h +++ b/native/atom_cef_client.h @@ -86,6 +86,7 @@ class AtomCefClient : public CefClient, // CefLifeSpanHandler methods virtual void OnAfterCreated(CefRefPtr browser) OVERRIDE; virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE; + virtual bool DoClose(CefRefPtr browser) OVERRIDE; // CefLoadHandler methods @@ -100,11 +101,13 @@ class AtomCefClient : public CefClient, bool Save(const std::string& path, const std::string& data); void RestartRendererProcess(CefRefPtr browser); + bool IsClosed() { return m_IsClosed; }; protected: CefRefPtr m_Browser; bool m_HandlePasteboardCommands = false; bool m_IgnoreTitleChanges = false; + bool m_IsClosed = false; void FocusNextWindow(); void FocusPreviousWindow(); diff --git a/native/atom_cef_client_mac.mm b/native/atom_cef_client_mac.mm index 4be8f3592..73ff381bf 100644 --- a/native/atom_cef_client_mac.mm +++ b/native/atom_cef_client_mac.mm @@ -156,7 +156,7 @@ void AtomCefClient::Exit(int status) { } void AtomCefClient::Log(const char *message) { - std::cout << message << "\n"; + NSLog(@"%s", message); } void AtomCefClient::GetVersion(int replyId, CefRefPtr browser) { @@ -169,3 +169,10 @@ void AtomCefClient::GetVersion(int replyId, CefRefPtr browser) { replyArguments->SetList(0, CreateReplyDescriptor(replyId, 0)); browser->SendProcessMessage(PID_RENDERER, replyMessage); } + +bool AtomCefClient::DoClose(CefRefPtr browser) { + m_IsClosed = true; + NSWindow *window = [browser->GetHost()->GetWindowHandle() window]; + [window performClose:window]; + return false; +} diff --git a/native/atom_main_mac.mm b/native/atom_main_mac.mm index ed1f3c3ca..4de9cb605 100644 --- a/native/atom_main_mac.mm +++ b/native/atom_main_mac.mm @@ -32,6 +32,7 @@ int AtomMain(int argc, char* argv[]) { [mainNib instantiateWithOwner:application topLevelObjects:nil]; CefRunMessageLoop(); + CefShutdown(); } return 0; diff --git a/native/atom_window_controller.mm b/native/atom_window_controller.mm index efb838b3e..b3d4bff7f 100644 --- a/native/atom_window_controller.mm +++ b/native/atom_window_controller.mm @@ -177,6 +177,10 @@ [self addBrowserToView:self.webView url:[urlString UTF8String] cefHandler:_cefClient]; } +- (BOOL)isBrowserUsable { + return _cefClient && !_cefClient->IsClosed() && _cefClient->GetBrowser(); +} + - (void)toggleDevTools { if (_devToolsView) { [self hideDevTools]; @@ -188,22 +192,21 @@ - (void)showDevTools { if (_devToolsView) return; + if (![self isBrowserUsable]) return; - if (_cefClient && _cefClient->GetBrowser()) { - NSRect webViewFrame = _webView.frame; - NSRect devToolsViewFrame = _webView.frame; - devToolsViewFrame.size.height = NSHeight(webViewFrame) / 3; - webViewFrame.size.height = NSHeight(webViewFrame) - NSHeight(devToolsViewFrame); - [_webView setFrame:webViewFrame]; - _devToolsView = [[NSView alloc] initWithFrame:devToolsViewFrame]; + NSRect webViewFrame = _webView.frame; + NSRect devToolsViewFrame = _webView.frame; + devToolsViewFrame.size.height = NSHeight(webViewFrame) / 3; + webViewFrame.size.height = NSHeight(webViewFrame) - NSHeight(devToolsViewFrame); + [_webView setFrame:webViewFrame]; + _devToolsView = [[NSView alloc] initWithFrame:devToolsViewFrame]; - [_splitView addSubview:_devToolsView]; - [_splitView adjustSubviews]; + [_splitView addSubview:_devToolsView]; + [_splitView adjustSubviews]; - _cefDevToolsClient = new AtomCefClient(true, true); - std::string devtools_url = _cefClient->GetBrowser()->GetHost()->GetDevToolsURL(true); - [self addBrowserToView:_devToolsView url:devtools_url.c_str() cefHandler:_cefDevToolsClient]; - } + _cefDevToolsClient = new AtomCefClient(true, true); + std::string devtools_url = _cefClient->GetBrowser()->GetHost()->GetDevToolsURL(true); + [self addBrowserToView:_devToolsView url:devtools_url.c_str() cefHandler:_cefDevToolsClient]; } - (void)hideDevTools { @@ -212,17 +215,19 @@ [_devToolsView release]; _devToolsView = nil; _cefDevToolsClient = NULL; - _cefClient->GetBrowser()->GetHost()->SetFocus(true); + if ([self isBrowserUsable]) { + _cefClient->GetBrowser()->GetHost()->SetFocus(true); + } } - (void)openPath:(NSString*)path { - if (_cefClient && _cefClient->GetBrowser()) { - CefRefPtr openMessage = CefProcessMessage::Create("openPath"); - CefRefPtr openArguments = openMessage->GetArgumentList(); - openArguments->SetSize(1); - openArguments->SetString(0, [path UTF8String]); - _cefClient->GetBrowser()->SendProcessMessage(PID_RENDERER, openMessage); - } + if (![self isBrowserUsable]) return; + + CefRefPtr openMessage = CefProcessMessage::Create("openPath"); + CefRefPtr openArguments = openMessage->GetArgumentList(); + openArguments->SetSize(1); + openArguments->SetString(0, [path UTF8String]); + _cefClient->GetBrowser()->SendProcessMessage(PID_RENDERER, openMessage); } - (void)setPidToKillOnClose:(NSNumber *)pid { @@ -239,14 +244,15 @@ } - (void)windowDidBecomeMain:(NSNotification *)notification { - if (_cefClient && _cefClient->GetBrowser()) { + if ([self isBrowserUsable]) { _cefClient->GetBrowser()->GetHost()->SetFocus(true); } } - (BOOL)windowShouldClose:(NSNotification *)notification { - if (_cefClient && _cefClient->GetBrowser()) { + if ([self isBrowserUsable]) { _cefClient->GetBrowser()->GetHost()->CloseBrowser(false); + return NO; } if (_pidToKillOnClose) kill([_pidToKillOnClose intValue], SIGQUIT); From 26638980bf24d29b82a7924338c2ff2d67c7abee Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 12 Apr 2013 11:09:58 -0700 Subject: [PATCH 17/19] Upgrade to git-utils 0.14 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bcecc183c..0e21a4cd7 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "ctags": "0.3.0", "oniguruma": "0.8.0", "mkdirp": "0.3.5", - "git-utils": "0.13.0", + "git-utils": "0.14.0", "underscore": "1.4.4", "d3": "3.0.8", "coffee-cache": "0.1.0", From 7b42e975fb85197d3973b55d7817d692751a0ced Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 12 Apr 2013 11:47:11 -0700 Subject: [PATCH 18/19] Include hidden files when running nak --- spec/app/project-spec.coffee | 16 ++++++++++++++++ src/app/project.coffee | 2 +- .../fuzzy-finder/lib/load-paths-task.coffee | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/spec/app/project-spec.coffee b/spec/app/project-spec.coffee index dffdd8152..6c0a777df 100644 --- a/spec/app/project-spec.coffee +++ b/spec/app/project-spec.coffee @@ -284,6 +284,22 @@ describe "Project", -> expect(paths.length).toBe 0 expect(matches.length).toBe 0 + it "includes files and folders that begin with a '.'", -> + projectPath = '/tmp/atom-tests/folder-with-dot-file' + filePath = fsUtils.join(projectPath, '.text') + fsUtils.write(filePath, 'match this') + project.setPath(projectPath) + paths = [] + matches = [] + waitsForPromise -> + project.scan /match this/, ({path, match, range}) -> + paths.push(path) + matches.push(match) + + runs -> + expect(paths.length).toBe 1 + expect(paths[0]).toBe filePath + expect(matches.length).toBe 1 describe "serialization", -> it "restores the project path", -> diff --git a/src/app/project.coffee b/src/app/project.coffee index 8ff23f274..d0b5a2ce6 100644 --- a/src/app/project.coffee +++ b/src/app/project.coffee @@ -196,7 +196,7 @@ class Project readLine(line) if state is 'readingLines' command = require.resolve('nak') - args = ['--ackmate', regex.source, @getPath()] + args = ['--hidden', '--ackmate', regex.source, @getPath()] args.unshift("--addVCSIgnores") if config.get('core.excludeVcsIgnoredPaths') new BufferedProcess({command, args, stdout, exit}) deferred diff --git a/src/packages/fuzzy-finder/lib/load-paths-task.coffee b/src/packages/fuzzy-finder/lib/load-paths-task.coffee index bb358db8e..15f7ff112 100644 --- a/src/packages/fuzzy-finder/lib/load-paths-task.coffee +++ b/src/packages/fuzzy-finder/lib/load-paths-task.coffee @@ -15,6 +15,7 @@ class LoadPathsTask args.unshift('--addVCSIgnores') if config.get('core.excludeVcsIgnoredPaths') args.unshift('--ignore', ignoredNames.join(',')) if ignoredNames.length > 0 args.unshift('--follow') + args.unshift('--hidden') paths = [] exit = (code) => From 558e41f74034759eec44bd09a7292cb8338de97a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 13 Apr 2013 10:24:58 +0800 Subject: [PATCH 19/19] Make main window restart renderer process when reloaded for 4 times. Fix #495. --- src/app/window.coffee | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/app/window.coffee b/src/app/window.coffee index 490351c70..db8a73992 100644 --- a/src/app/window.coffee +++ b/src/app/window.coffee @@ -164,13 +164,11 @@ window.reload = -> timesReloaded = process.global.timesReloaded ? 0 ++timesReloaded - restartValue = if window.location.search.indexOf('spec-bootstrap') == -1 then 10 else 3 - - if timesReloaded > restartValue + if timesReloaded > 3 atom.restartRendererProcess() else - $native.reload() process.global.timesReloaded = timesReloaded + $native.reload() window.onerror = -> atom.showDevTools()