mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Merge pull request #7953 from acontreras89/ac-pane-split
Improve multi-pane API
This commit is contained in:
@@ -81,10 +81,10 @@
|
||||
'cmd-_': 'window:decrease-font-size'
|
||||
'cmd-0': 'window:reset-font-size'
|
||||
|
||||
'cmd-k up': 'pane:split-up' # Atom Specific
|
||||
'cmd-k down': 'pane:split-down' # Atom Specific
|
||||
'cmd-k left': 'pane:split-left' # Atom Specific
|
||||
'cmd-k right': 'pane:split-right' # Atom Specific
|
||||
'cmd-k up': 'pane:split-up-and-copy-active-item' # Atom Specific
|
||||
'cmd-k down': 'pane:split-down-and-copy-active-item' # Atom Specific
|
||||
'cmd-k left': 'pane:split-left-and-copy-active-item' # Atom Specific
|
||||
'cmd-k right': 'pane:split-right-and-copy-active-item' # Atom Specific
|
||||
'cmd-k cmd-w': 'pane:close' # Atom Specific
|
||||
'cmd-k alt-cmd-w': 'pane:close-other-items' # Atom Specific
|
||||
'cmd-k cmd-p': 'window:focus-previous-pane'
|
||||
|
||||
@@ -60,10 +60,10 @@
|
||||
'ctrl-_': 'window:decrease-font-size'
|
||||
'ctrl-0': 'window:reset-font-size'
|
||||
|
||||
'ctrl-k up': 'pane:split-up' # Atom Specific
|
||||
'ctrl-k down': 'pane:split-down' # Atom Specific
|
||||
'ctrl-k left': 'pane:split-left' # Atom Specific
|
||||
'ctrl-k right': 'pane:split-right' # Atom Specific
|
||||
'ctrl-k up': 'pane:split-up-and-copy-active-item' # Atom Specific
|
||||
'ctrl-k down': 'pane:split-down-and-copy-active-item' # Atom Specific
|
||||
'ctrl-k left': 'pane:split-left-and-copy-active-item' # Atom Specific
|
||||
'ctrl-k right': 'pane:split-right-and-copy-active-item' # Atom Specific
|
||||
'ctrl-k ctrl-w': 'pane:close' # Atom Specific
|
||||
'ctrl-k alt-ctrl-w': 'pane:close-other-items' # Atom Specific
|
||||
'ctrl-k ctrl-p': 'window:focus-previous-pane'
|
||||
|
||||
@@ -66,10 +66,10 @@
|
||||
'ctrl-_': 'window:decrease-font-size'
|
||||
'ctrl-0': 'window:reset-font-size'
|
||||
|
||||
'ctrl-k up': 'pane:split-up' # Atom Specific
|
||||
'ctrl-k down': 'pane:split-down' # Atom Specific
|
||||
'ctrl-k left': 'pane:split-left' # Atom Specific
|
||||
'ctrl-k right': 'pane:split-right' # Atom Specific
|
||||
'ctrl-k up': 'pane:split-up-and-copy-active-item' # Atom Specific
|
||||
'ctrl-k down': 'pane:split-down-and-copy-active-item' # Atom Specific
|
||||
'ctrl-k left': 'pane:split-left-and-copy-active-item' # Atom Specific
|
||||
'ctrl-k right': 'pane:split-right-and-copy-active-item' # Atom Specific
|
||||
'ctrl-k ctrl-w': 'pane:close' # Atom Specific
|
||||
'ctrl-k alt-ctrl-w': 'pane:close-other-items' # Atom Specific
|
||||
'ctrl-k ctrl-p': 'window:focus-previous-pane'
|
||||
|
||||
@@ -231,10 +231,14 @@ describe "PaneContainerElement", ->
|
||||
expect(leftPane.getFlexScale()).toBe 1/1.1
|
||||
expect(rightPane.getFlexScale()).toBe 1/1.1
|
||||
|
||||
describe "changing focus directionally between panes", ->
|
||||
[containerElement, pane1, pane2, pane3, pane4, pane5, pane6, pane7, pane8, pane9] = []
|
||||
describe "changing focus, copying and moving items directionally between panes", ->
|
||||
[item1, item2, item3, item4, item5, item6, item7, item8, item9,
|
||||
pane1, pane2, pane3, pane4, pane5, pane6, pane7, pane8, pane9,
|
||||
container, containerElement] = []
|
||||
|
||||
beforeEach ->
|
||||
atom.config.set("core.destroyEmptyPanes", false)
|
||||
|
||||
# Set up a grid of 9 panes, in the following arrangement, where the
|
||||
# numbers correspond to the variable names below.
|
||||
#
|
||||
@@ -250,22 +254,30 @@ describe "PaneContainerElement", ->
|
||||
element = document.createElement('div')
|
||||
element.textContent = id
|
||||
element.tabIndex = -1
|
||||
element.copy = ->
|
||||
element.cloneNode(true)
|
||||
element
|
||||
|
||||
container = new PaneContainer(config: atom.config, confirm: atom.confirm.bind(atom))
|
||||
|
||||
[item1, item2, item3, item4, item5, item6, item7, item8, item9] =
|
||||
[buildElement('1'), buildElement('2'), buildElement('3'),
|
||||
buildElement('4'), buildElement('5'), buildElement('6'),
|
||||
buildElement('7'), buildElement('8'), buildElement('9')]
|
||||
|
||||
pane1 = container.getActivePane()
|
||||
pane1.activateItem(buildElement('1'))
|
||||
pane4 = pane1.splitDown(items: [buildElement('4')])
|
||||
pane7 = pane4.splitDown(items: [buildElement('7')])
|
||||
pane1.activateItem(item1)
|
||||
pane4 = pane1.splitDown(items: [item4])
|
||||
pane7 = pane4.splitDown(items: [item7])
|
||||
|
||||
pane2 = pane1.splitRight(items: [buildElement('2')])
|
||||
pane3 = pane2.splitRight(items: [buildElement('3')])
|
||||
pane2 = pane1.splitRight(items: [item2])
|
||||
pane3 = pane2.splitRight(items: [item3])
|
||||
|
||||
pane5 = pane4.splitRight(items: [buildElement('5')])
|
||||
pane6 = pane5.splitRight(items: [buildElement('6')])
|
||||
pane5 = pane4.splitRight(items: [item5])
|
||||
pane6 = pane5.splitRight(items: [item6])
|
||||
|
||||
pane8 = pane7.splitRight(items: [buildElement('8')])
|
||||
pane9 = pane8.splitRight(items: [buildElement('9')])
|
||||
pane8 = pane7.splitRight(items: [item8])
|
||||
pane9 = pane8.splitRight(items: [item9])
|
||||
|
||||
containerElement = atom.views.getView(container)
|
||||
containerElement.style.height = '400px'
|
||||
@@ -323,3 +335,87 @@ describe "PaneContainerElement", ->
|
||||
pane6.activate()
|
||||
containerElement.focusPaneViewOnRight()
|
||||
expect(document.activeElement).toBe pane6.getActiveItem()
|
||||
|
||||
describe "::moveActiveItemToPaneAbove(keepOriginal)", ->
|
||||
describe "when there are multiple rows above the focused pane", ->
|
||||
it "moves the active item up to the adjacent row", ->
|
||||
pane8.activate()
|
||||
containerElement.moveActiveItemToPaneAbove()
|
||||
expect(container.paneForItem(item8)).toBe pane5
|
||||
expect(pane5.getActiveItem()).toBe item8
|
||||
|
||||
describe "when there are no rows above the focused pane", ->
|
||||
it "keeps the active item in the focused pane", ->
|
||||
pane2.activate()
|
||||
containerElement.moveActiveItemToPaneAbove()
|
||||
expect(container.paneForItem(item2)).toBe pane2
|
||||
|
||||
describe "when `keepOriginal: true` is passed in the params", ->
|
||||
it "keeps the item and adds a copy of it to the adjacent pane", ->
|
||||
pane8.activate()
|
||||
containerElement.moveActiveItemToPaneAbove(keepOriginal: true)
|
||||
expect(container.paneForItem(item8)).toBe pane8
|
||||
expect(pane5.getActiveItem().textContent).toBe '8'
|
||||
|
||||
describe "::moveActiveItemToPaneBelow(keepOriginal)", ->
|
||||
describe "when there are multiple rows below the focused pane", ->
|
||||
it "moves the active item down to the adjacent row", ->
|
||||
pane2.activate()
|
||||
containerElement.moveActiveItemToPaneBelow()
|
||||
expect(container.paneForItem(item2)).toBe pane5
|
||||
expect(pane5.getActiveItem()).toBe item2
|
||||
|
||||
describe "when there are no rows below the focused pane", ->
|
||||
it "keeps the active item in the focused pane", ->
|
||||
pane8.activate()
|
||||
containerElement.moveActiveItemToPaneBelow()
|
||||
expect(container.paneForItem(item8)).toBe pane8
|
||||
|
||||
describe "when `keepOriginal: true` is passed in the params", ->
|
||||
it "keeps the item and adds a copy of it to the adjacent pane", ->
|
||||
pane2.activate()
|
||||
containerElement.moveActiveItemToPaneBelow(keepOriginal: true)
|
||||
expect(container.paneForItem(item2)).toBe pane2
|
||||
expect(pane5.getActiveItem().textContent).toBe '2'
|
||||
|
||||
describe "::moveActiveItemToPaneOnLeft(keepOriginal)", ->
|
||||
describe "when there are multiple columns to the left of the focused pane", ->
|
||||
it "moves the active item left to the adjacent column", ->
|
||||
pane6.activate()
|
||||
containerElement.moveActiveItemToPaneOnLeft()
|
||||
expect(container.paneForItem(item6)).toBe pane5
|
||||
expect(pane5.getActiveItem()).toBe item6
|
||||
|
||||
describe "when there are no columns to the left of the focused pane", ->
|
||||
it "keeps the active item in the focused pane", ->
|
||||
pane4.activate()
|
||||
containerElement.moveActiveItemToPaneOnLeft()
|
||||
expect(container.paneForItem(item4)).toBe pane4
|
||||
|
||||
describe "when `keepOriginal: true` is passed in the params", ->
|
||||
it "keeps the item and adds a copy of it to the adjacent pane", ->
|
||||
pane6.activate()
|
||||
containerElement.moveActiveItemToPaneOnLeft(keepOriginal: true)
|
||||
expect(container.paneForItem(item6)).toBe pane6
|
||||
expect(pane5.getActiveItem().textContent).toBe '6'
|
||||
|
||||
describe "::moveActiveItemToPaneOnRight(keepOriginal)", ->
|
||||
describe "when there are multiple columns to the right of the focused pane", ->
|
||||
it "moves the active item right to the adjacent column", ->
|
||||
pane4.activate()
|
||||
containerElement.moveActiveItemToPaneOnRight()
|
||||
expect(container.paneForItem(item4)).toBe pane5
|
||||
expect(pane5.getActiveItem()).toBe item4
|
||||
|
||||
describe "when there are no columns to the right of the focused pane", ->
|
||||
it "keeps the active item in the focused pane", ->
|
||||
pane6.activate()
|
||||
containerElement.moveActiveItemToPaneOnRight()
|
||||
expect(container.paneForItem(item6)).toBe pane6
|
||||
|
||||
describe "when `keepOriginal: true` is passed in the params", ->
|
||||
it "keeps the item and adds a copy of it to the adjacent pane", ->
|
||||
pane4.activate()
|
||||
containerElement.moveActiveItemToPaneOnRight(keepOriginal: true)
|
||||
expect(container.paneForItem(item4)).toBe pane4
|
||||
expect(pane5.getActiveItem().textContent).toBe '4'
|
||||
|
||||
@@ -325,3 +325,27 @@ describe "PaneContainer", ->
|
||||
expect(item1.saved).toBe true
|
||||
expect(item2.saved).toBe false
|
||||
expect(item3.saved).toBe true
|
||||
|
||||
describe "::moveActiveItemToPane(destPane) and ::copyActiveItemToPane(destPane)", ->
|
||||
[container, pane1, pane2, item1] = []
|
||||
|
||||
beforeEach ->
|
||||
class TestItem
|
||||
constructor: (id) -> @id = id
|
||||
copy: -> new TestItem(@id)
|
||||
|
||||
container = new PaneContainer(params)
|
||||
pane1 = container.getRoot()
|
||||
item1 = new TestItem('1')
|
||||
pane2 = pane1.splitRight(items: [item1])
|
||||
|
||||
describe "::::moveActiveItemToPane(destPane)", ->
|
||||
it "moves active item to given pane and focuses it", ->
|
||||
container.moveActiveItemToPane(pane1)
|
||||
expect(pane1.getActiveItem()).toBe item1
|
||||
|
||||
describe "::::copyActiveItemToPane(destPane)", ->
|
||||
it "copies active item to given pane and focuses it", ->
|
||||
container.copyActiveItemToPane(pane1)
|
||||
expect(container.paneForItem(item1)).toBe pane2
|
||||
expect(pane1.getActiveItem().id).toBe item1.id
|
||||
|
||||
@@ -606,12 +606,13 @@ describe "Pane", ->
|
||||
expect(item4.isDestroyed()).toBe false
|
||||
|
||||
describe "split methods", ->
|
||||
[pane1, container] = []
|
||||
[pane1, item1, container] = []
|
||||
|
||||
beforeEach ->
|
||||
container = new PaneContainer(config: atom.config, confirm: confirm, deserializerManager: atom.deserializers)
|
||||
pane1 = container.getActivePane()
|
||||
pane1.addItem(new Item("A"))
|
||||
item1 = new Item("A")
|
||||
pane1.addItem(item1)
|
||||
|
||||
describe "::splitLeft(params)", ->
|
||||
describe "when the parent is the container root", ->
|
||||
@@ -621,6 +622,11 @@ describe "Pane", ->
|
||||
expect(container.root.orientation).toBe 'horizontal'
|
||||
expect(container.root.children).toEqual [pane2, pane3, pane1]
|
||||
|
||||
describe "when `moveActiveItem: true` is passed in the params", ->
|
||||
it "moves the active item", ->
|
||||
pane2 = pane1.splitLeft(moveActiveItem: true)
|
||||
expect(pane2.getActiveItem()).toBe item1
|
||||
|
||||
describe "when `copyActiveItem: true` is passed in the params", ->
|
||||
it "duplicates the active item", ->
|
||||
pane2 = pane1.splitLeft(copyActiveItem: true)
|
||||
@@ -643,6 +649,11 @@ describe "Pane", ->
|
||||
expect(container.root.orientation).toBe 'horizontal'
|
||||
expect(container.root.children).toEqual [pane1, pane3, pane2]
|
||||
|
||||
describe "when `moveActiveItem: true` is passed in the params", ->
|
||||
it "moves the active item", ->
|
||||
pane2 = pane1.splitLeft(moveActiveItem: true)
|
||||
expect(pane2.getActiveItem()).toBe item1
|
||||
|
||||
describe "when `copyActiveItem: true` is passed in the params", ->
|
||||
it "duplicates the active item", ->
|
||||
pane2 = pane1.splitRight(copyActiveItem: true)
|
||||
@@ -665,6 +676,11 @@ describe "Pane", ->
|
||||
expect(container.root.orientation).toBe 'vertical'
|
||||
expect(container.root.children).toEqual [pane2, pane3, pane1]
|
||||
|
||||
describe "when `moveActiveItem: true` is passed in the params", ->
|
||||
it "moves the active item", ->
|
||||
pane2 = pane1.splitLeft(moveActiveItem: true)
|
||||
expect(pane2.getActiveItem()).toBe item1
|
||||
|
||||
describe "when `copyActiveItem: true` is passed in the params", ->
|
||||
it "duplicates the active item", ->
|
||||
pane2 = pane1.splitUp(copyActiveItem: true)
|
||||
@@ -687,6 +703,11 @@ describe "Pane", ->
|
||||
expect(container.root.orientation).toBe 'vertical'
|
||||
expect(container.root.children).toEqual [pane1, pane3, pane2]
|
||||
|
||||
describe "when `moveActiveItem: true` is passed in the params", ->
|
||||
it "moves the active item", ->
|
||||
pane2 = pane1.splitLeft(moveActiveItem: true)
|
||||
expect(pane2.getActiveItem()).toBe item1
|
||||
|
||||
describe "when `copyActiveItem: true` is passed in the params", ->
|
||||
it "duplicates the active item", ->
|
||||
pane2 = pane1.splitDown(copyActiveItem: true)
|
||||
|
||||
@@ -88,6 +88,8 @@ describe "TextEditor", ->
|
||||
it "returns a different edit session with the same initial state", ->
|
||||
editor.setSelectedBufferRange([[1, 2], [3, 4]])
|
||||
editor.addSelectionForBufferRange([[5, 6], [7, 8]], reversed: true)
|
||||
editor.firstVisibleScreenRow = 5
|
||||
editor.firstVisibleScreenColumn = 5
|
||||
editor.foldBufferRow(4)
|
||||
expect(editor.isFoldedAtBufferRow(4)).toBeTruthy()
|
||||
|
||||
@@ -95,6 +97,8 @@ describe "TextEditor", ->
|
||||
expect(editor2.id).not.toBe editor.id
|
||||
expect(editor2.getSelectedBufferRanges()).toEqual editor.getSelectedBufferRanges()
|
||||
expect(editor2.getSelections()[1].isReversed()).toBeTruthy()
|
||||
expect(editor2.getFirstVisibleScreenRow()).toBe 5
|
||||
expect(editor2.getFirstVisibleScreenColumn()).toBe 5
|
||||
expect(editor2.isFoldedAtBufferRow(4)).toBeTruthy()
|
||||
|
||||
# editor2 can now diverge from its origin edit session
|
||||
|
||||
@@ -36,6 +36,27 @@ class PaneContainerElement extends HTMLElement
|
||||
focusPaneViewOnRight: ->
|
||||
@nearestPaneInDirection('right')?.focus()
|
||||
|
||||
moveActiveItemToPaneAbove: (params) ->
|
||||
@moveActiveItemToNearestPaneInDirection('above', params)
|
||||
|
||||
moveActiveItemToPaneBelow: (params) ->
|
||||
@moveActiveItemToNearestPaneInDirection('below', params)
|
||||
|
||||
moveActiveItemToPaneOnLeft: (params) ->
|
||||
@moveActiveItemToNearestPaneInDirection('left', params)
|
||||
|
||||
moveActiveItemToPaneOnRight: (params) ->
|
||||
@moveActiveItemToNearestPaneInDirection('right', params)
|
||||
|
||||
moveActiveItemToNearestPaneInDirection: (direction, params) ->
|
||||
destPane = @nearestPaneInDirection(direction)?.getModel()
|
||||
return unless destPane?
|
||||
if params?.keepOriginal
|
||||
@model.copyActiveItemToPane(destPane)
|
||||
else
|
||||
@model.moveActiveItemToPane(destPane)
|
||||
destPane.focus()
|
||||
|
||||
nearestPaneInDirection: (direction) ->
|
||||
distance = (pointA, pointB) ->
|
||||
x = pointB.x - pointA.x
|
||||
|
||||
@@ -164,6 +164,15 @@ class PaneContainer extends Model
|
||||
else
|
||||
false
|
||||
|
||||
moveActiveItemToPane: (destPane) ->
|
||||
item = @activePane.getActiveItem()
|
||||
@activePane.moveItemToPane(item, destPane)
|
||||
destPane.setActiveItem(item)
|
||||
|
||||
copyActiveItemToPane: (destPane) ->
|
||||
item = @activePane.copyActiveItem()
|
||||
destPane.activateItem(item)
|
||||
|
||||
destroyEmptyPanes: ->
|
||||
pane.destroy() for pane in @getPanes() when pane.items.length is 0
|
||||
return
|
||||
|
||||
@@ -666,6 +666,8 @@ class Pane extends Model
|
||||
when 'before' then @parent.insertChildBefore(this, newPane)
|
||||
when 'after' then @parent.insertChildAfter(this, newPane)
|
||||
|
||||
@moveItemToPane(@activeItem, newPane) if params?.moveActiveItem
|
||||
|
||||
newPane.activate()
|
||||
newPane
|
||||
|
||||
|
||||
@@ -50,6 +50,14 @@ module.exports = ({commandRegistry, commandInstaller, config}) ->
|
||||
'window:focus-pane-below': -> @focusPaneViewBelow()
|
||||
'window:focus-pane-on-left': -> @focusPaneViewOnLeft()
|
||||
'window:focus-pane-on-right': -> @focusPaneViewOnRight()
|
||||
'window:move-active-item-to-pane-above': -> @moveActiveItemToPaneAbove()
|
||||
'window:move-active-item-to-pane-below': -> @moveActiveItemToPaneBelow()
|
||||
'window:move-active-item-to-pane-on-left': -> @moveActiveItemToPaneOnLeft()
|
||||
'window:move-active-item-to-pane-on-right': -> @moveActiveItemToPaneOnRight()
|
||||
'window:copy-active-item-to-pane-above': -> @moveActiveItemToPaneAbove(keepOriginal: true)
|
||||
'window:copy-active-item-to-pane-below': -> @moveActiveItemToPaneBelow(keepOriginal: true)
|
||||
'window:copy-active-item-to-pane-on-left': -> @moveActiveItemToPaneOnLeft(keepOriginal: true)
|
||||
'window:copy-active-item-to-pane-on-right': -> @moveActiveItemToPaneOnRight(keepOriginal: true)
|
||||
'window:save-all': -> @getModel().saveAll()
|
||||
'window:toggle-invisibles': -> config.set("editor.showInvisibles", not config.get("editor.showInvisibles"))
|
||||
'window:log-deprecation-warnings': -> Grim.logDeprecations()
|
||||
@@ -65,10 +73,18 @@ module.exports = ({commandRegistry, commandInstaller, config}) ->
|
||||
|
||||
commandRegistry.add 'atom-pane',
|
||||
'pane:save-items': -> @getModel().saveItems()
|
||||
'pane:split-left': -> @getModel().splitLeft(copyActiveItem: true)
|
||||
'pane:split-right': -> @getModel().splitRight(copyActiveItem: true)
|
||||
'pane:split-up': -> @getModel().splitUp(copyActiveItem: true)
|
||||
'pane:split-down': -> @getModel().splitDown(copyActiveItem: true)
|
||||
'pane:split-left': -> @getModel().splitLeft()
|
||||
'pane:split-right': -> @getModel().splitRight()
|
||||
'pane:split-up': -> @getModel().splitUp()
|
||||
'pane:split-down': -> @getModel().splitDown()
|
||||
'pane:split-left-and-copy-active-item': -> @getModel().splitLeft(copyActiveItem: true)
|
||||
'pane:split-right-and-copy-active-item': -> @getModel().splitRight(copyActiveItem: true)
|
||||
'pane:split-up-and-copy-active-item': -> @getModel().splitUp(copyActiveItem: true)
|
||||
'pane:split-down-and-copy-active-item': -> @getModel().splitDown(copyActiveItem: true)
|
||||
'pane:split-left-and-move-active-item': -> @getModel().splitLeft(moveActiveItem: true)
|
||||
'pane:split-right-and-move-active-item': -> @getModel().splitRight(moveActiveItem: true)
|
||||
'pane:split-up-and-move-active-item': -> @getModel().splitUp(moveActiveItem: true)
|
||||
'pane:split-down-and-move-active-item': -> @getModel().splitDown(moveActiveItem: true)
|
||||
'pane:close': -> @getModel().close()
|
||||
'pane:close-other-items': -> @getModel().destroyInactiveItems()
|
||||
'pane:increase-size': -> @getModel().increaseSize()
|
||||
|
||||
@@ -497,6 +497,7 @@ class TextEditor extends Model
|
||||
newEditor = new TextEditor({
|
||||
@buffer, displayBuffer, selectionsMarkerLayer, @tabLength, softTabs,
|
||||
suppressCursorCreation: true, @config, @notificationManager, @packageManager,
|
||||
@firstVisibleScreenRow, @firstVisibleScreenColumn,
|
||||
@clipboard, @viewRegistry, @grammarRegistry, @project, @assert, @applicationDelegate
|
||||
})
|
||||
newEditor
|
||||
|
||||
@@ -104,6 +104,14 @@ class WorkspaceElement extends HTMLElement
|
||||
|
||||
focusPaneViewOnRight: -> @paneContainer.focusPaneViewOnRight()
|
||||
|
||||
moveActiveItemToPaneAbove: (params) -> @paneContainer.moveActiveItemToPaneAbove(params)
|
||||
|
||||
moveActiveItemToPaneBelow: (params) -> @paneContainer.moveActiveItemToPaneBelow(params)
|
||||
|
||||
moveActiveItemToPaneOnLeft: (params) -> @paneContainer.moveActiveItemToPaneOnLeft(params)
|
||||
|
||||
moveActiveItemToPaneOnRight: (params) -> @paneContainer.moveActiveItemToPaneOnRight(params)
|
||||
|
||||
runPackageSpecs: ->
|
||||
if activePath = @workspace.getActivePaneItem()?.getPath?()
|
||||
[projectPath] = @project.relativizePath(activePath)
|
||||
|
||||
Reference in New Issue
Block a user