mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Merge branch 'dev' into css-theme-refactor
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
-webkit-box-shadow: 0 0 5px 5px #222;
|
||||
padding: 5px;
|
||||
z-index: 99;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.select-list .editor {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
background: #333333;
|
||||
border-bottom: 4px solid #424242;
|
||||
font: caption;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.tab {
|
||||
|
||||
@@ -8,11 +8,20 @@
|
||||
border-right: 2px solid #191919;
|
||||
min-width: 100px;
|
||||
z-index: 2;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
.tree-view .tree-view-resizer {
|
||||
float: right;
|
||||
height: 100%;
|
||||
width: 10px;
|
||||
background: transparent;
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
.tree-view .entry {
|
||||
text-shadow: 0 -1px 0 #000;
|
||||
text-wrap: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tree-view .entries {
|
||||
|
||||
@@ -1973,6 +1973,17 @@ describe "EditSession", ->
|
||||
editSession.indent()
|
||||
expect(editSession.lineForBufferRow(2)).toBe " "
|
||||
|
||||
it "auto-indents selection when autoIndent is called", ->
|
||||
editSession.setCursorBufferPosition([2, 0])
|
||||
editSession.insertText(" 0\n 2\n4\n")
|
||||
|
||||
editSession.setSelectedBufferRange([[2, 0], [4, 0]])
|
||||
editSession.autoIndentSelectedRows()
|
||||
|
||||
expect(editSession.lineForBufferRow(2)).toBe " 0"
|
||||
expect(editSession.lineForBufferRow(3)).toBe " 2"
|
||||
expect(editSession.lineForBufferRow(4)).toBe "4"
|
||||
|
||||
describe "editor.autoIndentOnPaste", ->
|
||||
it "does not auto-indent pasted text by default", ->
|
||||
editSession.setCursorBufferPosition([2, 0])
|
||||
|
||||
1
spec/fixtures/packages/package-with-snippets/snippets/.hidden-file
vendored
Normal file
1
spec/fixtures/packages/package-with-snippets/snippets/.hidden-file
vendored
Normal file
@@ -0,0 +1 @@
|
||||
This is a hidden file. Don't even try to load it as a snippet
|
||||
1
spec/fixtures/packages/package-with-snippets/snippets/junk-file
vendored
Normal file
1
spec/fixtures/packages/package-with-snippets/snippets/junk-file
vendored
Normal file
@@ -0,0 +1 @@
|
||||
This file isn't CSON, but shouldn't be a big deal
|
||||
@@ -35,10 +35,7 @@ class AtomPackage extends Package
|
||||
keymaps.map (relativePath) =>
|
||||
fs.resolve(@keymapsDirPath, relativePath, ['cson', 'json', ''])
|
||||
else
|
||||
if fs.exists(@keymapsDirPath)
|
||||
fs.list(@keymapsDirPath)
|
||||
else
|
||||
[]
|
||||
fs.list(@keymapsDirPath)
|
||||
|
||||
loadStylesheets: ->
|
||||
for stylesheetPath in @getStylesheetPaths()
|
||||
@@ -46,7 +43,4 @@ class AtomPackage extends Package
|
||||
|
||||
getStylesheetPaths: ->
|
||||
stylesheetDirPath = fs.join(@path, 'stylesheets')
|
||||
if fs.exists stylesheetDirPath
|
||||
fs.list stylesheetDirPath
|
||||
else
|
||||
[]
|
||||
fs.list(stylesheetDirPath)
|
||||
|
||||
@@ -208,6 +208,9 @@ class EditSession
|
||||
toggleLineCommentsInSelection: ->
|
||||
@mutateSelectedText (selection) -> selection.toggleLineComments()
|
||||
|
||||
autoIndentSelectedRows: ->
|
||||
@mutateSelectedText (selection) -> selection.autoIndentSelectedRows()
|
||||
|
||||
cutToEndOfLine: ->
|
||||
maintainPasteboard = false
|
||||
@mutateSelectedText (selection) ->
|
||||
|
||||
@@ -117,6 +117,7 @@ class Editor extends View
|
||||
'editor:select-word': @selectWord
|
||||
'editor:newline': @insertNewline
|
||||
'editor:indent': @indent
|
||||
'editor:auto-indent': @autoIndent
|
||||
'editor:indent-selected-rows': @indentSelectedRows
|
||||
'editor:outdent-selected-rows': @outdentSelectedRows
|
||||
'editor:backspace-to-beginning-of-word': @backspaceToBeginningOfWord
|
||||
@@ -151,6 +152,7 @@ class Editor extends View
|
||||
'core:select-to-bottom': @selectToBottom
|
||||
'core:close': @destroyActiveEditSession
|
||||
'editor:save': @save
|
||||
'editor:save-as': @saveAs
|
||||
'editor:newline-below': @insertNewlineBelow
|
||||
'editor:toggle-soft-tabs': @toggleSoftTabs
|
||||
'editor:toggle-soft-wrap': @toggleSoftWrap
|
||||
@@ -247,6 +249,7 @@ class Editor extends View
|
||||
insertNewline: -> @activeEditSession.insertNewline()
|
||||
insertNewlineBelow: -> @activeEditSession.insertNewlineBelow()
|
||||
indent: (options) -> @activeEditSession.indent(options)
|
||||
autoIndent: (options) -> @activeEditSession.autoIndentSelectedRows(options)
|
||||
indentSelectedRows: -> @activeEditSession.indentSelectedRows()
|
||||
outdentSelectedRows: -> @activeEditSession.outdentSelectedRows()
|
||||
cutSelection: -> @activeEditSession.cutSelectedText()
|
||||
@@ -653,6 +656,9 @@ class Editor extends View
|
||||
session.save()
|
||||
onSuccess?()
|
||||
else
|
||||
@saveAs(session, onSuccess)
|
||||
|
||||
saveAs: (session=@activeEditSession, onSuccess) ->
|
||||
atom.showSaveDialog (path) =>
|
||||
if path
|
||||
session.saveAs(path)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
'pageup': 'core:page-up'
|
||||
'pagedown': 'core:page-down'
|
||||
|
||||
'meta-S': 'window:save-all'
|
||||
'meta-alt-s': 'window:save-all'
|
||||
'meta-W': 'window:close'
|
||||
'meta-+': 'window:increase-font-size'
|
||||
'meta--': 'window:decrease-font-size'
|
||||
@@ -33,4 +33,4 @@
|
||||
'.tool-panel':
|
||||
'meta-escape': 'tool-panel:unfocus'
|
||||
'escape': 'core:close'
|
||||
'meta-w': 'noop'
|
||||
'meta-w': 'noop'
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
'.editor':
|
||||
'meta-s': 'editor:save'
|
||||
'meta-S': 'editor:save-as'
|
||||
'enter': 'editor:newline'
|
||||
'meta-enter': 'editor:newline-below'
|
||||
'tab': 'editor:indent'
|
||||
'meta-=': 'editor:auto-indent'
|
||||
'meta-d': 'editor:delete-line'
|
||||
'ctrl-[': 'editor:fold-current-row'
|
||||
'ctrl-]': 'editor:unfold-current-row'
|
||||
|
||||
@@ -307,6 +307,10 @@ class Selection
|
||||
if matchLength = buffer.lineForRow(row).match(leadingTabRegex)?[0].length
|
||||
buffer.delete [[row, 0], [row, matchLength]]
|
||||
|
||||
autoIndentSelectedRows: ->
|
||||
[start, end] = @getBufferRowRange()
|
||||
@editSession.autoIndentBufferRows(start, end)
|
||||
|
||||
toggleLineComments: ->
|
||||
@modifySelection =>
|
||||
@editSession.toggleLineCommentsForBufferRows(@getBufferRowRange()...)
|
||||
|
||||
@@ -99,9 +99,10 @@ windowAdditions =
|
||||
|
||||
measure: (description, fn) ->
|
||||
start = new Date().getTime()
|
||||
fn()
|
||||
value = fn()
|
||||
result = new Date().getTime() - start
|
||||
console.log description, result
|
||||
value
|
||||
|
||||
window[key] = value for key, value of windowAdditions
|
||||
window.startup()
|
||||
|
||||
@@ -207,12 +207,17 @@ describe "Snippets extension", ->
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[1, 6], [1, 36]]
|
||||
|
||||
describe "snippet loading", ->
|
||||
it "loads snippets from all atom packages with a snippets directory", ->
|
||||
it "loads non-hidden snippet files from all atom packages with snippets directories, logging a warning if a file can't be parsed", ->
|
||||
spyOn(console, 'warn')
|
||||
jasmine.unspy(AtomPackage.prototype, 'loadSnippets')
|
||||
snippets.loadAll()
|
||||
|
||||
expect(syntax.getProperty(['.test'], 'snippets.test')?.constructor).toBe Snippet
|
||||
|
||||
# warn about junk-file, but don't even try to parse a hidden file
|
||||
expect(console.warn).toHaveBeenCalled()
|
||||
expect(console.warn.calls.length).toBe 1
|
||||
|
||||
it "loads snippets from all TextMate packages with snippets", ->
|
||||
jasmine.unspy(TextMatePackage.prototype, 'loadSnippets')
|
||||
snippets.loadAll()
|
||||
|
||||
@@ -4,9 +4,7 @@ fs = require 'fs'
|
||||
|
||||
AtomPackage.prototype.loadSnippets = ->
|
||||
snippetsDirPath = fs.join(@path, 'snippets')
|
||||
if fs.exists(snippetsDirPath)
|
||||
for snippetsPath in fs.list(snippetsDirPath)
|
||||
snippets.load(snippetsPath)
|
||||
snippets.loadDirectory(snippetsDirPath) if fs.exists(snippetsDirPath)
|
||||
|
||||
TextMatePackage.prototype.loadSnippets = ->
|
||||
snippetsDirPath = fs.join(@path, 'Snippets')
|
||||
|
||||
@@ -19,11 +19,18 @@ module.exports =
|
||||
for pack in atom.getPackages()
|
||||
pack.loadSnippets()
|
||||
|
||||
for snippetsPath in fs.list(@userSnippetsDir)
|
||||
@load(snippetsPath)
|
||||
@loadDirectory(@userSnippetsDir) if fs.exists(@userSnippetsDir)
|
||||
|
||||
loadDirectory: (snippetsDirPath) ->
|
||||
for snippetsPath in fs.list(snippetsDirPath) when fs.base(snippetsPath).indexOf('.') isnt 0
|
||||
snippets.load(snippetsPath)
|
||||
|
||||
load: (snippetsPath) ->
|
||||
@add(fs.readObject(snippetsPath))
|
||||
try
|
||||
snippets = fs.readObject(snippetsPath)
|
||||
catch e
|
||||
console.warn "Error reading snippets file '#{snippetsPath}'"
|
||||
@add(snippets)
|
||||
|
||||
add: (snippetsBySelector) ->
|
||||
for selector, snippetsByName of snippetsBySelector
|
||||
|
||||
@@ -27,7 +27,8 @@ class TreeView extends ScrollView
|
||||
@instance.serialize()
|
||||
|
||||
@content: (rootView) ->
|
||||
@ol class: 'tree-view tool-panel', tabindex: -1
|
||||
@ol class: 'tree-view tool-panel', tabindex: -1, =>
|
||||
@div class: 'tree-view-resizer', outlet: 'resizer'
|
||||
|
||||
@deserialize: (state, rootView) ->
|
||||
treeView = new TreeView(rootView)
|
||||
@@ -35,6 +36,7 @@ class TreeView extends ScrollView
|
||||
treeView.selectEntryForPath(state.selectedPath)
|
||||
treeView.focusAfterAttach = state.hasFocus
|
||||
treeView.scrollTopAfterAttach = state.scrollTop
|
||||
treeView.width(state.width)
|
||||
treeView.attach() if state.attached
|
||||
treeView
|
||||
|
||||
@@ -46,6 +48,7 @@ class TreeView extends ScrollView
|
||||
initialize: (@rootView) ->
|
||||
super
|
||||
@on 'click', '.entry', (e) => @entryClicked(e)
|
||||
@on 'mousedown', '.tree-view-resizer', (e) => @resizeStarted(e)
|
||||
@command 'core:move-up', => @moveUp()
|
||||
@command 'core:move-down', => @moveDown()
|
||||
@command 'core:close', => @detach(); false
|
||||
@@ -79,6 +82,7 @@ class TreeView extends ScrollView
|
||||
hasFocus: @hasFocus()
|
||||
attached: @hasParent()
|
||||
scrollTop: @scrollTop()
|
||||
width: @width()
|
||||
|
||||
deactivate: ->
|
||||
@root?.unwatchEntries()
|
||||
@@ -119,6 +123,20 @@ class TreeView extends ScrollView
|
||||
|
||||
false
|
||||
|
||||
resizeStarted: (e) =>
|
||||
$(document.body).on('mousemove', @resizeTreeView)
|
||||
$(document.body).on('mouseup', @resizeStopped)
|
||||
@css(overflow: 'hidden')
|
||||
|
||||
resizeStopped: (e) =>
|
||||
$(document.body).off('mousemove', @resizeTreeView)
|
||||
$(document.body).off('mouseup', @resizeStopped)
|
||||
@css(overflow: 'auto')
|
||||
|
||||
resizeTreeView: (e) =>
|
||||
@css(width: e.pageX)
|
||||
@resizer.css(left: e.pageX)
|
||||
|
||||
updateRoot: ->
|
||||
@root?.remove()
|
||||
if rootDirectory = @rootView.project.getRootDirectory()
|
||||
|
||||
@@ -28,7 +28,7 @@ require = (path, cb) ->
|
||||
parts = file.split '.'
|
||||
ext = parts[parts.length-1]
|
||||
|
||||
if __modules[file]?
|
||||
if __moduleExists file
|
||||
if not __modules.loaded[file.toLowerCase()]?
|
||||
console.warn "Circular require: #{__filename} required #{file}"
|
||||
return __modules[file]
|
||||
@@ -73,16 +73,26 @@ resolve = (name, {verifyExistence}={}) ->
|
||||
file = file.replace '../', "#{prefix}/"
|
||||
|
||||
if file[0] isnt '/'
|
||||
paths.some (path) ->
|
||||
fileExists = /\.(.+)$/.test(file) and __exists "#{path}/#{file}"
|
||||
jsFileExists = not /\.(.+)$/.test(file) and __exists "#{path}/#{file}.js"
|
||||
|
||||
if jsFileExists
|
||||
file = "#{path}/#{file}.js"
|
||||
else if fileExists
|
||||
moduleAlreadyLoaded = paths.some (path) ->
|
||||
if __moduleExists "#{path}/#{file}"
|
||||
file = "#{path}/#{file}"
|
||||
else if expanded = __expand "#{path}/#{file}"
|
||||
else if __moduleExists "#{path}/#{file}.js"
|
||||
file = "#{path}/#{file}.js"
|
||||
else if expanded = __moduleExpand "#{path}/#{file}"
|
||||
file = expanded
|
||||
|
||||
if not moduleAlreadyLoaded
|
||||
hasExtension = /\.(.+)$/.test(file)
|
||||
paths.some (path) ->
|
||||
fileExists = hasExtension and __exists "#{path}/#{file}"
|
||||
jsFileExists = not hasExtension and __exists "#{path}/#{file}.js"
|
||||
|
||||
if jsFileExists
|
||||
file = "#{path}/#{file}.js"
|
||||
else if fileExists
|
||||
file = "#{path}/#{file}"
|
||||
else if expanded = __expand "#{path}/#{file}"
|
||||
file = expanded
|
||||
else
|
||||
file = __expand(file) or file
|
||||
|
||||
@@ -92,16 +102,27 @@ resolve = (name, {verifyExistence}={}) ->
|
||||
console.warn("Failed to resolve '#{name}'") if verifyExistence
|
||||
null
|
||||
|
||||
__moduleExists = (path) ->
|
||||
__modules[path]?
|
||||
|
||||
__moduleExpand = (path) ->
|
||||
return path if __moduleExists path
|
||||
for ext, handler of exts
|
||||
return "#{path}.#{ext}" if __moduleExists "#{path}.#{ext}"
|
||||
return "#{path}/index.#{ext}" if __moduleExists "#{path}/index.#{ext}"
|
||||
null
|
||||
|
||||
__expand = (path) ->
|
||||
modulePath = __moduleExpand path
|
||||
return modulePath if modulePath
|
||||
|
||||
return path if __isFile path
|
||||
for ext, handler of exts
|
||||
if __exists "#{path}.#{ext}"
|
||||
return "#{path}.#{ext}"
|
||||
else if __exists "#{path}/index.#{ext}"
|
||||
return "#{path}/index.#{ext}"
|
||||
return "#{path}.#{ext}" if __exists "#{path}.#{ext}"
|
||||
return "#{path}/index.#{ext}" if __exists "#{path}/index.#{ext}"
|
||||
|
||||
return path if __exists path
|
||||
return null
|
||||
null
|
||||
|
||||
__exists = (path) ->
|
||||
$native.exists path
|
||||
|
||||
Reference in New Issue
Block a user