Comparar commits
881 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| cffe733641 | |||
| 3127171b2b | |||
| 1d48cb641c | |||
| b7b5852863 | |||
| d104e68342 | |||
| 9640678c29 | |||
| 2ce1677aa5 | |||
| d5c8956d38 | |||
| d532f506fe | |||
| 32b414328a | |||
| b1697399dc | |||
| 27eccfaf81 | |||
| ebbd8101ba | |||
| 20504fc7a8 | |||
| 0db1971825 | |||
| 80c828d001 | |||
| e688df57f2 | |||
| 0790d33e9d | |||
| 05820a3044 | |||
| c4ac602644 | |||
| 12d4fae91c | |||
| 2f334979d5 | |||
| d9e414af27 | |||
| 335c1e215a | |||
| b9b7646d4b | |||
| d885fb2d13 | |||
| f5ae96820a | |||
| 435fee1433 | |||
| c96f976162 | |||
| 5115540f8e | |||
| d642553351 | |||
| fa090345a8 | |||
| 55d291ffde | |||
| 48f63926ab | |||
| b0501c9cb2 | |||
| 355ab1eb2f | |||
| 28ac51d140 | |||
| d6210b24d9 | |||
| b0731afd4c | |||
| 1c81aa90c0 | |||
| bbf6930061 | |||
| 3d149eb9d1 | |||
| 5a8b96b180 | |||
| 5add777291 | |||
| f866e69704 | |||
| b27b4387fc | |||
| 1f850f0af1 | |||
| 9f1bbc54de | |||
| e7d34d4b83 | |||
| c5a15fb50e | |||
| 7a251f5432 | |||
| dc2a453986 | |||
| fdd55dfd27 | |||
| 5147fb6a8b | |||
| 9bbbb58084 | |||
| 9ad080cd31 | |||
| 509976fa18 | |||
| aad5700418 | |||
| 09a0773043 | |||
| 0829da53b0 | |||
| 2ea92cf0e5 | |||
| 9a2cc36c6b | |||
| 965a6243e1 | |||
| 503fa30c28 | |||
| b8f239cd39 | |||
| 231da60e13 | |||
| a47719eb53 | |||
| 9f851e55d1 | |||
| ab89776f01 | |||
| 2cea51b50e | |||
| 4e4794f3fd | |||
| ac6fbf100d | |||
| 8c8e866a97 | |||
| f859ad5fc5 | |||
| d30cf35a16 | |||
| c35fb90653 | |||
| 73df017d83 | |||
| 0e1ef201c1 | |||
| be4d23aa13 | |||
| c58606907a | |||
| c489a4662b | |||
| 44fceaae20 | |||
| 1b393e4f48 | |||
| e84bd28c64 | |||
| bbf199fb60 | |||
| 367a4c4bd3 | |||
| 7d74f8179b | |||
| bcafef385f | |||
| 83d5890962 | |||
| 7ee3ccb43d | |||
| 9126f2e45c | |||
| 89ed95e2ae | |||
| 27174b2880 | |||
| ed1fbcc8e7 | |||
| 307ce4dc54 | |||
| 0833be4c27 | |||
| af116b2b8a | |||
| 59d582722b | |||
| 9239b95241 | |||
| ab8b5959d3 | |||
| 5ff7a286fc | |||
| f199c71fa8 | |||
| 265601cbdb | |||
| 67b39845c8 | |||
| a42505b6ae | |||
| f026d30426 | |||
| b4db61a7e7 | |||
| fad93b8d7e | |||
| feb72b38f8 | |||
| 23ce2cd1ac | |||
| ee2509e90f | |||
| ca5e66bbd1 | |||
| 3389555d71 | |||
| 202426a85b | |||
| a6d68f8683 | |||
| 6674bfbf97 | |||
| cd5309e494 | |||
| 11b2f4a18d | |||
| 88442ccb78 | |||
| c4768cb266 | |||
| cf772295fb | |||
| dabedeb065 | |||
| 224e6cb5d4 | |||
| 3f745e3d67 | |||
| d9a5e3c7e1 | |||
| d272606408 | |||
| 263567649d | |||
| c345532864 | |||
| c0c4e65b5d | |||
| b441b3cd6f | |||
| 3a51228899 | |||
| 42d5d0ba87 | |||
| a1d0635d98 | |||
| b66e931a99 | |||
| 0a7ea419a0 | |||
| 91770f2885 | |||
| d4c7fe4b47 | |||
| 8b848c1853 | |||
| eef6532b8c | |||
| 43de383b14 | |||
| 9d3aaad394 | |||
| 3cf104444c | |||
| f91741eec1 | |||
| 8f77d65aab | |||
| 3dced04aab | |||
| bac9eac1fc | |||
| d3e53c5ada | |||
| cad8afe78b | |||
| a7f30c63cb | |||
| 1d0dd86041 | |||
| 690ece3a9e | |||
| 100a1f5764 | |||
| 35f49be82a | |||
| 4225c25ad7 | |||
| 330592e2bd | |||
| d306876229 | |||
| 47aa269de5 | |||
| 2a80762d5b | |||
| 42ab14c2cb | |||
| e83784e141 | |||
| cedb41f4b0 | |||
| d873f3d255 | |||
| 2781c24fce | |||
| 2a45bd7f69 | |||
| f4fab84869 | |||
| 204e5a6b46 | |||
| 9459bd15a2 | |||
| 6cd96c8284 | |||
| 2ceced2b84 | |||
| be78572d78 | |||
| 61abda5166 | |||
| 93f98ec14e | |||
| d581c41c0e | |||
| 252bef63bf | |||
| 9c63a4f517 | |||
| e7b0c3e519 | |||
| 697ccedbd3 | |||
| 87efc7e1df | |||
| 6a0a694a7b | |||
| be1f28b3d8 | |||
| 32f7c72d28 | |||
| d51a86e804 | |||
| 93e3a5af2a | |||
| 278a507653 | |||
| 7422f4378e | |||
| f2ab14656b | |||
| 453abf8b90 | |||
| 7866f0819d | |||
| 921e3c581d | |||
| 58aa87438d | |||
| ad73902382 | |||
| bf63a9715c | |||
| 06c52c6873 | |||
| 9ac27bc2f8 | |||
| 98caaf0d70 | |||
| a102d1e134 | |||
| 6caa86fb04 | |||
| b1e0c8132d | |||
| f3947dd6e0 | |||
| 27dbbabe09 | |||
| 5950110860 | |||
| ab5d71e6b5 | |||
| 1ee2839245 | |||
| a6f31ed791 | |||
| e04b5a74d7 | |||
| 4acf143f45 | |||
| 5ad5ce0841 | |||
| 31d1ca12c1 | |||
| ace3325db8 | |||
| b718114fc4 | |||
| 1df8c77f41 | |||
| 26e867d65e | |||
| 2688761c29 | |||
| b64d9db198 | |||
| bc5b786bb2 | |||
| 13025c17f1 | |||
| 8b4b5230ab | |||
| 7d6d634ceb | |||
| b386b00bc0 | |||
| 2028045254 | |||
| ca60dae630 | |||
| a5605bd408 | |||
| caf6fdd5ac | |||
| 19872959bc | |||
| 299ea18c58 | |||
| 966360e022 | |||
| 70a2be849a | |||
| 1c7843d9b2 | |||
| 5291f1c62c | |||
| c9e7cfc02c | |||
| e93ca3c901 | |||
| 48bd330a5e | |||
| 6240bc1fc9 | |||
| 6ccc60342f | |||
| 03750d0b6c | |||
| 03e31ad918 | |||
| 610c07870a | |||
| 5c37d208f5 | |||
| 88c119f4ad | |||
| d03cfda6c4 | |||
| 8f02b21d08 | |||
| 953f2c61f7 | |||
| 15e95d0d21 | |||
| 391a71fed0 | |||
| 67ed490618 | |||
| c812dfef9b | |||
| 631bca6c89 | |||
| 095c1b74a7 | |||
| 7e408ad268 | |||
| 4945fd7aae | |||
| 0db5549b64 | |||
| 96095f9c30 | |||
| e2b4fcad65 | |||
| 3ea1c80fe7 | |||
| 525b4ac3eb | |||
| 6ffc750e18 | |||
| 66716db4d1 | |||
| 95d03fc5fa | |||
| b816fca75e | |||
| 6f148f681d | |||
| a489358f55 | |||
| 1cd0caeb2d | |||
| 310939338c | |||
| e39d50972d | |||
| 9a5f3ab000 | |||
| 9285f2605f | |||
| b654209adb | |||
| 0c07166a8e | |||
| de36ceb00c | |||
| aa292874ec | |||
| 736b6f37e4 | |||
| 8d9098464c | |||
| eb6ce74a12 | |||
| 33ee1cb0de | |||
| 11a07f41ac | |||
| 5cf97db07c | |||
| f095d38978 | |||
| 218f6ab629 | |||
| 26edd40f14 | |||
| 8241351143 | |||
| 286361bf2b | |||
| 3d5437c1e9 | |||
| 95b9140dcf | |||
| fc82e5ffd6 | |||
| 20521ad487 | |||
| 99f91fac48 | |||
| d4b0b33d86 | |||
| 790c125e0b | |||
| 4afe133f85 | |||
| 763e83584d | |||
| 62a671aae6 | |||
| c0eb5d0ebe | |||
| d1e9ad3ed1 | |||
| 396b53b8dc | |||
| d87d98278e | |||
| 682a4be285 | |||
| 14c68a4280 | |||
| ddfbc6c335 | |||
| 779642b3da | |||
| 705c78bf18 | |||
| 07a21a15a1 | |||
| 287895c78c | |||
| fcf7b6747b | |||
| 1af25ea401 | |||
| aecd689593 | |||
| 8ad8a61aab | |||
| 6a83246838 | |||
| a7fc1c4138 | |||
| c19aee5472 | |||
| e9d49b1df3 | |||
| 5a456c8552 | |||
| 1179ced85c | |||
| 7738472eb8 | |||
| 45274eaad3 | |||
| 24f7638e8b | |||
| 6ec7b7b38d | |||
| 094a7e9a5f | |||
| 97181121c9 | |||
| 3e4c7a8ab7 | |||
| f4b08649a0 | |||
| c1a93395f5 | |||
| 53b538311e | |||
| 19ae78e062 | |||
| 5a93f14199 | |||
| d7dd0f3224 | |||
| 37e6f03346 | |||
| 0aa3cd58c1 | |||
| ac23717f8c | |||
| 491561db4a | |||
| edfd67b093 | |||
| dd63d47c11 | |||
| 067f5ea7e8 | |||
| eb223c4f21 | |||
| f632b6fe79 | |||
| 5bdc8af850 | |||
| b03931371a | |||
| c02755f59a | |||
| e178b25f17 | |||
| 96efb232ee | |||
| 714cbc9f4b | |||
| 64e4053a19 | |||
| a7f1f90c1d | |||
| cacaba936b | |||
| b20589fbb6 | |||
| d3f14d8939 | |||
| 094ba81758 | |||
| 8a40be8345 | |||
| 2d8d330df7 | |||
| fbc9c05096 | |||
| 1eab423a1c | |||
| cfca6ecc86 | |||
| fb96b01f30 | |||
| 625b95a6d9 | |||
| 0fe9dc6aa9 | |||
| 38e6aee46d | |||
| 01f87d9678 | |||
| 93bf9357b0 | |||
| ed42a275ab | |||
| 6998337144 | |||
| 8b92aef3ff | |||
| 66d6af54bf | |||
| 2a06ece3df | |||
| 1c0c8db042 | |||
| 9293ef766b | |||
| a7a9b3707f | |||
| 7e16e42b3f | |||
| 179fb2d274 | |||
| f804006d6c | |||
| 9a9347e3a5 | |||
| e4bcb96dcc | |||
| 8a0992d689 | |||
| db17a6cba4 | |||
| 5449fc2e15 | |||
| 0a84ad5307 | |||
| 485c402661 | |||
| 4591f00a65 | |||
| b635fa0c97 | |||
| 004103d579 | |||
| 2c952fad95 | |||
| adc983e8da | |||
| 7dc9d0c8ce | |||
| 3d3521962c | |||
| 46a1f69ab1 | |||
| 298d3e5fb6 | |||
| 27291980cb | |||
| 64ae4bf6c3 | |||
| 90a71d1171 | |||
| a5b7d15bcc | |||
| be2d49a410 | |||
| 8a9805cc6d | |||
| 196694e352 | |||
| 12683571e3 | |||
| c0991447ff | |||
| f9fcb9f2e2 | |||
| 1daab1b956 | |||
| fc7f922de0 | |||
| 5f1f2cd9be | |||
| dca0576496 | |||
| aa7d8fb382 | |||
| 08f20adc35 | |||
| c5f1165f61 | |||
| 58499aeec7 | |||
| 83c73fc94a | |||
| b28a1aa5c7 | |||
| bcb72394f9 | |||
| efe7baf140 | |||
| 4b07103fcf | |||
| 9d60fd2322 | |||
| 71228a5f45 | |||
| 6b3ba8e332 | |||
| 5da4846fff | |||
| de619a731b | |||
| d2283b0567 | |||
| 2a00acfdaf | |||
| b2025ebad0 | |||
| 0b44cee8db | |||
| 5fed6199ec | |||
| ddc04f2278 | |||
| f64a813fc6 | |||
| 68bc3f6ead | |||
| ffbcddf063 | |||
| b341749d54 | |||
| d2ab75382a | |||
| b125565776 | |||
| 9cec02420c | |||
| 6f82281b8f | |||
| ffda2386c3 | |||
| aefc647155 | |||
| 83455a7f3a | |||
| d8f64c15b8 | |||
| c927e95c2c | |||
| 5b12646a44 | |||
| 68bb43ee7d | |||
| 4048fb978c | |||
| 2d885496a3 | |||
| 64222d3096 | |||
| 2c7bbf8e9f | |||
| a45e9a1e8b | |||
| 3fd5ba9b3c | |||
| eb0e3df720 | |||
| 60a49d9c81 | |||
| 43ccf0a041 | |||
| 1f6764e708 | |||
| 48f714d5fb | |||
| e2813b4dd9 | |||
| 41b3d65e05 | |||
| 1e50985ec7 | |||
| 1d6087fcd3 | |||
| f2e74f216c | |||
| b9950ef2df | |||
| 67f4d51774 | |||
| 1bf4db15b2 | |||
| 28eb03ed29 | |||
| 2843af458b | |||
| 163a7587f9 | |||
| 18f83e90f7 | |||
| 7094701c66 | |||
| d7d23f7fc9 | |||
| bdbc850695 | |||
| 4e0ab92827 | |||
| b662281958 | |||
| 4d2cc86ada | |||
| 19fcc1c441 | |||
| 1f5fa27113 | |||
| 362bd2e61a | |||
| 4cb80d3c7e | |||
| 7f108dab38 | |||
| cec5a83eff | |||
| a7c3c15885 | |||
| 1c16738969 | |||
| b4a456d911 | |||
| c92f805e6e | |||
| 859a4db242 | |||
| 3a94b70270 | |||
| 85d6689344 | |||
| e0726b0354 | |||
| 0abd25ad6f | |||
| 42522686d7 | |||
| 1e9a8b92f2 | |||
| dda2b2e893 | |||
| e04c05ffee | |||
| 8cb0197638 | |||
| 73763d3e41 | |||
| 9d1c3124ee | |||
| aaee54bd08 | |||
| 1ae8862a9c | |||
| f3dd757537 | |||
| 68693e3ca0 | |||
| e24a562387 | |||
| 9c6a5fb4fa | |||
| 25caaa92f1 | |||
| 78ee02f0c6 | |||
| e462fdc4ce | |||
| 96d8721c9e | |||
| 568151b1a5 | |||
| 3d6c9ee554 | |||
| d5d6422d28 | |||
| 8cf24bc7de | |||
| 5727865b94 | |||
| b95b86396e | |||
| d75c35285c | |||
| a7bc7c198d | |||
| d2f24615c1 | |||
| e4b942e991 | |||
| c9f8ffc749 | |||
| c2086eee0e | |||
| d5a66c590a | |||
| b374c1a11a | |||
| 509d16b65a | |||
| e8e13ca645 | |||
| 35f8e6a5a7 | |||
| 36a9ad7d90 | |||
| 6ff304094f | |||
| 0e51def6be | |||
| f366a67fee | |||
| f30f0de45e | |||
| 9e36cd705e | |||
| 2a5081f0e0 | |||
| 2c93b1459e | |||
| bf83fb7b10 | |||
| f4cc8c31b3 | |||
| e62ecbab6b | |||
| 4cef3bfef5 | |||
| 85fae83195 | |||
| f79b78054c | |||
| e803c06b28 | |||
| 1963a7f437 | |||
| 48eb5307e6 | |||
| 95d6ab1d4f | |||
| 9224c86452 | |||
| 0fa2b4426a | |||
| 1e4e59ad1c | |||
| 97a56574e0 | |||
| c06fefce14 | |||
| 00027e892c | |||
| d4dee07b41 | |||
| f475552673 | |||
| 6e33f10050 | |||
| 61651db0b0 | |||
| 982346b142 | |||
| 92ba107c89 | |||
| 7b4a9aa2e4 | |||
| 446398ad01 | |||
| 8afbab311f | |||
| 32f2a95f07 | |||
| d53d01d95b | |||
| 131522f93d | |||
| 1601a1fbfa | |||
| 2c89a5c82a | |||
| e4ec932513 | |||
| a834920fb7 | |||
| b5edefcae8 | |||
| 616a94a10e | |||
| 7034fe3b36 | |||
| 5f68af27f5 | |||
| ea207f0938 | |||
| 732f053d4a | |||
| 78e61c3ff9 | |||
| 22c9a222c9 | |||
| cc4ab0d36b | |||
| 7bdf3b1719 | |||
| 175d7811b4 | |||
| 3f3fca872b | |||
| 421c64347e | |||
| 557d277e9f | |||
| 3fc514659a | |||
| 747398f2a5 | |||
| 1f51317a10 | |||
| f592a5d11f | |||
| fb223db958 | |||
| 1d73c57f9e | |||
| 016f32d62e | |||
| 9ee4d334b2 | |||
| ddb16dcc6f | |||
| 8403e6583f | |||
| 6bdbabecbd | |||
| 2cda86efda | |||
| 46ff794c8b | |||
| 1406fbfe03 | |||
| dde13a5d4e | |||
| bfc7995aee | |||
| 7fd9c75d24 | |||
| 677be2df82 | |||
| b3bf47dd69 | |||
| a25920da72 | |||
| 9b28e7a47c | |||
| db811cfa9e | |||
| 6d0be70dbc | |||
| 74966bd547 | |||
| 488abc8c24 | |||
| 362d7712ad | |||
| 6ed3626133 | |||
| fc87c98261 | |||
| 46a7ea5936 | |||
| f412d88edd | |||
| 49471070a3 | |||
| 0ca9d7b97e | |||
| d42878164a | |||
| 9adad17e27 | |||
| be420b042c | |||
| 270642b2ea | |||
| 9a080bfd1b | |||
| 7c43ea7a0f | |||
| 28c5bd7814 | |||
| 8c3bae4275 | |||
| 71e3ab9d2b | |||
| a1634b2f9b | |||
| fb6351d9d7 | |||
| 90041b7115 | |||
| d6ba6067b8 | |||
| aface45084 | |||
| 16fc52b351 | |||
| 56184be6fe | |||
| 8f623db092 | |||
| 081c2efc98 | |||
| 3296674605 | |||
| 1e18e2b4e5 | |||
| 13b28c26f0 | |||
| 760f6d280a | |||
| f39ca3ea48 | |||
| d379582248 | |||
| 84f160f88e | |||
| c3d1dd82f0 | |||
| 32ff599a61 | |||
| cbdf93b075 | |||
| c721300be4 | |||
| 6630147b69 | |||
| 08076a4af1 | |||
| b9897d8b34 | |||
| 68fbff59d8 | |||
| 0b2bd468b5 | |||
| a36eae8e4d | |||
| ed23058af0 | |||
| c3d8f4843a | |||
| 085933c55e | |||
| 01987cb762 | |||
| 75a6c51ac7 | |||
| 1575ee9037 | |||
| 64612d4734 | |||
| 3aac342c21 | |||
| 69d3b3cfa2 | |||
| 84232d76de | |||
| dc69b07045 | |||
| 971539c438 | |||
| c36be85dd6 | |||
| 4bbc498d1d | |||
| 3ac992d5d5 | |||
| ddbedcee3e | |||
| ba8cc9e1c0 | |||
| ec4a2a468e | |||
| f09423e020 | |||
| 7e34e8c4ed | |||
| cc785de974 | |||
| a8c4d2e4ca | |||
| d918eb6fa7 | |||
| 69efdc2292 | |||
| fc891f8706 | |||
| 9fc96ba7d4 | |||
| b8a263c570 | |||
| c9a9b51238 | |||
| 13d16b4723 | |||
| ddacfd7d5f | |||
| 932207b106 | |||
| 2c39f3515b | |||
| 8e53b2d507 | |||
| 9bd7141359 | |||
| e534997bf9 | |||
| db9de34993 | |||
| 6f95f51da2 | |||
| a67743b5cd | |||
| 2a56e70110 | |||
| eaedb14942 | |||
| c7cd084e24 | |||
| 685a2c088b | |||
| be7111f007 | |||
| 59c28c0f76 | |||
| 27331cb379 | |||
| 52b5fff537 | |||
| 6fbd9fb8f8 | |||
| 5996fcbc83 | |||
| e34eb151ca | |||
| 4ee1987af4 | |||
| 91652e1174 | |||
| cbf22201e6 | |||
| 040b99b2ff | |||
| c4eecbb380 | |||
| d235180547 | |||
| a42b560c24 | |||
| 2894d87ff8 | |||
| b15e101b20 | |||
| 6cf52a7fb7 | |||
| 8cf20a6996 | |||
| 24432018ec | |||
| 5ec38f84c5 | |||
| 40ffe2a306 | |||
| b1eceb03dc | |||
| dde69f8da4 | |||
| a525d5267b | |||
| f7951aa57c | |||
| a63e058fa5 | |||
| 09327eae75 | |||
| edd48d71ae | |||
| 2faf8bc57b | |||
| aac3d7a559 | |||
| d914ae2a62 | |||
| 2710d40403 | |||
| d327d4923f | |||
| dd0bed9bff | |||
| ff78a5b075 | |||
| 856370f522 | |||
| 041d3f5c4c | |||
| 3969c71932 | |||
| 133bf0cedb | |||
| f168aafc33 | |||
| d237b3448c | |||
| bbaf908bb2 | |||
| 9d947d994e | |||
| e2ecff5e23 | |||
| decae9e34c | |||
| 4896741f0c | |||
| c360ccc62b | |||
| 913c002ee4 | |||
| 59c405d846 | |||
| a9826653e1 | |||
| b47d52d919 | |||
| 7422f0ab1b | |||
| 18c6c84d35 | |||
| 7bcf92e55a | |||
| ee7d4003de | |||
| 79e50084a9 | |||
| 73a70d430f | |||
| 503b4ce2a4 | |||
| 094ccbc1f2 | |||
| 434ab5174b | |||
| 1b85810735 | |||
| 0c75a4fd9c | |||
| d3f2798472 | |||
| c88c18c042 | |||
| cb7d4c8638 | |||
| 4a9d0ab4d3 | |||
| ac029d300a | |||
| 8fe0b7fb7b | |||
| c6c58ebc3e | |||
| 32ac99fd3e | |||
| 175a8b6968 | |||
| 6708388c29 | |||
| 958b19bd83 | |||
| e40dc5c4a6 | |||
| 12ff54c0bd | |||
| 83040d13c7 | |||
| ebc9a6bf51 | |||
| c8ad232c31 | |||
| cfd918977b | |||
| e7efaeaf17 | |||
| e849fc45ff | |||
| 9054c7a120 | |||
| 60c042bd81 | |||
| 495ba3571e | |||
| b8776425fd | |||
| 693fd43449 | |||
| 71f80809c0 | |||
| db13a40f0a | |||
| edf7e06b8d | |||
| 442abece14 | |||
| 5c143bfc6e | |||
| 51354f2326 | |||
| 1177508a45 | |||
| 4bbffd3589 | |||
| 2266c794b4 | |||
| 562ee58506 | |||
| fa96adc2ce | |||
| c46088e89a | |||
| 131ae0f9f7 | |||
| 49828b9681 | |||
| 141430ab0a | |||
| 807b4b223b | |||
| 89246f213a | |||
| a6fa2ff30a | |||
| 7f32c9a3f7 | |||
| 18b2433a99 | |||
| 51b9964f7e | |||
| 9084122a5c | |||
| 9ff07e0fc2 | |||
| 7ba47840d8 | |||
| 327e8476dd | |||
| 18eaec374c | |||
| 430a36ac42 | |||
| 508ca12be9 | |||
| adf7e17fce | |||
| 9c675f387a | |||
| 5770366c00 | |||
| f2581e8d96 | |||
| d7d678c082 | |||
| 44181457c5 | |||
| f9b27aecf5 | |||
| ddbb0ae1db | |||
| fec2567283 | |||
| ad8a020c29 | |||
| 06c04779bf | |||
| 1a047a8e14 | |||
| 0cf8666286 | |||
| 7c02b7e431 | |||
| 6c55cff603 | |||
| c64895a621 | |||
| 9dc3f2c909 | |||
| 1dc2ee743e | |||
| 1f7967d17f | |||
| 916729fbd5 | |||
| 1922536927 | |||
| de89f90700 | |||
| 09f1dff502 | |||
| 9a0414da6f | |||
| 119fc7f4f2 | |||
| 481e0b8b6c | |||
| 1b69f2db46 | |||
| 1b877c76b9 | |||
| 1fa791fc7a | |||
| e8a4867ff7 | |||
| 629717caea | |||
| 0d6253555b | |||
| 63d9edcc40 | |||
| bc2f217e7c | |||
| 7381bd09b1 | |||
| 379bd852d2 | |||
| a9ee6e5d43 | |||
| 2bef377e99 | |||
| 7f326421d7 | |||
| 3546f21af7 | |||
| 441dcfb56a | |||
| 42d9ef397d | |||
| 10eb89f078 | |||
| 8b2482af22 | |||
| a2ca59bf05 | |||
| 91f11868ea | |||
| 2c19e6a6a4 | |||
| e7ebe0a5c4 | |||
| 95ec0d8162 | |||
| 0a4f5a365a | |||
| b6b6b6d12b | |||
| 9f194ff4df | |||
| ed6ca9cd06 | |||
| 08971562cd | |||
| 263ff21cc1 | |||
| 99b08826dd | |||
| 417e00b938 | |||
| f8bb40c48f | |||
| 01b75c4393 | |||
| 9f1ffeee25 | |||
| c55faac0a9 | |||
| aaa50bae90 | |||
| b0c4910815 | |||
| 654f84a26c | |||
| ff10ea601c | |||
| 88bfba9fb2 | |||
| f11168df8e | |||
| 4ce056180c | |||
| 8718828869 | |||
| edfcc134ec | |||
| 6a34b88f79 | |||
| e596bf6ef9 | |||
| b369a1085c | |||
| 2e7e90a8aa | |||
| eae80ca46d | |||
| fe7505745d | |||
| 12b9f232c2 | |||
| 97a671cb49 | |||
| 9acea88101 | |||
| b29c0ca2f7 | |||
| a4a3577163 | |||
| 9dfaa8a4e5 | |||
| 661b09ab1c | |||
| 9399e00033 | |||
| 67d5d997c9 | |||
| 40c11410f0 | |||
| 307108ec6c | |||
| 0bb173b646 | |||
| 6538da22a6 | |||
| c79db992d9 | |||
| 89ab0becc2 | |||
| fc90a3c2ba | |||
| 382a06028c |
+1
-1
@@ -1 +1 @@
|
||||
v0.10.21
|
||||
v0.10.33
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
2.7.6
|
||||
+18
-9
@@ -2,7 +2,7 @@
|
||||
|
||||
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.
|
||||
|
||||
Visit [atom.io](https://atom.io) to learn more.
|
||||
Visit [atom.io](https://atom.io) to learn more or visit the [Atom forum](https://discuss.atom.io).
|
||||
|
||||
Visit [issue #3684](https://github.com/atom/atom/issues/3684) to learn more
|
||||
about the Atom 1.0 roadmap.
|
||||
@@ -17,16 +17,25 @@ Atom will automatically update when a new release is available.
|
||||
|
||||
### Windows
|
||||
|
||||
Install the [Atom chocolatey package](https://chocolatey.org/packages/Atom).
|
||||
Download the latest [AtomSetup.exe installer](https://github.com/atom/atom/releases/latest).
|
||||
|
||||
1. Install [chocolatey](https://chocolatey.org).
|
||||
2. Close and reopen your command prompt or PowerShell window.
|
||||
3. Run `cinst Atom`
|
||||
4. In the future run `cup Atom` to upgrade to the latest release.
|
||||
Atom will automatically update when a new release is available.
|
||||
|
||||
You can also download a `.zip` file from the [releases page](https://github.com/atom/atom/releases/latest).
|
||||
The Windows version does not currently automatically update so you will need to
|
||||
manually upgrade to future releases by re-downloading the `.zip` file.
|
||||
You can also download an `atom-windows.zip` file from the [releases page](https://github.com/atom/atom/releases/latest).
|
||||
The `.zip` version will not automatically update.
|
||||
|
||||
#### Uninstalling Chocolatey Version
|
||||
|
||||
The recommended installation of Atom on Windows used to be using [Chocolatey](https://chocolatey.org/packages/Atom/).
|
||||
This is no longer recommended now that the Atom Windows installer & auto-updater
|
||||
exists.
|
||||
|
||||
To switch from Chocolatey to the new installer:
|
||||
* Upgrade to Atom 0.155 or above by running `cup Atom`
|
||||
* Run `cuninst Atom` to uninstall the Chocolatey version of Atom
|
||||
* This will not delete any of your installed packages or Atom config files.
|
||||
* Download the latest [AtomSetup.exe installer](https://github.com/atom/atom/releases/latest).
|
||||
* Double-click the downloaded file to install Atom
|
||||
|
||||
### Debian Linux (Ubuntu)
|
||||
|
||||
|
||||
+1
-1
@@ -6,6 +6,6 @@
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "0.111.0"
|
||||
"atom-package-manager": "0.116.0"
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -45,12 +45,12 @@ if [ $REDIRECT_STDERR ]; then
|
||||
fi
|
||||
|
||||
if [ $OS == 'Mac' ]; then
|
||||
ATOM_PATH=${ATOM_PATH:-/Applications} # Set ATOM_PATH unless it is already set
|
||||
ATOM_PATH="${ATOM_PATH:-/Applications}" # Set ATOM_PATH unless it is already set
|
||||
ATOM_APP_NAME=Atom.app
|
||||
|
||||
# If ATOM_PATH isn't a executable file, use spotlight to search for Atom
|
||||
if [ ! -x "$ATOM_PATH/$ATOM_APP_NAME" ]; then
|
||||
ATOM_PATH=$(mdfind "kMDItemCFBundleIdentifier == 'com.github.atom'" | grep -v ShipIt | head -1 | xargs dirname)
|
||||
ATOM_PATH="$(mdfind "kMDItemCFBundleIdentifier == 'com.github.atom'" | grep -v ShipIt | head -1 | xargs -0 dirname)"
|
||||
fi
|
||||
|
||||
# Exit if Atom can't be found
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
require '../spec/spec-helper'
|
||||
|
||||
path = require 'path'
|
||||
{$, Point} = require 'atom'
|
||||
{$} = require '../src/space-pen-extensions'
|
||||
{Point} = require 'atom'
|
||||
_ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
Project = require '../src/project'
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
require './benchmark-helper'
|
||||
{$, _, WorkspaceView} = require 'atom'
|
||||
{$} = require '../src/space-pen-extensions'
|
||||
_ = require 'underscore-plus'
|
||||
{WorkspaceView} = require 'atom'
|
||||
TokenizedBuffer = require '../src/tokenized-buffer'
|
||||
|
||||
describe "editorView.", ->
|
||||
|
||||
@@ -6,7 +6,6 @@ os = require 'os'
|
||||
# modules work under node v0.11.x.
|
||||
require 'vm-compatibility-layer'
|
||||
|
||||
fm = require 'json-front-matter'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
packageJson = require '../package.json'
|
||||
@@ -22,9 +21,9 @@ module.exports = (grunt) ->
|
||||
grunt.loadNpmTasks('grunt-contrib-csslint')
|
||||
grunt.loadNpmTasks('grunt-contrib-coffee')
|
||||
grunt.loadNpmTasks('grunt-contrib-less')
|
||||
grunt.loadNpmTasks('grunt-markdown')
|
||||
grunt.loadNpmTasks('grunt-shell')
|
||||
grunt.loadNpmTasks('grunt-download-atom-shell')
|
||||
grunt.loadNpmTasks('grunt-atom-shell-installer')
|
||||
grunt.loadNpmTasks('grunt-peg')
|
||||
grunt.loadTasks('tasks')
|
||||
|
||||
@@ -194,32 +193,19 @@ module.exports = (grunt) ->
|
||||
'static/**/*.less'
|
||||
]
|
||||
|
||||
markdown:
|
||||
guides:
|
||||
files: [
|
||||
expand: true
|
||||
cwd: 'docs'
|
||||
src: '**/*.md'
|
||||
dest: 'docs/output/'
|
||||
ext: '.html'
|
||||
]
|
||||
options:
|
||||
template: 'docs/template.jst'
|
||||
templateContext:
|
||||
tag: "v#{major}.#{minor}"
|
||||
markdownOptions:
|
||||
gfm: true
|
||||
preCompile: (src, context) ->
|
||||
parsed = fm.parse(src)
|
||||
_.extend(context, parsed.attributes)
|
||||
parsed.body
|
||||
|
||||
'download-atom-shell':
|
||||
version: packageJson.atomShellVersion
|
||||
outputDir: 'atom-shell'
|
||||
downloadDir: atomShellDownloadDir
|
||||
rebuild: true # rebuild native modules after atom-shell is updated
|
||||
|
||||
'create-windows-installer':
|
||||
appDirectory: shellAppDir
|
||||
outputDirectory: path.join(buildDir, 'installer')
|
||||
authors: 'GitHub Inc.'
|
||||
loadingGif: path.resolve(__dirname, '..', 'resources', 'win', 'loading.gif')
|
||||
iconUrl: 'https://raw.githubusercontent.com/atom/atom/master/resources/win/atom.ico'
|
||||
|
||||
shell:
|
||||
'kill-atom':
|
||||
command: killCommand
|
||||
@@ -237,6 +223,7 @@ module.exports = (grunt) ->
|
||||
ciTasks.push('dump-symbols') if process.platform isnt 'win32'
|
||||
ciTasks.push('set-version', 'check-licenses', 'lint')
|
||||
ciTasks.push('mkdeb') if process.platform is 'linux'
|
||||
ciTasks.push('create-windows-installer') if process.platform is 'win32'
|
||||
ciTasks.push('test') if process.platform is 'darwin'
|
||||
ciTasks.push('codesign')
|
||||
ciTasks.push('publish-build')
|
||||
|
||||
@@ -7,11 +7,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "~0.2.9",
|
||||
"donna": "1.0.6",
|
||||
"donna": "1.0.7",
|
||||
"formidable": "~1.0.14",
|
||||
"fs-plus": "2.x",
|
||||
"github-releases": "~0.2.0",
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-atom-shell-installer": "^0.13.0",
|
||||
"grunt-cli": "~0.1.9",
|
||||
"grunt-coffeelint": "git+https://github.com/atom/grunt-coffeelint.git#cfb99aa99811d52687969532bd5a98011ed95bfe",
|
||||
"grunt-contrib-coffee": "~0.9.0",
|
||||
@@ -20,21 +21,17 @@
|
||||
"grunt-cson": "0.10.0",
|
||||
"grunt-download-atom-shell": "~0.10.0",
|
||||
"grunt-lesslint": "0.13.0",
|
||||
"grunt-markdown": "~0.4.0",
|
||||
"grunt-peg": "~1.1.0",
|
||||
"grunt-shell": "~0.3.1",
|
||||
"harmony-collections": "~0.3.8",
|
||||
"json-front-matter": "~0.1.3",
|
||||
"legal-eagle": "~0.4.0",
|
||||
"legal-eagle": "~0.6.0",
|
||||
"minidump": "~0.8",
|
||||
"normalize-package-data": "0.2.12",
|
||||
"npm": "~1.4.5",
|
||||
"rcedit": "~0.1.2",
|
||||
"read-package-json": "1.1.8",
|
||||
"rcedit": "~0.3.0",
|
||||
"request": "~2.27.0",
|
||||
"rimraf": "~2.2.2",
|
||||
"runas": "~1.0.1",
|
||||
"tello": "1.0.3",
|
||||
"tello": "1.0.4",
|
||||
"temp": "~0.8.1",
|
||||
"underscore-plus": "1.x",
|
||||
"unzip": "~0.1.9",
|
||||
|
||||
@@ -11,6 +11,7 @@ module.exports = (grunt) ->
|
||||
appDir = grunt.config.get('atom.appDir')
|
||||
|
||||
rm shellAppDir
|
||||
rm path.join(buildDir, 'installer')
|
||||
mkdir path.dirname(buildDir)
|
||||
|
||||
if process.platform is 'darwin'
|
||||
@@ -20,7 +21,9 @@ module.exports = (grunt) ->
|
||||
|
||||
mkdir appDir
|
||||
|
||||
cp 'atom.sh', path.join(appDir, 'atom.sh')
|
||||
if process.platform isnt 'win32'
|
||||
cp 'atom.sh', path.join(appDir, 'atom.sh')
|
||||
|
||||
cp 'package.json', path.join(appDir, 'package.json')
|
||||
|
||||
packageDirectories = []
|
||||
@@ -148,10 +151,10 @@ module.exports = (grunt) ->
|
||||
grunt.file.copy(sourcePath, path.resolve(appDir, '..', subDirectory, filename))
|
||||
|
||||
if process.platform is 'win32'
|
||||
# Set up chocolatey ignore and gui files
|
||||
fs.writeFileSync path.join(appDir, 'apm', 'node_modules', 'atom-package-manager', 'bin', 'node.exe.ignore'), ''
|
||||
fs.writeFileSync path.join(appDir, 'node_modules', 'symbols-view', 'vendor', 'ctags-win32.exe.ignore'), ''
|
||||
fs.writeFileSync path.join(shellAppDir, 'atom.exe.gui'), ''
|
||||
cp path.join('resources', 'win', 'atom.cmd'), path.join(shellAppDir, 'resources', 'cli', 'atom.cmd')
|
||||
cp path.join('resources', 'win', 'atom.sh'), path.join(shellAppDir, 'resources', 'cli', 'atom.sh')
|
||||
cp path.join('resources', 'win', 'atom.js'), path.join(shellAppDir, 'resources', 'cli', 'atom.js')
|
||||
cp path.join('resources', 'win', 'apm.sh'), path.join(shellAppDir, 'resources', 'cli', 'apm.sh')
|
||||
|
||||
dependencies = ['compile', 'generate-license:save', 'generate-module-cache', 'compile-packages-slug']
|
||||
dependencies.push('copy-info-plist') if process.platform is 'darwin'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
module.exports = (grunt) ->
|
||||
grunt.registerTask 'check-licenses', 'Report the licenses of all dependencies', ->
|
||||
legalEagle = require 'legal-eagle'
|
||||
@@ -13,7 +12,7 @@ module.exports = (grunt) ->
|
||||
legalEagle options, (err, summary) ->
|
||||
if err?
|
||||
console.error(err)
|
||||
exit 1
|
||||
process.exit 1
|
||||
|
||||
for key of summary
|
||||
delete summary[key] if key.match /^atom@/
|
||||
|
||||
@@ -36,7 +36,7 @@ module.exports = (grunt) ->
|
||||
spawn {cmd, args}, (error) ->
|
||||
return callback(error) if error?
|
||||
|
||||
setupExePath = path.join(grunt.config.get('atom.shellAppDir'), '..', 'Releases', 'setup.exe')
|
||||
setupExePath = path.resolve(grunt.config.get('atom.buildDir'), 'installer', 'AtomSetup.exe')
|
||||
if fs.isFileSync(setupExePath)
|
||||
args = [setupExePath]
|
||||
spawn {cmd, args}, (error) -> callback(error)
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{spawn, rm} = require('./task-helpers')(grunt)
|
||||
|
||||
grunt.registerTask 'create-installer', 'Create the Windows installer', ->
|
||||
return unless process.platform is 'win32'
|
||||
|
||||
done = @async()
|
||||
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
atomDir = path.join(buildDir, 'Atom')
|
||||
releasesDir = path.join(buildDir, 'Releases')
|
||||
atomGitHubToken = process.env.ATOM_ACCESS_TOKEN
|
||||
|
||||
packageInfo = grunt.file.readJSON(path.join(atomDir, 'resources', 'app', 'package.json'))
|
||||
inputTemplate = grunt.file.read(path.join('build', 'windows', 'atom.nuspec.erb'))
|
||||
|
||||
# NB: Build server has some sort of stamp on the version number
|
||||
packageInfo.version = packageInfo.version.replace(/-.*$/, '')
|
||||
|
||||
targetNuspecPath = path.join(buildDir, 'atom.nuspec')
|
||||
grunt.file.write(targetNuspecPath, _.template(inputTemplate, packageInfo))
|
||||
|
||||
# We use the previous releases to build deltas for the current release,
|
||||
# sync down the existing releases directory by rolling through GitHub releases
|
||||
cmd = 'build/windows/SyncGitHubReleases.exe'
|
||||
args = ['-r', releasesDir, '-u', 'https://github.com/atom/atom', '-t', atomGitHubToken]
|
||||
|
||||
spawn {cmd, args}, (error, result, code) ->
|
||||
if error?
|
||||
grunt.log.error "ATOM_ACCESS_TOKEN environment variable not set or invalid, can't download old releases; continuing anyways"
|
||||
|
||||
cmd = 'build/windows/nuget.exe'
|
||||
args = ['pack', targetNuspecPath, '-BasePath', atomDir, '-OutputDirectory', buildDir]
|
||||
|
||||
spawn {cmd, args}, (error, result, code) ->
|
||||
return done(error) if error?
|
||||
|
||||
pkgs = pkg for pkg in fs.readdirSync(buildDir) when path.extname(pkg) is '.nupkg'
|
||||
|
||||
cmd = 'build/windows/update.com'
|
||||
args = ['--releasify', path.join(buildDir, pkgs), '-r', releasesDir, '-g', 'build/windows/install-spinner.gif']
|
||||
spawn {cmd, args}, (error, result, code) -> done(error)
|
||||
@@ -6,12 +6,17 @@ _ = require 'underscore-plus'
|
||||
donna = require 'donna'
|
||||
tello = require 'tello'
|
||||
|
||||
moduleBlacklist = [
|
||||
'space-pen'
|
||||
]
|
||||
|
||||
module.exports = (grunt) ->
|
||||
getClassesToInclude = ->
|
||||
modulesPath = path.resolve(__dirname, '..', '..', 'node_modules')
|
||||
classes = {}
|
||||
fs.traverseTreeSync modulesPath, (modulePath) ->
|
||||
return false if modulePath.match(/node_modules/g).length > 1 # dont need the dependencies of the dependencies
|
||||
return false if path.basename(modulePath) in moduleBlacklist
|
||||
return true unless path.basename(modulePath) is 'package.json'
|
||||
return true unless fs.isFileSync(modulePath)
|
||||
|
||||
|
||||
@@ -54,6 +54,11 @@ module.exports = (gruntObject) ->
|
||||
uploadAssets(release, buildDir, assets, done)
|
||||
|
||||
getAssets = ->
|
||||
{cp} = require('./task-helpers')(grunt)
|
||||
|
||||
{version} = grunt.file.readJSON('package.json')
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
|
||||
switch process.platform
|
||||
when 'darwin'
|
||||
[
|
||||
@@ -62,16 +67,16 @@ getAssets = ->
|
||||
{assetName: 'atom-api.json', sourcePath: 'atom-api.json'}
|
||||
]
|
||||
when 'win32'
|
||||
[
|
||||
{assetName: 'atom-windows.zip', sourcePath: 'Atom'}
|
||||
]
|
||||
assets = [{assetName: 'atom-windows.zip', sourcePath: 'Atom'}]
|
||||
for squirrelAsset in ['AtomSetup.exe', 'RELEASES', "atom-#{version}-full.nupkg"]
|
||||
cp path.join(buildDir, 'installer', squirrelAsset), path.join(buildDir, squirrelAsset)
|
||||
assets.push({assetName: squirrelAsset, sourcePath: assetName})
|
||||
assets
|
||||
when 'linux'
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
if process.arch is 'ia32'
|
||||
arch = 'i386'
|
||||
else
|
||||
arch = 'amd64'
|
||||
{version} = grunt.file.readJSON('package.json')
|
||||
|
||||
# Check for a Debian build
|
||||
sourcePath = "#{buildDir}/atom-#{version}-#{arch}.deb"
|
||||
@@ -87,7 +92,6 @@ getAssets = ->
|
||||
arch = 'x86_64'
|
||||
assetName = "atom.#{arch}.rpm"
|
||||
|
||||
{cp} = require('./task-helpers')(grunt)
|
||||
cp sourcePath, path.join(buildDir, assetName)
|
||||
|
||||
[
|
||||
|
||||
@@ -11,6 +11,13 @@ module.exports = (grunt) ->
|
||||
|
||||
packageSpecQueue = null
|
||||
|
||||
logDeprecations = (label, {stderr}={}) ->
|
||||
if process.env.JANKY_SHA1 and stderr?.indexOf('Calls to deprecated functions') isnt -1
|
||||
grunt.log.error(label)
|
||||
stderr = stderr.replace(/^\[.*\] "/g, '')
|
||||
stderr = stderr.replace(/source: .*$/g, '')
|
||||
grunt.log.error(stderr)
|
||||
|
||||
getAppPath = ->
|
||||
contentsDir = grunt.config.get('atom.contentsDir')
|
||||
switch process.platform
|
||||
@@ -54,6 +61,7 @@ module.exports = (grunt) ->
|
||||
fs.unlinkSync(path.join(packagePath, 'ci.log'))
|
||||
|
||||
failedPackages.push path.basename(packagePath) if error
|
||||
logDeprecations("#{path.basename(packagePath)} Specs", results)
|
||||
callback()
|
||||
|
||||
modulesDirectory = path.resolve('node_modules')
|
||||
@@ -87,6 +95,7 @@ module.exports = (grunt) ->
|
||||
else
|
||||
# TODO: Restore concurrency on Windows
|
||||
packageSpecQueue.concurrency = concurrency
|
||||
logDeprecations('Core Specs', results)
|
||||
|
||||
callback(null, error)
|
||||
|
||||
|
||||
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id><%= name %></id>
|
||||
<version><%= version %></version>
|
||||
<authors>The Atom Community</authors>
|
||||
<owners>The Atom Community</owners>
|
||||
<iconUrl>https://raw.githubusercontent.com/atom/atom/master/resources/win/atom.ico</iconUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description><%= description %></description>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="locales\**" target="lib\net45\locales" />
|
||||
<file src="resources\**" target="lib\net45\resources" />
|
||||
<file src="*.pak" target="lib\net45" />
|
||||
<file src="atom.exe" target="lib\net45\atom.exe" />
|
||||
<file src="atom.exe.gui" target="lib\net45\atom.exe.gui" />
|
||||
<file src="chromiumcontent.dll" target="lib\net45\chromiumcontent.dll" />
|
||||
<file src="d3dcompiler_43.dll" target="lib\net45\d3dcompiler_43.dll" />
|
||||
<file src="ffmpegsumo.dll" target="lib\net45\ffmpegsumo.dll" />
|
||||
<file src="icudtl.dat" target="lib\net45\icudtl.dat" />
|
||||
<file src="libEGL.dll" target="lib\net45\libEGL.dll" />
|
||||
<file src="libGLESv2.dll" target="lib\net45\libGLESv2.dll" />
|
||||
<file src="LICENSE" target="lib\net45\LICENSE" />
|
||||
<file src="msvcp120.dll" target="lib\net45\msvcp120.dll" />
|
||||
<file src="msvcr120.dll" target="lib\net45\msvcr120.dll" />
|
||||
<file src="vccorlib120.dll" target="lib\net45\vccorlib120.dll" />
|
||||
<file src="version" target="lib\net45\version" />
|
||||
<file src="xinput1_3.dll" target="lib\net45\xinput1_3.dll" />
|
||||
</files>
|
||||
</package>
|
||||
Arquivo binário não exibido.
|
Antes Largura: | Altura: | Tamanho: 43 KiB |
+2
-57
@@ -1,60 +1,5 @@
|
||||
# Welcome to the Atom API Documentation
|
||||
# Welcome to the Atom Docs
|
||||
|
||||

|
||||
|
||||
## FAQ
|
||||
|
||||
### Where do I start?
|
||||
|
||||
Check out [EditorView][EditorView] and [Editor][Editor] classes for a good
|
||||
overview of the main editor API.
|
||||
|
||||
### How do I access these classes?
|
||||
|
||||
Check out the [Atom][Atom] class docs to see what globals are available and
|
||||
what they provide.
|
||||
|
||||
You can also require many of these classes in your package via:
|
||||
|
||||
```coffee
|
||||
{EditorView} = require 'atom'
|
||||
```
|
||||
|
||||
The classes available from `require 'atom'` are:
|
||||
* [BufferedProcess][BufferedProcess]
|
||||
* [BufferedNodeProcess][BufferedNodeProcess]
|
||||
* [EditorView][EditorView]
|
||||
* [Git][Git]
|
||||
* [Point][Point]
|
||||
* [Range][Range]
|
||||
* [ScrollView][ScrollView]
|
||||
* [SelectListView][SelectListView]
|
||||
* [View][View]
|
||||
* [WorkspaceView][WorkspaceView]
|
||||
* [Workspace][Workspace]
|
||||
|
||||
### How do I create a package?
|
||||
|
||||
You probably want to read the [creating a package][creating-a-package]
|
||||
doc first and come back here when you are done.
|
||||
|
||||
### Where are the node docs?
|
||||
|
||||
Atom ships with node 0.11.10 and the comprehensive node API docs are available
|
||||
[here][node-docs].
|
||||
|
||||
[Atom]: ../classes/Atom.html
|
||||
[BufferedProcess]: ../classes/BufferedProcess.html
|
||||
[BufferedNodeProcess]: ../classes/BufferedNodeProcess.html
|
||||
[Editor]: ../classes/Editor.html
|
||||
[EditorView]: ../classes/EditorView.html
|
||||
[Git]: ../classes/Git.html
|
||||
[Point]: ../classes/Point.html
|
||||
[Range]: ../classes/Range.html
|
||||
[ScrollView]: ../classes/ScrollView.html
|
||||
[SelectListView]: ../classes/SelectListView.html
|
||||
[View]: ../classes/View.html
|
||||
[WorkspaceView]: ../classes/WorkspaceView.html
|
||||
[Workspace]: ../classes/Workspace.html
|
||||
[creating-a-package]: https://atom.io/docs/latest/creating-a-package
|
||||
[node-docs]: http://nodejs.org/docs/v0.11.10/api
|
||||
TODO: Write when docs move to a dedicated repo.
|
||||
|
||||
@@ -11,32 +11,34 @@ value of a namespaced config key with `atom.config.get`:
|
||||
@showInvisibles() if atom.config.get "editor.showInvisibles"
|
||||
```
|
||||
|
||||
Or you can use the `::subscribe` with `atom.config.observe` to track changes
|
||||
from any view object.
|
||||
Or you can subscribe via `atom.config.observe` to track changes from any view
|
||||
object.
|
||||
|
||||
```coffeescript
|
||||
{View} = require 'space-pen'
|
||||
|
||||
class MyView extends View
|
||||
initialize: ->
|
||||
@subscribe atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
|
||||
@adjustFontSize()
|
||||
attached: ->
|
||||
@fontSizeObserveSubscription =
|
||||
atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
|
||||
@adjustFontSize()
|
||||
|
||||
detached: ->
|
||||
@fontSizeObserveSubscription.dispose()
|
||||
```
|
||||
|
||||
The `atom.config.observe` method will call the given callback immediately with
|
||||
the current value for the specified key path, and it will also call it in the
|
||||
future whenever the value of that key path changes.
|
||||
future whenever the value of that key path changes. If you only want to invoke
|
||||
the callback when the next time the value changes, use `atom.config.onDidChange`
|
||||
instead.
|
||||
|
||||
Subscriptions made with `::subscribe` are automatically canceled when the
|
||||
view is removed. You can cancel config subscriptions manually via the
|
||||
`off` method on the subscription object that `atom.config.observe` returns.
|
||||
|
||||
```coffeescript
|
||||
fontSizeSubscription = atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
|
||||
@adjustFontSize()
|
||||
|
||||
# ... later on
|
||||
|
||||
fontSizeSubscription.off() # Stop observing
|
||||
```
|
||||
Subscription methods return *disposable* subscription objects. Note in the
|
||||
example above how we save the subscription to the `@fontSizeObserveSubscription`
|
||||
instance variable and dispose of it when the view is detached. To group multiple
|
||||
subscriptions together, you can add them all to a
|
||||
[`CompositeDisposable`][composite-disposable] that you dispose when the view is
|
||||
detached.
|
||||
|
||||
### Writing Config Settings
|
||||
|
||||
@@ -48,10 +50,9 @@ but you can programmatically write to it with `atom.config.set`:
|
||||
atom.config.set("core.showInvisibles", true)
|
||||
```
|
||||
|
||||
You can also use `setDefaults`, which will assign default values for keys that
|
||||
are always overridden by values assigned with `set`. Defaults are not written
|
||||
out to the the `config.json` file to prevent it from becoming cluttered.
|
||||
If you're exposing package configuration via specific key paths, you'll want to
|
||||
associate them with a schema in your package's main module. Read more about
|
||||
schemas in the [config API docs][config-api].
|
||||
|
||||
```coffeescript
|
||||
atom.config.setDefaults("editor", fontSize: 18, showInvisibles: true)
|
||||
```
|
||||
[composite-disposable]: https://atom.io/docs/api/latest/CompositeDisposable
|
||||
[config-api]: https://atom.io/docs/api/latest/Config
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
# Globals
|
||||
|
||||
Atom exposes several services through singleton objects accessible via the
|
||||
`atom` global:
|
||||
|
||||
* atom
|
||||
* workspace:
|
||||
Manipulate and query the state of the user interface for the current
|
||||
window. Open editors, manipulate panes.
|
||||
* workspaceView:
|
||||
Similar to workspace, but provides access to the root of all views in the
|
||||
current window.
|
||||
* project:
|
||||
Access the directory associated with the current window. Load editors,
|
||||
perform project-wide searches, register custom openers for special file
|
||||
types.
|
||||
* config:
|
||||
Read, write, and observe user configuration settings.
|
||||
* keymap:
|
||||
Add and query the currently active keybindings.
|
||||
* deserializers:
|
||||
Deserialize instances from their state objects and register deserializers.
|
||||
* packages:
|
||||
Activate, deactivate, and query user packages.
|
||||
* themes:
|
||||
Activate, deactivate, and query user themes.
|
||||
* contextMenu:
|
||||
Register context menus.
|
||||
* menu:
|
||||
Register application menus.
|
||||
* pasteboard:
|
||||
Read from and write to the system pasteboard.
|
||||
* syntax:
|
||||
Assign and query syntactically-scoped properties.
|
||||
@@ -16,7 +16,7 @@ keystrokes pass through `atom-text-editor` elements:
|
||||
'ctrl-shift-e': 'editor:select-to-end-of-line'
|
||||
'cmd-left': 'editor:move-to-first-character-of-line'
|
||||
|
||||
'atom-text-editor:not(.mini)'
|
||||
'atom-text-editor:not([mini])'
|
||||
'cmd-alt-[': 'editor:fold-current-row'
|
||||
'cmd-alt-]': 'editor:unfold-current-row'
|
||||
```
|
||||
@@ -27,8 +27,8 @@ patterns* to *commands*. When an element with the `atom-text-editor` class is fo
|
||||
`editor:delete-to-beginning-of-line` is emitted on the `atom-text-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
|
||||
sense on mini-editors, so the selector restricts them to regular editors.
|
||||
`mini` attribute. In this example, the commands for code folding don't really
|
||||
make sense on mini-editors, so the selector restricts them to regular editors.
|
||||
|
||||
### Keystroke Patterns
|
||||
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
## Atom's View System
|
||||
|
||||
### SpacePen Basics
|
||||
|
||||
Atom's view system is built around the [SpacePen] view framework. SpacePen
|
||||
view objects inherit from the jQuery prototype, and wrap DOM nodes
|
||||
|
||||
View objects are actually jQuery wrappers around DOM fragments, supporting all
|
||||
the typical jQuery traversal and manipulation methods. In addition, view objects
|
||||
have methods that are view-specific. For example, you could call both general
|
||||
and view-specific on the global `atom.workspaceView` instance:
|
||||
|
||||
```coffeescript
|
||||
atom.workspaceView.find('atom-text-editor.active') # standard jQuery method
|
||||
atom.workspaceView.getActiveEditor() # view-specific method
|
||||
```
|
||||
|
||||
If you retrieve a jQuery wrapper for an element associated with a view, use the
|
||||
`.view()` method to retrieve the element's view object:
|
||||
|
||||
```coffeescript
|
||||
# this is a plain jQuery object; you can't call view-specific methods
|
||||
editorElement = atom.workspaceView.find('atom-text-editor.active')
|
||||
|
||||
# get the view object by calling `.view()` to call view-specific methods
|
||||
editorView = editorElement.view()
|
||||
editorView.setCursorBufferPosition([1, 2])
|
||||
```
|
||||
|
||||
Refer to the [SpacePen] documentation for more details.
|
||||
|
||||
### WorkspaceView
|
||||
|
||||
The root of Atom's view hierarchy is a global called `atom.workspaceView`, which is a
|
||||
singleton instance of the `WorkspaceView` view class. The root view fills the entire
|
||||
window, and contains every other view. If you open Atom's inspector with
|
||||
`alt-cmd-i`, you can see the internal structure of `WorkspaceView`:
|
||||
|
||||
![WorkspaceView in the inspector][workspaceview-inspector]
|
||||
|
||||
#### Panes
|
||||
|
||||
The `WorkspaceView` contains `prependToBottom/Top/Left/Right` and
|
||||
`appendToBottom/Top/Left/Right` methods, which are used to add Tool Panels. Tool
|
||||
panels are elements that take up screen real estate not devoted to text editing.
|
||||
In the example above, the `TreeView` is appended to the left, and the
|
||||
`CommandPanel` is appended to the top.
|
||||
|
||||
```coffeescript
|
||||
# place a view to the left of the panes
|
||||
atom.workspaceView.appendToLeft(new MyView)
|
||||
|
||||
# place a view below the panes
|
||||
atom.workspaceView.appendToBottom(new MyOtherView)
|
||||
```
|
||||
|
||||
[spacepen]: http://github.com/nathansobo/space-pen
|
||||
[workspaceView-inspector]: https://f.cloud.github.com/assets/1424/1091631/1932c2d6-166b-11e3-8adf-9690fe82d3b8.png
|
||||
@@ -30,6 +30,8 @@ All requests that take parameters require `application/json`.
|
||||
Parameters:
|
||||
|
||||
- **page** (optional)
|
||||
- **sort** (optional, values: `created_at`, `updated_at`, `downloads`)
|
||||
- **direction** (optional, values: `asc`, `desc`)
|
||||
|
||||
Returns a list of all packages in the following format:
|
||||
```json
|
||||
@@ -57,6 +59,20 @@ Link: <https://www.atom.io/api/packages?page=1>; rel="self",
|
||||
<https://www.atom.io/api/packages?page=2>; rel="next"
|
||||
```
|
||||
|
||||
By default, results are sorted by download count, descending.
|
||||
|
||||
#### GET /api/packages/search
|
||||
|
||||
Parameters:
|
||||
|
||||
- **q** String query to search
|
||||
- **sort** (optional, values: `created_at`, `updated_at`, `downloads`)
|
||||
- **direction** (optional, values: `asc`, `desc`)
|
||||
|
||||
Returns a list of all packages in the same format as `/api/packages`.
|
||||
|
||||
By default, results sorted by relevance to search query.
|
||||
|
||||
### Showing package details
|
||||
|
||||
#### GET /api/packages/:package_name
|
||||
|
||||
@@ -29,6 +29,10 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
|
||||
* `sudo pacman -S base-devel git nodejs libgnome-keyring python2`
|
||||
* `export PYTHON=/usr/bin/python2` before building Atom.
|
||||
|
||||
### Slackware
|
||||
|
||||
* `sbopkg -k -i node -i atom`
|
||||
|
||||
## Instructions
|
||||
|
||||
If you have problems with permissions don't forget to prefix with `sudo`
|
||||
@@ -43,7 +47,7 @@ If you have problems with permissions don't forget to prefix with `sudo`
|
||||
2. Checkout the latest Atom release:
|
||||
|
||||
```sh
|
||||
git fetch
|
||||
git fetch -p
|
||||
git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
|
||||
```
|
||||
|
||||
@@ -121,6 +125,15 @@ have Node.js installed, or node isn't identified as Node.js on your machine.
|
||||
If it's the latter, entering `sudo ln -s /usr/bin/nodejs /usr/bin/node` into
|
||||
your terminal may fix the issue.
|
||||
|
||||
#### You can also use Alternatives
|
||||
|
||||
On some variants (mostly Debian based distros) it's preferable for you to use
|
||||
Alternatives so that changes to the binary paths can be fixed or altered easily:
|
||||
|
||||
```sh
|
||||
sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 1 --slave /usr/bin/js js /usr/bin/nodejs
|
||||
```
|
||||
|
||||
### AttributeError: 'module' object has no attribute 'script_main'
|
||||
|
||||
If you get following error with a big traceback while building Atom:
|
||||
@@ -137,15 +150,6 @@ On Fedora you would do the following:
|
||||
sudo yum remove gyp
|
||||
```
|
||||
|
||||
#### You can also use Alternatives
|
||||
|
||||
On some variants (mostly Debian based distros) it's preferable for you to use
|
||||
Alternatives so that changes to the binary paths can be fixed or altered easily:
|
||||
|
||||
```sh
|
||||
sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 1 --slave /usr/bin/js js /usr/bin/nodejs
|
||||
```
|
||||
|
||||
### Linux build error reports in atom/atom
|
||||
* Use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Alinux&type=Issues)
|
||||
to get a list of reports about build errors on Linux.
|
||||
|
||||
@@ -40,7 +40,7 @@ package.json files have their own additions.
|
||||
- `main` (**Required**): the path to the CoffeeScript file that's the entry point
|
||||
to your package
|
||||
- `stylesheets` (**Optional**): an Array of Strings identifying the order of the
|
||||
stylesheets your package needs to load. If not specified, stylesheets in the
|
||||
style sheets your package needs to load. If not specified, style sheets in the
|
||||
_stylesheets_ directory are added alphabetically.
|
||||
- `keymaps`(**Optional**): an Array of Strings identifying the order of the
|
||||
key mappings your package needs to load. If not specified, mappings in the
|
||||
@@ -119,27 +119,27 @@ Also, please collaborate with us if you need an API that doesn't exist. Our goal
|
||||
is to build out Atom's API organically based on the needs of package authors
|
||||
like you.
|
||||
|
||||
## Stylesheets
|
||||
## Style Sheets
|
||||
|
||||
Stylesheets for your package should be placed in the _stylesheets_ directory.
|
||||
Any stylesheets in this directory will be loaded and attached to the DOM when
|
||||
your package is activated. Stylesheets can be written as CSS or [LESS] (but LESS
|
||||
is recommended).
|
||||
Style sheets for your package should be placed in the _stylesheets_ directory.
|
||||
Any style sheets in this directory will be loaded and attached to the DOM when
|
||||
your package is activated. Style sheets can be written as CSS or [LESS] (but
|
||||
LESS is recommended).
|
||||
|
||||
Ideally, you won't need much in the way of styling. We've provided a standard
|
||||
set of components which define both the colors and UI elements for any package
|
||||
that fits into Atom seamlessly. You can view all of Atom's UI components by opening
|
||||
the styleguide: open the command palette (`cmd-shift-P`) and search for _styleguide_,
|
||||
or just type `cmd-ctrl-shift-G`.
|
||||
that fits into Atom seamlessly. You can view all of Atom's UI components by
|
||||
opening the styleguide: open the command palette (`cmd-shift-P`) and search for
|
||||
_styleguide_, or just type `cmd-ctrl-shift-G`.
|
||||
|
||||
If you _do_ need special styling, try to keep only structural styles in the package
|
||||
stylesheets. If you _must_ specify colors and sizing, these should be taken from
|
||||
the active theme's [ui-variables.less][ui-variables]. For more information, see the
|
||||
[theme variables docs][theme-variables]. If you follow this guideline, your package
|
||||
will look good out of the box with any theme!
|
||||
If you _do_ need special styling, try to keep only structural styles in the
|
||||
package style sheets. If you _must_ specify colors and sizing, these should be
|
||||
taken from the active theme's [ui-variables.less][ui-variables]. For more
|
||||
information, see the [theme variables docs][theme-variables]. If you follow this
|
||||
guideline, your package will look good out of the box with any theme!
|
||||
|
||||
An optional `stylesheets` array in your _package.json_ can list the stylesheets
|
||||
by name to specify a loading order; otherwise, stylesheets are loaded
|
||||
An optional `stylesheets` array in your _package.json_ can list the style sheets
|
||||
by name to specify a loading order; otherwise, style sheets are loaded
|
||||
alphabetically.
|
||||
|
||||
## Keymaps
|
||||
@@ -157,9 +157,9 @@ loaded in alphabetical order. An optional `keymaps` array in your _package.json_
|
||||
can specify which keymaps to load and in what order.
|
||||
|
||||
|
||||
Keybindings are executed by determining which element the keypress occurred on. In
|
||||
the example above, `changer:magic` command is executed when pressing `ctrl-V` on
|
||||
the `.tree-view-scroller` element.
|
||||
Keybindings are executed by determining which element the keypress occurred on.
|
||||
In the example above, `changer:magic` command is executed when pressing `ctrl-V`
|
||||
on the `.tree-view-scroller` element.
|
||||
|
||||
See the [main keymaps documentation][keymaps] for more detailed information on
|
||||
how keymaps work.
|
||||
@@ -195,7 +195,8 @@ with your package that aren't tied to a specific element:
|
||||
```
|
||||
|
||||
To add your own item to the application menu, simply create a top level `menu`
|
||||
key in any menu configuration file in _menus_. This can be a JSON or [CSON] file.
|
||||
key in any menu configuration file in _menus_. This can be a JSON or [CSON]
|
||||
file.
|
||||
|
||||
The menu templates you specify are merged with all other templates provided
|
||||
by other packages in the order which they were loaded.
|
||||
|
||||
@@ -59,6 +59,8 @@ window in dev mode. To open a Dev Mode Atom window run `atom --dev .` in the
|
||||
terminal, use `cmd-shift-o` or use the _View > Developer > Open in Dev Mode_
|
||||
menu. When you edit your theme, changes will instantly be reflected!
|
||||
|
||||
> Note: It's advised to _not_ specify a `font-family` in your syntax theme because it will override the Font Family field in Atom's settings. If you still like to recommend a font that goes well with your theme, we recommend you do so in your README.
|
||||
|
||||
## Creating an Interface Theme
|
||||
|
||||
Interface themes **must** provide a `ui-variables.less` file which contains all
|
||||
|
||||
@@ -63,7 +63,7 @@ built-in keymaps:
|
||||
'atom-text-editor':
|
||||
'enter': 'editor:newline'
|
||||
|
||||
'atom-text-editor.mini input':
|
||||
'atom-text-editor[mini] input':
|
||||
'enter': 'core:confirm'
|
||||
```
|
||||
|
||||
@@ -118,7 +118,6 @@ You can open this file in an editor from the _Atom > Open Your Config_ menu.
|
||||
- `cr`: Carriage return (for Microsoft-style line endings)
|
||||
- `eol`: `\n` characters
|
||||
- `space`: Leading and trailing space characters
|
||||
- `normalizeIndentOnPaste`: Enable/disable conversion of pasted tabs to spaces
|
||||
- `preferredLineLength`: Identifies the length of a line (defaults to `80`)
|
||||
- `showInvisibles`: Whether to render placeholders for invisible characters (defaults to `false`)
|
||||
- `showIndentGuide`: Show/hide indent indicators within the editor
|
||||
|
||||
+5
-1
@@ -18,5 +18,9 @@
|
||||
* [Developing Node Modules](advanced/node-modules.md)
|
||||
* [Keymaps](advanced/keymaps.md)
|
||||
* [Serialization](advanced/serialization.md)
|
||||
* [View System](advanced/view-system.md)
|
||||
* [Scopes and Scope Descriptors](advanced/scopes-and-scope-descriptors.md)
|
||||
|
||||
### Upgrading to 1.0 APIs
|
||||
|
||||
* [Upgrading Your UI Theme Or Package Selectors](upgrading/upgrading-your-ui-theme.md)
|
||||
* [Upgrading Your Syntax Theme](upgrading/upgrading-your-syntax-theme.md)
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css">
|
||||
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../../assets/js/html5shiv.js"></script>
|
||||
<script src="../../assets/js/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<title>Atom - <%= title %></title>
|
||||
<style>
|
||||
/*github.com style (c) Vasily Polovnyov <vast@whiteants.net>*/
|
||||
pre code {
|
||||
display: block; padding: 0.5em;
|
||||
color: #333;
|
||||
background: #f8f8ff
|
||||
}
|
||||
pre .comment,
|
||||
pre .template_comment,
|
||||
pre .diff .header,
|
||||
pre .javadoc {
|
||||
color: #998;
|
||||
font-style: italic
|
||||
}
|
||||
pre .keyword,
|
||||
pre .css .rule .keyword,
|
||||
pre .winutils,
|
||||
pre .javascript .title,
|
||||
pre .nginx .title,
|
||||
pre .subst,
|
||||
pre .request,
|
||||
pre .status {
|
||||
color: #333;
|
||||
font-weight: bold
|
||||
}
|
||||
pre .number,
|
||||
pre .hexcolor,
|
||||
pre .ruby .constant {
|
||||
color: #099;
|
||||
}
|
||||
pre .string,
|
||||
pre .tag .value,
|
||||
pre .phpdoc,
|
||||
pre .tex .formula {
|
||||
color: #d14
|
||||
}
|
||||
pre .title,
|
||||
pre .id {
|
||||
color: #900;
|
||||
font-weight: bold
|
||||
}
|
||||
pre .javascript .title,
|
||||
pre .lisp .title,
|
||||
pre .clojure .title,
|
||||
pre .subst {
|
||||
font-weight: normal
|
||||
}
|
||||
pre .class .title,
|
||||
pre .haskell .type,
|
||||
pre .vhdl .literal,
|
||||
pre .tex .command {
|
||||
color: #458;
|
||||
font-weight: bold
|
||||
}
|
||||
pre .tag,
|
||||
pre .tag .title,
|
||||
pre .rules .property,
|
||||
pre .django .tag .keyword {
|
||||
color: #000080;
|
||||
font-weight: normal
|
||||
}
|
||||
pre .attribute,
|
||||
pre .variable,
|
||||
pre .lisp .body {
|
||||
color: #008080
|
||||
}
|
||||
pre .regexp {
|
||||
color: #009926
|
||||
}
|
||||
pre .class {
|
||||
color: #458;
|
||||
font-weight: bold
|
||||
}
|
||||
pre .symbol,
|
||||
pre .ruby .symbol .string,
|
||||
pre .lisp .keyword,
|
||||
pre .tex .special,
|
||||
pre .prompt {
|
||||
color: #990073
|
||||
}
|
||||
pre .built_in,
|
||||
pre .lisp .title,
|
||||
pre .clojure .built_in {
|
||||
color: #0086b3
|
||||
}
|
||||
pre .preprocessor,
|
||||
pre .pi,
|
||||
pre .doctype,
|
||||
pre .shebang,
|
||||
pre .cdata {
|
||||
color: #999;
|
||||
font-weight: bold
|
||||
}
|
||||
pre .deletion {
|
||||
background: #fdd
|
||||
}
|
||||
pre .addition {
|
||||
background: #dfd
|
||||
}
|
||||
pre .diff .change {
|
||||
background: #0086b3
|
||||
}
|
||||
pre .chunk {
|
||||
color: #aaa
|
||||
}
|
||||
|
||||
body {
|
||||
padding-top: 50px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="/<%= tag %>/index.html">Atom Documentation</a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="/docs/api/<%= tag %>/api/index.html">API</a></li>
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<%= content %>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,27 @@
|
||||
# Upgrading Your Syntax Theme
|
||||
|
||||
Text editor content is now rendered in the shadow DOM, which shields it from being styled by global style sheets to protect against accidental style pollution. For more background on the shadow DOM, check out the [Shadow DOM 101][shadow-dom-101] on HTML 5 Rocks.
|
||||
|
||||
Syntax themes are specifically intended to style only text editor content, so they are automatically loaded directly into the text editor's shadow DOM when it is enabled. This happens automatically when the the theme's `package.json` contains a `theme: "syntax"` declaration, so you don't need to change anything to target the appropriate context.
|
||||
|
||||
When theme style sheets are loaded into the text editor's shadow DOM, selectors intended to target the editor from the *outside* no longer make sense. Styles targeting the `.editor` and `.editor-colors` classes instead need to target the `:host` pseudo-element, which matches against the containing `atom-text-editor` node. Check out the [Shadow DOM 201][host-pseudo-element] article for more information about the `:host` pseudo-element.
|
||||
|
||||
Here's an example from Atom's light syntax theme. Note that the previous selectors intended to target the editor from the outside have been retained to allow the theme to keep working during the transition phase when it is possible to disable the shadow DOM.
|
||||
|
||||
```css
|
||||
.editor-colors, :host { /* :host added */
|
||||
background-color: @syntax-background-color;
|
||||
color: @syntax-text-color;
|
||||
}
|
||||
|
||||
.editor, :host { /* :host added */
|
||||
.invisible-character {
|
||||
color: @syntax-invisible-character-color;
|
||||
}
|
||||
|
||||
/* more nested selectors... */
|
||||
}
|
||||
```
|
||||
|
||||
[shadow-dom-101]: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom
|
||||
[host-pseudo-element]: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201#toc-style-host
|
||||
@@ -0,0 +1,137 @@
|
||||
# Upgrading Your UI Theme Or Package Selectors
|
||||
|
||||
In addition to changes in Atom's scripting API, we'll also be making some breaking changes to Atom's DOM structure, requiring stylesheets and keymaps in both packages and themes to be updated.
|
||||
|
||||
## Deprecation Cop
|
||||
|
||||
Deprecation cop will list usages of deprecated selector patterns to guide you. You can access it via the command palette (`cmd-shift-p`, then search for `Deprecation`). It breaks the deprecations down by package:
|
||||
|
||||

|
||||
|
||||
## Custom Tags
|
||||
|
||||
Rather than adding classes to standard HTML elements to indicate their role, Atom now uses custom element names. For example, `<div class="workspace">` has now been replaced with `<atom-workspace>`. Selectors should be updated accordingly. Note that tag names have lower specificity than classes in CSS, so you'll need to take care in converting things.
|
||||
|
||||
Old Selector | New Selector
|
||||
--------------------|--------------------------------
|
||||
`.editor` | `atom-text-editor`
|
||||
`.editor.mini` | `atom-text-editor[mini]`
|
||||
`.workspace` | `atom-workspace`
|
||||
`.horizontal` | `atom-workspace-axis.horizontal`
|
||||
`.vertical` | `atom-workspace-axis.vertical`
|
||||
`.pane-container` | `atom-pane-conatiner`
|
||||
`.pane` | `atom-pane`
|
||||
`.tool-panel` | `atom-panel`
|
||||
`.panel-top` | `atom-panel.top`
|
||||
`.panel-bottom` | `atom-panel.bottom`
|
||||
`.panel-left` | `atom-panel.left`
|
||||
`.panel-right` | `atom-panel.right`
|
||||
`.overlay` | `atom-panel.modal`
|
||||
|
||||
## Supporting the Shadow DOM
|
||||
|
||||
Text editor content is now rendered in the shadow DOM, which shields it from being styled by global style sheets to protect against accidental style pollution. For more background on the shadow DOM, check out the [Shadow DOM 101][shadow-dom-101] on HTML 5 Rocks. If you need to style text editor content in a UI theme, you'll need to circumvent this protection for any rules that target the text editor's content. Some examples of the kinds of UI theme styles needing to be updated:
|
||||
|
||||
* Highlight decorations
|
||||
* Gutter decorations
|
||||
* Line decorations
|
||||
* Scrollbar styling
|
||||
* Anything targeting a child selector of `.editor`
|
||||
|
||||
During a transition phase, it will be possible to enable or disable the text editor's shadow DOM in the settings, so themes will need to be compatible with both approaches.
|
||||
|
||||
### Shadow DOM Selectors
|
||||
|
||||
Chromium provides two tools for bypassing shadow boundaries, the `::shadow` pseudo-element and the `/deep/` combinator. For an in-depth explanation of styling the shadow DOM, see the [Shadow DOM 201][shadow-dom-201] article on HTML 5 Rocks.
|
||||
|
||||
#### ::shadow
|
||||
|
||||
The `::shadow` pseudo-element allows you to bypass a single shadow root. For example, say you want to update a highlight decoration for a linter package. Initially, the style looks as follows:
|
||||
|
||||
```css
|
||||
// Without shadow DOM support
|
||||
atom-text-editor .highlight.my-linter {
|
||||
background: hotpink;
|
||||
}
|
||||
```
|
||||
|
||||
In order for this style to apply with the shadow DOM enabled, you will need to add a second selector with the `::shadow` pseudo-element. You should leave the original selector in place so your theme continues to work with the shadow DOM disabled during the transition period.
|
||||
|
||||
```css
|
||||
// With shadow DOM support
|
||||
atom-text-editor .highlight.my-linter,
|
||||
atom-text-editor::shadow .highlight.my-linter {
|
||||
background: hotpink;
|
||||
}
|
||||
```
|
||||
|
||||
Check out the [find-and-replace][find-and-replace] package for another example of using `::shadow` to pierce the shadow DOM.
|
||||
|
||||
#### /deep/
|
||||
|
||||
The `/deep/` combinator overrides *all* shadow boundaries, making it useful for rules you want to apply globally such as scrollbar styling. Here's a snippet containing scrollbar styling for the Atom Dark UI theme before shadow DOM support:
|
||||
|
||||
```css
|
||||
// Without shadow DOM support
|
||||
.scrollbars-visible-always {
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track,
|
||||
::-webkit-scrollbar-corner {
|
||||
background: @scrollbar-background-color;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: @scrollbar-color;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 1px black inset;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To style scrollbars even inside of the shadow DOM, each rule needs to be prefixed with `/deep/`. We use `/deep/` instead of `::shadow` because we don't care about the selector of the host element in this case. We just want our styling to apply everywhere.
|
||||
|
||||
```css
|
||||
// With shadow DOM support using /deep/
|
||||
.scrollbars-visible-always {
|
||||
/deep/ ::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
/deep/ ::-webkit-scrollbar-track,
|
||||
/deep/ ::-webkit-scrollbar-corner {
|
||||
background: @scrollbar-background-color;
|
||||
}
|
||||
|
||||
/deep/ ::-webkit-scrollbar-thumb {
|
||||
background: @scrollbar-color;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 1px black inset;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Context-Targeted Style Sheets
|
||||
|
||||
The selector features discussed above allow you to target shadow DOM content with specific selectors, but Atom also allows you to target a specific shadow DOM context with an entire style sheet. The context into which a style sheet is loaded is based on the file name. If you want to load a style sheet into the editor, name it with the `.atom-text-editor.less` or `.atom-text-editor.css` extensions.
|
||||
|
||||
```
|
||||
my-ui-theme/
|
||||
stylesheets/
|
||||
index.less # loaded globally
|
||||
index.atom-text-editor.less # loaded in the text editor shadow DOM
|
||||
```
|
||||
|
||||
Check out this [style sheet](https://github.com/atom/decoration-example/blob/master/stylesheets/decoration-example.atom-text-editor.less) from the decoration-example package for an example of context-targeting.
|
||||
|
||||
Inside a context-targeted style sheet, there's no need to use the `::shadow` or `/deep/` expressions. If you want to refer to the element containing the shadow root, you can use the `::host` pseudo-element.
|
||||
|
||||
During the transition phase, style sheets targeting the `atom-text-editor` context will *also* be loaded globally. Make sure you update your selectors in a way that maintains compatibility with the shadow DOM being disabled. That means if you use a `::host` pseudo element, you should also include the same style rule matches against `atom-text-editor`.
|
||||
|
||||
[shadow-dom-101]: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom
|
||||
[shadow-dom-201]: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201#toc-style-cat-hat
|
||||
[find-and-replace]: https://github.com/atom/find-and-replace/blob/95351f261bc384960a69b66bf12eae8002da63f9/stylesheets/find-and-replace.less#L10
|
||||
@@ -72,7 +72,7 @@ Writing Asynchronous specs can be tricky at first. Some examples.
|
||||
atom.workspace.open 'c.coffee'
|
||||
|
||||
it "should be opened in an editor", ->
|
||||
expect(atom.workspace.getActiveEditor().getPath()).toContain 'c.coffee'
|
||||
expect(atom.workspace.getActiveTextEditor().getPath()).toContain 'c.coffee'
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ Register the command in _lib/ascii-art.coffee_:
|
||||
```coffeescript
|
||||
module.exports =
|
||||
activate: ->
|
||||
atom.workspaceView.command "ascii-art:convert", => @convert()
|
||||
atom.commands.add 'atom-workspace', "ascii-art:convert", => @convert()
|
||||
|
||||
convert: ->
|
||||
# This assumes the active pane item is an editor
|
||||
@@ -57,10 +57,10 @@ module.exports =
|
||||
editor.insertText('Hello, World!')
|
||||
```
|
||||
|
||||
The `atom.workspaceView.command` method takes a command name and a callback. The
|
||||
callback executes when the command is triggered. In this case, when the command
|
||||
is triggered the callback will call the `convert` method and insert 'Hello,
|
||||
World!'.
|
||||
The `atom.commands.add` method takes a selector, command name, and a callback.
|
||||
The callback executes when the command is triggered on an element matching the
|
||||
selector. In this case, when the command is triggered the callback will call the
|
||||
`convert` method and insert 'Hello, World!'.
|
||||
|
||||
## Reload the Package
|
||||
|
||||
@@ -95,13 +95,13 @@ you don't need it anymore. When finished, the file will look like this:
|
||||
'cmd-alt-a': 'ascii-art:convert'
|
||||
```
|
||||
|
||||
Notice `atom-text-editor` on the first line. Just like CSS, keymap selectors *scope* key
|
||||
bindings so they only apply to specific elements. In this case, our binding is
|
||||
only active for elements matching the `atom-text-editor` selector. If the Tree View has
|
||||
focus, pressing `cmd-alt-a` won't trigger the `ascii-art:convert` command. But
|
||||
if the editor has focus, the `ascii-art:convert` method *will* be triggered.
|
||||
More information on key bindings can be found in the
|
||||
[keymaps](advanced/keymaps.html) documentation.
|
||||
Notice `atom-text-editor` on the first line. Just like CSS, keymap selectors
|
||||
*scope* key bindings so they only apply to specific elements. In this case, our
|
||||
binding is only active for elements matching the `atom-text-editor` selector. If
|
||||
the Tree View has focus, pressing `cmd-alt-a` won't trigger the
|
||||
`ascii-art:convert` command. But if the editor has focus, the
|
||||
`ascii-art:convert` method *will* be triggered. More information on key bindings
|
||||
can be found in the [keymaps](advanced/keymaps.html) documentation.
|
||||
|
||||
Now reload the window and verify that the key binding works! You can also verify
|
||||
that it **doesn't** work when the Tree View is focused.
|
||||
|
||||
+108
-16
@@ -1,35 +1,127 @@
|
||||
{Point, Range} = require 'text-buffer'
|
||||
{Emitter, Disposable, CompositeDisposable} = require 'event-kit'
|
||||
{deprecate} = require 'grim'
|
||||
|
||||
module.exports =
|
||||
BufferedNodeProcess: require '../src/buffered-node-process'
|
||||
BufferedProcess: require '../src/buffered-process'
|
||||
GitRepository: require '../src/git-repository'
|
||||
Notification: require '../src/notification'
|
||||
Point: Point
|
||||
Range: Range
|
||||
Emitter: Emitter
|
||||
Disposable: Disposable
|
||||
CompositeDisposable: CompositeDisposable
|
||||
|
||||
# The following classes can't be used from a Task handler and should therefore
|
||||
# only be exported when not running as a child node process
|
||||
unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
|
||||
module.exports.Task = require '../src/task'
|
||||
module.exports.TextEditor = require '../src/text-editor'
|
||||
|
||||
{$, $$, $$$, View} = require '../src/space-pen-extensions'
|
||||
|
||||
module.exports.$ = $
|
||||
module.exports.$$ = $$
|
||||
module.exports.$$$ = $$$
|
||||
module.exports.TextEditorView = require '../src/text-editor-view'
|
||||
module.exports.ScrollView = require '../src/scroll-view'
|
||||
module.exports.SelectListView = require '../src/select-list-view'
|
||||
module.exports.Task = require '../src/task'
|
||||
module.exports.View = View
|
||||
module.exports.WorkspaceView = require '../src/workspace-view'
|
||||
module.exports.Workspace = require '../src/workspace'
|
||||
module.exports.React = require 'react-atom-fork'
|
||||
module.exports.Reactionary = require 'reactionary-atom-fork'
|
||||
Object.defineProperty module.exports, 'Workspace', get: ->
|
||||
deprecate """
|
||||
Requiring `Workspace` from `atom` is no longer supported.
|
||||
If you need this, please open an issue on
|
||||
https://github.com/atom/atom/issues/new
|
||||
And let us know what you are using it for.
|
||||
"""
|
||||
require '../src/workspace'
|
||||
|
||||
Object.defineProperty module.exports, 'WorkspaceView', get: ->
|
||||
deprecate """
|
||||
Requiring `WorkspaceView` from `atom` is no longer supported.
|
||||
Use `atom.views.getView(atom.workspace)` instead.
|
||||
"""
|
||||
require '../src/workspace-view'
|
||||
|
||||
Object.defineProperty module.exports, '$', get: ->
|
||||
deprecate """
|
||||
Requiring `$` from `atom` is no longer supported.
|
||||
If you are using `space-pen`, please require `$` from `space-pen`. Otherwise require `jquery` instead:
|
||||
`{$} = require 'space-pen'`
|
||||
or
|
||||
`$ = require 'jquery'`
|
||||
Add `"space-pen": "^4"` to your package dependencies.
|
||||
Or add `"jquery": "^2"` to your package dependencies.
|
||||
"""
|
||||
$
|
||||
|
||||
Object.defineProperty module.exports, '$$', get: ->
|
||||
deprecate """
|
||||
Requiring `$$` from `atom` is no longer supported.
|
||||
Please require `space-pen` instead:
|
||||
`{$$} = require 'space-pen'`
|
||||
Add `"space-pen": "^4"` to your package dependencies.
|
||||
"""
|
||||
$$
|
||||
|
||||
Object.defineProperty module.exports, '$$$', get: ->
|
||||
deprecate """
|
||||
Requiring `$$$` from `atom` is no longer supported.
|
||||
Please require `space-pen` instead:
|
||||
`{$$$} = require 'space-pen'`
|
||||
Add `"space-pen": "^4"` to your package dependencies.
|
||||
"""
|
||||
$$$
|
||||
|
||||
Object.defineProperty module.exports, 'View', get: ->
|
||||
deprecate """
|
||||
Requiring `View` from `atom` is no longer supported.
|
||||
Please require `space-pen` instead:
|
||||
`{View} = require 'space-pen'`
|
||||
Add `"space-pen": "^4"` to your package dependencies.
|
||||
"""
|
||||
View
|
||||
|
||||
Object.defineProperty module.exports, 'EditorView', get: ->
|
||||
deprecate """
|
||||
Requiring `EditorView` from `atom` is no longer supported.
|
||||
Please require `TextEditorView` from `atom-space-pen-view` instead:
|
||||
`{TextEditorView} = require 'atom-space-pen-views'`
|
||||
Add `"atom-space-pen-views": "^0"` to your package dependencies.
|
||||
"""
|
||||
require '../src/text-editor-view'
|
||||
|
||||
Object.defineProperty module.exports, 'TextEditorView', get: ->
|
||||
deprecate """
|
||||
Requiring `TextEditorView` from `atom` is no longer supported.
|
||||
Please require `TextEditorView` from `atom-space-pen-view` instead:
|
||||
`{TextEditorView} = require 'atom-space-pen-views'`
|
||||
Add `"atom-space-pen-views": "^0"` to your package dependencies.
|
||||
"""
|
||||
require '../src/text-editor-view'
|
||||
|
||||
Object.defineProperty module.exports, 'ScrollView', get: ->
|
||||
deprecate """
|
||||
Requiring `ScrollView` from `atom` is no longer supported.
|
||||
Please require `ScrollView` from `atom-space-pen-view` instead:
|
||||
`{ScrollView} = require 'atom-space-pen-views'`
|
||||
Note that the API has changed slightly! Please read the docs at https://github.com/atom/atom-space-pen-views
|
||||
Add `"atom-space-pen-views": "^0"` to your package dependencies.
|
||||
"""
|
||||
require '../src/scroll-view'
|
||||
|
||||
Object.defineProperty module.exports, 'SelectListView', get: ->
|
||||
deprecate """
|
||||
Requiring `SelectListView` from `atom` is no longer supported.
|
||||
Please require `SelectListView` from `atom-space-pen-view` instead:
|
||||
`{SelectListView} = require 'atom-space-pen-views'`
|
||||
Note that the API has changed slightly! Please read the docs at https://github.com/atom/atom-space-pen-views
|
||||
Add `"atom-space-pen-views": "^0"` to your package dependencies.
|
||||
"""
|
||||
require '../src/select-list-view'
|
||||
|
||||
Object.defineProperty module.exports, 'React', get: ->
|
||||
deprecate "Please require `react-atom-fork` instead: `React = require 'react-atom-fork'`. Add `\"react-atom-fork\": \"^0.11\"` to your package dependencies."
|
||||
require 'react-atom-fork'
|
||||
|
||||
Object.defineProperty module.exports, 'Reactionary', get: ->
|
||||
deprecate "Please require `reactionary-atom-fork` instead: `Reactionary = require 'reactionary-atom-fork'`. Add `\"reactionary-atom-fork\": \"^0.9\"` to your package dependencies."
|
||||
require 'reactionary-atom-fork'
|
||||
|
||||
Object.defineProperty module.exports, 'Git', get: ->
|
||||
deprecate "Please require `GitRepository` instead of `Git`: `{GitRepository} = require 'atom'`"
|
||||
module.exports.GitRepository
|
||||
|
||||
Object.defineProperty module.exports, 'EditorView', get: ->
|
||||
deprecate "Please require `TextEditorView` instead of `EditorView`: `{TextEditorView} = require 'atom'`"
|
||||
module.exports.TextEditorView
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@
|
||||
'shift-home': 'editor:select-to-first-character-of-line'
|
||||
'shift-end': 'editor:select-to-end-of-line'
|
||||
|
||||
'atom-text-editor:not(.mini)':
|
||||
'atom-text-editor:not([mini])':
|
||||
# Atom Specific
|
||||
'ctrl-C': 'editor:copy-path'
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
'shift-tab': 'editor:outdent-selected-rows'
|
||||
'ctrl-K': 'editor:delete-line'
|
||||
|
||||
'.select-list atom-text-editor.mini':
|
||||
'.select-list atom-text-editor[mini]':
|
||||
'enter': 'core:confirm'
|
||||
|
||||
'.tool-panel.panel-left, .tool-panel.panel-right':
|
||||
'escape': 'tool-panel:unfocus'
|
||||
|
||||
'atom-text-editor !important, atom-text-editor.mini !important':
|
||||
'atom-text-editor !important, atom-text-editor[mini] !important':
|
||||
'escape': 'editor:consolidate-selections'
|
||||
|
||||
# allow standard input fields to work correctly
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
'cmd-l': 'editor:select-line'
|
||||
'ctrl-t': 'editor:transpose'
|
||||
|
||||
'atom-workspace atom-text-editor:not(.mini)':
|
||||
'atom-workspace atom-text-editor:not([mini])':
|
||||
# Atom specific
|
||||
'alt-cmd-z': 'editor:checkout-head-revision'
|
||||
'cmd-<': 'editor:scroll-to-cursor'
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
'ctrl-k ctrl-l': 'editor:lower-case'
|
||||
'ctrl-l': 'editor:select-line'
|
||||
|
||||
'atom-workspace atom-text-editor:not(.mini)':
|
||||
'atom-workspace atom-text-editor:not([mini])':
|
||||
# Atom specific
|
||||
'alt-ctrl-z': 'editor:checkout-head-revision'
|
||||
'ctrl-<': 'editor:scroll-to-cursor'
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
'ctrl-k ctrl-l': 'editor:lower-case'
|
||||
'ctrl-l': 'editor:select-line'
|
||||
|
||||
'atom-workspace atom-text-editor:not(.mini)':
|
||||
'atom-workspace atom-text-editor:not([mini])':
|
||||
# Atom specific
|
||||
'alt-ctrl-z': 'editor:checkout-head-revision'
|
||||
'ctrl-<': 'editor:scroll-to-cursor'
|
||||
|
||||
+1
-1
@@ -202,7 +202,7 @@
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.overlayer': [
|
||||
'atom-text-editor, .overlayer': [
|
||||
{label: 'Undo', command: 'core:undo'}
|
||||
{label: 'Redo', command: 'core:redo'}
|
||||
{type: 'separator'}
|
||||
|
||||
+2
-1
@@ -94,6 +94,7 @@
|
||||
submenu: [
|
||||
{ label: '&Reload', command: 'window:reload' }
|
||||
{ label: 'Toggle &Full Screen', command: 'window:toggle-full-screen' }
|
||||
{ label: 'Toggle Menu Bar', command: 'window:toggle-menu-bar' }
|
||||
{
|
||||
label: 'Developer'
|
||||
submenu: [
|
||||
@@ -159,7 +160,7 @@
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.overlayer': [
|
||||
'atom-text-editor, .overlayer': [
|
||||
{label: 'Undo', command: 'core:undo'}
|
||||
{label: 'Redo', command: 'core:redo'}
|
||||
{type: 'separator'}
|
||||
|
||||
+6
-2
@@ -93,6 +93,7 @@
|
||||
submenu: [
|
||||
{ label: '&Reload', command: 'window:reload' }
|
||||
{ label: 'Toggle &Full Screen', command: 'window:toggle-full-screen' }
|
||||
{ label: 'Toggle Menu Bar', command: 'window:toggle-menu-bar' }
|
||||
{
|
||||
label: 'Panes'
|
||||
submenu: [
|
||||
@@ -162,7 +163,10 @@
|
||||
submenu: [
|
||||
{ label: 'View &Terms of Use', command: 'application:open-terms-of-use' }
|
||||
{ label: 'View &License', command: 'application:open-license' }
|
||||
{ label: "VERSION", enabled: false }
|
||||
{ label: 'VERSION', enabled: false }
|
||||
{ label: 'Restart and Install Update', command: 'application:install-update', visible: false}
|
||||
{ label: 'Check for Update', command: 'application:check-for-update', visible: false}
|
||||
{ label: 'Downloading Update', enabled: false, visible: false}
|
||||
{ type: 'separator' }
|
||||
{ label: '&Documentation', command: 'application:open-documentation' }
|
||||
{ label: 'Roadmap', command: 'application:open-roadmap' }
|
||||
@@ -177,7 +181,7 @@
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.overlayer': [
|
||||
'atom-text-editor, .overlayer': [
|
||||
{label: 'Undo', command: 'core:undo'}
|
||||
{label: 'Redo', command: 'core:redo'}
|
||||
{type: 'separator'}
|
||||
|
||||
+85
-80
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "0.146.0",
|
||||
"version": "0.164.0",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/browser/main.js",
|
||||
"repository": {
|
||||
@@ -17,33 +17,35 @@
|
||||
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
|
||||
}
|
||||
],
|
||||
"atomShellVersion": "0.19.1",
|
||||
"atomShellVersion": "0.19.4",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "^2.2.2",
|
||||
"atom-keymap": "^2.3.0",
|
||||
"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.3.1",
|
||||
"event-kit": "0.7.2",
|
||||
"event-kit": "0.8.1",
|
||||
"first-mate": "^2.2.0",
|
||||
"fs-plus": "^2.3.1",
|
||||
"fs-plus": "^2.3.2",
|
||||
"fstream": "0.1.24",
|
||||
"fuzzaldrin": "^2.1",
|
||||
"git-utils": "^2.1.5",
|
||||
"git-utils": "^2.2",
|
||||
"grim": "0.12.0",
|
||||
"guid": "0.0.10",
|
||||
"jasmine-json": "~0.0",
|
||||
"jasmine-tagged": "^1.1.2",
|
||||
"less-cache": "0.17.0",
|
||||
"jquery": "^2.1.1",
|
||||
"less-cache": "0.19.0",
|
||||
"marked": "^0.3",
|
||||
"mixto": "^1",
|
||||
"mkdirp": "0.3.5",
|
||||
"nslog": "^1.0.1",
|
||||
"oniguruma": "^3.0.4",
|
||||
"optimist": "0.4.0",
|
||||
"pathwatcher": "^2.3.2",
|
||||
"pathwatcher": "^2.3.5",
|
||||
"property-accessors": "^1",
|
||||
"q": "^1.0.1",
|
||||
"random-words": "0.0.1",
|
||||
@@ -51,96 +53,99 @@
|
||||
"reactionary-atom-fork": "^1.0.0",
|
||||
"runas": "1.0.1",
|
||||
"scandal": "1.0.3",
|
||||
"scoped-property-store": "^0.15.0",
|
||||
"scoped-property-store": "^0.15.4",
|
||||
"scrollbar-style": "^1.0.2",
|
||||
"season": "^1.0.2",
|
||||
"semver": "2.2.1",
|
||||
"serializable": "^1",
|
||||
"space-pen": "3.8.1",
|
||||
"service-hub": "^0.1.0",
|
||||
"space-pen": "3.8.2",
|
||||
"temp": "0.7.0",
|
||||
"text-buffer": "^3.6.0",
|
||||
"text-buffer": "^3.8.2",
|
||||
"theorist": "^1.0.2",
|
||||
"underscore-plus": "^1.6.1",
|
||||
"underscore-plus": "^1.6.6",
|
||||
"vm-compatibility-layer": "0.1.0"
|
||||
},
|
||||
"packageDependencies": {
|
||||
"atom-dark-syntax": "0.21.0",
|
||||
"atom-dark-ui": "0.35.0",
|
||||
"atom-light-syntax": "0.21.0",
|
||||
"atom-light-ui": "0.30.0",
|
||||
"base16-tomorrow-dark-theme": "0.21.0",
|
||||
"base16-tomorrow-light-theme": "0.4.0",
|
||||
"solarized-dark-syntax": "0.22.0",
|
||||
"solarized-light-syntax": "0.12.0",
|
||||
"archive-view": "0.37.0",
|
||||
"autocomplete": "0.33.0",
|
||||
"autoflow": "0.18.0",
|
||||
"autosave": "0.18.0",
|
||||
"background-tips": "0.17.0",
|
||||
"bookmarks": "0.30.0",
|
||||
"bracket-matcher": "0.62.0",
|
||||
"command-palette": "0.27.0",
|
||||
"deprecation-cop": "0.11.0",
|
||||
"dev-live-reload": "0.35.0",
|
||||
"encoding-selector": "0.7.0",
|
||||
"exception-reporting": "0.20.0",
|
||||
"find-and-replace": "0.146.0",
|
||||
"fuzzy-finder": "0.60.0",
|
||||
"git-diff": "0.43.0",
|
||||
"go-to-line": "0.26.0",
|
||||
"grammar-selector": "0.37.0",
|
||||
"image-view": "0.40.0",
|
||||
"incompatible-packages": "0.10.0",
|
||||
"keybinding-resolver": "0.20.0",
|
||||
"link": "0.26.0",
|
||||
"markdown-preview": "0.110.0",
|
||||
"metrics": "0.38.0",
|
||||
"open-on-github": "0.30.0",
|
||||
"package-generator": "0.32.0",
|
||||
"release-notes": "0.36.0",
|
||||
"settings-view": "0.159.0",
|
||||
"snippets": "0.56.0",
|
||||
"spell-check": "0.43.0",
|
||||
"status-bar": "0.46.0",
|
||||
"styleguide": "0.30.0",
|
||||
"symbols-view": "0.68.0",
|
||||
"tabs": "0.55.0",
|
||||
"timecop": "0.23.0",
|
||||
"tree-view": "0.132.0",
|
||||
"update-package-dependencies": "0.6.0",
|
||||
"welcome": "0.19.0",
|
||||
"whitespace": "0.26.0",
|
||||
"wrap-guide": "0.23.0",
|
||||
"language-c": "0.30.0",
|
||||
"language-coffee-script": "0.37.0",
|
||||
"language-css": "0.23.0",
|
||||
"language-gfm": "0.53.0",
|
||||
"atom-dark-syntax": "0.23.0",
|
||||
"atom-dark-ui": "0.42.0",
|
||||
"atom-light-syntax": "0.22.0",
|
||||
"atom-light-ui": "0.36.0",
|
||||
"base16-tomorrow-dark-theme": "0.22.0",
|
||||
"base16-tomorrow-light-theme": "0.5.0",
|
||||
"solarized-dark-syntax": "0.29.0",
|
||||
"solarized-light-syntax": "0.13.0",
|
||||
"archive-view": "0.40.0",
|
||||
"autocomplete": "0.34.0",
|
||||
"autoflow": "0.20.0",
|
||||
"autosave": "0.19.0",
|
||||
"background-tips": "0.18.0",
|
||||
"bookmarks": "0.31.0",
|
||||
"bracket-matcher": "0.64.0",
|
||||
"command-palette": "0.30.0",
|
||||
"deprecation-cop": "0.20.0",
|
||||
"dev-live-reload": "0.36.0",
|
||||
"encoding-selector": "0.12.0",
|
||||
"exception-reporting": "0.21.0",
|
||||
"find-and-replace": "0.152.0",
|
||||
"fuzzy-finder": "0.62.0",
|
||||
"git-diff": "0.45.0",
|
||||
"go-to-line": "0.27.0",
|
||||
"grammar-selector": "0.40.0",
|
||||
"image-view": "0.44.0",
|
||||
"incompatible-packages": "0.16.0",
|
||||
"keybinding-resolver": "0.24.0",
|
||||
"link": "0.28.0",
|
||||
"markdown-preview": "0.112.0",
|
||||
"metrics": "0.40.0",
|
||||
"notifications": "0.20.0",
|
||||
"open-on-github": "0.31.0",
|
||||
"package-generator": "0.34.0",
|
||||
"release-notes": "0.43.0",
|
||||
"settings-view": "0.161.0",
|
||||
"snippets": "0.60.0",
|
||||
"spell-check": "0.45.0",
|
||||
"status-bar": "0.54.0",
|
||||
"styleguide": "0.36.0",
|
||||
"symbols-view": "0.70.0",
|
||||
"tabs": "0.58.0",
|
||||
"timecop": "0.24.0",
|
||||
"tree-view": "0.139.0",
|
||||
"update-package-dependencies": "0.7.0",
|
||||
"welcome": "0.21.0",
|
||||
"whitespace": "0.27.0",
|
||||
"wrap-guide": "0.27.0",
|
||||
"language-c": "0.33.0",
|
||||
"language-clojure": "0.9.0",
|
||||
"language-coffee-script": "0.38.1",
|
||||
"language-css": "0.24.0",
|
||||
"language-gfm": "0.55.0",
|
||||
"language-git": "0.9.0",
|
||||
"language-go": "0.19.0",
|
||||
"language-html": "0.26.0",
|
||||
"language-hyperlink": "0.12.0",
|
||||
"language-java": "0.11.0",
|
||||
"language-javascript": "0.43.0",
|
||||
"language-json": "0.8.0",
|
||||
"language-less": "0.18.0",
|
||||
"language-go": "0.19.1",
|
||||
"language-html": "0.27.0",
|
||||
"language-hyperlink": "0.12.2",
|
||||
"language-java": "0.13.0",
|
||||
"language-javascript": "0.51.0",
|
||||
"language-json": "0.10.0",
|
||||
"language-less": "0.21.0",
|
||||
"language-make": "0.12.0",
|
||||
"language-mustache": "0.10.0",
|
||||
"language-objective-c": "0.11.0",
|
||||
"language-mustache": "0.11.0",
|
||||
"language-objective-c": "0.12.0",
|
||||
"language-perl": "0.9.0",
|
||||
"language-php": "0.18.0",
|
||||
"language-property-list": "0.7.0",
|
||||
"language-python": "0.23.0",
|
||||
"language-ruby": "0.41.0",
|
||||
"language-python": "0.26.0",
|
||||
"language-ruby": "0.44.0",
|
||||
"language-ruby-on-rails": "0.18.0",
|
||||
"language-sass": "0.25.0",
|
||||
"language-shellscript": "0.10.0",
|
||||
"language-sass": "0.29.0",
|
||||
"language-shellscript": "0.10.1",
|
||||
"language-source": "0.8.0",
|
||||
"language-sql": "0.11.0",
|
||||
"language-text": "0.6.0",
|
||||
"language-todo": "0.13.0",
|
||||
"language-toml": "0.14.0",
|
||||
"language-xml": "0.24.0",
|
||||
"language-yaml": "0.19.0"
|
||||
"language-todo": "0.15.0",
|
||||
"language-toml": "0.14.1",
|
||||
"language-xml": "0.25.0",
|
||||
"language-yaml": "0.21.0"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package: <%= name %>
|
||||
Version: <%= version %>
|
||||
Depends: gconf2, gconf-service, libgtk2.0-0, libudev0 | libudev1, libgcrypt11, libnotify4, libxtst6, libnss3, python, gvfs-bin, xdg-utils
|
||||
Depends: git, gconf2, gconf-service, libgtk2.0-0, libudev0 | libudev1, libgcrypt11, libnotify4, libxtst6, libnss3, python, gvfs-bin, xdg-utils
|
||||
Suggests: libgnome-keyring0, gir1.2-gnomekeyring-1.0
|
||||
Section: <%= section %>
|
||||
Priority: optional
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
"$0/../../app/apm/node_modules/atom-package-manager/bin/node.exe" "$0/../../app/apm/node_modules/atom-package-manager/lib/cli.js" "$@"
|
||||
@@ -0,0 +1,22 @@
|
||||
@echo off
|
||||
|
||||
SET EXPECT_OUTPUT=
|
||||
|
||||
FOR %%a IN (%*) DO (
|
||||
IF /I "%%a"=="-f" SET EXPECT_OUTPUT=YES
|
||||
IF /I "%%a"=="--foreground" SET EXPECT_OUTPUT=YES
|
||||
IF /I "%%a"=="-h" SET EXPECT_OUTPUT=YES
|
||||
IF /I "%%a"=="--help" SET EXPECT_OUTPUT=YES
|
||||
IF /I "%%a"=="-t" SET EXPECT_OUTPUT=YES
|
||||
IF /I "%%a"=="--test" SET EXPECT_OUTPUT=YES
|
||||
IF /I "%%a"=="-v" SET EXPECT_OUTPUT=YES
|
||||
IF /I "%%a"=="--version" SET EXPECT_OUTPUT=YES
|
||||
IF /I "%%a"=="-w" SET EXPECT_OUTPUT=YES
|
||||
IF /I "%%a"=="--wait" SET EXPECT_OUTPUT=YES
|
||||
)
|
||||
|
||||
IF "%EXPECT_OUTPUT%"=="YES" (
|
||||
"%~dp0\..\..\atom.exe" %*
|
||||
) ELSE (
|
||||
"%~dp0\..\app\apm\node_modules\atom-package-manager\bin\node.exe" "%~dp0\atom.js" %*
|
||||
)
|
||||
@@ -0,0 +1,9 @@
|
||||
var path = require('path');
|
||||
var spawn = require('child_process').spawn;
|
||||
|
||||
var atomCommandPath = path.resolve(__dirname, '..', '..', 'atom.exe');
|
||||
var arguments = process.argv.slice(2);
|
||||
arguments.unshift('--executed-from', process.cwd());
|
||||
var options = {detached: true, stdio: 'ignore'};
|
||||
spawn(atomCommandPath, arguments, options);
|
||||
process.exit(0);
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
|
||||
while getopts ":fhtvw-:" opt; do
|
||||
case "$opt" in
|
||||
-)
|
||||
case "${OPTARG}" in
|
||||
foreground|help|test|version|wait)
|
||||
EXPECT_OUTPUT=1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
f|h|t|v|w)
|
||||
EXPECT_OUTPUT=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $EXPECT_OUTPUT ]; then
|
||||
"$0/../../../atom.exe" "$@"
|
||||
else
|
||||
"$0/../../app/apm/node_modules/atom-package-manager/bin/node.exe" "$0/../atom.js" "$@"
|
||||
fi
|
||||
Arquivo binário não exibido.
|
Depois Largura: | Altura: | Tamanho: 274 KiB |
@@ -4,7 +4,9 @@ set -e
|
||||
|
||||
docker build -t atom-rpm .
|
||||
docker run \
|
||||
--rm \
|
||||
--env JANKY_SHA1="$JANKY_SHA1" \
|
||||
--env JANKY_BRANCH="$JANKY_BRANCH" \
|
||||
--env ATOM_ACCESS_TOKEN="$BUILD_ATOM_RPM_ACCESS_TOKEN" \
|
||||
atom-rpm /atom/script/rpmbuild
|
||||
docker rmi atom-rpm
|
||||
|
||||
@@ -34,6 +34,9 @@ exports.safeSpawn = function(command, args, options, callback) {
|
||||
var child = childProcess.spawn(command, args, options);
|
||||
child.stderr.pipe(process.stderr);
|
||||
child.stdout.pipe(process.stdout);
|
||||
child.on('error', function(error) {
|
||||
console.error('Command \'' + command + '\' failed: ' + error.message);
|
||||
});
|
||||
child.on('exit', function(code) {
|
||||
if (code != 0)
|
||||
process.exit(code);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{$} = require 'atom'
|
||||
{$} = require '../src/space-pen-extensions'
|
||||
|
||||
describe '"atom" protocol URL', ->
|
||||
it 'sends the file relative in the package as response', ->
|
||||
|
||||
@@ -3,6 +3,7 @@ _ = require 'underscore-plus'
|
||||
{convertStackTrace} = require 'coffeestack'
|
||||
{View, $, $$} = require '../src/space-pen-extensions'
|
||||
grim = require 'grim'
|
||||
marked = require 'marked'
|
||||
|
||||
sourceMaps = {}
|
||||
formatStackTrace = (spec, message='', stackTrace) ->
|
||||
@@ -37,7 +38,8 @@ module.exports =
|
||||
class AtomReporter extends View
|
||||
@content: ->
|
||||
@div class: 'spec-reporter', =>
|
||||
@div outlet: "suites"
|
||||
@div class: 'padded pull-right', =>
|
||||
@button outlet: 'reloadButton', class: 'btn btn-small reload-button', 'Reload Specs'
|
||||
@div outlet: 'coreArea', class: 'symbol-area', =>
|
||||
@div outlet: 'coreHeader', class: 'symbol-header'
|
||||
@ul outlet: 'coreSummary', class: 'symbol-summary list-unstyled'
|
||||
@@ -79,6 +81,8 @@ class AtomReporter extends View
|
||||
@on 'click', '.stack-trace', ->
|
||||
$(this).toggleClass('expanded')
|
||||
|
||||
@reloadButton.on 'click', -> require('ipc').send('call-window-method', 'restart')
|
||||
|
||||
reportRunnerResults: (runner) ->
|
||||
@updateSpecCounts()
|
||||
@status.addClass('alert-success').removeClass('alert-info') if @failedCount is 0
|
||||
@@ -110,7 +114,8 @@ class AtomReporter extends View
|
||||
for deprecation in deprecations
|
||||
@deprecationList.append $$ ->
|
||||
@div class: 'padded', =>
|
||||
@div class: 'result-message fail deprecation-message', deprecation.message
|
||||
@div class: 'result-message fail deprecation-message', =>
|
||||
@raw marked(deprecation.message)
|
||||
|
||||
for stack in deprecation.stacks
|
||||
fullStack = stack.map ({functionName, location}) ->
|
||||
|
||||
+82
-10
@@ -1,13 +1,10 @@
|
||||
{$, $$, WorkspaceView} = require 'atom'
|
||||
{$, $$} = require '../src/space-pen-extensions'
|
||||
Exec = require('child_process').exec
|
||||
path = require 'path'
|
||||
Package = require '../src/package'
|
||||
ThemeManager = require '../src/theme-manager'
|
||||
|
||||
describe "the `atom` global", ->
|
||||
beforeEach ->
|
||||
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
|
||||
|
||||
describe 'window sizing methods', ->
|
||||
describe '::getPosition and ::setPosition', ->
|
||||
it 'sets the position of the window, and can retrieve the position just set', ->
|
||||
@@ -33,10 +30,16 @@ describe "the `atom` global", ->
|
||||
version = '36b5518'
|
||||
expect(atom.isReleasedVersion()).toBe false
|
||||
|
||||
describe "window:update-available", ->
|
||||
it "is triggered when the auto-updater sends the update-downloaded event", ->
|
||||
describe "when an update becomes available", ->
|
||||
subscription = null
|
||||
|
||||
afterEach ->
|
||||
subscription?.dispose()
|
||||
|
||||
it "invokes onUpdateAvailable listeners", ->
|
||||
updateAvailableHandler = jasmine.createSpy("update-available-handler")
|
||||
atom.workspaceView.on 'window:update-available', updateAvailableHandler
|
||||
subscription = atom.onUpdateAvailable updateAvailableHandler
|
||||
|
||||
autoUpdater = require('remote').require('auto-updater')
|
||||
autoUpdater.emit 'update-downloaded', null, "notes", "version"
|
||||
|
||||
@@ -44,11 +47,80 @@ describe "the `atom` global", ->
|
||||
updateAvailableHandler.callCount > 0
|
||||
|
||||
runs ->
|
||||
[event, version, notes] = updateAvailableHandler.mostRecentCall.args
|
||||
expect(notes).toBe 'notes'
|
||||
expect(version).toBe 'version'
|
||||
{releaseVersion, releaseNotes} = updateAvailableHandler.mostRecentCall.args[0]
|
||||
expect(releaseVersion).toBe 'version'
|
||||
expect(releaseNotes).toBe 'notes'
|
||||
|
||||
describe "loading default config", ->
|
||||
it 'loads the default core config', ->
|
||||
expect(atom.config.get('core.excludeVcsIgnoredPaths')).toBe true
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe false
|
||||
|
||||
describe "window onerror handler", ->
|
||||
beforeEach ->
|
||||
spyOn atom, 'openDevTools'
|
||||
spyOn atom, 'executeJavaScriptInDevTools'
|
||||
|
||||
it "will open the dev tools when an error is triggered", ->
|
||||
try
|
||||
a + 1
|
||||
catch e
|
||||
window.onerror.call(window, e.toString(), 'abc', 2, 3, e)
|
||||
|
||||
expect(atom.openDevTools).toHaveBeenCalled()
|
||||
expect(atom.executeJavaScriptInDevTools).toHaveBeenCalled()
|
||||
|
||||
describe "::onWillThrowError", ->
|
||||
willThrowSpy = null
|
||||
beforeEach ->
|
||||
willThrowSpy = jasmine.createSpy()
|
||||
|
||||
it "is called when there is an error", ->
|
||||
error = null
|
||||
atom.onWillThrowError(willThrowSpy)
|
||||
try
|
||||
a + 1
|
||||
catch e
|
||||
error = e
|
||||
window.onerror.call(window, e.toString(), 'abc', 2, 3, e)
|
||||
|
||||
delete willThrowSpy.mostRecentCall.args[0].preventDefault
|
||||
expect(willThrowSpy).toHaveBeenCalledWith
|
||||
message: error.toString()
|
||||
url: 'abc'
|
||||
line: 2
|
||||
column: 3
|
||||
originalError: error
|
||||
|
||||
it "will not show the devtools when preventDefault() is called", ->
|
||||
willThrowSpy.andCallFake (errorObject) -> errorObject.preventDefault()
|
||||
atom.onWillThrowError(willThrowSpy)
|
||||
|
||||
try
|
||||
a + 1
|
||||
catch e
|
||||
window.onerror.call(window, e.toString(), 'abc', 2, 3, e)
|
||||
|
||||
expect(willThrowSpy).toHaveBeenCalled()
|
||||
expect(atom.openDevTools).not.toHaveBeenCalled()
|
||||
expect(atom.executeJavaScriptInDevTools).not.toHaveBeenCalled()
|
||||
|
||||
describe "::onDidThrowError", ->
|
||||
didThrowSpy = null
|
||||
beforeEach ->
|
||||
didThrowSpy = jasmine.createSpy()
|
||||
|
||||
it "is called when there is an error", ->
|
||||
error = null
|
||||
atom.onDidThrowError(didThrowSpy)
|
||||
try
|
||||
a + 1
|
||||
catch e
|
||||
error = e
|
||||
window.onerror.call(window, e.toString(), 'abc', 2, 3, e)
|
||||
expect(didThrowSpy).toHaveBeenCalledWith
|
||||
message: error.toString()
|
||||
url: 'abc'
|
||||
line: 2
|
||||
column: 3
|
||||
originalError: error
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
ChildProcess = require 'child_process'
|
||||
path = require 'path'
|
||||
BufferedProcess = require '../src/buffered-process'
|
||||
|
||||
describe "BufferedProcess", ->
|
||||
describe "when a bad command is specified", ->
|
||||
[oldOnError] = []
|
||||
beforeEach ->
|
||||
oldOnError = window.onerror
|
||||
window.onerror = jasmine.createSpy()
|
||||
|
||||
afterEach ->
|
||||
window.onerror = oldOnError
|
||||
|
||||
describe "when there is an error handler specified", ->
|
||||
it "calls the error handler and does not throw an exception", ->
|
||||
process = new BufferedProcess
|
||||
command: 'bad-command-nope'
|
||||
args: ['nothing']
|
||||
options: {}
|
||||
|
||||
errorSpy = jasmine.createSpy().andCallFake (error) -> error.handle()
|
||||
process.onWillThrowError(errorSpy)
|
||||
|
||||
waitsFor -> errorSpy.callCount > 0
|
||||
|
||||
runs ->
|
||||
expect(window.onerror).not.toHaveBeenCalled()
|
||||
expect(errorSpy).toHaveBeenCalled()
|
||||
expect(errorSpy.mostRecentCall.args[0].error.message).toContain 'spawn bad-command-nope ENOENT'
|
||||
|
||||
describe "when there is not an error handler specified", ->
|
||||
it "calls the error handler and does not throw an exception", ->
|
||||
process = new BufferedProcess
|
||||
command: 'bad-command-nope'
|
||||
args: ['nothing']
|
||||
options: {}
|
||||
|
||||
waitsFor -> window.onerror.callCount > 0
|
||||
|
||||
runs ->
|
||||
expect(window.onerror).toHaveBeenCalled()
|
||||
expect(window.onerror.mostRecentCall.args[0]).toContain 'Failed to spawn command `bad-command-nope`'
|
||||
expect(window.onerror.mostRecentCall.args[4].name).toBe 'BufferedProcessError'
|
||||
|
||||
describe "on Windows", ->
|
||||
originalPlatform = null
|
||||
|
||||
beforeEach ->
|
||||
# Prevent any commands from actually running and affecting the host
|
||||
originalSpawn = ChildProcess.spawn
|
||||
spyOn(ChildProcess, 'spawn').andCallFake ->
|
||||
# Just spawn something that won't actually modify the host
|
||||
if originalPlatform is 'win32'
|
||||
originalSpawn('dir')
|
||||
else
|
||||
originalSpawn('ls')
|
||||
|
||||
originalPlatform = process.platform
|
||||
Object.defineProperty process, 'platform', value: 'win32'
|
||||
|
||||
afterEach ->
|
||||
Object.defineProperty process, 'platform', value: originalPlatform
|
||||
|
||||
describe "when the explorer command is spawned on Windows", ->
|
||||
it "doesn't quote arguments of the form /root,C...", ->
|
||||
new BufferedProcess({command: 'explorer.exe', args: ['/root,C:\\foo']})
|
||||
expect(ChildProcess.spawn.argsForCall[0][1][2]).toBe '"explorer.exe /root,C:\\foo"'
|
||||
|
||||
it "spawns the command using a cmd.exe wrapper", ->
|
||||
new BufferedProcess({command: 'dir'})
|
||||
expect(path.basename(ChildProcess.spawn.argsForCall[0][0])).toBe 'cmd.exe'
|
||||
expect(ChildProcess.spawn.argsForCall[0][1][0]).toBe '/s'
|
||||
expect(ChildProcess.spawn.argsForCall[0][1][1]).toBe '/c'
|
||||
expect(ChildProcess.spawn.argsForCall[0][1][2]).toBe '"dir"'
|
||||
+399
-161
@@ -2,9 +2,9 @@ path = require 'path'
|
||||
temp = require 'temp'
|
||||
CSON = require 'season'
|
||||
fs = require 'fs-plus'
|
||||
Grim = require 'grim'
|
||||
|
||||
describe "Config", ->
|
||||
dotAtomPath = path.join(temp.dir, 'dot-atom-dir')
|
||||
dotAtomPath = null
|
||||
|
||||
beforeEach ->
|
||||
@@ -35,6 +35,36 @@ describe "Config", ->
|
||||
atom.config.setDefaults("bar", baz: 7)
|
||||
expect(atom.config.get("bar.baz")).toEqual {a: 3}
|
||||
|
||||
describe "when a 'sources' option is specified", ->
|
||||
it "only retrieves values from the specified sources", ->
|
||||
atom.config.set("x.y", 1, scopeSelector: ".foo", source: "a")
|
||||
atom.config.set("x.y", 2, scopeSelector: ".foo", source: "b")
|
||||
atom.config.set("x.y", 3, scopeSelector: ".foo", source: "c")
|
||||
atom.config.setSchema("x.y", type: "integer", default: 4)
|
||||
|
||||
expect(atom.config.get("x.y", sources: ["a"], scope: [".foo"])).toBe 1
|
||||
expect(atom.config.get("x.y", sources: ["b"], scope: [".foo"])).toBe 2
|
||||
expect(atom.config.get("x.y", sources: ["c"], scope: [".foo"])).toBe 3
|
||||
# Schema defaults never match a specific source. We could potentially add a special "schema" source.
|
||||
expect(atom.config.get("x.y", sources: ["x"], scope: [".foo"])).toBeUndefined()
|
||||
|
||||
expect(atom.config.get(null, sources: ['a'], scope: [".foo"]).x.y).toBe 1
|
||||
|
||||
describe "when an 'excludeSources' option is specified", ->
|
||||
it "only retrieves values from the specified sources", ->
|
||||
atom.config.set("x.y", 0)
|
||||
atom.config.set("x.y", 1, scopeSelector: ".foo", source: "a")
|
||||
atom.config.set("x.y", 2, scopeSelector: ".foo", source: "b")
|
||||
atom.config.set("x.y", 3, scopeSelector: ".foo", source: "c")
|
||||
atom.config.setSchema("x.y", type: "integer", default: 4)
|
||||
|
||||
expect(atom.config.get("x.y", excludeSources: ["a"], scope: [".foo"])).toBe 3
|
||||
expect(atom.config.get("x.y", excludeSources: ["c"], scope: [".foo"])).toBe 2
|
||||
expect(atom.config.get("x.y", excludeSources: ["b", "c"], scope: [".foo"])).toBe 1
|
||||
expect(atom.config.get("x.y", excludeSources: ["b", "c", "a"], scope: [".foo"])).toBe 0
|
||||
expect(atom.config.get("x.y", excludeSources: ["b", "c", "a", atom.config.getUserConfigPath()], scope: [".foo"])).toBe 4
|
||||
expect(atom.config.get("x.y", excludeSources: [atom.config.getUserConfigPath()])).toBe 4
|
||||
|
||||
describe ".set(keyPath, value)", ->
|
||||
it "allows a key path's value to be written", ->
|
||||
expect(atom.config.set("foo.bar.baz", 42)).toBe true
|
||||
@@ -51,7 +81,7 @@ describe "Config", ->
|
||||
expect(observeHandler).toHaveBeenCalledWith 42
|
||||
|
||||
describe "when the value equals the default value", ->
|
||||
it "does not store the value", ->
|
||||
it "does not store the value in the user's config", ->
|
||||
atom.config.setDefaults "foo",
|
||||
same: 1
|
||||
changes: 1
|
||||
@@ -67,60 +97,84 @@ describe "Config", ->
|
||||
atom.config.set('foo.null', undefined)
|
||||
atom.config.set('foo.undefined', null)
|
||||
atom.config.set('foo.sameObject', {b: 2, a: 1})
|
||||
expect(atom.config.settings.foo).toEqual {changes: 2}
|
||||
|
||||
expect(atom.config.get("foo.same", sources: [atom.config.getUserConfigPath()])).toBeUndefined()
|
||||
|
||||
expect(atom.config.get("foo.changes", sources: [atom.config.getUserConfigPath()])).toBe 2
|
||||
atom.config.set('foo.changes', 1)
|
||||
expect(atom.config.settings.foo).toEqual {}
|
||||
expect(atom.config.get("foo.changes", sources: [atom.config.getUserConfigPath()])).toBeUndefined()
|
||||
|
||||
describe ".getDefault(keyPath)", ->
|
||||
it "returns a clone of the default value", ->
|
||||
atom.config.setDefaults("foo", same: 1, changes: 1)
|
||||
|
||||
spyOn(Grim, 'deprecate')
|
||||
expect(atom.config.getDefault('foo.same')).toBe 1
|
||||
expect(atom.config.getDefault('foo.changes')).toBe 1
|
||||
expect(Grim.deprecate.callCount).toBe 2
|
||||
|
||||
atom.config.set('foo.same', 2)
|
||||
atom.config.set('foo.changes', 3)
|
||||
|
||||
expect(atom.config.getDefault('foo.same')).toBe 1
|
||||
expect(atom.config.getDefault('foo.changes')).toBe 1
|
||||
expect(Grim.deprecate.callCount).toBe 4
|
||||
|
||||
initialDefaultValue = [1, 2, 3]
|
||||
atom.config.setDefaults("foo", bar: initialDefaultValue)
|
||||
expect(atom.config.getDefault('foo.bar')).toEqual initialDefaultValue
|
||||
expect(atom.config.getDefault('foo.bar')).not.toBe initialDefaultValue
|
||||
expect(Grim.deprecate.callCount).toBe 6
|
||||
|
||||
describe "when scoped settings are used", ->
|
||||
it "returns the global default when no scoped default set", ->
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
expect(atom.config.getDefault('.source.coffee', 'foo.bar.baz')).toBe 10
|
||||
|
||||
it "returns the scoped default when a scoped default is set", ->
|
||||
spyOn(Grim, 'deprecate')
|
||||
expect(atom.config.getDefault('.source.coffee', 'foo.bar.baz')).toBe 10
|
||||
expect(Grim.deprecate).toHaveBeenCalled()
|
||||
|
||||
it "returns the scoped settings not including the user's config file", ->
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
atom.config.addScopedSettings("default", ".source.coffee", foo: bar: baz: 42)
|
||||
expect(atom.config.getDefault('.source.coffee', 'foo.bar.baz')).toBe 42
|
||||
|
||||
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
|
||||
spyOn(Grim, 'deprecate')
|
||||
expect(atom.config.getDefault('.source.coffee', 'foo.bar.baz')).toBe 42
|
||||
expect(Grim.deprecate.callCount).toBe 1
|
||||
|
||||
atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee')
|
||||
expect(atom.config.getDefault('.source.coffee', 'foo.bar.baz')).toBe 42
|
||||
expect(Grim.deprecate.callCount).toBe 2
|
||||
|
||||
describe ".isDefault(keyPath)", ->
|
||||
it "returns true when the value of the key path is its default value", ->
|
||||
atom.config.setDefaults("foo", same: 1, changes: 1)
|
||||
|
||||
spyOn(Grim, 'deprecate')
|
||||
expect(atom.config.isDefault('foo.same')).toBe true
|
||||
expect(atom.config.isDefault('foo.changes')).toBe true
|
||||
expect(Grim.deprecate.callCount).toBe 2
|
||||
|
||||
atom.config.set('foo.same', 2)
|
||||
atom.config.set('foo.same', 1)
|
||||
atom.config.set('foo.changes', 3)
|
||||
expect(atom.config.isDefault('foo.same')).toBe false
|
||||
|
||||
expect(atom.config.isDefault('foo.same')).toBe true
|
||||
expect(atom.config.isDefault('foo.changes')).toBe false
|
||||
expect(Grim.deprecate.callCount).toBe 4
|
||||
|
||||
describe "when scoped settings are used", ->
|
||||
it "returns false when a scoped setting was set by the user", ->
|
||||
spyOn(Grim, 'deprecate')
|
||||
expect(atom.config.isDefault('.source.coffee', 'foo.bar.baz')).toBe true
|
||||
expect(Grim.deprecate.callCount).toBe 1
|
||||
|
||||
atom.config.addScopedSettings("default", ".source.coffee", foo: bar: baz: 42)
|
||||
expect(atom.config.isDefault('.source.coffee', 'foo.bar.baz')).toBe true
|
||||
expect(Grim.deprecate.callCount).toBe 2
|
||||
|
||||
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
|
||||
atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee')
|
||||
expect(atom.config.isDefault('.source.coffee', 'foo.bar.baz')).toBe false
|
||||
expect(Grim.deprecate.callCount).toBe 3
|
||||
|
||||
describe ".setDefaults(keyPath)", ->
|
||||
it "sets a default when the setting's key contains an escaped dot", ->
|
||||
@@ -128,6 +182,12 @@ describe "Config", ->
|
||||
expect(atom.config.get("foo")).toEqual 'a\\.b': 1, b: 2
|
||||
|
||||
describe ".toggle(keyPath)", ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "negates the boolean value of the current key path value", ->
|
||||
atom.config.set('foo.a', 1)
|
||||
atom.config.toggle('foo.a')
|
||||
@@ -145,17 +205,17 @@ describe "Config", ->
|
||||
atom.config.toggle('foo.a')
|
||||
expect(atom.config.get('foo.a')).toBe false
|
||||
|
||||
describe ".restoreDefault(keyPath)", ->
|
||||
describe ".unset(keyPath, {scope})", ->
|
||||
it "sets the value of the key path to its default", ->
|
||||
atom.config.setDefaults('a', b: 3)
|
||||
atom.config.set('a.b', 4)
|
||||
expect(atom.config.get('a.b')).toBe 4
|
||||
atom.config.restoreDefault('a.b')
|
||||
atom.config.unset('a.b')
|
||||
expect(atom.config.get('a.b')).toBe 3
|
||||
|
||||
atom.config.set('a.c', 5)
|
||||
expect(atom.config.get('a.c')).toBe 5
|
||||
atom.config.restoreDefault('a.c')
|
||||
atom.config.unset('a.c')
|
||||
expect(atom.config.get('a.c')).toBeUndefined()
|
||||
|
||||
it "calls ::save()", ->
|
||||
@@ -163,60 +223,123 @@ describe "Config", ->
|
||||
atom.config.set('a.b', 4)
|
||||
atom.config.save.reset()
|
||||
|
||||
atom.config.restoreDefault('a.c')
|
||||
atom.config.unset('a.c')
|
||||
expect(atom.config.save.callCount).toBe 1
|
||||
|
||||
describe "when scoped settings are used", ->
|
||||
it "restores the global default when no scoped default set", ->
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
|
||||
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 55
|
||||
atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee')
|
||||
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 55
|
||||
|
||||
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
|
||||
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 10
|
||||
atom.config.unset('foo.bar.baz', scopeSelector: '.source.coffee')
|
||||
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 10
|
||||
|
||||
it "restores the scoped default when a scoped default is set", ->
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
atom.config.addScopedSettings("default", ".source.coffee", foo: bar: baz: 42)
|
||||
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
|
||||
atom.config.set('.source.coffee', 'foo.bar.ok', 100)
|
||||
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 55
|
||||
atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee')
|
||||
atom.config.set('foo.bar.ok', 100, scopeSelector: '.source.coffee')
|
||||
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 55
|
||||
|
||||
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
|
||||
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 42
|
||||
expect(atom.config.get(['.source.coffee'], 'foo.bar.ok')).toBe 100
|
||||
atom.config.unset('foo.bar.baz', scopeSelector: '.source.coffee')
|
||||
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 42
|
||||
expect(atom.config.get('foo.bar.ok', scope: ['.source.coffee'])).toBe 100
|
||||
|
||||
it "calls ::save()", ->
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
atom.config.addScopedSettings("default", ".source.coffee", foo: bar: baz: 42)
|
||||
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
|
||||
atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee')
|
||||
atom.config.save.reset()
|
||||
|
||||
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
|
||||
atom.config.unset('foo.bar.baz', scopeSelector: '.source.coffee')
|
||||
expect(atom.config.save.callCount).toBe 1
|
||||
|
||||
it "allows removing settings for a specific source and scope selector", ->
|
||||
atom.config.set('foo.bar', 55, scopeSelector: '.source.coffee', source: "source-a")
|
||||
atom.config.set('foo.bar', 65, scopeSelector: '.source.coffee', source: "source-b")
|
||||
expect(atom.config.get('foo.bar', scope: ['.source.coffee'])).toBe 65
|
||||
|
||||
atom.config.unset('foo.bar', source: "source-b", scopeSelector: ".source.coffee")
|
||||
expect(atom.config.get('foo.bar', scope: ['.source.coffee', '.string'])).toBe 55
|
||||
|
||||
it "allows removing all settings for a specific source", ->
|
||||
atom.config.set('foo.bar', 55, scopeSelector: '.source.coffee', source: "source-a")
|
||||
atom.config.set('foo.bar', 65, scopeSelector: '.source.coffee', source: "source-b")
|
||||
atom.config.set('foo.baz', 65, scopeSelector: '.source.coffee', source: "source-b")
|
||||
expect(atom.config.get('foo.bar', scope: ['.source.coffee'])).toBe 65
|
||||
|
||||
atom.config.unset(null, source: "source-b", scopeSelector: ".source.coffee")
|
||||
expect(atom.config.get('foo.bar', scope: ['.source.coffee', '.string'])).toBe 55
|
||||
expect(atom.config.get('foo.baz', scope: ['.source.coffee', '.string'])).toBe undefined
|
||||
|
||||
it "does not call ::save or add a scoped property when no value has been set", ->
|
||||
# see https://github.com/atom/atom/issues/4175
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
atom.config.unset('foo.bar.baz', scopeSelector: '.source.coffee')
|
||||
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 10
|
||||
|
||||
expect(atom.config.save).not.toHaveBeenCalled()
|
||||
|
||||
scopedProperties = atom.config.scopedSettingsStore.propertiesForSource('user-config')
|
||||
expect(scopedProperties['.coffee.source']).toBeUndefined()
|
||||
|
||||
it "removes the scoped value when it was the only set value on the object", ->
|
||||
spyOn(CSON, 'writeFileSync')
|
||||
jasmine.unspy atom.config, 'save'
|
||||
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee')
|
||||
atom.config.set('foo.bar.zfoo', 20, scopeSelector: '.source.coffee')
|
||||
CSON.writeFileSync.reset()
|
||||
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 55
|
||||
|
||||
atom.config.unset('foo.bar.baz', scopeSelector: '.source.coffee')
|
||||
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 10
|
||||
expect(atom.config.get('foo.bar.zfoo', scope: ['.source.coffee'])).toBe 20
|
||||
expect(CSON.writeFileSync).toHaveBeenCalled()
|
||||
properties = CSON.writeFileSync.mostRecentCall.args[1]
|
||||
expect(properties['.coffee.source']).toEqual
|
||||
foo:
|
||||
bar:
|
||||
zfoo: 20
|
||||
|
||||
CSON.writeFileSync.reset()
|
||||
atom.config.unset('foo.bar.zfoo', scopeSelector: '.source.coffee')
|
||||
expect(CSON.writeFileSync).toHaveBeenCalled()
|
||||
properties = CSON.writeFileSync.mostRecentCall.args[1]
|
||||
expect(properties['.coffee.source']).toBeUndefined()
|
||||
|
||||
it "does not call ::save when the value is already at the default", ->
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
atom.config.set('foo.bar.baz', 55)
|
||||
atom.config.save.reset()
|
||||
|
||||
atom.config.unset('foo.bar.ok', scopeSelector: '.source.coffee')
|
||||
expect(atom.config.save).not.toHaveBeenCalled()
|
||||
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 55
|
||||
|
||||
it "deprecates passing a scope selector as the first argument", ->
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee')
|
||||
|
||||
spyOn(Grim, 'deprecate')
|
||||
atom.config.unset('.source.coffee', 'foo.bar.baz')
|
||||
expect(Grim.deprecate).toHaveBeenCalled()
|
||||
|
||||
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 10
|
||||
|
||||
describe ".getSettings()", ->
|
||||
it "returns all settings including defaults", ->
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
atom.config.set("foo.ok", 12)
|
||||
|
||||
jasmine.snapshotDeprecations()
|
||||
expect(atom.config.getSettings().foo).toEqual
|
||||
ok: 12
|
||||
bar:
|
||||
baz: 10
|
||||
|
||||
describe "when scoped settings are used", ->
|
||||
it "returns all the scoped settings including all the defaults", ->
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
atom.config.set("foo.ok", 12)
|
||||
atom.config.addScopedSettings("default", ".source.coffee", foo: bar: baz: 42)
|
||||
atom.config.addScopedSettings("default", ".source.coffee", foo: bar: omg: 'omg')
|
||||
|
||||
expect(atom.config.getSettings(".source.coffee").foo).toEqual
|
||||
ok: 12
|
||||
bar:
|
||||
baz: 42
|
||||
omg: 'omg'
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
describe ".pushAtKeyPath(keyPath, value)", ->
|
||||
it "pushes the given value to the array at the key path and updates observers", ->
|
||||
@@ -252,6 +375,12 @@ describe "Config", ->
|
||||
expect(observeHandler).toHaveBeenCalledWith atom.config.get("foo.bar.baz")
|
||||
|
||||
describe ".getPositiveInt(keyPath, defaultValue)", ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "returns the proper coerced value", ->
|
||||
atom.config.set('editor.preferredLineLength', 0)
|
||||
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 1
|
||||
@@ -275,56 +404,37 @@ describe "Config", ->
|
||||
spyOn(CSON, 'writeFileSync')
|
||||
jasmine.unspy atom.config, 'save'
|
||||
|
||||
describe "when ~/.atom/config.json exists", ->
|
||||
it "writes any non-default properties to ~/.atom/config.json", ->
|
||||
atom.config.configFilePath = path.join(atom.config.configDirPath, "atom.config.json")
|
||||
atom.config.set("a.b.c", 1)
|
||||
atom.config.set("a.b.d", 2)
|
||||
atom.config.set("x.y.z", 3)
|
||||
atom.config.setDefaults("a.b", e: 4, f: 5)
|
||||
it "writes properties from the user config path source to the user config path", ->
|
||||
atom.config.configFilePath = "/fake/config/path"
|
||||
atom.config.set("a.b.c", 1)
|
||||
atom.config.set("a.b.d", 2)
|
||||
atom.config.set("x.y.z", 3)
|
||||
atom.config.set("x.y.q", 3, source: "/not/user/config")
|
||||
atom.config.set('foo.bar', 'ruby', scopeSelector: '.source.ruby')
|
||||
atom.config.set('foo.omg', 'wow', scopeSelector: '.source.ruby')
|
||||
atom.config.set('foo.bar', 'coffee', scopeSelector: '.source.coffee')
|
||||
|
||||
CSON.writeFileSync.reset()
|
||||
atom.config.save()
|
||||
atom.config.setDefaults("a.b", e: 4, f: 5)
|
||||
|
||||
expect(CSON.writeFileSync.argsForCall[0][0]).toBe(path.join(atom.config.configDirPath, "atom.config.json"))
|
||||
writtenConfig = CSON.writeFileSync.argsForCall[0][1]
|
||||
expect(writtenConfig).toEqual global: atom.config.settings
|
||||
CSON.writeFileSync.reset()
|
||||
atom.config.save()
|
||||
|
||||
describe "when ~/.atom/config.json doesn't exist", ->
|
||||
it "writes any non-default properties to ~/.atom/config.cson", ->
|
||||
atom.config.configFilePath = path.join(atom.config.configDirPath, "atom.config.cson")
|
||||
atom.config.set("a.b.c", 1)
|
||||
atom.config.set("a.b.d", 2)
|
||||
atom.config.set("x.y.z", 3)
|
||||
atom.config.setDefaults("a.b", e: 4, f: 5)
|
||||
|
||||
CSON.writeFileSync.reset()
|
||||
atom.config.save()
|
||||
|
||||
expect(CSON.writeFileSync.argsForCall[0][0]).toBe(path.join(atom.config.configDirPath, "atom.config.cson"))
|
||||
writtenConfig = CSON.writeFileSync.argsForCall[0][1]
|
||||
expect(writtenConfig).toEqual global: atom.config.settings
|
||||
|
||||
describe "when scoped settings are defined", ->
|
||||
it 'writes out explicitly set config settings', ->
|
||||
atom.config.set('.source.ruby', 'foo.bar', 'ruby')
|
||||
atom.config.set('.source.ruby', 'foo.omg', 'wow')
|
||||
atom.config.set('.source.coffee', 'foo.bar', 'coffee')
|
||||
|
||||
CSON.writeFileSync.reset()
|
||||
atom.config.save()
|
||||
|
||||
writtenConfig = CSON.writeFileSync.argsForCall[0][1]
|
||||
expect(writtenConfig).toEqualJson
|
||||
global:
|
||||
atom.config.settings
|
||||
'.ruby.source':
|
||||
foo:
|
||||
bar: 'ruby'
|
||||
omg: 'wow'
|
||||
'.coffee.source':
|
||||
foo:
|
||||
bar: 'coffee'
|
||||
expect(CSON.writeFileSync.argsForCall[0][0]).toBe atom.config.getUserConfigPath()
|
||||
writtenConfig = CSON.writeFileSync.argsForCall[0][1]
|
||||
global.debug = true
|
||||
expect(writtenConfig).toEqual
|
||||
'global':
|
||||
a: b:
|
||||
c: 1
|
||||
d: 2
|
||||
x: y: z: 3
|
||||
'.ruby.source':
|
||||
foo:
|
||||
bar: 'ruby'
|
||||
omg: 'wow'
|
||||
'.coffee.source':
|
||||
foo:
|
||||
bar: 'coffee'
|
||||
|
||||
describe ".setDefaults(keyPath, defaults)", ->
|
||||
it "assigns any previously-unassigned keys to the object at the key path", ->
|
||||
@@ -360,17 +470,26 @@ describe "Config", ->
|
||||
it "fires the callback every time the observed value changes", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
atom.config.set('foo.bar.baz', "value 2")
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 2', oldValue: 'value 1', keyPath: 'foo.bar.baz'})
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 2', oldValue: 'value 1'})
|
||||
observeHandler.reset()
|
||||
|
||||
atom.config.set('foo.bar.baz', "value 1")
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 1', oldValue: 'value 2', keyPath: 'foo.bar.baz'})
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 1', oldValue: 'value 2'})
|
||||
observeHandler.reset()
|
||||
|
||||
atom.config.set('foo.bar', {baz: "value 3"})
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 3', oldValue: 'value 1'})
|
||||
observeHandler.reset()
|
||||
|
||||
atom.config.set('foo.bar', null)
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: undefined, oldValue: 'value 3'})
|
||||
observeHandler.reset()
|
||||
|
||||
describe 'when a keyPath is not specified', ->
|
||||
beforeEach ->
|
||||
observeHandler = jasmine.createSpy("observeHandler")
|
||||
atom.config.set("foo.bar.baz", "value 1")
|
||||
observeSubscription = atom.config.onDidChange observeHandler
|
||||
atom.config.set("foo", bar: baz: "value 1")
|
||||
observeSubscription = atom.config.onDidChange(observeHandler)
|
||||
|
||||
it "does not fire the given callback initially", ->
|
||||
expect(observeHandler).not.toHaveBeenCalled()
|
||||
@@ -378,15 +497,22 @@ describe "Config", ->
|
||||
it "fires the callback every time any value changes", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
atom.config.set('foo.bar.baz', "value 2")
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 2', oldValue: 'value 1', keyPath: 'foo.bar.baz'})
|
||||
|
||||
expect(observeHandler).toHaveBeenCalled()
|
||||
expect(observeHandler.mostRecentCall.args[0].newValue.foo.bar.baz).toBe("value 2")
|
||||
expect(observeHandler.mostRecentCall.args[0].oldValue.foo.bar.baz).toBe("value 1")
|
||||
|
||||
observeHandler.reset()
|
||||
atom.config.set('foo.bar.baz', "value 1")
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 1', oldValue: 'value 2', keyPath: 'foo.bar.baz'})
|
||||
expect(observeHandler).toHaveBeenCalled()
|
||||
expect(observeHandler.mostRecentCall.args[0].newValue.foo.bar.baz).toBe("value 1")
|
||||
expect(observeHandler.mostRecentCall.args[0].oldValue.foo.bar.baz).toBe("value 2")
|
||||
|
||||
observeHandler.reset()
|
||||
atom.config.set('foo.bar.int', 1)
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 1, oldValue: undefined, keyPath: 'foo.bar.int'})
|
||||
expect(observeHandler).toHaveBeenCalled()
|
||||
expect(observeHandler.mostRecentCall.args[0].newValue.foo.bar.int).toBe(1)
|
||||
expect(observeHandler.mostRecentCall.args[0].oldValue.foo.bar.int).toBe(undefined)
|
||||
|
||||
describe ".observe(keyPath)", ->
|
||||
[observeHandler, observeSubscription] = []
|
||||
@@ -394,7 +520,7 @@ describe "Config", ->
|
||||
beforeEach ->
|
||||
observeHandler = jasmine.createSpy("observeHandler")
|
||||
atom.config.set("foo.bar.baz", "value 1")
|
||||
observeSubscription = atom.config.observe "foo.bar.baz", observeHandler
|
||||
observeSubscription = atom.config.observe("foo.bar.baz", observeHandler)
|
||||
|
||||
it "fires the given callback with the current value at the keypath", ->
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 1")
|
||||
@@ -407,6 +533,25 @@ describe "Config", ->
|
||||
|
||||
atom.config.set('foo.bar.baz', "value 1")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 1")
|
||||
observeHandler.reset()
|
||||
|
||||
atom.config.set('foo.bar', {baz: "value 3"})
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 3")
|
||||
observeHandler.reset()
|
||||
|
||||
atom.config.set('foo.bar', null)
|
||||
expect(observeHandler).toHaveBeenCalledWith(undefined)
|
||||
observeHandler.reset()
|
||||
|
||||
atom.config.set('foo.bar.baz.quux', "value 4")
|
||||
expect(observeHandler).toHaveBeenCalledWith({quux: "value 4"})
|
||||
|
||||
atom.config.set('foo.bar.baz.buzz', "value 5")
|
||||
expect(observeHandler).toHaveBeenCalledWith({quux: "value 4", buzz: "value 5"})
|
||||
|
||||
observeHandler.reset()
|
||||
atom.config.loadUserConfig()
|
||||
expect(observeHandler).toHaveBeenCalledWith(undefined)
|
||||
|
||||
it "fires the callback when the observed value is deleted", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
@@ -424,7 +569,7 @@ describe "Config", ->
|
||||
|
||||
it "does not fire the callback once the observe subscription is off'ed", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
observeSubscription.off()
|
||||
observeSubscription.dispose()
|
||||
atom.config.set('foo.bar.baz', "value 2")
|
||||
expect(observeHandler).not.toHaveBeenCalled()
|
||||
|
||||
@@ -436,6 +581,51 @@ describe "Config", ->
|
||||
atom.config.set('foo.bar.baz', "value 10")
|
||||
expect(bazCatHandler).not.toHaveBeenCalled()
|
||||
|
||||
describe "observing scoped settings", ->
|
||||
otherHandler = null
|
||||
|
||||
beforeEach ->
|
||||
observeSubscription.dispose()
|
||||
otherHandler = jasmine.createSpy('otherHandler')
|
||||
|
||||
it "allows settings to be observed in a specific scope", ->
|
||||
atom.config.observe("foo.bar.baz", scope: [".some.scope"], observeHandler)
|
||||
atom.config.observe("foo.bar.baz", scope: [".another.scope"], otherHandler)
|
||||
|
||||
atom.config.set('foo.bar.baz', "value 2", scopeSelector: ".some")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 2")
|
||||
expect(otherHandler).not.toHaveBeenCalledWith("value 2")
|
||||
|
||||
it "deprecates using a scope descriptor as the first argument", ->
|
||||
spyOn(Grim, 'deprecate')
|
||||
atom.config.observe([".some.scope"], "foo.bar.baz", observeHandler)
|
||||
atom.config.observe([".another.scope"], "foo.bar.baz", otherHandler)
|
||||
expect(Grim.deprecate).toHaveBeenCalled()
|
||||
|
||||
atom.config.set('foo.bar.baz', "value 2", scopeSelector: ".some")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 2")
|
||||
expect(otherHandler).not.toHaveBeenCalledWith("value 2")
|
||||
|
||||
describe ".transact(callback)", ->
|
||||
changeSpy = null
|
||||
|
||||
beforeEach ->
|
||||
changeSpy = jasmine.createSpy('onDidChange callback')
|
||||
atom.config.onDidChange("foo.bar.baz", changeSpy)
|
||||
|
||||
it "allows only one change event for the duration of the given callback", ->
|
||||
atom.config.transact ->
|
||||
atom.config.set("foo.bar.baz", 1)
|
||||
atom.config.set("foo.bar.baz", 2)
|
||||
atom.config.set("foo.bar.baz", 3)
|
||||
|
||||
expect(changeSpy.callCount).toBe(1)
|
||||
expect(changeSpy.argsForCall[0][0]).toEqual(newValue: 3, oldValue: undefined)
|
||||
|
||||
it "does not emit an event if no changes occur while paused", ->
|
||||
atom.config.transact ->
|
||||
expect(changeSpy).not.toHaveBeenCalled()
|
||||
|
||||
describe ".initializeConfigDirectory()", ->
|
||||
beforeEach ->
|
||||
if fs.existsSync(dotAtomPath)
|
||||
@@ -468,6 +658,15 @@ describe "Config", ->
|
||||
atom.config.configDirPath = dotAtomPath
|
||||
atom.config.configFilePath = path.join(atom.config.configDirPath, "atom.config.cson")
|
||||
expect(fs.existsSync(atom.config.configDirPath)).toBeFalsy()
|
||||
atom.config.setSchema 'foo',
|
||||
type: 'object'
|
||||
properties:
|
||||
bar:
|
||||
type: 'string'
|
||||
default: 'def'
|
||||
int:
|
||||
type: 'integer'
|
||||
default: 12
|
||||
|
||||
afterEach ->
|
||||
fs.removeSync(dotAtomPath)
|
||||
@@ -487,7 +686,7 @@ describe "Config", ->
|
||||
|
||||
it "updates the config data based on the file contents", ->
|
||||
expect(atom.config.get("foo.bar")).toBe 'baz'
|
||||
expect(atom.config.get(['.source.ruby'], "foo.bar")).toBe 'more-specific'
|
||||
expect(atom.config.get("foo.bar", scope: ['.source.ruby'])).toBe 'more-specific'
|
||||
|
||||
describe "when the config file contains valid cson", ->
|
||||
beforeEach ->
|
||||
@@ -508,11 +707,13 @@ describe "Config", ->
|
||||
describe "when the config file contains invalid cson", ->
|
||||
beforeEach ->
|
||||
spyOn(console, 'error')
|
||||
spyOn(atom.notifications, 'addError')
|
||||
fs.writeFileSync(atom.config.configFilePath, "{{{{{")
|
||||
|
||||
it "logs an error to the console and does not overwrite the config file on a subsequent save", ->
|
||||
atom.config.loadUserConfig()
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
expect(atom.notifications.addError.callCount).toBe 1
|
||||
atom.config.set("hair", "blonde") # trigger a save
|
||||
expect(atom.config.save).not.toHaveBeenCalled()
|
||||
|
||||
@@ -523,43 +724,42 @@ describe "Config", ->
|
||||
expect(fs.existsSync(atom.config.configFilePath)).toBe true
|
||||
expect(CSON.readFileSync(atom.config.configFilePath)).toEqual {}
|
||||
|
||||
describe "when a schema is specified", ->
|
||||
describe "when the config file contains values that do not adhere to the schema", ->
|
||||
warnSpy = null
|
||||
beforeEach ->
|
||||
schema =
|
||||
type: 'object'
|
||||
properties:
|
||||
bar:
|
||||
type: 'string'
|
||||
default: 'def'
|
||||
int:
|
||||
type: 'integer'
|
||||
default: 12
|
||||
warnSpy = spyOn console, 'warn'
|
||||
fs.writeFileSync atom.config.configFilePath, """
|
||||
foo:
|
||||
bar: 'baz'
|
||||
int: 'bad value'
|
||||
"""
|
||||
atom.config.loadUserConfig()
|
||||
|
||||
atom.config.setSchema('foo', schema)
|
||||
it "updates the only the settings that have values matching the schema", ->
|
||||
expect(atom.config.get("foo.bar")).toBe 'baz'
|
||||
expect(atom.config.get("foo.int")).toBe 12
|
||||
|
||||
describe "when the config file contains values that do not adhere to the schema", ->
|
||||
warnSpy = null
|
||||
beforeEach ->
|
||||
warnSpy = spyOn console, 'warn'
|
||||
fs.writeFileSync atom.config.configFilePath, """
|
||||
foo:
|
||||
bar: 'baz'
|
||||
int: 'bad value'
|
||||
"""
|
||||
atom.config.loadUserConfig()
|
||||
|
||||
it "updates the only the settings that have values matching the schema", ->
|
||||
expect(atom.config.get("foo.bar")).toBe 'baz'
|
||||
expect(atom.config.get("foo.int")).toBe 12
|
||||
|
||||
expect(warnSpy).toHaveBeenCalled()
|
||||
expect(warnSpy.mostRecentCall.args[0]).toContain "'foo.int' could not be set"
|
||||
expect(warnSpy).toHaveBeenCalled()
|
||||
expect(warnSpy.mostRecentCall.args[0]).toContain "foo.int"
|
||||
|
||||
describe ".observeUserConfig()", ->
|
||||
updatedHandler = null
|
||||
|
||||
beforeEach ->
|
||||
atom.config.setDefaults('foo', bar: 'def')
|
||||
atom.config.setSchema 'foo',
|
||||
type: 'object'
|
||||
properties:
|
||||
bar:
|
||||
type: 'string'
|
||||
default: 'def'
|
||||
baz:
|
||||
type: 'string'
|
||||
scoped:
|
||||
type: 'boolean'
|
||||
int:
|
||||
type: 'integer'
|
||||
default: 12
|
||||
|
||||
atom.config.configDirPath = dotAtomPath
|
||||
atom.config.configFilePath = path.join(atom.config.configDirPath, "atom.config.cson")
|
||||
expect(fs.existsSync(atom.config.configDirPath)).toBeFalsy()
|
||||
@@ -592,32 +792,38 @@ describe "Config", ->
|
||||
it "does not fire a change event for paths that did not change", ->
|
||||
atom.config.onDidChange 'foo.bar', noChangeSpy = jasmine.createSpy()
|
||||
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: 'baz', omg: 'ok'}")
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: 'baz', baz: 'ok'}")
|
||||
waitsFor 'update event', -> updatedHandler.callCount > 0
|
||||
runs ->
|
||||
expect(noChangeSpy).not.toHaveBeenCalled()
|
||||
expect(atom.config.get('foo.bar')).toBe 'baz'
|
||||
expect(atom.config.get('foo.omg')).toBe 'ok'
|
||||
expect(atom.config.get('foo.baz')).toBe 'ok'
|
||||
|
||||
describe 'when the default value is a complex value', ->
|
||||
beforeEach ->
|
||||
atom.config.setSchema 'foo.bar',
|
||||
type: 'array'
|
||||
items:
|
||||
type: 'string'
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: ['baz', 'ok']}")
|
||||
waitsFor 'update event', -> updatedHandler.callCount > 0
|
||||
runs -> updatedHandler.reset()
|
||||
|
||||
it "does not fire a change event for paths that did not change", ->
|
||||
atom.config.onDidChange 'foo.bar', noChangeSpy = jasmine.createSpy()
|
||||
noChangeSpy = jasmine.createSpy()
|
||||
atom.config.onDidChange('foo.bar', noChangeSpy)
|
||||
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: ['baz', 'ok'], omg: 'another'}")
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: ['baz', 'ok'], baz: 'another'}")
|
||||
waitsFor 'update event', -> updatedHandler.callCount > 0
|
||||
runs ->
|
||||
expect(noChangeSpy).not.toHaveBeenCalled()
|
||||
expect(atom.config.get('foo.bar')).toEqual ['baz', 'ok']
|
||||
expect(atom.config.get('foo.omg')).toBe 'another'
|
||||
expect(atom.config.get('foo.baz')).toBe 'another'
|
||||
|
||||
describe 'when scoped settings are used', ->
|
||||
it "fires a change event for scoped settings that are removed", ->
|
||||
atom.config.onDidChange ['.source.ruby'], 'foo.scoped', scopedSpy = jasmine.createSpy()
|
||||
scopedSpy = jasmine.createSpy()
|
||||
atom.config.onDidChange('foo.scoped', scope: ['.source.ruby'], scopedSpy)
|
||||
|
||||
fs.writeFileSync atom.config.configFilePath, """
|
||||
global:
|
||||
@@ -627,10 +833,11 @@ describe "Config", ->
|
||||
waitsFor 'update event', -> updatedHandler.callCount > 0
|
||||
runs ->
|
||||
expect(scopedSpy).toHaveBeenCalled()
|
||||
expect(atom.config.get(['.source.ruby'], 'foo.scoped')).toBe false
|
||||
expect(atom.config.get('foo.scoped', scope: ['.source.ruby'])).toBe false
|
||||
|
||||
it "does not fire a change event for paths that did not change", ->
|
||||
atom.config.onDidChange ['.source.ruby'], 'foo.scoped', noChangeSpy = jasmine.createSpy()
|
||||
noChangeSpy = jasmine.createSpy()
|
||||
atom.config.onDidChange('foo.scoped', scope: ['.source.ruby'], noChangeSpy)
|
||||
|
||||
fs.writeFileSync atom.config.configFilePath, """
|
||||
global:
|
||||
@@ -643,9 +850,8 @@ describe "Config", ->
|
||||
waitsFor 'update event', -> updatedHandler.callCount > 0
|
||||
runs ->
|
||||
expect(noChangeSpy).not.toHaveBeenCalled()
|
||||
expect(atom.config.get(['.source.ruby'], 'foo.bar')).toBe 'baz'
|
||||
expect(atom.config.get(['.source.ruby'], 'foo.scoped')).toBe true
|
||||
|
||||
expect(atom.config.get('foo.bar', scope: ['.source.ruby'])).toBe 'baz'
|
||||
expect(atom.config.get('foo.scoped', scope: ['.source.ruby'])).toBe true
|
||||
|
||||
describe "when the config file changes to omit a setting with a default", ->
|
||||
it "resets the setting back to the default", ->
|
||||
@@ -1048,8 +1254,8 @@ describe "Config", ->
|
||||
|
||||
it 'it respects the scoped defaults', ->
|
||||
expect(atom.config.get('foo.bar.str')).toBe 'ok'
|
||||
expect(atom.config.get(['.source.js'], 'foo.bar.str')).toBe 'omg'
|
||||
expect(atom.config.get(['.source.coffee'], 'foo.bar.str')).toBe 'ok'
|
||||
expect(atom.config.get('foo.bar.str', scope: ['.source.js'])).toBe 'omg'
|
||||
expect(atom.config.get('foo.bar.str', scope: ['.source.coffee'])).toBe 'ok'
|
||||
|
||||
describe "scoped settings", ->
|
||||
describe ".get(scopeDescriptor, keyPath)", ->
|
||||
@@ -1058,29 +1264,29 @@ describe "Config", ->
|
||||
atom.config.addScopedSettings("config", ".source .string.quoted.double", foo: bar: baz: 22)
|
||||
atom.config.addScopedSettings("config", ".source", foo: bar: baz: 11)
|
||||
|
||||
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
|
||||
expect(atom.config.get([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBe 22
|
||||
expect(atom.config.get([".source.js", ".variable.assignment.js"], "foo.bar.baz")).toBe 11
|
||||
expect(atom.config.get([".text"], "foo.bar.baz")).toBeUndefined()
|
||||
expect(atom.config.get("foo.bar.baz", scope: [".source.coffee", ".string.quoted.double.coffee"])).toBe 42
|
||||
expect(atom.config.get("foo.bar.baz", scope: [".source.js", ".string.quoted.double.js"])).toBe 22
|
||||
expect(atom.config.get("foo.bar.baz", scope: [".source.js", ".variable.assignment.js"])).toBe 11
|
||||
expect(atom.config.get("foo.bar.baz", scope: [".text"])).toBeUndefined()
|
||||
|
||||
it "favors the most recently added properties in the event of a specificity tie", ->
|
||||
atom.config.addScopedSettings("config", ".source.coffee .string.quoted.single", foo: bar: baz: 42)
|
||||
atom.config.addScopedSettings("config", ".source.coffee .string.quoted.double", foo: bar: baz: 22)
|
||||
|
||||
expect(atom.config.get([".source.coffee", ".string.quoted.single"], "foo.bar.baz")).toBe 42
|
||||
expect(atom.config.get([".source.coffee", ".string.quoted.single.double"], "foo.bar.baz")).toBe 22
|
||||
expect(atom.config.get("foo.bar.baz", scope: [".source.coffee", ".string.quoted.single"])).toBe 42
|
||||
expect(atom.config.get("foo.bar.baz", scope: [".source.coffee", ".string.quoted.single.double"])).toBe 22
|
||||
|
||||
describe 'when there are global defaults', ->
|
||||
it 'falls back to the global when there is no scoped property specified', ->
|
||||
atom.config.setDefaults("foo", hasDefault: 'ok')
|
||||
expect(atom.config.get([".source.coffee", ".string.quoted.single"], "foo.hasDefault")).toBe 'ok'
|
||||
expect(atom.config.get("foo.hasDefault", scope: [".source.coffee", ".string.quoted.single"])).toBe 'ok'
|
||||
|
||||
describe 'setting priority', ->
|
||||
describe 'when package settings are added after user settings', ->
|
||||
it "returns the user's setting because the user's setting has higher priority", ->
|
||||
atom.config.set(".source.coffee", "foo.bar.baz", 100)
|
||||
atom.config.set("foo.bar.baz", 100, scopeSelector: ".source.coffee")
|
||||
atom.config.addScopedSettings("some-package", ".source.coffee", foo: bar: baz: 1)
|
||||
expect(atom.config.get([".source.coffee"], "foo.bar.baz")).toBe 100
|
||||
expect(atom.config.get("foo.bar.baz", scope: [".source.coffee"])).toBe 100
|
||||
|
||||
describe ".set(scope, keyPath, value)", ->
|
||||
it "sets the value and overrides the others", ->
|
||||
@@ -1088,10 +1294,10 @@ describe "Config", ->
|
||||
atom.config.addScopedSettings("config", ".source .string.quoted.double", foo: bar: baz: 22)
|
||||
atom.config.addScopedSettings("config", ".source", foo: bar: baz: 11)
|
||||
|
||||
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
|
||||
expect(atom.config.get("foo.bar.baz", scope: [".source.coffee", ".string.quoted.double.coffee"])).toBe 42
|
||||
|
||||
expect(atom.config.set(".source.coffee .string.quoted.double.coffee", "foo.bar.baz", 100)).toBe true
|
||||
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 100
|
||||
expect(atom.config.set("foo.bar.baz", 100, scopeSelector: ".source.coffee .string.quoted.double.coffee")).toBe true
|
||||
expect(atom.config.get("foo.bar.baz", scope: [".source.coffee", ".string.quoted.double.coffee"])).toBe 100
|
||||
|
||||
describe ".removeScopedSettingsForName(name)", ->
|
||||
it "allows properties to be removed by name", ->
|
||||
@@ -1099,12 +1305,13 @@ describe "Config", ->
|
||||
disposable2 = atom.config.addScopedSettings("b", ".source .string.quoted.double", foo: bar: baz: 22)
|
||||
|
||||
disposable2.dispose()
|
||||
expect(atom.config.get([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBeUndefined()
|
||||
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
|
||||
expect(atom.config.get("foo.bar.baz", scope: [".source.js", ".string.quoted.double.js"])).toBeUndefined()
|
||||
expect(atom.config.get("foo.bar.baz", scope: [".source.coffee", ".string.quoted.double.coffee"])).toBe 42
|
||||
|
||||
describe ".observe(scopeDescriptor, keyPath)", ->
|
||||
it 'calls the supplied callback when the value at the descriptor/keypath changes', ->
|
||||
atom.config.observe [".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz", changeSpy = jasmine.createSpy()
|
||||
changeSpy = jasmine.createSpy()
|
||||
atom.config.observe("foo.bar.baz", scope: [".source.coffee", ".string.quoted.double.coffee"], changeSpy)
|
||||
expect(changeSpy).toHaveBeenCalledWith(undefined)
|
||||
changeSpy.reset()
|
||||
|
||||
@@ -1135,28 +1342,59 @@ describe "Config", ->
|
||||
describe ".onDidChange(scopeDescriptor, keyPath)", ->
|
||||
it 'calls the supplied callback when the value at the descriptor/keypath changes', ->
|
||||
keyPath = "foo.bar.baz"
|
||||
atom.config.onDidChange [".source.coffee", ".string.quoted.double.coffee"], keyPath, changeSpy = jasmine.createSpy()
|
||||
changeSpy = jasmine.createSpy('onDidChange callback')
|
||||
atom.config.onDidChange keyPath, scope: [".source.coffee", ".string.quoted.double.coffee"], changeSpy
|
||||
|
||||
atom.config.set("foo.bar.baz", 12)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: undefined, newValue: 12, keyPath})
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: undefined, newValue: 12})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable1 = atom.config.addScopedSettings("a", ".source .string.quoted.double", foo: bar: baz: 22)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: 22, keyPath})
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: 22})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable2 = atom.config.addScopedSettings("b", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 42, keyPath})
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 42})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable2.dispose()
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 42, newValue: 22, keyPath})
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 42, newValue: 22})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable1.dispose()
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 12, keyPath})
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 12})
|
||||
changeSpy.reset()
|
||||
|
||||
atom.config.set("foo.bar.baz", undefined)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: undefined, keyPath})
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: undefined})
|
||||
changeSpy.reset()
|
||||
|
||||
it 'deprecates using a scope descriptor as an optional first argument', ->
|
||||
keyPath = "foo.bar.baz"
|
||||
spyOn(Grim, 'deprecate')
|
||||
atom.config.onDidChange [".source.coffee", ".string.quoted.double.coffee"], keyPath, changeSpy = jasmine.createSpy()
|
||||
expect(Grim.deprecate).toHaveBeenCalled()
|
||||
|
||||
atom.config.set("foo.bar.baz", 12)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: undefined, newValue: 12})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable1 = atom.config.addScopedSettings("a", ".source .string.quoted.double", foo: bar: baz: 22)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: 22})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable2 = atom.config.addScopedSettings("b", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 42})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable2.dispose()
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 42, newValue: 22})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable1.dispose()
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 12})
|
||||
changeSpy.reset()
|
||||
|
||||
atom.config.set("foo.bar.baz", undefined)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: undefined})
|
||||
changeSpy.reset()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{$$} = require 'atom'
|
||||
{$$} = require '../src/space-pen-extensions'
|
||||
|
||||
ContextMenuManager = require '../src/context-menu-manager'
|
||||
|
||||
@@ -151,24 +151,31 @@ describe "ContextMenuManager", ->
|
||||
shouldDisplay = false
|
||||
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual []
|
||||
|
||||
it "allows items to be specified in the legacy format for now", ->
|
||||
contextMenu.add '.parent':
|
||||
'A': 'a'
|
||||
'Separator 1': '-'
|
||||
'B':
|
||||
'C': 'c'
|
||||
'Separator 2': '-'
|
||||
'D': 'd'
|
||||
describe "when the menus are specified in a legacy format", ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
expect(contextMenu.templateForElement(parent)).toEqual [
|
||||
{label: 'A', command: 'a'}
|
||||
{type: 'separator'}
|
||||
{
|
||||
label: 'B'
|
||||
submenu: [
|
||||
{label: 'C', command: 'c'}
|
||||
{type: 'separator'}
|
||||
{label: 'D', command: 'd'}
|
||||
]
|
||||
}
|
||||
]
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "allows items to be specified in the legacy format for now", ->
|
||||
contextMenu.add '.parent':
|
||||
'A': 'a'
|
||||
'Separator 1': '-'
|
||||
'B':
|
||||
'C': 'c'
|
||||
'Separator 2': '-'
|
||||
'D': 'd'
|
||||
|
||||
expect(contextMenu.templateForElement(parent)).toEqual [
|
||||
{label: 'A', command: 'a'}
|
||||
{type: 'separator'}
|
||||
{
|
||||
label: 'B'
|
||||
submenu: [
|
||||
{label: 'C', command: 'c'}
|
||||
{type: 'separator'}
|
||||
{label: 'D', command: 'd'}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1085,6 +1085,12 @@ describe "DisplayBuffer", ->
|
||||
expect(oldProperties).toEqual decorationProperties
|
||||
expect(newProperties).toEqual type: 'gutter', class: 'two', id: decoration.id
|
||||
|
||||
describe "::getDecorations(properties)", ->
|
||||
it "returns decorations matching the given optional properties", ->
|
||||
expect(displayBuffer.getDecorations()).toEqual [decoration]
|
||||
expect(displayBuffer.getDecorations(class: 'two').length).toEqual 0
|
||||
expect(displayBuffer.getDecorations(class: 'one').length).toEqual 1
|
||||
|
||||
describe "::setScrollTop", ->
|
||||
beforeEach ->
|
||||
displayBuffer.manageScrollPosition = true
|
||||
|
||||
@@ -9,5 +9,6 @@ module.exports =
|
||||
atom.commands.add 'atom-workspace', 'activation-command', =>
|
||||
@activationCommandCallCount++
|
||||
|
||||
atom.workspaceView.getActiveView()?.command 'activation-command', =>
|
||||
editorView = atom.views.getView(atom.workspace.getActiveTextEditor())?.__spacePenView
|
||||
editorView?.command 'activation-command', =>
|
||||
@legacyActivationCommandCallCount++
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.test-1':
|
||||
'Menu item 1': 'command-1'
|
||||
'.test-1': [
|
||||
{label: 'Menu item 1', command: 'command-1'}
|
||||
]
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.test-1':
|
||||
'Menu item 2': 'command-2'
|
||||
'.test-1': [
|
||||
{label: 'Menu item 2', command: 'command-2'}
|
||||
]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
'context-menu':
|
||||
'.test-1':
|
||||
'Menu item 3': 'command-3'
|
||||
'.test-1': [
|
||||
{label: 'Menu item 3', command: 'command-3'}
|
||||
]
|
||||
|
||||
@@ -132,7 +132,7 @@ describe "GitRepository", ->
|
||||
atom.workspace.open(filePath)
|
||||
|
||||
runs ->
|
||||
editor = atom.workspace.getActiveEditor()
|
||||
editor = atom.workspace.getActiveTextEditor()
|
||||
|
||||
it "displays a confirmation dialog by default", ->
|
||||
spyOn(atom, 'confirm').andCallFake ({buttons}) -> buttons.OK()
|
||||
@@ -259,6 +259,10 @@ describe "GitRepository", ->
|
||||
editor.getBuffer().emitter.emit 'did-change-path'
|
||||
expect(statusHandler.callCount).toBe 1
|
||||
|
||||
it "stops listening to the buffer when the repository is destroyed (regression)", ->
|
||||
atom.project.getRepositories()[0].destroy()
|
||||
expect(-> editor.save()).not.toThrow()
|
||||
|
||||
describe "when a project is deserialized", ->
|
||||
[buffer, project2] = []
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ module.exports.runSpecSuite = (specSuite, logFile, logErrors=true) ->
|
||||
log(str)
|
||||
onComplete: (runner) ->
|
||||
fs.closeSync(logStream) if logStream?
|
||||
if process.env.JANKY_SHA1
|
||||
grim = require 'grim'
|
||||
grim.logDeprecations() if grim.getDeprecationsLength() > 0
|
||||
atom.exit(runner.results().failedCount > 0 ? 1 : 0)
|
||||
else
|
||||
AtomReporter = require './atom-reporter'
|
||||
|
||||
@@ -96,12 +96,13 @@ describe "LanguageMode", ->
|
||||
buffer.setText("//this is a single line comment")
|
||||
expect(languageMode.rowRangeForCommentAtBufferRow(0)).toBeUndefined()
|
||||
|
||||
describe "suggestedIndentForBufferRow", ->
|
||||
it "returns the suggested indentation based on auto-indent/outdent rules", ->
|
||||
describe ".suggestedIndentForBufferRow", ->
|
||||
it "bases indentation off of the previous non-blank line", ->
|
||||
expect(languageMode.suggestedIndentForBufferRow(0)).toBe 0
|
||||
expect(languageMode.suggestedIndentForBufferRow(1)).toBe 1
|
||||
expect(languageMode.suggestedIndentForBufferRow(2)).toBe 2
|
||||
expect(languageMode.suggestedIndentForBufferRow(9)).toBe 1
|
||||
expect(languageMode.suggestedIndentForBufferRow(11)).toBe 1
|
||||
|
||||
describe "rowRangeForParagraphAtBufferRow", ->
|
||||
describe "with code and comments", ->
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
NotificationManager = require '../src/notification-manager'
|
||||
|
||||
describe "NotificationManager", ->
|
||||
[manager] = []
|
||||
|
||||
beforeEach ->
|
||||
manager = new NotificationManager
|
||||
|
||||
describe "the atom global", ->
|
||||
it "has a notifications instance", ->
|
||||
expect(atom.notifications instanceof NotificationManager).toBe true
|
||||
|
||||
describe "adding events", ->
|
||||
addSpy = null
|
||||
|
||||
beforeEach ->
|
||||
addSpy = jasmine.createSpy()
|
||||
manager.onDidAddNotification(addSpy)
|
||||
|
||||
it "emits an event when a notification has been added", ->
|
||||
manager.add('error', 'Some error!', icon: 'someIcon')
|
||||
expect(addSpy).toHaveBeenCalled()
|
||||
|
||||
notification = addSpy.mostRecentCall.args[0]
|
||||
expect(notification.getType()).toBe 'error'
|
||||
expect(notification.getMessage()).toBe 'Some error!'
|
||||
expect(notification.getIcon()).toBe 'someIcon'
|
||||
|
||||
it "emits a fatal error ::addFatalError has been called", ->
|
||||
manager.addFatalError('Some error!', icon: 'someIcon')
|
||||
expect(addSpy).toHaveBeenCalled()
|
||||
notification = addSpy.mostRecentCall.args[0]
|
||||
expect(notification.getType()).toBe 'fatal'
|
||||
|
||||
it "emits an error ::addError has been called", ->
|
||||
manager.addError('Some error!', icon: 'someIcon')
|
||||
expect(addSpy).toHaveBeenCalled()
|
||||
notification = addSpy.mostRecentCall.args[0]
|
||||
expect(notification.getType()).toBe 'error'
|
||||
|
||||
it "emits a warning notification ::addWarning has been called", ->
|
||||
manager.addWarning('Something!', icon: 'someIcon')
|
||||
expect(addSpy).toHaveBeenCalled()
|
||||
notification = addSpy.mostRecentCall.args[0]
|
||||
expect(notification.getType()).toBe 'warning'
|
||||
|
||||
it "emits an info notification ::addInfo has been called", ->
|
||||
manager.addInfo('Something!', icon: 'someIcon')
|
||||
expect(addSpy).toHaveBeenCalled()
|
||||
notification = addSpy.mostRecentCall.args[0]
|
||||
expect(notification.getType()).toBe 'info'
|
||||
|
||||
it "emits a success notification ::addSuccess has been called", ->
|
||||
manager.addSuccess('Something!', icon: 'someIcon')
|
||||
expect(addSpy).toHaveBeenCalled()
|
||||
notification = addSpy.mostRecentCall.args[0]
|
||||
expect(notification.getType()).toBe 'success'
|
||||
@@ -0,0 +1,47 @@
|
||||
Notification = require '../src/notification'
|
||||
|
||||
describe "Notification", ->
|
||||
[notification] = []
|
||||
|
||||
describe "::getTimestamp()", ->
|
||||
it "returns a Date object", ->
|
||||
notification = new Notification('error', 'message!')
|
||||
expect(notification.getTimestamp() instanceof Date).toBe true
|
||||
|
||||
describe "::getIcon()", ->
|
||||
it "returns a default when no icon specified", ->
|
||||
notification = new Notification('error', 'message!')
|
||||
expect(notification.getIcon()).toBe 'flame'
|
||||
|
||||
it "returns the icon specified", ->
|
||||
notification = new Notification('error', 'message!', icon: 'my-icon')
|
||||
expect(notification.getIcon()).toBe 'my-icon'
|
||||
|
||||
describe "dismissing notifications", ->
|
||||
describe "when the notfication is dismissable", ->
|
||||
it "calls a callback when the notification is dismissed", ->
|
||||
dismissedSpy = jasmine.createSpy()
|
||||
notification = new Notification('error', 'message', dismissable: true)
|
||||
notification.onDidDismiss dismissedSpy
|
||||
|
||||
expect(notification.isDismissable()).toBe true
|
||||
expect(notification.isDismissed()).toBe false
|
||||
|
||||
notification.dismiss()
|
||||
|
||||
expect(dismissedSpy).toHaveBeenCalled()
|
||||
expect(notification.isDismissed()).toBe true
|
||||
|
||||
describe "when the notfication is not dismissable", ->
|
||||
it "does nothing when ::dismiss() is called", ->
|
||||
dismissedSpy = jasmine.createSpy()
|
||||
notification = new Notification('error', 'message')
|
||||
notification.onDidDismiss dismissedSpy
|
||||
|
||||
expect(notification.isDismissable()).toBe false
|
||||
expect(notification.isDismissed()).toBe true
|
||||
|
||||
notification.dismiss()
|
||||
|
||||
expect(dismissedSpy).not.toHaveBeenCalled()
|
||||
expect(notification.isDismissed()).toBe true
|
||||
@@ -1,9 +1,10 @@
|
||||
{$, $$, WorkspaceView} = require 'atom'
|
||||
{$, $$} = require '../src/space-pen-extensions'
|
||||
Package = require '../src/package'
|
||||
|
||||
describe "PackageManager", ->
|
||||
workspaceElement = null
|
||||
beforeEach ->
|
||||
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
|
||||
describe "::loadPackage(name)", ->
|
||||
it "continues if the package has an invalid package.json", ->
|
||||
@@ -97,21 +98,29 @@ describe "PackageManager", ->
|
||||
expect(atom.config.set('package-with-config-schema.numbers.one', '10')).toBe true
|
||||
expect(atom.config.get('package-with-config-schema.numbers.one')).toBe 10
|
||||
|
||||
it "still assigns configDefaults from the module though deprecated", ->
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBeUndefined()
|
||||
describe "when a package has configDefaults", ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-config-defaults')
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBe 1
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.two')).toBe 2
|
||||
it "still assigns configDefaults from the module though deprecated", ->
|
||||
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBeUndefined()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-config-defaults')
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBe 1
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.two')).toBe 2
|
||||
|
||||
describe "when the package metadata includes `activationCommands`", ->
|
||||
[mainModule, promise, workspaceCommandListener] = []
|
||||
|
||||
beforeEach ->
|
||||
atom.workspaceView.attachToDom()
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
mainModule = require './fixtures/packages/package-with-activation-commands/index'
|
||||
mainModule.legacyActivationCommandCallCount = 0
|
||||
mainModule.activationCommandCallCount = 0
|
||||
@@ -125,29 +134,29 @@ describe "PackageManager", ->
|
||||
|
||||
it "defers requiring/activating the main module until an activation event bubbles to the root view", ->
|
||||
expect(promise.isFulfilled()).not.toBeTruthy()
|
||||
atom.workspaceView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
|
||||
workspaceElement.dispatchEvent(new CustomEvent('activation-command', bubbles: true))
|
||||
|
||||
waitsForPromise ->
|
||||
promise
|
||||
|
||||
it "triggers the activation event on all handlers registered during activation", ->
|
||||
waitsForPromise ->
|
||||
atom.workspaceView.open()
|
||||
atom.workspace.open()
|
||||
|
||||
runs ->
|
||||
editorView = atom.workspaceView.getActiveView()
|
||||
editorView = atom.views.getView(atom.workspace.getActiveTextEditor()).__spacePenView
|
||||
legacyCommandListener = jasmine.createSpy("legacyCommandListener")
|
||||
editorView.command 'activation-command', legacyCommandListener
|
||||
editorCommandListener = jasmine.createSpy("editorCommandListener")
|
||||
atom.commands.add 'atom-text-editor', 'activation-command', editorCommandListener
|
||||
editorView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
|
||||
atom.commands.dispatch(editorView[0], 'activation-command')
|
||||
expect(mainModule.activate.callCount).toBe 1
|
||||
expect(mainModule.legacyActivationCommandCallCount).toBe 1
|
||||
expect(mainModule.activationCommandCallCount).toBe 1
|
||||
expect(legacyCommandListener.callCount).toBe 1
|
||||
expect(editorCommandListener.callCount).toBe 1
|
||||
expect(workspaceCommandListener.callCount).toBe 1
|
||||
editorView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
|
||||
atom.commands.dispatch(editorView[0], 'activation-command')
|
||||
expect(mainModule.legacyActivationCommandCallCount).toBe 2
|
||||
expect(mainModule.activationCommandCallCount).toBe 2
|
||||
expect(legacyCommandListener.callCount).toBe 2
|
||||
@@ -349,8 +358,8 @@ describe "PackageManager", ->
|
||||
atom.packages.activatePackage('package-with-grammars')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Alot'
|
||||
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Alittle'
|
||||
expect(atom.grammars.selectGrammar('a.alot').name).toBe 'Alot'
|
||||
expect(atom.grammars.selectGrammar('a.alittle').name).toBe 'Alittle'
|
||||
|
||||
describe "scoped-property loading", ->
|
||||
it "loads the scoped properties", ->
|
||||
@@ -358,26 +367,26 @@ describe "PackageManager", ->
|
||||
atom.packages.activatePackage("package-with-scoped-properties")
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
|
||||
expect(atom.config.get 'editor.increaseIndentPattern', scope: ['.source.omg']).toBe '^a'
|
||||
|
||||
describe "converted textmate packages", ->
|
||||
it "loads the package's grammars", ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
|
||||
it "loads the translated scoped properties", ->
|
||||
expect(atom.config.get(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
|
||||
expect(atom.config.get('editor.commentStart', scope: ['.source.ruby'])).toBeUndefined()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get(['.source.ruby'], 'editor.commentStart')).toBe '# '
|
||||
expect(atom.config.get('editor.commentStart', scope: ['.source.ruby'])).toBe '# '
|
||||
|
||||
describe "::deactivatePackage(id)", ->
|
||||
afterEach ->
|
||||
@@ -454,8 +463,8 @@ describe "PackageManager", ->
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackage('package-with-grammars')
|
||||
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Null Grammar'
|
||||
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Null Grammar'
|
||||
expect(atom.grammars.selectGrammar('a.alot').name).toBe 'Null Grammar'
|
||||
expect(atom.grammars.selectGrammar('a.alittle').name).toBe 'Null Grammar'
|
||||
|
||||
it "removes the package's keymaps", ->
|
||||
waitsForPromise ->
|
||||
@@ -484,21 +493,21 @@ describe "PackageManager", ->
|
||||
atom.packages.activatePackage("package-with-scoped-properties")
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
|
||||
expect(atom.config.get 'editor.increaseIndentPattern', scope: ['.source.omg']).toBe '^a'
|
||||
atom.packages.deactivatePackage("package-with-scoped-properties")
|
||||
expect(atom.config.get ['.source.omg'], 'editor.increaseIndentPattern').toBeUndefined()
|
||||
expect(atom.config.get 'editor.increaseIndentPattern', scope: ['.source.omg']).toBeUndefined()
|
||||
|
||||
describe "textmate packages", ->
|
||||
it "removes the package's grammars", ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
atom.packages.deactivatePackage('language-ruby')
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
it "removes the package's scoped properties", ->
|
||||
waitsForPromise ->
|
||||
@@ -506,13 +515,14 @@ describe "PackageManager", ->
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackage('language-ruby')
|
||||
expect(atom.config.get(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
|
||||
expect(atom.config.get('editor.commentStart', scope: ['.source.ruby'])).toBeUndefined()
|
||||
|
||||
describe "::activate()", ->
|
||||
packageActivator = null
|
||||
themeActivator = null
|
||||
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
spyOn(console, 'warn')
|
||||
atom.packages.loadPackages()
|
||||
|
||||
@@ -526,8 +536,9 @@ describe "PackageManager", ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
Syntax = require '../src/syntax'
|
||||
atom.syntax = window.syntax = new Syntax()
|
||||
GrammarRegistry = require '../src/grammar-registry'
|
||||
atom.grammars = window.syntax = new GrammarRegistry()
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "activates all the packages, and none of the themes", ->
|
||||
atom.packages.activate()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{$} = require 'atom'
|
||||
{$} = require '../src/space-pen-extensions'
|
||||
path = require 'path'
|
||||
Package = require '../src/package'
|
||||
ThemePackage = require '../src/theme-package'
|
||||
|
||||
@@ -148,3 +148,57 @@ describe "PaneContainer", ->
|
||||
saved = container.confirmClose()
|
||||
expect(saved).toBeFalsy()
|
||||
expect(atom.confirm).toHaveBeenCalled()
|
||||
|
||||
describe "::onDidAddPane(callback)", ->
|
||||
it "invokes the given callback when panes are added", ->
|
||||
container = new PaneContainer
|
||||
events = []
|
||||
container.onDidAddPane (event) -> events.push(event)
|
||||
|
||||
pane1 = container.getActivePane()
|
||||
pane2 = pane1.splitRight()
|
||||
pane3 = pane2.splitDown()
|
||||
|
||||
expect(events).toEqual [{pane: pane2}, {pane: pane3}]
|
||||
|
||||
describe "::onDidDestroyPane(callback)", ->
|
||||
it "invokes the given callback when panes are destroyed", ->
|
||||
container = new PaneContainer
|
||||
events = []
|
||||
container.onDidDestroyPane (event) -> events.push(event)
|
||||
|
||||
pane1 = container.getActivePane()
|
||||
pane2 = pane1.splitRight()
|
||||
pane3 = pane2.splitDown()
|
||||
|
||||
pane2.destroy()
|
||||
pane3.destroy()
|
||||
|
||||
expect(events).toEqual [{pane: pane2}, {pane: pane3}]
|
||||
|
||||
describe "::onWillDestroyPaneItem() and ::onDidDestroyPaneItem", ->
|
||||
it "invokes the given callbacks when an item will be destroyed on any pane", ->
|
||||
container = new PaneContainer
|
||||
pane1 = container.getRoot()
|
||||
item1 = new Object
|
||||
item2 = new Object
|
||||
item3 = new Object
|
||||
|
||||
pane1.addItem(item1)
|
||||
events = []
|
||||
container.onWillDestroyPaneItem (event) -> events.push(['will', event])
|
||||
container.onDidDestroyPaneItem (event) -> events.push(['did', event])
|
||||
pane2 = pane1.splitRight(items: [item2, item3])
|
||||
|
||||
pane1.destroyItem(item1)
|
||||
pane2.destroyItem(item3)
|
||||
pane2.destroyItem(item2)
|
||||
|
||||
expect(events).toEqual [
|
||||
['will', {item: item1, pane: pane1, index: 0}]
|
||||
['did', {item: item1, pane: pane1, index: 0}]
|
||||
['will', {item: item3, pane: pane2, index: 1}]
|
||||
['did', {item: item3, pane: pane2, index: 1}]
|
||||
['will', {item: item2, pane: pane2, index: 0}]
|
||||
['did', {item: item2, pane: pane2, index: 0}]
|
||||
]
|
||||
|
||||
@@ -3,7 +3,8 @@ temp = require 'temp'
|
||||
PaneContainer = require '../src/pane-container'
|
||||
PaneContainerView = require '../src/pane-container-view'
|
||||
PaneView = require '../src/pane-view'
|
||||
{$, View, $$} = require 'atom'
|
||||
{Disposable} = require 'event-kit'
|
||||
{$, View, $$} = require '../src/space-pen-extensions'
|
||||
|
||||
describe "PaneContainerView", ->
|
||||
[TestView, container, pane1, pane2, pane3, deserializerDisposable] = []
|
||||
@@ -18,6 +19,8 @@ describe "PaneContainerView", ->
|
||||
getUri: -> path.join(temp.dir, @name)
|
||||
save: -> @saved = true
|
||||
isEqual: (other) -> @name is other?.name
|
||||
onDidChangeTitle: -> new Disposable(->)
|
||||
onDidChangeModified: -> new Disposable(->)
|
||||
|
||||
container = atom.views.getView(atom.workspace.paneContainer).__spacePenView
|
||||
pane1 = container.getRoot()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
PaneContainer = require '../src/pane-container'
|
||||
PaneView = require '../src/pane-view'
|
||||
fs = require 'fs-plus'
|
||||
{Emitter} = require 'event-kit'
|
||||
{$, View} = require 'atom'
|
||||
{Emitter, Disposable} = require 'event-kit'
|
||||
{$, View} = require '../src/space-pen-extensions'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
|
||||
@@ -21,8 +21,11 @@ describe "PaneView", ->
|
||||
@emitter.emit 'did-change-title', 'title'
|
||||
onDidChangeTitle: (callback) ->
|
||||
@emitter.on 'did-change-title', callback
|
||||
onDidChangeModified: -> new Disposable(->)
|
||||
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
deserializerDisposable = atom.deserializers.add(TestView)
|
||||
container = atom.views.getView(new PaneContainer).__spacePenView
|
||||
containerModel = container.model
|
||||
@@ -41,6 +44,7 @@ describe "PaneView", ->
|
||||
|
||||
afterEach ->
|
||||
deserializerDisposable.dispose()
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
describe "when the active pane item changes", ->
|
||||
it "hides all item views except the active one", ->
|
||||
@@ -155,14 +159,19 @@ describe "PaneView", ->
|
||||
expect(view1.is(':visible')).toBe true
|
||||
|
||||
describe "when the title of the active item changes", ->
|
||||
describe 'when there is no onDidChangeTitle method', ->
|
||||
describe 'when there is no onDidChangeTitle method (deprecated)', ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
view1.onDidChangeTitle = null
|
||||
view2.onDidChangeTitle = null
|
||||
|
||||
pane.activateItem(view2)
|
||||
pane.activateItem(view1)
|
||||
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "emits pane:active-item-title-changed", ->
|
||||
activeItemTitleChangedHandler = jasmine.createSpy("activeItemTitleChangedHandler")
|
||||
pane.on 'pane:active-item-title-changed', activeItemTitleChangedHandler
|
||||
@@ -220,7 +229,7 @@ describe "PaneView", ->
|
||||
|
||||
beforeEach ->
|
||||
pane2Model = paneModel.splitRight() # Can't destroy the last pane, so we add another
|
||||
pane2 = containerModel.getView(pane2Model).__spacePenView
|
||||
pane2 = atom.views.getView(pane2Model).__spacePenView
|
||||
|
||||
it "triggers a 'pane:removed' event with the pane", ->
|
||||
removedHandler = jasmine.createSpy("removedHandler")
|
||||
@@ -253,7 +262,7 @@ describe "PaneView", ->
|
||||
|
||||
beforeEach ->
|
||||
pane2Model = paneModel.splitRight(items: [pane.copyActiveItem()])
|
||||
pane2 = containerModel.getView(pane2Model).__spacePenView
|
||||
pane2 = atom.views.getView(pane2Model).__spacePenView
|
||||
expect(pane2Model.isActive()).toBe true
|
||||
|
||||
it "adds or removes the .active class as appropriate", ->
|
||||
@@ -300,8 +309,8 @@ describe "PaneView", ->
|
||||
pane2Model = pane1Model.splitRight(items: [pane1Model.copyActiveItem()])
|
||||
pane3Model = pane2Model.splitDown(items: [pane2Model.copyActiveItem()])
|
||||
pane2 = pane2Model._view
|
||||
pane2 = containerModel.getView(pane2Model).__spacePenView
|
||||
pane3 = containerModel.getView(pane3Model).__spacePenView
|
||||
pane2 = atom.views.getView(pane2Model).__spacePenView
|
||||
pane3 = atom.views.getView(pane3Model).__spacePenView
|
||||
|
||||
expect(container.find('> atom-pane-axis.horizontal > atom-pane').toArray()).toEqual [pane1[0]]
|
||||
expect(container.find('> atom-pane-axis.horizontal > atom-pane-axis.vertical > atom-pane').toArray()).toEqual [pane2[0], pane3[0]]
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
ViewRegistry = require '../src/view-registry'
|
||||
Panel = require '../src/panel'
|
||||
PanelElement = require '../src/panel-element'
|
||||
PanelContainer = require '../src/panel-container'
|
||||
PanelContainerElement = require '../src/panel-container-element'
|
||||
|
||||
describe "PanelContainerElement", ->
|
||||
[jasmineContent, element, container, viewRegistry] = []
|
||||
[jasmineContent, element, container] = []
|
||||
|
||||
class TestPanelContainerItem
|
||||
constructior: ->
|
||||
@@ -13,29 +12,27 @@ describe "PanelContainerElement", ->
|
||||
class TestPanelContainerItemElement extends HTMLElement
|
||||
createdCallback: ->
|
||||
@classList.add('test-root')
|
||||
setModel: (@model) ->
|
||||
initialize: (@model) ->
|
||||
this
|
||||
|
||||
TestPanelContainerItemElement = document.registerElement 'atom-test-container-item-element', prototype: TestPanelContainerItemElement.prototype
|
||||
|
||||
beforeEach ->
|
||||
jasmineContent = document.body.querySelector('#jasmine-content')
|
||||
|
||||
viewRegistry = new ViewRegistry
|
||||
viewRegistry.addViewProvider
|
||||
modelConstructor: Panel
|
||||
viewConstructor: PanelElement
|
||||
viewRegistry.addViewProvider
|
||||
modelConstructor: PanelContainer
|
||||
viewConstructor: PanelContainerElement
|
||||
viewRegistry.addViewProvider
|
||||
modelConstructor: TestPanelContainerItem
|
||||
viewConstructor: TestPanelContainerItemElement
|
||||
atom.views.addViewProvider Panel, (model) ->
|
||||
new PanelElement().initialize(model)
|
||||
atom.views.addViewProvider PanelContainer, (model) ->
|
||||
new PaneContainerElement().initialize(model)
|
||||
atom.views.addViewProvider TestPanelContainerItem, (model) ->
|
||||
new TestPanelContainerItemElement().initialize(model)
|
||||
|
||||
container = new PanelContainer({viewRegistry, location: 'left'})
|
||||
element = container.getView()
|
||||
container = new PanelContainer({location: 'left'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
it 'has a location attribute with value from the model', ->
|
||||
expect(element.getAttribute('location')).toBe 'left'
|
||||
it 'has a location class with value from the model', ->
|
||||
expect(element).toHaveClass 'left'
|
||||
|
||||
it 'removes the element when the container is destroyed', ->
|
||||
expect(element.parentNode).toBe jasmineContent
|
||||
@@ -43,23 +40,38 @@ describe "PanelContainerElement", ->
|
||||
expect(element.parentNode).not.toBe jasmineContent
|
||||
|
||||
describe "adding and removing panels", ->
|
||||
it "allows panels to be inserted at any position", ->
|
||||
panel1 = new Panel({item: new TestPanelContainerItem(), priority: 10})
|
||||
panel2 = new Panel({item: new TestPanelContainerItem(), priority: 5})
|
||||
panel3 = new Panel({item: new TestPanelContainerItem(), priority: 8})
|
||||
|
||||
container.addPanel(panel1)
|
||||
container.addPanel(panel2)
|
||||
container.addPanel(panel3)
|
||||
|
||||
expect(element.childNodes[2].getModel()).toBe(panel1)
|
||||
expect(element.childNodes[1].getModel()).toBe(panel3)
|
||||
expect(element.childNodes[0].getModel()).toBe(panel2)
|
||||
|
||||
describe "when the container is at the left location", ->
|
||||
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
|
||||
expect(element.childNodes.length).toBe 0
|
||||
|
||||
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
|
||||
panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
expect(element.childNodes.length).toBe 1
|
||||
expect(element.childNodes[0].getAttribute('location')).toBe 'left'
|
||||
expect(element.childNodes[0]).toHaveClass 'left'
|
||||
expect(element.childNodes[0]).toHaveClass 'tool-panel' # legacy selector support
|
||||
expect(element.childNodes[0]).toHaveClass 'panel-left' # legacy selector support
|
||||
|
||||
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
|
||||
|
||||
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
|
||||
panel2 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel2)
|
||||
expect(element.childNodes.length).toBe 2
|
||||
|
||||
expect(panel1.getView().style.display).not.toBe 'none'
|
||||
expect(panel2.getView().style.display).not.toBe 'none'
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe 'none'
|
||||
expect(atom.views.getView(panel2).style.display).not.toBe 'none'
|
||||
|
||||
panel1.destroy()
|
||||
expect(element.childNodes.length).toBe 1
|
||||
@@ -69,24 +81,26 @@ describe "PanelContainerElement", ->
|
||||
|
||||
describe "when the container is at the bottom location", ->
|
||||
beforeEach ->
|
||||
container = new PanelContainer({viewRegistry, location: 'bottom'})
|
||||
element = container.getView()
|
||||
container = new PanelContainer({location: 'bottom'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
|
||||
expect(element.childNodes.length).toBe 0
|
||||
|
||||
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem(), className: 'one'})
|
||||
panel1 = new Panel({item: new TestPanelContainerItem(), className: 'one'})
|
||||
container.addPanel(panel1)
|
||||
expect(element.childNodes.length).toBe 1
|
||||
expect(element.childNodes[0].getAttribute('location')).toBe 'bottom'
|
||||
expect(element.childNodes[0]).toHaveClass 'bottom'
|
||||
expect(element.childNodes[0]).toHaveClass 'tool-panel' # legacy selector support
|
||||
expect(element.childNodes[0]).toHaveClass 'panel-bottom' # legacy selector support
|
||||
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
|
||||
expect(panel1.getView()).toHaveClass 'one'
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'one'
|
||||
|
||||
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem(), className: 'two'})
|
||||
panel2 = new Panel({item: new TestPanelContainerItem(), className: 'two'})
|
||||
container.addPanel(panel2)
|
||||
expect(element.childNodes.length).toBe 2
|
||||
expect(panel2.getView()).toHaveClass 'two'
|
||||
expect(atom.views.getView(panel2)).toHaveClass 'two'
|
||||
|
||||
panel1.destroy()
|
||||
expect(element.childNodes.length).toBe 1
|
||||
@@ -96,23 +110,34 @@ describe "PanelContainerElement", ->
|
||||
|
||||
describe "when the container is modal", ->
|
||||
beforeEach ->
|
||||
container = new PanelContainer({viewRegistry, location: 'modal'})
|
||||
element = container.getView()
|
||||
container = new PanelContainer({location: 'modal'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
it "allows only one panel to be visible at a time", ->
|
||||
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
|
||||
panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
|
||||
expect(panel1.getView().style.display).not.toBe 'none'
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe 'none'
|
||||
|
||||
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
|
||||
panel2 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel2)
|
||||
|
||||
expect(panel1.getView().style.display).toBe 'none'
|
||||
expect(panel2.getView().style.display).not.toBe 'none'
|
||||
expect(atom.views.getView(panel1).style.display).toBe 'none'
|
||||
expect(atom.views.getView(panel2).style.display).not.toBe 'none'
|
||||
|
||||
panel1.show()
|
||||
|
||||
expect(panel1.getView().style.display).not.toBe 'none'
|
||||
expect(panel2.getView().style.display).toBe 'none'
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe 'none'
|
||||
expect(atom.views.getView(panel2).style.display).toBe 'none'
|
||||
|
||||
it "adds the 'modal' class to panels", ->
|
||||
panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'modal'
|
||||
|
||||
# legacy selector support
|
||||
expect(atom.views.getView(panel1)).not.toHaveClass 'tool-panel'
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'overlay'
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'from-top'
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
ViewRegistry = require '../src/view-registry'
|
||||
Panel = require '../src/panel'
|
||||
PanelContainer = require '../src/panel-container'
|
||||
|
||||
describe "PanelContainer", ->
|
||||
[container, viewRegistry] = []
|
||||
[container] = []
|
||||
|
||||
class TestPanelItem
|
||||
constructior: ->
|
||||
|
||||
beforeEach ->
|
||||
viewRegistry = new ViewRegistry
|
||||
container = new PanelContainer({viewRegistry})
|
||||
container = new PanelContainer
|
||||
|
||||
describe "::addPanel(panel)", ->
|
||||
it 'emits an onDidAddPanel event with the index the panel was inserted at', ->
|
||||
@@ -46,7 +44,7 @@ describe "PanelContainer", ->
|
||||
[initialPanel] = []
|
||||
beforeEach ->
|
||||
# 'left' logic is the same as 'top'
|
||||
container = new PanelContainer({viewRegistry, location: 'left'})
|
||||
container = new PanelContainer({location: 'left'})
|
||||
initialPanel = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(initialPanel)
|
||||
|
||||
@@ -75,7 +73,7 @@ describe "PanelContainer", ->
|
||||
[initialPanel] = []
|
||||
beforeEach ->
|
||||
# 'bottom' logic is the same as 'right'
|
||||
container = new PanelContainer({viewRegistry, location: 'right'})
|
||||
container = new PanelContainer({location: 'right'})
|
||||
initialPanel = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(initialPanel)
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
ViewRegistry = require '../src/view-registry'
|
||||
Panel = require '../src/panel'
|
||||
PanelElement = require '../src/panel-element'
|
||||
|
||||
describe "PanelElement", ->
|
||||
[jasmineContent, element, panel, viewRegistry] = []
|
||||
[jasmineContent, element, panel] = []
|
||||
|
||||
class TestPanelItem
|
||||
constructior: ->
|
||||
@@ -11,23 +10,22 @@ describe "PanelElement", ->
|
||||
class TestPanelItemElement extends HTMLElement
|
||||
createdCallback: ->
|
||||
@classList.add('test-root')
|
||||
setModel: (@model) ->
|
||||
initialize: (@model) ->
|
||||
this
|
||||
|
||||
TestPanelItemElement = document.registerElement 'atom-test-item-element', prototype: TestPanelItemElement.prototype
|
||||
|
||||
beforeEach ->
|
||||
jasmineContent = document.body.querySelector('#jasmine-content')
|
||||
|
||||
viewRegistry = new ViewRegistry
|
||||
viewRegistry.addViewProvider
|
||||
modelConstructor: Panel
|
||||
viewConstructor: PanelElement
|
||||
viewRegistry.addViewProvider
|
||||
modelConstructor: TestPanelItem
|
||||
viewConstructor: TestPanelItemElement
|
||||
atom.views.addViewProvider Panel, (model) ->
|
||||
new PanelElement().initialize(model)
|
||||
atom.views.addViewProvider TestPanelItem, (model) ->
|
||||
new TestPanelItemElement().initialize(model)
|
||||
|
||||
it 'removes the element when the panel is destroyed', ->
|
||||
panel = new Panel({viewRegistry, item: new TestPanelItem})
|
||||
element = panel.getView()
|
||||
panel = new Panel({item: new TestPanelItem})
|
||||
element = atom.views.getView(panel)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
expect(element.parentNode).toBe jasmineContent
|
||||
@@ -36,15 +34,15 @@ describe "PanelElement", ->
|
||||
|
||||
describe "changing panel visibility", ->
|
||||
it 'initially renders panel created with visibile: false', ->
|
||||
panel = new Panel({viewRegistry, visible: false, item: new TestPanelItem})
|
||||
element = panel.getView()
|
||||
panel = new Panel({visible: false, item: new TestPanelItem})
|
||||
element = atom.views.getView(panel)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
expect(element.style.display).toBe 'none'
|
||||
|
||||
it 'hides and shows the panel element when Panel::hide() and Panel::show() are called', ->
|
||||
panel = new Panel({viewRegistry, item: new TestPanelItem})
|
||||
element = panel.getView()
|
||||
panel = new Panel({item: new TestPanelItem})
|
||||
element = atom.views.getView(panel)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
expect(element.style.display).not.toBe 'none'
|
||||
@@ -57,8 +55,8 @@ describe "PanelElement", ->
|
||||
|
||||
describe "when a class name is specified", ->
|
||||
it 'initially renders panel created with visibile: false', ->
|
||||
panel = new Panel({viewRegistry, className: 'some classes', item: new TestPanelItem})
|
||||
element = panel.getView()
|
||||
panel = new Panel({className: 'some classes', item: new TestPanelItem})
|
||||
element = atom.views.getView(panel)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
expect(element).toHaveClass 'some'
|
||||
|
||||
@@ -21,3 +21,7 @@ describe "Panel", ->
|
||||
panel.show()
|
||||
expect(panel.isVisible()).toBe true
|
||||
expect(spy).toHaveBeenCalledWith(true)
|
||||
|
||||
panel.destroy()
|
||||
expect(panel.isVisible()).toBe false
|
||||
expect(spy).toHaveBeenCalledWith(false)
|
||||
|
||||
@@ -170,30 +170,30 @@ describe "Project", ->
|
||||
absolutePath = fs.absolute(__dirname)
|
||||
expect(atom.project.resolve(absolutePath)).toBe absolutePath
|
||||
|
||||
describe ".setPath(path)", ->
|
||||
describe ".setPaths(path)", ->
|
||||
describe "when path is a file", ->
|
||||
it "sets its path to the files parent directory and updates the root directory", ->
|
||||
atom.project.setPaths([require.resolve('./fixtures/dir/a')])
|
||||
expect(atom.project.getPaths()[0]).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
expect(atom.project.getRootDirectory().path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
expect(atom.project.getDirectories()[0].path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
|
||||
describe "when path is a directory", ->
|
||||
it "sets its path to the directory and updates the root directory", ->
|
||||
directory = fs.absolute(path.join(__dirname, 'fixtures', 'dir', 'a-dir'))
|
||||
atom.project.setPaths([directory])
|
||||
expect(atom.project.getPaths()[0]).toEqual directory
|
||||
expect(atom.project.getRootDirectory().path).toEqual directory
|
||||
expect(atom.project.getDirectories()[0].path).toEqual directory
|
||||
|
||||
describe "when path is null", ->
|
||||
it "sets its path and root directory to null", ->
|
||||
atom.project.setPaths([])
|
||||
expect(atom.project.getPaths()[0]?).toBeFalsy()
|
||||
expect(atom.project.getRootDirectory()?).toBeFalsy()
|
||||
expect(atom.project.getDirectories()[0]?).toBeFalsy()
|
||||
|
||||
it "normalizes the path to remove consecutive slashes, ., and .. segments", ->
|
||||
atom.project.setPaths(["#{require.resolve('./fixtures/dir/a')}#{path.sep}b#{path.sep}#{path.sep}.."])
|
||||
expect(atom.project.getPaths()[0]).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
expect(atom.project.getRootDirectory().path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
expect(atom.project.getDirectories()[0].path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
|
||||
describe ".replace()", ->
|
||||
[filePath, commentFilePath, sampleContent, sampleCommentContent] = []
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
SelectListView = require '../src/select-list-view'
|
||||
{$, $$} = require 'atom'
|
||||
{$, $$} = require '../src/space-pen-extensions'
|
||||
|
||||
describe "SelectListView", ->
|
||||
[selectList, items, list, filterEditorView] = []
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{View, $, $$} = require 'atom'
|
||||
{View, $, $$} = require '../src/space-pen-extensions'
|
||||
|
||||
describe "SpacePen extensions", ->
|
||||
class TestView extends View
|
||||
|
||||
@@ -9,12 +9,17 @@ _ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
Grim = require 'grim'
|
||||
KeymapManager = require '../src/keymap-extensions'
|
||||
{$, WorkspaceView, Workspace} = require 'atom'
|
||||
|
||||
# FIXME: Remove jquery from this
|
||||
{$} = require '../src/space-pen-extensions'
|
||||
|
||||
Config = require '../src/config'
|
||||
{Point} = require 'text-buffer'
|
||||
Project = require '../src/project'
|
||||
Workspace = require '../src/workspace'
|
||||
TextEditor = require '../src/text-editor'
|
||||
TextEditorView = require '../src/text-editor-view'
|
||||
TextEditorElement = require '../src/text-editor-element'
|
||||
TokenizedBuffer = require '../src/tokenized-buffer'
|
||||
TextEditorComponent = require '../src/text-editor-component'
|
||||
pathwatcher = require 'pathwatcher'
|
||||
@@ -76,13 +81,15 @@ beforeEach ->
|
||||
atom.commands.restoreSnapshot(commandsToRestore)
|
||||
atom.styles.restoreSnapshot(styleElementsToRestore)
|
||||
|
||||
atom.workspaceViewParentSelector = '#jasmine-content'
|
||||
|
||||
window.resetTimeouts()
|
||||
atom.packages.packageStates = {}
|
||||
|
||||
serializedWindowState = null
|
||||
|
||||
spyOn(atom, 'saveSync')
|
||||
atom.syntax.clearGrammarOverrides()
|
||||
atom.grammars.clearGrammarOverrides()
|
||||
|
||||
spy = spyOn(atom.packages, 'resolvePackagePath').andCallFake (packageName) ->
|
||||
if specPackageName and packageName is specPackageName
|
||||
@@ -111,8 +118,7 @@ beforeEach ->
|
||||
config.save.reset()
|
||||
|
||||
# make editor display updates synchronous
|
||||
spyOn(TextEditorView.prototype, 'requestDisplayUpdate').andCallFake -> @updateDisplay()
|
||||
TextEditorComponent.performSyncUpdates = true
|
||||
TextEditorElement::setUpdatedSynchronously(true)
|
||||
|
||||
spyOn(atom, "setRepresentedFilename")
|
||||
spyOn(window, "setTimeout").andCallFake window.fakeSetTimeout
|
||||
@@ -135,8 +141,9 @@ afterEach ->
|
||||
atom.menu.template = []
|
||||
atom.contextMenu.clear()
|
||||
|
||||
atom.workspaceView?.remove?()
|
||||
atom.workspaceView = null
|
||||
atom.workspace?.destroy()
|
||||
atom.workspace = null
|
||||
atom.__workspaceView = null
|
||||
delete atom.state.workspace
|
||||
|
||||
atom.project?.destroy()
|
||||
@@ -150,7 +157,7 @@ afterEach ->
|
||||
|
||||
jasmine.unspy(atom, 'saveSync')
|
||||
ensureNoPathSubscriptions()
|
||||
atom.syntax.clearObservers()
|
||||
atom.grammars.clearObservers()
|
||||
waits(0) # yield to ui thread to make screen update more frequently
|
||||
|
||||
ensureNoPathSubscriptions = ->
|
||||
@@ -191,6 +198,17 @@ jasmine.unspy = (object, methodName) ->
|
||||
throw new Error("Not a spy") unless object[methodName].hasOwnProperty('originalValue')
|
||||
object[methodName] = object[methodName].originalValue
|
||||
|
||||
jasmine.attachToDOM = (element) ->
|
||||
jasmineContent = document.querySelector('#jasmine-content')
|
||||
jasmineContent.appendChild(element) unless jasmineContent.contains(element)
|
||||
|
||||
deprecationsSnapshot = null
|
||||
jasmine.snapshotDeprecations = ->
|
||||
deprecationsSnapshot = Grim.getDeprecations() # suppress deprecations!!
|
||||
|
||||
jasmine.restoreDeprecationsSnapshot = ->
|
||||
Grim.grimDeprecations = deprecationsSnapshot
|
||||
|
||||
addCustomMatchers = (spec) ->
|
||||
spec.addMatchers
|
||||
toBeInstanceOf: (expected) ->
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
ChildProcess = require 'child_process'
|
||||
{EventEmitter} = require 'events'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
SquirrelUpdate = require '../src/browser/squirrel-update'
|
||||
|
||||
describe "Windows squirrel updates", ->
|
||||
tempHomeDirectory = null
|
||||
|
||||
beforeEach ->
|
||||
# Prevent the actually home directory from being manipulated
|
||||
tempHomeDirectory = temp.mkdirSync('atom-temp-home-')
|
||||
spyOn(fs, 'getHomeDirectory').andReturn(tempHomeDirectory)
|
||||
|
||||
# Prevent any commands from actually running and affecting the host
|
||||
originalSpawn = ChildProcess.spawn
|
||||
spyOn(ChildProcess, 'spawn').andCallFake (command, args) ->
|
||||
if path.basename(command) is 'Update.exe' and args?[0] is '--createShortcut'
|
||||
fs.writeFileSync(path.join(tempHomeDirectory, 'Desktop', 'Atom.lnk'), '')
|
||||
|
||||
# Just spawn something that won't actually modify the host
|
||||
if process.platform is 'win32'
|
||||
originalSpawn('dir')
|
||||
else
|
||||
originalSpawn('ls')
|
||||
|
||||
it "quits the app on all squirrel events", ->
|
||||
app = quit: jasmine.createSpy('quit')
|
||||
|
||||
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-install')).toBe true
|
||||
|
||||
waitsFor ->
|
||||
app.quit.callCount is 1
|
||||
|
||||
runs ->
|
||||
app.quit.reset()
|
||||
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-updated')).toBe true
|
||||
|
||||
waitsFor ->
|
||||
app.quit.callCount is 1
|
||||
|
||||
runs ->
|
||||
app.quit.reset()
|
||||
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-uninstall')).toBe true
|
||||
|
||||
waitsFor ->
|
||||
app.quit.callCount is 1
|
||||
|
||||
runs ->
|
||||
app.quit.reset()
|
||||
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-obsolete')).toBe true
|
||||
|
||||
waitsFor ->
|
||||
app.quit.callCount is 1
|
||||
|
||||
runs ->
|
||||
expect(SquirrelUpdate.handleStartupEvent(app, '--not-squirrel')).toBe false
|
||||
|
||||
it "keeps the desktop shortcut deleted on updates if it was previously deleted after install", ->
|
||||
desktopShortcutPath = path.join(tempHomeDirectory, 'Desktop', 'Atom.lnk')
|
||||
expect(fs.existsSync(desktopShortcutPath)).toBe false
|
||||
|
||||
app = quit: jasmine.createSpy('quit')
|
||||
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-install')).toBe true
|
||||
|
||||
waitsFor ->
|
||||
app.quit.callCount is 1
|
||||
|
||||
runs ->
|
||||
app.quit.reset()
|
||||
expect(fs.existsSync(desktopShortcutPath)).toBe true
|
||||
fs.removeSync(desktopShortcutPath)
|
||||
expect(fs.existsSync(desktopShortcutPath)).toBe false
|
||||
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-updated')).toBe true
|
||||
|
||||
waitsFor ->
|
||||
app.quit.callCount is 1
|
||||
|
||||
runs ->
|
||||
expect(fs.existsSync(desktopShortcutPath)).toBe false
|
||||
|
||||
describe ".restartAtom", ->
|
||||
it "quits the app and spawns a new one", ->
|
||||
app = new EventEmitter()
|
||||
app.quit = jasmine.createSpy('quit')
|
||||
|
||||
SquirrelUpdate.restartAtom(app)
|
||||
expect(app.quit.callCount).toBe 1
|
||||
|
||||
expect(ChildProcess.spawn.callCount).toBe 0
|
||||
app.emit('will-quit')
|
||||
expect(ChildProcess.spawn.callCount).toBe 1
|
||||
expect(path.basename(ChildProcess.spawn.argsForCall[0][0])).toBe 'atom.cmd'
|
||||
@@ -74,3 +74,39 @@ describe "StylesElement", ->
|
||||
expect(element.children.length).toBe 2
|
||||
expect(element.children[0].textContent).toBe "a {color: red;}"
|
||||
expect(element.children[1].textContent).toBe "a {color: blue;}"
|
||||
|
||||
describe "atom-text-editor shadow DOM selector upgrades", ->
|
||||
beforeEach ->
|
||||
element.setAttribute('context', 'atom-text-editor')
|
||||
spyOn(console, 'warn')
|
||||
|
||||
it "upgrades selectors containing .editor-colors", ->
|
||||
atom.styles.addStyleSheet(".editor-colors {background: black;}", context: 'atom-text-editor')
|
||||
expect(element.firstChild.sheet.cssRules[0].selectorText).toBe ':host'
|
||||
|
||||
it "upgrades selectors containing .editor", ->
|
||||
atom.styles.addStyleSheet """
|
||||
.editor {background: black;}
|
||||
.editor.mini {background: black;}
|
||||
.editor:focus {background: black;}
|
||||
""", context: 'atom-text-editor'
|
||||
|
||||
expect(element.firstChild.sheet.cssRules[0].selectorText).toBe ':host'
|
||||
expect(element.firstChild.sheet.cssRules[1].selectorText).toBe ':host(.mini)'
|
||||
expect(element.firstChild.sheet.cssRules[2].selectorText).toBe ':host(:focus)'
|
||||
|
||||
it "defers selector upgrade until the element is attached", ->
|
||||
element = new StylesElement
|
||||
element.setAttribute('context', 'atom-text-editor')
|
||||
element.initialize()
|
||||
|
||||
atom.styles.addStyleSheet ".editor {background: black;}", context: 'atom-text-editor'
|
||||
expect(element.firstChild.sheet).toBeNull()
|
||||
|
||||
document.querySelector('#jasmine-content').appendChild(element)
|
||||
expect(element.firstChild.sheet.cssRules[0].selectorText).toBe ':host'
|
||||
|
||||
it "does not throw exceptions on rules with no selectors", ->
|
||||
atom.styles.addStyleSheet """
|
||||
@media screen {font-size: 10px;}
|
||||
""", context: 'atom-text-editor'
|
||||
|
||||
+29
-56
@@ -23,10 +23,10 @@ describe "the `syntax` global", ->
|
||||
describe "serialization", ->
|
||||
it "remembers grammar overrides by path", ->
|
||||
filePath = '/foo/bar/file.js'
|
||||
expect(atom.syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
|
||||
atom.syntax.setGrammarOverrideForPath(filePath, 'source.ruby')
|
||||
syntax2 = atom.deserializers.deserialize(atom.syntax.serialize())
|
||||
syntax2.addGrammar(grammar) for grammar in atom.syntax.grammars when grammar isnt atom.syntax.nullGrammar
|
||||
expect(atom.grammars.selectGrammar(filePath).name).not.toBe 'Ruby'
|
||||
atom.grammars.setGrammarOverrideForPath(filePath, 'source.ruby')
|
||||
syntax2 = atom.deserializers.deserialize(atom.grammars.serialize())
|
||||
syntax2.addGrammar(grammar) for grammar in atom.grammars.grammars when grammar isnt atom.grammars.nullGrammar
|
||||
expect(syntax2.selectGrammar(filePath).name).toBe 'Ruby'
|
||||
|
||||
describe ".selectGrammar(filePath)", ->
|
||||
@@ -35,15 +35,15 @@ describe "the `syntax` global", ->
|
||||
atom.packages.activatePackage('language-git')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar("file.js").name).toBe "JavaScript" # based on extension (.js)
|
||||
expect(atom.syntax.selectGrammar(path.join(temp.dir, '.git', 'config')).name).toBe "Git Config" # based on end of the path (.git/config)
|
||||
expect(atom.syntax.selectGrammar("Rakefile").name).toBe "Ruby" # based on the file's basename (Rakefile)
|
||||
expect(atom.syntax.selectGrammar("curb").name).toBe "Null Grammar"
|
||||
expect(atom.syntax.selectGrammar("/hu.git/config").name).toBe "Null Grammar"
|
||||
expect(atom.grammars.selectGrammar("file.js").name).toBe "JavaScript" # based on extension (.js)
|
||||
expect(atom.grammars.selectGrammar(path.join(temp.dir, '.git', 'config')).name).toBe "Git Config" # based on end of the path (.git/config)
|
||||
expect(atom.grammars.selectGrammar("Rakefile").name).toBe "Ruby" # based on the file's basename (Rakefile)
|
||||
expect(atom.grammars.selectGrammar("curb").name).toBe "Null Grammar"
|
||||
expect(atom.grammars.selectGrammar("/hu.git/config").name).toBe "Null Grammar"
|
||||
|
||||
it "uses the filePath's shebang line if the grammar cannot be determined by the extension or basename", ->
|
||||
filePath = require.resolve("./fixtures/shebang")
|
||||
expect(atom.syntax.selectGrammar(filePath).name).toBe "Ruby"
|
||||
expect(atom.grammars.selectGrammar(filePath).name).toBe "Ruby"
|
||||
|
||||
it "uses the number of newlines in the first line regex to determine the number of lines to test against", ->
|
||||
waitsForPromise ->
|
||||
@@ -51,28 +51,28 @@ describe "the `syntax` global", ->
|
||||
|
||||
runs ->
|
||||
fileContent = "first-line\n<html>"
|
||||
expect(atom.syntax.selectGrammar("dummy.coffee", fileContent).name).toBe "CoffeeScript"
|
||||
expect(atom.grammars.selectGrammar("dummy.coffee", fileContent).name).toBe "CoffeeScript"
|
||||
|
||||
fileContent = '<?xml version="1.0" encoding="UTF-8"?>'
|
||||
expect(atom.syntax.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Null Grammar"
|
||||
expect(atom.grammars.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Null Grammar"
|
||||
|
||||
fileContent += '\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'
|
||||
expect(atom.syntax.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Property List (XML)"
|
||||
expect(atom.grammars.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Property List (XML)"
|
||||
|
||||
it "doesn't read the file when the file contents are specified", ->
|
||||
filePath = require.resolve("./fixtures/shebang")
|
||||
filePathContents = fs.readFileSync(filePath, 'utf8')
|
||||
spyOn(fs, 'read').andCallThrough()
|
||||
expect(atom.syntax.selectGrammar(filePath, filePathContents).name).toBe "Ruby"
|
||||
expect(atom.grammars.selectGrammar(filePath, filePathContents).name).toBe "Ruby"
|
||||
expect(fs.read).not.toHaveBeenCalled()
|
||||
|
||||
it "allows the default grammar to be overridden for a path", ->
|
||||
filePath = '/foo/bar/file.js'
|
||||
expect(atom.syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
|
||||
atom.syntax.setGrammarOverrideForPath(filePath, 'source.ruby')
|
||||
expect(atom.syntax.selectGrammar(filePath).name).toBe 'Ruby'
|
||||
atom.syntax.clearGrammarOverrideForPath(filePath)
|
||||
expect(atom.syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
|
||||
expect(atom.grammars.selectGrammar(filePath).name).not.toBe 'Ruby'
|
||||
atom.grammars.setGrammarOverrideForPath(filePath, 'source.ruby')
|
||||
expect(atom.grammars.selectGrammar(filePath).name).toBe 'Ruby'
|
||||
atom.grammars.clearGrammarOverrideForPath(filePath)
|
||||
expect(atom.grammars.selectGrammar(filePath).name).not.toBe 'Ruby'
|
||||
|
||||
describe "when multiple grammars have matching fileTypes", ->
|
||||
it "selects the grammar with the longest fileType match", ->
|
||||
@@ -82,8 +82,8 @@ describe "the `syntax` global", ->
|
||||
scopeName: 'source1'
|
||||
fileTypes: ['test']
|
||||
)
|
||||
grammar1 = atom.syntax.loadGrammarSync(grammarPath1)
|
||||
expect(atom.syntax.selectGrammar('more.test', '')).toBe grammar1
|
||||
grammar1 = atom.grammars.loadGrammarSync(grammarPath1)
|
||||
expect(atom.grammars.selectGrammar('more.test', '')).toBe grammar1
|
||||
|
||||
grammarPath2 = temp.path(suffix: '.json')
|
||||
fs.writeFileSync grammarPath2, JSON.stringify(
|
||||
@@ -91,44 +91,17 @@ describe "the `syntax` global", ->
|
||||
scopeName: 'source2'
|
||||
fileTypes: ['test', 'more.test']
|
||||
)
|
||||
grammar2 = atom.syntax.loadGrammarSync(grammarPath2)
|
||||
expect(atom.syntax.selectGrammar('more.test', '')).toBe grammar2
|
||||
grammar2 = atom.grammars.loadGrammarSync(grammarPath2)
|
||||
expect(atom.grammars.selectGrammar('more.test', '')).toBe grammar2
|
||||
|
||||
describe "when there is no file path", ->
|
||||
it "does not throw an exception (regression)", ->
|
||||
expect(-> atom.syntax.selectGrammar(null, '#!/usr/bin/ruby')).not.toThrow()
|
||||
expect(-> atom.syntax.selectGrammar(null, '')).not.toThrow()
|
||||
expect(-> atom.syntax.selectGrammar(null, null)).not.toThrow()
|
||||
expect(-> atom.grammars.selectGrammar(null, '#!/usr/bin/ruby')).not.toThrow()
|
||||
expect(-> atom.grammars.selectGrammar(null, '')).not.toThrow()
|
||||
expect(-> atom.grammars.selectGrammar(null, null)).not.toThrow()
|
||||
|
||||
describe ".removeGrammar(grammar)", ->
|
||||
it "removes the grammar, so it won't be returned by selectGrammar", ->
|
||||
grammar = atom.syntax.selectGrammar('foo.js')
|
||||
atom.syntax.removeGrammar(grammar)
|
||||
expect(atom.syntax.selectGrammar('foo.js').name).not.toBe grammar.name
|
||||
|
||||
describe ".getProperty(scopeDescriptor)", ->
|
||||
it "returns the property with the most specific scope selector", ->
|
||||
atom.syntax.addProperties(".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
atom.syntax.addProperties(".source .string.quoted.double", foo: bar: baz: 22)
|
||||
atom.syntax.addProperties(".source", foo: bar: baz: 11)
|
||||
|
||||
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
|
||||
expect(atom.syntax.getProperty([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBe 22
|
||||
expect(atom.syntax.getProperty([".source.js", ".variable.assignment.js"], "foo.bar.baz")).toBe 11
|
||||
expect(atom.syntax.getProperty([".text"], "foo.bar.baz")).toBeUndefined()
|
||||
|
||||
it "favors the most recently added properties in the event of a specificity tie", ->
|
||||
atom.syntax.addProperties(".source.coffee .string.quoted.single", foo: bar: baz: 42)
|
||||
atom.syntax.addProperties(".source.coffee .string.quoted.double", foo: bar: baz: 22)
|
||||
|
||||
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.single"], "foo.bar.baz")).toBe 42
|
||||
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.single.double"], "foo.bar.baz")).toBe 22
|
||||
|
||||
describe ".removeProperties(name)", ->
|
||||
it "allows properties to be removed by name", ->
|
||||
atom.syntax.addProperties("a", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
atom.syntax.addProperties("b", ".source .string.quoted.double", foo: bar: baz: 22)
|
||||
|
||||
atom.syntax.removeProperties("b")
|
||||
expect(atom.syntax.getProperty([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBeUndefined()
|
||||
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
|
||||
grammar = atom.grammars.selectGrammar('foo.js')
|
||||
atom.grammars.removeGrammar(grammar)
|
||||
expect(atom.grammars.selectGrammar('foo.js').name).not.toBe grammar.name
|
||||
|
||||
@@ -37,9 +37,9 @@ describe "TextEditorComponent", ->
|
||||
wrapperView = new TextEditorView(editor, {lineOverdrawMargin})
|
||||
wrapperView.attachToDom()
|
||||
wrapperNode = wrapperView.element
|
||||
wrapperNode.setUpdatedSynchronously(false)
|
||||
|
||||
{component} = wrapperView
|
||||
component.performSyncUpdates = false
|
||||
component.setFontFamily('monospace')
|
||||
component.setLineHeight(1.3)
|
||||
component.setFontSize(20)
|
||||
@@ -302,7 +302,7 @@ describe "TextEditorComponent", ->
|
||||
|
||||
it "interleaves invisible line-ending characters with indent guides on empty lines", ->
|
||||
component.setShowIndentGuide(true)
|
||||
editor.setTextInBufferRange([[10, 0], [11, 0]], "\r\n", false)
|
||||
editor.setTextInBufferRange([[10, 0], [11, 0]], "\r\n", normalizeLineEndings: false)
|
||||
nextAnimationFrame()
|
||||
expect(component.lineNodeForScreenRow(10).innerHTML).toBe '<span class="indent-guide"><span class="invisible-character">C</span><span class="invisible-character">E</span></span>'
|
||||
|
||||
@@ -1203,6 +1203,232 @@ describe "TextEditorComponent", ->
|
||||
expect(componentNode.querySelector('.test-highlight')).toBeFalsy()
|
||||
expect(componentNode.querySelector('.new-test-highlight')).toBeTruthy()
|
||||
|
||||
describe "overlay decoration rendering", ->
|
||||
[item] = []
|
||||
beforeEach ->
|
||||
item = document.createElement('div')
|
||||
item.classList.add 'overlay-test'
|
||||
|
||||
describe "when the marker is empty", ->
|
||||
it "renders an overlay decoration when added and removes the overlay when the decoration is destroyed", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[2, 13], [2, 13]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay .overlay-test')
|
||||
expect(overlay).toBe item
|
||||
|
||||
decoration.destroy()
|
||||
nextAnimationFrame()
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay .overlay-test')
|
||||
expect(overlay).toBe null
|
||||
|
||||
it "renders in the correct position on initial display and when the marker moves", ->
|
||||
editor.setCursorBufferPosition([2, 5])
|
||||
|
||||
marker = editor.getLastCursor().getMarker()
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([2, 5])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
editor.moveRight()
|
||||
editor.moveRight()
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([2, 7])
|
||||
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
describe "when the marker is not empty", ->
|
||||
it "renders at the head of the marker by default", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[2, 5], [2, 10]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([2, 10])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
it "renders at the head of the marker when the marker is reversed", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[2, 5], [2, 10]], invalidate: 'never', reversed: true)
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([2, 5])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
it "renders at the tail of the marker when the 'position' option is 'tail'", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[2, 5], [2, 10]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', position: 'tail', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([2, 5])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
describe "positioning the overlay when near the edge of the editor", ->
|
||||
[itemWidth, itemHeight] = []
|
||||
beforeEach ->
|
||||
itemWidth = 4 * editor.getDefaultCharWidth()
|
||||
itemHeight = 4 * editor.getLineHeightInPixels()
|
||||
|
||||
gutterWidth = componentNode.querySelector('.gutter').offsetWidth
|
||||
windowWidth = gutterWidth + 30 * editor.getDefaultCharWidth()
|
||||
windowHeight = 9 * editor.getLineHeightInPixels()
|
||||
|
||||
item.style.width = itemWidth + 'px'
|
||||
item.style.height = itemHeight + 'px'
|
||||
|
||||
wrapperNode.style.width = windowWidth + 'px'
|
||||
wrapperNode.style.height = windowHeight + 'px'
|
||||
|
||||
component.measureHeightAndWidth()
|
||||
nextAnimationFrame()
|
||||
|
||||
it "flips horizontally when near the right edge", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[0, 26], [0, 26]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([0, 26])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
editor.insertText('a')
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([0, 27])
|
||||
|
||||
expect(overlay.style.left).toBe position.left - itemWidth + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
it "flips vertically when near the bottom edge", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[4, 0], [4, 0]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([4, 0])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
editor.insertNewline()
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([5, 0])
|
||||
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top - itemHeight + 'px'
|
||||
|
||||
describe "when the editor is very small", ->
|
||||
beforeEach ->
|
||||
gutterWidth = componentNode.querySelector('.gutter').offsetWidth
|
||||
windowWidth = gutterWidth + 6 * editor.getDefaultCharWidth()
|
||||
windowHeight = 6 * editor.getLineHeightInPixels()
|
||||
|
||||
wrapperNode.style.width = windowWidth + 'px'
|
||||
wrapperNode.style.height = windowHeight + 'px'
|
||||
|
||||
component.measureHeightAndWidth()
|
||||
nextAnimationFrame()
|
||||
|
||||
it "does not flip horizontally and force the overlay to have a negative left", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[0, 2], [0, 2]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([0, 2])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
editor.insertText('a')
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([0, 3])
|
||||
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
it "does not flip vertically and force the overlay to have a negative top", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[1, 0], [1, 0]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([1, 0])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
editor.insertNewline()
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([2, 0])
|
||||
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
|
||||
describe "when editor scroll position is not 0", ->
|
||||
it "flips horizontally when near the right edge", ->
|
||||
editor.setScrollLeft(2 * editor.getDefaultCharWidth())
|
||||
marker = editor.displayBuffer.markBufferRange([[0, 28], [0, 28]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([0, 28])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
editor.insertText('a')
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([0, 29])
|
||||
|
||||
expect(overlay.style.left).toBe position.left - itemWidth + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
it "flips vertically when near the bottom edge", ->
|
||||
editor.setScrollTop(2 * editor.getLineHeightInPixels())
|
||||
marker = editor.displayBuffer.markBufferRange([[6, 0], [6, 0]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([6, 0])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
editor.insertNewline()
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([7, 0])
|
||||
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top - itemHeight + 'px'
|
||||
|
||||
describe "hidden input field", ->
|
||||
it "renders the hidden input field at the position of the last cursor if the cursor is on screen and the editor is focused", ->
|
||||
editor.setVerticalScrollMargin(0)
|
||||
@@ -1386,6 +1612,22 @@ describe "TextEditorComponent", ->
|
||||
expect(nextAnimationFrame).toBe noAnimationFrame
|
||||
expect(editor.getSelectedScreenRange()).toEqual [[2, 4], [6, 8]]
|
||||
|
||||
describe "when the editor is destroyed while dragging", ->
|
||||
it "cleans up the handlers for window.mouseup and window.mousemove", ->
|
||||
linesNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([2, 4]), which: 1))
|
||||
linesNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenPosition([6, 8]), which: 1))
|
||||
nextAnimationFrame()
|
||||
|
||||
spyOn(window, 'removeEventListener').andCallThrough()
|
||||
|
||||
linesNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenPosition([6, 10]), which: 1))
|
||||
editor.destroy()
|
||||
nextAnimationFrame()
|
||||
|
||||
call.args.pop() for call in window.removeEventListener.calls
|
||||
expect(window.removeEventListener).toHaveBeenCalledWith('mouseup')
|
||||
expect(window.removeEventListener).toHaveBeenCalledWith('mousemove')
|
||||
|
||||
describe "when a line is folded", ->
|
||||
beforeEach ->
|
||||
editor.foldBufferRow 4
|
||||
@@ -1682,7 +1924,8 @@ describe "TextEditorComponent", ->
|
||||
}
|
||||
""", context: 'atom-text-editor'
|
||||
|
||||
nextAnimationFrame()
|
||||
nextAnimationFrame() # handle stylesheet change event
|
||||
nextAnimationFrame() # perform requested update
|
||||
|
||||
scrollbarCornerNode = componentNode.querySelector('.scrollbar-corner')
|
||||
expect(verticalScrollbarNode.offsetWidth).toBe 8
|
||||
@@ -2317,7 +2560,7 @@ describe "TextEditorComponent", ->
|
||||
describe "grammar data attributes", ->
|
||||
it "adds and updates the grammar data attribute based on the current grammar", ->
|
||||
expect(wrapperNode.dataset.grammar).toBe 'source js'
|
||||
editor.setGrammar(atom.syntax.nullGrammar)
|
||||
editor.setGrammar(atom.grammars.nullGrammar)
|
||||
expect(wrapperNode.dataset.grammar).toBe 'text plain null-grammar'
|
||||
|
||||
describe "encoding data attributes", ->
|
||||
@@ -2350,9 +2593,9 @@ describe "TextEditorComponent", ->
|
||||
|
||||
describe 'soft wrap settings', ->
|
||||
beforeEach ->
|
||||
atom.config.set '.source.coffee', 'editor.softWrap', true
|
||||
atom.config.set '.source.coffee', 'editor.preferredLineLength', 17
|
||||
atom.config.set '.source.coffee', 'editor.softWrapAtPreferredLineLength', true
|
||||
atom.config.set 'editor.softWrap', true, scopeSelector: '.source.coffee'
|
||||
atom.config.set 'editor.preferredLineLength', 17, scopeSelector: '.source.coffee'
|
||||
atom.config.set 'editor.softWrapAtPreferredLineLength', true, scopeSelector: '.source.coffee'
|
||||
|
||||
editor.setEditorWidthInChars(20)
|
||||
coffeeEditor.setEditorWidthInChars(20)
|
||||
@@ -2362,18 +2605,18 @@ describe "TextEditorComponent", ->
|
||||
expect(coffeeEditor.lineTextForScreenRow(3)).toEqual ' return items '
|
||||
|
||||
it 'updates the wrapped lines when editor.preferredLineLength changes', ->
|
||||
atom.config.set '.source.coffee', 'editor.preferredLineLength', 20
|
||||
atom.config.set 'editor.preferredLineLength', 20, scopeSelector: '.source.coffee'
|
||||
expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if '
|
||||
|
||||
it 'updates the wrapped lines when editor.softWrapAtPreferredLineLength changes', ->
|
||||
atom.config.set '.source.coffee', 'editor.softWrapAtPreferredLineLength', false
|
||||
atom.config.set 'editor.softWrapAtPreferredLineLength', false, scopeSelector: '.source.coffee'
|
||||
expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if '
|
||||
|
||||
it 'updates the wrapped lines when editor.softWrap changes', ->
|
||||
atom.config.set '.source.coffee', 'editor.softWrap', false
|
||||
atom.config.set 'editor.softWrap', false, scopeSelector: '.source.coffee'
|
||||
expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if items.length <= 1'
|
||||
|
||||
atom.config.set '.source.coffee', 'editor.softWrap', true
|
||||
atom.config.set 'editor.softWrap', true, scopeSelector: '.source.coffee'
|
||||
expect(coffeeEditor.lineTextForScreenRow(3)).toEqual ' return items '
|
||||
|
||||
it 'updates the wrapped lines when the grammar changes', ->
|
||||
@@ -2401,11 +2644,11 @@ describe "TextEditorComponent", ->
|
||||
tab: 'F'
|
||||
cr: 'E'
|
||||
|
||||
atom.config.set '.source.js', 'editor.showInvisibles', true
|
||||
atom.config.set '.source.js', 'editor.invisibles', jsInvisibles
|
||||
atom.config.set 'editor.showInvisibles', true, scopeSelector: '.source.js'
|
||||
atom.config.set 'editor.invisibles', jsInvisibles, scopeSelector: '.source.js'
|
||||
|
||||
atom.config.set '.source.coffee', 'editor.showInvisibles', false
|
||||
atom.config.set '.source.coffee', 'editor.invisibles', coffeeInvisibles
|
||||
atom.config.set 'editor.showInvisibles', false, scopeSelector: '.source.coffee'
|
||||
atom.config.set 'editor.invisibles', coffeeInvisibles, scopeSelector: '.source.coffee'
|
||||
|
||||
editor.setText " a line with tabs\tand spaces \n"
|
||||
nextAnimationFrame()
|
||||
@@ -2421,7 +2664,7 @@ describe "TextEditorComponent", ->
|
||||
it "re-renders the invisibles when the invisible settings change", ->
|
||||
jsGrammar = editor.getGrammar()
|
||||
editor.setGrammar(coffeeEditor.getGrammar())
|
||||
atom.config.set '.source.coffee', 'editor.showInvisibles', true
|
||||
atom.config.set 'editor.showInvisibles', true, scopeSelector: '.source.coffee'
|
||||
nextAnimationFrame()
|
||||
expect(component.lineNodeForScreenRow(0).textContent).toBe "#{coffeeInvisibles.space}a line with tabs#{coffeeInvisibles.tab}and spaces#{coffeeInvisibles.space}#{coffeeInvisibles.eol}"
|
||||
|
||||
@@ -2430,7 +2673,7 @@ describe "TextEditorComponent", ->
|
||||
space: 'E'
|
||||
tab: 'W'
|
||||
cr: 'I'
|
||||
atom.config.set '.source.coffee', 'editor.invisibles', newInvisibles
|
||||
atom.config.set 'editor.invisibles', newInvisibles, scopeSelector: '.source.coffee'
|
||||
nextAnimationFrame()
|
||||
expect(component.lineNodeForScreenRow(0).textContent).toBe "#{newInvisibles.space}a line with tabs#{newInvisibles.tab}and spaces#{newInvisibles.space}#{newInvisibles.eol}"
|
||||
|
||||
@@ -2440,8 +2683,8 @@ describe "TextEditorComponent", ->
|
||||
|
||||
describe 'editor.showIndentGuide', ->
|
||||
beforeEach ->
|
||||
atom.config.set '.source.js', 'editor.showIndentGuide', true
|
||||
atom.config.set '.source.coffee', 'editor.showIndentGuide', false
|
||||
atom.config.set 'editor.showIndentGuide', true, scopeSelector: '.source.js'
|
||||
atom.config.set 'editor.showIndentGuide', false, scopeSelector: '.source.coffee'
|
||||
|
||||
it "has an 'indent-guide' class when scoped editor.showIndentGuide is true, but not when scoped editor.showIndentGuide is false", ->
|
||||
line1LeafNodes = getLeafNodes(component.lineNodeForScreenRow(1))
|
||||
@@ -2462,13 +2705,44 @@ describe "TextEditorComponent", ->
|
||||
expect(line1LeafNodes[0].classList.contains('indent-guide')).toBe true
|
||||
expect(line1LeafNodes[1].classList.contains('indent-guide')).toBe false
|
||||
|
||||
atom.config.set '.source.js', 'editor.showIndentGuide', false
|
||||
atom.config.set 'editor.showIndentGuide', false, scopeSelector: '.source.js'
|
||||
|
||||
line1LeafNodes = getLeafNodes(component.lineNodeForScreenRow(1))
|
||||
expect(line1LeafNodes[0].textContent).toBe ' '
|
||||
expect(line1LeafNodes[0].classList.contains('indent-guide')).toBe false
|
||||
expect(line1LeafNodes[1].classList.contains('indent-guide')).toBe false
|
||||
|
||||
describe "middle mouse paste on Linux", ->
|
||||
originalPlatform = null
|
||||
|
||||
beforeEach ->
|
||||
originalPlatform = process.platform
|
||||
Object.defineProperty process, 'platform', value: 'linux'
|
||||
|
||||
afterEach ->
|
||||
Object.defineProperty process, 'platform', value: originalPlatform
|
||||
|
||||
it "pastes the previously selected text at the clicked location", ->
|
||||
jasmine.unspy(window, 'setTimeout')
|
||||
clipboardWrittenTo = false
|
||||
spyOn(require('ipc'), 'send').andCallFake (eventName, selectedText) ->
|
||||
if eventName is 'write-text-to-selection-clipboard'
|
||||
require('clipboard').writeText(selectedText, 'selection')
|
||||
clipboardWrittenTo = true
|
||||
|
||||
atom.clipboard.write('')
|
||||
component.trackSelectionClipboard()
|
||||
editor.setSelectedBufferRange([[1, 6], [1, 10]])
|
||||
|
||||
waitsFor ->
|
||||
clipboardWrittenTo
|
||||
|
||||
runs ->
|
||||
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([10, 0]), button: 1))
|
||||
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenPosition([10, 0]), which: 2))
|
||||
expect(atom.clipboard.read()).toBe 'sort'
|
||||
expect(editor.lineTextForBufferRow(10)).toBe 'sort'
|
||||
|
||||
buildMouseEvent = (type, properties...) ->
|
||||
properties = extend({bubbles: true, cancelable: true}, properties...)
|
||||
properties.detail ?= 1
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
TextEditorElement = require '../src/text-editor-element'
|
||||
TextEditor = require '../src/text-editor'
|
||||
|
||||
# The rest of text-editor-component-spec will be moved to this file when React
|
||||
# is eliminated. This covers only concerns related to the wrapper element for now
|
||||
@@ -19,6 +20,43 @@ describe "TextEditorElement", ->
|
||||
element = jasmineContent.firstChild
|
||||
expect(element.getModel().getPlaceholderText()).toBe 'testing'
|
||||
|
||||
it "honors the text content", ->
|
||||
jasmineContent.innerHTML = "<atom-text-editor>testing</atom-text-editor>"
|
||||
element = jasmineContent.firstChild
|
||||
expect(element.getModel().getText()).toBe 'testing'
|
||||
|
||||
describe "when the model is assigned", ->
|
||||
it "adds the 'mini' attribute if .isMini() returns true on the model", ->
|
||||
element = new TextEditorElement
|
||||
model = new TextEditor(mini: true)
|
||||
element.setModel(model)
|
||||
expect(element.hasAttribute('mini')).toBe true
|
||||
|
||||
describe "when the editor is attached to the DOM", ->
|
||||
describe "when the editor.useShadowDOM config option is true", ->
|
||||
it "mounts the react component and unmounts when removed from the dom", ->
|
||||
atom.config.set('editor.useShadowDOM', true)
|
||||
|
||||
element = new TextEditorElement
|
||||
jasmine.attachToDOM(element)
|
||||
|
||||
component = element.component
|
||||
expect(component.isMounted()).toBe true
|
||||
element.getModel().destroy()
|
||||
expect(component.isMounted()).toBe false
|
||||
|
||||
describe "when the editor.useShadowDOM config option is false", ->
|
||||
it "mounts the react component and unmounts when removed from the dom", ->
|
||||
atom.config.set('editor.useShadowDOM', false)
|
||||
|
||||
element = new TextEditorElement
|
||||
jasmine.attachToDOM(element)
|
||||
|
||||
component = element.component
|
||||
expect(component.isMounted()).toBe true
|
||||
element.getModel().destroy()
|
||||
expect(component.isMounted()).toBe false
|
||||
|
||||
describe "focus and blur handling", ->
|
||||
describe "when the editor.useShadowDOM config option is true", ->
|
||||
it "proxies focus/blur events to/from the hidden input inside the shadow root", ->
|
||||
@@ -90,3 +128,55 @@ describe "TextEditorElement", ->
|
||||
verticalScrollbarNode = element.querySelector(".vertical-scrollbar")
|
||||
scrollbarWidth = verticalScrollbarNode.offsetWidth - verticalScrollbarNode.clientWidth
|
||||
expect(scrollbarWidth).toEqual(8)
|
||||
|
||||
describe "::onDidAttach and ::onDidDetach", ->
|
||||
it "invokes callbacks when the element is attached and detached", ->
|
||||
element = new TextEditorElement
|
||||
|
||||
attachedCallback = jasmine.createSpy("attachedCallback")
|
||||
detachedCallback = jasmine.createSpy("detachedCallback")
|
||||
|
||||
element.onDidAttach(attachedCallback)
|
||||
element.onDidDetach(detachedCallback)
|
||||
|
||||
jasmine.attachToDOM(element)
|
||||
|
||||
expect(attachedCallback).toHaveBeenCalled()
|
||||
expect(detachedCallback).not.toHaveBeenCalled()
|
||||
|
||||
attachedCallback.reset()
|
||||
element.remove()
|
||||
|
||||
expect(attachedCallback).not.toHaveBeenCalled()
|
||||
expect(detachedCallback).toHaveBeenCalled()
|
||||
|
||||
describe "::setUpdatedSynchronously", ->
|
||||
it "controls whether the text editor is updated synchronously", ->
|
||||
spyOn(window, 'requestAnimationFrame').andCallFake (fn) -> fn()
|
||||
|
||||
element = new TextEditorElement
|
||||
jasmine.attachToDOM(element)
|
||||
|
||||
element.setUpdatedSynchronously(false)
|
||||
expect(element.isUpdatedSynchronously()).toBe false
|
||||
|
||||
element.getModel().setText("hello")
|
||||
expect(window.requestAnimationFrame).toHaveBeenCalled()
|
||||
|
||||
expect(element.shadowRoot.textContent).toContain "hello"
|
||||
|
||||
window.requestAnimationFrame.reset()
|
||||
element.setUpdatedSynchronously(true)
|
||||
element.getModel().setText("goodbye")
|
||||
expect(window.requestAnimationFrame).not.toHaveBeenCalled()
|
||||
expect(element.shadowRoot.textContent).toContain "goodbye"
|
||||
|
||||
describe "::getDefaultCharacterWidth", ->
|
||||
it "returns null before the element is attached", ->
|
||||
element = new TextEditorElement
|
||||
expect(element.getDefaultCharacterWidth()).toBeNull()
|
||||
|
||||
it "returns the width of a character in the root scope", ->
|
||||
element = new TextEditorElement
|
||||
jasmine.attachToDOM(element)
|
||||
expect(element.getDefaultCharacterWidth()).toBeGreaterThan(0)
|
||||
|
||||
+304
-271
@@ -192,12 +192,18 @@ describe "TextEditor", ->
|
||||
expect(editor.getCursorBufferPosition()).toEqual [1, 1]
|
||||
|
||||
it "emits an event with the old position, new position, and the cursor that moved", ->
|
||||
editor.onDidChangeCursorPosition positionChangedHandler = jasmine.createSpy()
|
||||
cursorCallback = jasmine.createSpy('cursor-changed-position')
|
||||
editorCallback = jasmine.createSpy('editor-changed-cursor-position')
|
||||
|
||||
editor.getLastCursor().onDidChangePosition(cursorCallback)
|
||||
editor.onDidChangeCursorPosition(editorCallback)
|
||||
|
||||
editor.setCursorBufferPosition([2, 4])
|
||||
|
||||
expect(positionChangedHandler).toHaveBeenCalled()
|
||||
eventObject = positionChangedHandler.mostRecentCall.args[0]
|
||||
expect(editorCallback).toHaveBeenCalled()
|
||||
expect(cursorCallback).toHaveBeenCalled()
|
||||
eventObject = editorCallback.mostRecentCall.args[0]
|
||||
expect(cursorCallback.mostRecentCall.args[0]).toEqual(eventObject)
|
||||
|
||||
expect(eventObject.oldBufferPosition).toEqual [0, 0]
|
||||
expect(eventObject.oldScreenPosition).toEqual [0, 0]
|
||||
@@ -616,7 +622,7 @@ describe "TextEditor", ->
|
||||
describe "when invisible characters are enabled with hard tabs", ->
|
||||
it "moves to the first character of the current line without being confused by the invisible characters", ->
|
||||
atom.config.set('editor.showInvisibles', true)
|
||||
buffer.setTextInRange([[1, 0], [1, Infinity]], '\t\t\ta', false)
|
||||
buffer.setTextInRange([[1, 0], [1, Infinity]], '\t\t\ta', normalizeLineEndings: false)
|
||||
|
||||
editor.setCursorScreenPosition [1,7]
|
||||
editor.moveToFirstCharacterOfLine()
|
||||
@@ -1321,7 +1327,7 @@ describe "TextEditor", ->
|
||||
coffeeEditor.selectWordsContainingCursors()
|
||||
expect(coffeeEditor.getSelectedBufferRange()).toEqual [[0, 6], [0, 15]]
|
||||
|
||||
atom.config.set '.source.coffee', 'editor.nonWordCharacters', 'qusort'
|
||||
atom.config.set 'editor.nonWordCharacters', 'qusort', scopeSelector: '.source.coffee'
|
||||
|
||||
coffeeEditor.setCursorBufferPosition [0, 9]
|
||||
coffeeEditor.selectWordsContainingCursors()
|
||||
@@ -2477,32 +2483,32 @@ describe "TextEditor", ->
|
||||
expect(editor.getCursorScreenPosition()).toEqual [0, editor.getTabLength() * 2]
|
||||
|
||||
describe "clipboard operations", ->
|
||||
beforeEach ->
|
||||
editor.setSelectedBufferRanges([[[0, 4], [0, 13]], [[1, 6], [1, 10]]])
|
||||
|
||||
describe ".cutSelectedText()", ->
|
||||
it "removes the selected text from the buffer and places it on the clipboard", ->
|
||||
editor.setSelectedBufferRanges([[[0, 4], [0, 13]], [[1, 6], [1, 10]]])
|
||||
editor.cutSelectedText()
|
||||
expect(buffer.lineForRow(0)).toBe "var = function () {"
|
||||
expect(buffer.lineForRow(1)).toBe " var = function(items) {"
|
||||
|
||||
expect(clipboard.readText()).toBe 'quicksort\nsort'
|
||||
|
||||
describe "when no text is selected", ->
|
||||
beforeEach ->
|
||||
editor.setSelectedBufferRanges([[1, 0], [1, 0]])
|
||||
editor.addCursorAtBufferPosition([5, 0])
|
||||
editor.setSelectedBufferRanges([
|
||||
[[0, 0], [0, 0]],
|
||||
[[5, 0], [5, 0]],
|
||||
])
|
||||
|
||||
it "cuts the lines on which there are cursors", ->
|
||||
editor.cutSelectedText()
|
||||
|
||||
expect(buffer.getLineCount()).toBe(11)
|
||||
expect(buffer.lineForRow(1)).toBe(" if (items.length <= 1) return items;")
|
||||
expect(buffer.lineForRow(4)).toBe(" current < pivot ? left.push(current) : right.push(current);")
|
||||
expect(atom.clipboard.readWithMetadata().metadata.selections).toEqual([
|
||||
"var quicksort = function () {\n"
|
||||
" current = items.shift();\n"
|
||||
])
|
||||
expect(atom.clipboard.read()).toEqual """
|
||||
var quicksort = function () {
|
||||
|
||||
current = items.shift();
|
||||
|
||||
"""
|
||||
|
||||
describe ".cutToEndOfLine()", ->
|
||||
describe "when soft wrap is on", ->
|
||||
@@ -2542,11 +2548,11 @@ describe "TextEditor", ->
|
||||
expect(buffer.lineForRow(1)).toBe " var sort = function(items) {"
|
||||
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'
|
||||
])
|
||||
expect(atom.clipboard.read()).toEqual """
|
||||
quicksort
|
||||
sort
|
||||
items
|
||||
"""
|
||||
|
||||
describe "when no text is selected", ->
|
||||
beforeEach ->
|
||||
@@ -2557,40 +2563,150 @@ describe "TextEditor", ->
|
||||
|
||||
it "copies the lines on which there are cursors", ->
|
||||
editor.copySelectedText()
|
||||
expect(atom.clipboard.readWithMetadata().metadata.selections).toEqual([
|
||||
expect(atom.clipboard.read()).toEqual([
|
||||
" var sort = function(items) {\n"
|
||||
" current = items.shift();\n"
|
||||
])
|
||||
].join("\n"))
|
||||
expect(editor.getSelectedBufferRanges()).toEqual([
|
||||
[[1, 5], [1, 5]],
|
||||
[[5, 8], [5, 8]]
|
||||
])
|
||||
|
||||
describe ".pasteText()", ->
|
||||
copyText = (text, {startColumn, textEditor}={}) ->
|
||||
startColumn ?= 0
|
||||
textEditor ?= editor
|
||||
textEditor.setCursorBufferPosition([0, 0])
|
||||
textEditor.insertText(text)
|
||||
numberOfNewlines = text.match(/\n/g)?.length
|
||||
endColumn = text.match(/[^\n]*$/)[0]?.length
|
||||
textEditor.getLastSelection().setBufferRange([[0,startColumn], [numberOfNewlines,endColumn]])
|
||||
textEditor.cutSelectedText()
|
||||
|
||||
it "pastes text into the buffer", ->
|
||||
editor.setSelectedBufferRanges([[[0, 4], [0, 13]], [[1, 6], [1, 10]]])
|
||||
atom.clipboard.write('first')
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(0)).toBe "var first = function () {"
|
||||
expect(editor.lineTextForBufferRow(1)).toBe " var first = function(items) {"
|
||||
|
||||
describe "when `autoIndentOnPaste` is true", ->
|
||||
beforeEach ->
|
||||
atom.config.set("editor.autoIndentOnPaste", true)
|
||||
|
||||
describe "when only whitespace precedes the cursor", ->
|
||||
it "auto-indents the lines spanned by the pasted text", ->
|
||||
atom.clipboard.write("console.log(x);\nconsole.log(y);\n")
|
||||
editor.setCursorBufferPosition([5, 2])
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(5)).toBe(" console.log(x);")
|
||||
expect(editor.lineTextForBufferRow(6)).toBe(" console.log(y);")
|
||||
|
||||
describe "when non-whitespace characters precede the cursor", ->
|
||||
it "does not auto-indent the first line being pasted", ->
|
||||
editor.setText """
|
||||
if (x) {
|
||||
y();
|
||||
}
|
||||
"""
|
||||
|
||||
atom.clipboard.write(" z();")
|
||||
editor.setCursorBufferPosition([1, Infinity])
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(1)).toBe(" y(); z();")
|
||||
|
||||
describe "when `autoIndentOnPaste` is false", ->
|
||||
beforeEach ->
|
||||
atom.config.set('editor.autoIndentOnPaste', false)
|
||||
|
||||
describe "when the cursor is indented further than the original copied text", ->
|
||||
it "increases the indentation of the copied lines to match", ->
|
||||
editor.setSelectedBufferRange([[1, 2], [3, 0]])
|
||||
editor.copySelectedText()
|
||||
|
||||
editor.setCursorBufferPosition([5, 6])
|
||||
editor.pasteText()
|
||||
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " var sort = function(items) {"
|
||||
expect(editor.lineTextForBufferRow(6)).toBe " if (items.length <= 1) return items;"
|
||||
|
||||
describe "when the cursor is indented less far than the original copied text", ->
|
||||
it "decreases the indentation of the copied lines to match", ->
|
||||
editor.setSelectedBufferRange([[6, 6], [8, 0]])
|
||||
editor.copySelectedText()
|
||||
|
||||
editor.setCursorBufferPosition([1, 2])
|
||||
editor.pasteText()
|
||||
|
||||
expect(editor.lineTextForBufferRow(1)).toBe " current < pivot ? left.push(current) : right.push(current);"
|
||||
expect(editor.lineTextForBufferRow(2)).toBe "}"
|
||||
|
||||
describe "when the first copied line has leading whitespace", ->
|
||||
it "preserves the line's leading whitespace", ->
|
||||
editor.setSelectedBufferRange([[4, 0], [6, 0]])
|
||||
editor.copySelectedText()
|
||||
|
||||
editor.setCursorBufferPosition([0, 0])
|
||||
editor.pasteText()
|
||||
|
||||
expect(editor.lineTextForBufferRow(0)).toBe " while(items.length > 0) {"
|
||||
expect(editor.lineTextForBufferRow(1)).toBe " current = items.shift();"
|
||||
|
||||
describe 'when the clipboard has many selections', ->
|
||||
beforeEach ->
|
||||
atom.config.set("editor.autoIndentOnPaste", false)
|
||||
editor.setSelectedBufferRanges([[[0, 4], [0, 13]], [[1, 6], [1, 10]]])
|
||||
editor.copySelectedText()
|
||||
|
||||
it "pastes each selection separately into the buffer", ->
|
||||
atom.clipboard.write('first\nsecond', {selections: ['first', 'second'] })
|
||||
editor.copySelectedText()
|
||||
editor.moveRight()
|
||||
editor.insertText("_")
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(0)).toBe "var first = function () {"
|
||||
expect(editor.lineTextForBufferRow(1)).toBe " var second = function(items) {"
|
||||
expect(editor.lineTextForBufferRow(0)).toBe "var quicksort_quicksort = function () {"
|
||||
expect(editor.lineTextForBufferRow(1)).toBe " var sort_sort = 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.lineTextForBufferRow(0)).toBe "var first"
|
||||
expect(editor.lineTextForBufferRow(1)).toBe "second"
|
||||
expect(editor.lineTextForBufferRow(2)).toBe "third = function () {"
|
||||
beforeEach ->
|
||||
editor.setSelectedBufferRanges([[[0, 4], [0, 13]]])
|
||||
|
||||
expect(editor.lineTextForBufferRow(3)).toBe " var first"
|
||||
expect(editor.lineTextForBufferRow(4)).toBe "second"
|
||||
expect(editor.lineTextForBufferRow(5)).toBe "third = function(items) {"
|
||||
it "pastes the whole text into the buffer", ->
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(0)).toBe "var quicksort"
|
||||
expect(editor.lineTextForBufferRow(1)).toBe "sort = function () {"
|
||||
|
||||
describe "when a full line was cut", ->
|
||||
beforeEach ->
|
||||
editor.setCursorBufferPosition([2, 13])
|
||||
editor.cutSelectedText()
|
||||
editor.setCursorBufferPosition([2, 13])
|
||||
|
||||
it "pastes the line above the cursor and retains the cursor's column", ->
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(2)).toBe(" if (items.length <= 1) return items;")
|
||||
expect(editor.lineTextForBufferRow(3)).toBe(" var pivot = items.shift(), current, left = [], right = [];")
|
||||
expect(editor.getCursorBufferPosition()).toEqual([3, 13])
|
||||
|
||||
describe "when a full line was copied", ->
|
||||
beforeEach ->
|
||||
editor.setCursorBufferPosition([2, 13])
|
||||
editor.copySelectedText()
|
||||
|
||||
describe "when there is a selection", ->
|
||||
it "overwrites the selection as with any copied text", ->
|
||||
editor.setSelectedBufferRange([[1, 2], [1, Infinity]])
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(1)).toBe(" if (items.length <= 1) return items;")
|
||||
expect(editor.lineTextForBufferRow(2)).toBe(" ")
|
||||
expect(editor.lineTextForBufferRow(3)).toBe(" if (items.length <= 1) return items;")
|
||||
expect(editor.getCursorBufferPosition()).toEqual([2, 2])
|
||||
|
||||
describe "when there is no selection", ->
|
||||
it "pastes the line above the cursor and retains the cursor's column", ->
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(2)).toBe(" if (items.length <= 1) return items;")
|
||||
expect(editor.lineTextForBufferRow(3)).toBe(" if (items.length <= 1) return items;")
|
||||
expect(editor.getCursorBufferPosition()).toEqual([3, 13])
|
||||
|
||||
describe ".indentSelectedRows()", ->
|
||||
describe "when nothing is selected", ->
|
||||
@@ -2721,6 +2837,18 @@ describe "TextEditor", ->
|
||||
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[0, 1], [3, 0]]
|
||||
|
||||
describe ".autoIndentSelectedRows", ->
|
||||
it "auto-indents the selection", ->
|
||||
editor.setCursorBufferPosition([2, 0])
|
||||
editor.insertText("function() {\ninside=true\n}\n i=1\n")
|
||||
editor.getLastSelection().setBufferRange([[2,0], [6,0]])
|
||||
editor.autoIndentSelectedRows()
|
||||
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " function() {"
|
||||
expect(editor.lineTextForBufferRow(3)).toBe " inside=true"
|
||||
expect(editor.lineTextForBufferRow(4)).toBe " }"
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " i=1"
|
||||
|
||||
describe ".toggleLineCommentsInSelection()", ->
|
||||
it "toggles comments on the selected lines", ->
|
||||
editor.setSelectedBufferRange([[4, 5], [7, 5]])
|
||||
@@ -2892,18 +3020,16 @@ describe "TextEditor", ->
|
||||
expect(editor.isFoldedAtBufferRow(1)).toBeFalsy()
|
||||
expect(editor.isFoldedAtBufferRow(2)).toBeTruthy()
|
||||
|
||||
describe "begin/commitTransaction()", ->
|
||||
describe "::transact", ->
|
||||
it "restores the selection when the transaction is undone/redone", ->
|
||||
buffer.setText('1234')
|
||||
editor.setSelectedBufferRange([[0, 1], [0, 3]])
|
||||
editor.beginTransaction()
|
||||
|
||||
editor.delete()
|
||||
editor.moveToEndOfLine()
|
||||
editor.insertText('5')
|
||||
expect(buffer.getText()).toBe '145'
|
||||
|
||||
editor.commitTransaction()
|
||||
editor.transact ->
|
||||
editor.delete()
|
||||
editor.moveToEndOfLine()
|
||||
editor.insertText('5')
|
||||
expect(buffer.getText()).toBe '145'
|
||||
|
||||
editor.undo()
|
||||
expect(buffer.getText()).toBe '1234'
|
||||
@@ -3150,7 +3276,7 @@ describe "TextEditor", ->
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
it 'returns correct values based on the scope of the set grammars', ->
|
||||
atom.config.set '.source.coffee', 'editor.tabLength', 6
|
||||
atom.config.set 'editor.tabLength', 6, scopeSelector: '.source.coffee'
|
||||
|
||||
expect(editor.getTabLength()).toBe 2
|
||||
expect(coffeeEditor.getTabLength()).toBe 6
|
||||
@@ -3172,12 +3298,12 @@ describe "TextEditor", ->
|
||||
expect(editor.getTabLength()).toBe 2
|
||||
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 2
|
||||
|
||||
atom.config.set '.source.js', 'editor.tabLength', 6
|
||||
atom.config.set 'editor.tabLength', 6, scopeSelector: '.source.js'
|
||||
expect(editor.getTabLength()).toBe 6
|
||||
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 6
|
||||
|
||||
it 'updates the tab length when the grammar changes', ->
|
||||
atom.config.set '.source.coffee', 'editor.tabLength', 6
|
||||
atom.config.set 'editor.tabLength', 6, scopeSelector: '.source.coffee'
|
||||
|
||||
expect(editor.getTabLength()).toBe 2
|
||||
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 2
|
||||
@@ -3210,251 +3336,158 @@ describe "TextEditor", ->
|
||||
it "switches to the better-matched grammar and re-tokenizes the buffer", ->
|
||||
editor.destroy()
|
||||
|
||||
jsGrammar = atom.syntax.selectGrammar('a.js')
|
||||
atom.syntax.removeGrammar(jsGrammar)
|
||||
jsGrammar = atom.grammars.selectGrammar('a.js')
|
||||
atom.grammars.removeGrammar(jsGrammar)
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.js', autoIndent: false).then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
expect(editor.getGrammar()).toBe atom.syntax.nullGrammar
|
||||
expect(editor.getGrammar()).toBe atom.grammars.nullGrammar
|
||||
expect(editor.tokenizedLineForScreenRow(0).tokens.length).toBe 1
|
||||
|
||||
atom.syntax.addGrammar(jsGrammar)
|
||||
atom.grammars.addGrammar(jsGrammar)
|
||||
expect(editor.getGrammar()).toBe jsGrammar
|
||||
expect(editor.tokenizedLineForScreenRow(0).tokens.length).toBeGreaterThan 1
|
||||
|
||||
describe "auto-indent", ->
|
||||
copyText = (text, {startColumn, textEditor}={}) ->
|
||||
startColumn ?= 0
|
||||
textEditor ?= editor
|
||||
textEditor.setCursorBufferPosition([0, 0])
|
||||
textEditor.insertText(text)
|
||||
numberOfNewlines = text.match(/\n/g)?.length
|
||||
endColumn = text.match(/[^\n]*$/)[0]?.length
|
||||
textEditor.getLastSelection().setBufferRange([[0,startColumn], [numberOfNewlines,endColumn]])
|
||||
textEditor.cutSelectedText()
|
||||
|
||||
describe "editor.autoIndent", ->
|
||||
describe "when editor.autoIndent is false (default)", ->
|
||||
describe "when `indent` is triggered", ->
|
||||
it "does not auto-indent the line", ->
|
||||
editor.setCursorBufferPosition([1, 30])
|
||||
editor.insertText("\n ")
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
atom.config.set("editor.autoIndent", false)
|
||||
editor.indent()
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
describe "when editor.autoIndent is true", ->
|
||||
beforeEach ->
|
||||
atom.config.set("editor.autoIndent", true)
|
||||
|
||||
describe "when `indent` is triggered", ->
|
||||
it "auto-indents the line", ->
|
||||
editor.setCursorBufferPosition([1, 30])
|
||||
editor.insertText("\n ")
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
atom.config.set("editor.autoIndent", true)
|
||||
editor.indent()
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
describe "when a newline is added", ->
|
||||
describe "when the line preceding the newline adds a new level of indentation", ->
|
||||
it "indents the newline to one additional level of indentation beyond the preceding line", ->
|
||||
editor.setCursorBufferPosition([1, Infinity])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
|
||||
describe "when the line preceding the newline does't add a level of indentation", ->
|
||||
it "indents the new line to the same level a as the preceding line", ->
|
||||
editor.setCursorBufferPosition([5, 14])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(6)).toBe editor.indentationForBufferRow(5)
|
||||
|
||||
describe "when the line preceding the newline is a comment", ->
|
||||
it "maintains the indent of the commented line", ->
|
||||
editor.setCursorBufferPosition([0, 0])
|
||||
editor.insertText(' //')
|
||||
editor.setCursorBufferPosition([0, Infinity])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(1)).toBe 2
|
||||
|
||||
it "does not indent the line preceding the newline", ->
|
||||
editor.setCursorBufferPosition([2, 0])
|
||||
editor.insertText(' var this-line-should-be-indented-more\n')
|
||||
expect(editor.indentationForBufferRow(1)).toBe 1
|
||||
|
||||
atom.config.set("editor.autoIndent", true)
|
||||
editor.setCursorBufferPosition([2, Infinity])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(1)).toBe 1
|
||||
expect(editor.indentationForBufferRow(2)).toBe 1
|
||||
|
||||
describe "when the cursor is before whitespace", ->
|
||||
it "retains the whitespace following the cursor on the new line", ->
|
||||
editor.setText(" var sort = function() {}")
|
||||
editor.setCursorScreenPosition([0, 23])
|
||||
editor.insertNewline()
|
||||
|
||||
expect(buffer.lineForRow(0)).toBe ' var sort = function()'
|
||||
expect(buffer.lineForRow(1)).toBe ' {}'
|
||||
expect(editor.getCursorScreenPosition()).toEqual [1, 2]
|
||||
|
||||
describe "when inserted text matches a decrease indent pattern", ->
|
||||
describe "when the preceding line matches an increase indent pattern", ->
|
||||
it "decreases the indentation to match that of the preceding line", ->
|
||||
editor.setCursorBufferPosition([1, Infinity])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
editor.insertText('}')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1)
|
||||
|
||||
describe "when the preceding line doesn't match an increase indent pattern", ->
|
||||
it "decreases the indentation to be one level below that of the preceding line", ->
|
||||
editor.setCursorBufferPosition([3, Infinity])
|
||||
editor.insertText('\n ')
|
||||
expect(editor.indentationForBufferRow(4)).toBe editor.indentationForBufferRow(3)
|
||||
editor.insertText('}')
|
||||
expect(editor.indentationForBufferRow(4)).toBe editor.indentationForBufferRow(3) - 1
|
||||
|
||||
it "doesn't break when decreasing the indentation on a row that has no indentation", ->
|
||||
editor.setCursorBufferPosition([12, Infinity])
|
||||
editor.insertText("\n}; # too many closing brackets!")
|
||||
expect(editor.lineTextForBufferRow(13)).toBe "}; # too many closing brackets!"
|
||||
|
||||
describe "when inserted text does not match a decrease indent pattern", ->
|
||||
it "does not decrease the indentation", ->
|
||||
editor.setCursorBufferPosition([12, 0])
|
||||
editor.insertText(' ')
|
||||
expect(editor.lineTextForBufferRow(12)).toBe ' };'
|
||||
editor.insertText('\t\t')
|
||||
expect(editor.lineTextForBufferRow(12)).toBe ' \t\t};'
|
||||
|
||||
describe "when the current line does not match a decrease indent pattern", ->
|
||||
it "leaves the line unchanged", ->
|
||||
editor.setCursorBufferPosition([2, 4])
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
editor.insertText('foo')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
|
||||
describe 'when scoped settings are used', ->
|
||||
coffeeEditor = null
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-coffee-script')
|
||||
waitsForPromise ->
|
||||
atom.project.open('coffee.coffee', autoIndent: false).then (o) -> coffeeEditor = o
|
||||
|
||||
runs ->
|
||||
atom.config.set('.source.js', 'editor.autoIndent', true)
|
||||
atom.config.set('.source.coffee', 'editor.autoIndent', false)
|
||||
|
||||
afterEach: ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
it "does not auto-indent the line for javascript files", ->
|
||||
describe "editor.autoIndent", ->
|
||||
describe "when editor.autoIndent is false (default)", ->
|
||||
describe "when `indent` is triggered", ->
|
||||
it "does not auto-indent the line", ->
|
||||
editor.setCursorBufferPosition([1, 30])
|
||||
editor.insertText("\n")
|
||||
editor.insertText("\n ")
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
atom.config.set("editor.autoIndent", false)
|
||||
editor.indent()
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
describe "when editor.autoIndent is true", ->
|
||||
beforeEach ->
|
||||
atom.config.set("editor.autoIndent", true)
|
||||
|
||||
describe "when `indent` is triggered", ->
|
||||
it "auto-indents the line", ->
|
||||
editor.setCursorBufferPosition([1, 30])
|
||||
editor.insertText("\n ")
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
atom.config.set("editor.autoIndent", true)
|
||||
editor.indent()
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
coffeeEditor.setCursorBufferPosition([1, 18])
|
||||
coffeeEditor.insertText("\n")
|
||||
expect(coffeeEditor.lineTextForBufferRow(2)).toBe ""
|
||||
|
||||
describe "editor.normalizeIndentOnPaste", ->
|
||||
beforeEach ->
|
||||
atom.config.set('editor.normalizeIndentOnPaste', true)
|
||||
|
||||
it "does not normalize the indentation level of the text when editor.normalizeIndentOnPaste is false", ->
|
||||
copyText(" function() {\nvar cool = 1;\n }\n")
|
||||
atom.config.set('editor.normalizeIndentOnPaste', false)
|
||||
editor.setCursorBufferPosition([5, 2])
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " function() {"
|
||||
expect(editor.lineTextForBufferRow(6)).toBe "var cool = 1;"
|
||||
expect(editor.lineTextForBufferRow(7)).toBe " }"
|
||||
|
||||
describe "when the inserted text contains no newlines", ->
|
||||
it "does not adjust the indentation level of the text", ->
|
||||
editor.setCursorBufferPosition([5, 2])
|
||||
editor.insertText("foo", indentBasis: 5)
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " foo current = items.shift();"
|
||||
|
||||
it "does not adjust the whitespace if there are preceding characters", ->
|
||||
copyText(" foo")
|
||||
editor.setCursorBufferPosition([5, 30])
|
||||
editor.pasteText()
|
||||
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " current = items.shift(); foo"
|
||||
|
||||
describe "when the inserted text contains newlines", ->
|
||||
describe "when the cursor is preceded only by whitespace characters", ->
|
||||
it "normalizes indented lines to the cursor's current indentation level", ->
|
||||
copyText(" while (true) {\n foo();\n }\n", {startColumn: 2})
|
||||
editor.setCursorBufferPosition([3, 4])
|
||||
editor.pasteText()
|
||||
|
||||
expect(editor.lineTextForBufferRow(3)).toBe " while (true) {"
|
||||
expect(editor.lineTextForBufferRow(4)).toBe " foo();"
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " }"
|
||||
expect(editor.lineTextForBufferRow(6)).toBe "var pivot = items.shift(), current, left = [], right = [];"
|
||||
|
||||
describe "when the cursor is preceded by non-whitespace characters", ->
|
||||
it "normalizes the indentation level of all lines based on the level of the existing first line", ->
|
||||
copyText(" while (true) {\n foo();\n }\n", {startColumn: 0})
|
||||
describe "when a newline is added", ->
|
||||
describe "when the line preceding the newline adds a new level of indentation", ->
|
||||
it "indents the newline to one additional level of indentation beyond the preceding line", ->
|
||||
editor.setCursorBufferPosition([1, Infinity])
|
||||
editor.pasteText()
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
|
||||
expect(editor.lineTextForBufferRow(1)).toBe " var sort = function(items) {while (true) {"
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " foo();"
|
||||
expect(editor.lineTextForBufferRow(3)).toBe " }"
|
||||
expect(editor.lineTextForBufferRow(4)).toBe ""
|
||||
describe "when the line preceding the newline does't add a level of indentation", ->
|
||||
it "indents the new line to the same level a as the preceding line", ->
|
||||
editor.setCursorBufferPosition([5, 14])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(6)).toBe editor.indentationForBufferRow(5)
|
||||
|
||||
describe 'when scoped settings are used', ->
|
||||
coffeeEditor = null
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-coffee-script')
|
||||
waitsForPromise ->
|
||||
atom.project.open('coffee.coffee', autoIndent: false).then (o) -> coffeeEditor = o
|
||||
describe "when the line preceding the newline is a comment", ->
|
||||
it "maintains the indent of the commented line", ->
|
||||
editor.setCursorBufferPosition([0, 0])
|
||||
editor.insertText(' //')
|
||||
editor.setCursorBufferPosition([0, Infinity])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(1)).toBe 2
|
||||
|
||||
runs ->
|
||||
atom.config.set('.source.js', 'editor.normalizeIndentOnPaste', true)
|
||||
atom.config.set('.source.coffee', 'editor.normalizeIndentOnPaste', false)
|
||||
describe "when the line preceding the newline contains only whitespace", ->
|
||||
it "bases the new line's indentation on only the preceding line", ->
|
||||
editor.setCursorBufferPosition([6, Infinity])
|
||||
editor.insertText("\n ")
|
||||
expect(editor.getCursorBufferPosition()).toEqual([7, 2])
|
||||
|
||||
afterEach: ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
editor.insertNewline()
|
||||
expect(editor.lineTextForBufferRow(8)).toBe(" ")
|
||||
|
||||
it "normalizes the indentation level based on scoped settings", ->
|
||||
copyText(" while (true) {\n foo();\n }\n", {startColumn: 2, textEditor: coffeeEditor})
|
||||
coffeeEditor.setCursorBufferPosition([4, 4])
|
||||
coffeeEditor.pasteText()
|
||||
expect(coffeeEditor.lineTextForBufferRow(4)).toBe " while (true) {"
|
||||
expect(coffeeEditor.lineTextForBufferRow(5)).toBe " foo();"
|
||||
expect(coffeeEditor.lineTextForBufferRow(6)).toBe " }"
|
||||
it "does not indent the line preceding the newline", ->
|
||||
editor.setCursorBufferPosition([2, 0])
|
||||
editor.insertText(' var this-line-should-be-indented-more\n')
|
||||
expect(editor.indentationForBufferRow(1)).toBe 1
|
||||
|
||||
copyText(" while (true) {\n foo();\n }\n", {startColumn: 2})
|
||||
editor.setCursorBufferPosition([3, 4])
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(3)).toBe " while (true) {"
|
||||
expect(editor.lineTextForBufferRow(4)).toBe " foo();"
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " }"
|
||||
atom.config.set("editor.autoIndent", true)
|
||||
editor.setCursorBufferPosition([2, Infinity])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(1)).toBe 1
|
||||
expect(editor.indentationForBufferRow(2)).toBe 1
|
||||
|
||||
it "autoIndentSelectedRows auto-indents the selection", ->
|
||||
editor.setCursorBufferPosition([2, 0])
|
||||
editor.insertText("function() {\ninside=true\n}\n i=1\n")
|
||||
editor.getLastSelection().setBufferRange([[2,0], [6,0]])
|
||||
editor.autoIndentSelectedRows()
|
||||
describe "when the cursor is before whitespace", ->
|
||||
it "retains the whitespace following the cursor on the new line", ->
|
||||
editor.setText(" var sort = function() {}")
|
||||
editor.setCursorScreenPosition([0, 12])
|
||||
editor.insertNewline()
|
||||
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " function() {"
|
||||
expect(editor.lineTextForBufferRow(3)).toBe " inside=true"
|
||||
expect(editor.lineTextForBufferRow(4)).toBe " }"
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " i=1"
|
||||
expect(buffer.lineForRow(0)).toBe ' var sort ='
|
||||
expect(buffer.lineForRow(1)).toBe ' function() {}'
|
||||
expect(editor.getCursorScreenPosition()).toEqual [1, 2]
|
||||
|
||||
describe "when inserted text matches a decrease indent pattern", ->
|
||||
describe "when the preceding line matches an increase indent pattern", ->
|
||||
it "decreases the indentation to match that of the preceding line", ->
|
||||
editor.setCursorBufferPosition([1, Infinity])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
editor.insertText('}')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1)
|
||||
|
||||
describe "when the preceding line doesn't match an increase indent pattern", ->
|
||||
it "decreases the indentation to be one level below that of the preceding line", ->
|
||||
editor.setCursorBufferPosition([3, Infinity])
|
||||
editor.insertText('\n ')
|
||||
expect(editor.indentationForBufferRow(4)).toBe editor.indentationForBufferRow(3)
|
||||
editor.insertText('}')
|
||||
expect(editor.indentationForBufferRow(4)).toBe editor.indentationForBufferRow(3) - 1
|
||||
|
||||
it "doesn't break when decreasing the indentation on a row that has no indentation", ->
|
||||
editor.setCursorBufferPosition([12, Infinity])
|
||||
editor.insertText("\n}; # too many closing brackets!")
|
||||
expect(editor.lineTextForBufferRow(13)).toBe "}; # too many closing brackets!"
|
||||
|
||||
describe "when inserted text does not match a decrease indent pattern", ->
|
||||
it "does not decrease the indentation", ->
|
||||
editor.setCursorBufferPosition([12, 0])
|
||||
editor.insertText(' ')
|
||||
expect(editor.lineTextForBufferRow(12)).toBe ' };'
|
||||
editor.insertText('\t\t')
|
||||
expect(editor.lineTextForBufferRow(12)).toBe ' \t\t};'
|
||||
|
||||
describe "when the current line does not match a decrease indent pattern", ->
|
||||
it "leaves the line unchanged", ->
|
||||
editor.setCursorBufferPosition([2, 4])
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
editor.insertText('foo')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
|
||||
describe 'when scoped settings are used', ->
|
||||
coffeeEditor = null
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-coffee-script')
|
||||
waitsForPromise ->
|
||||
atom.project.open('coffee.coffee', autoIndent: false).then (o) -> coffeeEditor = o
|
||||
|
||||
runs ->
|
||||
atom.config.set('editor.autoIndent', true, scopeSelector: '.source.js')
|
||||
atom.config.set('editor.autoIndent', false, scopeSelector: '.source.coffee')
|
||||
|
||||
afterEach: ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
it "does not auto-indent the line for javascript files", ->
|
||||
editor.setCursorBufferPosition([1, 30])
|
||||
editor.insertText("\n")
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
coffeeEditor.setCursorBufferPosition([1, 18])
|
||||
coffeeEditor.insertText("\n")
|
||||
expect(coffeeEditor.lineTextForBufferRow(2)).toBe ""
|
||||
|
||||
describe "soft and hard tabs", ->
|
||||
afterEach ->
|
||||
@@ -3732,7 +3765,7 @@ describe "TextEditor", ->
|
||||
|
||||
it "updates the grammar based on grammar overrides", ->
|
||||
expect(editor.getGrammar().name).toBe 'JavaScript'
|
||||
atom.syntax.setGrammarOverrideForPath(editor.getPath(), 'source.coffee')
|
||||
atom.grammars.setGrammarOverrideForPath(editor.getPath(), 'source.coffee')
|
||||
editor.reloadGrammar()
|
||||
expect(editor.getGrammar().name).toBe 'CoffeeScript'
|
||||
|
||||
@@ -3750,7 +3783,7 @@ describe "TextEditor", ->
|
||||
atom.packages.activatePackage('language-hyperlink')
|
||||
|
||||
runs ->
|
||||
grammar = atom.syntax.selectGrammar("text.js")
|
||||
grammar = atom.grammars.selectGrammar("text.js")
|
||||
{tokens} = grammar.tokenizeLine("var i; // http://github.com")
|
||||
|
||||
expect(tokens[0].value).toBe "var"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
path = require 'path'
|
||||
|
||||
{$, $$, WorkspaceView} = require 'atom'
|
||||
{$, $$} = require '../src/space-pen-extensions'
|
||||
fs = require 'fs-plus'
|
||||
temp = require 'temp'
|
||||
|
||||
@@ -20,8 +20,12 @@ describe "ThemeManager", ->
|
||||
|
||||
describe "theme getters and setters", ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
atom.packages.loadPackages()
|
||||
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it 'getLoadedThemes get all the loaded themes', ->
|
||||
themes = themeManager.getLoadedThemes()
|
||||
expect(themes.length).toBeGreaterThan(2)
|
||||
@@ -70,7 +74,7 @@ describe "ThemeManager", ->
|
||||
describe "when the core.themes config value changes", ->
|
||||
it "add/removes stylesheets to reflect the new config value", ->
|
||||
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
|
||||
spyOn(themeManager, 'getUserStylesheetPath').andCallFake -> null
|
||||
spyOn(atom.styles, 'getUserStyleSheetPath').andCallFake -> null
|
||||
|
||||
waitsForPromise ->
|
||||
themeManager.activateThemes()
|
||||
@@ -130,15 +134,24 @@ describe "ThemeManager", ->
|
||||
expect(-> atom.packages.activatePackage('a-theme-that-will-not-be-found')).toThrow()
|
||||
|
||||
describe "::requireStylesheet(path)", ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "synchronously loads css at the given path and installs a style tag for it in the head", ->
|
||||
atom.styles.onDidAddStyleElement styleElementAddedHandler = jasmine.createSpy("styleElementAddedHandler")
|
||||
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
themeManager.onDidAddStylesheet 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(styleElementAddedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetAddedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
|
||||
@@ -148,8 +161,10 @@ describe "ThemeManager", ->
|
||||
expect(element[0].sheet).toBe stylesheetAddedHandler.argsForCall[0][0]
|
||||
|
||||
# doesn't append twice
|
||||
styleElementAddedHandler.reset()
|
||||
themeManager.requireStylesheet(cssPath)
|
||||
expect($('head style').length).toBe lengthBefore + 1
|
||||
expect(styleElementAddedHandler).not.toHaveBeenCalled()
|
||||
|
||||
$('head style[id*="css.css"]').remove()
|
||||
|
||||
@@ -192,6 +207,7 @@ describe "ThemeManager", ->
|
||||
disposable = themeManager.requireStylesheet(cssPath)
|
||||
expect($(document.body).css('font-weight')).toBe("bold")
|
||||
|
||||
atom.styles.onDidRemoveStyleElement styleElementRemovedHandler = jasmine.createSpy("styleElementRemovedHandler")
|
||||
themeManager.onDidRemoveStylesheet stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
|
||||
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
|
||||
@@ -199,6 +215,7 @@ describe "ThemeManager", ->
|
||||
|
||||
expect($(document.body).css('font-weight')).not.toBe("bold")
|
||||
|
||||
expect(styleElementRemovedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetRemovedHandler).toHaveBeenCalled()
|
||||
stylesheet = stylesheetRemovedHandler.argsForCall[0][0]
|
||||
expect(stylesheet instanceof CSSStyleSheet).toBe true
|
||||
@@ -207,14 +224,20 @@ describe "ThemeManager", ->
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
|
||||
describe "base stylesheet loading", ->
|
||||
workspaceElement = null
|
||||
beforeEach ->
|
||||
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView.append $('<atom-text-editor>')
|
||||
atom.workspaceView.attachToDom()
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
workspaceElement.appendChild document.createElement('atom-text-editor')
|
||||
|
||||
waitsForPromise ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
beforeEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "loads the correct values from the theme's ui-variables file", ->
|
||||
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
|
||||
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
|
||||
@@ -224,7 +247,7 @@ describe "ThemeManager", ->
|
||||
|
||||
runs ->
|
||||
# an override loaded in the base css
|
||||
expect(atom.workspaceView.css("background-color")).toBe "rgb(0, 0, 255)"
|
||||
expect(getComputedStyle(workspaceElement)["background-color"]).toBe "rgb(0, 0, 255)"
|
||||
|
||||
# from within the theme itself
|
||||
expect($("atom-text-editor").css("padding-top")).toBe "150px"
|
||||
@@ -241,14 +264,14 @@ describe "ThemeManager", ->
|
||||
|
||||
runs ->
|
||||
# an override loaded in the base css
|
||||
expect(atom.workspaceView.css("background-color")).toBe "rgb(0, 0, 255)"
|
||||
expect(getComputedStyle(workspaceElement)["background-color"]).toBe "rgb(0, 0, 255)"
|
||||
|
||||
# from within the theme itself
|
||||
expect($("atom-text-editor").css("background-color")).toBe "rgb(0, 152, 255)"
|
||||
|
||||
describe "theme classes on the workspace", ->
|
||||
it 'adds theme-* classes to the workspace for each active theme', ->
|
||||
expect(atom.workspaceView).toHaveClass 'theme-atom-dark-ui'
|
||||
expect(workspaceElement).toHaveClass 'theme-atom-dark-ui'
|
||||
|
||||
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
|
||||
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
|
||||
@@ -258,22 +281,32 @@ describe "ThemeManager", ->
|
||||
|
||||
runs ->
|
||||
# `theme-` twice as it prefixes the name with `theme-`
|
||||
expect(atom.workspaceView).toHaveClass 'theme-theme-with-ui-variables'
|
||||
expect(atom.workspaceView).toHaveClass 'theme-theme-with-syntax-variables'
|
||||
expect(atom.workspaceView).not.toHaveClass 'theme-atom-dark-ui'
|
||||
expect(atom.workspaceView).not.toHaveClass 'theme-atom-dark-syntax'
|
||||
expect(workspaceElement).toHaveClass 'theme-theme-with-ui-variables'
|
||||
expect(workspaceElement).toHaveClass 'theme-theme-with-syntax-variables'
|
||||
expect(workspaceElement).not.toHaveClass 'theme-atom-dark-ui'
|
||||
expect(workspaceElement).not.toHaveClass 'theme-atom-dark-syntax'
|
||||
|
||||
describe "when the user stylesheet changes", ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "reloads it", ->
|
||||
[styleElementAddedHandler, styleElementRemovedHandler] = []
|
||||
[stylesheetRemovedHandler, stylesheetAddedHandler, stylesheetsChangedHandler] = []
|
||||
userStylesheetPath = path.join(temp.mkdirSync("atom"), 'styles.less')
|
||||
fs.writeFileSync(userStylesheetPath, 'body {border-style: dotted !important;}')
|
||||
spyOn(themeManager, 'getUserStylesheetPath').andReturn userStylesheetPath
|
||||
spyOn(atom.styles, 'getUserStyleSheetPath').andReturn userStylesheetPath
|
||||
|
||||
waitsForPromise ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
runs ->
|
||||
atom.styles.onDidRemoveStyleElement styleElementRemovedHandler = jasmine.createSpy("styleElementRemovedHandler")
|
||||
atom.styles.onDidAddStyleElement styleElementAddedHandler = jasmine.createSpy("styleElementAddedHandler")
|
||||
|
||||
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
themeManager.onDidRemoveStylesheet stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
|
||||
themeManager.onDidAddStylesheet stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
|
||||
@@ -288,14 +321,19 @@ describe "ThemeManager", ->
|
||||
runs ->
|
||||
expect($(document.body).css('border-style')).toBe 'dashed'
|
||||
|
||||
expect(styleElementRemovedHandler).toHaveBeenCalled()
|
||||
expect(styleElementRemovedHandler.argsForCall[0][0].textContent).toContain 'dotted'
|
||||
expect(stylesheetRemovedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetRemovedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dotted'
|
||||
|
||||
expect(styleElementAddedHandler).toHaveBeenCalled()
|
||||
expect(styleElementAddedHandler.argsForCall[0][0].textContent).toContain 'dashed'
|
||||
expect(stylesheetAddedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetAddedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dashed'
|
||||
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
|
||||
styleElementRemovedHandler.reset()
|
||||
stylesheetRemovedHandler.reset()
|
||||
stylesheetsChangedHandler.reset()
|
||||
fs.removeSync(userStylesheetPath)
|
||||
@@ -304,6 +342,8 @@ describe "ThemeManager", ->
|
||||
themeManager.loadUserStylesheet.callCount is 2
|
||||
|
||||
runs ->
|
||||
expect(styleElementRemovedHandler).toHaveBeenCalled()
|
||||
expect(styleElementRemovedHandler.argsForCall[0][0].textContent).toContain 'dashed'
|
||||
expect(stylesheetRemovedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetRemovedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dashed'
|
||||
expect($(document.body).css('border-style')).toBe 'none'
|
||||
|
||||
@@ -522,7 +522,7 @@ describe "TokenizedBuffer", ->
|
||||
buffer = atom.project.bufferForPathSync()
|
||||
buffer.setText "<div class='name'><%= User.find(2).full_name %></div>"
|
||||
tokenizedBuffer = new TokenizedBuffer({buffer})
|
||||
tokenizedBuffer.setGrammar(atom.syntax.selectGrammar('test.erb'))
|
||||
tokenizedBuffer.setGrammar(atom.grammars.selectGrammar('test.erb'))
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
|
||||
{tokens} = tokenizedBuffer.tokenizedLineForRow(0)
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
TooltipManager = require '../src/tooltip-manager'
|
||||
{$} = require '../src/space-pen-extensions'
|
||||
|
||||
describe "TooltipManager", ->
|
||||
[manager, element] = []
|
||||
|
||||
beforeEach ->
|
||||
manager = new TooltipManager
|
||||
element = document.createElement('div')
|
||||
element.classList.add('foo')
|
||||
jasmine.attachToDOM(element)
|
||||
|
||||
hover = (element, fn) ->
|
||||
$(element).trigger 'mouseenter'
|
||||
advanceClock(manager.defaults.delay.show)
|
||||
fn()
|
||||
$(element).trigger 'mouseleave'
|
||||
advanceClock(manager.defaults.delay.hide)
|
||||
|
||||
describe "::add(target, options)", ->
|
||||
describe "when the target is an element", ->
|
||||
it "creates a tooltip based on the given options when hovering over the target element", ->
|
||||
manager.add element, title: "Title"
|
||||
hover element, ->
|
||||
expect(document.body.querySelector(".tooltip")).toHaveText("Title")
|
||||
|
||||
describe "when a keyBindingCommand is specified", ->
|
||||
describe "when a title is specified", ->
|
||||
it "appends the key binding corresponding to the command to the title", ->
|
||||
atom.keymaps.add 'test',
|
||||
'.foo': 'ctrl-x ctrl-y': 'test-command'
|
||||
'.bar': 'ctrl-x ctrl-z': 'test-command'
|
||||
|
||||
manager.add element, title: "Title", keyBindingCommand: 'test-command'
|
||||
|
||||
hover element, ->
|
||||
tooltipElement = document.body.querySelector(".tooltip")
|
||||
expect(tooltipElement).toHaveText "Title ⌃X ⌃Y"
|
||||
|
||||
describe "when no title is specified", ->
|
||||
it "shows the key binding corresponding to the command alone", ->
|
||||
atom.keymaps.add 'test', '.foo': 'ctrl-x ctrl-y': 'test-command'
|
||||
|
||||
manager.add element, keyBindingCommand: 'test-command'
|
||||
|
||||
hover element, ->
|
||||
tooltipElement = document.body.querySelector(".tooltip")
|
||||
expect(tooltipElement).toHaveText "⌃X ⌃Y"
|
||||
|
||||
describe "when a keyBindingTarget is specified", ->
|
||||
it "looks up the key binding relative to the target", ->
|
||||
atom.keymaps.add 'test',
|
||||
'.bar': 'ctrl-x ctrl-z': 'test-command'
|
||||
'.foo': 'ctrl-x ctrl-y': 'test-command'
|
||||
|
||||
manager.add element, keyBindingCommand: 'test-command', keyBindingTarget: element
|
||||
|
||||
hover element, ->
|
||||
tooltipElement = document.body.querySelector(".tooltip")
|
||||
expect(tooltipElement).toHaveText "⌃X ⌃Y"
|
||||
|
||||
it "does not display the keybinding if there is nothing mapped to the specified keyBindingCommand", ->
|
||||
manager.add element, title: 'A Title', keyBindingCommand: 'test-command', keyBindingTarget: element
|
||||
|
||||
hover element, ->
|
||||
tooltipElement = document.body.querySelector(".tooltip")
|
||||
expect(tooltipElement.textContent).toBe "A Title"
|
||||
|
||||
describe "when .dispose() is called on the returned disposable", ->
|
||||
it "no longer displays the tooltip on hover", ->
|
||||
disposable = manager.add element, title: "Title"
|
||||
|
||||
hover element, ->
|
||||
expect(document.body.querySelector(".tooltip")).toHaveText("Title")
|
||||
|
||||
disposable.dispose()
|
||||
|
||||
hover element, ->
|
||||
expect(document.body.querySelector(".tooltip")).toBeNull()
|
||||
@@ -25,47 +25,27 @@ describe "ViewRegistry", ->
|
||||
|
||||
describe "when passed a model object", ->
|
||||
describe "when a view provider is registered matching the object's constructor", ->
|
||||
describe "when the provider has a viewConstructor property", ->
|
||||
it "constructs a view element and assigns the model on it", ->
|
||||
class TestModel
|
||||
it "constructs a view element and assigns the model on it", ->
|
||||
class TestModel
|
||||
|
||||
class TestModelSubclass extends TestModel
|
||||
class TestModelSubclass extends TestModel
|
||||
|
||||
class TestView
|
||||
setModel: (@model) ->
|
||||
class TestView
|
||||
initialize: (@model) -> this
|
||||
|
||||
model = new TestModel
|
||||
model = new TestModel
|
||||
|
||||
registry.addViewProvider
|
||||
modelConstructor: TestModel
|
||||
viewConstructor: TestView
|
||||
registry.addViewProvider TestModel, (model) ->
|
||||
new TestView().initialize(model)
|
||||
|
||||
view = registry.getView(model)
|
||||
expect(view instanceof TestView).toBe true
|
||||
expect(view.model).toBe model
|
||||
view = registry.getView(model)
|
||||
expect(view instanceof TestView).toBe true
|
||||
expect(view.model).toBe model
|
||||
|
||||
subclassModel = new TestModelSubclass
|
||||
view2 = registry.getView(subclassModel)
|
||||
expect(view2 instanceof TestView).toBe true
|
||||
expect(view2.model).toBe subclassModel
|
||||
|
||||
describe "when the provider has a createView method", ->
|
||||
it "constructs a view element by calling the createView method with the model", ->
|
||||
class TestModel
|
||||
class TestView
|
||||
setModel: (@model) ->
|
||||
|
||||
registry.addViewProvider
|
||||
modelConstructor: TestModel
|
||||
createView: (model) ->
|
||||
view = new TestView
|
||||
view.setModel(model)
|
||||
view
|
||||
|
||||
model = new TestModel
|
||||
view = registry.getView(model)
|
||||
expect(view instanceof TestView).toBe true
|
||||
expect(view.model).toBe model
|
||||
subclassModel = new TestModelSubclass
|
||||
view2 = registry.getView(subclassModel)
|
||||
expect(view2 instanceof TestView).toBe true
|
||||
expect(view2.model).toBe subclassModel
|
||||
|
||||
describe "when no view provider is registered for the object's constructor", ->
|
||||
describe "when the object has a .getViewClass() method", ->
|
||||
@@ -97,10 +77,10 @@ describe "ViewRegistry", ->
|
||||
it "returns a disposable that can be used to remove the provider", ->
|
||||
class TestModel
|
||||
class TestView
|
||||
setModel: (@model) ->
|
||||
disposable = registry.addViewProvider
|
||||
modelConstructor: TestModel
|
||||
viewConstructor: TestView
|
||||
initialize: (@model) -> this
|
||||
|
||||
disposable = registry.addViewProvider TestModel, (model) ->
|
||||
new TestView().initialize(model)
|
||||
|
||||
expect(registry.getView(new TestModel) instanceof TestView).toBe true
|
||||
disposable.dispose()
|
||||
|
||||
+15
-18
@@ -1,4 +1,4 @@
|
||||
{$, $$} = require 'atom'
|
||||
{$, $$} = require '../src/space-pen-extensions'
|
||||
path = require 'path'
|
||||
TextEditor = require '../src/text-editor'
|
||||
WindowEventHandler = require '../src/window-event-handler'
|
||||
@@ -95,13 +95,13 @@ describe "Window", ->
|
||||
describe ".unloadEditorWindow()", ->
|
||||
it "saves the serialized state of the window so it can be deserialized after reload", ->
|
||||
workspaceState = atom.workspace.serialize()
|
||||
syntaxState = atom.syntax.serialize()
|
||||
syntaxState = atom.grammars.serialize()
|
||||
projectState = atom.project.serialize()
|
||||
|
||||
atom.unloadEditorWindow()
|
||||
|
||||
expect(atom.state.workspace).toEqual workspaceState
|
||||
expect(atom.state.syntax).toEqual syntaxState
|
||||
expect(atom.state.grammars).toEqual syntaxState
|
||||
expect(atom.state.project).toEqual projectState
|
||||
expect(atom.saveSync).toHaveBeenCalled()
|
||||
|
||||
@@ -112,9 +112,9 @@ describe "Window", ->
|
||||
|
||||
runs ->
|
||||
buffer = atom.workspace.getActivePaneItem().buffer
|
||||
pane = atom.workspaceView.getActivePaneView()
|
||||
pane.splitRight(pane.copyActiveItem())
|
||||
expect(atom.workspaceView.find('atom-text-editor').length).toBe 2
|
||||
pane = atom.workspace.getActivePane()
|
||||
pane.splitRight(copyActiveItem: true)
|
||||
expect(atom.workspace.getTextEditors().length).toBe 2
|
||||
|
||||
atom.removeEditorWindow()
|
||||
|
||||
@@ -128,17 +128,15 @@ describe "Window", ->
|
||||
setData: (key, value) -> @data[key] = value
|
||||
getData: (key) -> @data[key]
|
||||
|
||||
event = $.Event(type)
|
||||
event.originalEvent = { dataTransfer }
|
||||
event.preventDefault = ->
|
||||
event.stopPropagation = ->
|
||||
event = new CustomEvent("drop")
|
||||
event.dataTransfer = dataTransfer
|
||||
event
|
||||
|
||||
describe "when a file is dragged to window", ->
|
||||
it "opens it", ->
|
||||
spyOn(atom, "open")
|
||||
event = buildDragEvent("drop", [ {path: "/fake1"}, {path: "/fake2"} ])
|
||||
$(document).trigger(event)
|
||||
document.dispatchEvent(event)
|
||||
expect(atom.open.callCount).toBe 1
|
||||
expect(atom.open.argsForCall[0][0]).toEqual pathsToOpen: ['/fake1', '/fake2']
|
||||
|
||||
@@ -146,7 +144,7 @@ describe "Window", ->
|
||||
it "does nothing", ->
|
||||
spyOn(atom, "open")
|
||||
event = buildDragEvent("drop", [])
|
||||
$(document).trigger(event)
|
||||
document.dispatchEvent(event)
|
||||
expect(atom.open).not.toHaveBeenCalled()
|
||||
|
||||
describe "when a link is clicked", ->
|
||||
@@ -259,24 +257,23 @@ describe "Window", ->
|
||||
|
||||
describe "when the opened path exists", ->
|
||||
it "sets the project path to the opened path", ->
|
||||
$(window).trigger('window:open-path', [{pathToOpen: __filename}])
|
||||
|
||||
atom.getCurrentWindow().send 'message', 'open-path', pathToOpen: __filename
|
||||
expect(atom.project.getPaths()[0]).toBe __dirname
|
||||
|
||||
describe "when the opened path does not exist but its parent directory does", ->
|
||||
it "sets the project path to the opened path's parent directory", ->
|
||||
$(window).trigger('window:open-path', [{pathToOpen: path.join(__dirname, 'this-path-does-not-exist.txt')}])
|
||||
|
||||
pathToOpen = path.join(__dirname, 'this-path-does-not-exist.txt')
|
||||
atom.getCurrentWindow().send 'message', 'open-path', {pathToOpen}
|
||||
expect(atom.project.getPaths()[0]).toBe __dirname
|
||||
|
||||
describe "when the opened path is a file", ->
|
||||
it "opens it in the workspace", ->
|
||||
$(window).trigger('window:open-path', [{pathToOpen: __filename}])
|
||||
atom.getCurrentWindow().send 'message', 'open-path', pathToOpen: __filename
|
||||
|
||||
expect(atom.workspace.open.mostRecentCall.args[0]).toBe __filename
|
||||
|
||||
describe "when the opened path is a directory", ->
|
||||
it "does not open it in the workspace", ->
|
||||
$(window).trigger('window:open-path', [{pathToOpen: __dirname}])
|
||||
atom.getCurrentWindow().send 'message', 'open-path', pathToOpen: __dirname
|
||||
|
||||
expect(atom.workspace.open.callCount).toBe 0
|
||||
|
||||
@@ -356,7 +356,7 @@ describe "Workspace", ->
|
||||
atom.workspace.open('sample.coffee')
|
||||
|
||||
runs ->
|
||||
atom.workspace.getActiveEditor().setText """
|
||||
atom.workspace.getActiveTextEditor().setText """
|
||||
i = /test/; #FIXME
|
||||
"""
|
||||
|
||||
@@ -375,7 +375,7 @@ describe "Workspace", ->
|
||||
describe "document.title", ->
|
||||
describe "when the project has no path", ->
|
||||
it "sets the title to 'untitled'", ->
|
||||
atom.project.setPath(undefined)
|
||||
atom.project.setPaths([])
|
||||
expect(document.title).toBe 'untitled - Atom'
|
||||
|
||||
describe "when the project has a path", ->
|
||||
@@ -458,46 +458,98 @@ describe "Workspace", ->
|
||||
expect(atom.setDocumentEdited).toHaveBeenCalledWith(false)
|
||||
|
||||
describe "adding panels", ->
|
||||
class TestPanel
|
||||
constructior: ->
|
||||
class TestItem
|
||||
|
||||
class TestItemElement extends HTMLElement
|
||||
constructor: ->
|
||||
initialize: (@model) -> this
|
||||
getModel: -> @model
|
||||
|
||||
beforeEach ->
|
||||
atom.views.addViewProvider TestItem, (model) ->
|
||||
new TestItemElement().initialize(model)
|
||||
|
||||
describe '::addLeftPanel(model)', ->
|
||||
it 'adds a panel to the correct panel container', ->
|
||||
expect(atom.workspace.getLeftPanels().length).toBe(0)
|
||||
atom.workspace.panelContainers.left.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = atom.workspace.addLeftPanel(item: new TestPanel())
|
||||
|
||||
model = new TestItem
|
||||
panel = atom.workspace.addLeftPanel(item: model)
|
||||
|
||||
expect(panel).toBeDefined()
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
|
||||
itemView = atom.views.getView(atom.workspace.getLeftPanels()[0].getItem())
|
||||
expect(itemView instanceof TestItemElement).toBe(true)
|
||||
expect(itemView.getModel()).toBe(model)
|
||||
|
||||
describe '::addRightPanel(model)', ->
|
||||
it 'adds a panel to the correct panel container', ->
|
||||
expect(atom.workspace.getRightPanels().length).toBe(0)
|
||||
atom.workspace.panelContainers.right.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = atom.workspace.addRightPanel(item: new TestPanel())
|
||||
|
||||
model = new TestItem
|
||||
panel = atom.workspace.addRightPanel(item: model)
|
||||
|
||||
expect(panel).toBeDefined()
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
|
||||
itemView = atom.views.getView(atom.workspace.getRightPanels()[0].getItem())
|
||||
expect(itemView instanceof TestItemElement).toBe(true)
|
||||
expect(itemView.getModel()).toBe(model)
|
||||
|
||||
describe '::addTopPanel(model)', ->
|
||||
it 'adds a panel to the correct panel container', ->
|
||||
expect(atom.workspace.getTopPanels().length).toBe(0)
|
||||
atom.workspace.panelContainers.top.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = atom.workspace.addTopPanel(item: new TestPanel())
|
||||
|
||||
model = new TestItem
|
||||
panel = atom.workspace.addTopPanel(item: model)
|
||||
|
||||
expect(panel).toBeDefined()
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
|
||||
itemView = atom.views.getView(atom.workspace.getTopPanels()[0].getItem())
|
||||
expect(itemView instanceof TestItemElement).toBe(true)
|
||||
expect(itemView.getModel()).toBe(model)
|
||||
|
||||
describe '::addBottomPanel(model)', ->
|
||||
it 'adds a panel to the correct panel container', ->
|
||||
expect(atom.workspace.getBottomPanels().length).toBe(0)
|
||||
atom.workspace.panelContainers.bottom.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = atom.workspace.addBottomPanel(item: new TestPanel())
|
||||
|
||||
model = new TestItem
|
||||
panel = atom.workspace.addBottomPanel(item: model)
|
||||
|
||||
expect(panel).toBeDefined()
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
|
||||
itemView = atom.views.getView(atom.workspace.getBottomPanels()[0].getItem())
|
||||
expect(itemView instanceof TestItemElement).toBe(true)
|
||||
expect(itemView.getModel()).toBe(model)
|
||||
|
||||
describe '::addModalPanel(model)', ->
|
||||
it 'adds a panel to the correct panel container', ->
|
||||
expect(atom.workspace.getModalPanels().length).toBe(0)
|
||||
atom.workspace.panelContainers.modal.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = atom.workspace.addModalPanel(item: new TestPanel())
|
||||
|
||||
model = new TestItem
|
||||
panel = atom.workspace.addModalPanel(item: model)
|
||||
|
||||
expect(panel).toBeDefined()
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
expect(panel.getClassName()).toBe 'overlay from-top' # the default
|
||||
|
||||
itemView = atom.views.getView(atom.workspace.getModalPanels()[0].getItem())
|
||||
expect(itemView instanceof TestItemElement).toBe(true)
|
||||
expect(itemView.getModel()).toBe(model)
|
||||
|
||||
describe "::panelForItem(item)", ->
|
||||
it "returns the panel associated with the item", ->
|
||||
item = new TestItem
|
||||
panel = atom.workspace.addLeftPanel(item: item)
|
||||
|
||||
itemWithNoPanel = new TestItem
|
||||
|
||||
expect(atom.workspace.panelForItem(item)).toBe panel
|
||||
expect(atom.workspace.panelForItem(itemWithNoPanel)).toBe null
|
||||
|
||||
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário