Comparar commits
127 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| d1ba8b0140 | |||
| f4b23b801d | |||
| 14c8c463fb | |||
| b5fc4aec84 | |||
| 1f2fc4bf00 | |||
| 3601d113ad | |||
| 6a81f3c6ce | |||
| 00baedbdf9 | |||
| 2c3bec7468 | |||
| 409816ef07 | |||
| 8871d45227 | |||
| c5fa8fdf11 | |||
| e060e08f93 | |||
| 039afff1de | |||
| d33bd291dd | |||
| b422c7a678 | |||
| 55d243215a | |||
| 0bc2b45200 | |||
| 683d0d1b16 | |||
| 82c53b539a | |||
| c2f44efe31 | |||
| b3038eb968 | |||
| 3694111211 | |||
| bf2d307cbe | |||
| 38016b205c | |||
| b4dcd019c1 | |||
| 13a5bfd1dd | |||
| 9e0c4d1fb6 | |||
| cabcf19297 | |||
| 9aa7331e6e | |||
| 3daf505f3e | |||
| cd92f882bf | |||
| 707ac0b043 | |||
| 4a812707d8 | |||
| f2ef7beae6 | |||
| c64a4dd70f | |||
| 3ab0b16923 | |||
| fac72fbf10 | |||
| 7d71eeedf4 | |||
| 6d55bab4c8 | |||
| d506ccbaad | |||
| 8275ddd882 | |||
| b7765d9416 | |||
| 47f8f7eb11 | |||
| 63181a17c8 | |||
| c71457e9d4 | |||
| 7d31b17273 | |||
| 066f6bf03c | |||
| 40f8b990d0 | |||
| a492596f7f | |||
| 2df5957f9b | |||
| a7196ec906 | |||
| c094b7a0ef | |||
| 09b5ac887a | |||
| 67ff8f4382 | |||
| 0c9fd46030 | |||
| cf4a7c22ee | |||
| 30f04360dd | |||
| 371e25af69 | |||
| 7fdffdd201 | |||
| 475fd07790 | |||
| 9e99cf03ea | |||
| b2c74ac249 | |||
| daa2c77321 | |||
| 3f15338cad | |||
| 00f67122c4 | |||
| df3f884ada | |||
| 85bf163f76 | |||
| c6d6fb3b7a | |||
| 26f3bde0e6 | |||
| 97b742cb1d | |||
| 4c3ac8e6ec | |||
| 0be03c8d9c | |||
| 0bdddc955f | |||
| ad9b5e5b8d | |||
| c178ac3aa6 | |||
| 6b23479c3f | |||
| c4e3b76070 | |||
| 3dbaa0679b | |||
| 366714aa3d | |||
| 1077a59450 | |||
| 3bc115a7a0 | |||
| 71b3ab3ae6 | |||
| 169a5de6a3 | |||
| a615c3e081 | |||
| 02d34b3ba9 | |||
| 69217b2d8f | |||
| 4606ce2d50 | |||
| 1dc5593380 | |||
| 42e0f83259 | |||
| 428532cd24 | |||
| 7581832658 | |||
| c61c07f07d | |||
| abe7dde205 | |||
| 4bc49b82ef | |||
| de1fd977e0 | |||
| afce21f37d | |||
| 5230d040eb | |||
| ddb85abe77 | |||
| 55cce48af1 | |||
| d3239473b3 | |||
| fa103d42d0 | |||
| ecbf2b708c | |||
| d344adc21e | |||
| 74d772f069 | |||
| e2e804483f | |||
| e084e13ea3 | |||
| b5499247b3 | |||
| 54378b11d4 | |||
| 21802ddb7c | |||
| 20e08323c1 | |||
| 0877721ce9 | |||
| 2b86297a0b | |||
| 53bd1c8958 | |||
| 7f41be3103 | |||
| 7baa3b6f09 | |||
| 1080eb2d11 | |||
| 246575390a | |||
| bc6c85ceca | |||
| a0b405fe6f | |||
| 54b89cebcc | |||
| 7b9b044394 | |||
| 23cb0eda2f | |||
| a354d9f880 | |||
| 7526038f9a | |||
| c0973f8c0f | |||
| dededd80dd |
+2
-2
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "atom-bundled-apm",
|
||||
"description": "Atom's bundled APM",
|
||||
"description": "Atom's bundled apm",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "0.96.0"
|
||||
"atom-package-manager": "0.97.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ describe "editorView.", ->
|
||||
|
||||
beforeEach ->
|
||||
atom.workspaceViewParentSelector = '#jasmine-content'
|
||||
atom.workspaceView = new WorkspaceView
|
||||
atom.workspaceView = atom.workspace.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView.attachToDom()
|
||||
|
||||
atom.workspaceView.width(1024)
|
||||
|
||||
@@ -39,6 +39,7 @@ module.exports = (grunt) ->
|
||||
tmpDir = os.tmpdir()
|
||||
appName = if process.platform is 'darwin' then 'Atom.app' else 'Atom'
|
||||
buildDir = grunt.option('build-dir') ? path.join(tmpDir, 'atom-build')
|
||||
buildDir = path.resolve(buildDir)
|
||||
installDir = grunt.option('install-dir')
|
||||
|
||||
home = if process.platform is 'win32' then process.env.USERPROFILE else process.env.HOME
|
||||
@@ -62,6 +63,8 @@ module.exports = (grunt) ->
|
||||
installDir ?= process.env.INSTALL_PREFIX ? '/usr/local'
|
||||
killCommand ='pkill -9 atom'
|
||||
|
||||
installDir = path.resolve(installDir)
|
||||
|
||||
coffeeConfig =
|
||||
glob_to_multiple:
|
||||
expand: true
|
||||
@@ -231,8 +234,9 @@ module.exports = (grunt) ->
|
||||
ciTasks.push('dump-symbols') if process.platform isnt 'win32'
|
||||
ciTasks.push('set-version', 'check-licenses', 'lint')
|
||||
ciTasks.push('mkdeb') if process.platform is 'linux'
|
||||
ciTasks.push('test') if process.platform isnt 'linux'
|
||||
ciTasks.push('codesign', 'publish-build')
|
||||
ciTasks.push('test') if process.platform is 'darwin'
|
||||
ciTasks.push('codesign')
|
||||
ciTasks.push('publish-build')
|
||||
grunt.registerTask('ci', ciTasks)
|
||||
|
||||
defaultTasks = ['download-atom-shell', 'build', 'set-version']
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{spawn} = require('./task-helpers')(grunt)
|
||||
@@ -31,6 +32,15 @@ module.exports = (grunt) ->
|
||||
spawn {cmd: 'taskkill', args: ['/F', '/IM', 'atom.exe']}, ->
|
||||
cmd = process.env.JANKY_SIGNTOOL ? 'signtool'
|
||||
args = [path.join(grunt.config.get('atom.shellAppDir'), 'atom.exe')]
|
||||
spawn {cmd, args}, (error) -> callback(error)
|
||||
|
||||
spawn {cmd, args}, (error) ->
|
||||
return callback(error) if error?
|
||||
|
||||
setupExePath = path.join(grunt.config.get('atom.shellAppDir'), '..', 'Releases', 'setup.exe')
|
||||
if fs.isFileSync(setupExePath)
|
||||
args = [setupExePath]
|
||||
spawn {cmd, args}, (error) -> callback(error)
|
||||
else
|
||||
callback()
|
||||
else
|
||||
callback()
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{spawn, rm} = require('./task-helpers')(grunt)
|
||||
|
||||
grunt.registerTask 'create-installer', 'Create the Windows installer', ->
|
||||
return unless process.platform is 'win32'
|
||||
|
||||
done = @async()
|
||||
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
atomDir = path.join(buildDir, 'Atom')
|
||||
|
||||
packageInfo = grunt.file.readJSON(path.join(atomDir, 'resources', 'app', 'package.json'))
|
||||
inputTemplate = grunt.file.read(path.join('build', 'windows', 'atom.nuspec.erb'))
|
||||
|
||||
# NB: Build server has some sort of stamp on the version number
|
||||
packageInfo.version = packageInfo.version.replace(/-.*$/, '')
|
||||
|
||||
targetNuspecPath = path.join(buildDir, 'atom.nuspec')
|
||||
grunt.file.write(targetNuspecPath, _.template(inputTemplate, packageInfo))
|
||||
|
||||
cmd = 'build/windows/nuget.exe'
|
||||
args = ['pack', targetNuspecPath, '-BasePath', atomDir, '-OutputDirectory', buildDir]
|
||||
|
||||
spawn {cmd, args}, (error, result, code) ->
|
||||
return done(error) if error?
|
||||
|
||||
pkgs = pkg for pkg in fs.readdirSync(buildDir) when path.extname(pkg) is '.nupkg'
|
||||
|
||||
releasesDir = path.join(buildDir, 'Releases')
|
||||
|
||||
# NB: Gonna clear Releases for now, in the future we need to pull down
|
||||
# the existing version
|
||||
rm(releasesDir)
|
||||
|
||||
cmd = 'build/windows/update.com'
|
||||
args = ['--releasify', path.join(buildDir, pkgs), '-r', releasesDir, '-g', 'build/windows/install-spinner.gif']
|
||||
spawn {cmd, args}, (error, result, code) -> done(error)
|
||||
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id><%= name %></id>
|
||||
<version><%= version %></version>
|
||||
<authors>The Atom Community</authors>
|
||||
<owners>The Atom Community</owners>
|
||||
<iconUrl>https://raw.githubusercontent.com/atom/atom/master/resources/win/atom.ico</iconUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description><%= description %></description>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="locales\**" target="lib\net45\locales" />
|
||||
<file src="resources\**" target="lib\net45\resources" />
|
||||
<file src="*.pak" target="lib\net45" />
|
||||
|
||||
<file src="atom.exe" target="lib\net45\atom.exe" />
|
||||
<file src="atom.exe.gui" target="lib\net45\atom.exe.gui" />
|
||||
<file src="chromiumcontent.dll" target="lib\net45\chromiumcontent.dll" />
|
||||
<file src="d3dcompiler_43.dll" target="lib\net45\d3dcompiler_43.dll" />
|
||||
<file src="ffmpegsumo.dll" target="lib\net45\ffmpegsumo.dll" />
|
||||
<file src="icudtl.dat" target="lib\net45\icudtl.dat" />
|
||||
<file src="libEGL.dll" target="lib\net45\libEGL.dll" />
|
||||
<file src="libGLESv2.dll" target="lib\net45\libGLESv2.dll" />
|
||||
<file src="LICENSE" target="lib\net45\LICENSE" />
|
||||
<file src="msvcp120.dll" target="lib\net45\msvcp120.dll" />
|
||||
<file src="msvcr120.dll" target="lib\net45\msvcr120.dll" />
|
||||
<file src="vccorlib120.dll" target="lib\net45\vccorlib120.dll" />
|
||||
<file src="version" target="lib\net45\version" />
|
||||
<file src="xinput1_3.dll" target="lib\net45\xinput1_3.dll" />
|
||||
</files>
|
||||
</package>
|
||||
Arquivo binário não exibido.
|
Depois Largura: | Altura: | Tamanho: 43 KiB |
@@ -8,10 +8,6 @@ module.exports =
|
||||
Point: Point
|
||||
Range: Range
|
||||
|
||||
Object.defineProperty module.exports, 'Git', get: ->
|
||||
deprecate "Please require `GitRepository` instead of `Git`: `{GitRepository} = require 'atom'`"
|
||||
module.exports.GitRepository
|
||||
|
||||
# The following classes can't be used from a Task handler and should therefore
|
||||
# only be exported when not running as a child node process
|
||||
unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
|
||||
@@ -20,7 +16,7 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
|
||||
module.exports.$ = $
|
||||
module.exports.$$ = $$
|
||||
module.exports.$$$ = $$$
|
||||
module.exports.EditorView = require '../src/editor-view'
|
||||
module.exports.TextEditorView = require '../src/text-editor-view'
|
||||
module.exports.ScrollView = require '../src/scroll-view'
|
||||
module.exports.SelectListView = require '../src/select-list-view'
|
||||
module.exports.Task = require '../src/task'
|
||||
@@ -29,3 +25,11 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
|
||||
module.exports.Workspace = require '../src/workspace'
|
||||
module.exports.React = require 'react-atom-fork'
|
||||
module.exports.Reactionary = require 'reactionary-atom-fork'
|
||||
|
||||
Object.defineProperty module.exports, 'Git', get: ->
|
||||
deprecate "Please require `GitRepository` instead of `Git`: `{GitRepository} = require 'atom'`"
|
||||
module.exports.GitRepository
|
||||
|
||||
Object.defineProperty module.exports, 'EditorView', get: ->
|
||||
deprecate "Please require `TextEditorView` instead of `EditorView`: `{TextEditorView} = require 'atom'`"
|
||||
module.exports.TextEditorView
|
||||
|
||||
+2
-2
@@ -33,8 +33,8 @@
|
||||
{ label: '&Undo', command: 'core:undo' }
|
||||
{ label: '&Redo', command: 'core:redo' }
|
||||
{ type: 'separator' }
|
||||
{ label: '&Cut', command: 'core:cut' }
|
||||
{ label: 'C&opy', command: 'core:copy' }
|
||||
{ label: 'Cu&t', command: 'core:cut' }
|
||||
{ label: '&Copy', command: 'core:copy' }
|
||||
{ label: 'Copy Pat&h', command: 'editor:copy-path' }
|
||||
{ label: '&Paste', command: 'core:paste' }
|
||||
{ label: 'Select &All', command: 'core:select-all' }
|
||||
|
||||
+12
-12
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "0.130.0",
|
||||
"version": "0.132.0",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/browser/main.js",
|
||||
"repository": {
|
||||
@@ -20,7 +20,7 @@
|
||||
"atomShellVersion": "0.16.2",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "^2.1.1",
|
||||
"atom-keymap": "^2.1.3",
|
||||
"bootstrap": "git+https://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
|
||||
"clear-cut": "0.4.0",
|
||||
"coffee-script": "1.7.0",
|
||||
@@ -75,10 +75,10 @@
|
||||
"autocomplete": "0.32.0",
|
||||
"autoflow": "0.18.0",
|
||||
"autosave": "0.17.0",
|
||||
"background-tips": "0.16.0",
|
||||
"background-tips": "0.17.0",
|
||||
"bookmarks": "0.28.0",
|
||||
"bracket-matcher": "0.58.0",
|
||||
"command-palette": "0.25.0",
|
||||
"bracket-matcher": "0.60.0",
|
||||
"command-palette": "0.26.0",
|
||||
"deprecation-cop": "0.10.0",
|
||||
"dev-live-reload": "0.34.0",
|
||||
"exception-reporting": "0.20.0",
|
||||
@@ -93,19 +93,19 @@
|
||||
"keybinding-resolver": "0.20.0",
|
||||
"link": "0.25.0",
|
||||
"markdown-preview": "0.103.0",
|
||||
"metrics": "0.34.0",
|
||||
"metrics": "0.36.0",
|
||||
"open-on-github": "0.30.0",
|
||||
"package-generator": "0.31.0",
|
||||
"release-notes": "0.36.0",
|
||||
"settings-view": "0.145.0",
|
||||
"snippets": "0.52.0",
|
||||
"settings-view": "0.147.0",
|
||||
"snippets": "0.53.0",
|
||||
"spell-check": "0.42.0",
|
||||
"status-bar": "0.45.0",
|
||||
"styleguide": "0.30.0",
|
||||
"symbols-view": "0.66.0",
|
||||
"tabs": "0.52.0",
|
||||
"tabs": "0.53.0",
|
||||
"timecop": "0.22.0",
|
||||
"tree-view": "0.126.0",
|
||||
"tree-view": "0.127.0",
|
||||
"update-package-dependencies": "0.6.0",
|
||||
"welcome": "0.18.0",
|
||||
"whitespace": "0.25.0",
|
||||
@@ -131,12 +131,12 @@
|
||||
"language-python": "0.19.0",
|
||||
"language-ruby": "0.38.0",
|
||||
"language-ruby-on-rails": "0.18.0",
|
||||
"language-sass": "0.21.0",
|
||||
"language-sass": "0.22.0",
|
||||
"language-shellscript": "0.8.0",
|
||||
"language-source": "0.8.0",
|
||||
"language-sql": "0.11.0",
|
||||
"language-text": "0.6.0",
|
||||
"language-todo": "0.11.0",
|
||||
"language-todo": "0.12.0",
|
||||
"language-toml": "0.12.0",
|
||||
"language-xml": "0.21.0",
|
||||
"language-yaml": "0.17.0"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
Package: <%= name %>
|
||||
Version: <%= version %>
|
||||
Depends: python (>= 2.6), libc6
|
||||
Section: <%= section %>
|
||||
Priority: optional
|
||||
Architecture: <%= arch %>
|
||||
Installed-Size: <%= installedSize %>
|
||||
Maintainer: <%= maintainer %>
|
||||
Description: <%= description %>
|
||||
Atom is a free and open source text editor that is modern, approachable, and hackable to the core.
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
atom: arch-dependent-file-in-usr-share
|
||||
atom: changelog-file-missing-in-native-package
|
||||
atom: copyright-file-contains-full-apache-2-license
|
||||
atom: copyright-should-refer-to-common-license-file-for-apache-2
|
||||
atom: embedded-library
|
||||
atom: package-installs-python-bytecode
|
||||
atom: unstripped-binary-or-object
|
||||
+14
-3
@@ -16,7 +16,7 @@ DEB_PATH="$6"
|
||||
FILE_MODE=755
|
||||
|
||||
TARGET_ROOT="`mktemp -d`"
|
||||
chmod 755 "$TARGET_ROOT"
|
||||
chmod $FILE_MODE "$TARGET_ROOT"
|
||||
TARGET="$TARGET_ROOT/atom-$VERSION-$ARCH"
|
||||
|
||||
mkdir -m $FILE_MODE -p "$TARGET/usr"
|
||||
@@ -31,6 +31,17 @@ cp "$DESKTOP_FILE" "$TARGET/usr/share/applications"
|
||||
mkdir -m $FILE_MODE -p "$TARGET/usr/share/pixmaps"
|
||||
cp "$ICON_FILE" "$TARGET/usr/share/pixmaps"
|
||||
|
||||
dpkg-deb -b "$TARGET"
|
||||
# Copy generated LICENSE.md to /usr/share/doc/atom/copyright
|
||||
mkdir -m $FILE_MODE -p "$TARGET/usr/share/doc/atom"
|
||||
cp "$TARGET/usr/share/atom/resources/app/LICENSE.md" "$TARGET/usr/share/doc/atom/copyright"
|
||||
|
||||
# Add lintian overrides
|
||||
mkdir -m $FILE_MODE -p "$TARGET/usr/share/lintian/overrides"
|
||||
cp "$ROOT/resources/linux/debian/lintian-overrides" "$TARGET/usr/share/lintian/overrides/atom"
|
||||
|
||||
# Remove executable bit from .node files
|
||||
find "$TARGET" -type f -name "*.node" -exec chmod a-x {} \;
|
||||
|
||||
fakeroot dpkg-deb -b "$TARGET"
|
||||
mv "$TARGET_ROOT/atom-$VERSION-$ARCH.deb" "$DEB_PATH"
|
||||
rm -rf $TARGET_ROOT
|
||||
rm -rf "$TARGET_ROOT"
|
||||
|
||||
+1
-536
@@ -6,7 +6,7 @@ ThemeManager = require '../src/theme-manager'
|
||||
|
||||
describe "the `atom` global", ->
|
||||
beforeEach ->
|
||||
atom.workspaceView = new WorkspaceView
|
||||
atom.workspaceView = atom.workspace.getView(atom.workspace).__spacePenView
|
||||
|
||||
describe 'window sizing methods', ->
|
||||
describe '::getPosition and ::setPosition', ->
|
||||
@@ -25,541 +25,6 @@ describe "the `atom` global", ->
|
||||
atom.setSize(100, 400)
|
||||
expect(atom.getSize()).toEqual width: 100, height: 400
|
||||
|
||||
describe "package lifecycle methods", ->
|
||||
describe ".loadPackage(name)", ->
|
||||
it "continues if the package has an invalid package.json", ->
|
||||
spyOn(console, 'warn')
|
||||
atom.config.set("core.disabledPackages", [])
|
||||
expect(-> atom.packages.loadPackage("package-with-broken-package-json")).not.toThrow()
|
||||
|
||||
it "continues if the package has an invalid keymap", ->
|
||||
atom.config.set("core.disabledPackages", [])
|
||||
expect(-> atom.packages.loadPackage("package-with-broken-keymap")).not.toThrow()
|
||||
|
||||
describe ".unloadPackage(name)", ->
|
||||
describe "when the package is active", ->
|
||||
it "throws an error", ->
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-main').then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(atom.packages.isPackageLoaded(pack.name)).toBeTruthy()
|
||||
expect(atom.packages.isPackageActive(pack.name)).toBeTruthy()
|
||||
expect( -> atom.packages.unloadPackage(pack.name)).toThrow()
|
||||
expect(atom.packages.isPackageLoaded(pack.name)).toBeTruthy()
|
||||
expect(atom.packages.isPackageActive(pack.name)).toBeTruthy()
|
||||
|
||||
describe "when the package is not loaded", ->
|
||||
it "throws an error", ->
|
||||
expect(atom.packages.isPackageLoaded('unloaded')).toBeFalsy()
|
||||
expect( -> atom.packages.unloadPackage('unloaded')).toThrow()
|
||||
expect(atom.packages.isPackageLoaded('unloaded')).toBeFalsy()
|
||||
|
||||
describe "when the package is loaded", ->
|
||||
it "no longers reports it as being loaded", ->
|
||||
pack = atom.packages.loadPackage('package-with-main')
|
||||
expect(atom.packages.isPackageLoaded(pack.name)).toBeTruthy()
|
||||
atom.packages.unloadPackage(pack.name)
|
||||
expect(atom.packages.isPackageLoaded(pack.name)).toBeFalsy()
|
||||
|
||||
describe ".activatePackage(id)", ->
|
||||
describe "atom packages", ->
|
||||
describe "when called multiple times", ->
|
||||
it "it only calls activate on the package once", ->
|
||||
spyOn(Package.prototype, 'activateNow').andCallThrough()
|
||||
atom.packages.activatePackage('package-with-index')
|
||||
atom.packages.activatePackage('package-with-index')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-index')
|
||||
|
||||
runs ->
|
||||
expect(Package.prototype.activateNow.callCount).toBe 1
|
||||
|
||||
describe "when the package has a main module", ->
|
||||
describe "when the metadata specifies a main module path˜", ->
|
||||
it "requires the module at the specified path", ->
|
||||
mainModule = require('./fixtures/packages/package-with-main/main-module')
|
||||
spyOn(mainModule, 'activate')
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-main').then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(mainModule.activate).toHaveBeenCalled()
|
||||
expect(pack.mainModule).toBe mainModule
|
||||
|
||||
describe "when the metadata does not specify a main module", ->
|
||||
it "requires index.coffee", ->
|
||||
indexModule = require('./fixtures/packages/package-with-index/index')
|
||||
spyOn(indexModule, 'activate')
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-index').then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(indexModule.activate).toHaveBeenCalled()
|
||||
expect(pack.mainModule).toBe indexModule
|
||||
|
||||
it "assigns config defaults from the module", ->
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBeUndefined()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-config-defaults')
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBe 1
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.two')).toBe 2
|
||||
|
||||
describe "when the package metadata includes activation events", ->
|
||||
[mainModule, promise] = []
|
||||
|
||||
beforeEach ->
|
||||
mainModule = require './fixtures/packages/package-with-activation-events/index'
|
||||
spyOn(mainModule, 'activate').andCallThrough()
|
||||
spyOn(Package.prototype, 'requireMainModule').andCallThrough()
|
||||
|
||||
promise = atom.packages.activatePackage('package-with-activation-events')
|
||||
|
||||
it "defers requiring/activating the main module until an activation event bubbles to the root view", ->
|
||||
expect(promise.isFulfilled()).not.toBeTruthy()
|
||||
atom.workspaceView.trigger 'activation-event'
|
||||
|
||||
waitsForPromise ->
|
||||
promise
|
||||
|
||||
it "triggers the activation event on all handlers registered during activation", ->
|
||||
waitsForPromise ->
|
||||
atom.workspaceView.open()
|
||||
|
||||
runs ->
|
||||
editorView = atom.workspaceView.getActiveView()
|
||||
eventHandler = jasmine.createSpy("activation-event")
|
||||
editorView.command 'activation-event', eventHandler
|
||||
editorView.trigger 'activation-event'
|
||||
expect(mainModule.activate.callCount).toBe 1
|
||||
expect(mainModule.activationEventCallCount).toBe 1
|
||||
expect(eventHandler.callCount).toBe 1
|
||||
editorView.trigger 'activation-event'
|
||||
expect(mainModule.activationEventCallCount).toBe 2
|
||||
expect(eventHandler.callCount).toBe 2
|
||||
expect(mainModule.activate.callCount).toBe 1
|
||||
|
||||
it "activates the package immediately when the events are empty", ->
|
||||
mainModule = require './fixtures/packages/package-with-empty-activation-events/index'
|
||||
spyOn(mainModule, 'activate').andCallThrough()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-empty-activation-events')
|
||||
|
||||
runs ->
|
||||
expect(mainModule.activate.callCount).toBe 1
|
||||
|
||||
describe "when the package has no main module", ->
|
||||
it "does not throw an exception", ->
|
||||
spyOn(console, "error")
|
||||
spyOn(console, "warn").andCallThrough()
|
||||
expect(-> atom.packages.activatePackage('package-without-module')).not.toThrow()
|
||||
expect(console.error).not.toHaveBeenCalled()
|
||||
expect(console.warn).not.toHaveBeenCalled()
|
||||
|
||||
it "passes the activate method the package's previously serialized state if it exists", ->
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-serialization").then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(pack.mainModule.someNumber).not.toBe 77
|
||||
pack.mainModule.someNumber = 77
|
||||
atom.packages.deactivatePackage("package-with-serialization")
|
||||
spyOn(pack.mainModule, 'activate').andCallThrough()
|
||||
atom.packages.activatePackage("package-with-serialization")
|
||||
expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77})
|
||||
|
||||
it "logs warning instead of throwing an exception if the package fails to load", ->
|
||||
atom.config.set("core.disabledPackages", [])
|
||||
spyOn(console, "warn")
|
||||
expect(-> atom.packages.activatePackage("package-that-throws-an-exception")).not.toThrow()
|
||||
expect(console.warn).toHaveBeenCalled()
|
||||
|
||||
describe "keymap loading", ->
|
||||
describe "when the metadata does not contain a 'keymaps' manifest", ->
|
||||
it "loads all the .cson/.json files in the keymaps directory", ->
|
||||
element1 = $$ -> @div class: 'test-1'
|
||||
element2 = $$ -> @div class: 'test-2'
|
||||
element3 = $$ -> @div class: 'test-3'
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])).toHaveLength 0
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])).toHaveLength 0
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
|
||||
|
||||
atom.packages.activatePackage("package-with-keymaps")
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe "test-1"
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])[0].command).toBe "test-2"
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
|
||||
|
||||
describe "when the metadata contains a 'keymaps' manifest", ->
|
||||
it "loads only the keymaps specified by the manifest, in the specified order", ->
|
||||
element1 = $$ -> @div class: 'test-1'
|
||||
element3 = $$ -> @div class: 'test-3'
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])).toHaveLength 0
|
||||
|
||||
atom.packages.activatePackage("package-with-keymaps-manifest")
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe 'keymap-1'
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-n', target:element1[0])[0].command).toBe 'keymap-2'
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-y', target:element3[0])).toHaveLength 0
|
||||
|
||||
describe "menu loading", ->
|
||||
beforeEach ->
|
||||
atom.contextMenu.definitions = []
|
||||
atom.menu.template = []
|
||||
|
||||
describe "when the metadata does not contain a 'menus' manifest", ->
|
||||
it "loads all the .cson/.json files in the menus directory", ->
|
||||
element = ($$ -> @div class: 'test-1')[0]
|
||||
|
||||
expect(atom.contextMenu.definitionsForElement(element)).toEqual []
|
||||
|
||||
atom.packages.activatePackage("package-with-menus")
|
||||
|
||||
expect(atom.menu.template.length).toBe 2
|
||||
expect(atom.menu.template[0].label).toBe "Second to Last"
|
||||
expect(atom.menu.template[1].label).toBe "Last"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[0].label).toBe "Menu item 1"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[1].label).toBe "Menu item 2"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[2].label).toBe "Menu item 3"
|
||||
|
||||
describe "when the metadata contains a 'menus' manifest", ->
|
||||
it "loads only the menus specified by the manifest, in the specified order", ->
|
||||
element = ($$ -> @div class: 'test-1')[0]
|
||||
|
||||
expect(atom.contextMenu.definitionsForElement(element)).toEqual []
|
||||
|
||||
atom.packages.activatePackage("package-with-menus-manifest")
|
||||
|
||||
expect(atom.menu.template[0].label).toBe "Second to Last"
|
||||
expect(atom.menu.template[1].label).toBe "Last"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[0].label).toBe "Menu item 2"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[1].label).toBe "Menu item 1"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[2]).toBeUndefined()
|
||||
|
||||
describe "stylesheet loading", ->
|
||||
describe "when the metadata contains a 'stylesheets' manifest", ->
|
||||
it "loads stylesheets from the stylesheets directory as specified by the manifest", ->
|
||||
one = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css")
|
||||
two = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less")
|
||||
three = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css")
|
||||
|
||||
one = atom.themes.stringToId(one)
|
||||
two = atom.themes.stringToId(two)
|
||||
three = atom.themes.stringToId(three)
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
|
||||
atom.packages.activatePackage("package-with-stylesheets-manifest")
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
expect($('#jasmine-content').css('font-size')).toBe '1px'
|
||||
|
||||
describe "when the metadata does not contain a 'stylesheets' manifest", ->
|
||||
it "loads all stylesheets from the stylesheets directory", ->
|
||||
one = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/1.css")
|
||||
two = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/2.less")
|
||||
three = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/3.css")
|
||||
|
||||
|
||||
one = atom.themes.stringToId(one)
|
||||
two = atom.themes.stringToId(two)
|
||||
three = atom.themes.stringToId(three)
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
|
||||
atom.packages.activatePackage("package-with-stylesheets")
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toBeNull()
|
||||
expect($('#jasmine-content').css('font-size')).toBe '3px'
|
||||
|
||||
describe "grammar loading", ->
|
||||
it "loads the package's grammars", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-grammars')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Alot'
|
||||
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Alittle'
|
||||
|
||||
describe "scoped-property loading", ->
|
||||
it "loads the scoped properties", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-scoped-properties")
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
|
||||
|
||||
describe "converted textmate packages", ->
|
||||
it "loads the package's grammars", ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
|
||||
it "loads the translated scoped properties", ->
|
||||
expect(atom.syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBe '# '
|
||||
|
||||
describe ".deactivatePackage(id)", ->
|
||||
describe "atom packages", ->
|
||||
it "calls `deactivate` on the package's main module if activate was successful", ->
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-deactivate").then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(atom.packages.isPackageActive("package-with-deactivate")).toBeTruthy()
|
||||
spyOn(pack.mainModule, 'deactivate').andCallThrough()
|
||||
|
||||
atom.packages.deactivatePackage("package-with-deactivate")
|
||||
expect(pack.mainModule.deactivate).toHaveBeenCalled()
|
||||
expect(atom.packages.isPackageActive("package-with-module")).toBeFalsy()
|
||||
|
||||
spyOn(console, 'warn')
|
||||
|
||||
badPack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-that-throws-on-activate").then (p) -> badPack = p
|
||||
|
||||
runs ->
|
||||
expect(atom.packages.isPackageActive("package-that-throws-on-activate")).toBeTruthy()
|
||||
spyOn(badPack.mainModule, 'deactivate').andCallThrough()
|
||||
|
||||
atom.packages.deactivatePackage("package-that-throws-on-activate")
|
||||
expect(badPack.mainModule.deactivate).not.toHaveBeenCalled()
|
||||
expect(atom.packages.isPackageActive("package-that-throws-on-activate")).toBeFalsy()
|
||||
|
||||
it "does not serialize packages that have not been activated called on their main module", ->
|
||||
spyOn(console, 'warn')
|
||||
badPack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-that-throws-on-activate").then (p) -> badPack = p
|
||||
|
||||
runs ->
|
||||
spyOn(badPack.mainModule, 'serialize').andCallThrough()
|
||||
|
||||
atom.packages.deactivatePackage("package-that-throws-on-activate")
|
||||
expect(badPack.mainModule.serialize).not.toHaveBeenCalled()
|
||||
|
||||
it "absorbs exceptions that are thrown by the package module's serialize method", ->
|
||||
spyOn(console, 'error')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-serialize-error')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-serialization')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackages()
|
||||
expect(atom.packages.packageStates['package-with-serialize-error']).toBeUndefined()
|
||||
expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
|
||||
it "absorbs exceptions that are thrown by the package module's deactivate method", ->
|
||||
spyOn(console, 'error')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-that-throws-on-deactivate")
|
||||
|
||||
runs ->
|
||||
expect(-> atom.packages.deactivatePackage("package-that-throws-on-deactivate")).not.toThrow()
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
|
||||
it "removes the package's grammars", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-grammars')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackage('package-with-grammars')
|
||||
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Null Grammar'
|
||||
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Null Grammar'
|
||||
|
||||
it "removes the package's keymaps", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-keymaps')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackage('package-with-keymaps')
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target: ($$ -> @div class: 'test-1')[0])).toHaveLength 0
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target: ($$ -> @div class: 'test-2')[0])).toHaveLength 0
|
||||
|
||||
it "removes the package's stylesheets", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-stylesheets')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackage('package-with-stylesheets')
|
||||
one = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css")
|
||||
two = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less")
|
||||
three = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css")
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
|
||||
|
||||
it "removes the package's scoped-properties", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-scoped-properties")
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
|
||||
atom.packages.deactivatePackage("package-with-scoped-properties")
|
||||
expect(atom.syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBeUndefined()
|
||||
|
||||
describe "textmate packages", ->
|
||||
it "removes the package's grammars", ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
atom.packages.deactivatePackage('language-ruby')
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
it "removes the package's scoped properties", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackage('language-ruby')
|
||||
expect(atom.syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
|
||||
|
||||
describe ".activate()", ->
|
||||
packageActivator = null
|
||||
themeActivator = null
|
||||
|
||||
beforeEach ->
|
||||
spyOn(console, 'warn')
|
||||
atom.packages.loadPackages()
|
||||
|
||||
loadedPackages = atom.packages.getLoadedPackages()
|
||||
expect(loadedPackages.length).toBeGreaterThan 0
|
||||
|
||||
packageActivator = spyOn(atom.packages, 'activatePackages')
|
||||
themeActivator = spyOn(atom.themes, 'activatePackages')
|
||||
|
||||
afterEach ->
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
Syntax = require '../src/syntax'
|
||||
atom.syntax = window.syntax = new Syntax()
|
||||
|
||||
it "activates all the packages, and none of the themes", ->
|
||||
atom.packages.activate()
|
||||
|
||||
expect(packageActivator).toHaveBeenCalled()
|
||||
expect(themeActivator).toHaveBeenCalled()
|
||||
|
||||
packages = packageActivator.mostRecentCall.args[0]
|
||||
expect(['atom', 'textmate']).toContain(pack.getType()) for pack in packages
|
||||
|
||||
themes = themeActivator.mostRecentCall.args[0]
|
||||
expect(['theme']).toContain(theme.getType()) for theme in themes
|
||||
|
||||
describe ".enablePackage() and disablePackage()", ->
|
||||
describe "with packages", ->
|
||||
it ".enablePackage() enables a disabled package", ->
|
||||
packageName = 'package-with-main'
|
||||
atom.config.pushAtKeyPath('core.disabledPackages', packageName)
|
||||
atom.packages.observeDisabledPackages()
|
||||
expect(atom.config.get('core.disabledPackages')).toContain packageName
|
||||
|
||||
pack = atom.packages.enablePackage(packageName)
|
||||
loadedPackages = atom.packages.getLoadedPackages()
|
||||
activatedPackages = null
|
||||
waitsFor ->
|
||||
activatedPackages = atom.packages.getActivePackages()
|
||||
activatedPackages.length > 0
|
||||
|
||||
runs ->
|
||||
expect(loadedPackages).toContain(pack)
|
||||
expect(activatedPackages).toContain(pack)
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
it ".disablePackage() disables an enabled package", ->
|
||||
packageName = 'package-with-main'
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage(packageName)
|
||||
|
||||
runs ->
|
||||
atom.packages.observeDisabledPackages()
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
pack = atom.packages.disablePackage(packageName)
|
||||
|
||||
activatedPackages = atom.packages.getActivePackages()
|
||||
expect(activatedPackages).not.toContain(pack)
|
||||
expect(atom.config.get('core.disabledPackages')).toContain packageName
|
||||
|
||||
describe "with themes", ->
|
||||
reloadedHandler = null
|
||||
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
atom.themes.activateThemes()
|
||||
|
||||
afterEach ->
|
||||
atom.themes.deactivateThemes()
|
||||
|
||||
it ".enablePackage() and .disablePackage() enables and disables a theme", ->
|
||||
packageName = 'theme-with-package-file'
|
||||
|
||||
expect(atom.config.get('core.themes')).not.toContain packageName
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
# enabling of theme
|
||||
pack = atom.packages.enablePackage(packageName)
|
||||
|
||||
waitsFor ->
|
||||
pack in atom.packages.getActivePackages()
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get('core.themes')).toContain packageName
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
reloadedHandler = jasmine.createSpy('reloadedHandler')
|
||||
reloadedHandler.reset()
|
||||
atom.themes.onDidReloadAll reloadedHandler
|
||||
|
||||
pack = atom.packages.disablePackage(packageName)
|
||||
|
||||
waitsFor ->
|
||||
reloadedHandler.callCount is 1
|
||||
|
||||
runs ->
|
||||
expect(atom.packages.getActivePackages()).not.toContain pack
|
||||
expect(atom.config.get('core.themes')).not.toContain packageName
|
||||
expect(atom.config.get('core.themes')).not.toContain packageName
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
describe ".isReleasedVersion()", ->
|
||||
it "returns false if the version is a SHA and true otherwise", ->
|
||||
version = '0.1.0'
|
||||
|
||||
@@ -66,8 +66,11 @@ describe "CommandRegistry", ->
|
||||
registry.add '.child', 'command', -> calls.push('child-2')
|
||||
registry.add '.child', 'command', (event) -> calls.push('child-1'); event.stopPropagation()
|
||||
|
||||
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
|
||||
dispatchedEvent = new CustomEvent('command', bubbles: true)
|
||||
spyOn(dispatchedEvent, 'stopPropagation')
|
||||
grandchild.dispatchEvent(dispatchedEvent)
|
||||
expect(calls).toEqual ['child-1', 'child-2']
|
||||
expect(dispatchedEvent.stopPropagation).toHaveBeenCalled()
|
||||
|
||||
it "stops invoking callbacks when .stopImmediatePropagation() is called on the event", ->
|
||||
calls = []
|
||||
@@ -76,8 +79,21 @@ describe "CommandRegistry", ->
|
||||
registry.add '.child', 'command', -> calls.push('child-2')
|
||||
registry.add '.child', 'command', (event) -> calls.push('child-1'); event.stopImmediatePropagation()
|
||||
|
||||
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
|
||||
dispatchedEvent = new CustomEvent('command', bubbles: true)
|
||||
spyOn(dispatchedEvent, 'stopImmediatePropagation')
|
||||
grandchild.dispatchEvent(dispatchedEvent)
|
||||
expect(calls).toEqual ['child-1']
|
||||
expect(dispatchedEvent.stopImmediatePropagation).toHaveBeenCalled()
|
||||
|
||||
it "forwards .preventDefault() calls from the synthetic event to the original", ->
|
||||
calls = []
|
||||
|
||||
registry.add '.child', 'command', (event) -> event.preventDefault()
|
||||
|
||||
dispatchedEvent = new CustomEvent('command', bubbles: true)
|
||||
spyOn(dispatchedEvent, 'preventDefault')
|
||||
grandchild.dispatchEvent(dispatchedEvent)
|
||||
expect(dispatchedEvent.preventDefault).toHaveBeenCalled()
|
||||
|
||||
it "allows listeners to be removed via a disposable returned by ::add", ->
|
||||
calls = []
|
||||
@@ -124,3 +140,52 @@ describe "CommandRegistry", ->
|
||||
{name: 'namespace:command-2', displayName: 'Namespace: Command 2'}
|
||||
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
|
||||
]
|
||||
|
||||
describe "::dispatch(target, commandName)", ->
|
||||
it "simulates invocation of the given command ", ->
|
||||
called = false
|
||||
registry.add '.grandchild', 'command', (event) ->
|
||||
expect(this).toBe grandchild
|
||||
expect(event.type).toBe 'command'
|
||||
expect(event.eventPhase).toBe Event.BUBBLING_PHASE
|
||||
expect(event.target).toBe grandchild
|
||||
expect(event.currentTarget).toBe grandchild
|
||||
called = true
|
||||
|
||||
registry.dispatch(grandchild, 'command')
|
||||
expect(called).toBe true
|
||||
|
||||
it "returns a boolean indicating whether any listeners matched the command", ->
|
||||
registry.add '.grandchild', 'command', ->
|
||||
|
||||
expect(registry.dispatch(grandchild, 'command')).toBe true
|
||||
expect(registry.dispatch(grandchild, 'bogus')).toBe false
|
||||
expect(registry.dispatch(parent, 'command')).toBe false
|
||||
|
||||
describe "::getSnapshot and ::restoreSnapshot", ->
|
||||
it "removes all command handlers except for those in the snapshot", ->
|
||||
registry.add '.parent', 'namespace:command-1', ->
|
||||
registry.add '.child', 'namespace:command-2', ->
|
||||
snapshot = registry.getSnapshot()
|
||||
registry.add '.grandchild', 'namespace:command-3', ->
|
||||
|
||||
expect(registry.findCommands(target: grandchild)[0..2]).toEqual [
|
||||
{name: 'namespace:command-3', displayName: 'Namespace: Command 3'}
|
||||
{name: 'namespace:command-2', displayName: 'Namespace: Command 2'}
|
||||
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
|
||||
]
|
||||
|
||||
registry.restoreSnapshot(snapshot)
|
||||
|
||||
expect(registry.findCommands(target: grandchild)[0..1]).toEqual [
|
||||
{name: 'namespace:command-2', displayName: 'Namespace: Command 2'}
|
||||
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
|
||||
]
|
||||
|
||||
registry.add '.grandchild', 'namespace:command-3', ->
|
||||
registry.restoreSnapshot(snapshot)
|
||||
|
||||
expect(registry.findCommands(target: grandchild)[0..1]).toEqual [
|
||||
{name: 'namespace:command-2', displayName: 'Namespace: Command 2'}
|
||||
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
|
||||
]
|
||||
|
||||
@@ -1100,6 +1100,33 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.setScrollTop(maxScrollTop + 50)).toBe maxScrollTop
|
||||
expect(displayBuffer.getScrollTop()).toBe maxScrollTop
|
||||
|
||||
describe "editor.scrollPastEnd", ->
|
||||
describe "when editor.scrollPastEnd is false", ->
|
||||
beforeEach ->
|
||||
atom.config.set("editor.scrollPastEnd", false)
|
||||
displayBuffer.manageScrollPosition = true
|
||||
displayBuffer.setLineHeightInPixels(10)
|
||||
|
||||
it "does not add the height of the view to the scroll height", ->
|
||||
lineHeight = displayBuffer.getLineHeightInPixels()
|
||||
originalScrollHeight = displayBuffer.getScrollHeight()
|
||||
displayBuffer.setHeight(50)
|
||||
|
||||
expect(displayBuffer.getScrollHeight()).toBe originalScrollHeight
|
||||
|
||||
describe "when editor.scrollPastEnd is true", ->
|
||||
beforeEach ->
|
||||
atom.config.set("editor.scrollPastEnd", true)
|
||||
displayBuffer.manageScrollPosition = true
|
||||
displayBuffer.setLineHeightInPixels(10)
|
||||
|
||||
it "adds the height of the view to the scroll height", ->
|
||||
lineHeight = displayBuffer.getLineHeightInPixels()
|
||||
originalScrollHeight = displayBuffer.getScrollHeight()
|
||||
displayBuffer.setHeight(50)
|
||||
|
||||
expect(displayBuffer.getScrollHeight()).toEqual(originalScrollHeight + displayBuffer.height - (lineHeight * 3))
|
||||
|
||||
describe "::setScrollLeft", ->
|
||||
beforeEach ->
|
||||
displayBuffer.manageScrollPosition = true
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
module.exports =
|
||||
activateCallCount: 0
|
||||
activationCommandCallCount: 0
|
||||
legacyActivationCommandCallCount: 0
|
||||
|
||||
activate: ->
|
||||
@activateCallCount++
|
||||
|
||||
atom.commands.add '.workspace', 'activation-command', =>
|
||||
@activationCommandCallCount++
|
||||
|
||||
atom.workspaceView.getActiveView()?.command 'activation-command', =>
|
||||
@legacyActivationCommandCallCount++
|
||||
@@ -0,0 +1,2 @@
|
||||
'activationCommands':
|
||||
'.workspace': 'activation-command'
|
||||
@@ -1,13 +0,0 @@
|
||||
class Foo
|
||||
atom.deserializers.add(this)
|
||||
@deserialize: ({data}) -> new Foo(data)
|
||||
constructor: (@data) ->
|
||||
|
||||
module.exports =
|
||||
activateCallCount: 0
|
||||
activationEventCallCount: 0
|
||||
|
||||
activate: ->
|
||||
@activateCallCount++
|
||||
atom.workspaceView.getActiveView()?.command 'activation-event', =>
|
||||
@activationEventCallCount++
|
||||
@@ -1 +0,0 @@
|
||||
'activationEvents': ['activation-event']
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "no events",
|
||||
"version": "0.1.0",
|
||||
"activationEvents": []
|
||||
"activationCommands": {".workspace": []}
|
||||
}
|
||||
@@ -14,6 +14,10 @@ describe "LanguageMode", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-javascript')
|
||||
|
||||
afterEach ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
describe ".minIndentLevelForRowRange(startRow, endRow)", ->
|
||||
it "returns the minimum indent level for the given row range", ->
|
||||
expect(languageMode.minIndentLevelForRowRange(4, 7)).toBe 2
|
||||
@@ -149,6 +153,10 @@ describe "LanguageMode", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-coffee-script')
|
||||
|
||||
afterEach ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
describe ".toggleLineCommentsForBufferRows(start, end)", ->
|
||||
it "comments/uncomments lines in the given range", ->
|
||||
languageMode.toggleLineCommentsForBufferRows(4, 6)
|
||||
@@ -200,6 +208,10 @@ describe "LanguageMode", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-css')
|
||||
|
||||
afterEach ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
describe ".toggleLineCommentsForBufferRows(start, end)", ->
|
||||
it "comments/uncomments lines in the given range", ->
|
||||
languageMode.toggleLineCommentsForBufferRows(0, 1)
|
||||
@@ -248,6 +260,10 @@ describe "LanguageMode", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-css')
|
||||
|
||||
afterEach ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
describe "when commenting lines", ->
|
||||
it "only uses the `commentEnd` pattern if it comes from the same grammar as the `commentStart`", ->
|
||||
languageMode.toggleLineCommentsForBufferRows(0, 0)
|
||||
@@ -264,6 +280,10 @@ describe "LanguageMode", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-xml')
|
||||
|
||||
afterEach ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
describe "when uncommenting lines", ->
|
||||
it "removes the leading whitespace from the comment end pattern match", ->
|
||||
languageMode.toggleLineCommentsForBufferRows(0, 0)
|
||||
@@ -279,6 +299,10 @@ describe "LanguageMode", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-javascript')
|
||||
|
||||
afterEach ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
it "maintains cursor buffer position when a folding/unfolding", ->
|
||||
editor.setCursorBufferPosition([5,5])
|
||||
languageMode.foldAll()
|
||||
@@ -366,6 +390,10 @@ describe "LanguageMode", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-javascript')
|
||||
|
||||
afterEach ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
describe ".unfoldAll()", ->
|
||||
it "unfolds every folded line", ->
|
||||
initialScreenLineCount = editor.getScreenLineCount()
|
||||
@@ -435,6 +463,10 @@ describe "LanguageMode", ->
|
||||
atom.packages.activatePackage('language-source')
|
||||
atom.packages.activatePackage('language-css')
|
||||
|
||||
afterEach ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
describe "suggestedIndentForBufferRow", ->
|
||||
it "does not return negative values (regression)", ->
|
||||
editor.setText('.test {\npadding: 0;\n}')
|
||||
|
||||
@@ -0,0 +1,556 @@
|
||||
{$, $$, WorkspaceView} = require 'atom'
|
||||
Package = require '../src/package'
|
||||
|
||||
describe "PackageManager", ->
|
||||
beforeEach ->
|
||||
atom.workspaceView = new WorkspaceView
|
||||
|
||||
describe "::loadPackage(name)", ->
|
||||
it "continues if the package has an invalid package.json", ->
|
||||
spyOn(console, 'warn')
|
||||
atom.config.set("core.disabledPackages", [])
|
||||
expect(-> atom.packages.loadPackage("package-with-broken-package-json")).not.toThrow()
|
||||
|
||||
it "continues if the package has an invalid keymap", ->
|
||||
spyOn(console, 'warn')
|
||||
atom.config.set("core.disabledPackages", [])
|
||||
expect(-> atom.packages.loadPackage("package-with-broken-keymap")).not.toThrow()
|
||||
|
||||
describe "::unloadPackage(name)", ->
|
||||
describe "when the package is active", ->
|
||||
it "throws an error", ->
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-main').then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(atom.packages.isPackageLoaded(pack.name)).toBeTruthy()
|
||||
expect(atom.packages.isPackageActive(pack.name)).toBeTruthy()
|
||||
expect( -> atom.packages.unloadPackage(pack.name)).toThrow()
|
||||
expect(atom.packages.isPackageLoaded(pack.name)).toBeTruthy()
|
||||
expect(atom.packages.isPackageActive(pack.name)).toBeTruthy()
|
||||
|
||||
describe "when the package is not loaded", ->
|
||||
it "throws an error", ->
|
||||
expect(atom.packages.isPackageLoaded('unloaded')).toBeFalsy()
|
||||
expect( -> atom.packages.unloadPackage('unloaded')).toThrow()
|
||||
expect(atom.packages.isPackageLoaded('unloaded')).toBeFalsy()
|
||||
|
||||
describe "when the package is loaded", ->
|
||||
it "no longers reports it as being loaded", ->
|
||||
pack = atom.packages.loadPackage('package-with-main')
|
||||
expect(atom.packages.isPackageLoaded(pack.name)).toBeTruthy()
|
||||
atom.packages.unloadPackage(pack.name)
|
||||
expect(atom.packages.isPackageLoaded(pack.name)).toBeFalsy()
|
||||
|
||||
describe "::activatePackage(id)", ->
|
||||
describe "atom packages", ->
|
||||
describe "when called multiple times", ->
|
||||
it "it only calls activate on the package once", ->
|
||||
spyOn(Package.prototype, 'activateNow').andCallThrough()
|
||||
atom.packages.activatePackage('package-with-index')
|
||||
atom.packages.activatePackage('package-with-index')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-index')
|
||||
|
||||
runs ->
|
||||
expect(Package.prototype.activateNow.callCount).toBe 1
|
||||
|
||||
describe "when the package has a main module", ->
|
||||
describe "when the metadata specifies a main module path˜", ->
|
||||
it "requires the module at the specified path", ->
|
||||
mainModule = require('./fixtures/packages/package-with-main/main-module')
|
||||
spyOn(mainModule, 'activate')
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-main').then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(mainModule.activate).toHaveBeenCalled()
|
||||
expect(pack.mainModule).toBe mainModule
|
||||
|
||||
describe "when the metadata does not specify a main module", ->
|
||||
it "requires index.coffee", ->
|
||||
indexModule = require('./fixtures/packages/package-with-index/index')
|
||||
spyOn(indexModule, 'activate')
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-index').then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(indexModule.activate).toHaveBeenCalled()
|
||||
expect(pack.mainModule).toBe indexModule
|
||||
|
||||
it "assigns config defaults from the module", ->
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBeUndefined()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-config-defaults')
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBe 1
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.two')).toBe 2
|
||||
|
||||
describe "when the package metadata includes `activationCommands`", ->
|
||||
[mainModule, promise, workspaceCommandListener] = []
|
||||
|
||||
beforeEach ->
|
||||
atom.workspaceView.attachToDom()
|
||||
mainModule = require './fixtures/packages/package-with-activation-commands/index'
|
||||
mainModule.legacyActivationCommandCallCount = 0
|
||||
mainModule.activationCommandCallCount = 0
|
||||
spyOn(mainModule, 'activate').andCallThrough()
|
||||
spyOn(Package.prototype, 'requireMainModule').andCallThrough()
|
||||
|
||||
workspaceCommandListener = jasmine.createSpy('workspaceCommandListener')
|
||||
atom.commands.add '.workspace', 'activation-command', workspaceCommandListener
|
||||
|
||||
promise = atom.packages.activatePackage('package-with-activation-commands')
|
||||
|
||||
it "defers requiring/activating the main module until an activation event bubbles to the root view", ->
|
||||
expect(promise.isFulfilled()).not.toBeTruthy()
|
||||
atom.workspaceView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
|
||||
|
||||
waitsForPromise ->
|
||||
promise
|
||||
|
||||
it "triggers the activation event on all handlers registered during activation", ->
|
||||
waitsForPromise ->
|
||||
atom.workspaceView.open()
|
||||
|
||||
runs ->
|
||||
editorView = atom.workspaceView.getActiveView()
|
||||
legacyCommandListener = jasmine.createSpy("legacyCommandListener")
|
||||
editorView.command 'activation-command', legacyCommandListener
|
||||
editorCommandListener = jasmine.createSpy("editorCommandListener")
|
||||
atom.commands.add '.editor', 'activation-command', editorCommandListener
|
||||
editorView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
|
||||
expect(mainModule.activate.callCount).toBe 1
|
||||
expect(mainModule.legacyActivationCommandCallCount).toBe 1
|
||||
expect(mainModule.activationCommandCallCount).toBe 1
|
||||
expect(legacyCommandListener.callCount).toBe 1
|
||||
expect(editorCommandListener.callCount).toBe 1
|
||||
expect(workspaceCommandListener.callCount).toBe 1
|
||||
editorView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
|
||||
expect(mainModule.legacyActivationCommandCallCount).toBe 2
|
||||
expect(mainModule.activationCommandCallCount).toBe 2
|
||||
expect(legacyCommandListener.callCount).toBe 2
|
||||
expect(editorCommandListener.callCount).toBe 2
|
||||
expect(workspaceCommandListener.callCount).toBe 2
|
||||
expect(mainModule.activate.callCount).toBe 1
|
||||
|
||||
it "activates the package immediately when the events are empty", ->
|
||||
mainModule = require './fixtures/packages/package-with-empty-activation-commands/index'
|
||||
spyOn(mainModule, 'activate').andCallThrough()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-empty-activation-commands')
|
||||
|
||||
runs ->
|
||||
expect(mainModule.activate.callCount).toBe 1
|
||||
|
||||
describe "when the package has no main module", ->
|
||||
it "does not throw an exception", ->
|
||||
spyOn(console, "error")
|
||||
spyOn(console, "warn").andCallThrough()
|
||||
expect(-> atom.packages.activatePackage('package-without-module')).not.toThrow()
|
||||
expect(console.error).not.toHaveBeenCalled()
|
||||
expect(console.warn).not.toHaveBeenCalled()
|
||||
|
||||
it "passes the activate method the package's previously serialized state if it exists", ->
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-serialization").then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(pack.mainModule.someNumber).not.toBe 77
|
||||
pack.mainModule.someNumber = 77
|
||||
atom.packages.deactivatePackage("package-with-serialization")
|
||||
spyOn(pack.mainModule, 'activate').andCallThrough()
|
||||
atom.packages.activatePackage("package-with-serialization")
|
||||
expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77})
|
||||
|
||||
it "logs warning instead of throwing an exception if the package fails to load", ->
|
||||
atom.config.set("core.disabledPackages", [])
|
||||
spyOn(console, "warn")
|
||||
expect(-> atom.packages.activatePackage("package-that-throws-an-exception")).not.toThrow()
|
||||
expect(console.warn).toHaveBeenCalled()
|
||||
|
||||
describe "keymap loading", ->
|
||||
describe "when the metadata does not contain a 'keymaps' manifest", ->
|
||||
it "loads all the .cson/.json files in the keymaps directory", ->
|
||||
element1 = $$ -> @div class: 'test-1'
|
||||
element2 = $$ -> @div class: 'test-2'
|
||||
element3 = $$ -> @div class: 'test-3'
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])).toHaveLength 0
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])).toHaveLength 0
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
|
||||
|
||||
atom.packages.activatePackage("package-with-keymaps")
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe "test-1"
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])[0].command).toBe "test-2"
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
|
||||
|
||||
describe "when the metadata contains a 'keymaps' manifest", ->
|
||||
it "loads only the keymaps specified by the manifest, in the specified order", ->
|
||||
element1 = $$ -> @div class: 'test-1'
|
||||
element3 = $$ -> @div class: 'test-3'
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])).toHaveLength 0
|
||||
|
||||
atom.packages.activatePackage("package-with-keymaps-manifest")
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe 'keymap-1'
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-n', target:element1[0])[0].command).toBe 'keymap-2'
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-y', target:element3[0])).toHaveLength 0
|
||||
|
||||
describe "menu loading", ->
|
||||
beforeEach ->
|
||||
atom.contextMenu.definitions = []
|
||||
atom.menu.template = []
|
||||
|
||||
describe "when the metadata does not contain a 'menus' manifest", ->
|
||||
it "loads all the .cson/.json files in the menus directory", ->
|
||||
element = ($$ -> @div class: 'test-1')[0]
|
||||
|
||||
expect(atom.contextMenu.definitionsForElement(element)).toEqual []
|
||||
|
||||
atom.packages.activatePackage("package-with-menus")
|
||||
|
||||
expect(atom.menu.template.length).toBe 2
|
||||
expect(atom.menu.template[0].label).toBe "Second to Last"
|
||||
expect(atom.menu.template[1].label).toBe "Last"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[0].label).toBe "Menu item 1"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[1].label).toBe "Menu item 2"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[2].label).toBe "Menu item 3"
|
||||
|
||||
describe "when the metadata contains a 'menus' manifest", ->
|
||||
it "loads only the menus specified by the manifest, in the specified order", ->
|
||||
element = ($$ -> @div class: 'test-1')[0]
|
||||
|
||||
expect(atom.contextMenu.definitionsForElement(element)).toEqual []
|
||||
|
||||
atom.packages.activatePackage("package-with-menus-manifest")
|
||||
|
||||
expect(atom.menu.template[0].label).toBe "Second to Last"
|
||||
expect(atom.menu.template[1].label).toBe "Last"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[0].label).toBe "Menu item 2"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[1].label).toBe "Menu item 1"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[2]).toBeUndefined()
|
||||
|
||||
describe "stylesheet loading", ->
|
||||
describe "when the metadata contains a 'stylesheets' manifest", ->
|
||||
it "loads stylesheets from the stylesheets directory as specified by the manifest", ->
|
||||
one = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css")
|
||||
two = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less")
|
||||
three = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css")
|
||||
|
||||
one = atom.themes.stringToId(one)
|
||||
two = atom.themes.stringToId(two)
|
||||
three = atom.themes.stringToId(three)
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
|
||||
atom.packages.activatePackage("package-with-stylesheets-manifest")
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
expect($('#jasmine-content').css('font-size')).toBe '1px'
|
||||
|
||||
describe "when the metadata does not contain a 'stylesheets' manifest", ->
|
||||
it "loads all stylesheets from the stylesheets directory", ->
|
||||
one = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/1.css")
|
||||
two = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/2.less")
|
||||
three = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/3.css")
|
||||
|
||||
|
||||
one = atom.themes.stringToId(one)
|
||||
two = atom.themes.stringToId(two)
|
||||
three = atom.themes.stringToId(three)
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
|
||||
atom.packages.activatePackage("package-with-stylesheets")
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toBeNull()
|
||||
expect($('#jasmine-content').css('font-size')).toBe '3px'
|
||||
|
||||
describe "grammar loading", ->
|
||||
it "loads the package's grammars", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-grammars')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Alot'
|
||||
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Alittle'
|
||||
|
||||
describe "scoped-property loading", ->
|
||||
it "loads the scoped properties", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-scoped-properties")
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
|
||||
|
||||
describe "converted textmate packages", ->
|
||||
it "loads the package's grammars", ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
|
||||
it "loads the translated scoped properties", ->
|
||||
expect(atom.syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBe '# '
|
||||
|
||||
describe "::deactivatePackage(id)", ->
|
||||
describe "atom packages", ->
|
||||
it "calls `deactivate` on the package's main module if activate was successful", ->
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-deactivate").then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(atom.packages.isPackageActive("package-with-deactivate")).toBeTruthy()
|
||||
spyOn(pack.mainModule, 'deactivate').andCallThrough()
|
||||
|
||||
atom.packages.deactivatePackage("package-with-deactivate")
|
||||
expect(pack.mainModule.deactivate).toHaveBeenCalled()
|
||||
expect(atom.packages.isPackageActive("package-with-module")).toBeFalsy()
|
||||
|
||||
spyOn(console, 'warn')
|
||||
|
||||
badPack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-that-throws-on-activate").then (p) -> badPack = p
|
||||
|
||||
runs ->
|
||||
expect(atom.packages.isPackageActive("package-that-throws-on-activate")).toBeTruthy()
|
||||
spyOn(badPack.mainModule, 'deactivate').andCallThrough()
|
||||
|
||||
atom.packages.deactivatePackage("package-that-throws-on-activate")
|
||||
expect(badPack.mainModule.deactivate).not.toHaveBeenCalled()
|
||||
expect(atom.packages.isPackageActive("package-that-throws-on-activate")).toBeFalsy()
|
||||
|
||||
it "does not serialize packages that have not been activated called on their main module", ->
|
||||
spyOn(console, 'warn')
|
||||
badPack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-that-throws-on-activate").then (p) -> badPack = p
|
||||
|
||||
runs ->
|
||||
spyOn(badPack.mainModule, 'serialize').andCallThrough()
|
||||
|
||||
atom.packages.deactivatePackage("package-that-throws-on-activate")
|
||||
expect(badPack.mainModule.serialize).not.toHaveBeenCalled()
|
||||
|
||||
it "absorbs exceptions that are thrown by the package module's serialize method", ->
|
||||
spyOn(console, 'error')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-serialize-error')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-serialization')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackages()
|
||||
expect(atom.packages.packageStates['package-with-serialize-error']).toBeUndefined()
|
||||
expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
|
||||
it "absorbs exceptions that are thrown by the package module's deactivate method", ->
|
||||
spyOn(console, 'error')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-that-throws-on-deactivate")
|
||||
|
||||
runs ->
|
||||
expect(-> atom.packages.deactivatePackage("package-that-throws-on-deactivate")).not.toThrow()
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
|
||||
it "removes the package's grammars", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-grammars')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackage('package-with-grammars')
|
||||
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Null Grammar'
|
||||
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Null Grammar'
|
||||
|
||||
it "removes the package's keymaps", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-keymaps')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackage('package-with-keymaps')
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target: ($$ -> @div class: 'test-1')[0])).toHaveLength 0
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target: ($$ -> @div class: 'test-2')[0])).toHaveLength 0
|
||||
|
||||
it "removes the package's stylesheets", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-stylesheets')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackage('package-with-stylesheets')
|
||||
one = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css")
|
||||
two = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less")
|
||||
three = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css")
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
|
||||
|
||||
it "removes the package's scoped-properties", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-scoped-properties")
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
|
||||
atom.packages.deactivatePackage("package-with-scoped-properties")
|
||||
expect(atom.syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBeUndefined()
|
||||
|
||||
describe "textmate packages", ->
|
||||
it "removes the package's grammars", ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
atom.packages.deactivatePackage('language-ruby')
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
it "removes the package's scoped properties", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackage('language-ruby')
|
||||
expect(atom.syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
|
||||
|
||||
describe "::activate()", ->
|
||||
packageActivator = null
|
||||
themeActivator = null
|
||||
|
||||
beforeEach ->
|
||||
spyOn(console, 'warn')
|
||||
atom.packages.loadPackages()
|
||||
|
||||
loadedPackages = atom.packages.getLoadedPackages()
|
||||
expect(loadedPackages.length).toBeGreaterThan 0
|
||||
|
||||
packageActivator = spyOn(atom.packages, 'activatePackages')
|
||||
themeActivator = spyOn(atom.themes, 'activatePackages')
|
||||
|
||||
afterEach ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
Syntax = require '../src/syntax'
|
||||
atom.syntax = window.syntax = new Syntax()
|
||||
|
||||
it "activates all the packages, and none of the themes", ->
|
||||
atom.packages.activate()
|
||||
|
||||
expect(packageActivator).toHaveBeenCalled()
|
||||
expect(themeActivator).toHaveBeenCalled()
|
||||
|
||||
packages = packageActivator.mostRecentCall.args[0]
|
||||
expect(['atom', 'textmate']).toContain(pack.getType()) for pack in packages
|
||||
|
||||
themes = themeActivator.mostRecentCall.args[0]
|
||||
expect(['theme']).toContain(theme.getType()) for theme in themes
|
||||
|
||||
describe "::enablePackage() and ::disablePackage()", ->
|
||||
describe "with packages", ->
|
||||
it ".enablePackage() enables a disabled package", ->
|
||||
packageName = 'package-with-main'
|
||||
atom.config.pushAtKeyPath('core.disabledPackages', packageName)
|
||||
atom.packages.observeDisabledPackages()
|
||||
expect(atom.config.get('core.disabledPackages')).toContain packageName
|
||||
|
||||
pack = atom.packages.enablePackage(packageName)
|
||||
loadedPackages = atom.packages.getLoadedPackages()
|
||||
activatedPackages = null
|
||||
waitsFor ->
|
||||
activatedPackages = atom.packages.getActivePackages()
|
||||
activatedPackages.length > 0
|
||||
|
||||
runs ->
|
||||
expect(loadedPackages).toContain(pack)
|
||||
expect(activatedPackages).toContain(pack)
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
it ".disablePackage() disables an enabled package", ->
|
||||
packageName = 'package-with-main'
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage(packageName)
|
||||
|
||||
runs ->
|
||||
atom.packages.observeDisabledPackages()
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
pack = atom.packages.disablePackage(packageName)
|
||||
|
||||
activatedPackages = atom.packages.getActivePackages()
|
||||
expect(activatedPackages).not.toContain(pack)
|
||||
expect(atom.config.get('core.disabledPackages')).toContain packageName
|
||||
|
||||
describe "with themes", ->
|
||||
reloadedHandler = null
|
||||
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
atom.themes.activateThemes()
|
||||
|
||||
afterEach ->
|
||||
atom.themes.deactivateThemes()
|
||||
|
||||
it ".enablePackage() and .disablePackage() enables and disables a theme", ->
|
||||
packageName = 'theme-with-package-file'
|
||||
|
||||
expect(atom.config.get('core.themes')).not.toContain packageName
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
# enabling of theme
|
||||
pack = atom.packages.enablePackage(packageName)
|
||||
|
||||
waitsFor ->
|
||||
pack in atom.packages.getActivePackages()
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get('core.themes')).toContain packageName
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
reloadedHandler = jasmine.createSpy('reloadedHandler')
|
||||
reloadedHandler.reset()
|
||||
atom.themes.onDidReloadAll reloadedHandler
|
||||
|
||||
pack = atom.packages.disablePackage(packageName)
|
||||
|
||||
waitsFor ->
|
||||
reloadedHandler.callCount is 1
|
||||
|
||||
runs ->
|
||||
expect(atom.packages.getActivePackages()).not.toContain pack
|
||||
expect(atom.config.get('core.themes')).not.toContain packageName
|
||||
expect(atom.config.get('core.themes')).not.toContain packageName
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
@@ -99,6 +99,13 @@ describe "Pane", ->
|
||||
pane.addItem(item, 1)
|
||||
expect(events).toEqual [{item, index: 1}]
|
||||
|
||||
it "throws an exception if the item is already present on a pane", ->
|
||||
item = new Item("A")
|
||||
pane1 = new Pane(items: [item])
|
||||
container = new PaneContainer(root: pane1)
|
||||
pane2 = pane1.splitRight()
|
||||
expect(-> pane2.addItem(item)).toThrow()
|
||||
|
||||
describe "::activateItem(item)", ->
|
||||
pane = null
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ path = require 'path'
|
||||
temp = require 'temp'
|
||||
|
||||
describe "PaneView", ->
|
||||
[container, view1, view2, editor1, editor2, pane, paneModel] = []
|
||||
[container, containerModel, view1, view2, editor1, editor2, pane, paneModel] = []
|
||||
|
||||
class TestView extends View
|
||||
@deserialize: ({id, text}) -> new TestView({id, text})
|
||||
@@ -25,6 +25,7 @@ describe "PaneView", ->
|
||||
beforeEach ->
|
||||
atom.deserializers.add(TestView)
|
||||
container = new PaneContainerView
|
||||
containerModel = container.model
|
||||
view1 = new TestView(id: 'view-1', text: 'View 1')
|
||||
view2 = new TestView(id: 'view-2', text: 'View 2')
|
||||
waitsForPromise ->
|
||||
@@ -216,7 +217,7 @@ describe "PaneView", ->
|
||||
|
||||
beforeEach ->
|
||||
pane2Model = paneModel.splitRight() # Can't destroy the last pane, so we add another
|
||||
pane2 = pane2Model._view
|
||||
pane2 = containerModel.getView(pane2Model).__spacePenView
|
||||
|
||||
it "triggers a 'pane:removed' event with the pane", ->
|
||||
removedHandler = jasmine.createSpy("removedHandler")
|
||||
@@ -249,7 +250,7 @@ describe "PaneView", ->
|
||||
|
||||
beforeEach ->
|
||||
pane2Model = paneModel.splitRight(items: [pane.copyActiveItem()])
|
||||
pane2 = pane2Model._view
|
||||
pane2 = containerModel.getView(pane2Model).__spacePenView
|
||||
expect(pane2Model.isActive()).toBe true
|
||||
|
||||
it "adds or removes the .active class as appropriate", ->
|
||||
@@ -296,7 +297,8 @@ describe "PaneView", ->
|
||||
pane2Model = pane1Model.splitRight(items: [pane1Model.copyActiveItem()])
|
||||
pane3Model = pane2Model.splitDown(items: [pane2Model.copyActiveItem()])
|
||||
pane2 = pane2Model._view
|
||||
pane3 = pane3Model._view
|
||||
pane2 = containerModel.getView(pane2Model).__spacePenView
|
||||
pane3 = containerModel.getView(pane3Model).__spacePenView
|
||||
|
||||
expect(container.find('> .pane-row > .pane').toArray()).toEqual [pane1[0]]
|
||||
expect(container.find('> .pane-row > .pane-column > .pane').toArray()).toEqual [pane2[0], pane3[0]]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{times, random} = require 'underscore-plus'
|
||||
randomWords = require 'random-words'
|
||||
TextBuffer = require 'text-buffer'
|
||||
Editor = require '../src/editor'
|
||||
TextEditor = require '../src/text-editor'
|
||||
|
||||
describe "Editor", ->
|
||||
describe "TextEditor", ->
|
||||
[editor, tokenizedBuffer, buffer, steps, previousSteps] = []
|
||||
|
||||
softWrapColumn = 80
|
||||
@@ -17,7 +17,7 @@ describe "Editor", ->
|
||||
|
||||
times 10, (i) ->
|
||||
buffer = new TextBuffer
|
||||
editor = new Editor({buffer})
|
||||
editor = new TextEditor({buffer})
|
||||
editor.setEditorWidthInChars(80)
|
||||
tokenizedBuffer = editor.displayBuffer.tokenizedBuffer
|
||||
steps = []
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Editor = require '../src/editor'
|
||||
TextEditor = require '../src/text-editor'
|
||||
|
||||
describe "Selection", ->
|
||||
[buffer, editor, selection] = []
|
||||
|
||||
beforeEach ->
|
||||
buffer = atom.project.bufferForPathSync('sample.js')
|
||||
editor = new Editor(buffer: buffer, tabLength: 2)
|
||||
editor = new TextEditor(buffer: buffer, tabLength: 2)
|
||||
selection = editor.getLastSelection()
|
||||
|
||||
afterEach ->
|
||||
|
||||
@@ -12,10 +12,10 @@ KeymapManager = require '../src/keymap-extensions'
|
||||
Config = require '../src/config'
|
||||
{Point} = require 'text-buffer'
|
||||
Project = require '../src/project'
|
||||
Editor = require '../src/editor'
|
||||
EditorView = require '../src/editor-view'
|
||||
TextEditor = require '../src/text-editor'
|
||||
TextEditorView = require '../src/text-editor-view'
|
||||
TokenizedBuffer = require '../src/tokenized-buffer'
|
||||
EditorComponent = require '../src/editor-component'
|
||||
TextEditorComponent = require '../src/text-editor-component'
|
||||
pathwatcher = require 'pathwatcher'
|
||||
clipboard = require 'clipboard'
|
||||
|
||||
@@ -27,6 +27,7 @@ fixturePackagesPath = path.resolve(__dirname, './fixtures/packages')
|
||||
atom.packages.packageDirPaths.unshift(fixturePackagesPath)
|
||||
atom.keymaps.loadBundledKeymaps()
|
||||
keyBindingsToRestore = atom.keymaps.getKeyBindings()
|
||||
commandsToRestore = atom.commands.getSnapshot()
|
||||
|
||||
$(window).on 'core:close', -> window.close()
|
||||
$(window).on 'beforeunload', ->
|
||||
@@ -65,6 +66,7 @@ beforeEach ->
|
||||
atom.workspace = new Workspace()
|
||||
atom.keymaps.keyBindings = _.clone(keyBindingsToRestore)
|
||||
atom.commands.setRootNode(document.body)
|
||||
atom.commands.restoreSnapshot(commandsToRestore)
|
||||
|
||||
window.resetTimeouts()
|
||||
atom.packages.packageStates = {}
|
||||
@@ -90,7 +92,7 @@ beforeEach ->
|
||||
spyOn(config, 'load')
|
||||
spyOn(config, 'save')
|
||||
config.setDefaults('core', WorkspaceView.configDefaults)
|
||||
config.setDefaults('editor', EditorView.configDefaults)
|
||||
config.setDefaults('editor', TextEditorView.configDefaults)
|
||||
config.set "core.destroyEmptyPanes", false
|
||||
config.set "editor.fontFamily", "Courier"
|
||||
config.set "editor.fontSize", 16
|
||||
@@ -101,14 +103,14 @@ beforeEach ->
|
||||
atom.config = config
|
||||
|
||||
# make editor display updates synchronous
|
||||
spyOn(EditorView.prototype, 'requestDisplayUpdate').andCallFake -> @updateDisplay()
|
||||
EditorComponent.performSyncUpdates = true
|
||||
spyOn(TextEditorView.prototype, 'requestDisplayUpdate').andCallFake -> @updateDisplay()
|
||||
TextEditorComponent.performSyncUpdates = true
|
||||
|
||||
spyOn(WorkspaceView.prototype, 'setTitle').andCallFake (@title) ->
|
||||
spyOn(window, "setTimeout").andCallFake window.fakeSetTimeout
|
||||
spyOn(window, "clearTimeout").andCallFake window.fakeClearTimeout
|
||||
spyOn(pathwatcher.File.prototype, "detectResurrectionAfterDelay").andCallFake -> @detectResurrection()
|
||||
spyOn(Editor.prototype, "shouldPromptToSave").andReturn false
|
||||
spyOn(TextEditor.prototype, "shouldPromptToSave").andReturn false
|
||||
|
||||
# make tokenization synchronous
|
||||
TokenizedBuffer.prototype.chunkSize = Infinity
|
||||
@@ -121,8 +123,6 @@ beforeEach ->
|
||||
addCustomMatchers(this)
|
||||
|
||||
afterEach ->
|
||||
atom.commands.clear()
|
||||
|
||||
atom.packages.deactivatePackages()
|
||||
atom.menu.template = []
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ temp = require 'temp'
|
||||
|
||||
describe "the `syntax` global", ->
|
||||
beforeEach ->
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-text')
|
||||
|
||||
@@ -17,6 +16,10 @@ describe "the `syntax` global", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
afterEach ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
describe "serialization", ->
|
||||
it "remembers grammar overrides by path", ->
|
||||
filePath = '/foo/bar/file.js'
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
_ = require 'underscore-plus'
|
||||
{extend, flatten, toArray, last} = _
|
||||
|
||||
EditorView = require '../src/editor-view'
|
||||
EditorComponent = require '../src/editor-component'
|
||||
TextEditorView = require '../src/text-editor-view'
|
||||
TextEditorComponent = require '../src/text-editor-component'
|
||||
nbsp = String.fromCharCode(160)
|
||||
|
||||
describe "EditorComponent", ->
|
||||
describe "TextEditorComponent", ->
|
||||
[contentNode, editor, wrapperView, wrapperNode, component, componentNode, verticalScrollbarNode, horizontalScrollbarNode] = []
|
||||
[lineHeightInPixels, charWidth, nextAnimationFrame, noAnimationFrame, lineOverdrawMargin] = []
|
||||
|
||||
@@ -34,7 +34,7 @@ describe "EditorComponent", ->
|
||||
contentNode = document.querySelector('#jasmine-content')
|
||||
contentNode.style.width = '1000px'
|
||||
|
||||
wrapperView = new EditorView(editor, {lineOverdrawMargin})
|
||||
wrapperView = new TextEditorView(editor, {lineOverdrawMargin})
|
||||
wrapperView.attachToDom()
|
||||
wrapperNode = wrapperView.element
|
||||
|
||||
@@ -1999,7 +1999,7 @@ describe "EditorComponent", ->
|
||||
hiddenParent.style.display = 'none'
|
||||
contentNode.appendChild(hiddenParent)
|
||||
|
||||
wrapperView = new EditorView(editor, {lineOverdrawMargin})
|
||||
wrapperView = new TextEditorView(editor, {lineOverdrawMargin})
|
||||
wrapperNode = wrapperView.element
|
||||
wrapperView.appendTo(hiddenParent)
|
||||
|
||||
@@ -2225,7 +2225,7 @@ describe "EditorComponent", ->
|
||||
|
||||
describe "when placholderText is specified", ->
|
||||
it "renders the placeholder text when the buffer is empty", ->
|
||||
component.setProps(placeholderText: 'Hello World')
|
||||
editor.setPlaceholderText('Hello World')
|
||||
expect(componentNode.querySelector('.placeholder-text')).toBeNull()
|
||||
editor.setText('')
|
||||
nextAnimationFrame()
|
||||
@@ -2259,6 +2259,11 @@ describe "EditorComponent", ->
|
||||
editor.setGrammar(atom.syntax.nullGrammar)
|
||||
expect(wrapperNode.dataset.grammar).toBe 'text plain null-grammar'
|
||||
|
||||
describe "detaching and reattaching the editor (regression)", ->
|
||||
it "does not throw an exception", ->
|
||||
wrapperView.detach()
|
||||
wrapperView.attachToDom()
|
||||
|
||||
buildMouseEvent = (type, properties...) ->
|
||||
properties = extend({bubbles: true, cancelable: true}, properties...)
|
||||
properties.detail ?= 1
|
||||
@@ -1,7 +1,7 @@
|
||||
clipboard = require 'clipboard'
|
||||
Editor = require '../src/editor'
|
||||
TextEditor = require '../src/text-editor'
|
||||
|
||||
describe "Editor", ->
|
||||
describe "TextEditor", ->
|
||||
[buffer, editor, lineLengths] = []
|
||||
|
||||
convertToHardTabs = (buffer) ->
|
||||
@@ -49,7 +49,7 @@ describe "Editor", ->
|
||||
|
||||
state = editor.serialize()
|
||||
atom.config.set('editor.invisibles', eol: '?')
|
||||
editor2 = Editor.deserialize(state)
|
||||
editor2 = TextEditor.deserialize(state)
|
||||
|
||||
expect(editor2.displayBuffer.invisibles.eol).toBe '?'
|
||||
expect(editor2.displayBuffer.tokenizedBuffer.invisibles.eol).toBe '?'
|
||||
@@ -3263,6 +3263,9 @@ describe "Editor", ->
|
||||
runs ->
|
||||
expect(editor.softTabs).toBe false
|
||||
|
||||
atom.packages.deactivatePackage('language-coffee-script')
|
||||
atom.packages.unloadPackage('language-coffee-script')
|
||||
|
||||
describe ".destroy()", ->
|
||||
it "destroys all markers associated with the edit session", ->
|
||||
expect(buffer.getMarkerCount()).toBeGreaterThan 0
|
||||
@@ -3665,3 +3668,21 @@ describe "Editor", ->
|
||||
editor.selectPageUp()
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
expect(editor.getSelectedBufferRanges()).toEqual [[[0,0], [12,2]]]
|
||||
|
||||
describe '.get/setPlaceholderText()', ->
|
||||
it 'can be created with placeholderText', ->
|
||||
TextBuffer = require 'text-buffer'
|
||||
newEditor = new TextEditor
|
||||
buffer: new TextBuffer
|
||||
mini: true
|
||||
placeholderText: 'yep'
|
||||
expect(newEditor.getPlaceholderText()).toBe 'yep'
|
||||
|
||||
it 'models placeholderText and emits an event when changed', ->
|
||||
editor.onDidChangePlaceholderText handler = jasmine.createSpy()
|
||||
|
||||
expect(editor.getPlaceholderText()).toBeUndefined()
|
||||
|
||||
editor.setPlaceholderText('OK')
|
||||
expect(handler).toHaveBeenCalledWith 'OK'
|
||||
expect(editor.getPlaceholderText()).toBe 'OK'
|
||||
@@ -209,7 +209,7 @@ describe "ThemeManager", ->
|
||||
|
||||
describe "base stylesheet loading", ->
|
||||
beforeEach ->
|
||||
atom.workspaceView = new WorkspaceView
|
||||
atom.workspaceView = atom.workspace.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView.append $$ -> @div class: 'editor'
|
||||
atom.workspaceView.attachToDom()
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
ViewRegistry = require '../src/view-registry'
|
||||
{View} = require '../src/space-pen-extensions'
|
||||
|
||||
describe "ViewRegistry", ->
|
||||
registry = null
|
||||
|
||||
beforeEach ->
|
||||
registry = new ViewRegistry
|
||||
|
||||
describe "::getView(object)", ->
|
||||
describe "when passed a DOM node", ->
|
||||
it "returns the given DOM node", ->
|
||||
node = document.createElement('div')
|
||||
expect(registry.getView(node)).toBe node
|
||||
|
||||
describe "when passed a SpacePen view", ->
|
||||
it "returns the root node of the view with a __spacePenView property pointing at the SpacePen view", ->
|
||||
class TestView extends View
|
||||
@content: -> @div "Hello"
|
||||
|
||||
view = new TestView
|
||||
node = registry.getView(view)
|
||||
expect(node.textContent).toBe "Hello"
|
||||
expect(node.__spacePenView).toBe view
|
||||
|
||||
describe "when passed a model object", ->
|
||||
describe "when a view provider is registered matching the object's constructor", ->
|
||||
describe "when the provider has a viewConstructor property", ->
|
||||
it "constructs a view element and assigns the model on it", ->
|
||||
class TestModel
|
||||
|
||||
class TestModelSubclass extends TestModel
|
||||
|
||||
class TestView
|
||||
setModel: (@model) ->
|
||||
|
||||
model = new TestModel
|
||||
|
||||
registry.addViewProvider
|
||||
modelConstructor: TestModel
|
||||
viewConstructor: TestView
|
||||
|
||||
view = registry.getView(model)
|
||||
expect(view instanceof TestView).toBe true
|
||||
expect(view.model).toBe model
|
||||
|
||||
subclassModel = new TestModelSubclass
|
||||
view2 = registry.getView(subclassModel)
|
||||
expect(view2 instanceof TestView).toBe true
|
||||
expect(view2.model).toBe subclassModel
|
||||
|
||||
describe "when the provider has a createView method", ->
|
||||
it "constructs a view element by calling the createView method with the model", ->
|
||||
class TestModel
|
||||
class TestView
|
||||
setModel: (@model) ->
|
||||
|
||||
registry.addViewProvider
|
||||
modelConstructor: TestModel
|
||||
createView: (model) ->
|
||||
view = new TestView
|
||||
view.setModel(model)
|
||||
view
|
||||
|
||||
model = new TestModel
|
||||
view = registry.getView(model)
|
||||
expect(view instanceof TestView).toBe true
|
||||
expect(view.model).toBe model
|
||||
|
||||
describe "when no view provider is registered for the object's constructor", ->
|
||||
describe "when the object has a .getViewClass() method", ->
|
||||
it "builds an instance of the view class with the model, then returns its root node with a __spacePenView property pointing at the view", ->
|
||||
class TestView extends View
|
||||
@content: (model) -> @div model.name
|
||||
initialize: (@model) ->
|
||||
|
||||
class TestModel
|
||||
constructor: (@name) ->
|
||||
getViewClass: -> TestView
|
||||
|
||||
model = new TestModel("hello")
|
||||
node = registry.getView(model)
|
||||
|
||||
expect(node.textContent).toBe "hello"
|
||||
view = node.__spacePenView
|
||||
expect(view instanceof TestView).toBe true
|
||||
expect(view.model).toBe model
|
||||
|
||||
# returns the same DOM node for repeated calls
|
||||
expect(registry.getView(model)).toBe node
|
||||
|
||||
describe "when the object has no .getViewClass() method", ->
|
||||
it "throws an exception", ->
|
||||
expect(-> registry.getView(new Object)).toThrow()
|
||||
|
||||
describe "::addViewProvider(providerSpec)", ->
|
||||
it "returns a disposable that can be used to remove the provider", ->
|
||||
class TestModel
|
||||
class TestView
|
||||
setModel: (@model) ->
|
||||
disposable = registry.addViewProvider
|
||||
modelConstructor: TestModel
|
||||
viewConstructor: TestView
|
||||
|
||||
expect(registry.getView(new TestModel) instanceof TestView).toBe true
|
||||
disposable.dispose()
|
||||
expect(-> registry.getView(new TestModel)).toThrow()
|
||||
@@ -1,6 +1,6 @@
|
||||
{$, $$} = require 'atom'
|
||||
path = require 'path'
|
||||
Editor = require '../src/editor'
|
||||
TextEditor = require '../src/text-editor'
|
||||
WindowEventHandler = require '../src/window-event-handler'
|
||||
|
||||
describe "Window", ->
|
||||
@@ -59,7 +59,7 @@ describe "Window", ->
|
||||
[beforeUnloadEvent] = []
|
||||
|
||||
beforeEach ->
|
||||
jasmine.unspy(Editor.prototype, "shouldPromptToSave")
|
||||
jasmine.unspy(TextEditor.prototype, "shouldPromptToSave")
|
||||
beforeUnloadEvent = $.Event(new Event('beforeunload'))
|
||||
|
||||
describe "when pane items are are modified", ->
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
Workspace = require '../src/workspace'
|
||||
{View} = require '../src/space-pen-extensions'
|
||||
|
||||
describe "Workspace", ->
|
||||
workspace = null
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Q = require 'q'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
EditorView = require '../src/editor-view'
|
||||
TextEditorView = require '../src/text-editor-view'
|
||||
PaneView = require '../src/pane-view'
|
||||
Workspace = require '../src/workspace'
|
||||
|
||||
@@ -13,7 +13,7 @@ describe "WorkspaceView", ->
|
||||
atom.project.setPath(atom.project.resolve('dir'))
|
||||
pathToOpen = atom.project.resolve('a')
|
||||
atom.workspace = new Workspace
|
||||
atom.workspaceView = new WorkspaceView(atom.workspace)
|
||||
atom.workspaceView = atom.workspace.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView.enableKeymap()
|
||||
atom.workspaceView.focus()
|
||||
|
||||
@@ -29,7 +29,7 @@ describe "WorkspaceView", ->
|
||||
atom.workspaceView.remove()
|
||||
atom.project = atom.deserializers.deserialize(projectState)
|
||||
atom.workspace = Workspace.deserialize(workspaceState)
|
||||
atom.workspaceView = new WorkspaceView(atom.workspace)
|
||||
atom.workspaceView = atom.workspace.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView.attachToDom()
|
||||
|
||||
describe "when the serialized WorkspaceView has an unsaved buffer", ->
|
||||
@@ -61,7 +61,7 @@ describe "WorkspaceView", ->
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('b').then (editor) ->
|
||||
pane2.activateItem(editor)
|
||||
pane2.activateItem(editor.copy())
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('../sample.js').then (editor) ->
|
||||
@@ -185,7 +185,8 @@ describe "WorkspaceView", ->
|
||||
|
||||
describe "when the root view is deserialized", ->
|
||||
it "updates the title to contain the project's path", ->
|
||||
workspaceView2 = new WorkspaceView(atom.workspace.testSerialization())
|
||||
workspace2 = atom.workspace.testSerialization()
|
||||
workspaceView2 = workspace2.getView(workspace2).__spacePenView
|
||||
item = atom.workspace.getActivePaneItem()
|
||||
expect(workspaceView2.title).toBe "#{item.getTitle()} - #{atom.project.getPath()}"
|
||||
workspaceView2.remove()
|
||||
@@ -252,7 +253,7 @@ describe "WorkspaceView", ->
|
||||
editorViewCreatedHandler = jasmine.createSpy('editorViewCreatedHandler')
|
||||
atom.workspaceView.eachEditorView(editorViewCreatedHandler)
|
||||
editorViewCreatedHandler.reset()
|
||||
miniEditor = new EditorView(mini: true)
|
||||
miniEditor = new TextEditorView(mini: true)
|
||||
atom.workspaceView.append(miniEditor)
|
||||
expect(editorViewCreatedHandler).not.toHaveBeenCalled()
|
||||
|
||||
|
||||
+10
-4
@@ -103,7 +103,7 @@ class Atom extends Model
|
||||
Section: Properties
|
||||
###
|
||||
|
||||
# Public: A {CommandRegistry} instance
|
||||
# Experimental: A {CommandRegistry} instance
|
||||
commands: null
|
||||
|
||||
# Public: A {Config} instance
|
||||
@@ -158,6 +158,12 @@ class Atom extends Model
|
||||
#
|
||||
# Call after this instance has been assigned to the `atom` global.
|
||||
initialize: ->
|
||||
# Disable deprecations unless in dev mode or spec mode so that regular
|
||||
# editor performance isn't impacted by generating stack traces for
|
||||
# deprecated calls.
|
||||
unless @inDevMode() or @inSpecMode()
|
||||
require('grim').deprecate = ->
|
||||
|
||||
window.onerror = =>
|
||||
@openDevTools()
|
||||
@executeJavaScriptInDevTools('InspectorFrontendAPI.showConsole()')
|
||||
@@ -209,7 +215,7 @@ class Atom extends Model
|
||||
@deserializers.add(TextBuffer)
|
||||
TokenizedBuffer = require './tokenized-buffer'
|
||||
DisplayBuffer = require './display-buffer'
|
||||
Editor = require './editor'
|
||||
TextEditor = require './text-editor'
|
||||
|
||||
@windowEventHandler = new WindowEventHandler
|
||||
|
||||
@@ -462,7 +468,7 @@ class Atom extends Model
|
||||
dimensions = @restoreWindowDimensions()
|
||||
@config.load()
|
||||
@config.setDefaults('core', require('./workspace-view').configDefaults)
|
||||
@config.setDefaults('editor', require('./editor-view').configDefaults)
|
||||
@config.setDefaults('editor', require('./text-editor-view').configDefaults)
|
||||
@keymaps.loadBundledKeymaps()
|
||||
@themes.loadBaseStylesheets()
|
||||
@packages.loadPackages()
|
||||
@@ -582,7 +588,7 @@ class Atom extends Model
|
||||
|
||||
startTime = Date.now()
|
||||
@workspace = Workspace.deserialize(@state.workspace) ? new Workspace
|
||||
@workspaceView = new WorkspaceView(@workspace)
|
||||
@workspaceView = @workspace.getView(@workspace).__spacePenView
|
||||
@deserializeTimings.workspace = Date.now() - startTime
|
||||
|
||||
@keymaps.defaultTarget = @workspaceView[0]
|
||||
|
||||
@@ -492,6 +492,14 @@ class AtomApplication
|
||||
else
|
||||
BrowserWindow.getFocusedWindow()
|
||||
|
||||
openOptions =
|
||||
properties: properties.concat(['multiSelections', 'createDirectory'])
|
||||
title: 'Open'
|
||||
|
||||
if process.platform is 'linux'
|
||||
if projectPath = @lastFocusedWindow?.projectPath
|
||||
openOptions.defaultPath = projectPath
|
||||
|
||||
dialog = require 'dialog'
|
||||
dialog.showOpenDialog parentWindow, title: 'Open', properties: properties.concat(['multiSelections', 'createDirectory']), (pathsToOpen) =>
|
||||
dialog.showOpenDialog parentWindow, openOptions, (pathsToOpen) =>
|
||||
@openPaths({pathsToOpen, devMode, safeMode, window})
|
||||
|
||||
@@ -46,13 +46,15 @@ class CommandRegistry
|
||||
constructor: (@rootNode) ->
|
||||
@listenersByCommandName = {}
|
||||
|
||||
getRootNode: -> @rootNode
|
||||
|
||||
setRootNode: (newRootNode) ->
|
||||
oldRootNode = @rootNode
|
||||
@rootNode = newRootNode
|
||||
|
||||
for commandName of @listenersByCommandName
|
||||
oldRootNode?.removeEventListener(commandName, @dispatchCommand, true)
|
||||
newRootNode?.addEventListener(commandName, @dispatchCommand, true)
|
||||
@removeCommandListener(oldRootNode, commandName)
|
||||
@addCommandListener(newRootNode, commandName)
|
||||
|
||||
# Public: Add one or more command listeners associated with a selector.
|
||||
#
|
||||
@@ -88,7 +90,7 @@ class CommandRegistry
|
||||
return disposable
|
||||
|
||||
unless @listenersByCommandName[commandName]?
|
||||
@rootNode?.addEventListener(commandName, @dispatchCommand, true)
|
||||
@addCommandListener(@rootNode, commandName)
|
||||
@listenersByCommandName[commandName] = []
|
||||
|
||||
listener = new CommandListener(selector, callback)
|
||||
@@ -99,35 +101,7 @@ class CommandRegistry
|
||||
listenersForCommand.splice(listenersForCommand.indexOf(listener), 1)
|
||||
if listenersForCommand.length is 0
|
||||
delete @listenersByCommandName[commandName]
|
||||
@rootNode.removeEventListener(commandName, @dispatchCommand, true)
|
||||
|
||||
dispatchCommand: (event) =>
|
||||
propagationStopped = false
|
||||
immediatePropagationStopped = false
|
||||
currentTarget = event.target
|
||||
|
||||
syntheticEvent = Object.create event,
|
||||
eventPhase: value: Event.BUBBLING_PHASE
|
||||
currentTarget: get: -> currentTarget
|
||||
stopPropagation: value: ->
|
||||
propagationStopped = true
|
||||
stopImmediatePropagation: value: ->
|
||||
propagationStopped = true
|
||||
immediatePropagationStopped = true
|
||||
|
||||
loop
|
||||
matchingListeners =
|
||||
@listenersByCommandName[event.type]
|
||||
.filter (listener) -> currentTarget.webkitMatchesSelector(listener.selector)
|
||||
.sort (a, b) -> a.compare(b)
|
||||
|
||||
for listener in matchingListeners
|
||||
break if immediatePropagationStopped
|
||||
listener.callback.call(currentTarget, syntheticEvent)
|
||||
|
||||
break if propagationStopped
|
||||
break if currentTarget is @rootNode
|
||||
currentTarget = currentTarget.parentNode
|
||||
@removeCommandListener(@rootNode, commandName)
|
||||
|
||||
# Public: Find all registered commands matching a query.
|
||||
#
|
||||
@@ -154,6 +128,7 @@ class CommandRegistry
|
||||
|
||||
break if currentTarget is @rootNode
|
||||
currentTarget = currentTarget.parentNode
|
||||
break unless currentTarget?
|
||||
|
||||
for name, displayName of $(target).events() when displayName
|
||||
commands.push({name, displayName, jQuery: true})
|
||||
@@ -163,10 +138,91 @@ class CommandRegistry
|
||||
|
||||
commands
|
||||
|
||||
clear: ->
|
||||
# Public: Simulate the dispatch of a command on a DOM node.
|
||||
#
|
||||
# This can be useful for testing when you want to simulate the invocation of a
|
||||
# command on a detached DOM node. Otherwise, the DOM node in question needs to
|
||||
# be attached to the document so the event bubbles up to the root node to be
|
||||
# processed.
|
||||
#
|
||||
# * `target` The DOM node at which to start bubbling the command event.
|
||||
# * `commandName` {String} indicating the name of the command to dispatch.
|
||||
dispatch: (target, commandName) ->
|
||||
event = new CustomEvent(commandName, bubbles: true)
|
||||
eventWithTarget = Object.create(event, target: value: target)
|
||||
@handleCommandEvent(eventWithTarget)
|
||||
|
||||
getSnapshot: ->
|
||||
snapshot = {}
|
||||
for commandName, listeners of @listenersByCommandName
|
||||
snapshot[commandName] = listeners.slice()
|
||||
snapshot
|
||||
|
||||
restoreSnapshot: (snapshot) ->
|
||||
rootNode = @getRootNode()
|
||||
@setRootNode(null) # clear listeners for current commands
|
||||
@listenersByCommandName = {}
|
||||
for commandName, listeners of snapshot
|
||||
@listenersByCommandName[commandName] = listeners.slice()
|
||||
@setRootNode(rootNode) # restore listeners for commands in snapshot
|
||||
|
||||
handleCommandEvent: (originalEvent) =>
|
||||
originalEvent.__handledByCommandRegistry = true
|
||||
|
||||
propagationStopped = false
|
||||
immediatePropagationStopped = false
|
||||
matched = false
|
||||
currentTarget = originalEvent.target
|
||||
invokedListeners = []
|
||||
|
||||
syntheticEvent = Object.create originalEvent,
|
||||
eventPhase: value: Event.BUBBLING_PHASE
|
||||
currentTarget: get: -> currentTarget
|
||||
stopPropagation: value: ->
|
||||
originalEvent.stopPropagation()
|
||||
propagationStopped = true
|
||||
stopImmediatePropagation: value: ->
|
||||
originalEvent.stopImmediatePropagation()
|
||||
propagationStopped = true
|
||||
immediatePropagationStopped = true
|
||||
disableInvokedListeners: value: ->
|
||||
listener.enabled = false for listener in invokedListeners
|
||||
-> listener.enabled = true for listener in invokedListeners
|
||||
|
||||
loop
|
||||
matchingListeners =
|
||||
(@listenersByCommandName[originalEvent.type] ? [])
|
||||
.filter (listener) -> currentTarget.webkitMatchesSelector(listener.selector)
|
||||
.sort (a, b) -> a.compare(b)
|
||||
|
||||
matched = true if matchingListeners.length > 0
|
||||
|
||||
for listener in matchingListeners when listener.enabled
|
||||
break if immediatePropagationStopped
|
||||
invokedListeners.push(listener)
|
||||
listener.callback.call(currentTarget, syntheticEvent)
|
||||
|
||||
break if currentTarget is @rootNode
|
||||
break if propagationStopped
|
||||
currentTarget = currentTarget.parentNode
|
||||
break unless currentTarget?
|
||||
|
||||
matched
|
||||
|
||||
handleJQueryCommandEvent: (event) =>
|
||||
@handleCommandEvent(event) unless event.originalEvent?.__handledByCommandRegistry
|
||||
|
||||
addCommandListener: (node, commandName, listener) ->
|
||||
node?.addEventListener(commandName, @handleCommandEvent, true)
|
||||
$(node).on commandName, @handleJQueryCommandEvent
|
||||
|
||||
removeCommandListener: (node, commandName) ->
|
||||
node?.removeEventListener(commandName, @handleCommandEvent, true)
|
||||
$(node).off commandName, @handleJQueryCommandEvent
|
||||
|
||||
class CommandListener
|
||||
enabled: true
|
||||
|
||||
constructor: (@selector, @callback) ->
|
||||
@specificity = (SpecificityCache[@selector] ?= specificity(@selector))
|
||||
@sequenceNumber = SequenceCount++
|
||||
|
||||
+9
-5
@@ -65,14 +65,18 @@ class Config
|
||||
_.extend(@settings, userConfig)
|
||||
@configFileHasErrors = false
|
||||
@emit 'updated'
|
||||
catch e
|
||||
catch error
|
||||
@configFileHasErrors = true
|
||||
console.error "Failed to load user config '#{@configFilePath}'", e.message
|
||||
console.error e.stack
|
||||
console.error "Failed to load user config '#{@configFilePath}'", error.message
|
||||
console.error error.stack
|
||||
|
||||
observeUserConfig: ->
|
||||
@watchSubscription ?= pathWatcher.watch @configFilePath, (eventType) =>
|
||||
@loadUserConfig() if eventType is 'change' and @watchSubscription?
|
||||
try
|
||||
@watchSubscription ?= pathWatcher.watch @configFilePath, (eventType) =>
|
||||
@loadUserConfig() if eventType is 'change' and @watchSubscription?
|
||||
catch error
|
||||
console.error "Failed to watch user config '#{@configFilePath}'", error.message
|
||||
console.error error.stack
|
||||
|
||||
unobserveUserConfig: ->
|
||||
@watchSubscription?.close()
|
||||
|
||||
+5
-5
@@ -7,7 +7,7 @@ Grim = require 'grim'
|
||||
# Extended: The `Cursor` class represents the little blinking line identifying
|
||||
# where text can be inserted.
|
||||
#
|
||||
# Cursors belong to {Editor}s and have some metadata attached in the form
|
||||
# Cursors belong to {TextEditor}s and have some metadata attached in the form
|
||||
# of a {Marker}.
|
||||
module.exports =
|
||||
class Cursor extends Model
|
||||
@@ -17,7 +17,7 @@ class Cursor extends Model
|
||||
visible: true
|
||||
needsAutoscroll: null
|
||||
|
||||
# Instantiated by an {Editor}
|
||||
# Instantiated by an {TextEditor}
|
||||
constructor: ({@editor, @marker, id}) ->
|
||||
@emitter = new Emitter
|
||||
|
||||
@@ -114,7 +114,7 @@ class Cursor extends Model
|
||||
#
|
||||
# * `screenPosition` {Array} of two numbers: the screen row, and the screen column.
|
||||
# * `options` (optional) {Object} with the following keys:
|
||||
# * `autoscroll` A Boolean which, if `true`, scrolls the {Editor} to wherever
|
||||
# * `autoscroll` A Boolean which, if `true`, scrolls the {TextEditor} to wherever
|
||||
# the cursor moves to.
|
||||
setScreenPosition: (screenPosition, options={}) ->
|
||||
@changePosition options, =>
|
||||
@@ -128,7 +128,7 @@ class Cursor extends Model
|
||||
#
|
||||
# * `bufferPosition` {Array} of two numbers: the buffer row, and the buffer column.
|
||||
# * `options` (optional) {Object} with the following keys:
|
||||
# * `autoscroll` A Boolean which, if `true`, scrolls the {Editor} to wherever
|
||||
# * `autoscroll` A Boolean which, if `true`, scrolls the {TextEditor} to wherever
|
||||
# the cursor moves to.
|
||||
setBufferPosition: (bufferPosition, options={}) ->
|
||||
@changePosition options, =>
|
||||
@@ -232,7 +232,7 @@ class Cursor extends Model
|
||||
else
|
||||
bufferPosition.column > firstCharacterColumn
|
||||
|
||||
# Public: Identifies if this cursor is the last in the {Editor}.
|
||||
# Public: Identifies if this cursor is the last in the {TextEditor}.
|
||||
#
|
||||
# "Last" is defined as the most recently added cursor.
|
||||
#
|
||||
|
||||
@@ -12,7 +12,7 @@ nextId = -> idCounter++
|
||||
# around marked ranges of text.
|
||||
#
|
||||
# {Decoration} objects are not meant to be created directly, but created with
|
||||
# {Editor::decorateMarker}. eg.
|
||||
# {TextEditor::decorateMarker}. eg.
|
||||
#
|
||||
# ```coffee
|
||||
# range = editor.getSelectedBufferRange() # any range you like
|
||||
|
||||
@@ -315,9 +315,14 @@ class DisplayBuffer extends Model
|
||||
@charWidthsByScope = {}
|
||||
|
||||
getScrollHeight: ->
|
||||
return 0 unless @getLineHeightInPixels() > 0
|
||||
lineHeight = @getLineHeightInPixels()
|
||||
return 0 unless lineHeight > 0
|
||||
|
||||
@getLineCount() * @getLineHeightInPixels()
|
||||
scrollHeight = @getLineCount() * lineHeight
|
||||
if @height? and atom.config.get('editor.scrollPastEnd')
|
||||
scrollHeight = scrollHeight + @height - (lineHeight * 3)
|
||||
|
||||
scrollHeight
|
||||
|
||||
getScrollWidth: ->
|
||||
@scrollWidth
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
module.exports =
|
||||
class ItemRegistry
|
||||
constructor: ->
|
||||
@items = new WeakSet
|
||||
|
||||
addItem: (item) ->
|
||||
if @hasItem(item)
|
||||
throw new Error("The workspace can only contain one instance of item #{item}")
|
||||
@items.add(item)
|
||||
|
||||
removeItem: (item) ->
|
||||
@items.delete(item)
|
||||
|
||||
hasItem: (item) ->
|
||||
@items.has(item)
|
||||
@@ -8,9 +8,9 @@ class LanguageMode
|
||||
Emitter.includeInto(this)
|
||||
Subscriber.includeInto(this)
|
||||
|
||||
# Sets up a `LanguageMode` for the given {Editor}.
|
||||
# Sets up a `LanguageMode` for the given {TextEditor}.
|
||||
#
|
||||
# editor - The {Editor} to associate with
|
||||
# editor - The {TextEditor} to associate with
|
||||
constructor: (@editor) ->
|
||||
{@buffer} = @editor
|
||||
|
||||
@@ -283,7 +283,7 @@ class LanguageMode
|
||||
# Given a buffer row, this indents it.
|
||||
#
|
||||
# bufferRow - The row {Number}.
|
||||
# options - An options {Object} to pass through to {Editor::setIndentationForBufferRow}.
|
||||
# options - An options {Object} to pass through to {TextEditor::setIndentationForBufferRow}.
|
||||
autoIndentBufferRow: (bufferRow, options) ->
|
||||
indentLevel = @suggestedIndentForBufferRow(bufferRow)
|
||||
@editor.setIndentationForBufferRow(bufferRow, indentLevel, options)
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ Grim = require 'grim'
|
||||
#
|
||||
# ### Marker Creation
|
||||
#
|
||||
# Use {Editor::markBufferRange} rather than creating Markers directly.
|
||||
# Use {TextEditor::markBufferRange} rather than creating Markers directly.
|
||||
#
|
||||
# ### Head and Tail
|
||||
#
|
||||
@@ -42,7 +42,7 @@ Grim = require 'grim'
|
||||
# region in any way, including changes that end at the marker's
|
||||
# start or start at the marker's end. This is the most fragile strategy.
|
||||
#
|
||||
# See {Editor::markBufferRange} for usage.
|
||||
# See {TextEditor::markBufferRange} for usage.
|
||||
module.exports =
|
||||
class Marker
|
||||
EmitterMixin.includeInto(this)
|
||||
|
||||
+51
-59
@@ -5,7 +5,7 @@ async = require 'async'
|
||||
CSON = require 'season'
|
||||
fs = require 'fs-plus'
|
||||
EmitterMixin = require('emissary').Emitter
|
||||
{Emitter} = require 'event-kit'
|
||||
{Emitter, CompositeDisposable} = require 'event-kit'
|
||||
Q = require 'q'
|
||||
{deprecate} = require 'grim'
|
||||
|
||||
@@ -99,7 +99,7 @@ class Package
|
||||
@loadMenus()
|
||||
@loadStylesheets()
|
||||
@scopedPropertiesPromise = @loadScopedProperties()
|
||||
@requireMainModule() unless @hasActivationEvents()
|
||||
@requireMainModule() unless @hasActivationCommands()
|
||||
|
||||
catch error
|
||||
console.warn "Failed to load package named '#{@name}'", error.stack ? error
|
||||
@@ -119,8 +119,8 @@ class Package
|
||||
@activationDeferred = Q.defer()
|
||||
@measure 'activateTime', =>
|
||||
@activateResources()
|
||||
if @hasActivationEvents()
|
||||
@subscribeToActivationEvents()
|
||||
if @hasActivationCommands()
|
||||
@subscribeToActivationCommands()
|
||||
else
|
||||
@activateNow()
|
||||
|
||||
@@ -270,7 +270,7 @@ class Package
|
||||
deactivate: ->
|
||||
@activationDeferred?.reject()
|
||||
@activationDeferred = null
|
||||
@unsubscribeFromActivationEvents()
|
||||
@activationCommandSubscriptions?.dispose()
|
||||
@deactivateResources()
|
||||
@deactivateConfig()
|
||||
if @mainActivated
|
||||
@@ -319,64 +319,56 @@ class Package
|
||||
path.join(@path, 'index')
|
||||
@mainModulePath = fs.resolveExtension(mainModulePath, ["", _.keys(require.extensions)...])
|
||||
|
||||
hasActivationEvents: ->
|
||||
if _.isArray(@metadata.activationEvents)
|
||||
return @metadata.activationEvents.some (activationEvent) ->
|
||||
activationEvent?.length > 0
|
||||
else if _.isString(@metadata.activationEvents)
|
||||
return @metadata.activationEvents.length > 0
|
||||
else if _.isObject(@metadata.activationEvents)
|
||||
for event, selector of @metadata.activationEvents
|
||||
return true if event.length > 0 and selector.length > 0
|
||||
|
||||
hasActivationCommands: ->
|
||||
for selector, commands of @getActivationCommands()
|
||||
return true if commands.length > 0
|
||||
false
|
||||
|
||||
subscribeToActivationEvents: ->
|
||||
return unless @metadata.activationEvents?
|
||||
if _.isArray(@metadata.activationEvents)
|
||||
atom.workspaceView.command(event, @handleActivationEvent) for event in @metadata.activationEvents
|
||||
else if _.isString(@metadata.activationEvents)
|
||||
atom.workspaceView.command(@metadata.activationEvents, @handleActivationEvent)
|
||||
else
|
||||
atom.workspaceView.command(event, selector, @handleActivationEvent) for event, selector of @metadata.activationEvents
|
||||
subscribeToActivationCommands: ->
|
||||
@activationCommandSubscriptions = new CompositeDisposable
|
||||
for selector, commands of @getActivationCommands()
|
||||
for command in commands
|
||||
@activationCommandSubscriptions.add(
|
||||
atom.commands.add(selector, command, @handleActivationCommand)
|
||||
)
|
||||
|
||||
handleActivationEvent: (event) =>
|
||||
bubblePathEventHandlers = @disableEventHandlersOnBubblePath(event)
|
||||
getActivationCommands: ->
|
||||
return @activationCommands if @activationCommands?
|
||||
|
||||
@activationCommands = {}
|
||||
|
||||
if @metadata.activationCommands?
|
||||
for selector, commands of @metadata.activationCommands
|
||||
@activationCommands[selector] ?= []
|
||||
if _.isString(commands)
|
||||
@activationCommands[selector].push(commands)
|
||||
else if _.isArray(commands)
|
||||
@activationCommands[selector].push(commands...)
|
||||
|
||||
if @metadata.activationEvents?
|
||||
if _.isArray(@metadata.activationEvents)
|
||||
for eventName in @metadata.activationEvents
|
||||
@activationCommands['.workspace'] ?= []
|
||||
@activationCommands['.workspace'].push(eventName)
|
||||
else if _.isString(@metadata.activationEvents)
|
||||
eventName = @metadata.activationEvents
|
||||
@activationCommands['.workspace'] ?= []
|
||||
@activationCommands['.workspace'].push(eventName)
|
||||
else
|
||||
for eventName, selector of @metadata.activationEvents
|
||||
selector ?= '.workspace'
|
||||
@activationCommands[selector] ?= []
|
||||
@activationCommands[selector].push(eventName)
|
||||
|
||||
@activationCommands
|
||||
|
||||
handleActivationCommand: (event) =>
|
||||
event.stopImmediatePropagation()
|
||||
@activationCommandSubscriptions.dispose()
|
||||
reenableInvokedListeners = event.disableInvokedListeners()
|
||||
@activateNow()
|
||||
$ ?= require('./space-pen-extensions').$
|
||||
$(event.target).trigger(event)
|
||||
@restoreEventHandlersOnBubblePath(bubblePathEventHandlers)
|
||||
@unsubscribeFromActivationEvents()
|
||||
false
|
||||
|
||||
unsubscribeFromActivationEvents: ->
|
||||
return unless atom.workspaceView?
|
||||
|
||||
if _.isArray(@metadata.activationEvents)
|
||||
atom.workspaceView.off(event, @handleActivationEvent) for event in @metadata.activationEvents
|
||||
else if _.isString(@metadata.activationEvents)
|
||||
atom.workspaceView.off(@metadata.activationEvents, @handleActivationEvent)
|
||||
else
|
||||
atom.workspaceView.off(event, selector, @handleActivationEvent) for event, selector of @metadata.activationEvents
|
||||
|
||||
disableEventHandlersOnBubblePath: (event) ->
|
||||
bubblePathEventHandlers = []
|
||||
disabledHandler = ->
|
||||
$ ?= require('./space-pen-extensions').$
|
||||
element = $(event.target)
|
||||
while element.length
|
||||
if eventHandlers = element.handlers()?[event.type]
|
||||
for eventHandler in eventHandlers
|
||||
eventHandler.disabledHandler = eventHandler.handler
|
||||
eventHandler.handler = disabledHandler
|
||||
bubblePathEventHandlers.push(eventHandler)
|
||||
element = element.parent()
|
||||
bubblePathEventHandlers
|
||||
|
||||
restoreEventHandlersOnBubblePath: (eventHandlers) ->
|
||||
for eventHandler in eventHandlers
|
||||
eventHandler.handler = eventHandler.disabledHandler
|
||||
delete eventHandler.disabledHandler
|
||||
event.target.dispatchEvent(new CustomEvent(event.type, bubbles: true))
|
||||
reenableInvokedListeners()
|
||||
|
||||
# Does the given module path contain native code?
|
||||
isNativeModule: (modulePath) ->
|
||||
|
||||
@@ -16,10 +16,6 @@ class PaneAxisView extends View
|
||||
afterAttach: ->
|
||||
@container = @closest('.panes').view()
|
||||
|
||||
viewForModel: (model) ->
|
||||
viewClass = model.getViewClass()
|
||||
model._view ?= new viewClass(model)
|
||||
|
||||
onChildReplaced: ({index, oldChild, newChild}) =>
|
||||
focusedElement = document.activeElement if @hasFocus()
|
||||
@onChildRemoved({child: oldChild, index})
|
||||
@@ -27,11 +23,11 @@ class PaneAxisView extends View
|
||||
focusedElement?.focus() if document.activeElement is document.body
|
||||
|
||||
onChildAdded: ({child, index}) =>
|
||||
view = @viewForModel(child)
|
||||
view = @model.getView(child).__spacePenView
|
||||
@insertAt(index, view)
|
||||
|
||||
onChildRemoved: ({child}) =>
|
||||
view = @viewForModel(child)
|
||||
view = @model.getView(child).__spacePenView
|
||||
view.detach()
|
||||
PaneView ?= require './pane-view'
|
||||
if view instanceof PaneView and view.model.isDestroyed()
|
||||
|
||||
@@ -46,6 +46,9 @@ class PaneAxis extends Model
|
||||
else
|
||||
PaneRowView ?= require './pane-row-view'
|
||||
|
||||
getView: (object) ->
|
||||
@container.getView(object)
|
||||
|
||||
getChildren: -> @children.slice()
|
||||
|
||||
getPanes: ->
|
||||
|
||||
@@ -26,11 +26,6 @@ class PaneContainerView extends View
|
||||
@subscriptions.add @model.observeRoot(@onRootChanged)
|
||||
@subscriptions.add @model.onDidChangeActivePaneItem(@onActivePaneItemChanged)
|
||||
|
||||
viewForModel: (model) ->
|
||||
if model?
|
||||
viewClass = model.getViewClass()
|
||||
model._view ?= new viewClass(model)
|
||||
|
||||
getRoot: ->
|
||||
@children().first().view()
|
||||
|
||||
@@ -42,7 +37,7 @@ class PaneContainerView extends View
|
||||
@trigger 'pane:removed', [oldRoot]
|
||||
oldRoot?.detach()
|
||||
if root?
|
||||
view = @viewForModel(root)
|
||||
view = @model.getView(root).__spacePenView
|
||||
@append(view)
|
||||
focusedElement?.focus()
|
||||
else
|
||||
@@ -88,7 +83,7 @@ class PaneContainerView extends View
|
||||
@getActivePaneView()
|
||||
|
||||
getActivePaneView: ->
|
||||
@viewForModel(@model.activePane)
|
||||
@model.getView(@model.getActivePane()).__spacePenView
|
||||
|
||||
getActivePaneItem: ->
|
||||
@model.getActivePaneItem()
|
||||
@@ -97,7 +92,7 @@ class PaneContainerView extends View
|
||||
@getActivePaneView()?.activeView
|
||||
|
||||
paneForUri: (uri) ->
|
||||
@viewForModel(@model.paneForUri(uri))
|
||||
@model.getView(@model.paneForUri(uri)).__spacePenView
|
||||
|
||||
focusNextPaneView: ->
|
||||
@model.activateNextPane()
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
{Emitter, CompositeDisposable} = require 'event-kit'
|
||||
Serializable = require 'serializable'
|
||||
Pane = require './pane'
|
||||
ViewRegistry = require './view-registry'
|
||||
ItemRegistry = require './item-registry'
|
||||
PaneContainerView = null
|
||||
|
||||
module.exports =
|
||||
class PaneContainer extends Model
|
||||
@@ -27,6 +30,8 @@ class PaneContainer extends Model
|
||||
@emitter = new Emitter
|
||||
@subscriptions = new CompositeDisposable
|
||||
|
||||
@viewRegistry = params?.viewRegistry ? new ViewRegistry
|
||||
@itemRegistry = new ItemRegistry
|
||||
@setRoot(params?.root ? new Pane)
|
||||
@destroyEmptyPanes() if params?.destroyEmptyPanes
|
||||
|
||||
@@ -43,6 +48,12 @@ class PaneContainer extends Model
|
||||
root: @root?.serialize()
|
||||
activePaneId: @activePane.id
|
||||
|
||||
getViewClass: ->
|
||||
PaneContainerView ?= require './pane-container-view'
|
||||
|
||||
getView: (object) ->
|
||||
@viewRegistry.getView(object)
|
||||
|
||||
onDidChangeRoot: (fn) ->
|
||||
@emitter.on 'did-change-root', fn
|
||||
|
||||
@@ -169,7 +180,17 @@ class PaneContainer extends Model
|
||||
monitorPaneItems: ->
|
||||
@subscriptions.add @observePanes (pane) =>
|
||||
for item, index in pane.getItems()
|
||||
@emitter.emit 'did-add-pane-item', {item, pane, index}
|
||||
@addedPaneItem(item, pane, index)
|
||||
|
||||
pane.onDidAddItem ({item, index}) =>
|
||||
@emitter.emit 'did-add-pane-item', {item, pane, index}
|
||||
@addedPaneItem(item, pane, index)
|
||||
|
||||
pane.onDidRemoveItem ({item}) =>
|
||||
@removedPaneItem(item)
|
||||
|
||||
addedPaneItem: (item, pane, index) ->
|
||||
@itemRegistry.addItem(item)
|
||||
@emitter.emit 'did-add-pane-item', {item, pane, index}
|
||||
|
||||
removedPaneItem: (item) ->
|
||||
@itemRegistry.removeItem(item)
|
||||
|
||||
+10
-30
@@ -8,7 +8,7 @@ Pane = require './pane'
|
||||
|
||||
# A container which can contains multiple items to be switched between.
|
||||
#
|
||||
# Items can be almost anything however most commonly they're {EditorView}s.
|
||||
# Items can be almost anything however most commonly they're {TextEditorView}s.
|
||||
#
|
||||
# Most packages won't need to use this class, unless you're interested in
|
||||
# building a package that deals with switching between panes or items.
|
||||
@@ -33,17 +33,9 @@ class PaneView extends View
|
||||
|
||||
previousActiveItem: null
|
||||
|
||||
initialize: (args...) ->
|
||||
initialize: (@model) ->
|
||||
@subscriptions = new CompositeDisposable
|
||||
|
||||
if args[0] instanceof Pane
|
||||
@model = args[0]
|
||||
else
|
||||
@model = new Pane(items: args)
|
||||
@model._view = this
|
||||
|
||||
@onItemAdded(item) for item in @items
|
||||
@viewsByItem = new WeakMap()
|
||||
@handleEvents()
|
||||
|
||||
handleEvents: ->
|
||||
@@ -175,7 +167,7 @@ class PaneView extends View
|
||||
item.on('modified-status-changed', @activeItemModifiedChanged)
|
||||
@activeItemDisposables.add(disposable) if disposable?.dispose?
|
||||
|
||||
view = @viewForItem(item)
|
||||
view = @model.getView(item).__spacePenView
|
||||
otherView.hide() for otherView in @itemViews.children().not(view).views()
|
||||
@itemViews.append(view) unless view.parent().is(@itemViews)
|
||||
view.show() if @attached
|
||||
@@ -189,8 +181,8 @@ class PaneView extends View
|
||||
onItemRemoved: ({item, index, destroyed}) =>
|
||||
if item instanceof $
|
||||
viewToRemove = item
|
||||
else if viewToRemove = @viewsByItem.get(item)
|
||||
@viewsByItem.delete(item)
|
||||
else
|
||||
viewToRemove = @model.getView(item).__spacePenView
|
||||
|
||||
if viewToRemove?
|
||||
if destroyed
|
||||
@@ -213,27 +205,15 @@ class PaneView extends View
|
||||
activeItemModifiedChanged: =>
|
||||
@trigger 'pane:active-item-modified-status-changed'
|
||||
|
||||
viewForItem: (item) ->
|
||||
return unless item?
|
||||
if item instanceof $
|
||||
item
|
||||
else if view = @viewsByItem.get(item)
|
||||
view
|
||||
else
|
||||
viewClass = item.getViewClass()
|
||||
view = new viewClass(item)
|
||||
@viewsByItem.set(item, view)
|
||||
view
|
||||
@::accessor 'activeView', -> @model.getView(@activeItem)?.__spacePenView
|
||||
|
||||
@::accessor 'activeView', -> @viewForItem(@activeItem)
|
||||
splitLeft: (items...) -> @model.getView(@model.splitLeft({items})).__spacePenView
|
||||
|
||||
splitLeft: (items...) -> @model.splitLeft({items})._view
|
||||
splitRight: (items...) -> @model.getView(@model.splitRight({items})).__spacePenView
|
||||
|
||||
splitRight: (items...) -> @model.splitRight({items})._view
|
||||
splitUp: (items...) -> @model.getView(@model.splitUp({items})).__spacePenView
|
||||
|
||||
splitUp: (items...) -> @model.splitUp({items})._view
|
||||
|
||||
splitDown: (items...) -> @model.splitDown({items})._view
|
||||
splitDown: (items...) -> @model.getView(@model.splitDown({items})).__spacePenView
|
||||
|
||||
# Public: Get the container view housing this pane.
|
||||
#
|
||||
|
||||
+7
-4
@@ -4,7 +4,7 @@
|
||||
Serializable = require 'serializable'
|
||||
Grim = require 'grim'
|
||||
PaneAxis = require './pane-axis'
|
||||
Editor = require './editor'
|
||||
TextEditor = require './text-editor'
|
||||
PaneView = null
|
||||
|
||||
# Extended: A container for presenting content in the center of the workspace.
|
||||
@@ -56,6 +56,9 @@ class Pane extends Model
|
||||
# Called by the view layer to construct a view for this model.
|
||||
getViewClass: -> PaneView ?= require './pane-view'
|
||||
|
||||
getView: (object) ->
|
||||
@container.getView(object)
|
||||
|
||||
getParent: -> @parent
|
||||
|
||||
setParent: (@parent) -> @parent
|
||||
@@ -258,9 +261,9 @@ class Pane extends Model
|
||||
@emitter.emit 'did-change-active-item', @activeItem
|
||||
@activeItem
|
||||
|
||||
# Return an {Editor} if the pane item is an {Editor}, or null otherwise.
|
||||
# Return an {TextEditor} if the pane item is an {TextEditor}, or null otherwise.
|
||||
getActiveEditor: ->
|
||||
@activeItem if @activeItem instanceof Editor
|
||||
@activeItem if @activeItem instanceof TextEditor
|
||||
|
||||
# Public: Return the item at the given index.
|
||||
#
|
||||
@@ -377,8 +380,8 @@ class Pane extends Model
|
||||
# * `index` {Number} indicating the index to which to move the item in the
|
||||
# given pane.
|
||||
moveItemToPane: (item, pane, index) ->
|
||||
pane.addItem(item, index)
|
||||
@removeItem(item)
|
||||
pane.addItem(item, index)
|
||||
|
||||
# Public: Destroy the active item and activate the next item.
|
||||
destroyActiveItem: ->
|
||||
|
||||
@@ -11,7 +11,7 @@ Serializable = require 'serializable'
|
||||
TextBuffer = require 'text-buffer'
|
||||
{Directory} = require 'pathwatcher'
|
||||
|
||||
Editor = require './editor'
|
||||
TextEditor = require './text-editor'
|
||||
Task = require './task'
|
||||
GitRepository = require './git-repository'
|
||||
|
||||
@@ -232,12 +232,12 @@ class Project extends Model
|
||||
###
|
||||
|
||||
# Given a path to a file, this constructs and associates a new
|
||||
# {Editor}, showing the file.
|
||||
# {TextEditor}, showing the file.
|
||||
#
|
||||
# * `filePath` The {String} path of the file to associate with.
|
||||
# * `options` Options that you can pass to the {Editor} constructor.
|
||||
# * `options` Options that you can pass to the {TextEditor} constructor.
|
||||
#
|
||||
# Returns a promise that resolves to an {Editor}.
|
||||
# Returns a promise that resolves to an {TextEditor}.
|
||||
open: (filePath, options={}) ->
|
||||
filePath = @resolve(filePath)
|
||||
@bufferForPath(filePath).then (buffer) =>
|
||||
@@ -330,7 +330,7 @@ class Project extends Model
|
||||
buffer?.destroy()
|
||||
|
||||
buildEditorForBuffer: (buffer, editorOptions) ->
|
||||
editor = new Editor(_.extend({buffer, registerEditor: true}, editorOptions))
|
||||
editor = new TextEditor(_.extend({buffer, registerEditor: true}, editorOptions))
|
||||
editor
|
||||
|
||||
eachBuffer: (args...) ->
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{$, View} = require './space-pen-extensions'
|
||||
EditorView = require './editor-view'
|
||||
TextEditorView = require './text-editor-view'
|
||||
fuzzyFilter = require('fuzzaldrin').filter
|
||||
|
||||
# Essential: Provides a view that renders a list of items with an editor that
|
||||
@@ -34,7 +34,7 @@ module.exports =
|
||||
class SelectListView extends View
|
||||
@content: ->
|
||||
@div class: 'select-list', =>
|
||||
@subview 'filterEditorView', new EditorView(mini: true)
|
||||
@subview 'filterEditorView', new TextEditorView(mini: true)
|
||||
@div class: 'error-message', outlet: 'error'
|
||||
@div class: 'loading', outlet: 'loadingArea', =>
|
||||
@span class: 'loading-message', outlet: 'loading'
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
{Emitter} = require 'event-kit'
|
||||
Grim = require 'grim'
|
||||
|
||||
# Extended: Represents a selection in the {Editor}.
|
||||
# Extended: Represents a selection in the {TextEditor}.
|
||||
module.exports =
|
||||
class Selection extends Model
|
||||
cursor: null
|
||||
@@ -93,7 +93,7 @@ class Selection extends Model
|
||||
# * `screenRange` The new {Range} to select.
|
||||
# * `options` (optional) {Object} with the keys:
|
||||
# * `preserveFolds` if `true`, the fold settings are preserved after the selection moves.
|
||||
# * `autoscroll` if `true`, the {Editor} scrolls to the new selection.
|
||||
# * `autoscroll` if `true`, the {TextEditor} scrolls to the new selection.
|
||||
setBufferRange: (bufferRange, options={}) ->
|
||||
bufferRange = Range.fromObject(bufferRange)
|
||||
@needsAutoscroll = options.autoscroll
|
||||
@@ -591,7 +591,7 @@ class Selection extends Model
|
||||
#
|
||||
# * `options` (optional) {Object} with the keys:
|
||||
# * `autoIndent` If `true`, the line is indented to an automatically-inferred
|
||||
# level. Otherwise, {Editor::getTabText} is inserted.
|
||||
# level. Otherwise, {TextEditor::getTabText} is inserted.
|
||||
indent: ({ autoIndent }={}) ->
|
||||
{ row, column } = @cursor.getBufferPosition()
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ ScrollbarCornerComponent = require './scrollbar-corner-component'
|
||||
SubscriberMixin = require './subscriber-mixin'
|
||||
|
||||
module.exports =
|
||||
EditorComponent = React.createClass
|
||||
displayName: 'EditorComponent'
|
||||
TextEditorComponent = React.createClass
|
||||
displayName: 'TextEditorComponent'
|
||||
mixins: [SubscriberMixin]
|
||||
|
||||
statics:
|
||||
@@ -64,7 +64,7 @@ EditorComponent = React.createClass
|
||||
decorations = editor.decorationsForScreenRowRange(renderedStartRow, renderedEndRow)
|
||||
highlightDecorations = @getHighlightDecorations(decorations)
|
||||
lineDecorations = @getLineDecorations(decorations)
|
||||
placeholderText = @props.placeholderText if @props.placeholderText? and editor.isEmpty()
|
||||
placeholderText = editor.getPlaceholderText() if editor.isEmpty()
|
||||
visible = @isVisible()
|
||||
|
||||
scrollHeight = editor.getScrollHeight()
|
||||
@@ -236,7 +236,7 @@ EditorComponent = React.createClass
|
||||
@updateRequestedWhilePaused = true
|
||||
return
|
||||
|
||||
if @performSyncUpdates ? EditorComponent.performSyncUpdates
|
||||
if @performSyncUpdates ? TextEditorComponent.performSyncUpdates
|
||||
@forceUpdate()
|
||||
else unless @updateRequested
|
||||
@updateRequested = true
|
||||
@@ -358,6 +358,7 @@ EditorComponent = React.createClass
|
||||
@subscribe editor.observeDecorations(@onDecorationAdded)
|
||||
@subscribe editor.onDidRemoveDecoration(@onDecorationRemoved)
|
||||
@subscribe editor.onDidChangeCharacterWidths(@onCharacterWidthsChanged)
|
||||
@subscribe editor.onDidChangePlaceholderText(@onPlaceholderTextChanged)
|
||||
@subscribe editor.$scrollTop.changes, @onScrollTopChanged
|
||||
@subscribe editor.$scrollLeft.changes, @requestUpdate
|
||||
@subscribe editor.$verticalScrollbarWidth.changes, @requestUpdate
|
||||
@@ -605,7 +606,7 @@ EditorComponent = React.createClass
|
||||
|
||||
onScrollViewScroll: ->
|
||||
if @isMounted()
|
||||
console.warn "EditorScrollView scrolled when it shouldn't have."
|
||||
console.warn "TextEditorScrollView scrolled when it shouldn't have."
|
||||
scrollViewNode = @refs.scrollView.getDOMNode()
|
||||
scrollViewNode.scrollTop = 0
|
||||
scrollViewNode.scrollLeft = 0
|
||||
@@ -780,6 +781,9 @@ EditorComponent = React.createClass
|
||||
onCharacterWidthsChanged: (@scopedCharacterWidthsChangeCount) ->
|
||||
@requestUpdate()
|
||||
|
||||
onPlaceholderTextChanged: ->
|
||||
@requestUpdate()
|
||||
|
||||
handleDragUntilMouseUp: (event, dragHandler) ->
|
||||
{editor} = @props
|
||||
dragging = false
|
||||
@@ -2,24 +2,24 @@
|
||||
React = require 'react-atom-fork'
|
||||
{defaults} = require 'underscore-plus'
|
||||
TextBuffer = require 'text-buffer'
|
||||
Editor = require './editor'
|
||||
EditorComponent = require './editor-component'
|
||||
TextEditor = require './text-editor'
|
||||
TextEditorComponent = require './text-editor-component'
|
||||
{deprecate} = require 'grim'
|
||||
|
||||
# Public: Represents the entire visual pane in Atom.
|
||||
#
|
||||
# The EditorView manages the {Editor}, which manages the file buffers.
|
||||
# `EditorView` is intentionally sparse. Most of the things you'll want
|
||||
# to do are on {Editor}.
|
||||
# The TextEditorView manages the {TextEditor}, which manages the file buffers.
|
||||
# `TextEditorView` is intentionally sparse. Most of the things you'll want
|
||||
# to do are on {TextEditor}.
|
||||
#
|
||||
# ## Examples
|
||||
#
|
||||
# Requiring in packages
|
||||
#
|
||||
# ```coffee
|
||||
# {EditorView} = require 'atom'
|
||||
# {TextEditorView} = require 'atom'
|
||||
#
|
||||
# miniEditorView = new EditorView(mini: true)
|
||||
# miniEditorView = new TextEditorView(mini: true)
|
||||
# ```
|
||||
#
|
||||
# Iterating over the open editor views
|
||||
@@ -36,7 +36,7 @@ EditorComponent = require './editor-component'
|
||||
# console.log(editorView.getModel().getPath())
|
||||
# ```
|
||||
module.exports =
|
||||
class EditorView extends View
|
||||
class TextEditorView extends View
|
||||
@configDefaults:
|
||||
fontFamily: ''
|
||||
fontSize: 16
|
||||
@@ -60,6 +60,7 @@ class EditorView extends View
|
||||
space: '\u00b7'
|
||||
tab: '\u00bb'
|
||||
cr: '\u00a4'
|
||||
scrollPastEnd: false
|
||||
|
||||
@content: (params) ->
|
||||
attributes = params.attributes ? {}
|
||||
@@ -69,32 +70,33 @@ class EditorView extends View
|
||||
|
||||
focusOnAttach: false
|
||||
|
||||
# The constructor for setting up an `EditorView` instance.
|
||||
# The constructor for setting up an `TextEditorView` instance.
|
||||
#
|
||||
# * `editorOrParams` Either an {Editor}, or an object with one property, `mini`.
|
||||
# If `mini` is `true`, a "miniature" `Editor` is constructed.
|
||||
# * `editorOrParams` Either an {TextEditor}, or an object with one property, `mini`.
|
||||
# If `mini` is `true`, a "miniature" `TextEditor` is constructed.
|
||||
# Typically, this is ideal for scenarios where you need an Atom editor,
|
||||
# but without all the chrome, like scrollbars, gutter, _e.t.c._.
|
||||
#
|
||||
constructor: (editorOrParams, props) ->
|
||||
super
|
||||
|
||||
if editorOrParams instanceof Editor
|
||||
if editorOrParams instanceof TextEditor
|
||||
@editor = editorOrParams
|
||||
else
|
||||
{@editor, mini, placeholderText} = editorOrParams
|
||||
props ?= {}
|
||||
props.mini = mini
|
||||
props.placeholderText = placeholderText
|
||||
@editor ?= new Editor
|
||||
@editor ?= new TextEditor
|
||||
buffer: new TextBuffer
|
||||
softWrapped: false
|
||||
tabLength: 2
|
||||
softTabs: true
|
||||
mini: mini
|
||||
placeholderText: placeholderText
|
||||
|
||||
props = defaults({@editor, parentView: this}, props)
|
||||
@component = React.renderComponent(EditorComponent(props), @element)
|
||||
@componentDescriptor = TextEditorComponent(props)
|
||||
@component = React.renderComponent(@componentDescriptor, @element)
|
||||
|
||||
node = @component.getDOMNode()
|
||||
|
||||
@@ -128,7 +130,7 @@ class EditorView extends View
|
||||
|
||||
# Public: Get the underlying editor model for this view.
|
||||
#
|
||||
# Returns an {Editor}
|
||||
# Returns an {TextEditor}
|
||||
getModel: -> @editor
|
||||
|
||||
getEditor: -> @editor
|
||||
@@ -145,6 +147,7 @@ class EditorView extends View
|
||||
return unless onDom
|
||||
return if @attached
|
||||
@attached = true
|
||||
@component = React.renderComponent(@componentDescriptor, @element) unless @component.isMounted()
|
||||
@component.checkForVisibilityChange()
|
||||
|
||||
@focus() if @focusOnAttach
|
||||
@@ -171,27 +174,27 @@ class EditorView extends View
|
||||
@editor.getScrollLeft()
|
||||
|
||||
scrollToBottom: ->
|
||||
deprecate 'Use Editor::scrollToBottom instead. You can get the editor via editorView.getModel()'
|
||||
deprecate 'Use TextEditor::scrollToBottom instead. You can get the editor via editorView.getModel()'
|
||||
@editor.setScrollBottom(Infinity)
|
||||
|
||||
scrollToScreenPosition: (screenPosition, options) ->
|
||||
deprecate 'Use Editor::scrollToScreenPosition instead. You can get the editor via editorView.getModel()'
|
||||
deprecate 'Use TextEditor::scrollToScreenPosition instead. You can get the editor via editorView.getModel()'
|
||||
@editor.scrollToScreenPosition(screenPosition, options)
|
||||
|
||||
scrollToBufferPosition: (bufferPosition, options) ->
|
||||
deprecate 'Use Editor::scrollToBufferPosition instead. You can get the editor via editorView.getModel()'
|
||||
deprecate 'Use TextEditor::scrollToBufferPosition instead. You can get the editor via editorView.getModel()'
|
||||
@editor.scrollToBufferPosition(bufferPosition, options)
|
||||
|
||||
scrollToCursorPosition: ->
|
||||
deprecate 'Use Editor::scrollToCursorPosition instead. You can get the editor via editorView.getModel()'
|
||||
deprecate 'Use TextEditor::scrollToCursorPosition instead. You can get the editor via editorView.getModel()'
|
||||
@editor.scrollToCursorPosition()
|
||||
|
||||
pixelPositionForBufferPosition: (bufferPosition) ->
|
||||
deprecate 'Use Editor::pixelPositionForBufferPosition instead. You can get the editor via editorView.getModel()'
|
||||
deprecate 'Use TextEditor::pixelPositionForBufferPosition instead. You can get the editor via editorView.getModel()'
|
||||
@editor.pixelPositionForBufferPosition(bufferPosition)
|
||||
|
||||
pixelPositionForScreenPosition: (screenPosition) ->
|
||||
deprecate 'Use Editor::pixelPositionForScreenPosition instead. You can get the editor via editorView.getModel()'
|
||||
deprecate 'Use TextEditor::pixelPositionForScreenPosition instead. You can get the editor via editorView.getModel()'
|
||||
@editor.pixelPositionForScreenPosition(screenPosition)
|
||||
|
||||
appendToLinesView: (view) ->
|
||||
@@ -251,13 +254,13 @@ class EditorView extends View
|
||||
pane = @getPaneView()
|
||||
pane?.splitDown(pane?.copyActiveItem()).activeView
|
||||
|
||||
# Public: Get this {EditorView}'s {PaneView}.
|
||||
# Public: Get this {TextEditorView}'s {PaneView}.
|
||||
#
|
||||
# Returns a {PaneView}
|
||||
getPaneView: ->
|
||||
@parent('.item-views').parents('.pane').view()
|
||||
getPane: ->
|
||||
deprecate 'Use EditorView::getPaneView() instead'
|
||||
deprecate 'Use TextEditorView::getPaneView() instead'
|
||||
@getPaneView()
|
||||
|
||||
show: ->
|
||||
@@ -277,11 +280,11 @@ class EditorView extends View
|
||||
@editor.pageUp()
|
||||
|
||||
getFirstVisibleScreenRow: ->
|
||||
deprecate 'Use Editor::getFirstVisibleScreenRow instead. You can get the editor via editorView.getModel()'
|
||||
deprecate 'Use TextEditor::getFirstVisibleScreenRow instead. You can get the editor via editorView.getModel()'
|
||||
@editor.getFirstVisibleScreenRow()
|
||||
|
||||
getLastVisibleScreenRow: ->
|
||||
deprecate 'Use Editor::getLastVisibleScreenRow instead. You can get the editor via editorView.getModel()'
|
||||
deprecate 'Use TextEditor::getLastVisibleScreenRow instead. You can get the editor via editorView.getModel()'
|
||||
@editor.getLastVisibleScreenRow()
|
||||
|
||||
getFontFamily: ->
|
||||
@@ -312,7 +315,7 @@ class EditorView extends View
|
||||
@component.setShowIndentGuide(showIndentGuide)
|
||||
|
||||
setSoftWrap: (softWrapped) ->
|
||||
deprecate 'Use Editor::setSoftWrapped instead. You can get the editor via editorView.getModel()'
|
||||
deprecate 'Use TextEditor::setSoftWrapped instead. You can get the editor via editorView.getModel()'
|
||||
@editor.setSoftWrapped(softWrapped)
|
||||
|
||||
setShowInvisibles: (showInvisibles) ->
|
||||
@@ -346,16 +349,9 @@ class EditorView extends View
|
||||
redraw: ->
|
||||
deprecate('Please remove from your code. ::redraw no longer does anything')
|
||||
|
||||
# Public: Set the text to appear in the editor when it is empty.
|
||||
#
|
||||
# This only affects mini editors.
|
||||
#
|
||||
# * `placeholderText` A {String} of text to display when empty.
|
||||
setPlaceholderText: (placeholderText) ->
|
||||
if @component?
|
||||
@component.setProps({placeholderText})
|
||||
else
|
||||
@props.placeholderText = placeholderText
|
||||
deprecate('Use TextEditor::setPlaceholderText instead. eg. editorView.getModel().setPlaceholderText(text)')
|
||||
@getModel().setPlaceholderText(placeholderText)
|
||||
|
||||
lineElementForScreenRow: (screenRow) ->
|
||||
$(@component.lineNodeForScreenRow(screenRow))
|
||||
@@ -16,16 +16,16 @@ TextMateScopeSelector = require('first-mate').ScopeSelector
|
||||
# Public: This class represents all essential editing state for a single
|
||||
# {TextBuffer}, including cursor and selection positions, folds, and soft wraps.
|
||||
# If you're manipulating the state of an editor, use this class. If you're
|
||||
# interested in the visual appearance of editors, use {EditorView} instead.
|
||||
# interested in the visual appearance of editors, use {TextEditorView} instead.
|
||||
#
|
||||
# A single {TextBuffer} can belong to multiple editors. For example, if the
|
||||
# same file is open in two different panes, Atom creates a separate editor for
|
||||
# each pane. If the buffer is manipulated the changes are reflected in both
|
||||
# editors, but each maintains its own cursor position, folded lines, etc.
|
||||
#
|
||||
# ## Accessing Editor Instances
|
||||
# ## Accessing TextEditor Instances
|
||||
#
|
||||
# The easiest way to get hold of `Editor` objects is by registering a callback
|
||||
# The easiest way to get hold of `TextEditor` objects is by registering a callback
|
||||
# with `::observeTextEditors` on the `atom.workspace` global. Your callback will
|
||||
# then be called with all current editor instances and also when any editor is
|
||||
# created in the future.
|
||||
@@ -53,7 +53,7 @@ TextMateScopeSelector = require('first-mate').ScopeSelector
|
||||
# **When in doubt, just default to buffer coordinates**, then experiment with
|
||||
# soft wraps and folds to ensure your code interacts with them correctly.
|
||||
module.exports =
|
||||
class Editor extends Model
|
||||
class TextEditor extends Model
|
||||
Serializable.includeInto(this)
|
||||
atom.deserializers.add(this)
|
||||
Delegator.includeInto(this)
|
||||
@@ -77,7 +77,7 @@ class Editor extends Model
|
||||
'$verticalScrollbarWidth', '$horizontalScrollbarHeight', '$scrollTop', '$scrollLeft',
|
||||
'manageScrollPosition', toProperty: 'displayBuffer'
|
||||
|
||||
constructor: ({@softTabs, initialLine, initialColumn, tabLength, softWrapped, @displayBuffer, buffer, registerEditor, suppressCursorCreation, @mini}) ->
|
||||
constructor: ({@softTabs, initialLine, initialColumn, tabLength, softWrapped, @displayBuffer, buffer, registerEditor, suppressCursorCreation, @mini, @placeholderText}) ->
|
||||
super
|
||||
|
||||
@emitter = new Emitter
|
||||
@@ -163,7 +163,7 @@ class Editor extends Model
|
||||
@subscribe @displayBuffer.onDidRemoveDecoration (decoration) => @emit 'decoration-removed', decoration
|
||||
|
||||
getViewClass: ->
|
||||
require './editor-view'
|
||||
require './text-editor-view'
|
||||
|
||||
destroyed: ->
|
||||
@unsubscribe()
|
||||
@@ -405,6 +405,15 @@ class Editor extends Model
|
||||
onDidRemoveDecoration: (callback) ->
|
||||
@displayBuffer.onDidRemoveDecoration(callback)
|
||||
|
||||
# Extended: Calls your `callback` when the placeholder text is changed.
|
||||
#
|
||||
# * `callback` {Function}
|
||||
# * `placeholderText` {String} new text
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
|
||||
onDidChangePlaceholderText: (callback) ->
|
||||
@emitter.on 'did-change-placeholder-text', callback
|
||||
|
||||
onDidChangeCharacterWidths: (callback) ->
|
||||
@displayBuffer.onDidChangeCharacterWidths(callback)
|
||||
|
||||
@@ -417,57 +426,57 @@ class Editor extends Model
|
||||
on: (eventName) ->
|
||||
switch eventName
|
||||
when 'title-changed'
|
||||
deprecate("Use Editor::onDidChangeTitle instead")
|
||||
deprecate("Use TextEditor::onDidChangeTitle instead")
|
||||
when 'path-changed'
|
||||
deprecate("Use Editor::onDidChangePath instead")
|
||||
deprecate("Use TextEditor::onDidChangePath instead")
|
||||
when 'modified-status-changed'
|
||||
deprecate("Use Editor::onDidChangeModified instead")
|
||||
deprecate("Use TextEditor::onDidChangeModified instead")
|
||||
when 'soft-wrap-changed'
|
||||
deprecate("Use Editor::onDidChangeSoftWrapped instead")
|
||||
deprecate("Use TextEditor::onDidChangeSoftWrapped instead")
|
||||
when 'grammar-changed'
|
||||
deprecate("Use Editor::onDidChangeGrammar instead")
|
||||
deprecate("Use TextEditor::onDidChangeGrammar instead")
|
||||
when 'character-widths-changed'
|
||||
deprecate("Use Editor::onDidChangeCharacterWidths instead")
|
||||
deprecate("Use TextEditor::onDidChangeCharacterWidths instead")
|
||||
when 'contents-modified'
|
||||
deprecate("Use Editor::onDidStopChanging instead")
|
||||
deprecate("Use TextEditor::onDidStopChanging instead")
|
||||
when 'contents-conflicted'
|
||||
deprecate("Use Editor::onDidConflict instead")
|
||||
deprecate("Use TextEditor::onDidConflict instead")
|
||||
|
||||
when 'will-insert-text'
|
||||
deprecate("Use Editor::onWillInsertText instead")
|
||||
deprecate("Use TextEditor::onWillInsertText instead")
|
||||
when 'did-insert-text'
|
||||
deprecate("Use Editor::onDidInsertText instead")
|
||||
deprecate("Use TextEditor::onDidInsertText instead")
|
||||
|
||||
when 'cursor-added'
|
||||
deprecate("Use Editor::onDidAddCursor instead")
|
||||
deprecate("Use TextEditor::onDidAddCursor instead")
|
||||
when 'cursor-removed'
|
||||
deprecate("Use Editor::onDidRemoveCursor instead")
|
||||
deprecate("Use TextEditor::onDidRemoveCursor instead")
|
||||
when 'cursor-moved'
|
||||
deprecate("Use Editor::onDidChangeCursorPosition instead")
|
||||
deprecate("Use TextEditor::onDidChangeCursorPosition instead")
|
||||
|
||||
when 'selection-added'
|
||||
deprecate("Use Editor::onDidAddSelection instead")
|
||||
deprecate("Use TextEditor::onDidAddSelection instead")
|
||||
when 'selection-removed'
|
||||
deprecate("Use Editor::onDidRemoveSelection instead")
|
||||
deprecate("Use TextEditor::onDidRemoveSelection instead")
|
||||
when 'selection-screen-range-changed'
|
||||
deprecate("Use Editor::onDidChangeSelectionRange instead")
|
||||
deprecate("Use TextEditor::onDidChangeSelectionRange instead")
|
||||
|
||||
when 'decoration-added'
|
||||
deprecate("Use Editor::onDidAddDecoration instead")
|
||||
deprecate("Use TextEditor::onDidAddDecoration instead")
|
||||
when 'decoration-removed'
|
||||
deprecate("Use Editor::onDidRemoveDecoration instead")
|
||||
deprecate("Use TextEditor::onDidRemoveDecoration instead")
|
||||
when 'decoration-updated'
|
||||
deprecate("Use Decoration::onDidChangeProperties instead. You will get the decoration back from `Editor::decorateMarker()`")
|
||||
deprecate("Use Decoration::onDidChangeProperties instead. You will get the decoration back from `TextEditor::decorateMarker()`")
|
||||
when 'decoration-changed'
|
||||
deprecate("Use Marker::onDidChange instead. eg. `editor::decorateMarker(...).getMarker().onDidChange()`")
|
||||
|
||||
when 'screen-lines-changed'
|
||||
deprecate("Use Editor::onDidChange instead")
|
||||
deprecate("Use TextEditor::onDidChange instead")
|
||||
|
||||
when 'scroll-top-changed'
|
||||
deprecate("Use Editor::onDidChangeScrollTop instead")
|
||||
deprecate("Use TextEditor::onDidChangeScrollTop instead")
|
||||
when 'scroll-left-changed'
|
||||
deprecate("Use Editor::onDidChangeScrollLeft instead")
|
||||
deprecate("Use TextEditor::onDidChangeScrollLeft instead")
|
||||
|
||||
EmitterMixin::on.apply(this, arguments)
|
||||
|
||||
@@ -477,12 +486,12 @@ class Editor extends Model
|
||||
# Retrieves the current buffer's URI.
|
||||
getUri: -> @buffer.getUri()
|
||||
|
||||
# Create an {Editor} with its initial state based on this object
|
||||
# Create an {TextEditor} with its initial state based on this object
|
||||
copy: ->
|
||||
tabLength = @getTabLength()
|
||||
displayBuffer = @displayBuffer.copy()
|
||||
softTabs = @getSoftTabs()
|
||||
newEditor = new Editor({@buffer, displayBuffer, tabLength, softTabs, suppressCursorCreation: true, registerEditor: true})
|
||||
newEditor = new TextEditor({@buffer, displayBuffer, tabLength, softTabs, suppressCursorCreation: true, registerEditor: true})
|
||||
for marker in @findMarkers(editorId: @id)
|
||||
marker.copy(editorId: newEditor.id, preserveFolds: true)
|
||||
newEditor
|
||||
@@ -498,7 +507,7 @@ class Editor extends Model
|
||||
# Set the number of characters that can be displayed horizontally in the
|
||||
# editor.
|
||||
#
|
||||
# * `editorWidthInChars` A {Number} representing the width of the {EditorView}
|
||||
# * `editorWidthInChars` A {Number} representing the width of the {TextEditorView}
|
||||
# in characters.
|
||||
setEditorWidthInChars: (editorWidthInChars) ->
|
||||
@displayBuffer.setEditorWidthInChars(editorWidthInChars)
|
||||
@@ -606,7 +615,7 @@ class Editor extends Model
|
||||
# * `bufferRow` A {Number} representing a zero-indexed buffer row.
|
||||
lineTextForBufferRow: (bufferRow) -> @buffer.lineForRow(bufferRow)
|
||||
lineForBufferRow: (bufferRow) ->
|
||||
deprecate 'Use Editor::lineTextForBufferRow(bufferRow) instead'
|
||||
deprecate 'Use TextEditor::lineTextForBufferRow(bufferRow) instead'
|
||||
@lineTextForBufferRow(bufferRow)
|
||||
|
||||
# Essential: Returns a {String} representing the contents of the line at the
|
||||
@@ -622,13 +631,13 @@ class Editor extends Model
|
||||
# Returns {TokenizedLine}
|
||||
tokenizedLineForScreenRow: (screenRow) -> @displayBuffer.tokenizedLineForScreenRow(screenRow)
|
||||
lineForScreenRow: (screenRow) ->
|
||||
deprecate "Editor::tokenizedLineForScreenRow(bufferRow) is the new name. But it's private. Try to use Editor::lineTextForScreenRow instead"
|
||||
deprecate "TextEditor::tokenizedLineForScreenRow(bufferRow) is the new name. But it's private. Try to use TextEditor::lineTextForScreenRow instead"
|
||||
@tokenizedLineForScreenRow(screenRow)
|
||||
|
||||
# {Delegates to: DisplayBuffer.tokenizedLinesForScreenRows}
|
||||
tokenizedLinesForScreenRows: (start, end) -> @displayBuffer.tokenizedLinesForScreenRows(start, end)
|
||||
linesForScreenRows: (start, end) ->
|
||||
deprecate "Use Editor::tokenizedLinesForScreenRows instead"
|
||||
deprecate "Use TextEditor::tokenizedLinesForScreenRows instead"
|
||||
@tokenizedLinesForScreenRows(start, end)
|
||||
|
||||
# Returns a {Number} representing the line length for the given
|
||||
@@ -880,7 +889,7 @@ class Editor extends Model
|
||||
|
||||
# Deprecated: Use {::duplicateLines} instead.
|
||||
duplicateLine: ->
|
||||
deprecate("Use Editor::duplicateLines() instead")
|
||||
deprecate("Use TextEditor::duplicateLines() instead")
|
||||
@duplicateLines()
|
||||
|
||||
replaceSelectedText: (options={}, fn) ->
|
||||
@@ -1015,12 +1024,12 @@ class Editor extends Model
|
||||
|
||||
# Deprecated: Use {::deleteToBeginningOfWord} instead.
|
||||
backspaceToBeginningOfWord: ->
|
||||
deprecate("Use Editor::deleteToBeginningOfWord() instead")
|
||||
deprecate("Use TextEditor::deleteToBeginningOfWord() instead")
|
||||
@deleteToBeginningOfWord()
|
||||
|
||||
# Deprecated: Use {::deleteToBeginningOfLine} instead.
|
||||
backspaceToBeginningOfLine: ->
|
||||
deprecate("Use Editor::deleteToBeginningOfLine() instead")
|
||||
deprecate("Use TextEditor::deleteToBeginningOfLine() instead")
|
||||
@deleteToBeginningOfLine()
|
||||
|
||||
###
|
||||
@@ -1066,7 +1075,7 @@ class Editor extends Model
|
||||
abortTransaction: -> @buffer.abortTransaction()
|
||||
|
||||
###
|
||||
Section: Editor Coordinates
|
||||
Section: TextEditor Coordinates
|
||||
###
|
||||
|
||||
# Essential: Convert a position in buffer-coordinates to screen-coordinates.
|
||||
@@ -1429,7 +1438,7 @@ class Editor extends Model
|
||||
moveUp: (lineCount) ->
|
||||
@moveCursors (cursor) -> cursor.moveUp(lineCount, moveToEndOfSelection: true)
|
||||
moveCursorUp: (lineCount) ->
|
||||
deprecate("Use Editor::moveUp() instead")
|
||||
deprecate("Use TextEditor::moveUp() instead")
|
||||
@moveUp(lineCount)
|
||||
|
||||
# Essential: Move every cursor down one row in screen coordinates.
|
||||
@@ -1438,7 +1447,7 @@ class Editor extends Model
|
||||
moveDown: (lineCount) ->
|
||||
@moveCursors (cursor) -> cursor.moveDown(lineCount, moveToEndOfSelection: true)
|
||||
moveCursorDown: (lineCount) ->
|
||||
deprecate("Use Editor::moveDown() instead")
|
||||
deprecate("Use TextEditor::moveDown() instead")
|
||||
@moveDown(lineCount)
|
||||
|
||||
# Essential: Move every cursor left one column.
|
||||
@@ -1447,7 +1456,7 @@ class Editor extends Model
|
||||
moveLeft: (columnCount) ->
|
||||
@moveCursors (cursor) -> cursor.moveLeft(columnCount, moveToEndOfSelection: true)
|
||||
moveCursorLeft: ->
|
||||
deprecate("Use Editor::moveLeft() instead")
|
||||
deprecate("Use TextEditor::moveLeft() instead")
|
||||
@moveLeft()
|
||||
|
||||
# Essential: Move every cursor right one column.
|
||||
@@ -1456,56 +1465,56 @@ class Editor extends Model
|
||||
moveRight: (columnCount) ->
|
||||
@moveCursors (cursor) -> cursor.moveRight(columnCount, moveToEndOfSelection: true)
|
||||
moveCursorRight: ->
|
||||
deprecate("Use Editor::moveRight() instead")
|
||||
deprecate("Use TextEditor::moveRight() instead")
|
||||
@moveRight()
|
||||
|
||||
# Essential: Move every cursor to the beginning of its line in buffer coordinates.
|
||||
moveToBeginningOfLine: ->
|
||||
@moveCursors (cursor) -> cursor.moveToBeginningOfLine()
|
||||
moveCursorToBeginningOfLine: ->
|
||||
deprecate("Use Editor::moveToBeginningOfLine() instead")
|
||||
deprecate("Use TextEditor::moveToBeginningOfLine() instead")
|
||||
@moveToBeginningOfLine()
|
||||
|
||||
# Essential: Move every cursor to the beginning of its line in screen coordinates.
|
||||
moveToBeginningOfScreenLine: ->
|
||||
@moveCursors (cursor) -> cursor.moveToBeginningOfScreenLine()
|
||||
moveCursorToBeginningOfScreenLine: ->
|
||||
deprecate("Use Editor::moveToBeginningOfScreenLine() instead")
|
||||
deprecate("Use TextEditor::moveToBeginningOfScreenLine() instead")
|
||||
@moveToBeginningOfScreenLine()
|
||||
|
||||
# Essential: Move every cursor to the first non-whitespace character of its line.
|
||||
moveToFirstCharacterOfLine: ->
|
||||
@moveCursors (cursor) -> cursor.moveToFirstCharacterOfLine()
|
||||
moveCursorToFirstCharacterOfLine: ->
|
||||
deprecate("Use Editor::moveToFirstCharacterOfLine() instead")
|
||||
deprecate("Use TextEditor::moveToFirstCharacterOfLine() instead")
|
||||
@moveToFirstCharacterOfLine()
|
||||
|
||||
# Essential: Move every cursor to the end of its line in buffer coordinates.
|
||||
moveToEndOfLine: ->
|
||||
@moveCursors (cursor) -> cursor.moveToEndOfLine()
|
||||
moveCursorToEndOfLine: ->
|
||||
deprecate("Use Editor::moveToEndOfLine() instead")
|
||||
deprecate("Use TextEditor::moveToEndOfLine() instead")
|
||||
@moveToEndOfLine()
|
||||
|
||||
# Essential: Move every cursor to the end of its line in screen coordinates.
|
||||
moveToEndOfScreenLine: ->
|
||||
@moveCursors (cursor) -> cursor.moveToEndOfScreenLine()
|
||||
moveCursorToEndOfScreenLine: ->
|
||||
deprecate("Use Editor::moveToEndOfScreenLine() instead")
|
||||
deprecate("Use TextEditor::moveToEndOfScreenLine() instead")
|
||||
@moveToEndOfScreenLine()
|
||||
|
||||
# Essential: Move every cursor to the beginning of its surrounding word.
|
||||
moveToBeginningOfWord: ->
|
||||
@moveCursors (cursor) -> cursor.moveToBeginningOfWord()
|
||||
moveCursorToBeginningOfWord: ->
|
||||
deprecate("Use Editor::moveToBeginningOfWord() instead")
|
||||
deprecate("Use TextEditor::moveToBeginningOfWord() instead")
|
||||
@moveToBeginningOfWord()
|
||||
|
||||
# Essential: Move every cursor to the end of its surrounding word.
|
||||
moveToEndOfWord: ->
|
||||
@moveCursors (cursor) -> cursor.moveToEndOfWord()
|
||||
moveCursorToEndOfWord: ->
|
||||
deprecate("Use Editor::moveToEndOfWord() instead")
|
||||
deprecate("Use TextEditor::moveToEndOfWord() instead")
|
||||
@moveToEndOfWord()
|
||||
|
||||
# Cursor Extended
|
||||
@@ -1516,7 +1525,7 @@ class Editor extends Model
|
||||
moveToTop: ->
|
||||
@moveCursors (cursor) -> cursor.moveToTop()
|
||||
moveCursorToTop: ->
|
||||
deprecate("Use Editor::moveToTop() instead")
|
||||
deprecate("Use TextEditor::moveToTop() instead")
|
||||
@moveToTop()
|
||||
|
||||
# Extended: Move every cursor to the bottom of the buffer.
|
||||
@@ -1525,42 +1534,42 @@ class Editor extends Model
|
||||
moveToBottom: ->
|
||||
@moveCursors (cursor) -> cursor.moveToBottom()
|
||||
moveCursorToBottom: ->
|
||||
deprecate("Use Editor::moveToBottom() instead")
|
||||
deprecate("Use TextEditor::moveToBottom() instead")
|
||||
@moveToBottom()
|
||||
|
||||
# Extended: Move every cursor to the beginning of the next word.
|
||||
moveToBeginningOfNextWord: ->
|
||||
@moveCursors (cursor) -> cursor.moveToBeginningOfNextWord()
|
||||
moveCursorToBeginningOfNextWord: ->
|
||||
deprecate("Use Editor::moveToBeginningOfNextWord() instead")
|
||||
deprecate("Use TextEditor::moveToBeginningOfNextWord() instead")
|
||||
@moveToBeginningOfNextWord()
|
||||
|
||||
# Extended: Move every cursor to the previous word boundary.
|
||||
moveToPreviousWordBoundary: ->
|
||||
@moveCursors (cursor) -> cursor.moveToPreviousWordBoundary()
|
||||
moveCursorToPreviousWordBoundary: ->
|
||||
deprecate("Use Editor::moveToPreviousWordBoundary() instead")
|
||||
deprecate("Use TextEditor::moveToPreviousWordBoundary() instead")
|
||||
@moveToPreviousWordBoundary()
|
||||
|
||||
# Extended: Move every cursor to the next word boundary.
|
||||
moveToNextWordBoundary: ->
|
||||
@moveCursors (cursor) -> cursor.moveToNextWordBoundary()
|
||||
moveCursorToNextWordBoundary: ->
|
||||
deprecate("Use Editor::moveToNextWordBoundary() instead")
|
||||
deprecate("Use TextEditor::moveToNextWordBoundary() instead")
|
||||
@moveToNextWordBoundary()
|
||||
|
||||
# Extended: Move every cursor to the beginning of the next paragraph.
|
||||
moveToBeginningOfNextParagraph: ->
|
||||
@moveCursors (cursor) -> cursor.moveToBeginningOfNextParagraph()
|
||||
moveCursorToBeginningOfNextParagraph: ->
|
||||
deprecate("Use Editor::moveToBeginningOfNextParagraph() instead")
|
||||
deprecate("Use TextEditor::moveToBeginningOfNextParagraph() instead")
|
||||
@moveToBeginningOfNextParagraph()
|
||||
|
||||
# Extended: Move every cursor to the beginning of the previous paragraph.
|
||||
moveToBeginningOfPreviousParagraph: ->
|
||||
@moveCursors (cursor) -> cursor.moveToBeginningOfPreviousParagraph()
|
||||
moveCursorToBeginningOfPreviousParagraph: ->
|
||||
deprecate("Use Editor::moveToBeginningOfPreviousParagraph() instead")
|
||||
deprecate("Use TextEditor::moveToBeginningOfPreviousParagraph() instead")
|
||||
@moveToBeginningOfPreviousParagraph()
|
||||
|
||||
# Extended: Returns the most recently added {Cursor}
|
||||
@@ -1569,7 +1578,7 @@ class Editor extends Model
|
||||
|
||||
# Deprecated:
|
||||
getCursor: ->
|
||||
deprecate("Use Editor::getLastCursor() instead")
|
||||
deprecate("Use TextEditor::getLastCursor() instead")
|
||||
@getLastCursor()
|
||||
|
||||
# Extended: Returns the word surrounding the most recently added cursor.
|
||||
@@ -1883,14 +1892,14 @@ class Editor extends Model
|
||||
selectLinesContainingCursors: ->
|
||||
@expandSelectionsForward (selection) -> selection.selectLine()
|
||||
selectLine: ->
|
||||
deprecate('Use Editor::selectLinesContainingCursors instead')
|
||||
deprecate('Use TextEditor::selectLinesContainingCursors instead')
|
||||
@selectLinesContainingCursors()
|
||||
|
||||
# Essential: Select the word surrounding each cursor.
|
||||
selectWordsContainingCursors: ->
|
||||
@expandSelectionsForward (selection) -> selection.selectWord()
|
||||
selectWord: ->
|
||||
deprecate('Use Editor::selectWordsContainingCursors instead')
|
||||
deprecate('Use TextEditor::selectWordsContainingCursors instead')
|
||||
@selectWordsContainingCursors()
|
||||
|
||||
# Selection Extended
|
||||
@@ -1950,10 +1959,10 @@ class Editor extends Model
|
||||
# Deprecated:
|
||||
getSelection: (index) ->
|
||||
if index?
|
||||
deprecate("Use Editor::getSelections()[index] instead when getting a specific selection")
|
||||
deprecate("Use TextEditor::getSelections()[index] instead when getting a specific selection")
|
||||
@getSelections()[index]
|
||||
else
|
||||
deprecate("Use Editor::getLastSelection() instead")
|
||||
deprecate("Use TextEditor::getLastSelection() instead")
|
||||
@getLastSelection()
|
||||
|
||||
# Extended: Get current {Selection}s.
|
||||
@@ -2213,7 +2222,7 @@ class Editor extends Model
|
||||
# Returns a {Boolean}.
|
||||
isSoftWrapped: (softWrapped) -> @displayBuffer.isSoftWrapped()
|
||||
getSoftWrapped: ->
|
||||
deprecate("Use Editor::isSoftWrapped instead")
|
||||
deprecate("Use TextEditor::isSoftWrapped instead")
|
||||
@displayBuffer.isSoftWrapped()
|
||||
|
||||
# Essential: Enable or disable soft wrapping for this editor.
|
||||
@@ -2223,7 +2232,7 @@ class Editor extends Model
|
||||
# Returns a {Boolean}.
|
||||
setSoftWrapped: (softWrapped) -> @displayBuffer.setSoftWrapped(softWrapped)
|
||||
setSoftWrap: (softWrapped) ->
|
||||
deprecate("Use Editor::setSoftWrapped instead")
|
||||
deprecate("Use TextEditor::setSoftWrapped instead")
|
||||
@setSoftWrapped(softWrapped)
|
||||
|
||||
# Essential: Toggle soft wrapping for this editor
|
||||
@@ -2231,7 +2240,7 @@ class Editor extends Model
|
||||
# Returns a {Boolean}.
|
||||
toggleSoftWrapped: -> @setSoftWrapped(not @isSoftWrapped())
|
||||
toggleSoftWrap: ->
|
||||
deprecate("Use Editor::toggleSoftWrapped instead")
|
||||
deprecate("Use TextEditor::toggleSoftWrapped instead")
|
||||
@toggleSoftWrapped()
|
||||
|
||||
# Public: Gets the column at which column will soft wrap
|
||||
@@ -2345,7 +2354,7 @@ class Editor extends Model
|
||||
# Returns an {Array} of {String}s.
|
||||
scopesAtCursor: -> @getLastCursor().getScopes()
|
||||
getCursorScopes: ->
|
||||
deprecate 'Use Editor::scopesAtCursor() instead'
|
||||
deprecate 'Use TextEditor::scopesAtCursor() instead'
|
||||
@scopesAtCursor()
|
||||
|
||||
# Essential: Get the syntactic scopes for the given position in buffer
|
||||
@@ -2565,7 +2574,7 @@ class Editor extends Model
|
||||
@displayBuffer.outermostFoldsInBufferRowRange(startRow, endRow)
|
||||
|
||||
###
|
||||
Section: Scrolling the Editor
|
||||
Section: Scrolling the TextEditor
|
||||
###
|
||||
|
||||
# Essential: Scroll the editor to reveal the most recently added cursor if it is
|
||||
@@ -2667,9 +2676,24 @@ class Editor extends Model
|
||||
@addSelection(marker)
|
||||
|
||||
###
|
||||
Section: Editor Rendering
|
||||
Section: TextEditor Rendering
|
||||
###
|
||||
|
||||
# Public: Retrieves the greyed out placeholder of a mini editor.
|
||||
#
|
||||
# Returns a {String}.
|
||||
getPlaceholderText: ->
|
||||
@placeholderText
|
||||
|
||||
# Public: Set the greyed out placeholder of a mini editor. Placeholder text
|
||||
# will be displayed when the editor has no content.
|
||||
#
|
||||
# * `placeholderText` {String} text that is displayed when the editor has no content.
|
||||
setPlaceholderText: (placeholderText) ->
|
||||
return if @placeholderText is placeholderText
|
||||
@placeholderText = placeholderText
|
||||
@emitter.emit 'did-change-placeholder-text', @placeholderText
|
||||
|
||||
# Extended: Retrieves the number of the row that is visible and currently at the
|
||||
# top of the editor.
|
||||
#
|
||||
@@ -2759,7 +2783,7 @@ class Editor extends Model
|
||||
|
||||
# Deprecated: Call {::joinLines} instead.
|
||||
joinLine: ->
|
||||
deprecate("Use Editor::joinLines() instead")
|
||||
deprecate("Use TextEditor::joinLines() instead")
|
||||
@joinLines()
|
||||
|
||||
###
|
||||
@@ -2767,6 +2791,6 @@ class Editor extends Model
|
||||
###
|
||||
|
||||
inspect: ->
|
||||
"<Editor #{@id}>"
|
||||
"<TextEditor #{@id}>"
|
||||
|
||||
logScreenLines: (start, end) -> @displayBuffer.logLines(start, end)
|
||||
@@ -0,0 +1,45 @@
|
||||
{Disposable} = require 'event-kit'
|
||||
{jQuery} = require './space-pen-extensions'
|
||||
|
||||
module.exports =
|
||||
class ViewRegistry
|
||||
constructor: ->
|
||||
@views = new WeakMap
|
||||
@providers = []
|
||||
|
||||
addViewProvider: (providerSpec) ->
|
||||
@providers.push(providerSpec)
|
||||
new Disposable =>
|
||||
@providers = @providers.filter (provider) -> provider isnt providerSpec
|
||||
|
||||
getView: (object) ->
|
||||
return unless object?
|
||||
|
||||
if view = @views.get(object)
|
||||
view
|
||||
else
|
||||
view = @createView(object)
|
||||
@views.set(object, view)
|
||||
view
|
||||
|
||||
createView: (object) ->
|
||||
if object instanceof HTMLElement
|
||||
object
|
||||
else if object instanceof jQuery
|
||||
object[0].__spacePenView ?= object
|
||||
object[0]
|
||||
else if provider = @findProvider(object)
|
||||
element = provider.createView?(object)
|
||||
unless element?
|
||||
element = new provider.viewConstructor
|
||||
element.setModel(object)
|
||||
element
|
||||
else if viewConstructor = object?.getViewClass?()
|
||||
view = new viewConstructor(object)
|
||||
view[0].__spacePenView ?= view
|
||||
view[0]
|
||||
else
|
||||
throw new Error("Can't create a view for #{object.constructor.name} instance. Please register a view provider.")
|
||||
|
||||
findProvider: (object) ->
|
||||
@providers.find ({modelConstructor}) -> object instanceof modelConstructor
|
||||
+24
-24
@@ -13,7 +13,7 @@ PaneView = require './pane-view'
|
||||
PaneColumnView = require './pane-column-view'
|
||||
PaneRowView = require './pane-row-view'
|
||||
PaneContainerView = require './pane-container-view'
|
||||
Editor = require './editor'
|
||||
TextEditor = require './text-editor'
|
||||
|
||||
atom.commands.add '.workspace',
|
||||
'window:increase-font-size': -> @getModel().increaseFontSize()
|
||||
@@ -87,7 +87,7 @@ class WorkspaceView extends View
|
||||
@element.getModel = -> model
|
||||
atom.commands.setRootNode(@[0])
|
||||
|
||||
panes = new PaneContainerView(@model.paneContainer)
|
||||
panes = @model.getView(@model.paneContainer).__spacePenView
|
||||
@panes.replaceWith(panes)
|
||||
@panes = panes
|
||||
|
||||
@@ -183,11 +183,11 @@ class WorkspaceView extends View
|
||||
###
|
||||
|
||||
# Essential: Register a function to be called for every current and future
|
||||
# editor view in the workspace (only includes {EditorView}s that are pane
|
||||
# editor view in the workspace (only includes {TextEditorView}s that are pane
|
||||
# items).
|
||||
#
|
||||
# * `callback` A {Function} with an {EditorView} as its only argument.
|
||||
# * `editorView` {EditorView}
|
||||
# * `callback` A {Function} with an {TextEditorView} as its only argument.
|
||||
# * `editorView` {TextEditorView}
|
||||
#
|
||||
# Returns a subscription object with an `.off` method that you can call to
|
||||
# unregister the callback.
|
||||
@@ -403,7 +403,7 @@ class WorkspaceView extends View
|
||||
# to the view objects. Also consider using {::eachEditorView}, which will call
|
||||
# a callback for all current and *future* editor views.
|
||||
#
|
||||
# Returns an {Array} of {EditorView}s.
|
||||
# Returns an {Array} of {TextEditorView}s.
|
||||
getEditorViews: ->
|
||||
for editorElement in @panes.element.querySelectorAll('.pane > .item-views > .editor')
|
||||
$(editorElement).view()
|
||||
@@ -421,13 +421,13 @@ class WorkspaceView extends View
|
||||
when 'beep'
|
||||
deprecate('Use Atom::onDidBeep instead')
|
||||
when 'cursor:moved'
|
||||
deprecate('Use Editor::onDidChangeCursorPosition instead')
|
||||
deprecate('Use TextEditor::onDidChangeCursorPosition instead')
|
||||
when 'editor:attached'
|
||||
deprecate('Use Editor::onDidAddTextEditor instead')
|
||||
deprecate('Use TextEditor::onDidAddTextEditor instead')
|
||||
when 'editor:detached'
|
||||
deprecate('Use Editor::onDidDestroy instead')
|
||||
deprecate('Use TextEditor::onDidDestroy instead')
|
||||
when 'editor:will-be-removed'
|
||||
deprecate('Use Editor::onDidDestroy instead')
|
||||
deprecate('Use TextEditor::onDidDestroy instead')
|
||||
when 'pane:active-item-changed'
|
||||
deprecate('Use Pane::onDidChangeActiveItem instead')
|
||||
when 'pane:active-item-modified-status-changed'
|
||||
@@ -451,38 +451,38 @@ class WorkspaceView extends View
|
||||
when 'pane-container:active-pane-item-changed'
|
||||
deprecate('Use Workspace::onDidChangeActivePaneItem instead')
|
||||
when 'selection:changed'
|
||||
deprecate('Use Editor::onDidChangeSelectionRange instead')
|
||||
deprecate('Use TextEditor::onDidChangeSelectionRange instead')
|
||||
when 'uri-opened'
|
||||
deprecate('Use Workspace::onDidOpen instead')
|
||||
originalWorkspaceViewOn.apply(this, arguments)
|
||||
|
||||
EditorView = require './editor-view'
|
||||
originalEditorViewOn = EditorView::on
|
||||
EditorView::on = (eventName) ->
|
||||
TextEditorView = require './text-editor-view'
|
||||
originalEditorViewOn = TextEditorView::on
|
||||
TextEditorView::on = (eventName) ->
|
||||
switch eventName
|
||||
when 'cursor:moved'
|
||||
deprecate('Use Editor::onDidChangeCursorPosition instead')
|
||||
deprecate('Use TextEditor::onDidChangeCursorPosition instead')
|
||||
when 'editor:attached'
|
||||
deprecate('Use Editor::onDidAddTextEditor instead')
|
||||
deprecate('Use TextEditor::onDidAddTextEditor instead')
|
||||
when 'editor:detached'
|
||||
deprecate('Use Editor::onDidDestroy instead')
|
||||
deprecate('Use TextEditor::onDidDestroy instead')
|
||||
when 'editor:will-be-removed'
|
||||
deprecate('Use Editor::onDidDestroy instead')
|
||||
deprecate('Use TextEditor::onDidDestroy instead')
|
||||
when 'selection:changed'
|
||||
deprecate('Use Editor::onDidChangeSelectionRange instead')
|
||||
deprecate('Use TextEditor::onDidChangeSelectionRange instead')
|
||||
originalEditorViewOn.apply(this, arguments)
|
||||
|
||||
originalPaneViewOn = PaneView::on
|
||||
PaneView::on = (eventName) ->
|
||||
switch eventName
|
||||
when 'cursor:moved'
|
||||
deprecate('Use Editor::onDidChangeCursorPosition instead')
|
||||
deprecate('Use TextEditor::onDidChangeCursorPosition instead')
|
||||
when 'editor:attached'
|
||||
deprecate('Use Editor::onDidAddTextEditor instead')
|
||||
deprecate('Use TextEditor::onDidAddTextEditor instead')
|
||||
when 'editor:detached'
|
||||
deprecate('Use Editor::onDidDestroy instead')
|
||||
deprecate('Use TextEditor::onDidDestroy instead')
|
||||
when 'editor:will-be-removed'
|
||||
deprecate('Use Editor::onDidDestroy instead')
|
||||
deprecate('Use TextEditor::onDidDestroy instead')
|
||||
when 'pane:active-item-changed'
|
||||
deprecate('Use Pane::onDidChangeActiveItem instead')
|
||||
when 'pane:active-item-modified-status-changed'
|
||||
@@ -504,7 +504,7 @@ class WorkspaceView extends View
|
||||
when 'pane:removed'
|
||||
deprecate('Use Pane::onDidDestroy instead')
|
||||
when 'selection:changed'
|
||||
deprecate('Use Editor::onDidChangeSelectionRange instead')
|
||||
deprecate('Use TextEditor::onDidChangeSelectionRange instead')
|
||||
originalPaneViewOn.apply(this, arguments)
|
||||
|
||||
# Deprecated
|
||||
|
||||
+106
-15
@@ -6,9 +6,11 @@ Q = require 'q'
|
||||
Serializable = require 'serializable'
|
||||
Delegator = require 'delegato'
|
||||
{Emitter} = require 'event-kit'
|
||||
Editor = require './editor'
|
||||
TextEditor = require './text-editor'
|
||||
PaneContainer = require './pane-container'
|
||||
Pane = require './pane'
|
||||
ViewRegistry = require './view-registry'
|
||||
WorkspaceView = null
|
||||
|
||||
# Essential: Represents the state of the user interface for the entire window.
|
||||
# An instance of this class is available via the `atom.workspace` global.
|
||||
@@ -17,7 +19,7 @@ Pane = require './pane'
|
||||
# editors, and manipulate panes. To add panels, you'll need to use the
|
||||
# {WorkspaceView} class for now until we establish APIs at the model layer.
|
||||
#
|
||||
# * `editor` {Editor} the new editor
|
||||
# * `editor` {TextEditor} the new editor
|
||||
#
|
||||
module.exports =
|
||||
class Workspace extends Model
|
||||
@@ -27,7 +29,7 @@ class Workspace extends Model
|
||||
@delegatesProperty 'activePane', 'activePaneItem', toProperty: 'paneContainer'
|
||||
|
||||
@properties
|
||||
paneContainer: -> new PaneContainer
|
||||
paneContainer: null
|
||||
fullScreen: false
|
||||
destroyedItemUris: -> []
|
||||
|
||||
@@ -37,6 +39,8 @@ class Workspace extends Model
|
||||
@emitter = new Emitter
|
||||
@openers = []
|
||||
|
||||
@viewRegistry ?= new ViewRegistry
|
||||
@paneContainer ?= new PaneContainer({@viewRegistry})
|
||||
@paneContainer.onDidDestroyPaneItem(@onPaneItemDestroyed)
|
||||
|
||||
@registerOpener (filePath) =>
|
||||
@@ -55,6 +59,8 @@ class Workspace extends Model
|
||||
for packageName in params.packagesWithActiveGrammars ? []
|
||||
atom.packages.getLoadedPackage(packageName)?.loadGrammarsSync()
|
||||
|
||||
params.viewRegistry = new ViewRegistry
|
||||
params.paneContainer.viewRegistry = params.viewRegistry
|
||||
params.paneContainer = PaneContainer.deserialize(params.paneContainer)
|
||||
params
|
||||
|
||||
@@ -64,6 +70,9 @@ class Workspace extends Model
|
||||
fullScreen: atom.isFullScreen()
|
||||
packagesWithActiveGrammars: @getPackageNamesWithActiveGrammars()
|
||||
|
||||
getViewClass: ->
|
||||
WorkspaceView ?= require './workspace-view'
|
||||
|
||||
getPackageNamesWithActiveGrammars: ->
|
||||
packageNames = []
|
||||
addGrammar = ({includedGrammarScopes, packageName}={}) ->
|
||||
@@ -95,7 +104,7 @@ class Workspace extends Model
|
||||
# editors in the workspace.
|
||||
#
|
||||
# * `callback` {Function} to be called with current and future text editors.
|
||||
# * `editor` An {Editor} that is present in {::getTextEditors} at the time
|
||||
# * `editor` An {TextEditor} that is present in {::getTextEditors} at the time
|
||||
# of subscription or that is added at some later time.
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
|
||||
@@ -191,7 +200,7 @@ class Workspace extends Model
|
||||
#
|
||||
# * `callback` {Function} to be called panes are added.
|
||||
# * `event` {Object} with the following keys:
|
||||
# * `textEditor` {Editor} that was added.
|
||||
# * `textEditor` {TextEditor} that was added.
|
||||
# * `pane` {Pane} containing the added text editor.
|
||||
# * `index` {Number} indicating the index of the added text editor in its
|
||||
# pane.
|
||||
@@ -199,7 +208,7 @@ class Workspace extends Model
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
|
||||
onDidAddTextEditor: (callback) ->
|
||||
@onDidAddPaneItem ({item, pane, index}) ->
|
||||
callback({textEditor: item, pane, index}) if item instanceof Editor
|
||||
callback({textEditor: item, pane, index}) if item instanceof TextEditor
|
||||
|
||||
eachEditor: (callback) ->
|
||||
deprecate("Use Workspace::observeTextEditors instead")
|
||||
@@ -212,7 +221,7 @@ class Workspace extends Model
|
||||
|
||||
editors = []
|
||||
for pane in @paneContainer.getPanes()
|
||||
editors.push(item) for item in pane.getItems() when item instanceof Editor
|
||||
editors.push(item) for item in pane.getItems() when item instanceof TextEditor
|
||||
|
||||
editors
|
||||
|
||||
@@ -249,7 +258,7 @@ class Workspace extends Model
|
||||
# If `false`, only the active pane will be searched for
|
||||
# an existing item for the same URI. Defaults to `false`.
|
||||
#
|
||||
# Returns a promise that resolves to the {Editor} for the file URI.
|
||||
# Returns a promise that resolves to the {TextEditor} for the file URI.
|
||||
open: (uri, options={}) ->
|
||||
searchAllPanes = options.searchAllPanes
|
||||
split = options.split
|
||||
@@ -343,7 +352,7 @@ class Workspace extends Model
|
||||
|
||||
# Public: Register an opener for a uri.
|
||||
#
|
||||
# An {Editor} will be used if no openers return a value.
|
||||
# An {TextEditor} will be used if no openers return a value.
|
||||
#
|
||||
# ## Examples
|
||||
#
|
||||
@@ -382,17 +391,17 @@ class Workspace extends Model
|
||||
|
||||
# Essential: Get all text editors in the workspace.
|
||||
#
|
||||
# Returns an {Array} of {Editor}s.
|
||||
# Returns an {Array} of {TextEditor}s.
|
||||
getTextEditors: ->
|
||||
@getPaneItems().filter (item) -> item instanceof Editor
|
||||
@getPaneItems().filter (item) -> item instanceof TextEditor
|
||||
|
||||
# Essential: Get the active item if it is an {Editor}.
|
||||
# Essential: Get the active item if it is an {TextEditor}.
|
||||
#
|
||||
# Returns an {Editor} or `undefined` if the current active item is not an
|
||||
# {Editor}.
|
||||
# Returns an {TextEditor} or `undefined` if the current active item is not an
|
||||
# {TextEditor}.
|
||||
getActiveTextEditor: ->
|
||||
activeItem = @getActivePaneItem()
|
||||
activeItem if activeItem instanceof Editor
|
||||
activeItem if activeItem instanceof TextEditor
|
||||
|
||||
# Deprecated:
|
||||
getActiveEditor: ->
|
||||
@@ -488,3 +497,85 @@ class Workspace extends Model
|
||||
# Called by Model superclass when destroyed
|
||||
destroyed: ->
|
||||
@paneContainer.destroy()
|
||||
|
||||
###
|
||||
Section: View Management
|
||||
###
|
||||
|
||||
# Essential: Get the view associated with an object in the workspace.
|
||||
#
|
||||
# If you're just *using* the workspace, you shouldn't need to access the view
|
||||
# layer, but view layer access may be necessary if you want to perform DOM
|
||||
# manipulation that isn't supported via the model API.
|
||||
#
|
||||
# ## Examples
|
||||
#
|
||||
# ### Getting An Editor View
|
||||
# ```coffee
|
||||
# textEditor = atom.workspace.getActiveTextEditor()
|
||||
# textEditorView = atom.workspace.getView(textEditor)
|
||||
# ```
|
||||
#
|
||||
# ### Getting A Pane View
|
||||
# ```coffee
|
||||
# pane = atom.workspace.getActivePane()
|
||||
# paneView = atom.workspace.getView(pane)
|
||||
# ```
|
||||
#
|
||||
# ### Getting The Workspace View
|
||||
#
|
||||
# ```coffee
|
||||
# workspaceView = atom.workspace.getView(atom.workspace)
|
||||
# ```
|
||||
#
|
||||
# * `object` The object for which you want to retrieve a view. This can be a
|
||||
# pane item, a pane, or the workspace itself.
|
||||
#
|
||||
# Returns a DOM element.
|
||||
getView: (object) ->
|
||||
@viewRegistry.getView(object)
|
||||
|
||||
# Essential: Add a provider that will be used to construct views in the
|
||||
# workspace's view layer based on model objects in its model layer.
|
||||
#
|
||||
# If you're adding your own kind of pane item, a good strategy for all but the
|
||||
# simplest items is to separate the model and the view. The model handles
|
||||
# application logic and is the primary point of API interaction. The view
|
||||
# just handles presentation.
|
||||
#
|
||||
# Use view providers to inform the workspace how your model objects should be
|
||||
# presented in the DOM. A view provider must always return a DOM node, which
|
||||
# makes [HTML 5 custom elements](http://www.html5rocks.com/en/tutorials/webcomponents/customelements/)
|
||||
# an ideal tool for implementing views in Atom.
|
||||
#
|
||||
# ## Example
|
||||
#
|
||||
# Text editors are divided into a model and a view layer, so when you interact
|
||||
# with methods like `atom.workspace.getActiveTextEditor()` you're only going
|
||||
# to get the model object. We display text editors on screen by teaching the
|
||||
# workspace what view constructor it should use to represent them:
|
||||
#
|
||||
# ```coffee
|
||||
# atom.workspace.addViewProvider
|
||||
# modelConstructor: TextEditor
|
||||
# viewConstructor: TextEditorElement
|
||||
# ```
|
||||
#
|
||||
# * `providerSpec` {Object} containing the following keys:
|
||||
# * `modelConstructor` Constructor {Function} for your model.
|
||||
# * `viewConstructor` (Optional) Constructor {Function} for your view. It
|
||||
# should be a subclass of `HTMLElement` (that is, your view should be a
|
||||
# DOM node) and have a `::setModel()` method which will be called
|
||||
# immediately after construction. If you don't supply this property, you
|
||||
# must supply the `createView` property with a function that never returns
|
||||
# `undefined`.
|
||||
# * `createView` (Optional) Factory {Function} that must return a subclass
|
||||
# of `HTMLElement` or `undefined`. If this property is not present or the
|
||||
# function returns `undefined`, the view provider will fall back to the
|
||||
# `viewConstructor` property. If you don't provide this property, you must
|
||||
# provider a `viewConstructor` property.
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to remove the
|
||||
# added provider.
|
||||
addViewProvider: (providerSpec) ->
|
||||
@viewRegistry.addViewProvider(providerSpec)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
.source {
|
||||
.gfm {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
|
||||
.markup.heading {
|
||||
font-weight: bold;
|
||||
}
|
||||
@@ -17,9 +15,5 @@
|
||||
.comment.quote {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.raw {
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário