mirror of
https://github.com/atom/atom.git
synced 2026-02-09 14:15:24 -05:00
Merge branch 'master' into dh-async-repo
This commit is contained in:
@@ -117,7 +117,7 @@ class AtomEnvironment extends Model
|
||||
|
||||
# Call .loadOrCreate instead
|
||||
constructor: (params={}) ->
|
||||
{@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence} = params
|
||||
{@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params
|
||||
|
||||
@state = {version: @constructor.version}
|
||||
|
||||
@@ -183,7 +183,7 @@ class AtomEnvironment extends Model
|
||||
|
||||
@themes.loadBaseStylesheets()
|
||||
@initialStyleElements = @styles.getSnapshot()
|
||||
@themes.initialLoadComplete = true
|
||||
@themes.initialLoadComplete = true if onlyLoadBaseStyleSheets
|
||||
@setBodyPlatformClass()
|
||||
|
||||
@stylesElement = @styles.buildStylesElement()
|
||||
|
||||
@@ -35,7 +35,7 @@ class CommandInstaller
|
||||
process.resourcesPath
|
||||
|
||||
installShellCommandsInteractively: ->
|
||||
showErrorDialog = (error) ->
|
||||
showErrorDialog = (error) =>
|
||||
@applicationDelegate.confirm
|
||||
message: "Failed to install shell commands"
|
||||
detailedMessage: error.message
|
||||
|
||||
@@ -671,17 +671,47 @@ class Config
|
||||
#
|
||||
# * `callback` {Function} to execute while suppressing calls to handlers.
|
||||
transact: (callback) ->
|
||||
@transactDepth++
|
||||
@beginTransaction()
|
||||
try
|
||||
callback()
|
||||
finally
|
||||
@transactDepth--
|
||||
@emitChangeEvent()
|
||||
@endTransaction()
|
||||
|
||||
###
|
||||
Section: Internal methods used by core
|
||||
###
|
||||
|
||||
# Private: Suppress calls to handler functions registered with {::onDidChange}
|
||||
# and {::observe} for the duration of the {Promise} returned by `callback`.
|
||||
# After the {Promise} is either resolved or rejected, handlers will be called
|
||||
# once if the value for their key-path has changed.
|
||||
#
|
||||
# * `callback` {Function} that returns a {Promise}, which will be executed
|
||||
# while suppressing calls to handlers.
|
||||
#
|
||||
# Returns a {Promise} that is either resolved or rejected according to the
|
||||
# `{Promise}` returned by `callback`. If `callback` throws an error, a
|
||||
# rejected {Promise} will be returned instead.
|
||||
transactAsync: (callback) ->
|
||||
@beginTransaction()
|
||||
try
|
||||
endTransaction = (fn) => (args...) =>
|
||||
@endTransaction()
|
||||
fn(args...)
|
||||
result = callback()
|
||||
new Promise (resolve, reject) =>
|
||||
result.then(endTransaction(resolve)).catch(endTransaction(reject))
|
||||
catch error
|
||||
@endTransaction()
|
||||
Promise.reject(error)
|
||||
|
||||
beginTransaction: ->
|
||||
@transactDepth++
|
||||
|
||||
endTransaction: ->
|
||||
@transactDepth--
|
||||
@emitChangeEvent()
|
||||
|
||||
pushAtKeyPath: (keyPath, value) ->
|
||||
arrayValue = @get(keyPath) ? []
|
||||
result = arrayValue.push(value)
|
||||
|
||||
@@ -36,21 +36,21 @@ class GrammarRegistry extends FirstMate.GrammarRegistry
|
||||
if score > highestScore or not bestMatch?
|
||||
bestMatch = grammar
|
||||
highestScore = score
|
||||
else if score is highestScore and bestMatch?.bundledPackage
|
||||
bestMatch = grammar unless grammar.bundledPackage
|
||||
bestMatch
|
||||
|
||||
# Extended: Returns a {Number} representing how well the grammar matches the
|
||||
# `filePath` and `contents`.
|
||||
getGrammarScore: (grammar, filePath, contents) ->
|
||||
return Infinity if @grammarOverrideForPath(filePath) is grammar.scopeName
|
||||
|
||||
contents = fs.readFileSync(filePath, 'utf8') if not contents? and fs.isFileSync(filePath)
|
||||
|
||||
if @grammarOverrideForPath(filePath) is grammar.scopeName
|
||||
2 + (filePath?.length ? 0)
|
||||
else if @grammarMatchesContents(grammar, contents)
|
||||
1 + (filePath?.length ? 0)
|
||||
else
|
||||
@getGrammarPathScore(grammar, filePath)
|
||||
score = @getGrammarPathScore(grammar, filePath)
|
||||
if score > 0 and not grammar.bundledPackage
|
||||
score += 0.25
|
||||
if @grammarMatchesContents(grammar, contents)
|
||||
score += 0.125
|
||||
score
|
||||
|
||||
getGrammarPathScore: (grammar, filePath) ->
|
||||
return -1 unless filePath
|
||||
|
||||
@@ -58,6 +58,7 @@ module.exports = ({blobStore}) ->
|
||||
document.title = "Spec Suite"
|
||||
|
||||
# Avoid throttling of test window by playing silence
|
||||
# See related discussion in https://github.com/atom/atom/pull/9485
|
||||
context = new AudioContext()
|
||||
source = context.createBufferSource()
|
||||
source.connect(context.destination)
|
||||
@@ -69,6 +70,7 @@ module.exports = ({blobStore}) ->
|
||||
buildAtomEnvironment = (params) ->
|
||||
params = cloneObject(params)
|
||||
params.blobStore = blobStore unless params.hasOwnProperty("blobStore")
|
||||
params.onlyLoadBaseStyleSheets = true unless params.hasOwnProperty("onlyLoadBaseStyleSheets")
|
||||
new AtomEnvironment(params)
|
||||
|
||||
promise = testRunner({
|
||||
|
||||
@@ -37,6 +37,7 @@ class PackageManager
|
||||
@emitter = new Emitter
|
||||
@activationHookEmitter = new Emitter
|
||||
@packageDirPaths = []
|
||||
@deferredActivationHooks = []
|
||||
if configDirPath? and not safeMode
|
||||
if @devMode
|
||||
@packageDirPaths.push(path.join(configDirPath, "dev", "packages"))
|
||||
@@ -336,8 +337,10 @@ class PackageManager
|
||||
keymapsToEnable = _.difference(oldValue, newValue)
|
||||
keymapsToDisable = _.difference(newValue, oldValue)
|
||||
|
||||
@getLoadedPackage(packageName).deactivateKeymaps() for packageName in keymapsToDisable when not @isPackageDisabled(packageName)
|
||||
@getLoadedPackage(packageName).activateKeymaps() for packageName in keymapsToEnable when not @isPackageDisabled(packageName)
|
||||
for packageName in keymapsToDisable when not @isPackageDisabled(packageName)
|
||||
@getLoadedPackage(packageName)?.deactivateKeymaps()
|
||||
for packageName in keymapsToEnable when not @isPackageDisabled(packageName)
|
||||
@getLoadedPackage(packageName)?.activateKeymaps()
|
||||
null
|
||||
|
||||
loadPackages: ->
|
||||
@@ -407,6 +410,7 @@ class PackageManager
|
||||
packages = @getLoadedPackagesForTypes(types)
|
||||
promises = promises.concat(activator.activatePackages(packages))
|
||||
Promise.all(promises).then =>
|
||||
@triggerDeferredActivationHooks()
|
||||
@emitter.emit 'did-activate-initial-packages'
|
||||
|
||||
# another type of package manager can handle other package types.
|
||||
@@ -416,11 +420,11 @@ class PackageManager
|
||||
|
||||
activatePackages: (packages) ->
|
||||
promises = []
|
||||
@config.transact =>
|
||||
@config.transactAsync =>
|
||||
for pack in packages
|
||||
promise = @activatePackage(pack.name)
|
||||
promises.push(promise) unless pack.hasActivationCommands()
|
||||
return
|
||||
promises.push(promise) unless pack.activationShouldBeDeferred()
|
||||
Promise.all(promises)
|
||||
@observeDisabledPackages()
|
||||
@observePackagesWithKeymapsDisabled()
|
||||
promises
|
||||
@@ -437,9 +441,17 @@ class PackageManager
|
||||
else
|
||||
Promise.reject(new Error("Failed to load package '#{name}'"))
|
||||
|
||||
triggerDeferredActivationHooks: ->
|
||||
return unless @deferredActivationHooks?
|
||||
@activationHookEmitter.emit(hook) for hook in @deferredActivationHooks
|
||||
@deferredActivationHooks = null
|
||||
|
||||
triggerActivationHook: (hook) ->
|
||||
return new Error("Cannot trigger an empty activation hook") unless hook? and _.isString(hook) and hook.length > 0
|
||||
@activationHookEmitter.emit(hook)
|
||||
if @deferredActivationHooks?
|
||||
@deferredActivationHooks.push hook
|
||||
else
|
||||
@activationHookEmitter.emit(hook)
|
||||
|
||||
onDidTriggerActivationHook: (hook, callback) ->
|
||||
return unless hook? and _.isString(hook) and hook.length > 0
|
||||
|
||||
@@ -312,6 +312,9 @@ class Pane extends Model
|
||||
else
|
||||
@activateItemAtIndex(@items.length - 1)
|
||||
|
||||
activateLastItem: ->
|
||||
@activateItemAtIndex(@items.length - 1)
|
||||
|
||||
# Public: Move the active tab to the right.
|
||||
moveItemRight: ->
|
||||
index = @getActiveItemIndex()
|
||||
@@ -722,7 +725,7 @@ class Pane extends Model
|
||||
@notificationManager.addWarning("Unable to save file: #{error.message}")
|
||||
else if error.code is 'EACCES'
|
||||
addWarningWithPath('Unable to save file: Permission denied')
|
||||
else if error.code in ['EPERM', 'EBUSY', 'UNKNOWN', 'EEXIST']
|
||||
else if error.code in ['EPERM', 'EBUSY', 'UNKNOWN', 'EEXIST', 'ELOOP', 'EAGAIN']
|
||||
addWarningWithPath('Unable to save file', detail: error.message)
|
||||
else if error.code is 'EROFS'
|
||||
addWarningWithPath('Unable to save file: Read-only file system')
|
||||
|
||||
@@ -55,7 +55,7 @@ class Project extends Model
|
||||
###
|
||||
|
||||
deserialize: (state, deserializerManager) ->
|
||||
states.paths = [state.path] if state.path? # backward compatibility
|
||||
state.paths = [state.path] if state.path? # backward compatibility
|
||||
|
||||
@buffers = _.compact state.buffers.map (bufferState) ->
|
||||
# Check that buffer's file path is accessible
|
||||
|
||||
@@ -12,7 +12,7 @@ module.exports = ({commandRegistry, commandInstaller, config}) ->
|
||||
'pane:show-item-6': -> @getModel().getActivePane().activateItemAtIndex(5)
|
||||
'pane:show-item-7': -> @getModel().getActivePane().activateItemAtIndex(6)
|
||||
'pane:show-item-8': -> @getModel().getActivePane().activateItemAtIndex(7)
|
||||
'pane:show-item-9': -> @getModel().getActivePane().activateItemAtIndex(8)
|
||||
'pane:show-item-9': -> @getModel().getActivePane().activateLastItem()
|
||||
'pane:move-item-right': -> @getModel().getActivePane().moveItemRight()
|
||||
'pane:move-item-left': -> @getModel().getActivePane().moveItemLeft()
|
||||
'window:increase-font-size': -> @getModel().increaseFontSize()
|
||||
|
||||
@@ -50,10 +50,6 @@ class TextEditorComponent
|
||||
|
||||
@presenter = new TextEditorPresenter
|
||||
model: @editor
|
||||
scrollTop: 0
|
||||
scrollLeft: 0
|
||||
scrollRow: @editor.getScrollRow()
|
||||
scrollColumn: @editor.getScrollColumn()
|
||||
tileSize: tileSize
|
||||
cursorBlinkPeriod: @cursorBlinkPeriod
|
||||
cursorBlinkResumeDelay: @cursorBlinkResumeDelay
|
||||
|
||||
@@ -13,15 +13,12 @@ class TextEditorPresenter
|
||||
minimumReflowInterval: 200
|
||||
|
||||
constructor: (params) ->
|
||||
{@model, @config, @autoHeight, @explicitHeight, @contentFrameWidth, @scrollTop, @scrollLeft, @scrollColumn, @scrollRow, @boundingClientRect, @windowWidth, @windowHeight, @gutterWidth} = params
|
||||
{horizontalScrollbarHeight, verticalScrollbarWidth} = params
|
||||
{@lineHeight, @baseCharacterWidth, @backgroundColor, @gutterBackgroundColor, @tileSize} = params
|
||||
{@cursorBlinkPeriod, @cursorBlinkResumeDelay, @stoppedScrollingDelay, @focused} = params
|
||||
@measuredHorizontalScrollbarHeight = horizontalScrollbarHeight
|
||||
@measuredVerticalScrollbarWidth = verticalScrollbarWidth
|
||||
@gutterWidth ?= 0
|
||||
@tileSize ?= 6
|
||||
{@model, @config} = params
|
||||
{@cursorBlinkPeriod, @cursorBlinkResumeDelay, @stoppedScrollingDelay, @tileSize} = params
|
||||
{@contentFrameWidth} = params
|
||||
|
||||
@gutterWidth = 0
|
||||
@tileSize ?= 6
|
||||
@realScrollTop = @scrollTop
|
||||
@realScrollLeft = @scrollLeft
|
||||
@disposables = new CompositeDisposable
|
||||
@@ -77,7 +74,6 @@ class TextEditorPresenter
|
||||
@updateVerticalDimensions()
|
||||
@updateScrollbarDimensions()
|
||||
|
||||
@restoreScrollPosition()
|
||||
@commitPendingLogicalScrollTopPosition()
|
||||
@commitPendingScrollTopPosition()
|
||||
|
||||
@@ -218,6 +214,7 @@ class TextEditorPresenter
|
||||
|
||||
@disposables.add @model.onDidAddCursor(@didAddCursor.bind(this))
|
||||
@disposables.add @model.onDidRequestAutoscroll(@requestAutoscroll.bind(this))
|
||||
@disposables.add @model.onDidChangeFirstVisibleScreenRow(@didChangeFirstVisibleScreenRow.bind(this))
|
||||
@observeCursor(cursor) for cursor in @model.getCursors()
|
||||
@disposables.add @model.onDidAddGutter(@didAddGutter.bind(this))
|
||||
return
|
||||
@@ -778,8 +775,7 @@ class TextEditorPresenter
|
||||
if scrollTop isnt @realScrollTop and not Number.isNaN(scrollTop)
|
||||
@realScrollTop = scrollTop
|
||||
@scrollTop = Math.round(scrollTop)
|
||||
@scrollRow = Math.round(@scrollTop / @lineHeight)
|
||||
@model.setScrollRow(@scrollRow)
|
||||
@model.setFirstVisibleScreenRow(Math.round(@scrollTop / @lineHeight), true)
|
||||
|
||||
@updateStartRow()
|
||||
@updateEndRow()
|
||||
@@ -795,8 +791,7 @@ class TextEditorPresenter
|
||||
if scrollLeft isnt @realScrollLeft and not Number.isNaN(scrollLeft)
|
||||
@realScrollLeft = scrollLeft
|
||||
@scrollLeft = Math.round(scrollLeft)
|
||||
@scrollColumn = Math.round(@scrollLeft / @baseCharacterWidth)
|
||||
@model.setScrollColumn(@scrollColumn)
|
||||
@model.setFirstVisibleScreenColumn(Math.round(@scrollLeft / @baseCharacterWidth))
|
||||
|
||||
@emitter.emit 'did-change-scroll-left', @scrollLeft
|
||||
|
||||
@@ -1095,6 +1090,7 @@ class TextEditorPresenter
|
||||
setLineHeight: (lineHeight) ->
|
||||
unless @lineHeight is lineHeight
|
||||
@lineHeight = lineHeight
|
||||
@restoreScrollTopIfNeeded()
|
||||
@model.setLineHeightInPixels(lineHeight)
|
||||
@shouldUpdateHeightState = true
|
||||
@shouldUpdateHorizontalScrollState = true
|
||||
@@ -1122,6 +1118,7 @@ class TextEditorPresenter
|
||||
@halfWidthCharWidth = halfWidthCharWidth
|
||||
@koreanCharWidth = koreanCharWidth
|
||||
@model.setDefaultCharWidth(baseCharacterWidth, doubleWidthCharWidth, halfWidthCharWidth, koreanCharWidth)
|
||||
@restoreScrollLeftIfNeeded()
|
||||
@characterWidthsChanged()
|
||||
|
||||
characterWidthsChanged: ->
|
||||
@@ -1433,6 +1430,9 @@ class TextEditorPresenter
|
||||
|
||||
@emitDidUpdateState()
|
||||
|
||||
didChangeFirstVisibleScreenRow: (screenRow) ->
|
||||
@updateScrollTop(screenRow * @lineHeight)
|
||||
|
||||
getVerticalScrollMarginInPixels: ->
|
||||
Math.round(@model.getVerticalScrollMargin() * @lineHeight)
|
||||
|
||||
@@ -1512,14 +1512,6 @@ class TextEditorPresenter
|
||||
@updateScrollTop(@pendingScrollTop)
|
||||
@pendingScrollTop = null
|
||||
|
||||
restoreScrollPosition: ->
|
||||
return if @hasRestoredScrollPosition or not @hasPixelPositionRequirements()
|
||||
|
||||
@setScrollTop(@scrollRow * @lineHeight) if @scrollRow?
|
||||
@setScrollLeft(@scrollColumn * @baseCharacterWidth) if @scrollColumn?
|
||||
|
||||
@hasRestoredScrollPosition = true
|
||||
|
||||
clearPendingScrollPosition: ->
|
||||
@pendingScrollLogicalPosition = null
|
||||
@pendingScrollTop = null
|
||||
@@ -1531,6 +1523,14 @@ class TextEditorPresenter
|
||||
canScrollTopTo: (scrollTop) ->
|
||||
@scrollTop isnt @constrainScrollTop(scrollTop)
|
||||
|
||||
restoreScrollTopIfNeeded: ->
|
||||
unless @scrollTop?
|
||||
@updateScrollTop(@model.getFirstVisibleScreenRow() * @lineHeight)
|
||||
|
||||
restoreScrollLeftIfNeeded: ->
|
||||
unless @scrollLeft?
|
||||
@updateScrollLeft(@model.getFirstVisibleScreenColumn() * @baseCharacterWidth)
|
||||
|
||||
onDidChangeScrollTop: (callback) ->
|
||||
@emitter.on 'did-change-scroll-top', callback
|
||||
|
||||
|
||||
@@ -54,13 +54,11 @@ GutterContainer = require './gutter-container'
|
||||
# soft wraps and folds to ensure your code interacts with them correctly.
|
||||
module.exports =
|
||||
class TextEditor extends Model
|
||||
callDisplayBufferCreatedHook: false
|
||||
buffer: null
|
||||
languageMode: null
|
||||
cursors: null
|
||||
selections: null
|
||||
suppressSelectionMerging: false
|
||||
updateBatchDepth: 0
|
||||
selectionFlashDuration: 500
|
||||
gutterContainer: null
|
||||
|
||||
@@ -90,7 +88,7 @@ class TextEditor extends Model
|
||||
super
|
||||
|
||||
{
|
||||
@softTabs, @scrollRow, @scrollColumn, initialLine, initialColumn, tabLength,
|
||||
@softTabs, @firstVisibleScreenRow, @firstVisibleScreenColumn, initialLine, initialColumn, tabLength,
|
||||
softWrapped, @displayBuffer, @selectionsMarkerLayer, buffer, suppressCursorCreation,
|
||||
@mini, @placeholderText, lineNumberGutterVisible, largeFileMode, @config,
|
||||
@notificationManager, @packageManager, @clipboard, @viewRegistry, @grammarRegistry,
|
||||
@@ -106,6 +104,8 @@ class TextEditor extends Model
|
||||
throw new Error("Must pass a project parameter when constructing TextEditors") unless @project?
|
||||
throw new Error("Must pass an assert parameter when constructing TextEditors") unless @assert?
|
||||
|
||||
@firstVisibleScreenRow ?= 0
|
||||
@firstVisibleScreenColumn ?= 0
|
||||
@emitter = new Emitter
|
||||
@disposables = new CompositeDisposable
|
||||
@cursors = []
|
||||
@@ -146,8 +146,8 @@ class TextEditor extends Model
|
||||
deserializer: 'TextEditor'
|
||||
id: @id
|
||||
softTabs: @softTabs
|
||||
scrollRow: @getScrollRow()
|
||||
scrollColumn: @getScrollColumn()
|
||||
firstVisibleScreenRow: @getFirstVisibleScreenRow()
|
||||
firstVisibleScreenColumn: @getFirstVisibleScreenColumn()
|
||||
displayBuffer: @displayBuffer.serialize()
|
||||
selectionsMarkerLayerId: @selectionsMarkerLayer.id
|
||||
|
||||
@@ -453,6 +453,9 @@ class TextEditor extends Model
|
||||
onDidChangeCharacterWidths: (callback) ->
|
||||
@displayBuffer.onDidChangeCharacterWidths(callback)
|
||||
|
||||
onDidChangeFirstVisibleScreenRow: (callback, fromView) ->
|
||||
@emitter.on 'did-change-first-visible-screen-row', callback
|
||||
|
||||
onDidChangeScrollTop: (callback) ->
|
||||
Grim.deprecate("This is now a view method. Call TextEditorElement::onDidChangeScrollTop instead.")
|
||||
|
||||
@@ -583,18 +586,18 @@ class TextEditor extends Model
|
||||
else
|
||||
'untitled'
|
||||
|
||||
# Essential: Get unique title for display in other parts of the UI
|
||||
# such as the window title.
|
||||
# Essential: Get unique title for display in other parts of the UI, such as
|
||||
# the window title.
|
||||
#
|
||||
# If the editor's buffer is unsaved, its title is "untitled"
|
||||
# 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.
|
||||
# if the the direct parent directory is already different.
|
||||
#
|
||||
# Returns a {String}
|
||||
getUniqueTitle: ->
|
||||
getLongTitle: ->
|
||||
if sessionPath = @getPath()
|
||||
title = @getTitle()
|
||||
|
||||
@@ -622,22 +625,6 @@ class TextEditor extends Model
|
||||
else
|
||||
'untitled'
|
||||
|
||||
# Essential: Get the editor's long title for display in other parts of the UI
|
||||
# such as the window title.
|
||||
#
|
||||
# If the editor's buffer is saved, its long title is formatted as
|
||||
# "<filename> - <directory>". If it is unsaved, its title is "untitled"
|
||||
#
|
||||
# Returns a {String}.
|
||||
getLongTitle: ->
|
||||
if sessionPath = @getPath()
|
||||
fileName = path.basename(sessionPath)
|
||||
directory = @project.relativize(path.dirname(sessionPath))
|
||||
directory = if directory.length > 0 then directory else path.basename(path.dirname(sessionPath))
|
||||
"#{fileName} - #{directory}"
|
||||
else
|
||||
'untitled'
|
||||
|
||||
# Essential: Returns the {String} path of this editor's text buffer.
|
||||
getPath: -> @buffer.getPath()
|
||||
|
||||
@@ -3130,14 +3117,6 @@ class TextEditor extends Model
|
||||
@placeholderText = placeholderText
|
||||
@emitter.emit 'did-change-placeholder-text', @placeholderText
|
||||
|
||||
getFirstVisibleScreenRow: ->
|
||||
deprecate("This is now a view method. Call TextEditorElement::getFirstVisibleScreenRow instead.")
|
||||
@viewRegistry.getView(this).getVisibleRowRange()[0]
|
||||
|
||||
getLastVisibleScreenRow: ->
|
||||
Grim.deprecate("This is now a view method. Call TextEditorElement::getLastVisibleScreenRow instead.")
|
||||
@viewRegistry.getView(this).getVisibleRowRange()[1]
|
||||
|
||||
pixelPositionForBufferPosition: (bufferPosition) ->
|
||||
Grim.deprecate("This method is deprecated on the model layer. Use `TextEditorElement::pixelPositionForBufferPosition` instead")
|
||||
@viewRegistry.getView(this).pixelPositionForBufferPosition(bufferPosition)
|
||||
@@ -3192,11 +3171,40 @@ class TextEditor extends Model
|
||||
Grim.deprecate("This is now a view method. Call TextEditorElement::getWidth instead.")
|
||||
@displayBuffer.getWidth()
|
||||
|
||||
getScrollRow: -> @scrollRow
|
||||
setScrollRow: (@scrollRow) ->
|
||||
# Experimental: Scroll the editor such that the given screen row is at the
|
||||
# top of the visible area.
|
||||
setFirstVisibleScreenRow: (screenRow, fromView) ->
|
||||
unless fromView
|
||||
maxScreenRow = @getLineCount() - 1
|
||||
unless @config.get('editor.scrollPastEnd')
|
||||
height = @displayBuffer.getHeight()
|
||||
lineHeightInPixels = @displayBuffer.getLineHeightInPixels()
|
||||
if height? and lineHeightInPixels?
|
||||
maxScreenRow -= Math.floor(height / lineHeightInPixels)
|
||||
screenRow = Math.max(Math.min(screenRow, maxScreenRow), 0)
|
||||
|
||||
getScrollColumn: -> @scrollColumn
|
||||
setScrollColumn: (@scrollColumn) ->
|
||||
unless screenRow is @firstVisibleScreenRow
|
||||
@firstVisibleScreenRow = screenRow
|
||||
@emitter.emit 'did-change-first-visible-screen-row', screenRow unless fromView
|
||||
|
||||
getFirstVisibleScreenRow: -> @firstVisibleScreenRow
|
||||
|
||||
getLastVisibleScreenRow: ->
|
||||
height = @displayBuffer.getHeight()
|
||||
lineHeightInPixels = @displayBuffer.getLineHeightInPixels()
|
||||
if height? and lineHeightInPixels?
|
||||
Math.min(@firstVisibleScreenRow + Math.floor(height / lineHeightInPixels), @getLineCount() - 1)
|
||||
else
|
||||
null
|
||||
|
||||
getVisibleRowRange: ->
|
||||
if lastVisibleScreenRow = @getLastVisibleScreenRow()
|
||||
[@firstVisibleScreenRow, lastVisibleScreenRow]
|
||||
else
|
||||
null
|
||||
|
||||
setFirstVisibleScreenColumn: (@firstVisibleScreenColumn) ->
|
||||
getFirstVisibleScreenColumn: -> @firstVisibleScreenColumn
|
||||
|
||||
getScrollTop: ->
|
||||
Grim.deprecate("This is now a view method. Call TextEditorElement::getScrollTop instead.")
|
||||
@@ -3253,11 +3261,6 @@ class TextEditor extends Model
|
||||
|
||||
@viewRegistry.getView(this).getMaxScrollTop()
|
||||
|
||||
getVisibleRowRange: ->
|
||||
Grim.deprecate("This is now a view method. Call TextEditorElement::getVisibleRowRange instead.")
|
||||
|
||||
@viewRegistry.getView(this).getVisibleRowRange()
|
||||
|
||||
intersectsVisibleRowRange: (startRow, endRow) ->
|
||||
Grim.deprecate("This is now a view method. Call TextEditorElement::intersectsVisibleRowRange instead.")
|
||||
|
||||
|
||||
@@ -468,7 +468,7 @@ class Workspace extends Model
|
||||
when 'EACCES'
|
||||
@notificationManager.addWarning("Permission denied '#{error.path}'")
|
||||
return Promise.resolve()
|
||||
when 'EPERM', 'EBUSY', 'ENXIO', 'EIO', 'ENOTCONN', 'UNKNOWN', 'ECONNRESET', 'EINVAL'
|
||||
when 'EPERM', 'EBUSY', 'ENXIO', 'EIO', 'ENOTCONN', 'UNKNOWN', 'ECONNRESET', 'EINVAL', 'EMFILE', 'ENOTDIR'
|
||||
@notificationManager.addWarning("Unable to open '#{error.path ? uri}'", detail: error.message)
|
||||
return Promise.resolve()
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user