mirror of
https://github.com/atom/atom.git
synced 2026-02-06 20:55:33 -05:00
Merge remote-tracking branch 'origin/dev' into cefode
This commit is contained in:
@@ -17,8 +17,8 @@ describe "Autocomplete", ->
|
||||
autocompletePackage = window.loadPackage("autocomplete")
|
||||
expect(AutocompleteView.prototype.initialize).not.toHaveBeenCalled()
|
||||
|
||||
leftEditor = rootView.getActiveEditor()
|
||||
rightEditor = rootView.getActiveEditor().splitRight()
|
||||
leftEditor = rootView.getActiveView()
|
||||
rightEditor = leftEditor.splitRight()
|
||||
|
||||
leftEditor.trigger 'autocomplete:attach'
|
||||
expect(leftEditor.find('.autocomplete')).toExist()
|
||||
@@ -40,7 +40,7 @@ describe "AutocompleteView", ->
|
||||
|
||||
beforeEach ->
|
||||
window.rootView = new RootView
|
||||
editor = new Editor(editSession: fixturesProject.buildEditSessionForPath('sample.js'))
|
||||
editor = new Editor(editSession: project.buildEditSession('sample.js'))
|
||||
window.loadPackage('autocomplete')
|
||||
autocomplete = new AutocompleteView(editor)
|
||||
miniEditor = autocomplete.miniEditor
|
||||
|
||||
@@ -7,7 +7,7 @@ describe "Autoflow package", ->
|
||||
window.rootView = new RootView
|
||||
rootView.open()
|
||||
window.loadPackage 'autoflow'
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
config.set('editor.preferredLineLength', 30)
|
||||
|
||||
describe "autoflow:reflow-paragraph", ->
|
||||
|
||||
@@ -8,7 +8,7 @@ describe "bracket matching", ->
|
||||
rootView.open('sample.js')
|
||||
window.loadPackage('bracket-matcher')
|
||||
rootView.attachToDom()
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
editSession = editor.activeEditSession
|
||||
buffer = editSession.buffer
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ describe "CommandLogger", ->
|
||||
rootView.open('sample.js')
|
||||
commandLogger = window.loadPackage('command-logger').packageMain
|
||||
commandLogger.eventLog = {}
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
|
||||
describe "when a command is triggered", ->
|
||||
it "records the number of times the command is triggered", ->
|
||||
|
||||
@@ -19,8 +19,8 @@ describe "CommandPalette", ->
|
||||
|
||||
describe "when command-palette:toggle is triggered on the root view", ->
|
||||
it "shows a list of all valid command descriptions, names, and keybindings for the previously focused element", ->
|
||||
keyBindings = _.losslessInvert(keymap.bindingsForElement(rootView.getActiveEditor()))
|
||||
for eventName, description of rootView.getActiveEditor().events()
|
||||
keyBindings = _.losslessInvert(keymap.bindingsForElement(rootView.getActiveView()))
|
||||
for eventName, description of rootView.getActiveView().events()
|
||||
eventLi = palette.list.children("[data-event-name='#{eventName}']")
|
||||
if description
|
||||
expect(eventLi).toExist()
|
||||
@@ -32,7 +32,7 @@ describe "CommandPalette", ->
|
||||
expect(eventLi).not.toExist()
|
||||
|
||||
it "displays all commands registerd on the window", ->
|
||||
editorEvents = rootView.getActiveEditor().events()
|
||||
editorEvents = rootView.getActiveView().events()
|
||||
windowEvents = $(window).events()
|
||||
expect(_.isEmpty(windowEvents)).toBeFalsy()
|
||||
for eventName, description of windowEvents
|
||||
@@ -60,19 +60,19 @@ describe "CommandPalette", ->
|
||||
expect(palette.hasParent()).toBeTruthy()
|
||||
palette.trigger 'command-palette:toggle'
|
||||
expect(palette.hasParent()).toBeFalsy()
|
||||
expect(rootView.getActiveEditor().isFocused).toBeTruthy()
|
||||
expect(rootView.getActiveView().isFocused).toBeTruthy()
|
||||
|
||||
describe "when the command palette is cancelled", ->
|
||||
it "focuses the root view and detaches the command palette", ->
|
||||
expect(palette.hasParent()).toBeTruthy()
|
||||
palette.cancel()
|
||||
expect(palette.hasParent()).toBeFalsy()
|
||||
expect(rootView.getActiveEditor().isFocused).toBeTruthy()
|
||||
expect(rootView.getActiveView().isFocused).toBeTruthy()
|
||||
|
||||
describe "when an command selection is confirmed", ->
|
||||
it "detaches the palette, then focuses the previously focused element and emits the selected command on it", ->
|
||||
eventHandler = jasmine.createSpy 'eventHandler'
|
||||
activeEditor = rootView.getActiveEditor()
|
||||
activeEditor = rootView.getActiveView()
|
||||
{eventName} = palette.array[5]
|
||||
activeEditor.preempt eventName, eventHandler
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ class CommandPanelView extends View
|
||||
@errorMessages.empty()
|
||||
|
||||
try
|
||||
@commandInterpreter.eval(command, rootView.getActiveEditSession()).done ({operationsToPreview, errorMessages}) =>
|
||||
@commandInterpreter.eval(command, rootView.getActivePaneItem()).done ({operationsToPreview, errorMessages}) =>
|
||||
@loadingMessage.hide()
|
||||
@history.push(command)
|
||||
@historyIndex = @history.length
|
||||
@@ -155,12 +155,12 @@ class CommandPanelView extends View
|
||||
@miniEditor.setText(@history[@historyIndex] or '')
|
||||
|
||||
repeatRelativeAddress: ->
|
||||
@commandInterpreter.repeatRelativeAddress(rootView.getActiveEditSession())
|
||||
@commandInterpreter.repeatRelativeAddress(rootView.getActivePaneItem())
|
||||
|
||||
repeatRelativeAddressInReverse: ->
|
||||
@commandInterpreter.repeatRelativeAddressInReverse(rootView.getActiveEditSession())
|
||||
@commandInterpreter.repeatRelativeAddressInReverse(rootView.getActivePaneItem())
|
||||
|
||||
setSelectionAsLastRelativeAddress: ->
|
||||
selection = rootView.getActiveEditor().getSelectedText()
|
||||
selection = rootView.getActiveView().getSelectedText()
|
||||
regex = _.escapeRegExp(selection)
|
||||
@commandInterpreter.lastRelativeAddress = new CompositeCommand([new RegexAddress(regex)])
|
||||
|
||||
@@ -6,12 +6,11 @@ EditSession = require 'edit-session'
|
||||
_ = require 'underscore'
|
||||
|
||||
describe "CommandInterpreter", ->
|
||||
[project, interpreter, editSession, buffer] = []
|
||||
[interpreter, editSession, buffer] = []
|
||||
|
||||
beforeEach ->
|
||||
project = new Project(fixturesProject.resolve('dir/'))
|
||||
interpreter = new CommandInterpreter(fixturesProject)
|
||||
editSession = fixturesProject.buildEditSessionForPath('sample.js')
|
||||
interpreter = new CommandInterpreter(project)
|
||||
editSession = project.buildEditSession('sample.js')
|
||||
buffer = editSession.buffer
|
||||
|
||||
afterEach ->
|
||||
@@ -418,7 +417,7 @@ describe "CommandInterpreter", ->
|
||||
describe "X x/regex/", ->
|
||||
it "returns selection operations for all regex matches in all the project's files", ->
|
||||
editSession.destroy()
|
||||
project = new Project(fixturesProject.resolve('dir/'))
|
||||
project.setPath(project.resolve('dir'))
|
||||
interpreter = new CommandInterpreter(project)
|
||||
|
||||
operationsToPreview = null
|
||||
@@ -428,7 +427,7 @@ describe "CommandInterpreter", ->
|
||||
runs ->
|
||||
expect(operationsToPreview.length).toBeGreaterThan 3
|
||||
for operation in operationsToPreview
|
||||
editSession = project.buildEditSessionForPath(operation.getPath())
|
||||
editSession = project.buildEditSession(operation.getPath())
|
||||
editSession.setSelectedBufferRange(operation.execute(editSession))
|
||||
expect(editSession.getSelectedText()).toMatch /a+/
|
||||
editSession.destroy()
|
||||
|
||||
@@ -3,14 +3,14 @@ CommandPanelView = require 'command-panel/lib/command-panel-view'
|
||||
_ = require 'underscore'
|
||||
|
||||
describe "CommandPanel", ->
|
||||
[editor, buffer, commandPanel] = []
|
||||
[editSession, buffer, commandPanel] = []
|
||||
|
||||
beforeEach ->
|
||||
window.rootView = new RootView
|
||||
rootView.open('sample.js')
|
||||
rootView.enableKeymap()
|
||||
editor = rootView.getActiveEditor()
|
||||
buffer = editor.activeEditSession.buffer
|
||||
editSession = rootView.getActivePaneItem()
|
||||
buffer = editSession.buffer
|
||||
commandPanelMain = window.loadPackage('command-panel', activateImmediately: true).packageMain
|
||||
commandPanel = commandPanelMain.commandPanelView
|
||||
commandPanel.history = []
|
||||
@@ -219,41 +219,41 @@ describe "CommandPanel", ->
|
||||
it "repeats the last search command if there is one", ->
|
||||
rootView.trigger 'command-panel:repeat-relative-address'
|
||||
|
||||
editor.setCursorScreenPosition([4, 0])
|
||||
editSession.setCursorScreenPosition([4, 0])
|
||||
|
||||
commandPanel.execute("/current")
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[5,6], [5,13]]
|
||||
expect(editSession.getSelectedBufferRange()).toEqual [[5,6], [5,13]]
|
||||
|
||||
rootView.trigger 'command-panel:repeat-relative-address'
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[6,6], [6,13]]
|
||||
expect(editSession.getSelectedBufferRange()).toEqual [[6,6], [6,13]]
|
||||
|
||||
commandPanel.execute('s/r/R/g')
|
||||
|
||||
rootView.trigger 'command-panel:repeat-relative-address'
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[6,34], [6,41]]
|
||||
expect(editSession.getSelectedBufferRange()).toEqual [[6,34], [6,41]]
|
||||
|
||||
commandPanel.execute('0')
|
||||
commandPanel.execute('/sort/ s/r/R/') # this contains a substitution... won't be repeated
|
||||
|
||||
rootView.trigger 'command-panel:repeat-relative-address'
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[3,31], [3,38]]
|
||||
expect(editSession.getSelectedBufferRange()).toEqual [[3,31], [3,38]]
|
||||
|
||||
describe "when command-panel:repeat-relative-address-in-reverse is triggered on the root view", ->
|
||||
it "it repeats the last relative address in the reverse direction", ->
|
||||
rootView.trigger 'command-panel:repeat-relative-address-in-reverse'
|
||||
|
||||
editor.setCursorScreenPosition([6, 0])
|
||||
editSession.setCursorScreenPosition([6, 0])
|
||||
|
||||
commandPanel.execute("/current")
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[6,6], [6,13]]
|
||||
expect(editSession.getSelectedBufferRange()).toEqual [[6,6], [6,13]]
|
||||
|
||||
rootView.trigger 'command-panel:repeat-relative-address-in-reverse'
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[5,6], [5,13]]
|
||||
expect(editSession.getSelectedBufferRange()).toEqual [[5,6], [5,13]]
|
||||
|
||||
describe "when command-panel:set-selection-as-regex-address is triggered on the root view", ->
|
||||
it "sets the @lastRelativeAddress to a RegexAddress of the current selection", ->
|
||||
rootView.open(require.resolve('fixtures/sample.js'))
|
||||
rootView.getActiveEditor().setSelectedBufferRange([[1,21],[1,28]])
|
||||
rootView.getActivePaneItem().setSelectedBufferRange([[1,21],[1,28]])
|
||||
|
||||
commandInterpreter = commandPanel.commandInterpreter
|
||||
expect(commandInterpreter.lastRelativeAddress).toBeUndefined()
|
||||
@@ -267,7 +267,7 @@ describe "CommandPanel", ->
|
||||
commandPanel.miniEditor.setText("foo")
|
||||
commandPanel.miniEditor.setCursorBufferPosition([0, 0])
|
||||
|
||||
rootView.getActiveEditor().trigger "command-panel:find-in-file"
|
||||
rootView.getActiveView().trigger "command-panel:find-in-file"
|
||||
expect(commandPanel.attach).toHaveBeenCalled()
|
||||
expect(commandPanel.parent).not.toBeEmpty()
|
||||
expect(commandPanel.miniEditor.getText()).toBe "/"
|
||||
@@ -297,8 +297,8 @@ describe "CommandPanel", ->
|
||||
|
||||
describe "when the command returns operations to be previewed", ->
|
||||
beforeEach ->
|
||||
rootView.getActivePane().remove()
|
||||
rootView.attachToDom()
|
||||
editor.remove()
|
||||
rootView.trigger 'command-panel:toggle'
|
||||
waitsForPromise -> commandPanel.execute('X x/quicksort/')
|
||||
|
||||
@@ -350,16 +350,14 @@ describe "CommandPanel", ->
|
||||
expect(commandPanel).toBeVisible()
|
||||
expect(commandPanel.errorMessages).not.toBeVisible()
|
||||
|
||||
|
||||
describe "when the command contains an escaped character", ->
|
||||
it "executes the command with the escaped character (instead of as a backslash followed by the character)", ->
|
||||
rootView.trigger 'command-panel:toggle'
|
||||
|
||||
editSession = rootView.open(require.resolve 'fixtures/sample-with-tabs.coffee')
|
||||
editor.edit(editSession)
|
||||
commandPanel.miniEditor.setText "/\\tsell"
|
||||
commandPanel.miniEditor.hiddenInput.trigger keydownEvent('enter')
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[3,1],[3,6]]
|
||||
expect(editSession.getSelectedBufferRange()).toEqual [[3,1],[3,6]]
|
||||
|
||||
describe "when move-up and move-down are triggerred on the editor", ->
|
||||
it "navigates forward and backward through the command history", ->
|
||||
@@ -470,11 +468,11 @@ describe "CommandPanel", ->
|
||||
|
||||
previewList.trigger 'core:confirm'
|
||||
|
||||
editSession = rootView.getActiveEditSession()
|
||||
editSession = rootView.getActivePaneItem()
|
||||
expect(editSession.buffer.getPath()).toBe project.resolve(operation.getPath())
|
||||
expect(editSession.getSelectedBufferRange()).toEqual operation.getBufferRange()
|
||||
expect(editSession.getSelectedBufferRange()).toEqual operation.getBufferRange()
|
||||
expect(editor.isScreenRowVisible(editor.getCursorScreenRow())).toBeTruthy()
|
||||
expect(rootView.getActiveView().isScreenRowVisible(editSession.getCursorScreenRow())).toBeTruthy()
|
||||
expect(previewList.focus).toHaveBeenCalled()
|
||||
|
||||
expect(executeHandler).not.toHaveBeenCalled()
|
||||
@@ -496,7 +494,7 @@ describe "CommandPanel", ->
|
||||
previewList.find('li.operation:eq(4) span').mousedown()
|
||||
|
||||
expect(previewList.getSelectedOperation()).toBe operation
|
||||
editSession = rootView.getActiveEditSession()
|
||||
editSession = rootView.getActivePaneItem()
|
||||
expect(editSession.buffer.getPath()).toBe project.resolve(operation.getPath())
|
||||
expect(editSession.getSelectedBufferRange()).toEqual operation.getBufferRange()
|
||||
expect(previewList.focus).toHaveBeenCalled()
|
||||
|
||||
@@ -22,19 +22,18 @@ class FuzzyFinderView extends SelectList
|
||||
|
||||
@subscribe $(window), 'focus', => @reloadProjectPaths = true
|
||||
@observeConfig 'fuzzy-finder.ignoredNames', => @reloadProjectPaths = true
|
||||
rootView.eachEditor (editor) ->
|
||||
editor.activeEditSession.lastOpened = (new Date) - 1
|
||||
editor.on 'editor:active-edit-session-changed', (e, editSession, index) ->
|
||||
editSession.lastOpened = (new Date) - 1
|
||||
rootView.eachPane (pane) ->
|
||||
pane.activeItem.lastOpened = (new Date) - 1
|
||||
pane.on 'pane:active-item-changed', (e, item) -> item.lastOpened = (new Date) - 1
|
||||
|
||||
@miniEditor.command 'editor:split-left', =>
|
||||
@splitOpenPath (editor, session) -> editor.splitLeft(session)
|
||||
@miniEditor.command 'editor:split-right', =>
|
||||
@splitOpenPath (editor, session) -> editor.splitRight(session)
|
||||
@miniEditor.command 'editor:split-down', =>
|
||||
@splitOpenPath (editor, session) -> editor.splitDown(session)
|
||||
@miniEditor.command 'editor:split-up', =>
|
||||
@splitOpenPath (editor, session) -> editor.splitUp(session)
|
||||
@miniEditor.command 'pane:split-left', =>
|
||||
@splitOpenPath (pane, session) -> pane.splitLeft(session)
|
||||
@miniEditor.command 'pane:split-right', =>
|
||||
@splitOpenPath (pane, session) -> pane.splitRight(session)
|
||||
@miniEditor.command 'pane:split-down', =>
|
||||
@splitOpenPath (pane, session) -> pane.splitDown(session)
|
||||
@miniEditor.command 'pane:split-up', =>
|
||||
@splitOpenPath (pane, session) -> pane.splitUp(session)
|
||||
|
||||
itemForElement: (path) ->
|
||||
$$ ->
|
||||
@@ -70,10 +69,8 @@ class FuzzyFinderView extends SelectList
|
||||
splitOpenPath: (fn) ->
|
||||
path = @getSelectedElement()
|
||||
return unless path
|
||||
|
||||
editor = rootView.getActiveEditor()
|
||||
if editor
|
||||
fn(editor, project.buildEditSessionForPath(path))
|
||||
if pane = rootView.getActivePane()
|
||||
fn(pane, project.buildEditSession(path))
|
||||
else
|
||||
@openPath(path)
|
||||
|
||||
@@ -118,7 +115,7 @@ class FuzzyFinderView extends SelectList
|
||||
else
|
||||
return unless project.getPath()?
|
||||
@allowActiveEditorChange = false
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
currentWord = editor.getWordUnderCursor(wordRegex: @filenameRegex)
|
||||
|
||||
if currentWord.length == 0
|
||||
@@ -177,7 +174,7 @@ class FuzzyFinderView extends SelectList
|
||||
editSession.getPath()?
|
||||
|
||||
editSessions = _.sortBy editSessions, (editSession) =>
|
||||
if editSession is rootView.getActiveEditSession()
|
||||
if editSession is rootView.getActivePaneItem()
|
||||
0
|
||||
else
|
||||
-(editSession.lastOpened or 1)
|
||||
|
||||
@@ -21,8 +21,8 @@ describe 'FuzzyFinder', ->
|
||||
it "shows the FuzzyFinder or hides it and returns focus to the active editor if it already showing", ->
|
||||
rootView.attachToDom()
|
||||
expect(rootView.find('.fuzzy-finder')).not.toExist()
|
||||
rootView.find('.editor').trigger 'editor:split-right'
|
||||
[editor1, editor2] = rootView.find('.editor').map -> $(this).view()
|
||||
rootView.getActiveView().splitRight()
|
||||
[editor1, editor2] = rootView.getEditors()
|
||||
|
||||
expect(rootView.find('.fuzzy-finder')).not.toExist()
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
@@ -72,13 +72,13 @@ describe 'FuzzyFinder', ->
|
||||
describe "when a path selection is confirmed", ->
|
||||
it "opens the file associated with that path in the editor", ->
|
||||
rootView.attachToDom()
|
||||
editor1 = rootView.getActiveEditor()
|
||||
editor1 = rootView.getActiveView()
|
||||
editor2 = editor1.splitRight()
|
||||
expect(rootView.getActiveEditor()).toBe editor2
|
||||
expect(rootView.getActiveView()).toBe editor2
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
|
||||
finderView.confirmed('dir/a')
|
||||
expectedPath = fixturesProject.resolve('dir/a')
|
||||
expectedPath = project.resolve('dir/a')
|
||||
|
||||
expect(finderView.hasParent()).toBeFalsy()
|
||||
expect(editor1.getPath()).not.toBe expectedPath
|
||||
@@ -88,26 +88,26 @@ describe 'FuzzyFinder', ->
|
||||
describe "when the selected path isn't a file that exists", ->
|
||||
it "leaves the the tree view open, doesn't open the path in the editor, and displays an error", ->
|
||||
rootView.attachToDom()
|
||||
path = rootView.getActiveEditor().getPath()
|
||||
path = rootView.getActiveView().getPath()
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
finderView.confirmed('dir/this/is/not/a/file.txt')
|
||||
expect(finderView.hasParent()).toBeTruthy()
|
||||
expect(rootView.getActiveEditor().getPath()).toBe path
|
||||
expect(rootView.getActiveView().getPath()).toBe path
|
||||
expect(finderView.find('.error').text().length).toBeGreaterThan 0
|
||||
advanceClock(2000)
|
||||
expect(finderView.find('.error').text().length).toBe 0
|
||||
|
||||
describe "buffer-finder behavior", ->
|
||||
describe "toggling", ->
|
||||
describe "when the active editor contains edit sessions for buffers with paths", ->
|
||||
describe "when there are pane items with paths", ->
|
||||
beforeEach ->
|
||||
rootView.open('sample.txt')
|
||||
|
||||
it "shows the FuzzyFinder or hides it, returning focus to the active editor if", ->
|
||||
it "shows the FuzzyFinder if it isn't showing, or hides it and returns focus to the active editor", ->
|
||||
rootView.attachToDom()
|
||||
expect(rootView.find('.fuzzy-finder')).not.toExist()
|
||||
rootView.find('.editor').trigger 'editor:split-right'
|
||||
[editor1, editor2] = rootView.find('.editor').map -> $(this).view()
|
||||
rootView.getActiveView().splitRight()
|
||||
[editor1, editor2] = rootView.getEditors()
|
||||
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
expect(rootView.find('.fuzzy-finder')).toExist()
|
||||
@@ -122,26 +122,17 @@ describe 'FuzzyFinder', ->
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
expect(finderView.miniEditor.getText()).toBe ''
|
||||
|
||||
it "lists the paths of the current open buffers by most recently modified", ->
|
||||
it "lists the paths of the current items, sorted by most recently opened but with the current item last", ->
|
||||
rootView.attachToDom()
|
||||
rootView.open 'sample-with-tabs.coffee'
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
children = finderView.list.children('li')
|
||||
expect(children.get(0).outerText).toBe "sample.txt"
|
||||
expect(children.get(1).outerText).toBe "sample.js"
|
||||
expect(children.get(2).outerText).toBe "sample-with-tabs.coffee"
|
||||
expect(_.pluck(finderView.list.children('li'), 'outerText')).toEqual ['sample.txt', 'sample.js', 'sample-with-tabs.coffee']
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
|
||||
rootView.open 'sample.txt'
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
children = finderView.list.children('li')
|
||||
expect(children.get(0).outerText).toBe "sample-with-tabs.coffee"
|
||||
expect(children.get(1).outerText).toBe "sample.js"
|
||||
expect(children.get(2).outerText).toBe "sample.txt"
|
||||
|
||||
expect(finderView.list.children('li').length).toBe 3
|
||||
expect(finderView.list.find("li:contains(sample.js)")).toExist()
|
||||
expect(finderView.list.find("li:contains(sample.txt)")).toExist()
|
||||
expect(finderView.list.find("li:contains(sample-with-tabs.coffee)")).toExist()
|
||||
expect(_.pluck(finderView.list.children('li'), 'outerText')).toEqual ['sample-with-tabs.coffee', 'sample.js', 'sample.txt']
|
||||
expect(finderView.list.children().first()).toHaveClass 'selected'
|
||||
|
||||
it "serializes the list of paths and their last opened time", ->
|
||||
@@ -151,29 +142,26 @@ describe 'FuzzyFinder', ->
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
rootView.open()
|
||||
|
||||
states = rootView.serialize().packageStates
|
||||
states = rootView.serialize().packages
|
||||
states = _.map states['fuzzy-finder'], (path, time) -> [ path, time ]
|
||||
states = _.sortBy states, (path, time) -> -time
|
||||
|
||||
paths = [ 'sample-with-tabs.coffee', 'sample.txt', 'sample.js' ]
|
||||
|
||||
for [time, path] in states
|
||||
expect(_.last path.split '/').toBe paths.shift()
|
||||
expect(time).toBeGreaterThan 50000
|
||||
|
||||
describe "when the active editor only contains edit sessions for anonymous buffers", ->
|
||||
describe "when there are only panes with anonymous items", ->
|
||||
it "does not open", ->
|
||||
editor = rootView.getActiveEditor()
|
||||
editor.edit(project.buildEditSessionForPath())
|
||||
editor.loadPreviousEditSession()
|
||||
editor.destroyActiveEditSession()
|
||||
expect(editor.getOpenBufferPaths().length).toBe 0
|
||||
rootView.getActivePane().remove()
|
||||
rootView.open()
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
expect(rootView.find('.fuzzy-finder')).not.toExist()
|
||||
|
||||
describe "when there is no active editor", ->
|
||||
describe "when there are no pane items", ->
|
||||
it "does not open", ->
|
||||
rootView.getActiveEditor().destroyActiveEditSession()
|
||||
expect(rootView.getActiveEditor()).toBeUndefined()
|
||||
rootView.getActivePane().remove()
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
expect(rootView.find('.fuzzy-finder')).not.toExist()
|
||||
|
||||
@@ -182,16 +170,16 @@ describe 'FuzzyFinder', ->
|
||||
|
||||
beforeEach ->
|
||||
rootView.attachToDom()
|
||||
editor1 = rootView.getActiveEditor()
|
||||
editor1 = rootView.getActiveView()
|
||||
editor2 = editor1.splitRight()
|
||||
expect(rootView.getActiveEditor()).toBe editor2
|
||||
expect(rootView.getActiveView()).toBe editor2
|
||||
rootView.open('sample.txt')
|
||||
editor2.loadPreviousEditSession()
|
||||
editor2.trigger 'pane:show-previous-item'
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
|
||||
describe "when there is an edit session for the confirmed path in the active editor", ->
|
||||
it "switches the active editor to the edit session for the selected path", ->
|
||||
expectedPath = fixturesProject.resolve('sample.txt')
|
||||
describe "when the active pane has an item for the selected path", ->
|
||||
it "switches to the item for the selected path", ->
|
||||
expectedPath = project.resolve('sample.txt')
|
||||
finderView.confirmed('sample.txt')
|
||||
|
||||
expect(finderView.hasParent()).toBeFalsy()
|
||||
@@ -199,27 +187,26 @@ describe 'FuzzyFinder', ->
|
||||
expect(editor2.getPath()).toBe expectedPath
|
||||
expect(editor2.isFocused).toBeTruthy()
|
||||
|
||||
describe "when there is NO edit session for the confirmed path on the active editor, but there is one on another editor", ->
|
||||
it "focuses the editor that contains an edit session for the selected path", ->
|
||||
describe "when the active pane does not have an item for the selected path", ->
|
||||
it "adds a new item to the active pane for the selcted path", ->
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
editor1.focus()
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
|
||||
expect(rootView.getActiveEditor()).toBe editor1
|
||||
expect(rootView.getActiveView()).toBe editor1
|
||||
|
||||
expectedPath = fixturesProject.resolve('sample.txt')
|
||||
expectedPath = project.resolve('sample.txt')
|
||||
finderView.confirmed('sample.txt')
|
||||
|
||||
expect(finderView.hasParent()).toBeFalsy()
|
||||
expect(editor1.getPath()).not.toBe expectedPath
|
||||
expect(editor2.getPath()).toBe expectedPath
|
||||
expect(editor2.isFocused).toBeTruthy()
|
||||
expect(editor1.getPath()).toBe expectedPath
|
||||
expect(editor1.isFocused).toBeTruthy()
|
||||
|
||||
describe "git-status-finder behavior", ->
|
||||
[originalText, originalPath, newPath] = []
|
||||
|
||||
beforeEach ->
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
originalText = editor.getText()
|
||||
originalPath = editor.getPath()
|
||||
fs.write(originalPath, 'making a change for the better')
|
||||
@@ -248,7 +235,7 @@ describe 'FuzzyFinder', ->
|
||||
describe "when an editor is open", ->
|
||||
it "detaches the finder and focuses the previously focused element", ->
|
||||
rootView.attachToDom()
|
||||
activeEditor = rootView.getActiveEditor()
|
||||
activeEditor = rootView.getActiveView()
|
||||
activeEditor.focus()
|
||||
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
@@ -265,7 +252,7 @@ describe 'FuzzyFinder', ->
|
||||
describe "when no editors are open", ->
|
||||
it "detaches the finder and focuses the previously focused element", ->
|
||||
rootView.attachToDom()
|
||||
rootView.getActiveEditor().destroyActiveEditSession()
|
||||
rootView.getActivePane().remove()
|
||||
|
||||
inputView = $$ -> @input()
|
||||
rootView.append(inputView)
|
||||
@@ -351,7 +338,7 @@ describe 'FuzzyFinder', ->
|
||||
editor = null
|
||||
|
||||
beforeEach ->
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
rootView.attachToDom()
|
||||
|
||||
it "opens the fuzzy finder window when there are multiple matches", ->
|
||||
@@ -405,59 +392,63 @@ describe 'FuzzyFinder', ->
|
||||
expect(finderView.find('.error').text().length).toBeGreaterThan 0
|
||||
|
||||
describe "opening a path into a split", ->
|
||||
beforeEach ->
|
||||
rootView.attachToDom()
|
||||
it "opens the path by splitting the active editor left", ->
|
||||
expect(rootView.getPanes().length).toBe 1
|
||||
pane = rootView.getActivePane()
|
||||
spyOn(pane, "splitLeft").andCallThrough()
|
||||
|
||||
describe "when an editor is active", ->
|
||||
it "opens the path by splitting the active editor left", ->
|
||||
editor = rootView.getActiveEditor()
|
||||
spyOn(editor, "splitLeft").andCallThrough()
|
||||
expect(rootView.find('.editor').length).toBe 1
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
finderView.miniEditor.trigger 'editor:split-left'
|
||||
expect(rootView.find('.editor').length).toBe 2
|
||||
expect(editor.splitLeft).toHaveBeenCalled()
|
||||
expect(rootView.getActiveEditor()).not.toBe editor
|
||||
expect(rootView.getActiveEditor().getPath()).toBe editor.getPath()
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
path = finderView.getSelectedElement()
|
||||
finderView.miniEditor.trigger 'pane:split-left'
|
||||
|
||||
it "opens the path by splitting the active editor right", ->
|
||||
editor = rootView.getActiveEditor()
|
||||
spyOn(editor, "splitRight").andCallThrough()
|
||||
expect(rootView.find('.editor').length).toBe 1
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
finderView.miniEditor.trigger 'editor:split-right'
|
||||
expect(rootView.find('.editor').length).toBe 2
|
||||
expect(editor.splitRight).toHaveBeenCalled()
|
||||
expect(rootView.getActiveEditor()).not.toBe editor
|
||||
expect(rootView.getActiveEditor().getPath()).toBe editor.getPath()
|
||||
expect(rootView.getPanes().length).toBe 2
|
||||
expect(pane.splitLeft).toHaveBeenCalled()
|
||||
expect(rootView.getActiveView().getPath()).toBe project.resolve(path)
|
||||
|
||||
it "opens the path by splitting the active editor down", ->
|
||||
editor = rootView.getActiveEditor()
|
||||
spyOn(editor, "splitDown").andCallThrough()
|
||||
expect(rootView.find('.editor').length).toBe 1
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
finderView.miniEditor.trigger 'editor:split-down'
|
||||
expect(rootView.find('.editor').length).toBe 2
|
||||
expect(editor.splitDown).toHaveBeenCalled()
|
||||
expect(rootView.getActiveEditor()).not.toBe editor
|
||||
expect(rootView.getActiveEditor().getPath()).toBe editor.getPath()
|
||||
it "opens the path by splitting the active editor right", ->
|
||||
expect(rootView.getPanes().length).toBe 1
|
||||
pane = rootView.getActivePane()
|
||||
spyOn(pane, "splitRight").andCallThrough()
|
||||
|
||||
it "opens the path by splitting the active editor up", ->
|
||||
editor = rootView.getActiveEditor()
|
||||
spyOn(editor, "splitUp").andCallThrough()
|
||||
expect(rootView.find('.editor').length).toBe 1
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
finderView.miniEditor.trigger 'editor:split-up'
|
||||
expect(rootView.find('.editor').length).toBe 2
|
||||
expect(editor.splitUp).toHaveBeenCalled()
|
||||
expect(rootView.getActiveEditor()).not.toBe editor
|
||||
expect(rootView.getActiveEditor().getPath()).toBe editor.getPath()
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
path = finderView.getSelectedElement()
|
||||
finderView.miniEditor.trigger 'pane:split-right'
|
||||
|
||||
expect(rootView.getPanes().length).toBe 2
|
||||
expect(pane.splitRight).toHaveBeenCalled()
|
||||
expect(rootView.getActiveView().getPath()).toBe project.resolve(path)
|
||||
|
||||
it "opens the path by splitting the active editor up", ->
|
||||
expect(rootView.getPanes().length).toBe 1
|
||||
pane = rootView.getActivePane()
|
||||
spyOn(pane, "splitUp").andCallThrough()
|
||||
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
path = finderView.getSelectedElement()
|
||||
finderView.miniEditor.trigger 'pane:split-up'
|
||||
|
||||
expect(rootView.getPanes().length).toBe 2
|
||||
expect(pane.splitUp).toHaveBeenCalled()
|
||||
expect(rootView.getActiveView().getPath()).toBe project.resolve(path)
|
||||
|
||||
it "opens the path by splitting the active editor down", ->
|
||||
expect(rootView.getPanes().length).toBe 1
|
||||
pane = rootView.getActivePane()
|
||||
spyOn(pane, "splitDown").andCallThrough()
|
||||
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
path = finderView.getSelectedElement()
|
||||
finderView.miniEditor.trigger 'pane:split-down'
|
||||
|
||||
expect(rootView.getPanes().length).toBe 2
|
||||
expect(pane.splitDown).toHaveBeenCalled()
|
||||
expect(rootView.getActiveView().getPath()).toBe project.resolve(path)
|
||||
|
||||
describe "git status decorations", ->
|
||||
[originalText, originalPath, editor, newPath] = []
|
||||
|
||||
beforeEach ->
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
originalText = editor.getText()
|
||||
originalPath = editor.getPath()
|
||||
newPath = project.resolve('newsample.js')
|
||||
@@ -470,7 +461,7 @@ describe 'FuzzyFinder', ->
|
||||
describe "when a modified file is shown in the list", ->
|
||||
it "displays the modified icon", ->
|
||||
editor.setText('modified')
|
||||
editor.save()
|
||||
editor.activeEditSession.save()
|
||||
git.getPathStatus(editor.getPath())
|
||||
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
|
||||
@@ -136,6 +136,6 @@ describe "GitHub Flavored Markdown grammar", ->
|
||||
describe "auto indent", ->
|
||||
it "indents newlines entered after list lines", ->
|
||||
config.set('editor.autoIndent', true)
|
||||
editSession = fixturesProject.buildEditSessionForPath('gfm.md')
|
||||
editSession = project.buildEditSession('gfm.md')
|
||||
editSession.insertNewlineBelow()
|
||||
expect(editSession.buffer.lineForRow(1)).toBe ' '
|
||||
|
||||
@@ -9,7 +9,7 @@ class Gists
|
||||
rootView.command 'gist:create', '.editor', => @createGist()
|
||||
|
||||
createGist: (editor) ->
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
return unless editor?
|
||||
|
||||
gist = { public: false, files: {} }
|
||||
|
||||
@@ -8,7 +8,7 @@ describe "Gists package", ->
|
||||
window.rootView = new RootView
|
||||
rootView.open('sample.js')
|
||||
window.loadPackage('gists')
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
spyOn($, 'ajax')
|
||||
|
||||
describe "when gist:create is triggered on an editor", ->
|
||||
|
||||
@@ -38,7 +38,7 @@ class GoToLineView extends View
|
||||
|
||||
confirm: ->
|
||||
lineNumber = @miniEditor.getText()
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
|
||||
@detach()
|
||||
|
||||
@@ -51,5 +51,5 @@ class GoToLineView extends View
|
||||
attach: ->
|
||||
@previouslyFocusedElement = $(':focus')
|
||||
rootView.append(this)
|
||||
@message.text("Enter a line number 1-#{rootView.getActiveEditor().getLineCount()}")
|
||||
@message.text("Enter a line number 1-#{rootView.getActiveView().getLineCount()}")
|
||||
@miniEditor.focus()
|
||||
|
||||
@@ -8,7 +8,7 @@ describe 'GoToLine', ->
|
||||
window.rootView = new RootView
|
||||
rootView.open('sample.js')
|
||||
rootView.enableKeymap()
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
goToLine = GoToLineView.activate()
|
||||
editor.setCursorBufferPosition([1,0])
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class MarkdownPreviewView extends ScrollView
|
||||
@detaching = false
|
||||
|
||||
getActiveText: ->
|
||||
rootView.getActiveEditor()?.getText()
|
||||
rootView.getActiveView()?.getText()
|
||||
|
||||
getErrorHtml: (error) ->
|
||||
$$$ ->
|
||||
@@ -74,7 +74,7 @@ class MarkdownPreviewView extends ScrollView
|
||||
@markdownBody.html(html) if @hasParent()
|
||||
|
||||
isMarkdownEditor: (path) ->
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
return unless editor?
|
||||
return true if editor.getGrammar().scopeName is 'source.gfm'
|
||||
path and fs.isMarkdownExtension(fs.extension(path))
|
||||
|
||||
@@ -13,7 +13,7 @@ describe "MarkdownPreview", ->
|
||||
describe "markdown-preview:toggle event", ->
|
||||
it "toggles on/off a preview for a .md file", ->
|
||||
rootView.open('file.md')
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
editor.trigger('markdown-preview:toggle')
|
||||
|
||||
@@ -25,7 +25,7 @@ describe "MarkdownPreview", ->
|
||||
|
||||
it "displays a preview for a .markdown file", ->
|
||||
rootView.open('file.markdown')
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
editor.trigger('markdown-preview:toggle')
|
||||
expect(rootView.find('.markdown-preview')).toExist()
|
||||
@@ -35,7 +35,7 @@ describe "MarkdownPreview", ->
|
||||
it "displays a preview for a file with the source.gfm grammar scope", ->
|
||||
gfmGrammar = _.find syntax.grammars, (grammar) -> grammar.scopeName is 'source.gfm'
|
||||
rootView.open('file.js')
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
project.addGrammarOverrideForPath(editor.getPath(), gfmGrammar)
|
||||
editor.reloadGrammar()
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
@@ -46,39 +46,39 @@ describe "MarkdownPreview", ->
|
||||
|
||||
it "does not display a preview for non-markdown file", ->
|
||||
rootView.open('file.js')
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
editor.trigger('markdown-preview:toggle')
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
expect(MarkdownPreview.prototype.loadHtml).not.toHaveBeenCalled()
|
||||
|
||||
describe "core:cancel event", ->
|
||||
it "removes markdown preview", ->
|
||||
rootView.open('file.md')
|
||||
editor = rootView.getActiveEditor()
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
editor.trigger('markdown-preview:toggle')
|
||||
describe "core:cancel event", ->
|
||||
it "removes markdown preview", ->
|
||||
rootView.open('file.md')
|
||||
editor = rootView.getActiveView()
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
editor.trigger('markdown-preview:toggle')
|
||||
|
||||
markdownPreviewView = rootView.find('.markdown-preview')?.view()
|
||||
expect(markdownPreviewView).toExist()
|
||||
markdownPreviewView.trigger('core:cancel')
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
markdownPreviewView = rootView.find('.markdown-preview')?.view()
|
||||
expect(markdownPreviewView).toExist()
|
||||
markdownPreviewView.trigger('core:cancel')
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
|
||||
describe "when the editor receives focus", ->
|
||||
it "removes the markdown preview view", ->
|
||||
rootView.attachToDom()
|
||||
rootView.open('file.md')
|
||||
editor = rootView.getActiveEditor()
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
editor.trigger('markdown-preview:toggle')
|
||||
describe "when the editor receives focus", ->
|
||||
it "removes the markdown preview view", ->
|
||||
rootView.attachToDom()
|
||||
rootView.open('file.md')
|
||||
editor = rootView.getActiveView()
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
editor.trigger('markdown-preview:toggle')
|
||||
|
||||
markdownPreviewView = rootView.find('.markdown-preview')
|
||||
editor.focus()
|
||||
expect(markdownPreviewView).toExist()
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
markdownPreviewView = rootView.find('.markdown-preview')
|
||||
editor.focus()
|
||||
expect(markdownPreviewView).toExist()
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
|
||||
describe "when no editor is open", ->
|
||||
it "does not attach", ->
|
||||
expect(rootView.getActiveEditor()).toBeFalsy()
|
||||
rootView.trigger('markdown-preview:toggle')
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
describe "when no editor is open", ->
|
||||
it "does not attach", ->
|
||||
expect(rootView.getActiveView()).toBeFalsy()
|
||||
rootView.trigger('markdown-preview:toggle')
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
|
||||
@@ -21,11 +21,11 @@ describe 'Package Generator', ->
|
||||
rootView.trigger("package-generator:generate")
|
||||
packageGeneratorView = rootView.find(".package-generator").view()
|
||||
expect(packageGeneratorView.miniEditor.isFocused).toBeTruthy()
|
||||
expect(rootView.getActiveEditor().isFocused).toBeFalsy()
|
||||
expect(rootView.getActiveView().isFocused).toBeFalsy()
|
||||
|
||||
packageGeneratorView.trigger("core:cancel")
|
||||
expect(packageGeneratorView.hasParent()).toBeFalsy()
|
||||
expect(rootView.getActiveEditor().isFocused).toBeTruthy()
|
||||
expect(rootView.getActiveView().isFocused).toBeTruthy()
|
||||
|
||||
describe "when a package is generated", ->
|
||||
[packageName, packagePath] = []
|
||||
@@ -58,6 +58,7 @@ describe 'Package Generator', ->
|
||||
expect(fs.join(fs.directory(packagePath), "camel-case-is-for-the-birds")).toExistOnDisk()
|
||||
|
||||
it "correctly lays out the package files and closes the package generator view", ->
|
||||
rootView.attachToDom()
|
||||
rootView.trigger("package-generator:generate")
|
||||
packageGeneratorView = rootView.find(".package-generator").view()
|
||||
expect(packageGeneratorView.hasParent()).toBeTruthy()
|
||||
@@ -73,7 +74,7 @@ describe 'Package Generator', ->
|
||||
expect("#{packagePath}/stylesheets/#{packageName}.css").toExistOnDisk()
|
||||
|
||||
expect(packageGeneratorView.hasParent()).toBeFalsy()
|
||||
expect(rootView.getActiveEditor().isFocused).toBeTruthy()
|
||||
expect(rootView.getActiveView().isFocused).toBeTruthy()
|
||||
|
||||
it "replaces instances of packageName placeholders in template files", ->
|
||||
rootView.trigger("package-generator:generate")
|
||||
|
||||
@@ -21,8 +21,8 @@ describe "Snippets extension", ->
|
||||
|
||||
window.loadPackage("snippets")
|
||||
|
||||
editor = rootView.getActiveEditor()
|
||||
editSession = rootView.getActiveEditSession()
|
||||
editor = rootView.getActiveView()
|
||||
editSession = rootView.getActivePaneItem()
|
||||
buffer = editor.getBuffer()
|
||||
rootView.simulateDomAttachment()
|
||||
rootView.enableKeymap()
|
||||
@@ -300,7 +300,7 @@ describe "Snippets extension", ->
|
||||
jasmine.unspy(LoadSnippetsTask.prototype, 'loadTextMateSnippets')
|
||||
snippets.loaded = false
|
||||
task = new LoadSnippetsTask(snippets)
|
||||
task.packages = [Package.build(fixturesProject.resolve('packages/package-with-a-cson-grammar.tmbundle'))]
|
||||
task.packages = [Package.build(project.resolve('packages/package-with-a-cson-grammar.tmbundle'))]
|
||||
task.start()
|
||||
|
||||
waitsFor "CSON snippets to load", 5000, -> snippets.loaded
|
||||
|
||||
@@ -9,7 +9,7 @@ describe "Spell check", ->
|
||||
config.set('spell-check.grammars', [])
|
||||
window.loadPackage('spell-check')
|
||||
rootView.attachToDom()
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
|
||||
it "decorates all misspelled words", ->
|
||||
editor.setText("This middle of thiss sentencts has issues.")
|
||||
@@ -110,5 +110,5 @@ describe "Spell check", ->
|
||||
view = editor.find('.misspelling').view()
|
||||
buffer = editor.getBuffer()
|
||||
expect(buffer.getMarkerPosition(view.marker)).not.toBeUndefined()
|
||||
editor.destroyEditSessions()
|
||||
editor.remove()
|
||||
expect(buffer.getMarkerPosition(view.marker)).toBeUndefined()
|
||||
|
||||
@@ -47,7 +47,7 @@ class StatusBarView extends View
|
||||
subscribeToBuffer: ->
|
||||
@buffer?.off '.status-bar'
|
||||
@buffer = @editor.getBuffer()
|
||||
@buffer.on 'contents-modified.status-bar', (e) => @updateBufferHasModifiedText(e.differsFromDisk)
|
||||
@buffer.on 'modified-status-changed.status-bar', (isModified) => @updateBufferHasModifiedText(isModified)
|
||||
@buffer.on 'saved.status-bar', => @updateStatusBar()
|
||||
@updateStatusBar()
|
||||
|
||||
@@ -60,8 +60,8 @@ class StatusBarView extends View
|
||||
updateGrammarText: ->
|
||||
@grammarName.text(@editor.getGrammar().name)
|
||||
|
||||
updateBufferHasModifiedText: (differsFromDisk)->
|
||||
if differsFromDisk
|
||||
updateBufferHasModifiedText: (isModified)->
|
||||
if isModified
|
||||
@bufferModified.text('*') unless @isModified
|
||||
@isModified = true
|
||||
else
|
||||
|
||||
@@ -12,7 +12,7 @@ describe "StatusBar", ->
|
||||
rootView.open('sample.js')
|
||||
rootView.simulateDomAttachment()
|
||||
StatusBar.activate()
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
statusBar = rootView.find('.status-bar').view()
|
||||
buffer = editor.getBuffer()
|
||||
|
||||
@@ -63,7 +63,7 @@ describe "StatusBar", ->
|
||||
editor.insertText("\n")
|
||||
advanceClock(buffer.stoppedChangingDelay)
|
||||
expect(statusBar.bufferModified.text()).toBe '*'
|
||||
editor.save()
|
||||
editor.getBuffer().save()
|
||||
expect(statusBar.bufferModified.text()).toBe ''
|
||||
|
||||
it "disables the buffer modified indicator if the content matches again", ->
|
||||
|
||||
@@ -12,7 +12,7 @@ describe "StripTrailingWhitespace", ->
|
||||
|
||||
window.loadPackage('strip-trailing-whitespace')
|
||||
rootView.focus()
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
|
||||
afterEach ->
|
||||
fs.remove(path) if fs.exists(path)
|
||||
@@ -23,7 +23,7 @@ describe "StripTrailingWhitespace", ->
|
||||
|
||||
# works for buffers that are already open when extension is initialized
|
||||
editor.insertText("foo \nbar\t \n\nbaz")
|
||||
editor.save()
|
||||
editor.getBuffer().save()
|
||||
expect(editor.getText()).toBe "foo\nbar\n\nbaz"
|
||||
|
||||
# works for buffers that are opened after extension is initialized
|
||||
@@ -47,25 +47,25 @@ describe "StripTrailingWhitespace", ->
|
||||
|
||||
it "adds a trailing newline when there is no trailing newline", ->
|
||||
editor.insertText "foo"
|
||||
editor.save()
|
||||
editor.getBuffer().save()
|
||||
expect(editor.getText()).toBe "foo\n"
|
||||
|
||||
it "removes extra trailing newlines and only keeps one", ->
|
||||
editor.insertText "foo\n\n\n\n"
|
||||
editor.save()
|
||||
editor.getBuffer().save()
|
||||
expect(editor.getText()).toBe "foo\n"
|
||||
|
||||
it "leaves a buffer with a single trailing newline untouched", ->
|
||||
editor.insertText "foo\nbar\n"
|
||||
editor.save()
|
||||
editor.getBuffer().save()
|
||||
expect(editor.getText()).toBe "foo\nbar\n"
|
||||
|
||||
it "leaves an empty buffer untouched", ->
|
||||
editor.insertText ""
|
||||
editor.save()
|
||||
editor.getBuffer().save()
|
||||
expect(editor.getText()).toBe ""
|
||||
|
||||
it "leaves a buffer that is a single newline untouched", ->
|
||||
editor.insertText "\n"
|
||||
editor.save()
|
||||
editor.getBuffer().save()
|
||||
expect(editor.getText()).toBe "\n"
|
||||
|
||||
@@ -43,7 +43,7 @@ class SymbolsView extends SelectList
|
||||
populateFileSymbols: ->
|
||||
tags = []
|
||||
callback = (tag) -> tags.push tag
|
||||
path = rootView.getActiveEditor().getPath()
|
||||
path = rootView.getActiveView().getPath()
|
||||
@list.empty()
|
||||
@setLoading("Generating symbols...")
|
||||
new TagGenerator(path, callback).generate().done =>
|
||||
@@ -91,7 +91,7 @@ class SymbolsView extends SelectList
|
||||
@moveToPosition(position) if position
|
||||
|
||||
moveToPosition: (position) ->
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
editor.scrollToBufferPosition(position, center: true)
|
||||
editor.setCursorBufferPosition(position)
|
||||
editor.moveCursorToFirstCharacterOfLine()
|
||||
@@ -111,7 +111,7 @@ class SymbolsView extends SelectList
|
||||
return new Point(index, 0) if pattern is $.trim(line)
|
||||
|
||||
goToDeclaration: ->
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
matches = TagReader.find(editor)
|
||||
return unless matches.length
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ describe "SymbolsView", ->
|
||||
describe "when tags can be generated for a file", ->
|
||||
it "initially displays all JavaScript functions with line numbers", ->
|
||||
rootView.open('sample.js')
|
||||
rootView.getActiveEditor().trigger "symbols-view:toggle-file-symbols"
|
||||
rootView.getActiveView().trigger "symbols-view:toggle-file-symbols"
|
||||
symbolsView = rootView.find('.symbols-view').view()
|
||||
expect(symbolsView.find('.loading')).toHaveText 'Generating symbols...'
|
||||
|
||||
@@ -39,7 +39,7 @@ describe "SymbolsView", ->
|
||||
|
||||
it "displays error when no tags match text in mini-editor", ->
|
||||
rootView.open('sample.js')
|
||||
rootView.getActiveEditor().trigger "symbols-view:toggle-file-symbols"
|
||||
rootView.getActiveView().trigger "symbols-view:toggle-file-symbols"
|
||||
symbolsView = rootView.find('.symbols-view').view()
|
||||
|
||||
waitsFor ->
|
||||
@@ -66,7 +66,7 @@ describe "SymbolsView", ->
|
||||
describe "when tags can't be generated for a file", ->
|
||||
it "shows an error message when no matching tags are found", ->
|
||||
rootView.open('sample.txt')
|
||||
rootView.getActiveEditor().trigger "symbols-view:toggle-file-symbols"
|
||||
rootView.getActiveView().trigger "symbols-view:toggle-file-symbols"
|
||||
symbolsView = rootView.find('.symbols-view').view()
|
||||
setErrorSpy = spyOn(symbolsView, "setError").andCallThrough()
|
||||
|
||||
@@ -93,14 +93,14 @@ describe "SymbolsView", ->
|
||||
|
||||
runs ->
|
||||
rootView.open('sample.js')
|
||||
expect(rootView.getActiveEditor().getCursorBufferPosition()).toEqual [0,0]
|
||||
expect(rootView.getActiveView().getCursorBufferPosition()).toEqual [0,0]
|
||||
expect(rootView.find('.symbols-view')).not.toExist()
|
||||
symbolsView = SymbolsView.activate()
|
||||
symbolsView.setArray(tags)
|
||||
symbolsView.attach()
|
||||
expect(rootView.find('.symbols-view')).toExist()
|
||||
symbolsView.confirmed(tags[1])
|
||||
expect(rootView.getActiveEditor().getCursorBufferPosition()).toEqual [1,2]
|
||||
expect(rootView.getActiveView().getCursorBufferPosition()).toEqual [1,2]
|
||||
|
||||
describe "TagGenerator", ->
|
||||
it "generates tags for all JavaScript functions", ->
|
||||
@@ -136,29 +136,29 @@ describe "SymbolsView", ->
|
||||
describe "go to declaration", ->
|
||||
it "doesn't move the cursor when no declaration is found", ->
|
||||
rootView.open("tagged.js")
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
editor.setCursorBufferPosition([0,2])
|
||||
editor.trigger 'symbols-view:go-to-declaration'
|
||||
expect(editor.getCursorBufferPosition()).toEqual [0,2]
|
||||
|
||||
it "moves the cursor to the declaration", ->
|
||||
rootView.open("tagged.js")
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
editor.setCursorBufferPosition([6,24])
|
||||
editor.trigger 'symbols-view:go-to-declaration'
|
||||
expect(editor.getCursorBufferPosition()).toEqual [2,0]
|
||||
|
||||
it "displays matches when more than one exists and opens the selected match", ->
|
||||
rootView.open("tagged.js")
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
editor.setCursorBufferPosition([8,14])
|
||||
editor.trigger 'symbols-view:go-to-declaration'
|
||||
symbolsView = rootView.find('.symbols-view').view()
|
||||
expect(symbolsView.list.children('li').length).toBe 2
|
||||
expect(symbolsView).toBeVisible()
|
||||
symbolsView.confirmed(symbolsView.array[0])
|
||||
expect(rootView.getActiveEditor().getPath()).toBe project.resolve("tagged-duplicate.js")
|
||||
expect(rootView.getActiveEditor().getCursorBufferPosition()).toEqual [0,4]
|
||||
expect(rootView.getActiveView().getPath()).toBe project.resolve("tagged-duplicate.js")
|
||||
expect(rootView.getActiveView().getCursorBufferPosition()).toEqual [0,4]
|
||||
|
||||
describe "when the tag is in a file that doesn't exist", ->
|
||||
renamedPath = null
|
||||
@@ -173,7 +173,7 @@ describe "SymbolsView", ->
|
||||
|
||||
it "doesn't display the tag", ->
|
||||
rootView.open("tagged.js")
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
editor.setCursorBufferPosition([8,14])
|
||||
editor.trigger 'symbols-view:go-to-declaration'
|
||||
symbolsView = rootView.find('.symbols-view').view()
|
||||
|
||||
98
src/packages/tabs/lib/tab-bar-view.coffee
Normal file
98
src/packages/tabs/lib/tab-bar-view.coffee
Normal file
@@ -0,0 +1,98 @@
|
||||
$ = require 'jquery'
|
||||
_ = require 'underscore'
|
||||
SortableList = require 'sortable-list'
|
||||
TabView = require './tab-view'
|
||||
|
||||
module.exports =
|
||||
class TabBarView extends SortableList
|
||||
@content: ->
|
||||
@ul class: "tabs #{@viewClass()}"
|
||||
|
||||
initialize: (@pane) ->
|
||||
super
|
||||
|
||||
@paneContainer = @pane.getContainer()
|
||||
@addTabForItem(item) for item in @pane.getItems()
|
||||
|
||||
@pane.on 'pane:item-added', (e, item, index) => @addTabForItem(item, index)
|
||||
@pane.on 'pane:item-moved', (e, item, index) => @moveItemTabToIndex(item, index)
|
||||
@pane.on 'pane:item-removed', (e, item) => @removeTabForItem(item)
|
||||
@pane.on 'pane:active-item-changed', => @updateActiveTab()
|
||||
|
||||
@updateActiveTab()
|
||||
|
||||
@on 'click', '.tab', (e) =>
|
||||
tab = $(e.target).closest('.tab').view()
|
||||
@pane.showItem(tab.item)
|
||||
@pane.focus()
|
||||
|
||||
@on 'click', '.tab .close-icon', (e) =>
|
||||
tab = $(e.target).closest('.tab').view()
|
||||
@pane.destroyItem(tab.item)
|
||||
false
|
||||
|
||||
@pane.prepend(this)
|
||||
|
||||
addTabForItem: (item, index) ->
|
||||
@insertTabAtIndex(new TabView(item, @pane), index)
|
||||
|
||||
moveItemTabToIndex: (item, index) ->
|
||||
tab = @tabForItem(item)
|
||||
tab.detach()
|
||||
@insertTabAtIndex(tab, index)
|
||||
|
||||
insertTabAtIndex: (tab, index) ->
|
||||
followingTab = @tabAtIndex(index) if index?
|
||||
if followingTab
|
||||
tab.insertBefore(followingTab)
|
||||
else
|
||||
@append(tab)
|
||||
|
||||
removeTabForItem: (item) ->
|
||||
@tabForItem(item).remove()
|
||||
|
||||
getTabs: ->
|
||||
@children('.tab').toArray().map (elt) -> $(elt).view()
|
||||
|
||||
tabAtIndex: (index) ->
|
||||
@children(".tab:eq(#{index})").view()
|
||||
|
||||
tabForItem: (item) ->
|
||||
_.detect @getTabs(), (tab) -> tab.item is item
|
||||
|
||||
setActiveTab: (tabView) ->
|
||||
unless tabView.hasClass('active')
|
||||
@find(".tab.active").removeClass('active')
|
||||
tabView.addClass('active')
|
||||
|
||||
updateActiveTab: ->
|
||||
@setActiveTab(@tabForItem(@pane.activeItem))
|
||||
|
||||
shouldAllowDrag: ->
|
||||
(@paneContainer.getPanes().length > 1) or (@pane.getItems().length > 1)
|
||||
|
||||
onDragStart: (event) =>
|
||||
super
|
||||
pane = $(event.target).closest('.pane')
|
||||
paneIndex = @paneContainer.indexOfPane(pane)
|
||||
event.originalEvent.dataTransfer.setData 'from-pane-index', paneIndex
|
||||
|
||||
onDrop: (event) =>
|
||||
super
|
||||
|
||||
dataTransfer = event.originalEvent.dataTransfer
|
||||
fromIndex = parseInt(dataTransfer.getData('sortable-index'))
|
||||
fromPaneIndex = parseInt(dataTransfer.getData('from-pane-index'))
|
||||
fromPane = @paneContainer.paneAtIndex(fromPaneIndex)
|
||||
toIndex = @getSortableElement(event).index()
|
||||
toPane = $(event.target).closest('.pane').view()
|
||||
draggedTab = fromPane.find(".tabs .sortable:eq(#{fromIndex})").view()
|
||||
item = draggedTab.item
|
||||
|
||||
if toPane is fromPane
|
||||
toIndex++ if fromIndex > toIndex
|
||||
toPane.moveItem(item, toIndex)
|
||||
else
|
||||
fromPane.moveItemToPane(item, toPane, toIndex)
|
||||
toPane.showItem(item)
|
||||
toPane.focus()
|
||||
@@ -1,100 +1,55 @@
|
||||
$ = require 'jquery'
|
||||
SortableList = require 'sortable-list'
|
||||
Tab = require './tab'
|
||||
{View} = require 'space-pen'
|
||||
fs = require 'fs'
|
||||
|
||||
module.exports =
|
||||
class TabView extends SortableList
|
||||
@activate: ->
|
||||
rootView.eachEditor (editor) =>
|
||||
@prependToEditorPane(editor) if editor.attached
|
||||
|
||||
@prependToEditorPane: (editor) ->
|
||||
if pane = editor.pane()
|
||||
pane.prepend(new TabView(editor))
|
||||
|
||||
class TabView extends View
|
||||
@content: ->
|
||||
@ul class: "tabs #{@viewClass()}"
|
||||
@li class: 'tab sortable', =>
|
||||
@span class: 'title', outlet: 'title'
|
||||
@span class: 'close-icon'
|
||||
|
||||
initialize: (@editor) ->
|
||||
super
|
||||
initialize: (@item, @pane) ->
|
||||
@item.on? 'title-changed', => @updateTitle()
|
||||
@item.on? 'modified-status-changed', => @updateModifiedStatus()
|
||||
@updateTitle()
|
||||
@updateModifiedStatus()
|
||||
|
||||
@addTabForEditSession(editSession) for editSession in @editor.editSessions
|
||||
updateTitle: ->
|
||||
return if @updatingTitle
|
||||
@updatingTitle = true
|
||||
|
||||
@setActiveTab(@editor.getActiveEditSessionIndex())
|
||||
@editor.on 'editor:active-edit-session-changed', (e, editSession, index) => @setActiveTab(index)
|
||||
@editor.on 'editor:edit-session-added', (e, editSession) => @addTabForEditSession(editSession)
|
||||
@editor.on 'editor:edit-session-removed', (e, editSession, index) => @removeTabAtIndex(index)
|
||||
@editor.on 'editor:edit-session-order-changed', (e, editSession, fromIndex, toIndex) =>
|
||||
fromTab = @find(".tab:eq(#{fromIndex})")
|
||||
toTab = @find(".tab:eq(#{toIndex})")
|
||||
fromTab.detach()
|
||||
if fromIndex < toIndex
|
||||
fromTab.insertAfter(toTab)
|
||||
else
|
||||
fromTab.insertBefore(toTab)
|
||||
title = @item.getTitle()
|
||||
useLongTitle = false
|
||||
for tab in @getSiblingTabs()
|
||||
if tab.item.getTitle() is title
|
||||
tab.updateTitle()
|
||||
useLongTitle = true
|
||||
title = @item.getLongTitle?() ? title if useLongTitle
|
||||
|
||||
@on 'click', '.tab', (e) =>
|
||||
@editor.setActiveEditSessionIndex($(e.target).closest('.tab').index())
|
||||
@editor.focus()
|
||||
@title.text(title)
|
||||
@updatingTitle = false
|
||||
|
||||
@on 'click', '.tab .close-icon', (e) =>
|
||||
index = $(e.target).closest('.tab').index()
|
||||
@editor.destroyEditSessionIndex(index)
|
||||
false
|
||||
getSiblingTabs: ->
|
||||
@siblings('.tab').views()
|
||||
|
||||
addTabForEditSession: (editSession) ->
|
||||
@append(new Tab(editSession, @editor))
|
||||
|
||||
setActiveTab: (index) ->
|
||||
@find(".tab.active").removeClass('active')
|
||||
@find(".tab:eq(#{index})").addClass('active')
|
||||
|
||||
removeTabAtIndex: (index) ->
|
||||
@find(".tab:eq(#{index})").remove()
|
||||
|
||||
containsEditSession: (editor, editSession) ->
|
||||
for session in editor.editSessions
|
||||
return true if editSession.getPath() is session.getPath()
|
||||
|
||||
shouldAllowDrag: (event) ->
|
||||
panes = rootView.find('.pane')
|
||||
!(panes.length == 1 && panes.find('.sortable').length == 1)
|
||||
|
||||
onDragStart: (event) =>
|
||||
super
|
||||
|
||||
pane = $(event.target).closest('.pane')
|
||||
paneIndex = rootView.indexOfPane(pane)
|
||||
event.originalEvent.dataTransfer.setData 'from-pane-index', paneIndex
|
||||
|
||||
onDrop: (event) =>
|
||||
super
|
||||
|
||||
droppedNearTab = @getSortableElement(event)
|
||||
transfer = event.originalEvent.dataTransfer
|
||||
previousDraggedTabIndex = transfer.getData 'sortable-index'
|
||||
|
||||
fromPaneIndex = ~~transfer.getData 'from-pane-index'
|
||||
toPaneIndex = rootView.indexOfPane($(event.target).closest('.pane'))
|
||||
fromPane = $(rootView.find('.pane')[fromPaneIndex])
|
||||
fromEditor = fromPane.find('.editor').view()
|
||||
draggedTab = fromPane.find(".#{TabView.viewClass()} .sortable:eq(#{previousDraggedTabIndex})")
|
||||
|
||||
if draggedTab.is(droppedNearTab)
|
||||
fromEditor.focus()
|
||||
return
|
||||
|
||||
if fromPaneIndex == toPaneIndex
|
||||
droppedNearTab = @getSortableElement(event)
|
||||
fromIndex = draggedTab.index()
|
||||
toIndex = droppedNearTab.index()
|
||||
toIndex++ if fromIndex > toIndex
|
||||
fromEditor.moveEditSessionToIndex(fromIndex, toIndex)
|
||||
fromEditor.focus()
|
||||
updateModifiedStatus: ->
|
||||
if @item.isModified?()
|
||||
@addClass('modified') unless @isModified
|
||||
@isModified = true
|
||||
else
|
||||
toEditor = rootView.find(".pane:eq(#{toPaneIndex}) > .editor").view()
|
||||
if @containsEditSession(toEditor, fromEditor.editSessions[draggedTab.index()])
|
||||
fromEditor.focus()
|
||||
else
|
||||
fromEditor.moveEditSessionToEditor(draggedTab.index(), toEditor, droppedNearTab.index() + 1)
|
||||
toEditor.focus()
|
||||
@removeClass('modified') if @isModified
|
||||
@isModified = false
|
||||
|
||||
updateFileName: ->
|
||||
fileNameText = @editSession.buffer.getBaseName()
|
||||
if fileNameText?
|
||||
duplicates = @editor.getEditSessions().filter (session) -> fileNameText is session.buffer.getBaseName()
|
||||
if duplicates.length > 1
|
||||
directory = fs.base(fs.directory(@editSession.getPath()))
|
||||
fileNameText = "#{fileNameText} - #{directory}" if directory
|
||||
else
|
||||
fileNameText = 'untitled'
|
||||
|
||||
@fileName.text(fileNameText)
|
||||
@fileName.attr('title', @editSession.getPath())
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
{View} = require 'space-pen'
|
||||
fs = require 'fs'
|
||||
|
||||
module.exports =
|
||||
class Tab extends View
|
||||
@content: (editSession) ->
|
||||
@li class: 'tab sortable', =>
|
||||
@span class: 'file-name', outlet: 'fileName'
|
||||
@span class: 'close-icon'
|
||||
|
||||
initialize: (@editSession, @editor) ->
|
||||
@buffer = @editSession.buffer
|
||||
@subscribe @buffer, 'path-changed', => @updateFileName()
|
||||
@subscribe @buffer, 'contents-modified', => @updateModifiedStatus()
|
||||
@subscribe @buffer, 'saved', => @updateModifiedStatus()
|
||||
@subscribe @editor, 'editor:edit-session-added', => @updateFileName()
|
||||
@subscribe @editor, 'editor:edit-session-removed', => @updateFileName()
|
||||
@updateFileName()
|
||||
@updateModifiedStatus()
|
||||
|
||||
updateModifiedStatus: ->
|
||||
if @buffer.isModified()
|
||||
@toggleClass('file-modified') unless @isModified
|
||||
@isModified = true
|
||||
else
|
||||
@removeClass('file-modified') if @isModified
|
||||
@isModified = false
|
||||
|
||||
updateFileName: ->
|
||||
fileNameText = @editSession.buffer.getBaseName()
|
||||
if fileNameText?
|
||||
duplicates = @editor.getEditSessions().filter (session) -> fileNameText is session.buffer.getBaseName()
|
||||
if duplicates.length > 1
|
||||
directory = fs.base(fs.directory(@editSession.getPath()))
|
||||
fileNameText = "#{fileNameText} - #{directory}" if directory
|
||||
else
|
||||
fileNameText = 'untitled'
|
||||
|
||||
@fileName.text(fileNameText)
|
||||
@fileName.attr('title', @editSession.getPath())
|
||||
5
src/packages/tabs/lib/tabs.coffee
Normal file
5
src/packages/tabs/lib/tabs.coffee
Normal file
@@ -0,0 +1,5 @@
|
||||
TabBarView = require './tab-bar-view'
|
||||
|
||||
module.exports =
|
||||
activate: ->
|
||||
rootView.eachPane (pane) => new TabBarView(pane)
|
||||
@@ -1 +1 @@
|
||||
'main': 'lib/tab-view'
|
||||
'main': 'lib/tabs'
|
||||
|
||||
@@ -1,231 +1,256 @@
|
||||
$ = require 'jquery'
|
||||
_ = require 'underscore'
|
||||
RootView = require 'root-view'
|
||||
Pane = require 'pane'
|
||||
PaneContainer = require 'pane-container'
|
||||
TabBarView = require 'tabs/lib/tab-bar-view'
|
||||
fs = require 'fs'
|
||||
{View} = require 'space-pen'
|
||||
|
||||
describe "TabView", ->
|
||||
[editor, buffer, tabs] = []
|
||||
|
||||
describe "Tabs package main", ->
|
||||
beforeEach ->
|
||||
window.rootView = new RootView
|
||||
rootView.open('sample.js')
|
||||
rootView.open('sample.txt')
|
||||
rootView.simulateDomAttachment()
|
||||
window.loadPackage("tabs")
|
||||
editor = rootView.getActiveEditor()
|
||||
tabs = rootView.find('.tabs').view()
|
||||
|
||||
describe "@activate", ->
|
||||
it "appends a status bear to all existing and new editors", ->
|
||||
describe ".activate()", ->
|
||||
it "appends a tab bar all existing and new panes", ->
|
||||
expect(rootView.panes.find('.pane').length).toBe 1
|
||||
expect(rootView.panes.find('.pane > .tabs').length).toBe 1
|
||||
editor.splitRight()
|
||||
rootView.getActivePane().splitRight()
|
||||
expect(rootView.find('.pane').length).toBe 2
|
||||
expect(rootView.panes.find('.pane > .tabs').length).toBe 2
|
||||
|
||||
describe ".initialize()", ->
|
||||
it "creates a tab for each edit session on the editor to which the tab-strip belongs", ->
|
||||
expect(editor.editSessions.length).toBe 2
|
||||
expect(tabs.find('.tab').length).toBe 2
|
||||
describe "TabBarView", ->
|
||||
[item1, item2, editSession1, pane, tabBar] = []
|
||||
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe editor.editSessions[0].buffer.getBaseName()
|
||||
expect(tabs.find('.tab:eq(1) .file-name').text()).toBe editor.editSessions[1].buffer.getBaseName()
|
||||
class TestView extends View
|
||||
@deserialize: ({title, longTitle}) -> new TestView(title, longTitle)
|
||||
@content: (title) -> @div title
|
||||
initialize: (@title, @longTitle) ->
|
||||
getTitle: -> @title
|
||||
getLongTitle: -> @longTitle
|
||||
serialize: -> { deserializer: 'TestView', @title, @longTitle }
|
||||
|
||||
it "highlights the tab for the current active edit session", ->
|
||||
expect(editor.getActiveEditSessionIndex()).toBe 1
|
||||
expect(tabs.find('.tab:eq(1)')).toHaveClass 'active'
|
||||
beforeEach ->
|
||||
registerDeserializer(TestView)
|
||||
item1 = new TestView('Item 1')
|
||||
item2 = new TestView('Item 2')
|
||||
editSession1 = project.buildEditSession('sample.js')
|
||||
paneContainer = new PaneContainer
|
||||
pane = new Pane(item1, editSession1, item2)
|
||||
pane.showItem(item2)
|
||||
paneContainer.append(pane)
|
||||
tabBar = new TabBarView(pane)
|
||||
|
||||
it "sets the title on each tab to be the full path of the edit session", ->
|
||||
expect(tabs.find('.tab:eq(0) .file-name').attr('title')).toBe editor.editSessions[0].getPath()
|
||||
expect(tabs.find('.tab:eq(1) .file-name').attr('title')).toBe editor.editSessions[1].getPath()
|
||||
afterEach ->
|
||||
unregisterDeserializer(TestView)
|
||||
|
||||
describe "when the active edit session changes", ->
|
||||
it "highlights the tab for the newly-active edit session", ->
|
||||
editor.setActiveEditSessionIndex(0)
|
||||
expect(tabs.find('.active').length).toBe 1
|
||||
expect(tabs.find('.tab:eq(0)')).toHaveClass 'active'
|
||||
describe ".initialize(pane)", ->
|
||||
it "creates a tab for each item on the tab bar's parent pane", ->
|
||||
expect(pane.getItems().length).toBe 3
|
||||
expect(tabBar.find('.tab').length).toBe 3
|
||||
|
||||
editor.setActiveEditSessionIndex(1)
|
||||
expect(tabs.find('.active').length).toBe 1
|
||||
expect(tabs.find('.tab:eq(1)')).toHaveClass 'active'
|
||||
expect(tabBar.find('.tab:eq(0) .title').text()).toBe item1.getTitle()
|
||||
expect(tabBar.find('.tab:eq(1) .title').text()).toBe editSession1.getTitle()
|
||||
expect(tabBar.find('.tab:eq(2) .title').text()).toBe item2.getTitle()
|
||||
|
||||
describe "when a new edit session is created", ->
|
||||
it "adds a tab for the new edit session", ->
|
||||
rootView.open('two-hundred.txt')
|
||||
expect(tabs.find('.tab').length).toBe 3
|
||||
expect(tabs.find('.tab:eq(2) .file-name').text()).toBe 'two-hundred.txt'
|
||||
it "highlights the tab for the active pane item", ->
|
||||
expect(tabBar.find('.tab:eq(2)')).toHaveClass 'active'
|
||||
|
||||
describe "when the edit session's buffer has an undefined path", ->
|
||||
it "makes the tab text 'untitled'", ->
|
||||
rootView.open()
|
||||
expect(tabs.find('.tab').length).toBe 3
|
||||
expect(tabs.find('.tab:eq(2) .file-name').text()).toBe 'untitled'
|
||||
describe "when the active pane item changes", ->
|
||||
it "highlights the tab for the new active pane item", ->
|
||||
pane.showItem(item1)
|
||||
expect(tabBar.find('.active').length).toBe 1
|
||||
expect(tabBar.find('.tab:eq(0)')).toHaveClass 'active'
|
||||
|
||||
it "removes the tab's title", ->
|
||||
rootView.open()
|
||||
expect(tabs.find('.tab').length).toBe 3
|
||||
expect(tabs.find('.tab:eq(2) .file-name').attr('title')).toBeUndefined()
|
||||
pane.showItem(item2)
|
||||
expect(tabBar.find('.active').length).toBe 1
|
||||
expect(tabBar.find('.tab:eq(2)')).toHaveClass 'active'
|
||||
|
||||
describe "when an edit session is removed", ->
|
||||
it "removes the tab for the removed edit session", ->
|
||||
editor.setActiveEditSessionIndex(0)
|
||||
editor.destroyActiveEditSession()
|
||||
expect(tabs.find('.tab').length).toBe 1
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe 'sample.txt'
|
||||
describe "when a new item is added to the pane", ->
|
||||
it "adds a tab for the new item at the same index as the item in the pane", ->
|
||||
pane.showItem(item1)
|
||||
item3 = new TestView('Item 3')
|
||||
pane.showItem(item3)
|
||||
expect(tabBar.find('.tab').length).toBe 4
|
||||
expect(tabBar.tabAtIndex(1).find('.title')).toHaveText 'Item 3'
|
||||
|
||||
it "adds the 'modified' class to the new tab if the item is initially modified", ->
|
||||
editSession2 = project.buildEditSession('sample.txt')
|
||||
editSession2.insertText('x')
|
||||
pane.showItem(editSession2)
|
||||
expect(tabBar.tabForItem(editSession2)).toHaveClass 'modified'
|
||||
|
||||
describe "when an item is removed from the pane", ->
|
||||
it "removes the item's tab from the tab bar", ->
|
||||
pane.removeItem(item2)
|
||||
expect(tabBar.getTabs().length).toBe 2
|
||||
expect(tabBar.find('.tab:contains(Item 2)')).not.toExist()
|
||||
|
||||
describe "when a tab is clicked", ->
|
||||
it "activates the associated edit session", ->
|
||||
expect(editor.getActiveEditSessionIndex()).toBe 1
|
||||
tabs.find('.tab:eq(0)').click()
|
||||
expect(editor.getActiveEditSessionIndex()).toBe 0
|
||||
tabs.find('.tab:eq(1)').click()
|
||||
expect(editor.getActiveEditSessionIndex()).toBe 1
|
||||
it "shows the associated item on the pane and focuses the pane", ->
|
||||
spyOn(pane, 'focus')
|
||||
|
||||
it "focuses the associated editor", ->
|
||||
rootView.attachToDom()
|
||||
expect(editor).toMatchSelector ":has(:focus)"
|
||||
editor.splitRight()
|
||||
expect(editor).not.toMatchSelector ":has(:focus)"
|
||||
tabs.find('.tab:eq(0)').click()
|
||||
expect(editor).toMatchSelector ":has(:focus)"
|
||||
tabBar.tabAtIndex(0).click()
|
||||
expect(pane.activeItem).toBe pane.getItems()[0]
|
||||
|
||||
describe "when a file name associated with a tab changes", ->
|
||||
[buffer, oldPath, newPath] = []
|
||||
tabBar.tabAtIndex(2).click()
|
||||
expect(pane.activeItem).toBe pane.getItems()[2]
|
||||
|
||||
beforeEach ->
|
||||
buffer = editor.editSessions[0].buffer
|
||||
oldPath = "/tmp/file-to-rename.txt"
|
||||
newPath = "/tmp/renamed-file.txt"
|
||||
fs.write(oldPath, "this old path")
|
||||
rootView.open(oldPath)
|
||||
expect(pane.focus.callCount).toBe 2
|
||||
|
||||
afterEach ->
|
||||
fs.remove(newPath) if fs.exists(newPath)
|
||||
describe "when a tab's close icon is clicked", ->
|
||||
it "destroys the tab's item on the pane", ->
|
||||
tabBar.tabForItem(editSession1).find('.close-icon').click()
|
||||
expect(pane.getItems().length).toBe 2
|
||||
expect(pane.getItems().indexOf(editSession1)).toBe -1
|
||||
expect(editSession1.destroyed).toBeTruthy()
|
||||
expect(tabBar.getTabs().length).toBe 2
|
||||
expect(tabBar.find('.tab:contains(sample.js)')).not.toExist()
|
||||
|
||||
it "updates the file name in the tab", ->
|
||||
tabFileName = tabs.find('.tab:eq(2) .file-name')
|
||||
expect(tabFileName).toExist()
|
||||
editor.setActiveEditSessionIndex(0)
|
||||
fs.move(oldPath, newPath)
|
||||
waitsFor "file to be renamed", ->
|
||||
tabFileName.text() == "renamed-file.txt"
|
||||
describe "when a tab item's title changes", ->
|
||||
it "updates the title of the item's tab", ->
|
||||
editSession1.buffer.setPath('/this/is-a/test.txt')
|
||||
expect(tabBar.tabForItem(editSession1)).toHaveText 'test.txt'
|
||||
|
||||
describe "when the close icon is clicked", ->
|
||||
it "closes the selected non-active edit session", ->
|
||||
activeSession = editor.activeEditSession
|
||||
expect(editor.getActiveEditSessionIndex()).toBe 1
|
||||
tabs.find('.tab .close-icon:eq(0)').click()
|
||||
expect(editor.getActiveEditSessionIndex()).toBe 0
|
||||
expect(editor.activeEditSession).toBe activeSession
|
||||
describe "when two tabs have the same title", ->
|
||||
it "displays the long title on the tab if it's available from the item", ->
|
||||
item1.title = "Old Man"
|
||||
item1.longTitle = "Grumpy Old Man"
|
||||
item1.trigger 'title-changed'
|
||||
item2.title = "Old Man"
|
||||
item2.longTitle = "Jolly Old Man"
|
||||
item2.trigger 'title-changed'
|
||||
|
||||
it "closes the selected active edit session", ->
|
||||
firstSession = editor.getEditSessions()[0]
|
||||
expect(editor.getActiveEditSessionIndex()).toBe 1
|
||||
tabs.find('.tab .close-icon:eq(1)').click()
|
||||
expect(editor.getActiveEditSessionIndex()).toBe 0
|
||||
expect(editor.activeEditSession).toBe firstSession
|
||||
expect(tabBar.tabForItem(item1)).toHaveText "Grumpy Old Man"
|
||||
expect(tabBar.tabForItem(item2)).toHaveText "Jolly Old Man"
|
||||
|
||||
describe "when two tabs have the same file name", ->
|
||||
[tempPath] = []
|
||||
item2.longTitle = undefined
|
||||
item2.trigger 'title-changed'
|
||||
|
||||
beforeEach ->
|
||||
tempPath = '/tmp/sample.js'
|
||||
fs.write(tempPath, 'sample')
|
||||
expect(tabBar.tabForItem(item1)).toHaveText "Grumpy Old Man"
|
||||
expect(tabBar.tabForItem(item2)).toHaveText "Old Man"
|
||||
|
||||
afterEach ->
|
||||
fs.remove(tempPath) if fs.exists(tempPath)
|
||||
describe "when a tab item's modified status changes", ->
|
||||
it "adds or removes the 'modified' class to the tab based on the status", ->
|
||||
tab = tabBar.tabForItem(editSession1)
|
||||
expect(editSession1.isModified()).toBeFalsy()
|
||||
expect(tab).not.toHaveClass 'modified'
|
||||
|
||||
it "displays the parent folder name after the file name", ->
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe 'sample.js'
|
||||
rootView.open(tempPath)
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe 'sample.js - fixtures'
|
||||
expect(tabs.find('.tab:last .file-name').text()).toBe 'sample.js - tmp'
|
||||
editor.destroyActiveEditSession()
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe 'sample.js'
|
||||
editSession1.insertText('x')
|
||||
advanceClock(editSession1.buffer.stoppedChangingDelay)
|
||||
expect(editSession1.isModified()).toBeTruthy()
|
||||
expect(tab).toHaveClass 'modified'
|
||||
|
||||
describe "when an editor:edit-session-order-changed event is triggered", ->
|
||||
it "updates the order of the tabs to match the new edit session order", ->
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe "sample.js"
|
||||
expect(tabs.find('.tab:eq(1) .file-name').text()).toBe "sample.txt"
|
||||
editSession1.undo()
|
||||
advanceClock(editSession1.buffer.stoppedChangingDelay)
|
||||
expect(editSession1.isModified()).toBeFalsy()
|
||||
expect(tab).not.toHaveClass 'modified'
|
||||
|
||||
editor.moveEditSessionToIndex(0, 1)
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe "sample.txt"
|
||||
expect(tabs.find('.tab:eq(1) .file-name').text()).toBe "sample.js"
|
||||
|
||||
editor.moveEditSessionToIndex(1, 0)
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe "sample.js"
|
||||
expect(tabs.find('.tab:eq(1) .file-name').text()).toBe "sample.txt"
|
||||
describe "when a pane item moves to a new index", ->
|
||||
it "updates the order of the tabs to match the new item order", ->
|
||||
expect(tabBar.getTabs().map (tab) -> tab.text()).toEqual ["Item 1", "sample.js", "Item 2"]
|
||||
pane.moveItem(item2, 1)
|
||||
expect(tabBar.getTabs().map (tab) -> tab.text()).toEqual ["Item 1", "Item 2", "sample.js"]
|
||||
pane.moveItem(editSession1, 0)
|
||||
expect(tabBar.getTabs().map (tab) -> tab.text()).toEqual ["sample.js", "Item 1", "Item 2"]
|
||||
pane.moveItem(item1, 2)
|
||||
expect(tabBar.getTabs().map (tab) -> tab.text()).toEqual ["sample.js", "Item 2", "Item 1"]
|
||||
|
||||
describe "dragging and dropping tabs", ->
|
||||
describe "when the tab is dropped onto itself", ->
|
||||
it "doesn't move the edit session and focuses the editor", ->
|
||||
expect(tabs.find('.tab:eq(1) .file-name').text()).toBe "sample.txt"
|
||||
buildDragEvents = (dragged, dropTarget) ->
|
||||
dataTransfer =
|
||||
data: {}
|
||||
setData: (key, value) -> @data[key] = value
|
||||
getData: (key) -> @data[key]
|
||||
|
||||
sortableElement = [tabs.find('.tab:eq(0)')]
|
||||
spyOn(tabs, 'getSortableElement').andCallFake -> sortableElement[0]
|
||||
event = $.Event()
|
||||
event.target = tabs[0]
|
||||
event.originalEvent =
|
||||
dataTransfer:
|
||||
data: {}
|
||||
setData: (key, value) -> @data[key] = value
|
||||
getData: (key) -> @data[key]
|
||||
dragStartEvent = $.Event()
|
||||
dragStartEvent.target = dragged[0]
|
||||
dragStartEvent.originalEvent = { dataTransfer }
|
||||
|
||||
editor.hiddenInput.focusout()
|
||||
tabs.onDragStart(event)
|
||||
tabs.onDrop(event)
|
||||
dropEvent = $.Event()
|
||||
dropEvent.target = dropTarget[0]
|
||||
dropEvent.originalEvent = { dataTransfer }
|
||||
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe "sample.js"
|
||||
expect(tabs.find('.tab:eq(1) .file-name').text()).toBe "sample.txt"
|
||||
expect(editor.isFocused).toBeTruthy()
|
||||
[dragStartEvent, dropEvent]
|
||||
|
||||
describe "when a tab is dragged from and dropped onto the same editor", ->
|
||||
it "moves the edit session, updates the order of the tabs, and focuses the editor", ->
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe "sample.js"
|
||||
expect(tabs.find('.tab:eq(1) .file-name').text()).toBe "sample.txt"
|
||||
describe "when a tab is dragged within the same pane", ->
|
||||
describe "when it is dropped on tab that's later in the list", ->
|
||||
it "moves the tab and its item, shows the tab's item, and focuses the pane", ->
|
||||
expect(tabBar.getTabs().map (tab) -> tab.text()).toEqual ["Item 1", "sample.js", "Item 2"]
|
||||
expect(pane.getItems()).toEqual [item1, editSession1, item2]
|
||||
expect(pane.activeItem).toBe item2
|
||||
spyOn(pane, 'focus')
|
||||
|
||||
sortableElement = [tabs.find('.tab:eq(0)')]
|
||||
spyOn(tabs, 'getSortableElement').andCallFake -> sortableElement[0]
|
||||
event = $.Event()
|
||||
event.target = tabs[0]
|
||||
event.originalEvent =
|
||||
dataTransfer:
|
||||
data: {}
|
||||
setData: (key, value) -> @data[key] = value
|
||||
getData: (key) -> @data[key]
|
||||
[dragStartEvent, dropEvent] = buildDragEvents(tabBar.tabAtIndex(0), tabBar.tabAtIndex(1))
|
||||
tabBar.onDragStart(dragStartEvent)
|
||||
tabBar.onDrop(dropEvent)
|
||||
|
||||
editor.hiddenInput.focusout()
|
||||
tabs.onDragStart(event)
|
||||
sortableElement = [tabs.find('.tab:eq(1)')]
|
||||
tabs.onDrop(event)
|
||||
expect(tabBar.getTabs().map (tab) -> tab.text()).toEqual ["sample.js", "Item 1", "Item 2"]
|
||||
expect(pane.getItems()).toEqual [editSession1, item1, item2]
|
||||
expect(pane.activeItem).toBe item1
|
||||
expect(pane.focus).toHaveBeenCalled()
|
||||
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe "sample.txt"
|
||||
expect(tabs.find('.tab:eq(1) .file-name').text()).toBe "sample.js"
|
||||
expect(editor.isFocused).toBeTruthy()
|
||||
describe "when it is dropped on a tab that's earlier in the list", ->
|
||||
it "moves the tab and its item, shows the tab's item, and focuses the pane", ->
|
||||
expect(tabBar.getTabs().map (tab) -> tab.text()).toEqual ["Item 1", "sample.js", "Item 2"]
|
||||
expect(pane.getItems()).toEqual [item1, editSession1, item2]
|
||||
expect(pane.activeItem).toBe item2
|
||||
spyOn(pane, 'focus')
|
||||
|
||||
describe "when a tab is dragged from one editor and dropped onto another editor", ->
|
||||
it "moves the edit session, updates the order of the tabs, and focuses the destination editor", ->
|
||||
leftTabs = tabs
|
||||
rightEditor = editor.splitRight()
|
||||
rightTabs = rootView.find('.tabs:last').view()
|
||||
[dragStartEvent, dropEvent] = buildDragEvents(tabBar.tabAtIndex(2), tabBar.tabAtIndex(0))
|
||||
tabBar.onDragStart(dragStartEvent)
|
||||
tabBar.onDrop(dropEvent)
|
||||
|
||||
sortableElement = [leftTabs.find('.tab:eq(0)')]
|
||||
spyOn(tabs, 'getSortableElement').andCallFake -> sortableElement[0]
|
||||
event = $.Event()
|
||||
event.target = leftTabs
|
||||
event.originalEvent =
|
||||
dataTransfer:
|
||||
data: {}
|
||||
setData: (key, value) -> @data[key] = value
|
||||
getData: (key) -> @data[key]
|
||||
expect(tabBar.getTabs().map (tab) -> tab.text()).toEqual ["Item 1", "Item 2", "sample.js"]
|
||||
expect(pane.getItems()).toEqual [item1, item2, editSession1]
|
||||
expect(pane.activeItem).toBe item2
|
||||
expect(pane.focus).toHaveBeenCalled()
|
||||
|
||||
rightEditor.hiddenInput.focusout()
|
||||
tabs.onDragStart(event)
|
||||
describe "when it is dropped on itself", ->
|
||||
it "doesn't move the tab or item, but does make it the active item and focuses the pane", ->
|
||||
expect(tabBar.getTabs().map (tab) -> tab.text()).toEqual ["Item 1", "sample.js", "Item 2"]
|
||||
expect(pane.getItems()).toEqual [item1, editSession1, item2]
|
||||
expect(pane.activeItem).toBe item2
|
||||
spyOn(pane, 'focus')
|
||||
|
||||
event.target = rightTabs
|
||||
sortableElement = [rightTabs.find('.tab:eq(0)')]
|
||||
tabs.onDrop(event)
|
||||
[dragStartEvent, dropEvent] = buildDragEvents(tabBar.tabAtIndex(0), tabBar.tabAtIndex(0))
|
||||
tabBar.onDragStart(dragStartEvent)
|
||||
tabBar.onDrop(dropEvent)
|
||||
|
||||
expect(rightTabs.find('.tab:eq(0) .file-name').text()).toBe "sample.txt"
|
||||
expect(rightTabs.find('.tab:eq(1) .file-name').text()).toBe "sample.js"
|
||||
expect(rightEditor.isFocused).toBeTruthy()
|
||||
expect(tabBar.getTabs().map (tab) -> tab.text()).toEqual ["Item 1", "sample.js", "Item 2"]
|
||||
expect(pane.getItems()).toEqual [item1, editSession1, item2]
|
||||
expect(pane.activeItem).toBe item1
|
||||
expect(pane.focus).toHaveBeenCalled()
|
||||
|
||||
describe "when a tab is dragged to a different pane", ->
|
||||
[pane2, tabBar2, item2b] = []
|
||||
|
||||
beforeEach ->
|
||||
pane2 = pane.splitRight()
|
||||
[item2b] = pane2.getItems()
|
||||
tabBar2 = new TabBarView(pane2)
|
||||
|
||||
it "removes the tab and item from their original pane and moves them to the target pane", ->
|
||||
expect(tabBar.getTabs().map (tab) -> tab.text()).toEqual ["Item 1", "sample.js", "Item 2"]
|
||||
expect(pane.getItems()).toEqual [item1, editSession1, item2]
|
||||
expect(pane.activeItem).toBe item2
|
||||
|
||||
expect(tabBar2.getTabs().map (tab) -> tab.text()).toEqual ["Item 2"]
|
||||
expect(pane2.getItems()).toEqual [item2b]
|
||||
expect(pane2.activeItem).toBe item2b
|
||||
spyOn(pane2, 'focus')
|
||||
|
||||
[dragStartEvent, dropEvent] = buildDragEvents(tabBar.tabAtIndex(0), tabBar2.tabAtIndex(0))
|
||||
tabBar.onDragStart(dragStartEvent)
|
||||
tabBar.onDrop(dropEvent)
|
||||
|
||||
expect(tabBar.getTabs().map (tab) -> tab.text()).toEqual ["sample.js", "Item 2"]
|
||||
expect(pane.getItems()).toEqual [editSession1, item2]
|
||||
expect(pane.activeItem).toBe item2
|
||||
|
||||
expect(tabBar2.getTabs().map (tab) -> tab.text()).toEqual ["Item 2", "Item 1"]
|
||||
expect(pane2.getItems()).toEqual [item2b, item1]
|
||||
expect(pane2.activeItem).toBe item1
|
||||
expect(pane2.focus).toHaveBeenCalled()
|
||||
|
||||
@@ -40,7 +40,7 @@ class TreeView extends ScrollView
|
||||
else
|
||||
@selectActiveFile()
|
||||
|
||||
rootView.on 'root-view:active-path-changed', => @selectActiveFile()
|
||||
rootView.on 'pane:active-item-changed pane:became-active', => @selectActiveFile()
|
||||
project.on 'path-changed', => @updateRoot()
|
||||
@observeConfig 'core.hideGitIgnoredFiles', => @updateRoot()
|
||||
|
||||
@@ -98,7 +98,7 @@ class TreeView extends ScrollView
|
||||
@openSelectedEntry(false) if entry instanceof FileView
|
||||
when 2
|
||||
if entry.is('.selected.file')
|
||||
rootView.getActiveEditor().focus()
|
||||
rootView.getActiveView().focus()
|
||||
else if entry.is('.selected.directory')
|
||||
entry.toggleExpansion()
|
||||
|
||||
@@ -119,6 +119,7 @@ class TreeView extends ScrollView
|
||||
|
||||
updateRoot: ->
|
||||
@root?.remove()
|
||||
|
||||
if rootDirectory = project.getRootDirectory()
|
||||
@root = new DirectoryView(directory: rootDirectory, isExpanded: true, project: project)
|
||||
@treeViewList.append(@root)
|
||||
@@ -126,14 +127,14 @@ class TreeView extends ScrollView
|
||||
@root = null
|
||||
|
||||
selectActiveFile: ->
|
||||
activeFilePath = rootView.getActiveEditor()?.getPath()
|
||||
activeFilePath = rootView.getActiveView()?.getPath()
|
||||
@selectEntryForPath(activeFilePath) if activeFilePath
|
||||
|
||||
revealActiveFile: ->
|
||||
@attach()
|
||||
@focus()
|
||||
|
||||
return unless activeFilePath = rootView.getActiveEditor()?.getPath()
|
||||
return unless activeFilePath = rootView.getActiveView()?.getPath()
|
||||
|
||||
activePathComponents = project.relativize(activeFilePath).split('/')
|
||||
currentPath = project.getPath().replace(/\/$/, '')
|
||||
|
||||
@@ -2,7 +2,7 @@ module.exports =
|
||||
treeView: null
|
||||
|
||||
activate: (@state) ->
|
||||
@state.attached ?= true unless rootView.getActiveEditSession()
|
||||
@state.attached ?= true unless rootView.getActivePaneItem()
|
||||
|
||||
@createView() if @state.attached
|
||||
rootView.command 'tree-view:toggle', => @createView().toggle()
|
||||
|
||||
@@ -65,7 +65,7 @@ describe "TreeView", ->
|
||||
|
||||
describe "when the project is assigned a path because a new buffer is saved", ->
|
||||
it "creates a root directory view but does not attach to the root view", ->
|
||||
rootView.getActiveEditSession().saveAs("/tmp/test.txt")
|
||||
rootView.getActivePaneItem().saveAs("/tmp/test.txt")
|
||||
expect(treeView.hasParent()).toBeFalsy()
|
||||
expect(treeView.root.getPath()).toBe require.resolve('/tmp')
|
||||
expect(treeView.root.parent()).toMatchSelector(".tree-view")
|
||||
@@ -174,14 +174,14 @@ describe "TreeView", ->
|
||||
describe "if the current file has no path", ->
|
||||
it "shows and focuses the tree view, but does not attempt to select a specific file", ->
|
||||
rootView.open()
|
||||
expect(rootView.getActiveEditSession().getPath()).toBeUndefined()
|
||||
expect(rootView.getActivePaneItem().getPath()).toBeUndefined()
|
||||
rootView.trigger 'tree-view:reveal-active-file'
|
||||
expect(treeView.hasParent()).toBeTruthy()
|
||||
expect(treeView.focus).toHaveBeenCalled()
|
||||
|
||||
describe "if there is no editor open", ->
|
||||
it "shows and focuses the tree view, but does not attempt to select a specific file", ->
|
||||
expect(rootView.getActiveEditSession()).toBeUndefined()
|
||||
expect(rootView.getActivePaneItem()).toBeUndefined()
|
||||
rootView.trigger 'tree-view:reveal-active-file'
|
||||
expect(treeView.hasParent()).toBeTruthy()
|
||||
expect(treeView.focus).toHaveBeenCalled()
|
||||
@@ -195,7 +195,7 @@ describe "TreeView", ->
|
||||
treeView.trigger 'tool-panel:unfocus'
|
||||
expect(treeView).toBeVisible()
|
||||
expect(treeView.find(".tree-view")).not.toMatchSelector(':focus')
|
||||
expect(rootView.getActiveEditor().isFocused).toBeTruthy()
|
||||
expect(rootView.getActiveView().isFocused).toBeTruthy()
|
||||
|
||||
describe "when core:close is triggered on the tree view", ->
|
||||
it "detaches the TreeView, focuses the RootView and does not bubble the core:close event", ->
|
||||
@@ -262,28 +262,28 @@ describe "TreeView", ->
|
||||
|
||||
describe "when a file is single-clicked", ->
|
||||
it "selects the files and opens it in the active editor, without changing focus", ->
|
||||
expect(rootView.getActiveEditor()).toBeUndefined()
|
||||
expect(rootView.getActiveView()).toBeUndefined()
|
||||
|
||||
sampleJs.trigger clickEvent(originalEvent: { detail: 1 })
|
||||
expect(sampleJs).toHaveClass 'selected'
|
||||
expect(rootView.getActiveEditor().getPath()).toBe require.resolve('fixtures/tree-view/tree-view.js')
|
||||
expect(rootView.getActiveEditor().isFocused).toBeFalsy()
|
||||
expect(rootView.getActiveView().getPath()).toBe require.resolve('fixtures/tree-view/tree-view.js')
|
||||
expect(rootView.getActiveView().isFocused).toBeFalsy()
|
||||
|
||||
sampleTxt.trigger clickEvent(originalEvent: { detail: 1 })
|
||||
expect(sampleTxt).toHaveClass 'selected'
|
||||
expect(treeView.find('.selected').length).toBe 1
|
||||
expect(rootView.getActiveEditor().getPath()).toBe require.resolve('fixtures/tree-view/tree-view.txt')
|
||||
expect(rootView.getActiveEditor().isFocused).toBeFalsy()
|
||||
expect(rootView.getActiveView().getPath()).toBe require.resolve('fixtures/tree-view/tree-view.txt')
|
||||
expect(rootView.getActiveView().isFocused).toBeFalsy()
|
||||
|
||||
describe "when a file is double-clicked", ->
|
||||
it "selects the file and opens it in the active editor on the first click, then changes focus to the active editor on the second", ->
|
||||
sampleJs.trigger clickEvent(originalEvent: { detail: 1 })
|
||||
expect(sampleJs).toHaveClass 'selected'
|
||||
expect(rootView.getActiveEditor().getPath()).toBe require.resolve('fixtures/tree-view/tree-view.js')
|
||||
expect(rootView.getActiveEditor().isFocused).toBeFalsy()
|
||||
expect(rootView.getActiveView().getPath()).toBe require.resolve('fixtures/tree-view/tree-view.js')
|
||||
expect(rootView.getActiveView().isFocused).toBeFalsy()
|
||||
|
||||
sampleJs.trigger clickEvent(originalEvent: { detail: 2 })
|
||||
expect(rootView.getActiveEditor().isFocused).toBeTruthy()
|
||||
expect(rootView.getActiveView().isFocused).toBeTruthy()
|
||||
|
||||
describe "when a directory is single-clicked", ->
|
||||
it "is selected", ->
|
||||
@@ -299,26 +299,25 @@ describe "TreeView", ->
|
||||
expect(subdir).toHaveClass 'selected'
|
||||
subdir.trigger clickEvent(originalEvent: { detail: 2 })
|
||||
expect(subdir).toHaveClass 'expanded'
|
||||
expect(rootView.getActiveEditor().isFocused).toBeFalsy()
|
||||
expect(rootView.getActiveView().isFocused).toBeFalsy()
|
||||
|
||||
describe "when a new file is opened in the active editor", ->
|
||||
it "is selected in the tree view if the file's entry visible", ->
|
||||
it "selects the file in the tree view if the file's entry visible", ->
|
||||
sampleJs.click()
|
||||
rootView.open(require.resolve('fixtures/tree-view/tree-view.txt'))
|
||||
|
||||
expect(sampleTxt).toHaveClass 'selected'
|
||||
expect(treeView.find('.selected').length).toBe 1
|
||||
|
||||
it "selected a file's parent dir if the file's entry is not visible", ->
|
||||
rootView.open(require.resolve('fixtures/tree-view/dir1/sub-dir1/sub-file1'))
|
||||
|
||||
it "selects the file's parent dir if the file's entry is not visible", ->
|
||||
rootView.open('dir1/sub-dir1/sub-file1')
|
||||
dirView = treeView.root.find('.directory:contains(dir1)').view()
|
||||
expect(dirView).toHaveClass 'selected'
|
||||
|
||||
describe "when a different editor becomes active", ->
|
||||
it "selects the file in that is open in that editor", ->
|
||||
sampleJs.click()
|
||||
leftEditor = rootView.getActiveEditor()
|
||||
leftEditor = rootView.getActiveView()
|
||||
rightEditor = leftEditor.splitRight()
|
||||
sampleTxt.click()
|
||||
|
||||
@@ -569,8 +568,8 @@ describe "TreeView", ->
|
||||
it "opens the file in the editor and focuses it", ->
|
||||
treeView.root.find('.file:contains(tree-view.js)').click()
|
||||
treeView.root.trigger 'tree-view:open-selected-entry'
|
||||
expect(rootView.getActiveEditor().getPath()).toBe require.resolve('fixtures/tree-view/tree-view.js')
|
||||
expect(rootView.getActiveEditor().isFocused).toBeTruthy()
|
||||
expect(rootView.getActiveView().getPath()).toBe require.resolve('fixtures/tree-view/tree-view.js')
|
||||
expect(rootView.getActiveView().isFocused).toBeTruthy()
|
||||
|
||||
describe "when a directory is selected", ->
|
||||
it "expands or collapses the directory", ->
|
||||
@@ -586,7 +585,7 @@ describe "TreeView", ->
|
||||
describe "when nothing is selected", ->
|
||||
it "does nothing", ->
|
||||
treeView.root.trigger 'tree-view:open-selected-entry'
|
||||
expect(rootView.getActiveEditor()).toBeUndefined()
|
||||
expect(rootView.getActiveView()).toBeUndefined()
|
||||
|
||||
describe "file modification", ->
|
||||
[dirView, fileView, rootDirPath, dirPath, filePath] = []
|
||||
@@ -650,7 +649,7 @@ describe "TreeView", ->
|
||||
expect(fs.exists(newPath)).toBeTruthy()
|
||||
expect(fs.isFile(newPath)).toBeTruthy()
|
||||
expect(addDialog.parent()).not.toExist()
|
||||
expect(rootView.getActiveEditor().getPath()).toBe newPath
|
||||
expect(rootView.getActiveView().getPath()).toBe newPath
|
||||
|
||||
waitsFor "tree view to be updated", ->
|
||||
dirView.entries.find("> .file").length > 1
|
||||
@@ -680,9 +679,9 @@ describe "TreeView", ->
|
||||
expect(fs.exists(newPath)).toBeTruthy()
|
||||
expect(fs.isDirectory(newPath)).toBeTruthy()
|
||||
expect(addDialog.parent()).not.toExist()
|
||||
expect(rootView.getActiveEditor().getPath()).not.toBe newPath
|
||||
expect(rootView.getActiveView().getPath()).not.toBe newPath
|
||||
expect(treeView.find(".tree-view")).toMatchSelector(':focus')
|
||||
expect(rootView.getActiveEditor().isFocused).toBeFalsy()
|
||||
expect(rootView.getActiveView().isFocused).toBeFalsy()
|
||||
expect(dirView.find('.directory.selected:contains(new)').length).toBe(1)
|
||||
|
||||
it "selects the created directory", ->
|
||||
@@ -693,9 +692,9 @@ describe "TreeView", ->
|
||||
expect(fs.exists(newPath)).toBeTruthy()
|
||||
expect(fs.isDirectory(newPath)).toBeTruthy()
|
||||
expect(addDialog.parent()).not.toExist()
|
||||
expect(rootView.getActiveEditor().getPath()).not.toBe newPath
|
||||
expect(rootView.getActiveView().getPath()).not.toBe newPath
|
||||
expect(treeView.find(".tree-view")).toMatchSelector(':focus')
|
||||
expect(rootView.getActiveEditor().isFocused).toBeFalsy()
|
||||
expect(rootView.getActiveView().isFocused).toBeFalsy()
|
||||
expect(dirView.find('.directory.selected:contains(new2)').length).toBe(1)
|
||||
|
||||
describe "when a file or directory already exists at the given path", ->
|
||||
@@ -722,7 +721,7 @@ describe "TreeView", ->
|
||||
rootView.attachToDom()
|
||||
rootView.focus()
|
||||
expect(addDialog.parent()).not.toExist()
|
||||
expect(rootView.getActiveEditor().isFocused).toBeTruthy()
|
||||
expect(rootView.getActiveView().isFocused).toBeTruthy()
|
||||
|
||||
describe "when a directory is selected", ->
|
||||
it "opens an add dialog with the directory's path populated", ->
|
||||
@@ -839,7 +838,7 @@ describe "TreeView", ->
|
||||
rootView.attachToDom()
|
||||
rootView.focus()
|
||||
expect(moveDialog.parent()).not.toExist()
|
||||
expect(rootView.getActiveEditor().isFocused).toBeTruthy()
|
||||
expect(rootView.getActiveView().isFocused).toBeTruthy()
|
||||
|
||||
describe "when a file is selected that's name starts with a '.'", ->
|
||||
[dotFilePath, dotFileView, moveDialog] = []
|
||||
|
||||
@@ -8,7 +8,7 @@ describe "WrapGuide", ->
|
||||
rootView.open('sample.js')
|
||||
window.loadPackage('wrap-guide')
|
||||
rootView.attachToDom()
|
||||
editor = rootView.getActiveEditor()
|
||||
editor = rootView.getActiveView()
|
||||
wrapGuide = rootView.find('.wrap-guide').view()
|
||||
editor.width(editor.charWidth * wrapGuide.getDefaultColumn() * 2)
|
||||
editor.trigger 'resize'
|
||||
|
||||
Reference in New Issue
Block a user