Comparar commits
244 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 314833bbac | |||
| e643fe7e7d | |||
| 0d8a05bdb1 | |||
| 7410f9a90d | |||
| 3d98f66330 | |||
| b4977ff617 | |||
| d397001c33 | |||
| bd7de18c7a | |||
| 9ca506de4b | |||
| 532f119b9d | |||
| 187cf2a710 | |||
| a83a6e5127 | |||
| 3f1ce617a7 | |||
| 10e609ba27 | |||
| 6cae6981d8 | |||
| bff396ab1a | |||
| 7f442d045b | |||
| 8918eb4758 | |||
| 628ea72943 | |||
| fc2830bacb | |||
| b5bff9f8b8 | |||
| 5e2181e665 | |||
| b0e91f8b33 | |||
| 635af7f838 | |||
| e537080b64 | |||
| f2c7d171bf | |||
| 7a4a85cb20 | |||
| 2952f4c2ad | |||
| ce668e7139 | |||
| 917b223c6c | |||
| e3302b3f73 | |||
| e3dbd412e1 | |||
| fc9a11959c | |||
| 71155abf57 | |||
| d5458c1865 | |||
| 56af2ca4d7 | |||
| cc1e6e2a1f | |||
| d7c98cb394 | |||
| 4ff5f96fd4 | |||
| 1c1c3617e9 | |||
| 187e264445 | |||
| 493cd24059 | |||
| 3c766d87c2 | |||
| f360ca2cb7 | |||
| ba8bd80173 | |||
| 6102143faf | |||
| 3eadc61a3b | |||
| 2bef7e26d7 | |||
| 7d655bf840 | |||
| 42c4dc6937 | |||
| a4059110f9 | |||
| 952c96d03b | |||
| 4c73f4e968 | |||
| 5f36406b52 | |||
| 385cf0f3df | |||
| e70ad97273 | |||
| 0b7bf34a0f | |||
| 713bce7f0b | |||
| 534704a32c | |||
| 37241a7919 | |||
| 333c5b66d1 | |||
| a47d55f016 | |||
| 7882ac60d8 | |||
| 4fa0b6e783 | |||
| 3a8ddc0cd6 | |||
| 3803b473c5 | |||
| 93d993d876 | |||
| 2b3a3ac3c0 | |||
| c8b2e6ed2a | |||
| 58fa414c21 | |||
| 8872b0bc9b | |||
| c77a6b10de | |||
| f86280a77b | |||
| 65ae582d96 | |||
| 5694f9c703 | |||
| 6c4d1be004 | |||
| 9cfa46ea37 | |||
| 11d5dfee3a | |||
| 864f61c430 | |||
| ca164a0b0b | |||
| e011becc1a | |||
| 25f5717ccf | |||
| 3f0640f4c3 | |||
| 65e8de9db8 | |||
| c1ed25d5dc | |||
| f731769afd | |||
| c466cef7d1 | |||
| b4cb92af99 | |||
| 5e7cbbf506 | |||
| 397e0a8ac2 | |||
| 111b5d1fbe | |||
| b2e86c80c4 | |||
| b77ea04056 | |||
| ba94f38166 | |||
| 7cdaaf2f78 | |||
| 6caf60bd6b | |||
| 19c7086200 | |||
| 1519dda294 | |||
| a7efca8bb4 | |||
| dbe15f7dda | |||
| c81a6737ad | |||
| 5b0d974b43 | |||
| 2b73dff0f4 | |||
| adf0ff0a67 | |||
| c79ef0473d | |||
| d51b955e09 | |||
| 774d7ec0af | |||
| d6f4b00e16 | |||
| 9d81df8670 | |||
| 14a430b939 | |||
| 07de4a70a1 | |||
| eb84ac829b | |||
| b8db56a77b | |||
| 1036f16d1e | |||
| 5ed1cfc259 | |||
| ce5c29fb47 | |||
| f0fd48202c | |||
| d5eb8c21b2 | |||
| 76b9982e04 | |||
| ca7f11f7d0 | |||
| 1c1ace90db | |||
| bdd605e85b | |||
| e1b4b921ba | |||
| ab1ede5fe6 | |||
| 5e6d91d66c | |||
| dbd271f70a | |||
| 527ada47f9 | |||
| afb70d0a95 | |||
| b5f910ad06 | |||
| e412371b88 | |||
| 7b4bc16531 | |||
| e6df30e94c | |||
| d9ba9262bf | |||
| c4be32a5dd | |||
| 0a32f6b5f0 | |||
| f9fe5efbb0 | |||
| 87e723e33b | |||
| 3f0302b256 | |||
| 88d024e73b | |||
| 47a2e57633 | |||
| e7acbb314e | |||
| d6a4c70929 | |||
| 839cad0c2a | |||
| d3845db403 | |||
| 3d68bdf126 | |||
| 0d190d2cd4 | |||
| 4afae028ec | |||
| 5165f0df88 | |||
| 5b7b3501a6 | |||
| c3937d0c4c | |||
| 6e27208c5c | |||
| 91342db0ba | |||
| 8f7123ae12 | |||
| 3a22b3d4b8 | |||
| 919ca82ccd | |||
| d35baac054 | |||
| 9302242299 | |||
| ed90a78ea5 | |||
| 9aa2df7cee | |||
| 41ea18a8f1 | |||
| 5cf37fd13e | |||
| 3e12695914 | |||
| ed1c8897ec | |||
| 75eb0182e9 | |||
| 554165ca48 | |||
| 5a5cb869e2 | |||
| a649d75ab8 | |||
| 255cdbb60a | |||
| bd4e56fd08 | |||
| 5246d784db | |||
| e945b83318 | |||
| 38bd996996 | |||
| 8f3a72e11b | |||
| ddc62efb44 | |||
| 8f08e497a0 | |||
| 8048f8af5f | |||
| 4fc4e36902 | |||
| c66d3fdba0 | |||
| 9b49c2f987 | |||
| bceed13606 | |||
| d99c9edc43 | |||
| 31306a3243 | |||
| 67de17e0c3 | |||
| 3371252656 | |||
| a7e9037e5b | |||
| b3e376ce7c | |||
| d24b664873 | |||
| b8394830a0 | |||
| 7d76105530 | |||
| bbe399196f | |||
| 8c6cdf7358 | |||
| f71bb9349b | |||
| 6bb260140b | |||
| 88aec85f92 | |||
| 61cdee9743 | |||
| 15c3efa6e4 | |||
| a1835efb4e | |||
| 5e0f132d33 | |||
| 2c7c4c95f2 | |||
| 81f115d3db | |||
| c4f872acff | |||
| b3dbb18889 | |||
| 02a278d80c | |||
| c7954a4c5e | |||
| 61fff23be2 | |||
| 7070ed8ae4 | |||
| 101b18e408 | |||
| f0bd3b1c20 | |||
| 921bf8501f | |||
| 594a2d201b | |||
| cb0ba55871 | |||
| 27bcf046b1 | |||
| 44f19610b6 | |||
| a1d2e253ea | |||
| a961a8f644 | |||
| 86b7fec0bb | |||
| 6060e0d8a9 | |||
| c160601a9d | |||
| 56a1ecf6c1 | |||
| 648441ee5c | |||
| 03f0e084e1 | |||
| ab57dc840f | |||
| 2ff5309d54 | |||
| a308903735 | |||
| b6cb604330 | |||
| fb557e9b90 | |||
| 3180ab067c | |||
| 4b7d982eb4 | |||
| fbabc6f455 | |||
| fa759d8128 | |||
| e9ed45671f | |||
| 8cc871f326 | |||
| 3651adbefd | |||
| ff70ded25b | |||
| 244c06b524 | |||
| e7309b254c | |||
| 0cdce9c665 | |||
| 7a10bf1c33 | |||
| a6d5a4ab5d | |||
| 68f3c98872 | |||
| 0b8c0cc431 | |||
| d9eaf8d334 | |||
| 8d29ec4116 | |||
| 1ea54f8c92 |
@@ -1,6 +1,7 @@
|
||||
*.swp
|
||||
*~
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
.project
|
||||
.svn
|
||||
.nvm-version
|
||||
|
||||
@@ -57,6 +57,12 @@ in the proper package's repository.
|
||||
* :non-potable_water: `:non-potable_water:` when plugging memory leaks
|
||||
* :memo: `:memo:` when writing docs
|
||||
* :penguin: `:penguin:` when fixing something on Linux
|
||||
* :apple: `:apple:` when fixing something on Mac OS
|
||||
* :bug: `:bug:` when fixing a bug
|
||||
* :fire: `:fire:` when removing code or files
|
||||
* :green_heart: `:green_heart:` when fixing the CI build
|
||||
* :white_check_mark: `:white_check_mark:` when adding tests
|
||||
* :lock: `:lock:` when dealing with security
|
||||
|
||||
## CoffeeScript Styleguide
|
||||
|
||||
|
||||
+6
-47
@@ -1,14 +1,8 @@
|
||||

|
||||
|
||||
Atom is a hackable text editor for the 21st century.
|
||||
Atom is a hackable text editor for the 21st century, built on [atom-shell](http://github.com/atom/atom-shell), and based on everything we love about our favorite editors. We designed it to be deeply customizable, but still approachable using the default configuration.
|
||||
|
||||
Atom is open source and built on top of [atom-shell](http://github.com/atom/atom-shell).
|
||||
|
||||
Atom is designed to be customizable, but also usable without needing to edit a config file.
|
||||
|
||||
Atom is modern, approachable, and hackable to the core.
|
||||
|
||||
Visit [atom.io](http://atom.io) to learn more.
|
||||
Visit [atom.io](https://atom.io) to learn more.
|
||||
|
||||
## Installing
|
||||
|
||||
@@ -18,45 +12,10 @@ Atom will automatically update when a new release is available.
|
||||
|
||||
## Building
|
||||
|
||||
|
||||
**OS X Requirements**
|
||||
* OS X 10.8 or later
|
||||
* [node.js](http://nodejs.org/)
|
||||
* Command Line Tools for [Xcode](https://developer.apple.com/xcode/downloads/) (Run `xcode-select --install`)
|
||||
|
||||
```sh
|
||||
git clone https://github.com/atom/atom
|
||||
cd atom
|
||||
script/build # Creates application at /Applications/Atom.app
|
||||
```
|
||||
|
||||
**Linux Requirements**
|
||||
* Ubuntu LTS 12.04 64-bit is the recommended platform
|
||||
* [node.js](http://nodejs.org/)
|
||||
* `sudo apt-get install libgnome-keyring-dev`
|
||||
|
||||
```sh
|
||||
git clone https://github.com/atom/atom
|
||||
cd atom
|
||||
script/build # Creates application at /tmp/atom-build/Atom
|
||||
sudo script/grunt install # Installs command to /usr/local/bin/atom
|
||||
```
|
||||
|
||||
**Windows Requirements**
|
||||
* Windows 7 or later
|
||||
* [Visual C++ 2010 Express](http://www.microsoft.com/visualstudio/eng/products/visual-studio-2010-express)
|
||||
* [node.js - 32bit](http://nodejs.org/)
|
||||
* [Python 2.7.x](http://www.python.org/download/)
|
||||
* [GitHub for Windows](http://windows.github.com/)
|
||||
* Clone [atom/atom](https://github.com/atom/atom/) to `C:\Users\<user>\github\atom\`
|
||||
* Add `C:\Python27;C:\Program Files\nodejs;C:\Users\<user>\github\atom\node_modules\`
|
||||
to your PATH
|
||||
* Open the Windows GitHub shell
|
||||
|
||||
```bat
|
||||
cd C:\Users\<user>\github\atom
|
||||
script/build
|
||||
```
|
||||
* [Linux](docs/build-instructions/linux.md)
|
||||
* [OS X](docs/build-instructions/os-x.md)
|
||||
* [FreeBSD](docs/build-instructions/freebsd.md)
|
||||
* [Windows](docs/build-instructions/windows.md)
|
||||
|
||||
## Developing
|
||||
Check out the [guides](https://atom.io/docs/latest) and the [API reference](https://atom.io/docs/api).
|
||||
|
||||
+1
-1
@@ -6,6 +6,6 @@
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "0.46.0"
|
||||
"atom-package-manager": "0.54.0"
|
||||
}
|
||||
}
|
||||
|
||||
+14
-8
@@ -1,17 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "`uname`" == 'Darwin' ]; then
|
||||
if [ "$(uname)" == 'Darwin' ]; then
|
||||
OS='Mac'
|
||||
elif [ "`expr substr $(uname -s) 1 5`" == 'Linux' ]; then
|
||||
elif [ "$(expr substr $(uname -s) 1 5)" == 'Linux' ]; then
|
||||
OS='Linux'
|
||||
elif [ "`expr substr $(uname -s) 1 10`" == 'MINGW32_NT' ]; then
|
||||
elif [ "$(expr substr $(uname -s) 1 10)" == 'MINGW32_NT' ]; then
|
||||
OS='Cygwin'
|
||||
else
|
||||
echo "Your platform (`uname -a`) is not supported."
|
||||
echo "Your platform ($(uname -a)) is not supported."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
while getopts ":wtfvhs-:" opt; do
|
||||
while getopts ":wtfvh-:" opt; do
|
||||
case "$opt" in
|
||||
-)
|
||||
case "${OPTARG}" in
|
||||
@@ -66,8 +66,8 @@ if [ $OS == 'Mac' ]; then
|
||||
open -a "$ATOM_PATH/$ATOM_APP_NAME" -n --args --executed-from="$(pwd)" --pid=$$ "$@"
|
||||
fi
|
||||
elif [ $OS == 'Linux' ]; then
|
||||
SCRIPT=`readlink -f "$0"`
|
||||
USR_DIRECTORY=`readlink -f $(dirname $SCRIPT)/..`
|
||||
SCRIPT=$(readlink -f "$0")
|
||||
USR_DIRECTORY=$(readlink -f $(dirname $SCRIPT)/..)
|
||||
ATOM_PATH="$USR_DIRECTORY/share/atom/atom"
|
||||
|
||||
[ -x "$ATOM_PATH" ] || ATOM_PATH='/tmp/atom-build/Atom/atom'
|
||||
@@ -76,7 +76,13 @@ elif [ $OS == 'Linux' ]; then
|
||||
"$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@"
|
||||
exit $?
|
||||
else
|
||||
nohup "$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@" > /dev/null 2>&1 &
|
||||
(
|
||||
nohup "$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@" > /tmp/atom-nohup.out 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
cat /tmp/atom-nohup.out
|
||||
exit $?
|
||||
fi
|
||||
) &
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
"json-front-matter": "~0.1.3",
|
||||
"legal-eagle": "~0.4.0",
|
||||
"minidump": "0.5.x",
|
||||
"read-package-json": "1.1.8",
|
||||
"normalize-package-data": "0.2.12",
|
||||
"rcedit": "~0.1.2",
|
||||
"request": "~2.27.0",
|
||||
"rimraf": "~2.2.2",
|
||||
|
||||
@@ -5,14 +5,18 @@ module.exports = (grunt) ->
|
||||
{spawn} = require('./task-helpers')(grunt)
|
||||
|
||||
getVersion = (callback) ->
|
||||
if process.env.JANKY_SHA1 and process.env.JANKY_BRANCH is 'master'
|
||||
{version} = require(path.join(grunt.config.get('atom.appDir'), 'package.json'))
|
||||
onBuildMachine = process.env.JANKY_SHA1 and process.env.JANKY_BRANCH is 'master'
|
||||
inRepository = fs.existsSync(path.resolve(__dirname, '..', '..', '.git'))
|
||||
{version} = require(path.join(grunt.config.get('atom.appDir'), 'package.json'))
|
||||
if onBuildMachine or not inRepository
|
||||
callback(null, version)
|
||||
else
|
||||
cmd = 'git'
|
||||
args = ['rev-parse', '--short', 'HEAD']
|
||||
spawn {cmd, args}, (error, {stdout}={}, code) ->
|
||||
callback(error, stdout?.trim?())
|
||||
commitHash = stdout?.trim?()
|
||||
combinedVersion = "#{version}-#{commitHash}"
|
||||
callback(error, combinedVersion)
|
||||
|
||||
grunt.registerTask 'set-version', 'Set the version in the plist and package.json', ->
|
||||
done = @async()
|
||||
|
||||
@@ -10,8 +10,8 @@ keystrokes pass through elements with the class `.editor`:
|
||||
|
||||
```coffee
|
||||
'.editor':
|
||||
'cmd-delete': 'editor:backspace-to-beginning-of-line'
|
||||
'alt-backspace': 'editor:backspace-to-beginning-of-word'
|
||||
'cmd-delete': 'editor:delete-to-beginning-of-line'
|
||||
'alt-backspace': 'editor:delete-to-beginning-of-word'
|
||||
'ctrl-A': 'editor:select-to-first-character-of-line'
|
||||
'ctrl-shift-e': 'editor:select-to-end-of-line'
|
||||
'cmd-left': 'editor:move-to-first-character-of-line'
|
||||
@@ -24,7 +24,7 @@ keystrokes pass through elements with the class `.editor`:
|
||||
Beneath the first selector are several bindings, mapping specific *keystroke
|
||||
patterns* to *commands*. When an element with the `.editor` class is focused and
|
||||
`cmd-delete` is pressed, an custom DOM event called
|
||||
`editor:backspace-to-beginning-of-line` is emitted on the `.editor` element.
|
||||
`editor:delete-to-beginning-of-line` is emitted on the `.editor` element.
|
||||
|
||||
The second selector group also targets editors, but only if they don't have the
|
||||
`.mini` class. In this example, the commands for code folding don't really make
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
## Developing Node Modules
|
||||
|
||||
Atom contains a number of packages that are Node modules instead of Atom packages. If you want to
|
||||
make changes to the Node modules, for instance `atom-keymap`, you have to link them into the
|
||||
development environment differently than you would a normal Atom package.
|
||||
|
||||
### Linking a Node Module Into Your Atom Dev Environment
|
||||
|
||||
Here are the steps to run a local version of a node module *not an apm* within Atom. We're using
|
||||
`atom-keymap` as an example:
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/atom/atom-keymap.git
|
||||
$ cd atom-keymap
|
||||
$ npm install
|
||||
$ npm link
|
||||
$ apm rebuild # This is the special step, it makes the npm work with Atom's version of Node
|
||||
$ cd WHERE-YOU-CLONED-ATOM
|
||||
$ npm link atom-keymap
|
||||
$ atom # Should work!
|
||||
```
|
||||
|
||||
After this, you'll have to `npm install` and `apm rebuild` when you make a change to the node
|
||||
module's code.
|
||||
@@ -0,0 +1,22 @@
|
||||
# FreeBSD
|
||||
|
||||
FreeBSD -RELEASE 64-bit is the recommended platform.
|
||||
|
||||
## Requirements
|
||||
|
||||
* FreeBSD
|
||||
* `pkg install node`
|
||||
* `pkg install npm`
|
||||
* `pkg install libgnome-keyring`
|
||||
* `npm config set python /usr/local/bin/python2 -g` to ensure that gyp uses Python 2
|
||||
|
||||
## Instructions
|
||||
|
||||
```sh
|
||||
git clone https://github.com/atom/atom
|
||||
cd atom
|
||||
script/build # Creates application at /tmp/atom-build/Atom
|
||||
sudo script/grunt install # Installs command to /usr/local/bin/atom
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
@@ -0,0 +1,23 @@
|
||||
# Linux
|
||||
|
||||
Ubuntu LTS 12.04 64-bit is the recommended platform.
|
||||
|
||||
## Requirements
|
||||
|
||||
* OS with 64-bit architecture
|
||||
* [node.js](http://nodejs.org/download/) v0.10.x
|
||||
* [npm](http://www.npmjs.org/) v1.4.x
|
||||
* libgnome-keyring-dev `sudo apt-get install libgnome-keyring-dev` (refer to your distribution's manual on how to install packages if you are not on Debian or Ubuntu-based systems)
|
||||
* `npm config set python /usr/bin/python2 -g` to ensure that gyp uses Python 2
|
||||
|
||||
## Instructions
|
||||
|
||||
```sh
|
||||
git clone https://github.com/atom/atom
|
||||
cd atom
|
||||
script/build # Creates application at /tmp/atom-build/Atom
|
||||
sudo script/grunt install # Installs command to /usr/local/bin/atom
|
||||
script/grunt mkdeb # Generates a .deb package at /tmp/atom-build
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
@@ -0,0 +1,17 @@
|
||||
# OS X
|
||||
|
||||
## Requirements
|
||||
|
||||
* OS X 10.8 or later
|
||||
* [node.js](http://nodejs.org/download/) v0.10.x
|
||||
* Command Line Tools for [Xcode](https://developer.apple.com/xcode/downloads/) (run `xcode-select --install` to install)
|
||||
|
||||
## Instructions
|
||||
|
||||
```sh
|
||||
git clone https://github.com/atom/atom
|
||||
cd atom
|
||||
script/build # Creates application at /Applications/Atom.app
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
@@ -0,0 +1,42 @@
|
||||
# Windows
|
||||
|
||||
## Requirements
|
||||
|
||||
* Windows 7 or later
|
||||
* [Visual C++ 2010 SP1 Express](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs#DownloadFamilies_4)
|
||||
* [node.js - 32bit](http://nodejs.org/download/) v0.10.x
|
||||
* [Python 2.7.x](http://www.python.org/download/)
|
||||
* [GitHub for Windows](http://windows.github.com/)
|
||||
to your PATH
|
||||
* Open the Windows GitHub shell (NOT the Standard PowerShell, the shortcut labeled 'Git Shell' - make sure you have logged in at least once to the GitHub for Windows GUI App)
|
||||
* `$env:Path = $env:Path + ";C:\path\to\atom\repo\node_modules"`
|
||||
|
||||
## Instructions
|
||||
|
||||
```bat
|
||||
cd C:\
|
||||
git clone https://github.com/atom/atom
|
||||
cd atom
|
||||
script\build
|
||||
```
|
||||
|
||||
## Why do I have to use GitHub for Windows? Can't I just use my existing Git?
|
||||
|
||||
You totally can! GitHub for Windows's Git Shell just takes less work to set up. You need to have Posix tools in your `%PATH%` (i.e. `grep`, `sed`, et al.), which isn't the default configuration when you install Git. To fix this, you probably need to fiddle with your system PATH.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Some of the most common errors include:
|
||||
|
||||
gyp WARN install got an error, rolling back install
|
||||
and
|
||||
|
||||
>> The system cannot find the path specified.
|
||||
|
||||
These two error messages can usually be ignored. The solution to these errors is to re-run `script\build`, possibly several times.
|
||||
|
||||
If your Visual Studio is in a non-standard location, and you get the error `You must have Visual Studio 2010 or 2012 installed`, you need to modify `apm\node_modules\atom-package-manager\lib\config.js` around line 90 and replace the variable with your Visual Studio directory plus Common7/IDE.
|
||||
|
||||
Example:
|
||||
|
||||
vs2010Path = "H:/VS2010/Common7/IDE"
|
||||
@@ -20,7 +20,7 @@ apm help init
|
||||
|
||||
You should see a message print out with details about the `apm init` command.
|
||||
|
||||
If you do not, launch Atom and run the _Atom > Install Shell Commmands_ menu
|
||||
If you do not, launch Atom and run the _Atom > Install Shell Commands_ menu
|
||||
to install the `apm` and `atom` commands.
|
||||
|
||||
### Convert the Package
|
||||
@@ -49,4 +49,4 @@ the editor to see it in action!
|
||||
[plist]: http://en.wikipedia.org/wiki/Property_list
|
||||
[R]: http://en.wikipedia.org/wiki/R_(programming_language)
|
||||
[TextMate]: http://macromates.com
|
||||
[TextMateOrg]: https://github.com/textmate/r.tmbundle
|
||||
[TextMateOrg]: https://github.com/textmate
|
||||
|
||||
@@ -25,7 +25,7 @@ apm help init
|
||||
|
||||
You should see a message print out with details about the `apm init` command.
|
||||
|
||||
If you do not, launch Atom and run the _Atom > Install Shell Commmands_ menu
|
||||
If you do not, launch Atom and run the _Atom > Install Shell Commands_ menu
|
||||
to install the `apm` and `atom` commands.
|
||||
|
||||
You can now run `apm help init` to see all the options for initializing new
|
||||
|
||||
@@ -34,7 +34,7 @@ apm help install
|
||||
|
||||
You should see a message print out with details about the `apm install` command.
|
||||
|
||||
If you do not, launch Atom and run the _Atom > Install Shell Commmands_ menu
|
||||
If you do not, launch Atom and run the _Atom > Install Shell Commands_ menu
|
||||
to install the `apm` and `atom` commands.
|
||||
|
||||
You can also install packages by using the `apm install` command:
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
### Advanced Topics
|
||||
|
||||
* [Configuration](advanced/configuration.md)
|
||||
* [Developing Node Modules](advanced/node-modules.md)
|
||||
* [Keymaps](advanced/keymaps.md)
|
||||
* [Serialization](advanced/serialization.md)
|
||||
* [View System](advanced/view-system.md)
|
||||
|
||||
@@ -7,7 +7,7 @@ Publishing a package allows other people to install it and use it in Atom. It
|
||||
is a great way to share what you've made and get feedback and contributions from
|
||||
others.
|
||||
|
||||
This guide assumes your package's name is `my-package` and but you should pick a
|
||||
This guide assumes your package's name is `my-package` but you should pick a
|
||||
better name.
|
||||
|
||||
### Install apm
|
||||
@@ -24,7 +24,7 @@ apm help publish
|
||||
|
||||
You should see a message print out with details about the `apm publish` command.
|
||||
|
||||
If you do not, launch Atom and run the _Atom > Install Shell Commmands_ menu
|
||||
If you do not, launch Atom and run the _Atom > Install Shell Commands_ menu
|
||||
to install the `apm` and `atom` commands.
|
||||
|
||||
### Prepare Your Package
|
||||
@@ -42,7 +42,7 @@ If not, there are a few things you should check before publishing:
|
||||
* Your package is in a Git repository that has been pushed to
|
||||
[GitHub][github]. Follow [this guide][repo-guide] if your package isn't
|
||||
already on GitHub.
|
||||
|
||||
|
||||
### Publish Your Package
|
||||
|
||||
Before you publish a package it is a good idea to check ahead of time if
|
||||
@@ -59,7 +59,7 @@ Now let's review what the `apm publish` command does:
|
||||
3. Creates a new [Git tag][git-tag] for the version being published.
|
||||
4. Pushes the tag and current branch up to GitHub.
|
||||
5. Updates atom.io with the new version being published.
|
||||
|
||||
|
||||
Now run the following commands to publish your package:
|
||||
|
||||
```sh
|
||||
@@ -80,7 +80,7 @@ digit of the version before publishing so the published version will be `0.1.0`
|
||||
and the Git tag created will be `v0.1.0`.
|
||||
|
||||
In the future you can run `apm publish major` to publish the `1.0.0` version but
|
||||
since this was the first version being published it is a good idead to start
|
||||
since this was the first version being published it is a good idea to start
|
||||
with a minor release.
|
||||
|
||||
### Further Reading
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
'.editor':
|
||||
# Platform Bindings
|
||||
'alt-left': 'editor:move-to-beginning-of-word'
|
||||
'alt-right': 'editor:move-to-end-of-word'
|
||||
'alt-shift-left': 'editor:select-to-beginning-of-word'
|
||||
'alt-shift-right': 'editor:select-to-end-of-word'
|
||||
'home': 'editor:move-to-first-character-of-line'
|
||||
'end': 'editor:move-to-end-of-screen-line'
|
||||
'shift-home': 'editor:select-to-first-character-of-line'
|
||||
|
||||
+12
-4
@@ -65,6 +65,8 @@
|
||||
'cmd-}': 'pane:show-next-item'
|
||||
'cmd-alt-left': 'pane:show-previous-item'
|
||||
'cmd-alt-right': 'pane:show-next-item'
|
||||
'ctrl-tab': 'pane:show-next-item'
|
||||
'ctrl-shift-tab': 'pane:show-previous-item'
|
||||
'cmd-=': 'window:increase-font-size'
|
||||
'cmd-+': 'window:increase-font-size'
|
||||
'cmd--': 'window:decrease-font-size'
|
||||
@@ -94,17 +96,23 @@
|
||||
'cmd-9': 'pane:show-item-9'
|
||||
|
||||
'.editor':
|
||||
# Platform Bindings
|
||||
'alt-left': 'editor:move-to-beginning-of-word'
|
||||
'alt-right': 'editor:move-to-end-of-word'
|
||||
'alt-shift-left': 'editor:select-to-beginning-of-word'
|
||||
'alt-shift-right': 'editor:select-to-end-of-word'
|
||||
|
||||
# Apple Specific
|
||||
'cmd-backspace': 'editor:backspace-to-beginning-of-line'
|
||||
'cmd-shift-backspace': 'editor:backspace-to-beginning-of-line'
|
||||
'cmd-delete': 'editor:backspace-to-beginning-of-line'
|
||||
'cmd-backspace': 'editor:delete-to-beginning-of-line'
|
||||
'cmd-shift-backspace': 'editor:delete-to-beginning-of-line'
|
||||
'cmd-delete': 'editor:delete-to-beginning-of-line'
|
||||
'ctrl-A': 'editor:select-to-first-character-of-line'
|
||||
'ctrl-E': 'editor:select-to-end-of-line'
|
||||
'cmd-left': 'editor:move-to-first-character-of-line'
|
||||
'cmd-right': 'editor:move-to-end-of-screen-line'
|
||||
'cmd-shift-left': 'editor:select-to-first-character-of-line'
|
||||
'cmd-shift-right': 'editor:select-to-end-of-line'
|
||||
'alt-backspace': 'editor:backspace-to-beginning-of-word'
|
||||
'alt-backspace': 'editor:delete-to-beginning-of-word'
|
||||
'alt-delete': 'editor:delete-to-end-of-word'
|
||||
'ctrl-a': 'editor:move-to-beginning-of-line'
|
||||
'ctrl-e': 'editor:move-to-end-of-line'
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
'alt-F': 'editor:select-to-end-of-word'
|
||||
'alt-b': 'editor:move-to-beginning-of-word'
|
||||
'alt-B': 'editor:select-to-beginning-of-word'
|
||||
'alt-h': 'editor:backspace-to-beginning-of-word'
|
||||
'alt-h': 'editor:delete-to-beginning-of-word'
|
||||
'alt-d': 'editor:delete-to-end-of-word'
|
||||
|
||||
+11
-2
@@ -60,8 +60,17 @@
|
||||
'ctrl-k ctrl-right': 'window:focus-pane-on-right'
|
||||
|
||||
'.workspace .editor':
|
||||
# Windows specific
|
||||
'ctrl-delete': 'editor:backspace-to-beginning-of-word'
|
||||
# Platform Bindings
|
||||
'ctrl-left': 'editor:move-to-beginning-of-word'
|
||||
'ctrl-right': 'editor:move-to-end-of-word'
|
||||
'ctrl-shift-left': 'editor:select-to-beginning-of-word'
|
||||
'ctrl-shift-right': 'editor:select-to-end-of-word'
|
||||
'ctrl-backspace': 'editor:delete-to-beginning-of-word'
|
||||
'ctrl-delete': 'editor:delete-to-end-of-word'
|
||||
'ctrl-home': 'core:move-to-top'
|
||||
'ctrl-end': 'core:move-to-bottom'
|
||||
'ctrl-shift-home': 'core:select-to-top'
|
||||
'ctrl-shift-end': 'core:select-to-bottom'
|
||||
|
||||
# Sublime Parity
|
||||
'ctrl-a': 'core:select-all'
|
||||
|
||||
+15
-2
@@ -1,4 +1,8 @@
|
||||
'body':
|
||||
# Platform Bindings
|
||||
'ctrl-pageup': 'pane:show-previous-item'
|
||||
'ctrl-pagedown': 'pane:show-next-item'
|
||||
|
||||
# Atom Specific
|
||||
'enter': 'core:confirm'
|
||||
'escape': 'core:cancel'
|
||||
@@ -10,6 +14,7 @@
|
||||
'ctrl-alt-i': 'window:toggle-dev-tools'
|
||||
'ctrl-alt-p': 'window:run-package-specs'
|
||||
'ctrl-alt-s': 'application:run-all-specs'
|
||||
'F11': 'window:toggle-full-screen'
|
||||
|
||||
# Sublime Parity
|
||||
'ctrl-N': 'application:new-window'
|
||||
@@ -33,6 +38,7 @@
|
||||
'pageup': 'core:page-up'
|
||||
'pagedown': 'core:page-down'
|
||||
'backspace': 'core:backspace'
|
||||
'shift-backspace': 'core:backspace'
|
||||
'ctrl-tab': 'pane:show-next-item'
|
||||
'ctrl-shift-tab': 'pane:show-previous-item'
|
||||
'ctrl-shift-up': 'core:move-up'
|
||||
@@ -57,8 +63,15 @@
|
||||
'ctrl-k ctrl-right': 'window:focus-pane-on-right'
|
||||
|
||||
'.workspace .editor':
|
||||
# Windows specific
|
||||
'ctrl-delete': 'editor:backspace-to-beginning-of-word'
|
||||
# Platform Bindings
|
||||
'ctrl-left': 'editor:move-to-beginning-of-word'
|
||||
'ctrl-right': 'editor:move-to-end-of-word'
|
||||
'ctrl-shift-left': 'editor:select-to-beginning-of-word'
|
||||
'ctrl-shift-right': 'editor:select-to-end-of-word'
|
||||
'ctrl-backspace': 'editor:delete-to-beginning-of-word'
|
||||
'ctrl-delete': 'editor:delete-to-end-of-word'
|
||||
'ctrl-home': 'core:move-to-top'
|
||||
'ctrl-end': 'core:move-to-bottom'
|
||||
|
||||
# Sublime Parity
|
||||
'ctrl-a': 'core:select-all'
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
{
|
||||
label: 'Help'
|
||||
submenu: [
|
||||
{ label: 'Terms of Use', command: 'application:open-terms-of-use' }
|
||||
{ label: 'Documentation', command: 'application:open-documentation' }
|
||||
{ type: 'separator' }
|
||||
]
|
||||
|
||||
@@ -145,6 +145,7 @@
|
||||
{
|
||||
label: '&Help'
|
||||
submenu: [
|
||||
{ label: 'View &Terms of Use', command: 'application:open-terms-of-use' }
|
||||
{ label: 'View &License', command: 'application:open-license' }
|
||||
{ label: "VERSION", enabled: false }
|
||||
{ type: 'separator' }
|
||||
|
||||
@@ -165,6 +165,7 @@
|
||||
label: '&Help'
|
||||
submenu: [
|
||||
{ label: '&About Atom...', command: 'application:about' }
|
||||
{ label: 'View &Terms of Use', command: 'application:open-terms-of-use' }
|
||||
{ label: 'View &License', command: 'application:open-license' }
|
||||
{ label: "VERSION", enabled: false }
|
||||
{ label: "Install &update", command: 'application:install-update', visible: false }
|
||||
|
||||
+34
-34
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "0.94.0",
|
||||
"version": "0.96.0",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/browser/main.js",
|
||||
"repository": {
|
||||
@@ -17,18 +17,18 @@
|
||||
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
|
||||
}
|
||||
],
|
||||
"atomShellVersion": "0.12.2",
|
||||
"atomShellVersion": "0.12.5",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "^0.19.0",
|
||||
"bootstrap": "git://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
|
||||
"bootstrap": "git+https://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
|
||||
"clear-cut": "0.4.0",
|
||||
"coffee-script": "1.7.0",
|
||||
"coffeestack": "0.7.0",
|
||||
"delegato": "^1",
|
||||
"emissary": "^1.2.1",
|
||||
"first-mate": "^1.5.3",
|
||||
"fs-plus": "^2.2.2",
|
||||
"fs-plus": "^2.2.3",
|
||||
"fstream": "0.1.24",
|
||||
"fuzzaldrin": "^1.1",
|
||||
"git-utils": "^1.3",
|
||||
@@ -41,22 +41,22 @@
|
||||
"nslog": "0.5.0",
|
||||
"oniguruma": "^1.0.6",
|
||||
"optimist": "0.4.0",
|
||||
"pathwatcher": "^1.2.1",
|
||||
"pathwatcher": "^1.3.1",
|
||||
"property-accessors": "^1",
|
||||
"q": "^1.0.1",
|
||||
"random-words": "0.0.1",
|
||||
"react": "^0.10.0",
|
||||
"reactionary": "^0.8.0",
|
||||
"reactionary": "^0.9.0",
|
||||
"runas": "^0.5",
|
||||
"scandal": "0.15.2",
|
||||
"scoped-property-store": "^0.9.0",
|
||||
"scrollbar-style": "^0.1.0",
|
||||
"scrollbar-style": "^0.4.0",
|
||||
"season": "^1.0.2",
|
||||
"semver": "1.1.4",
|
||||
"serializable": "^1",
|
||||
"space-pen": "3.1.1",
|
||||
"temp": "0.5.0",
|
||||
"text-buffer": "^2.2.0",
|
||||
"text-buffer": "^2.2.2",
|
||||
"theorist": "^1",
|
||||
"underscore-plus": "^1.2.1",
|
||||
"vm-compatibility-layer": "0.1.0"
|
||||
@@ -69,72 +69,72 @@
|
||||
"base16-tomorrow-dark-theme": "0.15.0",
|
||||
"solarized-dark-syntax": "0.14.0",
|
||||
"solarized-light-syntax": "0.7.0",
|
||||
"archive-view": "0.30.0",
|
||||
"autocomplete": "0.27.0",
|
||||
"autoflow": "0.16.0",
|
||||
"archive-view": "0.31.0",
|
||||
"autocomplete": "0.28.0",
|
||||
"autoflow": "0.17.0",
|
||||
"autosave": "0.13.0",
|
||||
"background-tips": "0.13.0",
|
||||
"bookmarks": "0.22.0",
|
||||
"bracket-matcher": "0.33.0",
|
||||
"bracket-matcher": "0.34.0",
|
||||
"command-palette": "0.21.0",
|
||||
"deprecation-cop": "0.5.0",
|
||||
"dev-live-reload": "0.30.0",
|
||||
"exception-reporting": "0.17.0",
|
||||
"feedback": "0.32.0",
|
||||
"find-and-replace": "0.100.0",
|
||||
"fuzzy-finder": "0.50.0",
|
||||
"feedback": "0.33.0",
|
||||
"find-and-replace": "0.105.0",
|
||||
"fuzzy-finder": "0.51.0",
|
||||
"git-diff": "0.28.0",
|
||||
"go-to-line": "0.19.0",
|
||||
"go-to-line": "0.20.0",
|
||||
"grammar-selector": "0.26.0",
|
||||
"image-view": "0.33.0",
|
||||
"keybinding-resolver": "0.17.0",
|
||||
"link": "0.22.0",
|
||||
"markdown-preview": "0.69.0",
|
||||
"markdown-preview": "0.71.0",
|
||||
"metrics": "0.32.0",
|
||||
"open-on-github": "0.28.0",
|
||||
"package-generator": "0.30.0",
|
||||
"release-notes": "0.29.0",
|
||||
"settings-view": "0.114.0",
|
||||
"release-notes": "0.31.0",
|
||||
"settings-view": "0.115.0",
|
||||
"snippets": "0.43.0",
|
||||
"spell-check": "0.34.0",
|
||||
"spell-check": "0.35.0",
|
||||
"status-bar": "0.40.0",
|
||||
"styleguide": "0.29.0",
|
||||
"symbols-view": "0.50.0",
|
||||
"tabs": "0.39.0",
|
||||
"symbols-view": "0.52.0",
|
||||
"tabs": "0.40.0",
|
||||
"timecop": "0.18.0",
|
||||
"tree-view": "0.92.0",
|
||||
"tree-view": "0.93.0",
|
||||
"update-package-dependencies": "0.6.0",
|
||||
"welcome": "0.13.0",
|
||||
"welcome": "0.14.0",
|
||||
"whitespace": "0.22.0",
|
||||
"wrap-guide": "0.18.0",
|
||||
"language-c": "0.15.0",
|
||||
"language-coffee-script": "0.22.0",
|
||||
"language-css": "0.16.0",
|
||||
"language-gfm": "0.34.0",
|
||||
"language-gfm": "0.37.0",
|
||||
"language-git": "0.9.0",
|
||||
"language-go": "0.10.0",
|
||||
"language-html": "0.19.0",
|
||||
"language-go": "0.12.0",
|
||||
"language-html": "0.22.0",
|
||||
"language-hyperlink": "0.9.0",
|
||||
"language-java": "0.10.0",
|
||||
"language-javascript": "0.24.0",
|
||||
"language-javascript": "0.26.0",
|
||||
"language-json": "0.8.0",
|
||||
"language-less": "0.8.0",
|
||||
"language-less": "0.9.0",
|
||||
"language-make": "0.10.0",
|
||||
"language-objective-c": "0.11.0",
|
||||
"language-perl": "0.8.0",
|
||||
"language-php": "0.14.0",
|
||||
"language-property-list": "0.7.0",
|
||||
"language-python": "0.15.0",
|
||||
"language-ruby": "0.23.0",
|
||||
"language-ruby-on-rails": "0.12.0",
|
||||
"language-sass": "0.10.0",
|
||||
"language-python": "0.16.0",
|
||||
"language-ruby": "0.24.0",
|
||||
"language-ruby-on-rails": "0.14.0",
|
||||
"language-sass": "0.11.0",
|
||||
"language-shellscript": "0.8.0",
|
||||
"language-source": "0.7.0",
|
||||
"language-sql": "0.8.0",
|
||||
"language-text": "0.6.0",
|
||||
"language-todo": "0.10.0",
|
||||
"language-toml": "0.12.0",
|
||||
"language-xml": "0.12.0",
|
||||
"language-xml": "0.13.0",
|
||||
"language-yaml": "0.6.0"
|
||||
},
|
||||
"private": true,
|
||||
|
||||
+5
-3
@@ -1,8 +1,10 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var nodeMinorVersion = process.versions.node.split('.')[1]
|
||||
if (nodeMinorVersion !== '10') {
|
||||
console.warn("You must run script/bootstrap and script/build with node v0.10.x");
|
||||
var nodeVersion = process.versions.node.split('.')
|
||||
var nodeMajorVersion = +nodeVersion[0]
|
||||
var nodeMinorVersion = +nodeVersion[1]
|
||||
if (nodeMajorVersion === 0 && nodeMinorVersion < 10) {
|
||||
console.warn("You must run script/bootstrap and script/build with node v0.10 or above");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
@IF EXIST "%~dp0\node.exe" (
|
||||
"%~dp0\node.exe" "%~dp0\grunt" %*
|
||||
) ELSE (
|
||||
node "%~dp0\grunt" %*
|
||||
)
|
||||
@@ -1,6 +1,8 @@
|
||||
#!/bin/bash
|
||||
# mkdeb version control-file-path deb-file-path
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT=`readlink -f "$0"`
|
||||
ROOT=`readlink -f $(dirname $SCRIPT)/..`
|
||||
cd $ROOT
|
||||
@@ -12,6 +14,7 @@ ICON_FILE="$4"
|
||||
DEB_PATH="$5"
|
||||
|
||||
TARGET_ROOT="`mktemp -d`"
|
||||
chmod 755 "$TARGET_ROOT"
|
||||
TARGET="$TARGET_ROOT/atom-$VERSION-amd64"
|
||||
|
||||
mkdir -p "$TARGET/usr"
|
||||
|
||||
@@ -510,20 +510,20 @@ describe "the `atom` global", ->
|
||||
# enabling of theme
|
||||
pack = atom.packages.enablePackage(packageName)
|
||||
|
||||
activatedPackages = null
|
||||
waitsFor ->
|
||||
activatedPackages = atom.packages.getActivePackages()
|
||||
activatedPackages.length > 0
|
||||
pack in atom.packages.getActivePackages()
|
||||
|
||||
runs ->
|
||||
expect(activatedPackages).toContain(pack)
|
||||
expect(atom.config.get('core.themes')).toContain packageName
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
# disabling of theme
|
||||
pack = atom.packages.disablePackage(packageName)
|
||||
activatedPackages = atom.packages.getActivePackages()
|
||||
expect(activatedPackages).not.toContain(pack)
|
||||
|
||||
waitsFor ->
|
||||
not (pack in atom.packages.getActivePackages())
|
||||
|
||||
runs ->
|
||||
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
|
||||
|
||||
@@ -5,6 +5,10 @@ fs = require 'fs-plus'
|
||||
|
||||
describe "Config", ->
|
||||
dotAtomPath = path.join(temp.dir, 'dot-atom-dir')
|
||||
dotAtomPath = null
|
||||
|
||||
beforeEach ->
|
||||
dotAtomPath = temp.path('dot-atom-dir')
|
||||
|
||||
describe ".get(keyPath)", ->
|
||||
it "allows a key path's value to be read", ->
|
||||
@@ -258,8 +262,10 @@ describe "Config", ->
|
||||
|
||||
describe ".initializeConfigDirectory()", ->
|
||||
beforeEach ->
|
||||
if fs.existsSync(dotAtomPath)
|
||||
fs.removeSync(dotAtomPath)
|
||||
|
||||
atom.config.configDirPath = dotAtomPath
|
||||
expect(fs.existsSync(atom.config.configDirPath)).toBeFalsy()
|
||||
|
||||
afterEach ->
|
||||
fs.removeSync(dotAtomPath)
|
||||
|
||||
@@ -979,6 +979,7 @@ describe "DisplayBuffer", ->
|
||||
describe "::setScrollLeft", ->
|
||||
beforeEach ->
|
||||
displayBuffer.manageScrollPosition = true
|
||||
displayBuffer.setLineHeight(10)
|
||||
displayBuffer.setDefaultCharWidth(10)
|
||||
|
||||
it "disallows negative values", ->
|
||||
@@ -1001,6 +1002,7 @@ describe "DisplayBuffer", ->
|
||||
displayBuffer.manageScrollPosition = true
|
||||
displayBuffer.setLineHeight(10)
|
||||
displayBuffer.setDefaultCharWidth(10)
|
||||
displayBuffer.setHorizontalScrollbarHeight(0)
|
||||
|
||||
displayBuffer.setHeight(50)
|
||||
displayBuffer.setWidth(50)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{extend, flatten, toArray} = require 'underscore-plus'
|
||||
{extend, flatten, toArray, last} = require 'underscore-plus'
|
||||
ReactEditorView = require '../src/react-editor-view'
|
||||
nbsp = String.fromCharCode(160)
|
||||
|
||||
describe "EditorComponent", ->
|
||||
[editor, wrapperView, component, node, verticalScrollbarNode, horizontalScrollbarNode] = []
|
||||
[contentNode, editor, wrapperView, component, node, verticalScrollbarNode, horizontalScrollbarNode] = []
|
||||
[lineHeightInPixels, charWidth, delayAnimationFrames, nextAnimationFrame] = []
|
||||
|
||||
beforeEach ->
|
||||
@@ -26,6 +26,9 @@ describe "EditorComponent", ->
|
||||
atom.project.open('sample.js').then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
contentNode = document.querySelector('#jasmine-content')
|
||||
contentNode.style.width = '1000px'
|
||||
|
||||
wrapperView = new ReactEditorView(editor)
|
||||
wrapperView.attachToDom()
|
||||
{component} = wrapperView
|
||||
@@ -38,6 +41,9 @@ describe "EditorComponent", ->
|
||||
verticalScrollbarNode = node.querySelector('.vertical-scrollbar')
|
||||
horizontalScrollbarNode = node.querySelector('.horizontal-scrollbar')
|
||||
|
||||
afterEach ->
|
||||
contentNode.style.width = ''
|
||||
|
||||
describe "line rendering", ->
|
||||
it "renders only the currently-visible lines", ->
|
||||
node.style.height = 4.5 * lineHeightInPixels + 'px'
|
||||
@@ -188,6 +194,20 @@ describe "EditorComponent", ->
|
||||
expect(lines[4].textContent).toBe "#{nbsp}3"
|
||||
expect(lines[5].textContent).toBe "#{nbsp}•"
|
||||
|
||||
it "pads line numbers to be right justified based on the maximum number of line number digits", ->
|
||||
editor.getBuffer().setText([1..10].join('\n'))
|
||||
lineNumberNodes = toArray(node.querySelectorAll('.line-number'))
|
||||
|
||||
for node, i in lineNumberNodes[0..8]
|
||||
expect(node.textContent).toBe "#{nbsp}#{i + 1}"
|
||||
expect(lineNumberNodes[9].textContent).toBe '10'
|
||||
|
||||
# Removes padding when the max number of digits goes down
|
||||
editor.getBuffer().delete([[1, 0], [2, 0]])
|
||||
lineNumberNodes = toArray(node.querySelectorAll('.line-number'))
|
||||
for node, i in lineNumberNodes
|
||||
expect(node.textContent).toBe "#{i + 1}"
|
||||
|
||||
describe "cursor rendering", ->
|
||||
it "renders the currently visible cursors", ->
|
||||
cursor1 = editor.getCursor()
|
||||
@@ -529,6 +549,110 @@ describe "EditorComponent", ->
|
||||
|
||||
expect(editor.getScrollLeft()).toBe 100
|
||||
|
||||
it "does not obscure the last line with the horizontal scrollbar", ->
|
||||
node.style.height = 4.5 * lineHeightInPixels + 'px'
|
||||
node.style.width = 10 * charWidth + 'px'
|
||||
component.measureHeightAndWidth()
|
||||
editor.setScrollBottom(editor.getScrollHeight())
|
||||
lastLineNode = last(node.querySelectorAll('.line'))
|
||||
bottomOfLastLine = lastLineNode.getBoundingClientRect().bottom
|
||||
topOfHorizontalScrollbar = horizontalScrollbarNode.getBoundingClientRect().top
|
||||
expect(bottomOfLastLine).toBe topOfHorizontalScrollbar
|
||||
|
||||
# Scroll so there's no space below the last line when the horizontal scrollbar disappears
|
||||
node.style.width = 100 * charWidth + 'px'
|
||||
component.measureHeightAndWidth()
|
||||
lastLineNode = last(node.querySelectorAll('.line'))
|
||||
bottomOfLastLine = lastLineNode.getBoundingClientRect().bottom
|
||||
bottomOfEditor = node.getBoundingClientRect().bottom
|
||||
expect(bottomOfLastLine).toBe bottomOfEditor
|
||||
|
||||
it "does not obscure the last character of the longest line with the vertical scrollbar", ->
|
||||
node.style.height = 7 * lineHeightInPixels + 'px'
|
||||
node.style.width = 10 * charWidth + 'px'
|
||||
component.measureHeightAndWidth()
|
||||
|
||||
editor.setScrollLeft(Infinity)
|
||||
|
||||
lineNodes = node.querySelectorAll('.line')
|
||||
rightOfLongestLine = lineNodes[6].getBoundingClientRect().right
|
||||
leftOfVerticalScrollbar = verticalScrollbarNode.getBoundingClientRect().left
|
||||
|
||||
expect(rightOfLongestLine).toBe leftOfVerticalScrollbar - 1 # Leave 1 px so the cursor is visible on the end of the line
|
||||
|
||||
it "only displays dummy scrollbars when scrollable in that direction", ->
|
||||
expect(verticalScrollbarNode.style.display).toBe 'none'
|
||||
expect(horizontalScrollbarNode.style.display).toBe 'none'
|
||||
|
||||
node.style.height = 4.5 * lineHeightInPixels + 'px'
|
||||
node.style.width = '1000px'
|
||||
component.measureHeightAndWidth()
|
||||
|
||||
expect(verticalScrollbarNode.style.display).toBe ''
|
||||
expect(horizontalScrollbarNode.style.display).toBe 'none'
|
||||
|
||||
node.style.width = 10 * charWidth + 'px'
|
||||
component.measureHeightAndWidth()
|
||||
|
||||
expect(verticalScrollbarNode.style.display).toBe ''
|
||||
expect(horizontalScrollbarNode.style.display).toBe ''
|
||||
|
||||
node.style.height = 20 * lineHeightInPixels + 'px'
|
||||
component.measureHeightAndWidth()
|
||||
|
||||
expect(verticalScrollbarNode.style.display).toBe 'none'
|
||||
expect(horizontalScrollbarNode.style.display).toBe ''
|
||||
|
||||
it "makes the dummy scrollbar divs only as tall/wide as the actual scrollbars", ->
|
||||
node.style.height = 4 * lineHeightInPixels + 'px'
|
||||
node.style.width = 10 * charWidth + 'px'
|
||||
component.measureHeightAndWidth()
|
||||
|
||||
atom.themes.applyStylesheet "test", """
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
"""
|
||||
|
||||
scrollbarCornerNode = node.querySelector('.scrollbar-corner')
|
||||
expect(verticalScrollbarNode.offsetWidth).toBe 8
|
||||
expect(horizontalScrollbarNode.offsetHeight).toBe 8
|
||||
expect(scrollbarCornerNode.offsetWidth).toBe 8
|
||||
expect(scrollbarCornerNode.offsetHeight).toBe 8
|
||||
|
||||
it "assigns the bottom/right of the scrollbars to the width of the opposite scrollbar if it is visible", ->
|
||||
scrollbarCornerNode = node.querySelector('.scrollbar-corner')
|
||||
|
||||
expect(verticalScrollbarNode.style.bottom).toBe ''
|
||||
expect(horizontalScrollbarNode.style.right).toBe ''
|
||||
|
||||
node.style.height = 4.5 * lineHeightInPixels + 'px'
|
||||
node.style.width = '1000px'
|
||||
component.measureHeightAndWidth()
|
||||
expect(verticalScrollbarNode.style.bottom).toBe ''
|
||||
expect(horizontalScrollbarNode.style.right).toBe verticalScrollbarNode.offsetWidth + 'px'
|
||||
expect(scrollbarCornerNode.style.display).toBe 'none'
|
||||
|
||||
node.style.width = 10 * charWidth + 'px'
|
||||
component.measureHeightAndWidth()
|
||||
expect(verticalScrollbarNode.style.bottom).toBe horizontalScrollbarNode.offsetHeight + 'px'
|
||||
expect(horizontalScrollbarNode.style.right).toBe verticalScrollbarNode.offsetWidth + 'px'
|
||||
expect(scrollbarCornerNode.style.display).toBe ''
|
||||
|
||||
node.style.height = 20 * lineHeightInPixels + 'px'
|
||||
component.measureHeightAndWidth()
|
||||
expect(verticalScrollbarNode.style.bottom).toBe horizontalScrollbarNode.offsetHeight + 'px'
|
||||
expect(horizontalScrollbarNode.style.right).toBe ''
|
||||
expect(scrollbarCornerNode.style.display).toBe 'none'
|
||||
|
||||
it "accounts for the width of the gutter in the scrollWidth of the horizontal scrollbar", ->
|
||||
gutterNode = node.querySelector('.gutter')
|
||||
node.style.width = 10 * charWidth + 'px'
|
||||
component.measureHeightAndWidth()
|
||||
|
||||
expect(horizontalScrollbarNode.scrollWidth).toBe gutterNode.offsetWidth + editor.getScrollWidth()
|
||||
|
||||
describe "when a mousewheel event occurs on the editor", ->
|
||||
it "updates the horizontal or vertical scrollbar depending on which delta is greater (x or y)", ->
|
||||
node.style.height = 4.5 * lineHeightInPixels + 'px'
|
||||
|
||||
+47
-13
@@ -698,6 +698,7 @@ describe "Editor", ->
|
||||
editor.setHorizontalScrollMargin(2)
|
||||
editor.setLineHeight(10)
|
||||
editor.setDefaultCharWidth(10)
|
||||
editor.setHorizontalScrollbarHeight(0)
|
||||
editor.setHeight(5.5 * 10)
|
||||
editor.setWidth(5.5 * 10)
|
||||
|
||||
@@ -1138,6 +1139,7 @@ describe "Editor", ->
|
||||
editor.setDefaultCharWidth(10)
|
||||
editor.setHeight(50)
|
||||
editor.setWidth(50)
|
||||
editor.setHorizontalScrollbarHeight(0)
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
|
||||
editor.setSelectedBufferRange([[5, 6], [6, 8]], autoscroll: true)
|
||||
@@ -1729,26 +1731,26 @@ describe "Editor", ->
|
||||
editor.backspace()
|
||||
expect(editor.lineForBufferRow(0)).toBe 'var = () {'
|
||||
|
||||
describe ".backspaceToBeginningOfWord()", ->
|
||||
describe ".deleteToBeginningOfWord()", ->
|
||||
describe "when no text is selected", ->
|
||||
it "deletes all text between the cursor and the beginning of the word", ->
|
||||
editor.setCursorBufferPosition([1, 24])
|
||||
editor.addCursorAtBufferPosition([3, 5])
|
||||
[cursor1, cursor2] = editor.getCursors()
|
||||
|
||||
editor.backspaceToBeginningOfWord()
|
||||
editor.deleteToBeginningOfWord()
|
||||
expect(buffer.lineForRow(1)).toBe ' var sort = function(ems) {'
|
||||
expect(buffer.lineForRow(3)).toBe ' ar pivot = items.shift(), current, left = [], right = [];'
|
||||
expect(cursor1.getBufferPosition()).toEqual [1, 22]
|
||||
expect(cursor2.getBufferPosition()).toEqual [3, 4]
|
||||
|
||||
editor.backspaceToBeginningOfWord()
|
||||
editor.deleteToBeginningOfWord()
|
||||
expect(buffer.lineForRow(1)).toBe ' var sort = functionems) {'
|
||||
expect(buffer.lineForRow(2)).toBe ' if (items.length <= 1) return itemsar pivot = items.shift(), current, left = [], right = [];'
|
||||
expect(cursor1.getBufferPosition()).toEqual [1, 21]
|
||||
expect(cursor2.getBufferPosition()).toEqual [2, 39]
|
||||
|
||||
editor.backspaceToBeginningOfWord()
|
||||
editor.deleteToBeginningOfWord()
|
||||
expect(buffer.lineForRow(1)).toBe ' var sort = ems) {'
|
||||
expect(buffer.lineForRow(2)).toBe ' if (items.length <= 1) return ar pivot = items.shift(), current, left = [], right = [];'
|
||||
expect(cursor1.getBufferPosition()).toEqual [1, 13]
|
||||
@@ -1756,24 +1758,24 @@ describe "Editor", ->
|
||||
|
||||
editor.setText(' var sort')
|
||||
editor.setCursorBufferPosition([0, 2])
|
||||
editor.backspaceToBeginningOfWord()
|
||||
editor.deleteToBeginningOfWord()
|
||||
expect(buffer.lineForRow(0)).toBe 'var sort'
|
||||
|
||||
describe "when text is selected", ->
|
||||
it "deletes only selected text", ->
|
||||
editor.setSelectedBufferRanges([[[1, 24], [1, 27]], [[2, 0], [2, 4]]])
|
||||
editor.backspaceToBeginningOfWord()
|
||||
editor.deleteToBeginningOfWord()
|
||||
expect(buffer.lineForRow(1)).toBe ' var sort = function(it) {'
|
||||
expect(buffer.lineForRow(2)).toBe 'if (items.length <= 1) return items;'
|
||||
|
||||
describe ".backspaceToBeginningOfLine()", ->
|
||||
describe ".deleteToBeginningOfLine()", ->
|
||||
describe "when no text is selected", ->
|
||||
it "deletes all text between the cursor and the beginning of the line", ->
|
||||
editor.setCursorBufferPosition([1, 24])
|
||||
editor.addCursorAtBufferPosition([2, 5])
|
||||
[cursor1, cursor2] = editor.getCursors()
|
||||
|
||||
editor.backspaceToBeginningOfLine()
|
||||
editor.deleteToBeginningOfLine()
|
||||
expect(buffer.lineForRow(1)).toBe 'ems) {'
|
||||
expect(buffer.lineForRow(2)).toBe 'f (items.length <= 1) return items;'
|
||||
expect(cursor1.getBufferPosition()).toEqual [1, 0]
|
||||
@@ -1782,13 +1784,13 @@ describe "Editor", ->
|
||||
describe "when at the beginning of the line", ->
|
||||
it "deletes the newline", ->
|
||||
editor.setCursorBufferPosition([2])
|
||||
editor.backspaceToBeginningOfLine()
|
||||
editor.deleteToBeginningOfLine()
|
||||
expect(buffer.lineForRow(1)).toBe ' var sort = function(items) { if (items.length <= 1) return items;'
|
||||
|
||||
describe "when text is selected", ->
|
||||
it "still deletes all text to begginning of the line", ->
|
||||
editor.setSelectedBufferRanges([[[1, 24], [1, 27]], [[2, 0], [2, 4]]])
|
||||
editor.backspaceToBeginningOfLine()
|
||||
editor.deleteToBeginningOfLine()
|
||||
expect(buffer.lineForRow(1)).toBe 'ems) {'
|
||||
expect(buffer.lineForRow(2)).toBe ' if (items.length <= 1) return items;'
|
||||
|
||||
@@ -2061,17 +2063,44 @@ describe "Editor", ->
|
||||
|
||||
describe ".copySelectedText()", ->
|
||||
it "copies selected text onto the clipboard", ->
|
||||
editor.setSelectedBufferRanges([[[0,4], [0,13]], [[1,6], [1, 10]], [[2,8], [2, 13]]])
|
||||
|
||||
editor.copySelectedText()
|
||||
expect(buffer.lineForRow(0)).toBe "var quicksort = function () {"
|
||||
expect(buffer.lineForRow(1)).toBe " var sort = function(items) {"
|
||||
expect(clipboard.readText()).toBe 'quicksort\nsort'
|
||||
expect(buffer.lineForRow(2)).toBe " if (items.length <= 1) return items;"
|
||||
expect(clipboard.readText()).toBe 'quicksort\nsort\nitems'
|
||||
expect(atom.clipboard.readWithMetadata().metadata.selections).toEqual([
|
||||
'quicksort'
|
||||
'sort'
|
||||
'items'
|
||||
])
|
||||
|
||||
describe ".pasteText()", ->
|
||||
it "pastes text into the buffer", ->
|
||||
atom.clipboard.write('first')
|
||||
editor.pasteText()
|
||||
expect(editor.buffer.lineForRow(0)).toBe "var first = function () {"
|
||||
expect(buffer.lineForRow(1)).toBe " var first = function(items) {"
|
||||
expect(editor.lineForBufferRow(0)).toBe "var first = function () {"
|
||||
expect(editor.lineForBufferRow(1)).toBe " var first = function(items) {"
|
||||
|
||||
describe 'when the clipboard has many selections', ->
|
||||
it "pastes each selection separately into the buffer", ->
|
||||
atom.clipboard.write('first\nsecond', {selections: ['first', 'second'] })
|
||||
editor.pasteText()
|
||||
expect(editor.lineForBufferRow(0)).toBe "var first = function () {"
|
||||
expect(editor.lineForBufferRow(1)).toBe " var second = function(items) {"
|
||||
|
||||
describe 'and the selections count does not match', ->
|
||||
it "pastes the whole text into the buffer", ->
|
||||
atom.clipboard.write('first\nsecond\nthird', {selections: ['first', 'second', 'third'] })
|
||||
editor.pasteText()
|
||||
expect(editor.lineForBufferRow(0)).toBe "var first"
|
||||
expect(editor.lineForBufferRow(1)).toBe "second"
|
||||
expect(editor.lineForBufferRow(2)).toBe "third = function () {"
|
||||
|
||||
expect(editor.lineForBufferRow(3)).toBe " var first"
|
||||
expect(editor.lineForBufferRow(4)).toBe "second"
|
||||
expect(editor.lineForBufferRow(5)).toBe "third = function(items) {"
|
||||
|
||||
describe ".indentSelectedRows()", ->
|
||||
describe "when nothing is selected", ->
|
||||
@@ -2594,6 +2623,10 @@ describe "Editor", ->
|
||||
atom.workspace.open('sample-with-tabs.coffee', softTabs: true).then (editor) ->
|
||||
expect(editor.getSoftTabs()).toBeFalsy()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample-with-tabs-and-initial-comment.js', softTabs: true).then (editor) ->
|
||||
expect(editor.getSoftTabs()).toBeFalsy()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open(null, softTabs: false).then (editor) ->
|
||||
expect(editor.getSoftTabs()).toBeFalsy()
|
||||
@@ -3094,6 +3127,7 @@ describe "Editor", ->
|
||||
editor.setDefaultCharWidth(10)
|
||||
editor.setHeight(50)
|
||||
editor.setWidth(50)
|
||||
editor.setHorizontalScrollbarHeight(0)
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
expect(editor.getScrollLeft()).toBe 0
|
||||
|
||||
|
||||
@@ -1803,6 +1803,13 @@ describe "EditorView", ->
|
||||
expect(editorView.renderedLines.find('.line:eq(10) .indent-guide').text()).toBe "#{eol} "
|
||||
expect(editorView.renderedLines.find('.line:eq(10) .invisible-character').text()).toBe eol
|
||||
|
||||
describe "when editor.showIndentGuide is set to false", ->
|
||||
it "does not render the indent guide on whitespace only lines (regression)", ->
|
||||
editorView.attachToDom()
|
||||
editor.setText(' ')
|
||||
atom.config.set('editor.showIndentGuide', false)
|
||||
expect(editorView.renderedLines.find('.line:eq(0) .indent-guide').length).toBe 0
|
||||
|
||||
describe "when soft-wrap is enabled", ->
|
||||
beforeEach ->
|
||||
jasmine.unspy(window, 'setTimeout')
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Look, this is a comment. Don't go making assumtions that I want soft tabs
|
||||
* because this block comment has leading spaces, Geez.
|
||||
*/
|
||||
|
||||
if (beNice) {
|
||||
console.log('Thank you for being nice.');
|
||||
}
|
||||
@@ -131,15 +131,21 @@ describe "ThemeManager", ->
|
||||
|
||||
describe "requireStylesheet(path)", ->
|
||||
it "synchronously loads css at the given path and installs a style tag for it in the head", ->
|
||||
themeManager.on 'stylesheets-changed', stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
themeManager.on 'stylesheet-added', stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
|
||||
cssPath = atom.project.resolve('css.css')
|
||||
lengthBefore = $('head style').length
|
||||
|
||||
themeManager.requireStylesheet(cssPath)
|
||||
expect($('head style').length).toBe lengthBefore + 1
|
||||
|
||||
expect(stylesheetAddedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
|
||||
element = $('head style[id*="css.css"]')
|
||||
expect(element.attr('id')).toBe themeManager.stringToId(cssPath)
|
||||
expect(element.text()).toBe fs.readFileSync(cssPath, 'utf8')
|
||||
expect(element[0].sheet).toBe stylesheetAddedHandler.argsForCall[0][0]
|
||||
|
||||
# doesn't append twice
|
||||
themeManager.requireStylesheet(cssPath)
|
||||
@@ -187,9 +193,18 @@ describe "ThemeManager", ->
|
||||
themeManager.requireStylesheet(cssPath)
|
||||
expect($(document.body).css('font-weight')).toBe("bold")
|
||||
|
||||
themeManager.on 'stylesheet-removed', stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
|
||||
themeManager.on 'stylesheets-changed', stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
|
||||
themeManager.removeStylesheet(cssPath)
|
||||
|
||||
expect($(document.body).css('font-weight')).not.toBe("bold")
|
||||
|
||||
expect(stylesheetRemovedHandler).toHaveBeenCalled()
|
||||
stylesheet = stylesheetRemovedHandler.argsForCall[0][0]
|
||||
expect(stylesheet instanceof CSSStyleSheet).toBe true
|
||||
expect(stylesheet.cssRules[0].selectorText).toBe 'body'
|
||||
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
|
||||
describe "base stylesheet loading", ->
|
||||
@@ -219,20 +234,21 @@ describe "ThemeManager", ->
|
||||
|
||||
describe "when the user stylesheet changes", ->
|
||||
it "reloads it", ->
|
||||
[stylesheetRemovedHandler, stylesheetAddedHandler, stylesheetsChangedHandler] = []
|
||||
userStylesheetPath = path.join(temp.mkdirSync("atom"), 'styles.less')
|
||||
fs.writeFileSync(userStylesheetPath, 'body {border-style: dotted !important;}')
|
||||
|
||||
spyOn(themeManager, 'getUserStylesheetPath').andReturn userStylesheetPath
|
||||
themeManager.on 'stylesheets-changed', stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
|
||||
waitsForPromise ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
runs ->
|
||||
expect($(document.body).css('border-style')).toBe 'dotted'
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
stylesheetsChangedHandler.reset()
|
||||
themeManager.on 'stylesheets-changed', stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
themeManager.on 'stylesheet-removed', stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
|
||||
themeManager.on 'stylesheet-added', stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
|
||||
spyOn(themeManager, 'loadUserStylesheet').andCallThrough()
|
||||
|
||||
expect($(document.body).css('border-style')).toBe 'dotted'
|
||||
fs.writeFileSync(userStylesheetPath, 'body {border-style: dashed}')
|
||||
|
||||
waitsFor ->
|
||||
@@ -240,7 +256,16 @@ describe "ThemeManager", ->
|
||||
|
||||
runs ->
|
||||
expect($(document.body).css('border-style')).toBe 'dashed'
|
||||
|
||||
expect(stylesheetRemovedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetRemovedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dotted'
|
||||
|
||||
expect(stylesheetAddedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetAddedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dashed'
|
||||
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
|
||||
stylesheetRemovedHandler.reset()
|
||||
stylesheetsChangedHandler.reset()
|
||||
fs.removeSync(userStylesheetPath)
|
||||
|
||||
@@ -248,6 +273,8 @@ describe "ThemeManager", ->
|
||||
themeManager.loadUserStylesheet.callCount is 2
|
||||
|
||||
runs ->
|
||||
expect(stylesheetRemovedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetRemovedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dashed'
|
||||
expect($(document.body).css('border-style')).toBe 'none'
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
|
||||
@@ -259,5 +286,10 @@ describe "ThemeManager", ->
|
||||
runs ->
|
||||
spyOn(console, 'warn')
|
||||
expect(-> atom.config.set('core.themes', ['atom-light-ui', 'theme-really-does-not-exist'])).not.toThrow()
|
||||
|
||||
waitsFor (done) ->
|
||||
themeManager.once 'reloaded', done
|
||||
|
||||
runs ->
|
||||
expect(console.warn.callCount).toBe 1
|
||||
expect(console.warn.argsForCall[0][0].length).toBeGreaterThan 0
|
||||
|
||||
+5
-2
@@ -39,7 +39,7 @@ class Atom extends Model
|
||||
# Public: Load or create the Atom environment in the given mode.
|
||||
#
|
||||
# - mode: Pass 'editor' or 'spec' depending on the kind of environment you
|
||||
# want to build.
|
||||
# want to build.
|
||||
#
|
||||
# Returns an Atom instance, fully initialized
|
||||
@loadOrCreate: (mode) ->
|
||||
@@ -473,12 +473,15 @@ class Atom extends Model
|
||||
# Public: Set the full screen state of the current window.
|
||||
setFullScreen: (fullScreen=false) ->
|
||||
ipc.send('call-window-method', 'setFullScreen', fullScreen)
|
||||
if fullScreen then document.body.classList.add("fullscreen") else document.body.classList.remove("fullscreen")
|
||||
|
||||
# Public: Is the current window in full screen mode?
|
||||
isFullScreen: ->
|
||||
@getCurrentWindow().isFullScreen()
|
||||
|
||||
# Public: Get the version of the Atom application.
|
||||
#
|
||||
# Returns the version text {String}.
|
||||
getVersion: ->
|
||||
@constructor.getVersion()
|
||||
|
||||
@@ -488,7 +491,7 @@ class Atom extends Model
|
||||
|
||||
# Public: Get the directory path to Atom's configuration area.
|
||||
#
|
||||
# Returns the absolute path to ~/.atom
|
||||
# Returns the absolute path to `~/.atom`.
|
||||
getConfigDirPath: ->
|
||||
@constructor.getConfigDirPath()
|
||||
|
||||
|
||||
@@ -146,6 +146,7 @@ class AtomApplication
|
||||
atomWindow?.browserWindow.inspectElement(x, y)
|
||||
|
||||
@on 'application:open-documentation', -> shell.openExternal('https://atom.io/docs/latest/?app')
|
||||
@on 'application:open-terms-of-use', -> shell.openExternal('https://atom.io/terms')
|
||||
@on 'application:install-update', -> @autoUpdateManager.install()
|
||||
@on 'application:check-for-update', => @autoUpdateManager.check()
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ start = ->
|
||||
app.removeListener 'open-url', addUrlToOpen
|
||||
|
||||
args.pathsToOpen = args.pathsToOpen.map (pathToOpen) ->
|
||||
path.resolve(args.executedFrom ? process.cwd(), pathToOpen)
|
||||
path.resolve(args.executedFrom ? process.cwd(), pathToOpen.toString())
|
||||
|
||||
require('coffee-script').register()
|
||||
if args.devMode
|
||||
|
||||
@@ -12,7 +12,7 @@ ChildProcess = require 'child_process'
|
||||
# args = ['-ef']
|
||||
# stdout = (output) -> console.log(output)
|
||||
# exit = (code) -> console.log("ps -ef exited with #{code}")
|
||||
# process = new BufferredProcess({command, args, stdout, exit})
|
||||
# process = new BufferedProcess({command, args, stdout, exit})
|
||||
# ```
|
||||
module.exports =
|
||||
class BufferedProcess
|
||||
@@ -39,7 +39,14 @@ class BufferedProcess
|
||||
# containing the exit status (optional).
|
||||
constructor: ({command, args, options, stdout, stderr, exit}={}) ->
|
||||
options ?= {}
|
||||
@process = ChildProcess.spawn(command, args, options)
|
||||
# Quick hack. Killing @process will only kill cmd.exe, and not the child
|
||||
# process and will just orphan it. Does not escape ^ (cmd's escape symbol).
|
||||
# Related to joyent/node#2318
|
||||
if process.platform is "win32"
|
||||
@process = ChildProcess.spawn(process.env.comspec || "cmd.exe",
|
||||
[ "/c", command ].concat(args), options)
|
||||
else
|
||||
@process = ChildProcess.spawn(command, args, options)
|
||||
@killed = false
|
||||
|
||||
stdoutClosed = true
|
||||
|
||||
+5
-3
@@ -222,11 +222,13 @@ class Config
|
||||
#
|
||||
# keyPath - The {String} name of the key to observe
|
||||
# options - An optional {Object} containing the `callNow` key.
|
||||
# callback - The {Function} that fires when the. It is given a single argument, `value`,
|
||||
# which is the new value of `keyPath`.
|
||||
# callback - The {Function} to call when the value of the key changes.
|
||||
# The first argument will be the new value of the key and the
|
||||
# second argument will be an {Object} with a `previous` property
|
||||
# that is the prior value of the key.
|
||||
#
|
||||
# Returns an {Object} with the following keys:
|
||||
# :off - A {Function} that unobserves the `keyPath` with called.
|
||||
# :off - A {Function} that unobserves the `keyPath` when called.
|
||||
observe: (keyPath, options={}, callback) ->
|
||||
if _.isFunction(options)
|
||||
callback = options
|
||||
|
||||
@@ -78,7 +78,11 @@ class CursorView extends View
|
||||
setVisible: (visible) ->
|
||||
unless @visible is visible
|
||||
@visible = visible
|
||||
@toggle(@visible)
|
||||
hiddenCursor = 'hidden-cursor'
|
||||
if visible
|
||||
@removeClass hiddenCursor
|
||||
else
|
||||
@addClass hiddenCursor
|
||||
|
||||
stopBlinking: ->
|
||||
@constructor.stopBlinking(this) if @blinking
|
||||
|
||||
+1
-1
@@ -465,7 +465,7 @@ class Cursor extends Model
|
||||
getCurrentParagraphBufferRange: ->
|
||||
@editor.languageMode.rowRangeForParagraphAtBufferRow(@getBufferRow())
|
||||
|
||||
# Public: Returns the characters preceeding the cursor in the current word.
|
||||
# Public: Returns the characters preceding the cursor in the current word.
|
||||
getCurrentWordPrefix: ->
|
||||
@editor.getTextInBufferRange([@getBeginningOfCurrentWordBufferPosition(), @getBufferPosition()])
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ class DisplayBuffer extends Model
|
||||
|
||||
verticalScrollMargin: 2
|
||||
horizontalScrollMargin: 6
|
||||
horizontalScrollbarHeight: 15
|
||||
verticalScrollbarWidth: 15
|
||||
|
||||
constructor: ({tabLength, @editorWidthInChars, @tokenizedBuffer, buffer}={}) ->
|
||||
super
|
||||
@@ -111,32 +113,83 @@ class DisplayBuffer extends Model
|
||||
getHorizontalScrollMargin: -> @horizontalScrollMargin
|
||||
setHorizontalScrollMargin: (@horizontalScrollMargin) -> @horizontalScrollMargin
|
||||
|
||||
getHeight: -> @height ? @getScrollHeight()
|
||||
getHorizontalScrollbarHeight: -> @horizontalScrollbarHeight
|
||||
setHorizontalScrollbarHeight: (@horizontalScrollbarHeight) -> @horizontalScrollbarHeight
|
||||
|
||||
getVerticalScrollbarWidth: -> @verticalScrollbarWidth
|
||||
setVerticalScrollbarWidth: (@verticalScrollbarWidth) -> @verticalScrollbarWidth
|
||||
|
||||
getHeight: ->
|
||||
if @height?
|
||||
@height
|
||||
else
|
||||
if @horizontallyScrollable()
|
||||
@getScrollHeight() + @getHorizontalScrollbarHeight()
|
||||
else
|
||||
@getScrollHeight()
|
||||
|
||||
setHeight: (@height) -> @height
|
||||
|
||||
getWidth: -> @width ? @getScrollWidth()
|
||||
getClientHeight: (reentrant) ->
|
||||
if @horizontallyScrollable(reentrant)
|
||||
@getHeight() - @getHorizontalScrollbarHeight()
|
||||
else
|
||||
@getHeight()
|
||||
|
||||
getClientWidth: (reentrant) ->
|
||||
if @verticallyScrollable(reentrant)
|
||||
@getWidth() - @getVerticalScrollbarWidth()
|
||||
else
|
||||
@getWidth()
|
||||
|
||||
horizontallyScrollable: (reentrant) ->
|
||||
return false unless @width?
|
||||
return false if @getSoftWrap()
|
||||
if reentrant
|
||||
@getScrollWidth() > @getWidth()
|
||||
else
|
||||
@getScrollWidth() > @getClientWidth(true)
|
||||
|
||||
verticallyScrollable: (reentrant) ->
|
||||
return false unless @height?
|
||||
if reentrant
|
||||
@getScrollHeight() > @getHeight()
|
||||
else
|
||||
@getScrollHeight() > @getClientHeight(true)
|
||||
|
||||
getWidth: ->
|
||||
if @width?
|
||||
@width
|
||||
else
|
||||
if @verticallyScrollable()
|
||||
@getScrollWidth() + @getVerticalScrollbarWidth()
|
||||
else
|
||||
@getScrollWidth()
|
||||
|
||||
setWidth: (newWidth) ->
|
||||
oldWidth = @width
|
||||
@width = newWidth
|
||||
@updateWrappedScreenLines() if newWidth isnt oldWidth and @softWrap
|
||||
@setScrollTop(@getScrollTop()) # Ensure scrollTop is still valid in case horizontal scrollbar disappeared
|
||||
@width
|
||||
|
||||
getScrollTop: -> @scrollTop
|
||||
setScrollTop: (scrollTop) ->
|
||||
if @manageScrollPosition
|
||||
@scrollTop = Math.max(0, Math.min(@getScrollHeight() - @getHeight(), scrollTop))
|
||||
@scrollTop = Math.max(0, Math.min(@getScrollHeight() - @getClientHeight(), scrollTop))
|
||||
else
|
||||
@scrollTop = scrollTop
|
||||
|
||||
getScrollBottom: -> @scrollTop + @height
|
||||
setScrollBottom: (scrollBottom) ->
|
||||
@setScrollTop(scrollBottom - @height)
|
||||
@setScrollTop(scrollBottom - @getClientHeight())
|
||||
@getScrollBottom()
|
||||
|
||||
getScrollLeft: -> @scrollLeft
|
||||
setScrollLeft: (scrollLeft) ->
|
||||
if @manageScrollPosition
|
||||
@scrollLeft = Math.max(0, Math.min(@getScrollWidth() - @getWidth(), scrollLeft))
|
||||
@scrollLeft = Math.max(0, Math.min(@getScrollWidth() - @getClientWidth(), scrollLeft))
|
||||
@scrollLeft
|
||||
else
|
||||
@scrollLeft = scrollLeft
|
||||
|
||||
@@ -151,6 +204,8 @@ class DisplayBuffer extends Model
|
||||
getDefaultCharWidth: -> @defaultCharWidth
|
||||
setDefaultCharWidth: (@defaultCharWidth) -> @defaultCharWidth
|
||||
|
||||
getCursorWidth: -> 1
|
||||
|
||||
getScopedCharWidth: (scopeNames, char) ->
|
||||
@getScopedCharWidths(scopeNames)[char]
|
||||
|
||||
@@ -178,7 +233,7 @@ class DisplayBuffer extends Model
|
||||
@getLineCount() * @getLineHeight()
|
||||
|
||||
getScrollWidth: ->
|
||||
@getMaxLineLength() * @getDefaultCharWidth()
|
||||
(@getMaxLineLength() * @getDefaultCharWidth()) + @getCursorWidth()
|
||||
|
||||
getVisibleRowRange: ->
|
||||
unless @getLineHeight() > 0
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
React = require 'react'
|
||||
{div, span} = require 'reactionary'
|
||||
{debounce} = require 'underscore-plus'
|
||||
scrollbarStyle = require 'scrollbar-style'
|
||||
|
||||
GutterComponent = require './gutter-component'
|
||||
EditorScrollViewComponent = require './editor-scroll-view-component'
|
||||
ScrollbarComponent = require './scrollbar-component'
|
||||
ScrollbarCornerComponent = require './scrollbar-corner-component'
|
||||
SubscriberMixin = require './subscriber-mixin'
|
||||
|
||||
module.exports =
|
||||
@@ -20,10 +22,15 @@ EditorComponent = React.createClass
|
||||
cursorsMoved: false
|
||||
preservedRowRange: null
|
||||
scrollingVertically: false
|
||||
gutterWidth: 0
|
||||
refreshingScrollbars: false
|
||||
measuringScrollbars: true
|
||||
|
||||
render: ->
|
||||
{focused, fontSize, lineHeight, fontFamily, showIndentGuide} = @state
|
||||
{editor, cursorBlinkPeriod, cursorBlinkResumeDelay} = @props
|
||||
maxLineNumberDigits = editor.getScreenLineCount().toString().length
|
||||
|
||||
if @isMounted()
|
||||
renderedRowRange = @getRenderedRowRange()
|
||||
scrollHeight = editor.getScrollHeight()
|
||||
@@ -31,14 +38,19 @@ EditorComponent = React.createClass
|
||||
scrollTop = editor.getScrollTop()
|
||||
scrollLeft = editor.getScrollLeft()
|
||||
lineHeightInPixels = editor.getLineHeight()
|
||||
horizontalScrollbarHeight = editor.getHorizontalScrollbarHeight()
|
||||
verticalScrollbarWidth = editor.getVerticalScrollbarWidth()
|
||||
verticallyScrollable = editor.verticallyScrollable()
|
||||
horizontallyScrollable = editor.horizontallyScrollable()
|
||||
|
||||
className = 'editor editor-colors react'
|
||||
className += ' is-focused' if focused
|
||||
|
||||
div className: className, style: {fontSize, lineHeight, fontFamily}, tabIndex: -1,
|
||||
GutterComponent {
|
||||
editor, renderedRowRange, scrollTop, scrollHeight,
|
||||
lineHeight: lineHeightInPixels, @pendingChanges
|
||||
editor, renderedRowRange, maxLineNumberDigits, scrollTop, scrollHeight,
|
||||
lineHeight: lineHeightInPixels, fontSize, fontFamily, @pendingChanges,
|
||||
onWidthChanged: @onGutterWidthChanged
|
||||
}
|
||||
|
||||
EditorScrollViewComponent {
|
||||
@@ -55,6 +67,10 @@ EditorComponent = React.createClass
|
||||
onScroll: @onVerticalScroll
|
||||
scrollTop: scrollTop
|
||||
scrollHeight: scrollHeight
|
||||
visible: verticallyScrollable and not @refreshingScrollbars and not @measuringScrollbars
|
||||
scrollableInOppositeDirection: horizontallyScrollable
|
||||
verticalScrollbarWidth: verticalScrollbarWidth
|
||||
horizontalScrollbarHeight: horizontalScrollbarHeight
|
||||
|
||||
ScrollbarComponent
|
||||
ref: 'horizontalScrollbar'
|
||||
@@ -62,7 +78,19 @@ EditorComponent = React.createClass
|
||||
orientation: 'horizontal'
|
||||
onScroll: @onHorizontalScroll
|
||||
scrollLeft: scrollLeft
|
||||
scrollWidth: scrollWidth
|
||||
scrollWidth: scrollWidth + @gutterWidth
|
||||
visible: horizontallyScrollable and not @refreshingScrollbars and not @measuringScrollbars
|
||||
scrollableInOppositeDirection: verticallyScrollable
|
||||
verticalScrollbarWidth: verticalScrollbarWidth
|
||||
horizontalScrollbarHeight: horizontalScrollbarHeight
|
||||
|
||||
# Also used to measure the height/width of scrollbars after the initial render
|
||||
ScrollbarCornerComponent
|
||||
ref: 'scrollbarCorner'
|
||||
visible: not @refreshingScrollbars and (@measuringScrollbars or horizontallyScrollable and verticallyScrollable)
|
||||
measuringScrollbars: @measuringScrollbars
|
||||
height: horizontalScrollbarHeight
|
||||
width: verticalScrollbarWidth
|
||||
|
||||
getRenderedRowRange: ->
|
||||
renderedRowRange = @props.editor.getVisibleRowRange()
|
||||
@@ -86,6 +114,9 @@ EditorComponent = React.createClass
|
||||
@observeEditor()
|
||||
@listenForDOMEvents()
|
||||
@listenForCommands()
|
||||
@measureScrollbars()
|
||||
@subscribe atom.themes, 'stylesheet-added stylsheet-removed', @onStylesheetsChanged
|
||||
@subscribe scrollbarStyle.changes, @refreshScrollbars
|
||||
@props.editor.setVisible(true)
|
||||
@requestUpdate()
|
||||
|
||||
@@ -99,6 +130,8 @@ EditorComponent = React.createClass
|
||||
componentDidUpdate: ->
|
||||
@pendingChanges.length = 0
|
||||
@cursorsMoved = false
|
||||
@refreshingScrollbars = false
|
||||
@measureScrollbars() if @measuringScrollbars
|
||||
@props.parentView.trigger 'editor:display-updated'
|
||||
|
||||
observeEditor: ->
|
||||
@@ -141,8 +174,8 @@ EditorComponent = React.createClass
|
||||
'editor:move-to-previous-word': => editor.moveCursorToPreviousWord()
|
||||
'editor:select-word': => editor.selectWord()
|
||||
'editor:consolidate-selections': @consolidateSelections
|
||||
'editor:backspace-to-beginning-of-word': => editor.backspaceToBeginningOfWord()
|
||||
'editor:backspace-to-beginning-of-line': => editor.backspaceToBeginningOfLine()
|
||||
'editor:delete-to-beginning-of-word': => editor.deleteToBeginningOfWord()
|
||||
'editor:delete-to-beginning-of-line': => editor.deleteToBeginningOfLine()
|
||||
'editor:delete-to-end-of-word': => editor.deleteToEndOfWord()
|
||||
'editor:delete-line': => editor.deleteLine()
|
||||
'editor:cut-to-end-of-line': => editor.cutToEndOfLine()
|
||||
@@ -230,6 +263,16 @@ EditorComponent = React.createClass
|
||||
@subscribe atom.config.observe 'editor.fontSize', @setFontSize
|
||||
@subscribe atom.config.observe 'editor.showIndentGuide', @setShowIndentGuide
|
||||
|
||||
measureScrollbars: ->
|
||||
@measuringScrollbars = false
|
||||
|
||||
{editor} = @props
|
||||
scrollbarCornerNode = @refs.scrollbarCorner.getDOMNode()
|
||||
width = (scrollbarCornerNode.offsetWidth - scrollbarCornerNode.clientWidth) or 15
|
||||
height = (scrollbarCornerNode.offsetHeight - scrollbarCornerNode.clientHeight) or 15
|
||||
editor.setVerticalScrollbarWidth(width)
|
||||
editor.setHorizontalScrollbarHeight(height)
|
||||
|
||||
setFontSize: (fontSize) ->
|
||||
@setState({fontSize})
|
||||
|
||||
@@ -285,6 +328,35 @@ EditorComponent = React.createClass
|
||||
|
||||
event.preventDefault()
|
||||
|
||||
onStylesheetsChanged: (stylesheet) ->
|
||||
@refreshScrollbars() if @containsScrollbarSelector(stylesheet)
|
||||
|
||||
containsScrollbarSelector: (stylesheet) ->
|
||||
for rule in stylesheet.cssRules
|
||||
if rule.selectorText?.indexOf('scrollbar') > -1
|
||||
return true
|
||||
false
|
||||
|
||||
refreshScrollbars: ->
|
||||
# Believe it or not, proper handling of changes to scrollbar styles requires
|
||||
# three DOM updates.
|
||||
|
||||
# Scrollbar style changes won't apply to scrollbars that are already
|
||||
# visible, so first we need to hide scrollbars so we can redisplay them and
|
||||
# force Chromium to apply updates.
|
||||
@refreshingScrollbars = true
|
||||
@requestUpdate()
|
||||
|
||||
# Next, we display only the scrollbar corner so we can measure the new
|
||||
# scrollbar dimensions. The ::measuringScrollbars property will be set back
|
||||
# to false after the scrollbars are measured.
|
||||
@measuringScrollbars = true
|
||||
@requestUpdate()
|
||||
|
||||
# Finally, we restore the scrollbars based on the newly-measured dimensions
|
||||
# if the editor's content and dimensions require them to be visible.
|
||||
@requestUpdate()
|
||||
|
||||
clearPreservedRowRange: ->
|
||||
@preservedRowRange = null
|
||||
@scrollingVertically = false
|
||||
@@ -325,6 +397,9 @@ EditorComponent = React.createClass
|
||||
onCursorsMoved: ->
|
||||
@cursorsMoved = true
|
||||
|
||||
onGutterWidthChanged: (@gutterWidth) ->
|
||||
@requestUpdate()
|
||||
|
||||
requestUpdate: ->
|
||||
if @batchingUpdates
|
||||
@updateRequested = true
|
||||
|
||||
@@ -182,17 +182,19 @@ EditorScrollViewComponent = React.createClass
|
||||
measureHeightAndWidth: ->
|
||||
return unless @isMounted()
|
||||
|
||||
node = @getDOMNode()
|
||||
computedStyle = getComputedStyle(node)
|
||||
{editor} = @props
|
||||
node = @getDOMNode()
|
||||
editorNode = node.parentNode
|
||||
{position} = getComputedStyle(editorNode)
|
||||
{width, height} = editorNode.style
|
||||
|
||||
unless computedStyle.height is '0px'
|
||||
clientHeight = node.clientHeight
|
||||
if position is 'absolute' or height
|
||||
clientHeight = node.clientHeight
|
||||
editor.setHeight(clientHeight) if clientHeight > 0
|
||||
|
||||
unless computedStyle.width is '0px'
|
||||
if position is 'absolute' or width
|
||||
clientWidth = node.clientWidth
|
||||
editor.setWidth(clientWidth) if clientHeight > 0
|
||||
editor.setWidth(clientWidth) if clientWidth > 0
|
||||
|
||||
focus: ->
|
||||
@refs.input.focus()
|
||||
|
||||
@@ -50,7 +50,7 @@ class EditorView extends View
|
||||
showLineNumbers: true
|
||||
autoIndent: true
|
||||
normalizeIndentOnPaste: true
|
||||
nonWordCharacters: "./\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-"
|
||||
nonWordCharacters: "/\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-"
|
||||
preferredLineLength: 80
|
||||
tabLength: 2
|
||||
softWrap: false
|
||||
@@ -154,8 +154,8 @@ class EditorView extends View
|
||||
'editor:move-to-previous-word': => @editor.moveCursorToPreviousWord()
|
||||
'editor:select-word': => @editor.selectWord()
|
||||
'editor:consolidate-selections': (event) => @consolidateSelections(event)
|
||||
'editor:backspace-to-beginning-of-word': => @editor.backspaceToBeginningOfWord()
|
||||
'editor:backspace-to-beginning-of-line': => @editor.backspaceToBeginningOfLine()
|
||||
'editor:delete-to-beginning-of-word': => @editor.deleteToBeginningOfWord()
|
||||
'editor:delete-to-beginning-of-line': => @editor.deleteToBeginningOfLine()
|
||||
'editor:delete-to-end-of-word': => @editor.deleteToEndOfWord()
|
||||
'editor:delete-line': => @editor.deleteLine()
|
||||
'editor:cut-to-end-of-line': => @editor.cutToEndOfLine()
|
||||
@@ -387,7 +387,7 @@ class EditorView extends View
|
||||
|
||||
screenPosition = @screenPositionFromMouseEvent(e)
|
||||
if clickCount == 1
|
||||
if e.metaKey
|
||||
if e.metaKey or (process.platform isnt 'darwin' and e.ctrlKey)
|
||||
@editor.addCursorAtScreenPosition(screenPosition)
|
||||
else if e.shiftKey
|
||||
@editor.selectToScreenPosition(screenPosition)
|
||||
@@ -460,6 +460,9 @@ class EditorView extends View
|
||||
@hiddenInput.val(lastInput)
|
||||
false
|
||||
|
||||
# Ignore paste event, on Linux is wrongly emitted when user presses ctrl-v.
|
||||
@on "paste", -> false
|
||||
|
||||
bringHiddenInputIntoView: ->
|
||||
@hiddenInput.css(top: @scrollTop(), left: @scrollLeft())
|
||||
|
||||
@@ -1487,7 +1490,7 @@ class EditorView extends View
|
||||
position = 0
|
||||
for token in tokens
|
||||
@updateScopeStack(line, scopeStack, token.scopes)
|
||||
hasIndentGuide = not mini and showIndentGuide and token.hasLeadingWhitespace or (token.hasTrailingWhitespace and lineIsWhitespaceOnly)
|
||||
hasIndentGuide = not mini and showIndentGuide and (token.hasLeadingWhitespace or (token.hasTrailingWhitespace and lineIsWhitespaceOnly))
|
||||
line.push(token.getValueAsHtml({invisibles, hasIndentGuide}))
|
||||
position += token.value.length
|
||||
|
||||
|
||||
+66
-20
@@ -109,8 +109,8 @@ TextMateScopeSelector = require('first-mate').ScopeSelector
|
||||
# - {::insertNewlineAbove}
|
||||
# - {::insertNewlineBelow}
|
||||
# - {::backspace}
|
||||
# - {::backspaceToBeginningOfWord}
|
||||
# - {::backspaceToBeginningOfLine}
|
||||
# - {::deleteToBeginningOfWord}
|
||||
# - {::deleteToBeginningOfLine}
|
||||
# - {::delete}
|
||||
# - {::deleteToEndOfWord}
|
||||
# - {::deleteLine}
|
||||
@@ -160,7 +160,7 @@ class Editor extends Model
|
||||
|
||||
@displayBuffer ?= new DisplayBuffer({buffer, tabLength, softWrap})
|
||||
@buffer = @displayBuffer.buffer
|
||||
@softTabs = @buffer.usesSoftTabs() ? @softTabs ? atom.config.get('editor.softTabs') ? true
|
||||
@softTabs = @usesSoftTabs() ? @softTabs ? atom.config.get('editor.softTabs') ? true
|
||||
|
||||
for marker in @findMarkers(@getSelectionMarkerAttributes())
|
||||
marker.setAttributes(preserveFolds: true)
|
||||
@@ -264,7 +264,7 @@ class Editor extends Model
|
||||
else
|
||||
'untitled'
|
||||
|
||||
# Controls visiblity based on the given {Boolean}.
|
||||
# Controls visibility based on the given {Boolean}.
|
||||
setVisible: (visible) -> @displayBuffer.setVisible(visible)
|
||||
|
||||
# Set the number of characters that can be displayed horizontally in the
|
||||
@@ -275,7 +275,7 @@ class Editor extends Model
|
||||
setEditorWidthInChars: (editorWidthInChars) ->
|
||||
@displayBuffer.setEditorWidthInChars(editorWidthInChars)
|
||||
|
||||
# Public: Sets the column at which columsn will soft wrap
|
||||
# Public: Sets the column at which column will soft wrap
|
||||
getSoftWrapColumn: -> @displayBuffer.getSoftWrapColumn()
|
||||
|
||||
# Public: Returns a {Boolean} indicating whether softTabs are enabled for this
|
||||
@@ -317,6 +317,19 @@ class Editor extends Model
|
||||
# Public: Set the on-screen length of tab characters.
|
||||
setTabLength: (tabLength) -> @displayBuffer.setTabLength(tabLength)
|
||||
|
||||
# Public: Determine if the buffer uses hard or soft tabs.
|
||||
#
|
||||
# Returns `true` if the first non-comment line with leading whitespace starts
|
||||
# with a space character. Returns `false` if it starts with a hard tab (`\t`).
|
||||
#
|
||||
# Returns a {Boolean},
|
||||
usesSoftTabs: ->
|
||||
for bufferRow in [0..@buffer.getLastRow()]
|
||||
continue if @displayBuffer.tokenizedBuffer.lineForScreenRow(bufferRow).isComment()
|
||||
if match = @buffer.lineForRow(bufferRow).match(/^\s/)
|
||||
return match[0][0] != '\t'
|
||||
undefined
|
||||
|
||||
# Public: Clip the given {Point} to a valid position in the buffer.
|
||||
#
|
||||
# If the given {Point} describes a position that is actually reachable by the
|
||||
@@ -563,8 +576,8 @@ class Editor extends Model
|
||||
|
||||
bufferRowForScreenRow: (row) -> @displayBuffer.bufferRowForScreenRow(row)
|
||||
|
||||
# Public: Get the syntactic scopes for the most the given position in buffer
|
||||
# coorditanates.
|
||||
# Public: Get the syntactic scopes for the given position in buffer
|
||||
# coordinates.
|
||||
#
|
||||
# For example, if called with a position inside the parameter list of an
|
||||
# anonymous CoffeeScript function, the method returns the following array:
|
||||
@@ -645,17 +658,27 @@ class Editor extends Model
|
||||
backspace: ->
|
||||
@mutateSelectedText (selection) -> selection.backspace()
|
||||
|
||||
# Deprecated: Use {::deleteToBeginningOfWord} instead.
|
||||
backspaceToBeginningOfWord: ->
|
||||
deprecate("Use Editor::deleteToBeginningOfWord() instead")
|
||||
@deleteToBeginningOfWord()
|
||||
|
||||
# Deprecated: Use {::deleteToBeginningOfLine} instead.
|
||||
backspaceToBeginningOfLine: ->
|
||||
deprecate("Use Editor::deleteToBeginningOfLine() instead")
|
||||
@deleteToBeginningOfLine()
|
||||
|
||||
# Public: For each selection, if the selection is empty, delete all characters
|
||||
# of the containing word that precede the cursor. Otherwise delete the
|
||||
# selected text.
|
||||
backspaceToBeginningOfWord: ->
|
||||
@mutateSelectedText (selection) -> selection.backspaceToBeginningOfWord()
|
||||
deleteToBeginningOfWord: ->
|
||||
@mutateSelectedText (selection) -> selection.deleteToBeginningOfWord()
|
||||
|
||||
# Public: For each selection, if the selection is empty, delete all characters
|
||||
# of the containing line that precede the cursor. Otherwise delete the
|
||||
# selected text.
|
||||
backspaceToBeginningOfLine: ->
|
||||
@mutateSelectedText (selection) -> selection.backspaceToBeginningOfLine()
|
||||
deleteToBeginningOfLine: ->
|
||||
@mutateSelectedText (selection) -> selection.deleteToBeginningOfLine()
|
||||
|
||||
# Public: For each selection, if the selection is empty, delete the character
|
||||
# preceding the cursor. Otherwise delete the selected text.
|
||||
@@ -725,13 +748,24 @@ class Editor extends Model
|
||||
# Public: For each selection, replace the selected text with the contents of
|
||||
# the clipboard.
|
||||
#
|
||||
# If the clipboard contains the same number of selections as the current
|
||||
# editor, each selection will be replaced with the content of the
|
||||
# corresponding clipboard selection text.
|
||||
#
|
||||
# options - See {Selection::insertText}.
|
||||
pasteText: (options={}) ->
|
||||
{text, metadata} = atom.clipboard.readWithMetadata()
|
||||
|
||||
containsNewlines = text.indexOf('\n') isnt -1
|
||||
|
||||
if atom.config.get('editor.normalizeIndentOnPaste') and metadata
|
||||
if metadata?.selections? and metadata.selections.length is @getSelections().length
|
||||
@mutateSelectedText (selection, index) ->
|
||||
text = metadata.selections[index]
|
||||
selection.insertText(text, options)
|
||||
|
||||
return
|
||||
|
||||
else if atom.config.get("editor.normalizeIndentOnPaste") and metadata?.indentBasis?
|
||||
if !@getCursor().hasPrecedingCharactersOnLine() or containsNewlines
|
||||
options.indentBasis ?= metadata.indentBasis
|
||||
|
||||
@@ -1007,7 +1041,7 @@ class Editor extends Model
|
||||
#
|
||||
# fn - A {Function} that will be called with each {Selection}.
|
||||
mutateSelectedText: (fn) ->
|
||||
@transact => fn(selection) for selection in @getSelections()
|
||||
@transact => fn(selection,index) for selection,index in @getSelections()
|
||||
|
||||
replaceSelectedText: (options={}, fn) ->
|
||||
{selectWordIfEmpty} = options
|
||||
@@ -1269,7 +1303,7 @@ class Editor extends Model
|
||||
# Public: Determine if a given range in buffer coordinates intersects a
|
||||
# selection.
|
||||
#
|
||||
# bufferRange - A {Range} or range-comptatible {Array}.
|
||||
# bufferRange - A {Range} or range-compatible {Array}.
|
||||
#
|
||||
# Returns a {Boolean}.
|
||||
selectionIntersectsBufferRange: (bufferRange) ->
|
||||
@@ -1543,28 +1577,28 @@ class Editor extends Model
|
||||
# cursor is already on the first character of the line, move it to the
|
||||
# beginning of the line.
|
||||
#
|
||||
# This method may merge selections that end up intesecting.
|
||||
# This method may merge selections that end up intersecting.
|
||||
selectToFirstCharacterOfLine: ->
|
||||
@expandSelectionsBackward (selection) => selection.selectToFirstCharacterOfLine()
|
||||
|
||||
# Public: Move the cursor of each selection to the end of its line while
|
||||
# preserving the selection's tail position.
|
||||
#
|
||||
# This method may merge selections that end up intesecting.
|
||||
# This method may merge selections that end up intersecting.
|
||||
selectToEndOfLine: ->
|
||||
@expandSelectionsForward (selection) => selection.selectToEndOfLine()
|
||||
|
||||
# Public: For each selection, move its cursor to the preceding word boundary
|
||||
# while maintaining the selection's tail position.
|
||||
#
|
||||
# This method may merge selections that end up intesecting.
|
||||
# This method may merge selections that end up intersecting.
|
||||
selectToPreviousWordBoundary: ->
|
||||
@expandSelectionsBackward (selection) => selection.selectToPreviousWordBoundary()
|
||||
|
||||
# Public: For each selection, move its cursor to the next word boundary while
|
||||
# maintaining the selection's tail position.
|
||||
#
|
||||
# This method may merge selections that end up intesecting.
|
||||
# This method may merge selections that end up intersecting.
|
||||
selectToNextWordBoundary: ->
|
||||
@expandSelectionsForward (selection) => selection.selectToNextWordBoundary()
|
||||
|
||||
@@ -1574,7 +1608,7 @@ class Editor extends Model
|
||||
selectLine: ->
|
||||
@expandSelectionsForward (selection) => selection.selectLine()
|
||||
|
||||
# Public: Add a similarly-shaped selection to the next elibible line below
|
||||
# Public: Add a similarly-shaped selection to the next eligible line below
|
||||
# each selection.
|
||||
#
|
||||
# Operates on all selections. If the selection is empty, adds an empty
|
||||
@@ -1585,7 +1619,7 @@ class Editor extends Model
|
||||
addSelectionBelow: ->
|
||||
@expandSelectionsForward (selection) => selection.addSelectionBelow()
|
||||
|
||||
# Public: Add a similarly-shaped selection to the next elibible line above
|
||||
# Public: Add a similarly-shaped selection to the next eligible line above
|
||||
# each selection.
|
||||
#
|
||||
# Operates on all selections. If the selection is empty, adds an empty
|
||||
@@ -1838,6 +1872,8 @@ class Editor extends Model
|
||||
setHeight: (height) -> @displayBuffer.setHeight(height)
|
||||
getHeight: -> @displayBuffer.getHeight()
|
||||
|
||||
getClientHeight: -> @displayBuffer.getClientHeight()
|
||||
|
||||
setWidth: (width) -> @displayBuffer.setWidth(width)
|
||||
getWidth: -> @displayBuffer.getWidth()
|
||||
|
||||
@@ -1876,6 +1912,16 @@ class Editor extends Model
|
||||
|
||||
scrollToBufferPosition: (bufferPosition) -> @displayBuffer.scrollToBufferPosition(bufferPosition)
|
||||
|
||||
horizontallyScrollable: -> @displayBuffer.horizontallyScrollable()
|
||||
|
||||
verticallyScrollable: -> @displayBuffer.verticallyScrollable()
|
||||
|
||||
getHorizontalScrollbarHeight: -> @displayBuffer.getHorizontalScrollbarHeight()
|
||||
setHorizontalScrollbarHeight: (height) -> @displayBuffer.setHorizontalScrollbarHeight(height)
|
||||
|
||||
getVerticalScrollbarWidth: -> @displayBuffer.getVerticalScrollbarWidth()
|
||||
setVerticalScrollbarWidth: (width) -> @displayBuffer.setVerticalScrollbarWidth(width)
|
||||
|
||||
# Deprecated: Call {::joinLines} instead.
|
||||
joinLine: ->
|
||||
deprecate("Use Editor::joinLines() instead")
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ Task = require './task'
|
||||
# `atom.project` global and calling `getRepo()`. Note that this will only be
|
||||
# available when the project is backed by a Git repository.
|
||||
#
|
||||
# This class handles submodules automically by taking a `path` argument to many
|
||||
# This class handles submodules automatically by taking a `path` argument to many
|
||||
# of the methods. This `path` argument will determine which underlying
|
||||
# repository is used.
|
||||
#
|
||||
|
||||
@@ -8,18 +8,19 @@ GutterComponent = React.createClass
|
||||
displayName: 'GutterComponent'
|
||||
mixins: [SubscriberMixin]
|
||||
|
||||
lastMeasuredWidth: null
|
||||
|
||||
render: ->
|
||||
div className: 'gutter',
|
||||
@renderLineNumbers() if @isMounted()
|
||||
|
||||
renderLineNumbers: ->
|
||||
{editor, renderedRowRange, scrollTop, scrollHeight} = @props
|
||||
{editor, renderedRowRange, maxLineNumberDigits, scrollTop, scrollHeight} = @props
|
||||
[startRow, endRow] = renderedRowRange
|
||||
charWidth = editor.getDefaultCharWidth()
|
||||
lineHeight = editor.getLineHeight()
|
||||
maxDigits = editor.getLastBufferRow().toString().length
|
||||
style =
|
||||
width: charWidth * (maxDigits + 1.5)
|
||||
width: charWidth * (maxLineNumberDigits + 1.5)
|
||||
height: scrollHeight
|
||||
WebkitTransform: "translate3d(0, #{-scrollTop}px, 0)"
|
||||
|
||||
@@ -35,7 +36,7 @@ GutterComponent = React.createClass
|
||||
|
||||
key = tokenizedLines[i].id
|
||||
screenRow = startRow + i
|
||||
lineNumbers.push(LineNumberComponent({key, lineNumber, maxDigits, bufferRow, screenRow, lineHeight}))
|
||||
lineNumbers.push(LineNumberComponent({key, lineNumber, maxLineNumberDigits, bufferRow, screenRow, lineHeight}))
|
||||
lastBufferRow = bufferRow
|
||||
|
||||
div className: 'line-numbers', style: style,
|
||||
@@ -45,7 +46,7 @@ GutterComponent = React.createClass
|
||||
# non-zero-delta change to the screen lines has occurred within the current
|
||||
# visible row range.
|
||||
shouldComponentUpdate: (newProps) ->
|
||||
return true unless isEqualForProperties(newProps, @props, 'renderedRowRange', 'scrollTop', 'lineHeight')
|
||||
return true unless isEqualForProperties(newProps, @props, 'renderedRowRange', 'scrollTop', 'lineHeight', 'fontSize')
|
||||
|
||||
{renderedRowRange, pendingChanges} = newProps
|
||||
for change in pendingChanges when change.screenDelta > 0 or change.bufferDelta > 0
|
||||
@@ -53,6 +54,13 @@ GutterComponent = React.createClass
|
||||
|
||||
false
|
||||
|
||||
componentDidUpdate: (oldProps) ->
|
||||
unless @lastMeasuredWidth? and isEqualForProperties(oldProps, @props, 'maxLineNumberDigits', 'fontSize', 'fontFamily')
|
||||
width = @getDOMNode().offsetWidth
|
||||
if width isnt @lastMeasuredWidth
|
||||
@lastMeasuredWidth = width
|
||||
@props.onWidthChanged(width)
|
||||
|
||||
LineNumberComponent = React.createClass
|
||||
displayName: 'LineNumberComponent'
|
||||
|
||||
@@ -66,9 +74,9 @@ LineNumberComponent = React.createClass
|
||||
dangerouslySetInnerHTML: {__html: @buildInnerHTML()}
|
||||
|
||||
buildInnerHTML: ->
|
||||
{lineNumber, maxDigits} = @props
|
||||
if lineNumber.length < maxDigits
|
||||
padding = multiplyString(' ', maxDigits - lineNumber.length)
|
||||
{lineNumber, maxLineNumberDigits} = @props
|
||||
if lineNumber.length < maxLineNumberDigits
|
||||
padding = multiplyString(' ', maxLineNumberDigits - lineNumber.length)
|
||||
padding + lineNumber + @iconDivHTML
|
||||
else
|
||||
lineNumber + @iconDivHTML
|
||||
@@ -76,4 +84,4 @@ LineNumberComponent = React.createClass
|
||||
iconDivHTML: '<div class="icon-right"></div>'
|
||||
|
||||
shouldComponentUpdate: (newProps) ->
|
||||
not isEqualForProperties(newProps, @props, 'lineHeight', 'screenRow')
|
||||
not isEqualForProperties(newProps, @props, 'lineHeight', 'screenRow', 'maxLineNumberDigits')
|
||||
|
||||
@@ -58,7 +58,7 @@ class MenuManager
|
||||
testBody = document.createElement('body')
|
||||
testBody.classList.add(@classesForElement(document.body)...)
|
||||
|
||||
testWorkspace = document.createElement('body')
|
||||
testWorkspace = document.createElement('div')
|
||||
workspaceClasses = @classesForElement(document.body.querySelector('.workspace'))
|
||||
workspaceClasses = ['workspace'] if workspaceClasses.length is 0
|
||||
testWorkspace.classList.add(workspaceClasses...)
|
||||
@@ -69,7 +69,12 @@ class MenuManager
|
||||
@testEditor.classList.add('editor')
|
||||
testWorkspace.appendChild(@testEditor)
|
||||
|
||||
@testEditor.webkitMatchesSelector(selector)
|
||||
element = @testEditor
|
||||
while element
|
||||
return true if element.webkitMatchesSelector(selector)
|
||||
element = element.parentElement
|
||||
|
||||
false
|
||||
|
||||
# Public: Refreshes the currently visible menu.
|
||||
update: ->
|
||||
|
||||
@@ -43,7 +43,9 @@ class PackageManager
|
||||
|
||||
# Public: Get the path to the apm command
|
||||
getApmPath: ->
|
||||
@apmPath ?= path.resolve(__dirname, '..', 'apm', 'node_modules', 'atom-package-manager', 'bin', 'apm')
|
||||
commandName = 'apm'
|
||||
commandName += '.cmd' if process.platform is 'win32'
|
||||
@apmPath ?= path.resolve(__dirname, '..', 'apm', 'node_modules', 'atom-package-manager', 'bin', commandName)
|
||||
|
||||
# Public: Get the paths being used to look for packages.
|
||||
#
|
||||
|
||||
@@ -10,7 +10,7 @@ Pane = require './pane'
|
||||
# Items can be almost anything however most commonly they're {EditorView}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 tiems.
|
||||
# building a package that deals with switching between panes or items.
|
||||
module.exports =
|
||||
class PaneView extends View
|
||||
Delegator.includeInto(this)
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
React = require 'react'
|
||||
{div} = require 'reactionary'
|
||||
{isEqualForProperties} = require 'underscore-plus'
|
||||
{extend, isEqualForProperties} = require 'underscore-plus'
|
||||
|
||||
module.exports =
|
||||
ScrollbarComponent = React.createClass
|
||||
render: ->
|
||||
{orientation, className, scrollHeight, scrollWidth} = @props
|
||||
{orientation, className, scrollHeight, scrollWidth, visible} = @props
|
||||
{scrollableInOppositeDirection, horizontalScrollbarHeight, verticalScrollbarWidth} = @props
|
||||
|
||||
div {className, @onScroll},
|
||||
style = {}
|
||||
style.display = 'none' unless visible
|
||||
switch orientation
|
||||
when 'vertical'
|
||||
style.width = verticalScrollbarWidth
|
||||
style.bottom = horizontalScrollbarHeight if scrollableInOppositeDirection
|
||||
when 'horizontal'
|
||||
style.height = horizontalScrollbarHeight
|
||||
style.right = verticalScrollbarWidth if scrollableInOppositeDirection
|
||||
|
||||
div {className, style, @onScroll},
|
||||
switch orientation
|
||||
when 'vertical'
|
||||
div className: 'scrollbar-content', style: {height: scrollHeight}
|
||||
@@ -21,11 +32,13 @@ ScrollbarComponent = React.createClass
|
||||
throw new Error("Must specify an orientation property of 'vertical' or 'horizontal'")
|
||||
|
||||
shouldComponentUpdate: (newProps) ->
|
||||
return true if newProps.visible isnt @props.visible
|
||||
|
||||
switch @props.orientation
|
||||
when 'vertical'
|
||||
not isEqualForProperties(newProps, @props, 'scrollHeight', 'scrollTop')
|
||||
not isEqualForProperties(newProps, @props, 'scrollHeight', 'scrollTop', 'scrollableInOppositeDirection')
|
||||
when 'horizontal'
|
||||
not isEqualForProperties(newProps, @props, 'scrollWidth', 'scrollLeft')
|
||||
not isEqualForProperties(newProps, @props, 'scrollWidth', 'scrollLeft', 'scrollableInOppositeDirection')
|
||||
|
||||
componentDidUpdate: ->
|
||||
{orientation, scrollTop, scrollLeft} = @props
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
React = require 'react'
|
||||
{div} = require 'reactionary'
|
||||
|
||||
module.exports =
|
||||
ScrollbarComponent = React.createClass
|
||||
render: ->
|
||||
{visible, measuringScrollbars, width, height} = @props
|
||||
|
||||
if measuringScrollbars
|
||||
height = 25
|
||||
width = 25
|
||||
|
||||
display = 'none' unless visible
|
||||
|
||||
div className: 'scrollbar-corner', style: {display, width, height},
|
||||
div style:
|
||||
height: height + 1
|
||||
width: width + 1
|
||||
+25
-3
@@ -382,15 +382,25 @@ class Selection extends Model
|
||||
@selectLeft() if @isEmpty() and not @editor.isFoldedAtScreenRow(@cursor.getScreenRow())
|
||||
@deleteSelectedText()
|
||||
|
||||
# Deprecated: Use {::deleteToBeginningOfWord} instead.
|
||||
backspaceToBeginningOfWord: ->
|
||||
deprecate("Use Selection::deleteToBeginningOfWord() instead")
|
||||
@deleteToBeginningOfWord()
|
||||
|
||||
# Deprecated: Use {::deleteToBeginningOfLine} instead.
|
||||
backspaceToBeginningOfLine: ->
|
||||
deprecate("Use Selection::deleteToBeginningOfLine() instead")
|
||||
@deleteToBeginningOfLine()
|
||||
|
||||
# Public: Removes from the start of the selection to the beginning of the
|
||||
# current word if the selection is empty otherwise it deletes the selection.
|
||||
backspaceToBeginningOfWord: ->
|
||||
deleteToBeginningOfWord: ->
|
||||
@selectToBeginningOfWord() if @isEmpty()
|
||||
@deleteSelectedText()
|
||||
|
||||
# Public: Removes from the beginning of the line which the selection begins on
|
||||
# all the way through to the end of the selection.
|
||||
backspaceToBeginningOfLine: ->
|
||||
deleteToBeginningOfLine: ->
|
||||
if @isEmpty() and @cursor.isAtBeginningOfLine()
|
||||
@selectLeft()
|
||||
else
|
||||
@@ -503,11 +513,23 @@ class Selection extends Model
|
||||
@delete()
|
||||
|
||||
# Public: Copies the current selection to the clipboard.
|
||||
#
|
||||
# If the `maintainClipboard` is set to `true`, a specific metadata property
|
||||
# is created to store each content copied to the clipboard. The clipboard
|
||||
# `text` still contains the concatenation of the clipboard with the
|
||||
# current selection.
|
||||
copy: (maintainClipboard=false) ->
|
||||
return if @isEmpty()
|
||||
text = @editor.buffer.getTextInRange(@getBufferRange())
|
||||
if maintainClipboard
|
||||
text = "#{atom.clipboard.read()}\n#{text}"
|
||||
{text: clipboardText, metadata} = atom.clipboard.readWithMetadata()
|
||||
|
||||
if metadata?.selections?
|
||||
metadata.selections.push(text)
|
||||
else
|
||||
metadata = { selections: [clipboardText, text] }
|
||||
|
||||
text = "" + (clipboardText) + "\n" + text
|
||||
else
|
||||
metadata = { indentBasis: @editor.indentationForBufferRow(@getBufferRange().start.row) }
|
||||
|
||||
|
||||
@@ -158,10 +158,10 @@ class ThemeManager
|
||||
# load path.
|
||||
#
|
||||
# Returns the absolute path to the required stylesheet.
|
||||
requireStylesheet: (stylesheetPath, ttype = 'bundled', htmlElement) ->
|
||||
requireStylesheet: (stylesheetPath, type = 'bundled', htmlElement) ->
|
||||
if fullPath = @resolveStylesheet(stylesheetPath)
|
||||
content = @loadStylesheet(fullPath)
|
||||
@applyStylesheet(fullPath, content, ttype = 'bundled', htmlElement)
|
||||
@applyStylesheet(fullPath, content, type = 'bundled', htmlElement)
|
||||
else
|
||||
throw new Error("Could not find a file at path '#{stylesheetPath}'")
|
||||
|
||||
@@ -192,16 +192,24 @@ class ThemeManager
|
||||
|
||||
removeStylesheet: (stylesheetPath) ->
|
||||
fullPath = @resolveStylesheet(stylesheetPath) ? stylesheetPath
|
||||
@stylesheetElementForId(@stringToId(fullPath)).remove()
|
||||
@emit 'stylesheets-changed'
|
||||
element = @stylesheetElementForId(@stringToId(fullPath))
|
||||
if element.length > 0
|
||||
stylesheet = element[0].sheet
|
||||
element.remove()
|
||||
@emit 'stylesheet-removed', stylesheet
|
||||
@emit 'stylesheets-changed'
|
||||
|
||||
applyStylesheet: (path, text, ttype = 'bundled', htmlElement=$('html')) ->
|
||||
applyStylesheet: (path, text, type = 'bundled', htmlElement=$('html')) ->
|
||||
styleElement = @stylesheetElementForId(@stringToId(path), htmlElement)
|
||||
if styleElement.length
|
||||
@emit 'stylesheet-removed', styleElement[0].sheet
|
||||
styleElement.text(text)
|
||||
else
|
||||
if htmlElement.find("head style.#{ttype}").length
|
||||
htmlElement.find("head style.#{ttype}:last").after "<style class='#{ttype}' id='#{@stringToId(path)}'>#{text}</style>"
|
||||
styleElement = $("<style class='#{type}' id='#{@stringToId(path)}'>#{text}</style>")
|
||||
if htmlElement.find("head style.#{type}").length
|
||||
htmlElement.find("head style.#{type}:last").after(styleElement)
|
||||
else
|
||||
htmlElement.find("head").append "<style class='#{ttype}' id='#{@stringToId(path)}'>#{text}</style>"
|
||||
htmlElement.find("head").append(styleElement)
|
||||
|
||||
@emit 'stylesheet-added', styleElement[0].sheet
|
||||
@emit 'stylesheets-changed'
|
||||
|
||||
@@ -24,9 +24,9 @@ Editor = require './editor'
|
||||
# with the model object when possible, but it won't always be possible with the
|
||||
# current API.
|
||||
#
|
||||
# ## Adding Perimiter Panels
|
||||
# ## Adding Perimeter Panels
|
||||
#
|
||||
# Use the following methods if possible to attach panels to the perimiter of the
|
||||
# Use the following methods if possible to attach panels to the perimeter of the
|
||||
# workspace rather than manipulating the DOM directly to better insulate you to
|
||||
# changes in the workspace markup:
|
||||
#
|
||||
@@ -64,7 +64,7 @@ class WorkspaceView extends View
|
||||
@version: 4
|
||||
|
||||
@configDefaults:
|
||||
ignoredNames: [".git", ".svn", ".DS_Store"]
|
||||
ignoredNames: [".git", ".hg", ".svn", ".DS_Store", "Thumbs.db"]
|
||||
excludeVcsIgnoredPaths: true
|
||||
disabledPackages: []
|
||||
themes: ['atom-dark-ui', 'atom-dark-syntax']
|
||||
@@ -113,6 +113,7 @@ class WorkspaceView extends View
|
||||
@command 'application:quit', -> ipc.send('command', 'application:quit')
|
||||
@command 'application:hide', -> ipc.send('command', 'application:hide')
|
||||
@command 'application:hide-other-applications', -> ipc.send('command', 'application:hide-other-applications')
|
||||
@command 'application:install-update', -> ipc.send('command', 'application:install-update')
|
||||
@command 'application:unhide-all-applications', -> ipc.send('command', 'application:unhide-all-applications')
|
||||
@command 'application:new-window', -> ipc.send('command', 'application:new-window')
|
||||
@command 'application:new-file', -> ipc.send('command', 'application:new-file')
|
||||
|
||||
@@ -32,6 +32,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
.vertical-scrollbar {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.scrollbar-corner {
|
||||
position: absolute;
|
||||
overflow: auto;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.scroll-view {
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -215,6 +226,10 @@
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.cursor.hidden-cursor {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.editor .hidden-input {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário