mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Merge remote-tracking branch 'origin/master' into mb-deprecate-load-time-package-code
Conflicts: package.json
This commit is contained in:
@@ -66,13 +66,42 @@ class ApplicationDelegate
|
||||
ipc.send("call-window-method", "setFullScreen", fullScreen)
|
||||
|
||||
openWindowDevTools: ->
|
||||
remote.getCurrentWindow().openDevTools()
|
||||
new Promise (resolve) ->
|
||||
# Defer DevTools interaction to the next tick, because using them during
|
||||
# event handling causes some wrong input events to be triggered on
|
||||
# `TextEditorComponent` (Ref.: https://github.com/atom/atom/issues/9697).
|
||||
process.nextTick ->
|
||||
if remote.getCurrentWindow().isDevToolsOpened()
|
||||
resolve()
|
||||
else
|
||||
remote.getCurrentWindow().once("devtools-opened", -> resolve())
|
||||
ipc.send("call-window-method", "openDevTools")
|
||||
|
||||
closeWindowDevTools: ->
|
||||
new Promise (resolve) ->
|
||||
# Defer DevTools interaction to the next tick, because using them during
|
||||
# event handling causes some wrong input events to be triggered on
|
||||
# `TextEditorComponent` (Ref.: https://github.com/atom/atom/issues/9697).
|
||||
process.nextTick ->
|
||||
unless remote.getCurrentWindow().isDevToolsOpened()
|
||||
resolve()
|
||||
else
|
||||
remote.getCurrentWindow().once("devtools-closed", -> resolve())
|
||||
ipc.send("call-window-method", "closeDevTools")
|
||||
|
||||
toggleWindowDevTools: ->
|
||||
remote.getCurrentWindow().toggleDevTools()
|
||||
new Promise (resolve) =>
|
||||
# Defer DevTools interaction to the next tick, because using them during
|
||||
# event handling causes some wrong input events to be triggered on
|
||||
# `TextEditorComponent` (Ref.: https://github.com/atom/atom/issues/9697).
|
||||
process.nextTick =>
|
||||
if remote.getCurrentWindow().isDevToolsOpened()
|
||||
@closeWindowDevTools().then(resolve)
|
||||
else
|
||||
@openWindowDevTools().then(resolve)
|
||||
|
||||
executeJavaScriptInWindowDevTools: (code) ->
|
||||
remote.getCurrentWindow().executeJavaScriptInDevTools(code)
|
||||
ipc.send("call-window-method", "executeJavaScriptInDevTools", code)
|
||||
|
||||
setWindowDocumentEdited: (edited) ->
|
||||
ipc.send("call-window-method", "setDocumentEdited", edited)
|
||||
|
||||
@@ -670,8 +670,7 @@ class AtomEnvironment extends Model
|
||||
@emitter.emit 'will-throw-error', eventObject
|
||||
|
||||
if openDevTools
|
||||
@openDevTools()
|
||||
@executeJavaScriptInDevTools('DevToolsAPI.showConsole()')
|
||||
@openDevTools().then => @executeJavaScriptInDevTools('DevToolsAPI.showConsole()')
|
||||
|
||||
@emitter.emit 'did-throw-error', {message, url, line, column, originalError}
|
||||
|
||||
@@ -721,10 +720,15 @@ class AtomEnvironment extends Model
|
||||
###
|
||||
|
||||
# Extended: Open the dev tools for the current window.
|
||||
#
|
||||
# Returns a {Promise} that resolves when the DevTools have been opened.
|
||||
openDevTools: ->
|
||||
@applicationDelegate.openWindowDevTools()
|
||||
|
||||
# Extended: Toggle the visibility of the dev tools for the current window.
|
||||
#
|
||||
# Returns a {Promise} that resolves when the DevTools have been opened or
|
||||
# closed.
|
||||
toggleDevTools: ->
|
||||
@applicationDelegate.toggleWindowDevTools()
|
||||
|
||||
|
||||
@@ -373,6 +373,8 @@ class AtomApplication
|
||||
# :windowDimensions - Object with height and width keys.
|
||||
# :window - {AtomWindow} to open file paths in.
|
||||
openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window}={}) ->
|
||||
devMode = Boolean(devMode)
|
||||
safeMode = Boolean(safeMode)
|
||||
locationsToOpen = (@locationForPathToOpen(pathToOpen, executedFrom) for pathToOpen in pathsToOpen)
|
||||
pathsToOpen = (locationToOpen.pathToOpen for locationToOpen in locationsToOpen)
|
||||
|
||||
|
||||
@@ -158,25 +158,33 @@ require('source-map-support').install({
|
||||
}
|
||||
})
|
||||
|
||||
var sourceMapPrepareStackTrace = Error.prepareStackTrace
|
||||
var prepareStackTrace = sourceMapPrepareStackTrace
|
||||
var prepareStackTraceWithSourceMapping = Error.prepareStackTrace
|
||||
|
||||
// Prevent coffee-script from reassigning Error.prepareStackTrace
|
||||
Object.defineProperty(Error, 'prepareStackTrace', {
|
||||
get: function () { return prepareStackTrace },
|
||||
set: function (newValue) {}
|
||||
})
|
||||
let prepareStackTrace = prepareStackTraceWithSourceMapping
|
||||
|
||||
// Enable Grim to access the raw stack without reassigning Error.prepareStackTrace
|
||||
Error.prototype.getRawStack = function () { // eslint-disable-line no-extend-native
|
||||
prepareStackTrace = getRawStack
|
||||
var result = this.stack
|
||||
prepareStackTrace = sourceMapPrepareStackTrace
|
||||
return result
|
||||
function prepareStackTraceWithRawStackAssignment (error, frames) {
|
||||
error.rawStack = frames
|
||||
return prepareStackTrace(error, frames)
|
||||
}
|
||||
|
||||
function getRawStack (_, stack) {
|
||||
return stack
|
||||
Object.defineProperty(Error, 'prepareStackTrace', {
|
||||
get: function () {
|
||||
return prepareStackTraceWithRawStackAssignment
|
||||
},
|
||||
|
||||
set: function (newValue) {
|
||||
prepareStackTrace = newValue
|
||||
process.nextTick(function () {
|
||||
prepareStackTrace = prepareStackTraceWithSourceMapping
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
Error.prototype.getRawStack = function () { // eslint-disable-line no-extend-native
|
||||
// Access this.stack to ensure prepareStackTrace has been run on this error
|
||||
// because it assigns this.rawStack as a side-effect
|
||||
this.stack
|
||||
return this.rawStack
|
||||
}
|
||||
|
||||
Object.keys(COMPILERS).forEach(function (extension) {
|
||||
|
||||
@@ -21,7 +21,6 @@ module.exports =
|
||||
followSymlinks:
|
||||
type: 'boolean'
|
||||
default: true
|
||||
title: 'Follow symlinks'
|
||||
description: 'Follow symbolic links when searching files and when opening files with the fuzzy finder.'
|
||||
disabledPackages:
|
||||
type: 'array'
|
||||
@@ -54,7 +53,12 @@ module.exports =
|
||||
destroyEmptyPanes:
|
||||
type: 'boolean'
|
||||
default: true
|
||||
description: 'When the last item of a pane is removed, remove that pane as well.'
|
||||
title: 'Remove Empty Panes'
|
||||
description: 'When the last tab of a pane is closed, remove that pane as well.'
|
||||
closeEmptyWindows:
|
||||
type: 'boolean'
|
||||
default: true
|
||||
description: 'When a window with no open tabs or panes is given the \'Close Tab\' command, close that window.'
|
||||
fileEncoding:
|
||||
description: 'Default character set encoding to use when reading and writing files.'
|
||||
type: 'string'
|
||||
|
||||
@@ -699,7 +699,7 @@ class Config
|
||||
@endTransaction()
|
||||
fn(args...)
|
||||
result = callback()
|
||||
new Promise (resolve, reject) =>
|
||||
new Promise (resolve, reject) ->
|
||||
result.then(endTransaction(resolve)).catch(endTransaction(reject))
|
||||
catch error
|
||||
@endTransaction()
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
Task = require './task'
|
||||
|
||||
# Public: Searches local files for lines matching a specified regex.
|
||||
#
|
||||
# Implements thenable so it can be used with `Promise.all()`.
|
||||
# Searches local files for lines matching a specified regex. Implements `.then()`
|
||||
# so that it can be used with `Promise.all()`.
|
||||
class DirectorySearch
|
||||
constructor: (rootPaths, regex, options) ->
|
||||
scanHandlerOptions =
|
||||
@@ -22,31 +21,25 @@ class DirectorySearch
|
||||
@task.terminate()
|
||||
resolve()
|
||||
|
||||
# Public: Implementation of `then()` to satisfy the *thenable* contract.
|
||||
# This makes it possible to use a `DirectorySearch` with `Promise.all()`.
|
||||
#
|
||||
# Returns `Promise`.
|
||||
then: (args...) ->
|
||||
@promise.then.apply(@promise, args)
|
||||
|
||||
# Public: Cancels the search.
|
||||
cancel: ->
|
||||
# This will cause @promise to reject.
|
||||
@task.cancel()
|
||||
null
|
||||
|
||||
|
||||
# Default provider for the `atom.directory-searcher` service.
|
||||
module.exports =
|
||||
class DefaultDirectorySearcher
|
||||
# Public: Determines whether this object supports search for a `Directory`.
|
||||
# Determines whether this object supports search for a `Directory`.
|
||||
#
|
||||
# * `directory` {Directory} whose search needs might be supported by this object.
|
||||
#
|
||||
# Returns a `boolean` indicating whether this object can search this `Directory`.
|
||||
canSearchDirectory: (directory) -> true
|
||||
|
||||
# Public: Performs a text search for files in the specified `Directory`, subject to the
|
||||
# Performs a text search for files in the specified `Directory`, subject to the
|
||||
# specified parameters.
|
||||
#
|
||||
# Results are streamed back to the caller by invoking methods on the specified `options`,
|
||||
|
||||
@@ -55,7 +55,7 @@ module.exports = ({commandRegistry, commandInstaller, config}) ->
|
||||
'window:log-deprecation-warnings': -> Grim.logDeprecations()
|
||||
'window:toggle-auto-indent': -> config.set("editor.autoIndent", not config.get("editor.autoIndent"))
|
||||
'pane:reopen-closed-item': -> @getModel().reopenItem()
|
||||
'core:close': -> @getModel().destroyActivePaneItemOrEmptyPane()
|
||||
'core:close': -> @getModel().closeActivePaneItemOrEmptyPaneOrWindow()
|
||||
'core:save': -> @getModel().saveActivePaneItem()
|
||||
'core:save-as': -> @getModel().saveActivePaneItemAs()
|
||||
|
||||
|
||||
@@ -377,7 +377,8 @@ class TextEditorPresenter
|
||||
endRow = @constrainRow(@getEndTileRow() + @tileSize)
|
||||
|
||||
screenRows = [startRow...endRow]
|
||||
if longestScreenRow = @model.getLongestScreenRow()
|
||||
longestScreenRow = @model.getLongestScreenRow()
|
||||
if longestScreenRow?
|
||||
screenRows.push(longestScreenRow)
|
||||
if @screenRowsToMeasure?
|
||||
screenRows.push(@screenRowsToMeasure...)
|
||||
@@ -1244,14 +1245,7 @@ class TextEditorPresenter
|
||||
updateHighlightState: (decorationId, properties, screenRange) ->
|
||||
return unless @startRow? and @endRow? and @lineHeight? and @hasPixelPositionRequirements()
|
||||
|
||||
return if screenRange.isEmpty()
|
||||
|
||||
if screenRange.start.row < @startRow
|
||||
screenRange.start.row = @startRow
|
||||
screenRange.start.column = 0
|
||||
if screenRange.end.row >= @endRow
|
||||
screenRange.end.row = @endRow
|
||||
screenRange.end.column = 0
|
||||
@constrainRangeToVisibleRowRange(screenRange)
|
||||
|
||||
return if screenRange.isEmpty()
|
||||
|
||||
@@ -1281,6 +1275,23 @@ class TextEditorPresenter
|
||||
|
||||
true
|
||||
|
||||
constrainRangeToVisibleRowRange: (screenRange) ->
|
||||
if screenRange.start.row < @startRow
|
||||
screenRange.start.row = @startRow
|
||||
screenRange.start.column = 0
|
||||
|
||||
if screenRange.end.row < @startRow
|
||||
screenRange.end.row = @startRow
|
||||
screenRange.end.column = 0
|
||||
|
||||
if screenRange.start.row >= @endRow
|
||||
screenRange.start.row = @endRow
|
||||
screenRange.start.column = 0
|
||||
|
||||
if screenRange.end.row >= @endRow
|
||||
screenRange.end.row = @endRow
|
||||
screenRange.end.column = 0
|
||||
|
||||
repositionRegionWithinTile: (region, tileStartRow) ->
|
||||
region.top += @scrollTop - tileStartRow * @lineHeight
|
||||
region.left += @scrollLeft
|
||||
|
||||
@@ -581,10 +581,7 @@ class TextEditor extends Model
|
||||
#
|
||||
# Returns a {String}.
|
||||
getTitle: ->
|
||||
if sessionPath = @getPath()
|
||||
path.basename(sessionPath)
|
||||
else
|
||||
'untitled'
|
||||
@getFileName() ? 'untitled'
|
||||
|
||||
# Essential: Get unique title for display in other parts of the UI, such as
|
||||
# the window title.
|
||||
@@ -593,41 +590,52 @@ class TextEditor extends Model
|
||||
# If the editor's buffer is saved, its unique title is formatted as one
|
||||
# of the following,
|
||||
# * "<filename>" when it is the only editing buffer with this file name.
|
||||
# * "<unique-dir-prefix>/.../<filename>", where the "..." may be omitted
|
||||
# if the the direct parent directory is already different.
|
||||
# * "<filename> — <unique-dir-prefix>" when other buffers have this file name.
|
||||
#
|
||||
# Returns a {String}
|
||||
getLongTitle: ->
|
||||
if sessionPath = @getPath()
|
||||
title = @getTitle()
|
||||
if @getPath()
|
||||
fileName = @getFileName()
|
||||
|
||||
# find text editors with identical file name.
|
||||
paths = []
|
||||
allPathSegments = []
|
||||
for textEditor in atom.workspace.getTextEditors() when textEditor isnt this
|
||||
if textEditor.getTitle() is title
|
||||
paths.push(textEditor.getPath())
|
||||
if paths.length is 0
|
||||
return title
|
||||
fileName = path.basename(sessionPath)
|
||||
if textEditor.getFileName() is fileName
|
||||
allPathSegments.push(textEditor.getDirectoryPath().split(path.sep))
|
||||
|
||||
# find the first directory in all these paths that is unique
|
||||
nLevel = 0
|
||||
while (_.some(paths, (apath) -> path.basename(apath) is path.basename(sessionPath)))
|
||||
sessionPath = path.dirname(sessionPath)
|
||||
paths = _.map(paths, (apath) -> path.dirname(apath))
|
||||
nLevel += 1
|
||||
if allPathSegments.length is 0
|
||||
return fileName
|
||||
|
||||
directory = path.basename sessionPath
|
||||
if nLevel > 1
|
||||
path.join(directory, "...", fileName)
|
||||
else
|
||||
path.join(directory, fileName)
|
||||
ourPathSegments = @getDirectoryPath().split(path.sep)
|
||||
allPathSegments.push ourPathSegments
|
||||
|
||||
loop
|
||||
firstSegment = ourPathSegments[0]
|
||||
|
||||
commonBase = _.all(allPathSegments, (pathSegments) -> pathSegments.length > 1 and pathSegments[0] is firstSegment)
|
||||
if commonBase
|
||||
pathSegments.shift() for pathSegments in allPathSegments
|
||||
else
|
||||
break
|
||||
|
||||
"#{fileName} \u2014 #{path.join(pathSegments...)}"
|
||||
else
|
||||
'untitled'
|
||||
|
||||
# Essential: Returns the {String} path of this editor's text buffer.
|
||||
getPath: -> @buffer.getPath()
|
||||
|
||||
getFileName: ->
|
||||
if fullPath = @getPath()
|
||||
path.basename(fullPath)
|
||||
else
|
||||
null
|
||||
|
||||
getDirectoryPath: ->
|
||||
if fullPath = @getPath()
|
||||
path.dirname(fullPath)
|
||||
else
|
||||
null
|
||||
|
||||
# Extended: Returns the {String} character set encoding of this editor's text
|
||||
# buffer.
|
||||
getEncoding: -> @buffer.getEncoding()
|
||||
@@ -678,16 +686,16 @@ class TextEditor extends Model
|
||||
getSaveDialogOptions: -> {}
|
||||
|
||||
checkoutHeadRevision: ->
|
||||
if filePath = this.getPath()
|
||||
if @getPath()
|
||||
checkoutHead = =>
|
||||
@project.repositoryForDirectory(new Directory(path.dirname(filePath)))
|
||||
@project.repositoryForDirectory(new Directory(@getDirectoryPath()))
|
||||
.then (repository) =>
|
||||
repository?.checkoutHeadForEditor(this)
|
||||
|
||||
if @config.get('editor.confirmCheckoutHeadRevision')
|
||||
@applicationDelegate.confirm
|
||||
message: 'Confirm Checkout HEAD Revision'
|
||||
detailedMessage: "Are you sure you want to discard all changes to \"#{path.basename(filePath)}\" since the last Git commit?"
|
||||
detailedMessage: "Are you sure you want to discard all changes to \"#{@getFileName()}\" since the last Git commit?"
|
||||
buttons:
|
||||
OK: checkoutHead
|
||||
Cancel: null
|
||||
|
||||
@@ -42,9 +42,8 @@ class WindowEventHandler
|
||||
# `.native-key-bindings` class.
|
||||
handleNativeKeybindings: ->
|
||||
bindCommandToAction = (command, action) =>
|
||||
@addEventListener @document, command, (event) =>
|
||||
if event.target.webkitMatchesSelector('.native-key-bindings')
|
||||
@applicationDelegate.getCurrentWindow().webContents[action]()
|
||||
@subscriptions.add @atomEnvironment.commands.add '.native-key-bindings', command, (event) =>
|
||||
@applicationDelegate.getCurrentWindow().webContents[action]()
|
||||
|
||||
bindCommandToAction('core:copy', 'copy')
|
||||
bindCommandToAction('core:paste', 'paste')
|
||||
|
||||
@@ -155,7 +155,7 @@ class Workspace extends Model
|
||||
projectPaths = @project.getPaths() ? []
|
||||
if item = @getActivePaneItem()
|
||||
itemPath = item.getPath?()
|
||||
itemTitle = item.getTitle?()
|
||||
itemTitle = item.getLongTitle?() ? item.getTitle?()
|
||||
projectPath = _.find projectPaths, (projectPath) ->
|
||||
itemPath is projectPath or itemPath?.startsWith(projectPath + path.sep)
|
||||
itemTitle ?= "untitled"
|
||||
@@ -518,6 +518,12 @@ class Workspace extends Model
|
||||
@project.bufferForPath(filePath, options).then (buffer) =>
|
||||
@buildTextEditor(_.extend({buffer, largeFileMode}, options))
|
||||
|
||||
# Public: Returns a {Boolean} that is `true` if `object` is a `TextEditor`.
|
||||
#
|
||||
# * `object` An {Object} you want to perform the check against.
|
||||
isTextEditor: (object) ->
|
||||
object instanceof TextEditor
|
||||
|
||||
# Extended: Create a new text editor.
|
||||
#
|
||||
# Returns a {TextEditor}.
|
||||
@@ -675,9 +681,15 @@ class Workspace extends Model
|
||||
destroyActivePane: ->
|
||||
@getActivePane()?.destroy()
|
||||
|
||||
# Destroy the active pane item or the active pane if it is empty.
|
||||
destroyActivePaneItemOrEmptyPane: ->
|
||||
if @getActivePaneItem()? then @destroyActivePaneItem() else @destroyActivePane()
|
||||
# Close the active pane item, or the active pane if it is empty,
|
||||
# or the current window if there is only the empty root pane.
|
||||
closeActivePaneItemOrEmptyPaneOrWindow: ->
|
||||
if @getActivePaneItem()?
|
||||
@destroyActivePaneItem()
|
||||
else if @getPanes().length > 1
|
||||
@destroyActivePane()
|
||||
else if @config.get('core.closeEmptyWindows')
|
||||
atom.close()
|
||||
|
||||
# Increase the editor font size by 1px.
|
||||
increaseFontSize: ->
|
||||
|
||||
Reference in New Issue
Block a user