mirror of
https://github.com/atom/atom.git
synced 2026-02-12 23:55:10 -05:00
Merge remote-tracking branch 'origin/master' into config
This commit is contained in:
@@ -10,7 +10,7 @@ class Directory
|
||||
constructor: (@path) ->
|
||||
|
||||
getBaseName: ->
|
||||
fs.base(@path) + '/'
|
||||
fs.base(@path)
|
||||
|
||||
getPath: -> @path
|
||||
|
||||
|
||||
@@ -326,6 +326,14 @@ class Editor extends View
|
||||
@removeClass 'focused'
|
||||
@autosave() if config.get "editor.autosave"
|
||||
|
||||
@underlayer.on 'click', (e) =>
|
||||
return unless e.target is @underlayer[0]
|
||||
return unless e.offsetY > @overlayer.height()
|
||||
if e.shiftKey
|
||||
@selectToBottom()
|
||||
else
|
||||
@moveCursorToBottom()
|
||||
|
||||
@overlayer.on 'mousedown', (e) =>
|
||||
@overlayer.hide()
|
||||
clickedElement = document.elementFromPoint(e.pageX, e.pageY)
|
||||
@@ -738,7 +746,7 @@ class Editor extends View
|
||||
height = @lineHeight * @screenLineCount()
|
||||
unless @layerHeight == height
|
||||
@renderedLines.height(height)
|
||||
@underlayer.height(height)
|
||||
@underlayer.css('min-height', height)
|
||||
@overlayer.height(height)
|
||||
@layerHeight = height
|
||||
|
||||
@@ -751,6 +759,7 @@ class Editor extends View
|
||||
@underlayer.css('min-width', minWidth)
|
||||
@overlayer.css('min-width', minWidth)
|
||||
@layerMinWidth = minWidth
|
||||
@trigger 'editor:min-width-changed'
|
||||
|
||||
clearRenderedLines: ->
|
||||
@renderedLines.empty()
|
||||
|
||||
@@ -11,6 +11,11 @@ class Range
|
||||
else
|
||||
new Range(object.start, object.end)
|
||||
|
||||
@fromPointWithDelta: (point, rowDelta, columnDelta) ->
|
||||
pointA = Point.fromObject(point)
|
||||
pointB = new Point(point.row + rowDelta, point.column + columnDelta)
|
||||
new Range(pointA, pointB)
|
||||
|
||||
constructor: (pointA = new Point(0, 0), pointB = new Point(0, 0)) ->
|
||||
pointA = Point.fromObject(pointA)
|
||||
pointB = Point.fromObject(pointB)
|
||||
|
||||
@@ -42,11 +42,11 @@ class TextMateBundle
|
||||
|
||||
@grammarByShebang: (filePath) ->
|
||||
try
|
||||
firstLine = fs.read(filePath).match(/.*/)[0]
|
||||
fileContents = fs.read(filePath)
|
||||
catch e
|
||||
null
|
||||
|
||||
_.find @grammars, (grammar) -> grammar.firstLineRegex?.test(firstLine)
|
||||
_.find @grammars, (grammar) -> grammar.firstLineRegex?.test(fileContents)
|
||||
|
||||
@grammarForScopeName: (scopeName) ->
|
||||
@grammarsByScopeName[scopeName]
|
||||
|
||||
@@ -53,6 +53,7 @@ class TextMateGrammar
|
||||
|
||||
tokens.push(nextTokens...)
|
||||
position = tokensEndPosition
|
||||
break if position is line.length and nextTokens.length is 0
|
||||
|
||||
else # push filler token for unmatched text at end of line
|
||||
if position < line.length
|
||||
|
||||
@@ -96,6 +96,15 @@ describe "Autocomplete", ->
|
||||
expect(autocomplete.matchesList.find('li').length).toBe 1
|
||||
expect(autocomplete.matchesList.find('li:eq(0)')).toHaveText "No matches found"
|
||||
|
||||
it "autocompletes word and replaces case of prefix with case of word", ->
|
||||
editor.getBuffer().insert([10,0] ,"extra:SO:extra")
|
||||
editor.setCursorBufferPosition([10,8])
|
||||
autocomplete.attach()
|
||||
|
||||
expect(editor.lineForBufferRow(10)).toBe "extra:sort:extra"
|
||||
expect(editor.getCursorBufferPosition()).toEqual [10,10]
|
||||
expect(editor.getSelection().isEmpty()).toBeTruthy()
|
||||
|
||||
describe "when text is selected", ->
|
||||
it 'autocompletes word when there is only a prefix', ->
|
||||
editor.getBuffer().insert([10,0] ,"extra:sort:extra")
|
||||
@@ -399,5 +408,3 @@ describe "Autocomplete", ->
|
||||
|
||||
editor.trigger 'core:move-up'
|
||||
expect(editor.getCursorBufferPosition().row).toBe 0
|
||||
|
||||
|
||||
|
||||
@@ -185,11 +185,10 @@ class Autocomplete extends View
|
||||
{prefix, suffix} = @prefixAndSuffixOfSelection(selection)
|
||||
|
||||
if (prefix.length + suffix.length) > 0
|
||||
regex = new RegExp("^#{prefix}(.+)#{suffix}$", "i")
|
||||
regex = new RegExp("^#{prefix}.+#{suffix}$", "i")
|
||||
currentWord = prefix + @editor.getSelectedText() + suffix
|
||||
for word in @wordList when regex.test(word) and word != currentWord
|
||||
match = regex.exec(word)
|
||||
{prefix, suffix, word, infix: match[1]}
|
||||
{prefix, suffix, word}
|
||||
else
|
||||
[]
|
||||
|
||||
@@ -197,9 +196,15 @@ class Autocomplete extends View
|
||||
selection = @editor.getSelection()
|
||||
startPosition = selection.getBufferRange().start
|
||||
@isAutocompleting = true
|
||||
@editor.insertText(match.infix)
|
||||
buffer = @editor.getBuffer()
|
||||
@editor.activeEditSession.transact =>
|
||||
selection.deleteSelectedText()
|
||||
buffer.delete(Range.fromPointWithDelta(@editor.getCursorBufferPosition(), 0, -match.prefix.length))
|
||||
buffer.delete(Range.fromPointWithDelta(@editor.getCursorBufferPosition(), 0, match.suffix.length))
|
||||
@editor.insertText(match.word)
|
||||
|
||||
@currentMatchBufferRange = [startPosition, [startPosition.row, startPosition.column + match.infix.length]]
|
||||
infixLength = match.word.length - match.prefix.length - match.suffix.length
|
||||
@currentMatchBufferRange = [startPosition, [startPosition.row, startPosition.column + infixLength]]
|
||||
@editor.setSelectedBufferRange(@currentMatchBufferRange)
|
||||
@isAutocompleting = false
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ RootView = require 'root-view'
|
||||
FuzzyFinder = require 'fuzzy-finder'
|
||||
$ = require 'jquery'
|
||||
{$$} = require 'space-pen'
|
||||
fs = require 'fs'
|
||||
|
||||
describe 'FuzzyFinder', ->
|
||||
[rootView, finder] = []
|
||||
@@ -56,7 +57,7 @@ describe 'FuzzyFinder', ->
|
||||
runs ->
|
||||
expect(finder.list.children('li').length).toBe paths.length, finder.maxResults
|
||||
for path in paths
|
||||
expect(finder.list.find("li:contains(#{path})")).toExist()
|
||||
expect(finder.list.find("li:contains(#{fs.base(path)})")).toExist()
|
||||
expect(finder.list.children().first()).toHaveClass 'selected'
|
||||
expect(finder.find(".loading")).not.toBeVisible()
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
SelectList = require 'select-list'
|
||||
_ = require 'underscore'
|
||||
$ = require 'jquery'
|
||||
fs = require 'fs'
|
||||
|
||||
module.exports =
|
||||
class FuzzyFinder extends SelectList
|
||||
@@ -25,7 +26,20 @@ class FuzzyFinder extends SelectList
|
||||
@projectPaths = null
|
||||
|
||||
itemForElement: (path) ->
|
||||
$$ -> @li path
|
||||
$$ ->
|
||||
@li =>
|
||||
ext = fs.extension(path)
|
||||
if fs.isCompressedExtension(ext)
|
||||
typeClass = 'compressed-name'
|
||||
else if fs.isImageExtension(ext)
|
||||
typeClass = 'image-name'
|
||||
else if fs.isPdfExtension(ext)
|
||||
typeClass = 'pdf-name'
|
||||
else
|
||||
typeClass = 'text-name'
|
||||
@span fs.base(path), class: "file #{typeClass}"
|
||||
if folder = fs.directory(path)
|
||||
@span "- #{folder}/", class: 'directory'
|
||||
|
||||
confirmed : (path) ->
|
||||
return unless path.length
|
||||
|
||||
@@ -19,15 +19,15 @@ class StatusBar extends View
|
||||
|
||||
@content: ->
|
||||
@div class: 'status-bar', =>
|
||||
@div class: 'file-info', =>
|
||||
@span class: 'git-branch', outlet: 'branchArea', =>
|
||||
@span class: 'octicons branch-icon'
|
||||
@span class: 'branch-label', outlet: 'branchLabel'
|
||||
@span class: 'git-status', outlet: 'gitStatusIcon'
|
||||
@span class: 'file-info', =>
|
||||
@span class: 'current-path', outlet: 'currentPath'
|
||||
@span class: 'buffer-modified', outlet: 'bufferModified'
|
||||
@div class: 'cursor-position', =>
|
||||
@span outlet: 'gitStatusIcon'
|
||||
@span outlet: 'branchArea', =>
|
||||
@span class: 'octicons branch-icon'
|
||||
@span class: 'branch-label', outlet: 'branchLabel'
|
||||
@span outlet: 'cursorPosition'
|
||||
@span class: 'cursor-position', outlet: 'cursorPosition'
|
||||
|
||||
|
||||
initialize: (@rootView, @editor) ->
|
||||
@updatePathText()
|
||||
@@ -76,7 +76,7 @@ class StatusBar extends View
|
||||
@gitStatusIcon.empty()
|
||||
return unless path
|
||||
|
||||
@gitStatusIcon.removeClass().addClass('octicons')
|
||||
@gitStatusIcon.removeClass().addClass('git-status octicons')
|
||||
if @buffer.getGit()?.isPathModified(path)
|
||||
@gitStatusIcon.addClass('modified-status-icon')
|
||||
else if @buffer.getGit()?.isPathNew(path)
|
||||
|
||||
@@ -1,34 +1,87 @@
|
||||
.tabs {
|
||||
background: #222;
|
||||
border-bottom: 4px solid #555;
|
||||
background: #333333;
|
||||
border-bottom: 4px solid #424242;
|
||||
font: caption !important;
|
||||
}
|
||||
|
||||
.tab {
|
||||
cursor: default;
|
||||
float: left;
|
||||
margin: 4px;
|
||||
margin-bottom: 0;
|
||||
margin-right: 0;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
background: #3a3a3a;
|
||||
color: #d0d0d0;
|
||||
-webkit-border-top-left-radius: 4px;
|
||||
-webkit-border-top-right-radius: 4px;
|
||||
font-size: 90%;
|
||||
padding: 2px 21px 2px 9px;
|
||||
background-image: -webkit-linear-gradient(#444, #3d3d3d);
|
||||
color: #a5aaaa;
|
||||
display: table-cell;
|
||||
position: relative;
|
||||
width:175px;
|
||||
border-top: 1px solid #383838;
|
||||
border-right: 1px solid #2e2e2e;
|
||||
border-bottom: 1px solid #2e2e2e;
|
||||
box-shadow: inset 0 0 5px #383838, 0 1px 0 #585858, inset -1px 0 0 #4a4a4a, inset 1px 0 0 #4a4a4a;
|
||||
min-width: 40px;
|
||||
box-sizing: border-box;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
background: #555;
|
||||
color: white;
|
||||
.tab:first-child {
|
||||
box-shadow: inset 0 0 5px #383838, 0 1px 0 #585858, inset -1px 0 0 #4a4a4a;
|
||||
}
|
||||
|
||||
.tab:last-child {
|
||||
margin-right: 4px;
|
||||
.tab.active:first-child,
|
||||
.tab.active:first-child:hover {
|
||||
box-shadow: inset -1px 0 0 #595959;
|
||||
}
|
||||
|
||||
.tab.active,
|
||||
.tab.active:hover {
|
||||
color: #dae6e6;
|
||||
border-top: 1px solid #4a4a4a;
|
||||
box-shadow: inset -1px 0 0 #595959, inset 1px 0 0 #595959;
|
||||
border-bottom: 0 none;
|
||||
background-image: -webkit-linear-gradient(#555555, #424242);
|
||||
}
|
||||
|
||||
.tab.active:before,
|
||||
.tab.active:after {
|
||||
position: absolute;
|
||||
bottom: -1px;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
content: " ";
|
||||
z-index: 3;
|
||||
border: 1px solid #595959;
|
||||
}
|
||||
.tab.active:before {
|
||||
border-bottom-right-radius: 4px;
|
||||
border-width: 0 1px 1px 0;
|
||||
box-shadow: 2px 2px 0 #424242;
|
||||
left: -4px;
|
||||
}
|
||||
.tab.active:after {
|
||||
right: -4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-width: 0 0 1px 1px;
|
||||
box-shadow: -2px 2px 0 #424242;
|
||||
}
|
||||
.tab.active:first-child:before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tab:hover {
|
||||
color: #c8c8c5;
|
||||
background-image: -webkit-linear-gradient(#474747, #444444);
|
||||
}
|
||||
|
||||
.tab .file-name {
|
||||
margin-right: 5px;
|
||||
font-size: 11px !important;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
text-shadow: 0 -1px 1px black;
|
||||
position: absolute;
|
||||
left: 9px;
|
||||
top:4px;
|
||||
bottom:4px;
|
||||
right: 21px;
|
||||
}
|
||||
|
||||
.tab .close-icon {
|
||||
@@ -36,12 +89,17 @@
|
||||
font-size: 14px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
display: block;
|
||||
color: #777;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
top: -1px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.tab .close-icon:before {
|
||||
content: "\f050";
|
||||
content: "\f081";
|
||||
}
|
||||
|
||||
.tab .close-icon:hover {
|
||||
|
||||
@@ -26,18 +26,18 @@ describe "TreeView", ->
|
||||
|
||||
describe ".initialize(project)", ->
|
||||
it "renders the root of the project and its contents alphabetically with subdirectories first in a collapsed state", ->
|
||||
expect(treeView.root.find('> .header .disclosure-arrow')).toHaveText('▾')
|
||||
expect(treeView.root.find('> .header .name')).toHaveText('tree-view/')
|
||||
expect(treeView.root.find('> .header .disclosure-arrow')).not.toHaveClass('expanded')
|
||||
expect(treeView.root.find('> .header .name')).toHaveText('tree-view')
|
||||
|
||||
rootEntries = treeView.root.find('.entries')
|
||||
subdir0 = rootEntries.find('> li:eq(0)')
|
||||
expect(subdir0.find('.disclosure-arrow')).toHaveText('▸')
|
||||
expect(subdir0.find('.name')).toHaveText('dir1/')
|
||||
expect(subdir0).not.toHaveClass('expanded')
|
||||
expect(subdir0.find('.name')).toHaveText('dir1')
|
||||
expect(subdir0.find('.entries')).not.toExist()
|
||||
|
||||
subdir2 = rootEntries.find('> li:eq(1)')
|
||||
expect(subdir2.find('.disclosure-arrow')).toHaveText('▸')
|
||||
expect(subdir2.find('.name')).toHaveText('dir2/')
|
||||
expect(subdir2).not.toHaveClass('expanded')
|
||||
expect(subdir2.find('.name')).toHaveText('dir2')
|
||||
expect(subdir2.find('.entries')).not.toExist()
|
||||
|
||||
expect(rootEntries.find('> .file:contains(tree-view.js)')).toExist()
|
||||
@@ -194,40 +194,27 @@ describe "TreeView", ->
|
||||
expect(treeView).not.toMatchSelector(':focus')
|
||||
expect(rootView.getActiveEditor().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", ->
|
||||
treeView.attach()
|
||||
treeView.focus()
|
||||
rootViewCloseHandler = jasmine.createSpy('rootViewCloseHandler')
|
||||
rootView.on 'core:close', rootViewCloseHandler
|
||||
spyOn(rootView, 'focus')
|
||||
|
||||
treeView.trigger('core:close')
|
||||
expect(rootView.focus).toHaveBeenCalled()
|
||||
expect(rootViewCloseHandler).not.toHaveBeenCalled()
|
||||
expect(treeView.hasParent()).toBeFalsy()
|
||||
|
||||
describe "when a directory's disclosure arrow is clicked", ->
|
||||
it "expands / collapses the associated directory", ->
|
||||
subdir = treeView.root.find('.entries > li:contains(dir1/)').view()
|
||||
subdir = treeView.root.find('.entries > li:contains(dir1)').view()
|
||||
|
||||
expect(subdir.disclosureArrow).toHaveText('▸')
|
||||
expect(subdir).not.toHaveClass('expanded')
|
||||
expect(subdir.find('.entries')).not.toExist()
|
||||
|
||||
subdir.disclosureArrow.click()
|
||||
|
||||
expect(subdir.disclosureArrow).toHaveText('▾')
|
||||
expect(subdir).toHaveClass('expanded')
|
||||
expect(subdir.find('.entries')).toExist()
|
||||
|
||||
subdir.disclosureArrow.click()
|
||||
expect(subdir.disclosureArrow).toHaveText('▸')
|
||||
expect(subdir).not.toHaveClass('expanded')
|
||||
expect(subdir.find('.entries')).not.toExist()
|
||||
|
||||
it "restores the expansion state of descendant directories", ->
|
||||
child = treeView.root.find('.entries > li:contains(dir1/)').view()
|
||||
child = treeView.root.find('.entries > li:contains(dir1)').view()
|
||||
child.disclosureArrow.click()
|
||||
|
||||
grandchild = child.find('.entries > li:contains(sub-dir1/)').view()
|
||||
grandchild = child.find('.entries > li:contains(sub-dir1)').view()
|
||||
grandchild.disclosureArrow.click()
|
||||
|
||||
treeView.root.disclosureArrow.click()
|
||||
@@ -235,16 +222,16 @@ describe "TreeView", ->
|
||||
treeView.root.disclosureArrow.click()
|
||||
|
||||
# previously expanded descendants remain expanded
|
||||
expect(treeView.root.find('> .entries > li:contains(dir1/) > .entries > li:contains(sub-dir1/) > .entries').length).toBe 1
|
||||
expect(treeView.root.find('> .entries > li:contains(dir1) > .entries > li:contains(sub-dir1) > .entries').length).toBe 1
|
||||
|
||||
# collapsed descendants remain collapsed
|
||||
expect(treeView.root.find('> .entries > li.contains(dir2/) > .entries')).not.toExist()
|
||||
expect(treeView.root.find('> .entries > li.contains(dir2) > .entries')).not.toExist()
|
||||
|
||||
it "when collapsing a directory, removes change subscriptions from the collapsed directory and its descendants", ->
|
||||
child = treeView.root.entries.find('li:contains(dir1/)').view()
|
||||
child = treeView.root.entries.find('li:contains(dir1)').view()
|
||||
child.disclosureArrow.click()
|
||||
|
||||
grandchild = child.entries.find('li:contains(sub-dir1/)').view()
|
||||
grandchild = child.entries.find('li:contains(sub-dir1)').view()
|
||||
grandchild.disclosureArrow.click()
|
||||
|
||||
expect(treeView.root.directory.subscriptionCount()).toBe 1
|
||||
@@ -359,7 +346,7 @@ describe "TreeView", ->
|
||||
|
||||
beforeEach ->
|
||||
nested = treeView.root.find('.directory:eq(2)').view()
|
||||
expect(nested.find('.header').text()).toContain 'nested/'
|
||||
expect(nested.find('.header').text()).toContain 'nested'
|
||||
nested.expand()
|
||||
nested2 = nested.entries.find('.entry:last').view()
|
||||
nested2.click()
|
||||
@@ -486,7 +473,7 @@ describe "TreeView", ->
|
||||
|
||||
entryCount = treeView.find(".entry").length
|
||||
_.times entryCount, -> treeView.moveDown()
|
||||
expect(treeView.scrollBottom()).toBe treeView.prop('scrollHeight')
|
||||
expect(treeView.scrollBottom() + 2).toBe treeView.prop('scrollHeight')
|
||||
|
||||
_.times entryCount, -> treeView.moveUp()
|
||||
expect(treeView.scrollTop()).toBe 0
|
||||
@@ -668,7 +655,7 @@ describe "TreeView", ->
|
||||
expect(rootView.getActiveEditor().getPath()).not.toBe newPath
|
||||
expect(treeView).toMatchSelector(':focus')
|
||||
expect(rootView.getActiveEditor().isFocused).toBeFalsy()
|
||||
expect(dirView.find('.directory.selected:contains(new/)').length).toBe(1)
|
||||
expect(dirView.find('.directory.selected:contains(new)').length).toBe(1)
|
||||
|
||||
it "selects the created directory", ->
|
||||
treeView.attachToDom()
|
||||
@@ -681,7 +668,7 @@ describe "TreeView", ->
|
||||
expect(rootView.getActiveEditor().getPath()).not.toBe newPath
|
||||
expect(treeView).toMatchSelector(':focus')
|
||||
expect(rootView.getActiveEditor().isFocused).toBeFalsy()
|
||||
expect(dirView.find('.directory.selected:contains(new2/)').length).toBe(1)
|
||||
expect(dirView.find('.directory.selected:contains(new2)').length).toBe(1)
|
||||
|
||||
describe "when a file or directory already exists at the given path", ->
|
||||
it "shows an error message and does not close the dialog", ->
|
||||
|
||||
@@ -9,8 +9,9 @@ class DirectoryView extends View
|
||||
@content: ({directory, isExpanded} = {}) ->
|
||||
@li class: 'directory entry', =>
|
||||
@div outlet: 'header', class: 'header', =>
|
||||
@span '▸', class: 'disclosure-arrow', outlet: 'disclosureArrow'
|
||||
@span class: 'disclosure-arrow', outlet: 'disclosureArrow'
|
||||
@span directory.getBaseName(), class: 'name', outlet: 'directoryName'
|
||||
@span "", class: 'highlight'
|
||||
|
||||
directory: null
|
||||
entries: null
|
||||
@@ -47,7 +48,6 @@ class DirectoryView extends View
|
||||
expand: ->
|
||||
return if @isExpanded
|
||||
@addClass('expanded')
|
||||
@disclosureArrow.text('▾')
|
||||
@buildEntries()
|
||||
@watchEntries()
|
||||
@deserializeEntryExpansionStates(@entryStates) if @entryStates?
|
||||
@@ -57,7 +57,6 @@ class DirectoryView extends View
|
||||
collapse: ->
|
||||
@entryStates = @serializeEntryExpansionStates()
|
||||
@removeClass('expanded')
|
||||
@disclosureArrow.text('▸')
|
||||
@unwatchEntries()
|
||||
@entries.remove()
|
||||
@entries = null
|
||||
|
||||
@@ -1,16 +1,31 @@
|
||||
{View, $$} = require 'space-pen'
|
||||
$ = require 'jquery'
|
||||
Git = require 'git'
|
||||
fs = require 'fs'
|
||||
|
||||
module.exports =
|
||||
class FileView extends View
|
||||
|
||||
@content: (file) ->
|
||||
@li file.getBaseName(), class: 'file entry'
|
||||
@li class: 'file entry', =>
|
||||
@span file.getBaseName(), class: 'name', outlet: 'fileName'
|
||||
@span "", class: 'highlight'
|
||||
|
||||
file: null
|
||||
|
||||
initialize: (@file) ->
|
||||
@addClass('ignored') if new Git(@getPath()).isPathIgnored(@getPath())
|
||||
path = @getPath()
|
||||
extension = fs.extension(path)
|
||||
if fs.isCompressedExtension(extension)
|
||||
@fileName.addClass('compressed-name')
|
||||
else if fs.isImageExtension(extension)
|
||||
@fileName.addClass('image-name')
|
||||
else if fs.isPdfExtension(extension)
|
||||
@fileName.addClass('pdf-name')
|
||||
else
|
||||
@fileName.addClass('text-name')
|
||||
|
||||
@addClass('ignored') if new Git(path).isPathIgnored(path)
|
||||
|
||||
getPath: ->
|
||||
@file.path
|
||||
|
||||
@@ -27,7 +27,7 @@ class TreeView extends ScrollView
|
||||
@instance.serialize()
|
||||
|
||||
@content: (rootView) ->
|
||||
@div class: 'tree-view tool-panel', tabindex: -1
|
||||
@ol class: 'tree-view tool-panel', tabindex: -1
|
||||
|
||||
@deserialize: (state, rootView) ->
|
||||
treeView = new TreeView(rootView)
|
||||
@@ -48,7 +48,7 @@ class TreeView extends ScrollView
|
||||
@on 'click', '.entry', (e) => @entryClicked(e)
|
||||
@command 'core:move-up', => @moveUp()
|
||||
@command 'core:move-down', => @moveDown()
|
||||
@command 'core:close', => @detach(); false
|
||||
@command 'core:close', => false
|
||||
@command 'tree-view:expand-directory', => @expandDirectory()
|
||||
@command 'tree-view:collapse-directory', => @collapseDirectory()
|
||||
@command 'tree-view:open-selected-entry', => @openSelectedEntry(true)
|
||||
|
||||
@@ -10,6 +10,7 @@ describe "WrapGuide", ->
|
||||
rootView.attachToDom()
|
||||
editor = rootView.getActiveEditor()
|
||||
wrapGuide = rootView.find('.wrap-guide').view()
|
||||
editor.width(editor.charWidth * wrapGuide.defaultColumn * 2)
|
||||
|
||||
afterEach ->
|
||||
rootView.deactivate()
|
||||
@@ -27,6 +28,7 @@ describe "WrapGuide", ->
|
||||
width = editor.charWidth * wrapGuide.defaultColumn
|
||||
expect(width).toBeGreaterThan(0)
|
||||
expect(wrapGuide.position().left).toBe(width)
|
||||
expect(wrapGuide).toBeVisible()
|
||||
|
||||
describe "when the font size changes", ->
|
||||
it "updates the wrap guide position", ->
|
||||
@@ -34,6 +36,7 @@ describe "WrapGuide", ->
|
||||
expect(initial).toBeGreaterThan(0)
|
||||
rootView.trigger('window:increase-font-size')
|
||||
expect(wrapGuide.position().left).toBeGreaterThan(initial)
|
||||
expect(wrapGuide).toBeVisible()
|
||||
|
||||
describe "overriding getGuideColumn", ->
|
||||
it "invokes the callback with the editor path", ->
|
||||
@@ -41,7 +44,7 @@ describe "WrapGuide", ->
|
||||
wrapGuide.getGuideColumn = (path) ->
|
||||
editorPath = path
|
||||
80
|
||||
wrapGuide.updateGuide(editor)
|
||||
wrapGuide.updateGuide()
|
||||
expect(editorPath).toBe(require.resolve('fixtures/sample.js'))
|
||||
|
||||
it "invokes the callback with a default value", ->
|
||||
@@ -51,7 +54,7 @@ describe "WrapGuide", ->
|
||||
column = defaultColumn
|
||||
defaultColumn
|
||||
|
||||
wrapGuide.updateGuide(editor)
|
||||
wrapGuide.updateGuide()
|
||||
expect(column).toBeGreaterThan(0)
|
||||
|
||||
# this is disabled because we no longer support passing config to an extension
|
||||
@@ -68,5 +71,11 @@ describe "WrapGuide", ->
|
||||
it "hides the guide when the column is less than 1", ->
|
||||
wrapGuide.getGuideColumn = (path) ->
|
||||
-1
|
||||
wrapGuide.updateGuide(editor)
|
||||
wrapGuide.updateGuide()
|
||||
expect(wrapGuide).toBeHidden()
|
||||
|
||||
describe "when no lines exceed the guide column and the editor width is smaller than the guide column position", ->
|
||||
it "hides the guide", ->
|
||||
editor.width(10)
|
||||
wrapGuide.updateGuide()
|
||||
expect(wrapGuide).toBeHidden()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{View} = require 'space-pen'
|
||||
$ = require 'jquery'
|
||||
|
||||
module.exports =
|
||||
class WrapGuide extends View
|
||||
@@ -28,13 +29,18 @@ class WrapGuide extends View
|
||||
else
|
||||
@getGuideColumn = (path, defaultColumn) -> defaultColumn
|
||||
|
||||
@observeConfig 'editor.fontSize', => @updateGuide(@editor)
|
||||
@subscribe @editor, 'editor-path-change', => @updateGuide(@editor)
|
||||
@subscribe @editor, 'before-remove', => @rootView.off('.wrap-guide')
|
||||
@observeConfig 'editor.fontSize', => @updateGuide()
|
||||
@subscribe @editor, 'editor-path-change', => @updateGuide()
|
||||
@subscribe @editor, 'editor:min-width-changed', => @updateGuide()
|
||||
@subscribe $(window), 'resize', => @updateGuide()
|
||||
|
||||
updateGuide: (editor) ->
|
||||
column = @getGuideColumn(editor.getPath(), @defaultColumn)
|
||||
updateGuide: ->
|
||||
column = @getGuideColumn(@editor.getPath(), @defaultColumn)
|
||||
if column > 0
|
||||
@css('left', "#{editor.charWidth * column}px").show()
|
||||
columnWidth = @editor.charWidth * column
|
||||
if columnWidth < @editor.layerMinWidth or columnWidth < @editor.width()
|
||||
@css('left', "#{columnWidth}px").show()
|
||||
else
|
||||
@hide()
|
||||
else
|
||||
@hide()
|
||||
|
||||
@@ -123,3 +123,24 @@ module.exports =
|
||||
|
||||
md5ForPath: (path) ->
|
||||
$native.md5ForPath(path)
|
||||
|
||||
isCompressedExtension: (ext) ->
|
||||
_.contains([
|
||||
'.gz'
|
||||
'.jar'
|
||||
'.tar'
|
||||
'.zip'
|
||||
], ext)
|
||||
|
||||
isImageExtension: (ext) ->
|
||||
_.contains([
|
||||
'.gif'
|
||||
'.jpeg'
|
||||
'.jpg'
|
||||
'.png'
|
||||
], ext)
|
||||
|
||||
isPdfExtension: (ext) ->
|
||||
_.contains([
|
||||
'.pdf'
|
||||
], ext)
|
||||
|
||||
Reference in New Issue
Block a user