Comparar commits
754 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 6e8e4a56cf | |||
| e53c38f09d | |||
| 587b73e3b9 | |||
| 46efc52a22 | |||
| f78891b600 | |||
| 05e3bbde45 | |||
| 4dc4a022ab | |||
| 226ae374c1 | |||
| fbfe1c7224 | |||
| 53f8ae3055 | |||
| 1634b3acfc | |||
| 3067323564 | |||
| c410b79af0 | |||
| f09fc23fdc | |||
| a9262b18c2 | |||
| ef129f9491 | |||
| b4d38d14e3 | |||
| 97a21d7bbf | |||
| ab395952a9 | |||
| 6e55c80d3c | |||
| f1079056cf | |||
| b29a61ec87 | |||
| 4894849adc | |||
| cf78b01d45 | |||
| 1ed927f213 | |||
| b978b4f8c7 | |||
| baea6fcb49 | |||
| 7e06e10fcf | |||
| 0bcfa591f6 | |||
| f2532b1a35 | |||
| e0f8d6f365 | |||
| 50c705fea4 | |||
| 8bfea240ea | |||
| 4099828525 | |||
| 26983adbdf | |||
| ede703453a | |||
| d97c81bf6a | |||
| bd76242851 | |||
| d85c07e7e2 | |||
| 4077e791c9 | |||
| e7eef89fa5 | |||
| 5437236304 | |||
| b7aa421e4e | |||
| 9458db0c1f | |||
| 80c15513bb | |||
| 951289f67f | |||
| 1e7ba12e60 | |||
| 9a423359c4 | |||
| bb56c6badc | |||
| ae461b21a4 | |||
| 670b44f250 | |||
| d330a8fac5 | |||
| 8bd2650d01 | |||
| 560d9387dc | |||
| 39cc463e24 | |||
| 2c83c3fe17 | |||
| 07505ea82a | |||
| 47d3b3edf3 | |||
| 3d394e854e | |||
| a37b8ff632 | |||
| f8a05dd8e0 | |||
| 6a58f6054a | |||
| ddd4a9a968 | |||
| 743c50014f | |||
| af761fb004 | |||
| badf1725fa | |||
| 2b2149bca1 | |||
| e1d6d55311 | |||
| 670a710753 | |||
| dd1e5338c6 | |||
| 100af7d27d | |||
| 9b70cf2044 | |||
| 7fe9c14772 | |||
| 9690e44ffe | |||
| 0e57ede712 | |||
| dd7335c30b | |||
| 4537e9bd1a | |||
| 0488fc21da | |||
| 160bb29034 | |||
| 497b4a4e24 | |||
| dd4e7d6921 | |||
| d060ecdc24 | |||
| 84d1101903 | |||
| 6f3c53a17a | |||
| dd17e8f018 | |||
| cf3f1aa2eb | |||
| adaf1829da | |||
| 7863db480e | |||
| 5cc243ec11 | |||
| 2e46cf9b8d | |||
| 5e8655fa60 | |||
| c64a4b7ca9 | |||
| bda1429293 | |||
| eb19989ecd | |||
| 62c0db11ee | |||
| 8aeabe5fe5 | |||
| ab846a2495 | |||
| 7202908780 | |||
| c4cfac5615 | |||
| 866f2d9a76 | |||
| 3b455c00d3 | |||
| 1f777addd9 | |||
| 58744f6b7b | |||
| 7badd9ba25 | |||
| e8d7058383 | |||
| 42fc54f716 | |||
| c11675dca1 | |||
| cdb62812d2 | |||
| 2d3d64f399 | |||
| 2321aa2bee | |||
| fa733c85ad | |||
| 158bbef38f | |||
| b2bc09c13d | |||
| 268fceb073 | |||
| 5be21d6743 | |||
| 5d3602d37b | |||
| b86f6870c5 | |||
| 2ab5fa405c | |||
| 5f4fb23057 | |||
| 22f6268116 | |||
| 65f40d6f7b | |||
| 596987fbce | |||
| 2b218d2e01 | |||
| 582066915b | |||
| 1a98cb7070 | |||
| c2d0b6d4f5 | |||
| 2affff30ff | |||
| 3b6189e94b | |||
| 4e8e5a84c4 | |||
| 087387e633 | |||
| 769c6c52bb | |||
| 963c92eb4e | |||
| 22212be90d | |||
| 8a640b35e0 | |||
| df9a0dc7a3 | |||
| 5251183410 | |||
| 5bd028b24e | |||
| 8485831f40 | |||
| da30b66ffa | |||
| 3da11bf478 | |||
| 9b1d5e1864 | |||
| 1f445acc12 | |||
| 022bc2e2a5 | |||
| da18db754f | |||
| c20403d983 | |||
| 78dc87d4b6 | |||
| 5dd310f9ac | |||
| 427a32c336 | |||
| f3d4a3ad45 | |||
| ba642682ca | |||
| b1a0258ad4 | |||
| 44112f2ecd | |||
| 54b8aa4a02 | |||
| 5791548ac4 | |||
| 26f21abcf3 | |||
| ab0f9e88a7 | |||
| 6d8b891b65 | |||
| afdb96e1b1 | |||
| 9c1ca86cb0 | |||
| 4e95977fbd | |||
| 4a8a379891 | |||
| fb0387f43e | |||
| 5231a548e3 | |||
| a466d6cdaf | |||
| 19b0f760a1 | |||
| 228ba5f96a | |||
| 25922872f0 | |||
| 15a1982e8c | |||
| fcca61c2b2 | |||
| ee4116536d | |||
| c217c6544a | |||
| 205095a198 | |||
| 4326898d5f | |||
| b8285a00b0 | |||
| 025967193a | |||
| 75627f50a2 | |||
| 9fca1d26f1 | |||
| 6e827434fd | |||
| b3f6b3af4b | |||
| 63a33bd1e7 | |||
| a153f1e244 | |||
| 037a7f435c | |||
| 7641f1d1e4 | |||
| 05c1ae71e1 | |||
| cefabd4eb8 | |||
| 9f80be4570 | |||
| 61f75b0764 | |||
| ae2f4ac36e | |||
| d20e91897a | |||
| 2e0bb66a9a | |||
| d205c4d664 | |||
| 8db5ea7bc7 | |||
| 3c7eecbb6a | |||
| 8dab3d90b3 | |||
| 44bc470a00 | |||
| 498631725a | |||
| 945345b0c7 | |||
| 6576ec5cde | |||
| ce8143f8e6 | |||
| e993175205 | |||
| 4242ac0911 | |||
| f22e741a9b | |||
| a41b582032 | |||
| a24279d0b9 | |||
| 5985175b07 | |||
| d2ef888f22 | |||
| 35925ed349 | |||
| 490ec1aac7 | |||
| 25eea7d19b | |||
| 4c9e71770a | |||
| 4032d96b13 | |||
| c5aa3eb441 | |||
| 68bb765304 | |||
| bd7996e071 | |||
| 1eaba0cb52 | |||
| 0c590d6170 | |||
| 3df72ec173 | |||
| 1456bf0d91 | |||
| edec6b9b0a | |||
| 9abc4580f4 | |||
| 54260230c6 | |||
| 9bd11fc2f7 | |||
| 81586d22f4 | |||
| dc824485aa | |||
| d1fcfabf0b | |||
| ea8a3a78da | |||
| 62f5d0f7f3 | |||
| b3f4d03a82 | |||
| c2d51858b1 | |||
| a5bca03a46 | |||
| 02d20e3155 | |||
| 2910e017bb | |||
| 248e164de2 | |||
| 4d796f614c | |||
| a8be05bb3b | |||
| 101904e261 | |||
| c0622e8bb5 | |||
| ce5b755438 | |||
| 86781e6f9a | |||
| a7f4a5b08e | |||
| 2b8167da53 | |||
| bb0ee8a78b | |||
| d1115d4c7c | |||
| a71d7115bf | |||
| af14a26625 | |||
| dadd56f7a0 | |||
| 0e99b70650 | |||
| 2965398062 | |||
| 55ace0fe99 | |||
| 03f7511229 | |||
| 5f7976cada | |||
| fa074431f9 | |||
| b9239ffc57 | |||
| 06698c880f | |||
| 05dc9aad89 | |||
| e5660e5e83 | |||
| e928447eab | |||
| 9b0f622ffb | |||
| b6cc7273a1 | |||
| 232be1f876 | |||
| ddeec5d4d5 | |||
| dc83f8bac7 | |||
| ae2a7769ed | |||
| d0d6af7e55 | |||
| 137df72a60 | |||
| 2e187d3ec1 | |||
| 9f74250333 | |||
| de70a181c5 | |||
| 0272b2f281 | |||
| 365b7bfaf9 | |||
| 937ef321bd | |||
| 80a302df9e | |||
| 381ee353a3 | |||
| de3703d1ea | |||
| 0b8c4a0c7f | |||
| d299692237 | |||
| eaf435bd9a | |||
| 8d71cbd510 | |||
| 534ace6250 | |||
| 89157cdf29 | |||
| ef2795ea0d | |||
| 11b5bcff74 | |||
| d7019509e3 | |||
| 0417458fbb | |||
| ff32fff483 | |||
| f776678b83 | |||
| edacf02222 | |||
| 4b3d3701d5 | |||
| dcbd1723b7 | |||
| 6c00dbd5ec | |||
| 14fd4a9f7d | |||
| b65c6da948 | |||
| 1c1adf5beb | |||
| c1197d6390 | |||
| 7713720ba7 | |||
| 4f1ec786f0 | |||
| 27ff02ad0e | |||
| 738cdb6e66 | |||
| 0818e6d736 | |||
| 6b57030bda | |||
| b64a5c93e3 | |||
| 317001b435 | |||
| 4e3d15592e | |||
| f4c40c2932 | |||
| 9cfc451a79 | |||
| 198d3e90c7 | |||
| 00da8a9df6 | |||
| 293bd3ad3d | |||
| bd0564e30d | |||
| 953940c757 | |||
| 4ff6366d2b | |||
| 4db441f4df | |||
| 71ef21bb70 | |||
| de5e443329 | |||
| 6e15d68163 | |||
| 6a3c7bcd50 | |||
| dfc0df42b2 | |||
| 452c78b735 | |||
| 42f67033cc | |||
| 5c417cf9cc | |||
| 81143af4b4 | |||
| 5c048a4f13 | |||
| 2ac9cc9ed1 | |||
| e8f8ead53f | |||
| f3d8c5d7ec | |||
| 7d179ef40f | |||
| 375b8efc22 | |||
| 086a011a63 | |||
| 46ff52b13a | |||
| 0ed4d07c33 | |||
| efe3d65291 | |||
| 8576486d06 | |||
| e5abca138d | |||
| fa24154e24 | |||
| 45c05d3b7d | |||
| bf4ac1d3eb | |||
| 892cdae622 | |||
| f33d7ba27f | |||
| 06436ef530 | |||
| 815244bba0 | |||
| 0303ebb5e5 | |||
| eab791d47e | |||
| 6ad96d98b8 | |||
| ed4ebefdc1 | |||
| a1828fa3a6 | |||
| 345c0f670c | |||
| d78e6fa711 | |||
| c3a6475308 | |||
| 2cc9f6bee8 | |||
| 0c6fba2ce2 | |||
| fa72db87a2 | |||
| a0d7bbdb92 | |||
| 4c3e1ef82b | |||
| 1056418f97 | |||
| 37040ad485 | |||
| dee9cccae7 | |||
| 50e27854cc | |||
| c931071c91 | |||
| 498c8d21b2 | |||
| 263b792eee | |||
| ffd3990a6b | |||
| 31490ca31e | |||
| 37159bb478 | |||
| 16ad957609 | |||
| 137eeab4cf | |||
| ce2076f30a | |||
| 8479d564f5 | |||
| ec6004615a | |||
| 7e7441dc23 | |||
| 2a09d25eb1 | |||
| d5508b338b | |||
| 86bd43bf73 | |||
| 3075b74b64 | |||
| 11d7437ecc | |||
| df439f5ada | |||
| dc28ddbdc8 | |||
| 49e98d368a | |||
| 02e91aa4cd | |||
| 14c8e9cedc | |||
| 4867e3ef14 | |||
| 3a70b98ae1 | |||
| 08f35531ba | |||
| ce2959c0b9 | |||
| 4c4b82fe6c | |||
| f4c3050050 | |||
| 2b148b7720 | |||
| c40dd16466 | |||
| 7ffe5d1385 | |||
| c2ef68a435 | |||
| aa117774b3 | |||
| 6b44369458 | |||
| 177b3a6d14 | |||
| 4d1e488ef4 | |||
| 0a39c28a79 | |||
| e019347ca4 | |||
| b425df1d58 | |||
| 055c632ee9 | |||
| 2ac1862e5f | |||
| 5a82afd333 | |||
| 13f81a452d | |||
| c8144b7e1b | |||
| b3b78fa926 | |||
| 824c00dab3 | |||
| 8d331e94d2 | |||
| bc2dd9f52c | |||
| 5dd9f9c5ad | |||
| 3f1afec15b | |||
| e4705d45c4 | |||
| c0846ab8a6 | |||
| bfbb262844 | |||
| 5669aa39ce | |||
| d1f9133ef4 | |||
| 362c9c8588 | |||
| c63cde1cd3 | |||
| 6d937831b9 | |||
| 0eacbed162 | |||
| 6e034c6319 | |||
| a4f6c674ef | |||
| 405af7fb16 | |||
| 995e89b5f6 | |||
| 6b90b83867 | |||
| 66d469ee10 | |||
| 657cbc9c17 | |||
| 29ea506f93 | |||
| 155d144788 | |||
| 892f341feb | |||
| d5808b5c85 | |||
| d6feb686c1 | |||
| 5069a5b48b | |||
| 8c136b18c2 | |||
| f81bc4b870 | |||
| 111b956f93 | |||
| 88a95ad06b | |||
| 04bd602c23 | |||
| de78e53b35 | |||
| fb1a866447 | |||
| 8925d309b0 | |||
| b94485eafd | |||
| a83acd0e8a | |||
| 4e2c500b64 | |||
| 03f863d558 | |||
| b8ad484db0 | |||
| f0fd7c2682 | |||
| 3f170a8b5e | |||
| 37a7cfaf9a | |||
| 5683491029 | |||
| 4ca630a7da | |||
| 99aedbab89 | |||
| 52c05eade7 | |||
| 1ddb956a94 | |||
| 2570c20da0 | |||
| 299710f08a | |||
| 83e5873f3b | |||
| 4889e03cf2 | |||
| 7f6cc8a100 | |||
| e8e0ee1e34 | |||
| 8e3d8eda31 | |||
| afd1fa995f | |||
| a03c9b6d68 | |||
| cdd31d69a8 | |||
| f94983d4d9 | |||
| ffa528001c | |||
| 305b9bc030 | |||
| 6ed3ef3f60 | |||
| 5c2e55861c | |||
| c0843d467d | |||
| 734a79b7ec | |||
| 55a5e66701 | |||
| da86c86577 | |||
| 072c537b6b | |||
| 1577a28ad4 | |||
| ee23131688 | |||
| 7d8b5bc1fc | |||
| 0243597ee8 | |||
| 50a5609c6b | |||
| e76ea838e1 | |||
| ed5c011963 | |||
| 0bc1407e7d | |||
| 7aa00f3417 | |||
| 06e9dbf48a | |||
| ff5acb6a34 | |||
| 231295cb2c | |||
| c8a18dfaf8 | |||
| b339baa923 | |||
| 92d08b47ad | |||
| 5c3a7a99fc | |||
| ea932a01f9 | |||
| d261df0906 | |||
| fac167379f | |||
| f6d9af8d1a | |||
| a128cf5eb3 | |||
| e9c2ee9675 | |||
| e85d33b2a6 | |||
| a42b3ff171 | |||
| 86fdbfbb15 | |||
| 757abfe3db | |||
| cde7940e40 | |||
| d7d6e506da | |||
| 593fc1e77a | |||
| ae857203fd | |||
| a1c418e995 | |||
| f07f096f56 | |||
| 62c1972c95 | |||
| 314c525d2d | |||
| 04b3eef768 | |||
| 506753a535 | |||
| a8b9e1b790 | |||
| be51ccf786 | |||
| 65e077abd1 | |||
| 79598aaae9 | |||
| 62a43c6fb9 | |||
| 1fe1147901 | |||
| 1c97dcd195 | |||
| d3371dbcd2 | |||
| b2b4860983 | |||
| 57fc3deaed | |||
| 677949d61c | |||
| e09d7159bc | |||
| e02af51a04 | |||
| d2c7a2caca | |||
| 739a629552 | |||
| 88f0183352 | |||
| 7f01a163e5 | |||
| fc44662ba3 | |||
| 5052aaca95 | |||
| 826681b6c2 | |||
| 8334bba484 | |||
| a0ae526017 | |||
| 6a6c7b1852 | |||
| 42040f8a9d | |||
| 9d1db0f3de | |||
| f0b922f643 | |||
| bb92b8697d | |||
| 4c17c9eae6 | |||
| 289f17b119 | |||
| dfd7bcae7f | |||
| 0cfd37acd0 | |||
| 105fc302ea | |||
| f4ddc05b9c | |||
| 948f96dd6f | |||
| db627f5cde | |||
| a6866656b7 | |||
| 40c5289e2b | |||
| 7dffc58c5b | |||
| 67d430d100 | |||
| d745b9ef5f | |||
| b9d89cbf5d | |||
| 934c0720d8 | |||
| 06ac206707 | |||
| 6e1bdbbed7 | |||
| 3e3de50eb3 | |||
| d7a8dfb209 | |||
| b0aea54544 | |||
| 41598af2b2 | |||
| f495db41e7 | |||
| 76187f176c | |||
| d7cb1550bf | |||
| 086be13ac4 | |||
| f0cffcbd84 | |||
| d1f3d7d51e | |||
| bdc0341eb3 | |||
| 171411823f | |||
| 7926531330 | |||
| 440866d79e | |||
| d9c758b940 | |||
| 827a8ba107 | |||
| 65a1fafaf7 | |||
| 9bd6891ac2 | |||
| 8a0755340f | |||
| bdebe575b7 | |||
| 472a48092d | |||
| d877872c71 | |||
| 0a297d7642 | |||
| 87d2026e63 | |||
| 20f6489232 | |||
| 2c737b8927 | |||
| 0df5045edb | |||
| b91c25186f | |||
| 7b8a293f30 | |||
| 26df31aa1f | |||
| 36ff22e30a | |||
| 93c5b4be7b | |||
| 495fa43753 | |||
| 2954aacb1c | |||
| 1bf8f516c3 | |||
| e0a84232c3 | |||
| 8c204bb60e | |||
| 245c77869f | |||
| 508a30efb1 | |||
| 5ad54bbe92 | |||
| 4da6513fb5 | |||
| 1154490a97 | |||
| 0e7e24ca6b | |||
| 944ac14be7 | |||
| 7aa28920cf | |||
| 6ce6553456 | |||
| b4470a14cb | |||
| 5b629e6b29 | |||
| 7304b97547 | |||
| f523c5eb73 | |||
| 5981cfb8c9 | |||
| d1e966349f | |||
| dc19fa4baa | |||
| 84e90d140f | |||
| ea557ab109 | |||
| bfbc0b1c46 | |||
| d3b9a14f98 | |||
| 85ca8350e5 | |||
| ad6fc94a5c | |||
| 07a1b28e67 | |||
| 966adbdf20 | |||
| bbfac9430e | |||
| 7bc3fffa1a | |||
| 7b9aa23129 | |||
| 9ef4b84afb | |||
| 01625bc892 | |||
| feb97eb7b2 | |||
| a2781b2a84 | |||
| c9869580d4 | |||
| f4b67190bd | |||
| fcf230ccb5 | |||
| e7be5adaf1 | |||
| 1377ec5583 | |||
| f382edd431 | |||
| 4821c1aa5a | |||
| 8f97e5f81b | |||
| c16d84527d | |||
| 5c8e20a01d | |||
| ae0b3b47e3 | |||
| d73c34af25 | |||
| 3ba44b955d | |||
| b1e9e6b312 | |||
| 22e43600d2 | |||
| b9f13d05a8 | |||
| b2cc190a3b | |||
| 274bbeec27 | |||
| c0091b4601 | |||
| 8cf36af1dc | |||
| 80f52aa3ef | |||
| 56c6c3516a | |||
| f7ab04404c | |||
| b0de88de74 | |||
| 6ab002d4be | |||
| 0588e14850 | |||
| 82bf5da9aa | |||
| 9481260f6f | |||
| b8fdaa2dc5 | |||
| b57f5a7afa | |||
| a2a4379974 | |||
| 7f1947f7b2 | |||
| 55c9b42a74 | |||
| 9a41b5050e | |||
| 8ed751f5da | |||
| 3abe6eb098 | |||
| 4aa7a1ebd8 | |||
| 4997be54df | |||
| 93902b54e4 | |||
| 1d89150242 | |||
| ec5819a684 | |||
| d6f43f1858 | |||
| 503393122f | |||
| b5c6d76999 | |||
| b149d47b09 | |||
| f81f24fea6 | |||
| 201345ec5d | |||
| 95ee29ea39 | |||
| 4c6803cf6a | |||
| d3512514d8 | |||
| 014e2e6fce | |||
| 1eb3d8bf99 | |||
| 8e06e88efa | |||
| 8941b97ed2 | |||
| eedf4894ae | |||
| ddf36a013c | |||
| ee9284e228 | |||
| e6e039293a | |||
| 6c56f2f985 | |||
| a4b959f2b8 | |||
| c59b7f6ead | |||
| 17bfc29c5b | |||
| c154b8f4ec | |||
| a28fed8bae | |||
| c2081fa569 | |||
| 841412bd01 | |||
| f2d480fc72 | |||
| d7cd0de0f8 | |||
| 8910dd1a11 | |||
| c315631efd | |||
| 26524e87b0 | |||
| 2a73d7052d | |||
| a3bbbc19b5 | |||
| b44a5dd1f0 | |||
| f662b3d745 | |||
| d3b00f67f2 | |||
| 2605044f19 | |||
| fbe4cf5677 | |||
| ca4c40936a | |||
| 6958e0af10 | |||
| 237c668ef0 | |||
| c1ff53b02c | |||
| 938f216cab | |||
| fbcaabacab | |||
| 857fd5eaf4 | |||
| 8cd217e50a | |||
| 339cb02269 | |||
| 416898e278 | |||
| 6b9345a97d | |||
| d1b2147921 | |||
| 9914c49773 | |||
| 079ea4862a | |||
| 9ff435a203 | |||
| 0067e44681 | |||
| 34a8c6f3bc | |||
| 9bf7540657 | |||
| bc790ee838 | |||
| 810c851ab3 | |||
| d015343616 | |||
| fab0ac814d | |||
| eaa3a27328 | |||
| 1e4f4e0882 | |||
| 2d7aa2efda | |||
| c63d22b4d1 | |||
| 1ca479877e | |||
| 49dd9b0c07 | |||
| 49e22a41b2 | |||
| 4eff0f82d8 | |||
| 003b67ee19 | |||
| 541c140a19 | |||
| 19c0540eec | |||
| c39f2019db | |||
| f869edee2f | |||
| bb6294cb7c | |||
| 5d538fb1b0 | |||
| b78ac53224 | |||
| fb5d826d84 | |||
| a75faec64e | |||
| cdb4ed1327 | |||
| 0d55a377fb | |||
| 2084c45404 | |||
| 550f0d2a72 | |||
| ec6614c919 | |||
| 8db2c4d70a | |||
| bcbf01c852 | |||
| 058ff116b6 | |||
| 33dc3fd684 | |||
| 481c99d852 | |||
| 2e6b1cf902 | |||
| c4e54df100 | |||
| 20b94c8a4c | |||
| c9ee9b46ed | |||
| 74d1afa8ef | |||
| 38a6f52ef7 | |||
| 182f1324a4 | |||
| 33e2829697 |
+13
-15
@@ -12,19 +12,21 @@ propose changes to this document in a pull request.
|
||||
## Submitting Issues
|
||||
|
||||
* Check the [debugging guide](https://atom.io/docs/latest/debugging) for tips
|
||||
on debugging. You might be able to find the cause of the problem and fix
|
||||
on debugging. You might be able to find the cause of the problem and fix
|
||||
things yourself.
|
||||
* Include the version of Atom you are using and the OS.
|
||||
* Include screenshots and animated GIFs whenever possible; they are immensely
|
||||
helpful.
|
||||
* Include the behavior you expected and other places you've seen that behavior
|
||||
such as Emacs, vi, Xcode, etc.
|
||||
* Check the dev tools (`alt-cmd-i`) for errors to include. If the dev tools
|
||||
* Check the dev tools (`alt-cmd-i`) for errors to include. If the dev tools
|
||||
are open _before_ the error is triggered, a full stack trace for the error
|
||||
will be logged. If you can reproduce the error, use this approach to get the
|
||||
full stack trace and include it in the issue.
|
||||
* On Mac, check Console.app for stack traces to include if reporting a crash.
|
||||
* Perform a cursory search to see if a similar issue has already been submitted.
|
||||
* Please setup a [profile picture](https://help.github.com/articles/how-do-i-set-up-my-profile-picture)
|
||||
to make yourself recognizable and so we can all get to know each other better.
|
||||
|
||||
### Package Repositories
|
||||
|
||||
@@ -62,6 +64,8 @@ For more information on how to work with Atom's official packages, see
|
||||
* Use `path.join()` to concatenate filenames.
|
||||
* Use `os.tmpdir()` rather than `/tmp` when you need to reference the
|
||||
temporary directory.
|
||||
* Using a plain `return` when returning explicitly at the end of a function.
|
||||
* Not `return null`, `return undefined`, `null`, or `undefined`
|
||||
|
||||
## Git Commit Messages
|
||||
|
||||
@@ -82,6 +86,7 @@ For more information on how to work with Atom's official packages, see
|
||||
* :green_heart: `:green_heart:` when fixing the CI build
|
||||
* :white_check_mark: `:white_check_mark:` when adding tests
|
||||
* :lock: `:lock:` when dealing with security
|
||||
* :arrow_up: `:arrow_up:` when upgrading dependencies
|
||||
|
||||
## CoffeeScript Styleguide
|
||||
|
||||
@@ -96,30 +101,23 @@ For more information on how to work with Atom's official packages, see
|
||||
|
||||
## Documentation Styleguide
|
||||
|
||||
* Use [TomDoc](http://tomdoc.org).
|
||||
* Use [AtomDoc](https://github.com/atom/atomdoc).
|
||||
* Use [Markdown](https://daringfireball.net/projects/markdown).
|
||||
* Reference methods and classes in markdown with the custom `{}` notation:
|
||||
* Reference classes with `{ClassName}`
|
||||
* Reference instance methods with `{ClassName::methodName}`
|
||||
* Reference class methods with `{ClassName.methodName}`
|
||||
* Delegate to comments elsewhere with `{Delegates to: ClassName.methodName}`
|
||||
style notation.
|
||||
|
||||
### Example
|
||||
|
||||
```coffee
|
||||
# Public: Disable the package with the given name.
|
||||
#
|
||||
# This method emits multiple events:
|
||||
#
|
||||
# * `package-will-be-disabled` - before the package is disabled.
|
||||
# * `package-disabled` - after the package is disabled.
|
||||
#
|
||||
# name - The {String} name of the package to disable.
|
||||
# options - The {Object} with disable options (default: {}):
|
||||
# :trackTime - `true` to track the amount of time disabling took.
|
||||
# :ignoreErrors - `true` to catch and ignore errors thrown.
|
||||
# callback - The {Function} to call after the package has been disabled.
|
||||
# * `name` The {String} name of the package to disable.
|
||||
# * `options` (optional) The {Object} with disable options (default: {}):
|
||||
# * `trackTime` A {Boolean}, `true` to track the amount of time taken.
|
||||
# * `ignoreErrors` A {Boolean}, `true` to catch and ignore errors thrown.
|
||||
# * `callback` The {Function} to call after the package has been disabled.
|
||||
#
|
||||
# Returns `undefined`.
|
||||
disablePackage: (name, options, callback) ->
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# VERSION: 0.1
|
||||
# DESCRIPTION: Image to build Atom and create a .rpm file
|
||||
|
||||
# Base docker image
|
||||
FROM fedora:20
|
||||
|
||||
# Install dependencies
|
||||
RUN yum install -y \
|
||||
make \
|
||||
gcc \
|
||||
gcc-c++ \
|
||||
glibc-devel \
|
||||
git-core \
|
||||
libgnome-keyring-devel \
|
||||
rpmdevtools
|
||||
|
||||
# Install node
|
||||
RUN curl -sL https://rpm.nodesource.com/setup | bash -
|
||||
RUN yum install -y nodejs
|
||||
|
||||
ADD . /atom
|
||||
WORKDIR /atom
|
||||
+14
@@ -4,6 +4,9 @@ Atom is a hackable text editor for the 21st century, built on [atom-shell](http:
|
||||
|
||||
Visit [atom.io](https://atom.io) to learn more.
|
||||
|
||||
Visit [issue #3684](https://github.com/atom/atom/issues/3684) to learn more
|
||||
about the Atom 1.0 roadmap.
|
||||
|
||||
## Installing
|
||||
|
||||
### Mac OS X
|
||||
@@ -36,6 +39,17 @@ Currently only a 64-bit version is available.
|
||||
The Linux version does not currently automatically update so you will need to
|
||||
repeat these steps to upgrade to future releases.
|
||||
|
||||
### Red Hat Linux (Fedora, CentOS, Red Hat)
|
||||
|
||||
Currently only a 64-bit version is available.
|
||||
|
||||
1. Download `atom.x86_64.rpm` from the [Atom releases page](https://github.com/atom/atom/releases/latest).
|
||||
2. Run `sudo yum localinstall atom.x86_64.rpm` on the downloaded package.
|
||||
3. Launch Atom using the installed `atom` command.
|
||||
|
||||
The Linux version does not currently automatically update so you will need to
|
||||
repeat these steps to upgrade to future releases.
|
||||
|
||||
## Building
|
||||
|
||||
* [Linux](docs/build-instructions/linux.md)
|
||||
|
||||
+1
-1
@@ -6,6 +6,6 @@
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "0.101.0"
|
||||
"atom-package-manager": "0.109.0"
|
||||
}
|
||||
}
|
||||
|
||||
+2
-4
@@ -63,7 +63,7 @@ if [ $OS == 'Mac' ]; then
|
||||
"$ATOM_PATH/$ATOM_APP_NAME/Contents/MacOS/Atom" --executed-from="$(pwd)" --pid=$$ "$@"
|
||||
exit $?
|
||||
else
|
||||
open -a "$ATOM_PATH/$ATOM_APP_NAME" -n --args --executed-from="$(pwd)" --pid=$$ "$@"
|
||||
open -a "$ATOM_PATH/$ATOM_APP_NAME" -n --args --executed-from="$(pwd)" --pid=$$ --path-environment="$PATH" "$@"
|
||||
fi
|
||||
elif [ $OS == 'Linux' ]; then
|
||||
SCRIPT=$(readlink -f "$0")
|
||||
@@ -71,9 +71,7 @@ elif [ $OS == 'Linux' ]; then
|
||||
ATOM_PATH="$USR_DIRECTORY/share/atom/atom"
|
||||
DOT_ATOM_DIR="$HOME/.atom"
|
||||
|
||||
if [ ! -d "$DOT_ATOM_DIR" ]; then
|
||||
mkdir -p "$DOT_ATOM_DIR"
|
||||
fi
|
||||
mkdir -p "$DOT_ATOM_DIR"
|
||||
|
||||
: ${TMPDIR:=/tmp}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ describe "editorView.", ->
|
||||
|
||||
beforeEach ->
|
||||
atom.workspaceViewParentSelector = '#jasmine-content'
|
||||
atom.workspaceView = atom.workspace.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView.attachToDom()
|
||||
|
||||
atom.workspaceView.width(1024)
|
||||
|
||||
@@ -120,7 +120,10 @@ module.exports = (grunt) ->
|
||||
|
||||
for child in fs.readdirSync('node_modules') when child isnt '.bin'
|
||||
directory = path.join('node_modules', child)
|
||||
{engines, theme} = grunt.file.readJSON(path.join(directory, 'package.json'))
|
||||
metadataPath = path.join(directory, 'package.json')
|
||||
continue unless grunt.file.isFile(metadataPath)
|
||||
|
||||
{engines, theme} = grunt.file.readJSON(metadataPath)
|
||||
if engines?.atom?
|
||||
coffeeConfig.glob_to_multiple.src.push("#{directory}/**/*.coffee")
|
||||
lessConfig.glob_to_multiple.src.push("#{directory}/**/*.less")
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# VERSION: 0.1
|
||||
# DESCRIPTION: Create the atom editor in a container
|
||||
# AUTHOR: Jessica Frazelle <jessie@docker.com>
|
||||
# COMMENTS:
|
||||
# This file describes how to build the atom editor
|
||||
# in a container with all dependencies installed.
|
||||
# Tested on Debian Jessie.
|
||||
# USAGE:
|
||||
# # Download atom Dockerfile
|
||||
# wget http://raw.githubusercontent.com/atom/atom/master/Dockerfile
|
||||
#
|
||||
# # Build atom image
|
||||
# docker build -t atom .
|
||||
#
|
||||
# docker run -v /tmp/.X11-unix:/tmp/.X11-unix \
|
||||
# -e DISPLAY=unix$DISPLAY atom
|
||||
#
|
||||
|
||||
DOCKER-VERSION 1.3
|
||||
|
||||
# Base docker image
|
||||
FROM debian:jessie
|
||||
MAINTAINER Jessica Frazelle <jessie@docker.com>
|
||||
|
||||
# Install dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
build-essential \
|
||||
ca-certificates \
|
||||
curl \
|
||||
git \
|
||||
libasound2 \
|
||||
libgconf-2-4 \
|
||||
libgnome-keyring-dev \
|
||||
libgtk2.0-0 \
|
||||
libnss3 \
|
||||
libxtst6 \
|
||||
--no-install-recommends
|
||||
|
||||
# install node
|
||||
RUN curl -sL https://deb.nodesource.com/setup | bash -
|
||||
RUN apt-get install -y nodejs
|
||||
|
||||
# clone atom
|
||||
RUN git clone https://github.com/atom/atom /src
|
||||
WORKDIR /src
|
||||
RUN git fetch && git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
|
||||
RUN script/build && script/grunt install
|
||||
|
||||
# Autorun atom
|
||||
CMD /usr/local/bin/atom --foreground --log-file /var/log/atom.log && tail -f /var/log/atom.log
|
||||
@@ -7,7 +7,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "~0.2.9",
|
||||
"donna": "1.0.1",
|
||||
"donna": "1.0.6",
|
||||
"formidable": "~1.0.14",
|
||||
"fs-plus": "2.x",
|
||||
"github-releases": "~0.2.0",
|
||||
@@ -18,7 +18,7 @@
|
||||
"grunt-contrib-csslint": "~0.1.2",
|
||||
"grunt-contrib-less": "~0.8.0",
|
||||
"grunt-cson": "0.10.0",
|
||||
"grunt-download-atom-shell": "~0.8.0",
|
||||
"grunt-download-atom-shell": "~0.10.0",
|
||||
"grunt-lesslint": "0.13.0",
|
||||
"grunt-markdown": "~0.4.0",
|
||||
"grunt-peg": "~1.1.0",
|
||||
|
||||
@@ -153,7 +153,7 @@ module.exports = (grunt) ->
|
||||
fs.writeFileSync path.join(appDir, 'node_modules', 'symbols-view', 'vendor', 'ctags-win32.exe.ignore'), ''
|
||||
fs.writeFileSync path.join(shellAppDir, 'atom.exe.gui'), ''
|
||||
|
||||
dependencies = ['compile', "generate-license:save"]
|
||||
dependencies = ['compile', 'generate-license:save', 'generate-module-cache', 'compile-packages-slug']
|
||||
dependencies.push('copy-info-plist') if process.platform is 'darwin'
|
||||
dependencies.push('set-exe-icon') if process.platform is 'win32'
|
||||
grunt.task.run(dependencies...)
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
path = require 'path'
|
||||
CSON = require 'season'
|
||||
fs = require 'fs-plus'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{spawn, rm} = require('./task-helpers')(grunt)
|
||||
|
||||
grunt.registerTask 'compile-packages-slug', 'Add bundled package metadata information to the main package.json file', ->
|
||||
appDir = fs.realpathSync(grunt.config.get('atom.appDir'))
|
||||
|
||||
modulesDirectory = path.join(appDir, 'node_modules')
|
||||
packages = {}
|
||||
|
||||
for moduleDirectory in fs.listSync(modulesDirectory)
|
||||
continue if path.basename(moduleDirectory) is '.bin'
|
||||
|
||||
metadataPath = path.join(moduleDirectory, 'package.json')
|
||||
metadata = grunt.file.readJSON(metadataPath)
|
||||
continue unless metadata?.engines?.atom?
|
||||
|
||||
moduleCache = metadata._atomModuleCache ? {}
|
||||
|
||||
rm metadataPath
|
||||
_.remove(moduleCache.extensions?['.json'] ? [], 'package.json')
|
||||
|
||||
for property in ['_from', '_id', 'dist', 'readme', 'readmeFilename']
|
||||
delete metadata[property]
|
||||
|
||||
pack = {metadata, keymaps: {}, menus: {}}
|
||||
|
||||
if metadata.main
|
||||
mainPath = require.resolve(path.resolve(moduleDirectory, metadata.main))
|
||||
pack.main = path.relative(appDir, mainPath)
|
||||
|
||||
for keymapPath in fs.listSync(path.join(moduleDirectory, 'keymaps'), ['.cson', '.json'])
|
||||
relativePath = path.relative(appDir, keymapPath)
|
||||
pack.keymaps[relativePath] = CSON.readFileSync(keymapPath)
|
||||
rm keymapPath
|
||||
|
||||
for menuPath in fs.listSync(path.join(moduleDirectory, 'menus'), ['.cson', '.json'])
|
||||
relativePath = path.relative(appDir, menuPath)
|
||||
pack.menus[relativePath] = CSON.readFileSync(menuPath)
|
||||
rm menuPath
|
||||
|
||||
packages[metadata.name] = pack
|
||||
|
||||
for extension, paths of moduleCache.extensions
|
||||
delete moduleCache.extensions[extension] if paths.length is 0
|
||||
|
||||
metadata = grunt.file.readJSON(path.join(appDir, 'package.json'))
|
||||
metadata._atomPackages = packages
|
||||
|
||||
grunt.file.write(path.join(appDir, 'package.json'), JSON.stringify(metadata))
|
||||
@@ -12,6 +12,8 @@ module.exports = (grunt) ->
|
||||
|
||||
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'))
|
||||
@@ -22,20 +24,23 @@ module.exports = (grunt) ->
|
||||
targetNuspecPath = path.join(buildDir, 'atom.nuspec')
|
||||
grunt.file.write(targetNuspecPath, _.template(inputTemplate, packageInfo))
|
||||
|
||||
cmd = 'build/windows/nuget.exe'
|
||||
args = ['pack', targetNuspecPath, '-BasePath', atomDir, '-OutputDirectory', buildDir]
|
||||
# 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) ->
|
||||
return done(error) if error?
|
||||
if error?
|
||||
grunt.log.error "ATOM_ACCESS_TOKEN environment variable not set or invalid, can't download old releases; continuing anyways"
|
||||
|
||||
pkgs = pkg for pkg in fs.readdirSync(buildDir) when path.extname(pkg) is '.nupkg'
|
||||
cmd = 'build/windows/nuget.exe'
|
||||
args = ['pack', targetNuspecPath, '-BasePath', atomDir, '-OutputDirectory', buildDir]
|
||||
|
||||
releasesDir = path.join(buildDir, 'Releases')
|
||||
spawn {cmd, args}, (error, result, code) ->
|
||||
return done(error) if error?
|
||||
|
||||
# NB: Gonna clear Releases for now, in the future we need to pull down
|
||||
# the existing version
|
||||
rm(releasesDir)
|
||||
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)
|
||||
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)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
ModuleCache = require '../../src/module-cache'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
grunt.registerTask 'generate-module-cache', 'Generate a module cache for all core modules and packages', ->
|
||||
appDir = grunt.config.get('atom.appDir')
|
||||
|
||||
{packageDependencies} = grunt.file.readJSON('package.json')
|
||||
|
||||
for packageName, version of packageDependencies
|
||||
ModuleCache.create(path.join(appDir, 'node_modules', packageName))
|
||||
|
||||
ModuleCache.create(appDir)
|
||||
|
||||
metadata = grunt.file.readJSON(path.join(appDir, 'package.json'))
|
||||
|
||||
metadata._atomModuleCache.folders.forEach (folder) ->
|
||||
if '' in folder.paths
|
||||
folder.paths = [
|
||||
''
|
||||
'exports'
|
||||
'spec'
|
||||
'src'
|
||||
'src/browser'
|
||||
'static'
|
||||
'vendor'
|
||||
]
|
||||
|
||||
# Reactionary does not have an explicit react dependency
|
||||
metadata._atomModuleCache.folders.push
|
||||
paths: [
|
||||
'node_modules/reactionary-atom-fork/lib'
|
||||
]
|
||||
dependencies: {
|
||||
'react-atom-fork': metadata.dependencies['react-atom-fork']
|
||||
}
|
||||
|
||||
grunt.file.write(path.join(appDir, 'package.json'), JSON.stringify(metadata))
|
||||
@@ -32,7 +32,7 @@ module.exports = (grunt) ->
|
||||
binDir = path.join(installDir, 'bin')
|
||||
shareDir = path.join(installDir, 'share', 'atom')
|
||||
|
||||
iconName = path.join(shareDir,'resources','app','resources','atom.png')
|
||||
iconName = path.join(shareDir,'resources', 'app', 'resources', 'atom.png')
|
||||
|
||||
mkdir binDir
|
||||
cp 'atom.sh', path.join(binDir, 'atom')
|
||||
@@ -40,11 +40,11 @@ module.exports = (grunt) ->
|
||||
mkdir path.dirname(shareDir)
|
||||
cp shellAppDir, shareDir
|
||||
|
||||
# Create Atom.desktop if installation not in temporary folder
|
||||
# Create atom.desktop if installation not in temporary folder
|
||||
tmpDir = if process.env.TMPDIR? then process.env.TMPDIR else '/tmp'
|
||||
if installDir.indexOf(tmpDir) isnt 0
|
||||
desktopFile = path.join('resources', 'linux', 'Atom.desktop.in')
|
||||
desktopInstallFile = path.join(installDir, 'share', 'applications', 'Atom.desktop')
|
||||
desktopFile = path.join('resources', 'linux', 'atom.desktop.in')
|
||||
desktopInstallFile = path.join(installDir, 'share', 'applications', 'atom.desktop')
|
||||
|
||||
{description} = grunt.file.readJSON('package.json')
|
||||
iconName = path.join(shareDir, 'resources', 'app', 'resources', 'atom.png')
|
||||
|
||||
@@ -60,3 +60,18 @@ module.exports =
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
"""
|
||||
|
||||
'jschardet@1.1.0':
|
||||
license: 'LGPL'
|
||||
source: 'README.md in the repository'
|
||||
sourceText: """
|
||||
JsChardet
|
||||
=========
|
||||
|
||||
Port of python's chardet (http://chardet.feedparser.org/).
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
LGPL
|
||||
"""
|
||||
|
||||
@@ -39,7 +39,7 @@ module.exports = (grunt) ->
|
||||
getInstalledSize buildDir, (error, installedSize) ->
|
||||
data = {name, version, description, section, arch, maintainer, installDir, iconName, installedSize}
|
||||
controlFilePath = fillTemplate(path.join('resources', 'linux', 'debian', 'control'), data)
|
||||
desktopFilePath = fillTemplate(path.join('resources', 'linux', 'Atom.desktop'), data)
|
||||
desktopFilePath = fillTemplate(path.join('resources', 'linux', 'atom.desktop'), data)
|
||||
icon = path.join('resources', 'atom.png')
|
||||
|
||||
cmd = path.join('script', 'mkdeb')
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{spawn, rm, mkdir} = require('./task-helpers')(grunt)
|
||||
|
||||
fillTemplate = (filePath, data) ->
|
||||
template = _.template(String(fs.readFileSync("#{filePath}.in")))
|
||||
filled = template(data)
|
||||
|
||||
outputPath = path.join(grunt.config.get('atom.buildDir'), path.basename(filePath))
|
||||
grunt.file.write(outputPath, filled)
|
||||
outputPath
|
||||
|
||||
grunt.registerTask 'mkrpm', 'Create rpm package', ->
|
||||
done = @async()
|
||||
|
||||
if process.arch is 'ia32'
|
||||
arch = 'i386'
|
||||
else if process.arch is 'x64'
|
||||
arch = 'amd64'
|
||||
else
|
||||
return done("Unsupported arch #{process.arch}")
|
||||
|
||||
{name, version, description} = grunt.file.readJSON('package.json')
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
|
||||
rpmDir = path.join(buildDir, 'rpm')
|
||||
rm rpmDir
|
||||
mkdir rpmDir
|
||||
|
||||
installDir = grunt.config.get('atom.installDir')
|
||||
shareDir = path.join(installDir, 'share', 'atom')
|
||||
iconName = path.join(shareDir, 'resources', 'app', 'resources', 'atom.png')
|
||||
|
||||
data = {name, version, description, installDir, iconName}
|
||||
specFilePath = fillTemplate(path.join('resources', 'linux', 'redhat', 'atom.spec'), data)
|
||||
desktopFilePath = fillTemplate(path.join('resources', 'linux', 'atom.desktop'), data)
|
||||
|
||||
cmd = path.join('script', 'mkrpm')
|
||||
args = [specFilePath, desktopFilePath, buildDir]
|
||||
spawn {cmd, args}, (error) ->
|
||||
if error?
|
||||
done(error)
|
||||
else
|
||||
grunt.log.ok "Created rpm package in #{rpmDir}"
|
||||
done()
|
||||
@@ -20,9 +20,9 @@ module.exports = (gruntObject) ->
|
||||
{cp} = require('./task-helpers')(grunt)
|
||||
|
||||
grunt.registerTask 'publish-build', 'Publish the built app', ->
|
||||
return if process.env.JANKY_SHA1 and process.env.JANKY_BRANCH isnt 'master'
|
||||
tasks = ['upload-assets']
|
||||
tasks.unshift('build-docs', 'prepare-docs') if process.platform is 'darwin'
|
||||
tasks = []
|
||||
tasks.push('build-docs', 'prepare-docs') if process.platform is 'darwin'
|
||||
tasks.push('upload-assets') if process.env.JANKY_SHA1 and process.env.JANKY_BRANCH is 'master'
|
||||
grunt.task.run(tasks)
|
||||
|
||||
grunt.registerTask 'prepare-docs', 'Move api.json to atom-api.json', ->
|
||||
@@ -31,7 +31,16 @@ module.exports = (gruntObject) ->
|
||||
cp path.join(docsOutputDir, 'api.json'), path.join(buildDir, 'atom-api.json')
|
||||
|
||||
grunt.registerTask 'upload-assets', 'Upload the assets to a GitHub release', ->
|
||||
done = @async()
|
||||
doneCallback = @async()
|
||||
startTime = Date.now()
|
||||
done = (args...) ->
|
||||
elapsedTime = Math.round((Date.now() - startTime) / 100) / 10
|
||||
grunt.log.ok("Upload time: #{elapsedTime}s")
|
||||
doneCallback(args...)
|
||||
|
||||
unless token
|
||||
return done(new Error('ATOM_ACCESS_TOKEN environment variable not set'))
|
||||
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
assets = getAssets()
|
||||
|
||||
@@ -63,9 +72,21 @@ getAssets = ->
|
||||
else
|
||||
arch = 'amd64'
|
||||
{version} = grunt.file.readJSON('package.json')
|
||||
|
||||
# Check for a Debian build
|
||||
sourcePath = "#{buildDir}/atom-#{version}-#{arch}.deb"
|
||||
assetName = "atom-#{arch}.deb"
|
||||
|
||||
# Check for a Fedora build
|
||||
unless fs.isFileSync(sourcePath)
|
||||
rpmName = fs.readdirSync("#{buildDir}/rpm")[0]
|
||||
sourcePath = "#{buildDir}/rpm/#{rpmName}"
|
||||
if process.arch is 'ia32'
|
||||
arch = 'i386'
|
||||
else
|
||||
arch = 'x86_64'
|
||||
assetName = "atom.#{arch}.rpm"
|
||||
|
||||
{cp} = require('./task-helpers')(grunt)
|
||||
cp sourcePath, path.join(buildDir, assetName)
|
||||
|
||||
@@ -102,10 +123,22 @@ getAtomDraftRelease = (callback) ->
|
||||
logError('Fetching atom/atom releases failed', error, releases)
|
||||
callback(error)
|
||||
else
|
||||
for release in releases when release.draft
|
||||
callback(null, release)
|
||||
return
|
||||
callback(new Error('No draft release in atom/atom repo'))
|
||||
[firstDraft] = releases.filter ({draft}) -> draft
|
||||
if firstDraft?
|
||||
options =
|
||||
uri: firstDraft.assets_url
|
||||
method: 'GET'
|
||||
headers: defaultHeaders
|
||||
json: true
|
||||
request options, (error, response, assets=[]) ->
|
||||
if error? or response.statusCode isnt 200
|
||||
logError('Fetching draft release assets failed', error, assets)
|
||||
callback(error ? new Error(response.statusCode))
|
||||
else
|
||||
firstDraft.assets = assets
|
||||
callback(null, firstDraft)
|
||||
else
|
||||
callback(new Error('No draft release in atom/atom repo'))
|
||||
|
||||
deleteRelease = (release) ->
|
||||
options =
|
||||
|
||||
@@ -32,7 +32,7 @@ module.exports = (grunt) ->
|
||||
packageJsonPath = path.join(appDir, 'package.json')
|
||||
packageJson = require(packageJsonPath)
|
||||
packageJson.version = version
|
||||
packageJsonString = JSON.stringify(packageJson, null, 2)
|
||||
packageJsonString = JSON.stringify(packageJson)
|
||||
fs.writeFileSync(packageJsonPath, packageJsonString)
|
||||
|
||||
if process.platform is 'darwin'
|
||||
|
||||
@@ -4,6 +4,8 @@ path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
async = require 'async'
|
||||
|
||||
concurrency = 2
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{isAtomPackage, spawn} = require('./task-helpers')(grunt)
|
||||
|
||||
@@ -61,7 +63,7 @@ module.exports = (grunt) ->
|
||||
continue unless isAtomPackage(packagePath)
|
||||
packageSpecQueue.push(packagePath)
|
||||
|
||||
packageSpecQueue.concurrency = 1
|
||||
packageSpecQueue.concurrency = concurrency - 1
|
||||
packageSpecQueue.drain = -> callback(null, failedPackages)
|
||||
|
||||
runCoreSpecs = (callback) ->
|
||||
@@ -84,7 +86,7 @@ module.exports = (grunt) ->
|
||||
fs.unlinkSync('ci.log')
|
||||
else
|
||||
# TODO: Restore concurrency on Windows
|
||||
packageSpecQueue.concurrency = 2
|
||||
packageSpecQueue.concurrency = concurrency
|
||||
|
||||
callback(null, error)
|
||||
|
||||
@@ -102,7 +104,7 @@ module.exports = (grunt) ->
|
||||
method [runCoreSpecs, runPackageSpecs], (error, results) ->
|
||||
[coreSpecFailed, failedPackages] = results
|
||||
elapsedTime = Math.round((Date.now() - startTime) / 100) / 10
|
||||
grunt.verbose.writeln("Total spec time: #{elapsedTime}s")
|
||||
grunt.log.ok("Total spec time: #{elapsedTime}s using #{concurrency} cores")
|
||||
failures = failedPackages
|
||||
failures.push "atom core" if coreSpecFailed
|
||||
|
||||
|
||||
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.
@@ -6,25 +6,25 @@ Keymap files are encoded as JSON or CSON files containing nested hashes. They
|
||||
work much like stylesheets, but instead of applying style properties to elements
|
||||
matching the selector, they specify the meaning of keystrokes on elements
|
||||
matching the selector. Here is an example of some bindings that apply when
|
||||
keystrokes pass through elements with the class `.editor`:
|
||||
keystrokes pass through `atom-text-editor` elements:
|
||||
|
||||
```coffee
|
||||
'.editor':
|
||||
'atom-text-editor':
|
||||
'cmd-delete': 'editor:delete-to-beginning-of-line'
|
||||
'alt-backspace': 'editor:delete-to-beginning-of-word'
|
||||
'ctrl-A': 'editor:select-to-first-character-of-line'
|
||||
'ctrl-shift-e': 'editor:select-to-end-of-line'
|
||||
'cmd-left': 'editor:move-to-first-character-of-line'
|
||||
|
||||
'.editor:not(.mini)'
|
||||
'atom-text-editor:not(.mini)'
|
||||
'cmd-alt-[': 'editor:fold-current-row'
|
||||
'cmd-alt-]': 'editor:unfold-current-row'
|
||||
```
|
||||
|
||||
Beneath the first selector are several bindings, mapping specific *keystroke
|
||||
patterns* to *commands*. When an element with the `.editor` class is focused and
|
||||
patterns* to *commands*. When an element with the `atom-text-editor` class is focused and
|
||||
`cmd-delete` is pressed, an custom DOM event called
|
||||
`editor:delete-to-beginning-of-line` is emitted on the `.editor` element.
|
||||
`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
|
||||
@@ -91,7 +91,7 @@ the current keystroke sequence and continue searching from its parent. If you
|
||||
want to remove a binding from a keymap you don't control, such as keymaps in
|
||||
Atom core or in packages, use the `unset!` directive.
|
||||
|
||||
For example, the following code removes the keybinding for `a` in the Tree View,
|
||||
For example, the following code removes the keybinding for `a` in the Tree View,
|
||||
which is normally used to trigger the `tree-view:add-file` command:
|
||||
|
||||
```coffee
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
# Scoped Settings, Scopes and Scope Descriptors
|
||||
|
||||
Atom supports language-specific settings. You can soft wrap only Markdown files, or set the tab length to 4 in Python files.
|
||||
|
||||
Language-specific settings are a subset of something more general we call "scoped settings". Scoped settings allow targeting down to a specific syntax token type. For example, you could conceivably set a setting to target only Ruby comments, only code inside Markdown files, or even only JavaScript function names.
|
||||
|
||||
## Scope names in syntax tokens
|
||||
|
||||
Each token in the editor has a collection of scope names. For example, the aformentioned JavaScript function name might have the scope names `function` and `name`. An open paren might have the scope names `punctuation`, `parameters`, `begin`.
|
||||
|
||||
Scope names work just like CSS classes. In fact, in the editor, scope names are attached to a token's DOM node as CSS classes.
|
||||
|
||||
Take this piece of JavaScript:
|
||||
|
||||
```js
|
||||
function functionName() {
|
||||
console.log('Log it out');
|
||||
}
|
||||
```
|
||||
|
||||
In the dev tools, the first line's markup looks like this.
|
||||
|
||||

|
||||
|
||||
All the class names on the spans are scope names. Any scope name can be used to target a setting's value.
|
||||
|
||||
## Scope Selectors
|
||||
|
||||
Scope selectors allow you to target specific tokens just like a CSS selector targets specific nodes in the DOM. Some examples:
|
||||
|
||||
```coffee
|
||||
'.source.js' # selects all javascript tokens
|
||||
'.source.js .function.name' # selects all javascript function names
|
||||
'.function.name' # selects all function names in any language
|
||||
```
|
||||
|
||||
[Config::set][config-set] accepts a `scopeSelector`. If you'd like to set a setting for JavaScript function names, you can give it the js function name `scopeSelector`:
|
||||
|
||||
```coffee
|
||||
atom.config.set('.source.js .function.name', 'my-package.my-setting', 'special value')
|
||||
```
|
||||
|
||||
## Scope Descriptors
|
||||
|
||||
A scope descriptor is an [Object][scope-descriptor] that wraps an `Array` of
|
||||
`String`s. The Array describes a path from the root of the syntax tree to a
|
||||
token including _all_ scope names for the entire path.
|
||||
|
||||
In our JavaScript example above, a scope descriptor for the function name token would be:
|
||||
|
||||
```coffee
|
||||
['source.js', 'meta.function.js', 'entity.name.function.js']
|
||||
```
|
||||
|
||||
[Config::get][config-get] accepts a `scopeDescriptor`. You can get the value for your setting scoped to JavaScript function names via:
|
||||
|
||||
```coffee
|
||||
scopeDescriptor = ['source.js', 'meta.function.js', 'entity.name.function.js']
|
||||
value = atom.config.get(scopeDescriptor, 'my-package.my-setting')
|
||||
```
|
||||
|
||||
But, you do not need to generate scope descriptors by hand. There are a couple methods available to get the scope descriptor from the editor:
|
||||
|
||||
* [Editor::getRootScopeDescriptor][editor-getRootScopeDescriptor] to get the language's descriptor. eg. `[".source.js"]`
|
||||
* [Editor::scopeDescriptorForBufferPosition][editor-scopeDescriptorForBufferPosition] to get the descriptor at a specific position in the buffer.
|
||||
* [Cursor::getScopeDescriptor][cursor-getScopeDescriptor] to get a cursor's descriptor based on position. eg. if the cursor were in the name of the method in our example it would return `["source.js", "meta.function.js", "entity.name.function.js"]`
|
||||
|
||||
Let's revisit our example using these methods:
|
||||
|
||||
```coffee
|
||||
editor = atom.workspace.getActiveTextEditor()
|
||||
cursor = editor.getLastCursor()
|
||||
valueAtCursor = atom.config.get(cursor.getScopeDescriptor(), 'my-package.my-setting')
|
||||
valueForLanguage = atom.config.get(editor.getRootScopeDescriptor(), 'my-package.my-setting')
|
||||
```
|
||||
|
||||
|
||||
[config]:https://atom.io/docs/api/latest/Config
|
||||
[config-get]:https://atom.io/docs/api/latest/Config#instance-get
|
||||
[config-set]:https://atom.io/docs/api/latest/Config#instance-set
|
||||
[config-observe]:https://atom.io/docs/api/latest/Config#instance-observe
|
||||
|
||||
[editor-getRootScopeDescriptor]:https://atom.io/docs/api/latest/TextEditor#instance-getRootScopeDescriptor
|
||||
[editor-scopeDescriptorForBufferPosition]:https://atom.io/docs/api/latest/TextEditor#instance-scopeDescriptorForBufferPosition
|
||||
|
||||
[cursor-getScopeDescriptor]:https://atom.io/docs/api/latest/Cursor#instance-getScopeDescriptor
|
||||
[scope-descriptor]:https://atom.io/docs/api/latest/ScopeDescriptor
|
||||
@@ -11,7 +11,7 @@ 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('.editor.active') # standard jQuery method
|
||||
atom.workspaceView.find('atom-text-editor.active') # standard jQuery method
|
||||
atom.workspaceView.getActiveEditor() # view-specific method
|
||||
```
|
||||
|
||||
@@ -20,7 +20,7 @@ If you retrieve a jQuery wrapper for an element associated with a view, use the
|
||||
|
||||
```coffeescript
|
||||
# this is a plain jQuery object; you can't call view-specific methods
|
||||
editorElement = atom.workspaceView.find('.editor.active')
|
||||
editorElement = atom.workspaceView.find('atom-text-editor.active')
|
||||
|
||||
# get the view object by calling `.view()` to call view-specific methods
|
||||
editorView = editorElement.view()
|
||||
|
||||
@@ -16,17 +16,17 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
|
||||
|
||||
### Ubuntu / Debian
|
||||
|
||||
* `sudo apt-get install build-essential git libgnome-keyring-dev`
|
||||
* `sudo apt-get install build-essential git libgnome-keyring-dev fakeroot`
|
||||
* Instructions for [Node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
|
||||
|
||||
### Fedora
|
||||
### Fedora / CentOS / RHEL
|
||||
|
||||
* `sudo yum --assumeyes install make gcc gcc-c++ glibc-devel git-core libgnome-keyring-devel`
|
||||
* `sudo yum --assumeyes install make gcc gcc-c++ glibc-devel git-core libgnome-keyring-devel rpmdevtools`
|
||||
* Instructions for [Node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#fedora).
|
||||
|
||||
### Arch
|
||||
|
||||
* `sudo pacman -S base-devel git nodejs libgnome-keyring`
|
||||
* `sudo pacman -S base-devel git nodejs libgnome-keyring python2`
|
||||
* `export PYTHON=/usr/bin/python2` before building Atom.
|
||||
|
||||
## Instructions
|
||||
@@ -61,13 +61,19 @@ If you have problems with permissions don't forget to prefix with `sudo`
|
||||
sudo script/grunt install
|
||||
```
|
||||
|
||||
5. *Optionally*, you may generate a `.deb` package at `$TMPDIR/atom-build`:
|
||||
To use the newly installed Atom, quit and restart all running Atom instances.
|
||||
|
||||
5. *Optionally*, you may generate distributable packages of Atom at `$TMPDIR/atom-build`. Currenty, `.deb` and `.rpm` package types are supported. To create a `.deb` package run:
|
||||
|
||||
```sh
|
||||
script/grunt mkdeb
|
||||
```
|
||||
|
||||
Use the newly installed Atom by fully quitting Atom and then reopening.
|
||||
To create an `.rpm` package run
|
||||
|
||||
```sh
|
||||
script/grunt mkrpm
|
||||
```
|
||||
|
||||
## Advanced Options
|
||||
|
||||
@@ -85,7 +91,7 @@ script/build --build-dir /build/atom/here
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Exception: "TypeError: Unable to watch path"
|
||||
### TypeError: Unable to watch path
|
||||
|
||||
If you get following error with a big traceback right after Atom starts:
|
||||
|
||||
@@ -115,6 +121,22 @@ 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.
|
||||
|
||||
### AttributeError: 'module' object has no attribute 'script_main'
|
||||
|
||||
If you get following error with a big traceback while building Atom:
|
||||
|
||||
```
|
||||
sys.exit(gyp.script_main()) AttributeError: 'module' object has no attribute 'script_main' gyp ERR!
|
||||
```
|
||||
|
||||
you need to uninstall the system version of gyp.
|
||||
|
||||
On Fedora you would do the following:
|
||||
|
||||
```sh
|
||||
sudo yum remove gyp
|
||||
```
|
||||
|
||||
#### You can also use Alternatives
|
||||
|
||||
On some variants (mostly Debian based distros) it's preferable for you to use
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
## Why do I have to use GitHub for Windows?
|
||||
|
||||
You don't. You can use your existing Git! GitHub for Windows's Git Shell is just
|
||||
easier to set up.
|
||||
easier to set up.
|
||||
|
||||
If you _prefer_ using your existing Git installation, make sure git's cmd directory is in your PATH env variable (e.g. `C:\Program Files (x86)\Git\cmd`) before you open your powershell or command window.
|
||||
Note that you may have to open your command window as administrator. For powershell that doesn't seem to always be the case, though.
|
||||
@@ -67,11 +67,11 @@ If none of this works, do install Github for Windows and use its Git shell. Make
|
||||
* https://code.google.com/p/gyp/issues/detail?id=393
|
||||
|
||||
* `script/build` stops at installing runas with 'Failed at the runas@0.5.4 install script.'
|
||||
|
||||
|
||||
See the next item.
|
||||
|
||||
* `error MSB8020: The build tools for Visual Studio 2010 (Platform Toolset = 'v100') cannot be found.`
|
||||
|
||||
|
||||
* If you're building atom with Visual Studio 2013 try executing the following
|
||||
command in your Git shell and then re-run `script/build`:
|
||||
|
||||
|
||||
@@ -9,22 +9,27 @@ in the proper package's repository.
|
||||
|
||||
### Cloning
|
||||
|
||||
The first step is creating your own clone. You can of course do this manually
|
||||
with git, or you can use the `apm develop` command to create a clone based on
|
||||
the package's `repository` field in the `package.json`.
|
||||
The first step is creating your own clone.
|
||||
|
||||
For example, if you want to make changes to the `tree-view` package, run the
|
||||
following command:
|
||||
For example, if you want to make changes to the `tree-view` package, fork the repo on your github account, then clone it:
|
||||
|
||||
```
|
||||
> apm develop tree-view
|
||||
Cloning https://github.com/atom/tree-view ✓
|
||||
> git clone git@github.com:your-username/tree-view.git
|
||||
```
|
||||
|
||||
Next install all the dependencies:
|
||||
|
||||
```
|
||||
> cd tree-view
|
||||
> apm install
|
||||
Installing modules ✓
|
||||
~/.atom/dev/packages/tree-view -> ~/github/tree-view
|
||||
```
|
||||
|
||||
This clones the `tree-view` repository to `~/github`. If you prefer a different
|
||||
path, specify it via the `ATOM_REPOS_HOME` environment variable.
|
||||
Now you can link it to development mode so when you run an Atom window with `atom --dev`, you will use your fork instead of the built in package:
|
||||
|
||||
```
|
||||
> apm link -d
|
||||
```
|
||||
|
||||
### Running in Development Mode
|
||||
|
||||
@@ -46,7 +51,4 @@ from the package directory to create and remove dev-mode symlinks.
|
||||
|
||||
### Installing Dependencies
|
||||
|
||||
Finally, you need to install the cloned package's dependencies by running
|
||||
`apm install` within the package directory. This step is also performed
|
||||
automatically the first time you run `apm develop`, but you'll want to keep
|
||||
dependencies up to date by running `apm update` after pulling upstream changes.
|
||||
You'll want to keep dependencies up to date by running `apm update` after pulling any upstream changes.
|
||||
|
||||
@@ -210,7 +210,7 @@ specific parts of the interface, like adding a file in the tree-view:
|
||||
'.tree-view': [
|
||||
{label: 'Add file', command: 'tree-view:add-file'}
|
||||
]
|
||||
'.workspace': [
|
||||
'atom-workspace': [
|
||||
{label: 'Inspect Element', command: 'core:inspect'}
|
||||
]
|
||||
```
|
||||
@@ -233,7 +233,7 @@ an item with a single `type: 'separator'` key/value pair.
|
||||
|
||||
```coffeescript
|
||||
'context-menu':
|
||||
'.workspace': [
|
||||
'atom-workspace': [
|
||||
{
|
||||
label: 'Text'
|
||||
submenu: [
|
||||
|
||||
@@ -60,10 +60,10 @@ with events in specific contexts. Here's a small example, excerpted from Atom's
|
||||
built-in keymaps:
|
||||
|
||||
```coffee
|
||||
'.editor':
|
||||
'atom-text-editor':
|
||||
'enter': 'editor:newline'
|
||||
|
||||
'.mini.editor input':
|
||||
'atom-text-editor.mini input':
|
||||
'enter': 'core:confirm'
|
||||
```
|
||||
|
||||
@@ -169,7 +169,7 @@ For example, to change the color of the cursor, you could add the following
|
||||
rule to your _~/.atom/styles.less_ file:
|
||||
|
||||
```less
|
||||
.editor.is-focused .cursor {
|
||||
atom-text-editor.is-focused .cursor {
|
||||
border-color: pink;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
* [Converting a TextMate Bundle](converting-a-text-mate-bundle.md)
|
||||
* [Converting a TextMate Theme](converting-a-text-mate-theme.md)
|
||||
* [Contributing](contributing.md)
|
||||
* [Contributing to Core Packages](contributing-to-packages.md)
|
||||
* [Debugging](debugging.md)
|
||||
|
||||
### Advanced Topics
|
||||
@@ -18,3 +19,4 @@
|
||||
* [Keymaps](advanced/keymaps.md)
|
||||
* [Serialization](advanced/serialization.md)
|
||||
* [View System](advanced/view-system.md)
|
||||
* [Scopes and Scope Descriptors](advanced/scopes-and-scope-descriptors.md)
|
||||
|
||||
@@ -91,13 +91,13 @@ _keymaps/ascii-art.cson_ and add a key binding linking `ctrl-alt-a` to the
|
||||
you don't need it anymore. When finished, the file will look like this:
|
||||
|
||||
```coffeescript
|
||||
'.editor':
|
||||
'atom-text-editor':
|
||||
'cmd-alt-a': 'ascii-art:convert'
|
||||
```
|
||||
|
||||
Notice `.editor` on the first line. Just like CSS, keymap selectors *scope* key
|
||||
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 `.editor` selector. If the Tree View has
|
||||
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
|
||||
|
||||
@@ -4,11 +4,8 @@
|
||||
# after packages are loaded/activated and after the previous editor state
|
||||
# has been restored.
|
||||
#
|
||||
# An example hack to make opened Markdown files always be soft wrapped:
|
||||
# An example hack to log to the console when each text editor is saved.
|
||||
#
|
||||
# path = require 'path'
|
||||
#
|
||||
# atom.workspaceView.eachEditorView (editorView) ->
|
||||
# editor = editorView.getEditor()
|
||||
# if path.extname(editor.getPath()) is '.md'
|
||||
# editor.setSoftWrapped(true)
|
||||
# atom.workspace.observeTextEditors (editor) ->
|
||||
# editor.onDidSave ->
|
||||
# console.log "Saved! #{editor.getPath()}"
|
||||
|
||||
@@ -9,13 +9,17 @@
|
||||
#
|
||||
# Here's an example taken from Atom's built-in keymap:
|
||||
#
|
||||
# '.editor':
|
||||
# 'atom-text-editor':
|
||||
# 'enter': 'editor:newline'
|
||||
#
|
||||
# '.workspace':
|
||||
# 'atom-workspace':
|
||||
# 'ctrl-shift-p': 'core:move-up'
|
||||
# 'ctrl-p': 'core:move-down'
|
||||
#
|
||||
# You can find more information about keymaps in these guides:
|
||||
# * https://atom.io/docs/latest/customizing-atom#customizing-key-bindings
|
||||
# * https://atom.io/docs/latest/advanced/keymaps
|
||||
#
|
||||
# This file uses CoffeeScript Object Notation (CSON).
|
||||
# If you are unfamiliar with CSON, you can read more about it here:
|
||||
# https://github.com/bevry/cson#what-is-cson
|
||||
|
||||
@@ -13,3 +13,6 @@
|
||||
# 'prefix': 'log'
|
||||
# 'body': 'console.log $1'
|
||||
#
|
||||
# This file uses CoffeeScript Object Notation (CSON).
|
||||
# If you are unfamiliar with CSON, you can read more about it here:
|
||||
# https://github.com/bevry/cson#what-is-cson
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
|
||||
}
|
||||
|
||||
.editor {
|
||||
atom-text-editor {
|
||||
|
||||
}
|
||||
|
||||
.editor .cursor {
|
||||
atom-text-editor .cursor {
|
||||
|
||||
}
|
||||
|
||||
+6
-3
@@ -1,11 +1,11 @@
|
||||
'.editor':
|
||||
'atom-text-editor':
|
||||
# Platform Bindings
|
||||
'home': 'editor:move-to-first-character-of-line'
|
||||
'end': 'editor:move-to-end-of-screen-line'
|
||||
'shift-home': 'editor:select-to-first-character-of-line'
|
||||
'shift-end': 'editor:select-to-end-of-line'
|
||||
|
||||
'.editor:not(.mini)':
|
||||
'atom-text-editor:not(.mini)':
|
||||
# Atom Specific
|
||||
'ctrl-C': 'editor:copy-path'
|
||||
|
||||
@@ -15,10 +15,13 @@
|
||||
'shift-tab': 'editor:outdent-selected-rows'
|
||||
'ctrl-K': 'editor:delete-line'
|
||||
|
||||
'.select-list atom-text-editor.mini':
|
||||
'enter': 'core:confirm'
|
||||
|
||||
'.tool-panel.panel-left, .tool-panel.panel-right':
|
||||
'escape': 'tool-panel:unfocus'
|
||||
|
||||
'.editor !important, .editor.mini !important':
|
||||
'atom-text-editor !important, atom-text-editor.mini !important':
|
||||
'escape': 'editor:consolidate-selections'
|
||||
|
||||
# allow standard input fields to work correctly
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
'cmd-8': 'pane:show-item-8'
|
||||
'cmd-9': 'pane:show-item-9'
|
||||
|
||||
'.editor':
|
||||
'atom-text-editor':
|
||||
# Platform Bindings
|
||||
'alt-left': 'editor:move-to-beginning-of-word'
|
||||
'alt-right': 'editor:move-to-end-of-word'
|
||||
@@ -134,7 +134,7 @@
|
||||
'cmd-l': 'editor:select-line'
|
||||
'ctrl-t': 'editor:transpose'
|
||||
|
||||
'.workspace .editor:not(.mini)':
|
||||
'atom-workspace atom-text-editor:not(.mini)':
|
||||
# Atom specific
|
||||
'alt-cmd-z': 'editor:checkout-head-revision'
|
||||
'cmd-<': 'editor:scroll-to-cursor'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
'.editor':
|
||||
'atom-text-editor':
|
||||
'alt-f': 'editor:move-to-end-of-word'
|
||||
'alt-F': 'editor:select-to-end-of-word'
|
||||
'alt-b': 'editor:move-to-beginning-of-word'
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
'alt-8': 'pane:show-item-8'
|
||||
'alt-9': 'pane:show-item-9'
|
||||
|
||||
'.workspace .editor':
|
||||
'atom-workspace atom-text-editor':
|
||||
# Platform Bindings
|
||||
'ctrl-left': 'editor:move-to-beginning-of-word'
|
||||
'ctrl-right': 'editor:move-to-end-of-word'
|
||||
@@ -99,7 +99,7 @@
|
||||
'ctrl-k ctrl-l': 'editor:lower-case'
|
||||
'ctrl-l': 'editor:select-line'
|
||||
|
||||
'.workspace .editor:not(.mini)':
|
||||
'atom-workspace atom-text-editor:not(.mini)':
|
||||
# Atom specific
|
||||
'alt-ctrl-z': 'editor:checkout-head-revision'
|
||||
'ctrl-<': 'editor:scroll-to-cursor'
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
'ctrl-alt-i': 'window:toggle-dev-tools'
|
||||
'ctrl-alt-p': 'window:run-package-specs'
|
||||
'ctrl-alt-s': 'application:run-all-specs'
|
||||
'ctrl-alt-o': 'application:open-dev'
|
||||
'ctrl-shift-o': 'application:open-folder'
|
||||
'F11': 'window:toggle-full-screen'
|
||||
|
||||
# Sublime Parity
|
||||
@@ -74,7 +76,7 @@
|
||||
'ctrl-k ctrl-left': 'window:focus-pane-on-left'
|
||||
'ctrl-k ctrl-right': 'window:focus-pane-on-right'
|
||||
|
||||
'.workspace .editor':
|
||||
'atom-workspace atom-text-editor':
|
||||
# Platform Bindings
|
||||
'ctrl-left': 'editor:move-to-beginning-of-word'
|
||||
'ctrl-right': 'editor:move-to-end-of-word'
|
||||
@@ -94,7 +96,7 @@
|
||||
'ctrl-k ctrl-l': 'editor:lower-case'
|
||||
'ctrl-l': 'editor:select-line'
|
||||
|
||||
'.workspace .editor:not(.mini)':
|
||||
'atom-workspace atom-text-editor:not(.mini)':
|
||||
# Atom specific
|
||||
'alt-ctrl-z': 'editor:checkout-head-revision'
|
||||
'ctrl-<': 'editor:scroll-to-cursor'
|
||||
|
||||
+7
-1
@@ -190,6 +190,12 @@
|
||||
submenu: [
|
||||
{ label: 'Terms of Use', command: 'application:open-terms-of-use' }
|
||||
{ label: 'Documentation', command: 'application:open-documentation' }
|
||||
{ label: 'Roadmap', command: 'application:open-roadmap' }
|
||||
{ label: 'Frequently Asked Questions', command: 'application:open-faq' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Community Discussions', command: 'application:open-discussions' }
|
||||
{ label: 'Report Issue', command: 'application:report-issue' }
|
||||
{ label: 'Search Issues', command: 'application:search-issues' }
|
||||
{ type: 'separator' }
|
||||
]
|
||||
}
|
||||
@@ -212,7 +218,7 @@
|
||||
{label: 'Split Right', command: 'pane:split-right'}
|
||||
{type: 'separator'}
|
||||
]
|
||||
'.pane': [
|
||||
'atom-pane': [
|
||||
{type: 'separator'}
|
||||
{label: 'Split Up', command: 'pane:split-up'}
|
||||
{label: 'Split Down', command: 'pane:split-down'}
|
||||
|
||||
+7
-1
@@ -147,6 +147,12 @@
|
||||
{ label: "VERSION", enabled: false }
|
||||
{ type: 'separator' }
|
||||
{ label: '&Documentation', command: 'application:open-documentation' }
|
||||
{ label: 'Roadmap', command: 'application:open-roadmap' }
|
||||
{ label: 'Frequently Asked Questions', command: 'application:open-faq' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Community Discussions', command: 'application:open-discussions' }
|
||||
{ label: 'Report Issue', command: 'application:report-issue' }
|
||||
{ label: 'Search Issues', command: 'application:search-issues' }
|
||||
{ type: 'separator' }
|
||||
]
|
||||
}
|
||||
@@ -169,7 +175,7 @@
|
||||
{label: 'Split Right', command: 'pane:split-right'}
|
||||
{type: 'separator'}
|
||||
]
|
||||
'.pane': [
|
||||
'atom-pane': [
|
||||
{type: 'separator'}
|
||||
{label: 'Split Up', command: 'pane:split-up'}
|
||||
{label: 'Split Down', command: 'pane:split-down'}
|
||||
|
||||
+7
-1
@@ -165,6 +165,12 @@
|
||||
{ label: "VERSION", enabled: false }
|
||||
{ type: 'separator' }
|
||||
{ label: '&Documentation', command: 'application:open-documentation' }
|
||||
{ label: 'Roadmap', command: 'application:open-roadmap' }
|
||||
{ label: 'Frequently Asked Questions', command: 'application:open-faq' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Community Discussions', command: 'application:open-discussions' }
|
||||
{ label: 'Report Issue', command: 'application:report-issue' }
|
||||
{ label: 'Search Issues', command: 'application:search-issues' }
|
||||
{ type: 'separator' }
|
||||
]
|
||||
}
|
||||
@@ -187,7 +193,7 @@
|
||||
{label: 'Split Right', command: 'pane:split-right'}
|
||||
{type: 'separator'}
|
||||
]
|
||||
'.pane': [
|
||||
'atom-pane': [
|
||||
{type: 'separator'}
|
||||
{label: 'Split Up', command: 'pane:split-up'}
|
||||
{label: 'Split Down', command: 'pane:split-down'}
|
||||
|
||||
+58
-57
@@ -1,7 +1,7 @@
|
||||
{
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "0.136.0",
|
||||
"version": "0.144.0",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/browser/main.js",
|
||||
"repository": {
|
||||
@@ -17,10 +17,10 @@
|
||||
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
|
||||
}
|
||||
],
|
||||
"atomShellVersion": "0.17.1",
|
||||
"atomShellVersion": "0.19.1",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "^2.2.0",
|
||||
"atom-keymap": "^2.2.2",
|
||||
"bootstrap": "git+https://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
|
||||
"clear-cut": "0.4.0",
|
||||
"coffee-script": "1.7.0",
|
||||
@@ -35,111 +35,112 @@
|
||||
"git-utils": "^2.1.5",
|
||||
"grim": "0.12.0",
|
||||
"guid": "0.0.10",
|
||||
"jasmine-json": "~0.0",
|
||||
"jasmine-tagged": "^1.1.2",
|
||||
"less-cache": "0.15.0",
|
||||
"less-cache": "0.17.0",
|
||||
"mixto": "^1",
|
||||
"mkdirp": "0.3.5",
|
||||
"nslog": "^1.0.1",
|
||||
"oniguruma": "^3.0.4",
|
||||
"optimist": "0.4.0",
|
||||
"pathwatcher": "^2.1.3",
|
||||
"pathwatcher": "^2.3.2",
|
||||
"property-accessors": "^1",
|
||||
"q": "^1.0.1",
|
||||
"random-words": "0.0.1",
|
||||
"react-atom-fork": "^0.11.1",
|
||||
"reactionary-atom-fork": "^1.0.0",
|
||||
"runas": "1.0.1",
|
||||
"scandal": "1.0.2",
|
||||
"scoped-property-store": "^0.11.0",
|
||||
"scandal": "1.0.3",
|
||||
"scoped-property-store": "^0.15.0",
|
||||
"scrollbar-style": "^1.0.2",
|
||||
"season": "^1.0.2",
|
||||
"semver": "1.1.4",
|
||||
"semver": "2.2.1",
|
||||
"serializable": "^1",
|
||||
"space-pen": "3.6.1",
|
||||
"space-pen": "3.8.1",
|
||||
"temp": "0.7.0",
|
||||
"text-buffer": "^3.2.8",
|
||||
"text-buffer": "^3.6.0",
|
||||
"theorist": "^1.0.2",
|
||||
"underscore-plus": "^1.5.1",
|
||||
"underscore-plus": "^1.6.1",
|
||||
"vm-compatibility-layer": "0.1.0"
|
||||
},
|
||||
"packageDependencies": {
|
||||
"atom-dark-syntax": "0.19.0",
|
||||
"atom-dark-syntax": "0.20.0",
|
||||
"atom-dark-ui": "0.35.0",
|
||||
"atom-light-syntax": "0.20.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.32.0",
|
||||
"autocomplete": "0.33.0",
|
||||
"autoflow": "0.18.0",
|
||||
"autosave": "0.18.0",
|
||||
"background-tips": "0.17.0",
|
||||
"bookmarks": "0.28.0",
|
||||
"bracket-matcher": "0.61.0",
|
||||
"bookmarks": "0.30.0",
|
||||
"bracket-matcher": "0.62.0",
|
||||
"command-palette": "0.27.0",
|
||||
"deprecation-cop": "0.10.0",
|
||||
"dev-live-reload": "0.34.0",
|
||||
"deprecation-cop": "0.11.0",
|
||||
"dev-live-reload": "0.35.0",
|
||||
"encoding-selector": "0.5.0",
|
||||
"exception-reporting": "0.20.0",
|
||||
"feedback": "0.33.0",
|
||||
"find-and-replace": "0.139.0",
|
||||
"fuzzy-finder": "0.58.0",
|
||||
"git-diff": "0.39.0",
|
||||
"go-to-line": "0.25.0",
|
||||
"grammar-selector": "0.34.0",
|
||||
"image-view": "0.37.0",
|
||||
"incompatible-packages": "0.9.0",
|
||||
"find-and-replace": "0.145.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.25.0",
|
||||
"markdown-preview": "0.103.0",
|
||||
"metrics": "0.36.0",
|
||||
"link": "0.26.0",
|
||||
"markdown-preview": "0.109.0",
|
||||
"metrics": "0.38.0",
|
||||
"open-on-github": "0.30.0",
|
||||
"package-generator": "0.31.0",
|
||||
"package-generator": "0.32.0",
|
||||
"release-notes": "0.36.0",
|
||||
"settings-view": "0.149.0",
|
||||
"snippets": "0.55.0",
|
||||
"spell-check": "0.42.0",
|
||||
"settings-view": "0.156.0",
|
||||
"snippets": "0.56.0",
|
||||
"spell-check": "0.43.0",
|
||||
"status-bar": "0.46.0",
|
||||
"styleguide": "0.30.0",
|
||||
"symbols-view": "0.66.0",
|
||||
"tabs": "0.54.0",
|
||||
"timecop": "0.22.0",
|
||||
"tree-view": "0.128.0",
|
||||
"symbols-view": "0.67.0",
|
||||
"tabs": "0.55.0",
|
||||
"timecop": "0.23.0",
|
||||
"tree-view": "0.132.0",
|
||||
"update-package-dependencies": "0.6.0",
|
||||
"welcome": "0.18.0",
|
||||
"whitespace": "0.25.0",
|
||||
"wrap-guide": "0.22.0",
|
||||
"language-c": "0.28.0",
|
||||
"language-coffee-script": "0.35.0",
|
||||
"language-css": "0.18.0",
|
||||
"language-gfm": "0.51.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.22.0",
|
||||
"language-gfm": "0.53.0",
|
||||
"language-git": "0.9.0",
|
||||
"language-go": "0.18.0",
|
||||
"language-go": "0.19.0",
|
||||
"language-html": "0.26.0",
|
||||
"language-hyperlink": "0.12.0",
|
||||
"language-java": "0.11.0",
|
||||
"language-javascript": "0.40.0",
|
||||
"language-javascript": "0.43.0",
|
||||
"language-json": "0.8.0",
|
||||
"language-less": "0.15.0",
|
||||
"language-less": "0.18.0",
|
||||
"language-make": "0.12.0",
|
||||
"language-mustache": "0.10.0",
|
||||
"language-objective-c": "0.11.0",
|
||||
"language-perl": "0.9.0",
|
||||
"language-php": "0.16.0",
|
||||
"language-php": "0.18.0",
|
||||
"language-property-list": "0.7.0",
|
||||
"language-python": "0.19.0",
|
||||
"language-ruby": "0.39.0",
|
||||
"language-python": "0.23.0",
|
||||
"language-ruby": "0.41.0",
|
||||
"language-ruby-on-rails": "0.18.0",
|
||||
"language-sass": "0.22.0",
|
||||
"language-shellscript": "0.8.0",
|
||||
"language-sass": "0.25.0",
|
||||
"language-shellscript": "0.10.0",
|
||||
"language-source": "0.8.0",
|
||||
"language-sql": "0.11.0",
|
||||
"language-text": "0.6.0",
|
||||
"language-todo": "0.12.0",
|
||||
"language-toml": "0.12.0",
|
||||
"language-xml": "0.22.0",
|
||||
"language-yaml": "0.18.0"
|
||||
"language-todo": "0.13.0",
|
||||
"language-toml": "0.14.0",
|
||||
"language-xml": "0.24.0",
|
||||
"language-yaml": "0.19.0"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
[Desktop Entry]
|
||||
Name=Atom
|
||||
Comment=<%= description %>
|
||||
GenericName=Text Editor
|
||||
Exec=<%= installDir %>/share/atom/atom %U
|
||||
Icon=<%= iconName %>
|
||||
Type=Application
|
||||
@@ -0,0 +1,26 @@
|
||||
Name: <%= name %>
|
||||
Version: <%= version %>
|
||||
Release: 0.1%{?dist}
|
||||
Summary: Atom is a hackable text editor for the 21st century
|
||||
License: MIT
|
||||
URL: https://atom.io/
|
||||
AutoReqProv: no # Avoid libchromiumcontent.so missing dependency
|
||||
|
||||
%description
|
||||
<%= description %>
|
||||
|
||||
%install
|
||||
mkdir -p %{buildroot}/usr/local/share/atom
|
||||
cp -r /tmp/atom-build/Atom/* %{buildroot}/usr/local/share/atom
|
||||
mkdir -p %{buildroot}/usr/local/bin/
|
||||
ln -sf /usr/local/share/atom/resources/app/apm/node_modules/.bin/apm %{buildroot}/usr/local/bin/apm
|
||||
cp atom.sh %{buildroot}/usr/local/bin/atom
|
||||
chmod 755 atom.sh
|
||||
mkdir -p %{buildroot}/usr/local/share/applications/
|
||||
mv atom.desktop %{buildroot}/usr/local/share/applications/
|
||||
|
||||
%files
|
||||
/usr/local/bin/atom
|
||||
/usr/local/bin/apm
|
||||
/usr/local/share/atom/
|
||||
/usr/local/share/applications/atom.desktop
|
||||
Arquivo executável
+10
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
docker build -t atom-rpm .
|
||||
docker run \
|
||||
--env JANKY_SHA1="$JANKY_SHA1" \
|
||||
--env JANKY_BRANCH="$JANKY_BRANCH" \
|
||||
--env ATOM_ACCESS_TOKEN="$BUILD_ATOM_RPM_ACCESS_TOKEN" \
|
||||
atom-rpm /atom/script/rpmbuild
|
||||
@@ -15,4 +15,4 @@ if [%2] == [] (
|
||||
if exist %2 rmdir %2 /s /q
|
||||
|
||||
:: cp -rf %1 %2
|
||||
xcopy %1 %2 /e /h /c /i /y /r
|
||||
(robocopy %1 %2 /e) ^& IF %ERRORLEVEL% LEQ 1 exit 0
|
||||
|
||||
Arquivo executável
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
SPEC_FILE="$1"
|
||||
DESKTOP_FILE="$2"
|
||||
BUILD_DIRECTORY="$3"
|
||||
|
||||
RPM_BUILD_ROOT=~/rpmbuild
|
||||
ARCH=`uname -m`
|
||||
|
||||
rpmdev-setuptree
|
||||
|
||||
cp -r $BUILD_DIRECTORY/Atom/* $RPM_BUILD_ROOT/BUILD
|
||||
cp $SPEC_FILE $RPM_BUILD_ROOT/SPECS
|
||||
cp ./atom.sh $RPM_BUILD_ROOT/BUILD
|
||||
cp $DESKTOP_FILE $RPM_BUILD_ROOT/BUILD
|
||||
|
||||
rpmbuild -ba $SPEC_FILE
|
||||
cp $RPM_BUILD_ROOT/RPMS/$ARCH/atom-*.rpm $BUILD_DIRECTORY/rpm
|
||||
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
Arquivo executável
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
script/build
|
||||
script/grunt mkrpm publish-build --stack
|
||||
@@ -6,7 +6,7 @@ ThemeManager = require '../src/theme-manager'
|
||||
|
||||
describe "the `atom` global", ->
|
||||
beforeEach ->
|
||||
atom.workspaceView = atom.workspace.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
|
||||
|
||||
describe 'window sizing methods', ->
|
||||
describe '::getPosition and ::setPosition', ->
|
||||
|
||||
@@ -14,9 +14,12 @@ describe "CommandRegistry", ->
|
||||
parent.appendChild(child)
|
||||
document.querySelector('#jasmine-content').appendChild(parent)
|
||||
|
||||
registry = new CommandRegistry(parent)
|
||||
registry = new CommandRegistry
|
||||
|
||||
describe "command dispatch", ->
|
||||
afterEach ->
|
||||
registry.destroy()
|
||||
|
||||
describe "when a command event is dispatched on an element", ->
|
||||
it "invokes callbacks with selectors matching the target", ->
|
||||
called = false
|
||||
registry.add '.grandchild', 'command', (event) ->
|
||||
@@ -48,6 +51,16 @@ describe "CommandRegistry", ->
|
||||
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
|
||||
expect(calls).toEqual ['child', 'parent']
|
||||
|
||||
it "invokes inline listeners prior to listeners applied via selectors", ->
|
||||
calls = []
|
||||
registry.add '.grandchild', 'command', -> calls.push('grandchild')
|
||||
registry.add child, 'command', -> calls.push('child-inline')
|
||||
registry.add '.child', 'command', -> calls.push('child')
|
||||
registry.add '.parent', 'command', -> calls.push('parent')
|
||||
|
||||
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
|
||||
expect(calls).toEqual ['grandchild', 'child-inline', 'child', 'parent']
|
||||
|
||||
it "orders multiple matching listeners for an element by selector specificity", ->
|
||||
child.classList.add('foo', 'bar')
|
||||
calls = []
|
||||
@@ -86,8 +99,6 @@ describe "CommandRegistry", ->
|
||||
expect(dispatchedEvent.stopImmediatePropagation).toHaveBeenCalled()
|
||||
|
||||
it "forwards .preventDefault() calls from the synthetic event to the original", ->
|
||||
calls = []
|
||||
|
||||
registry.add '.child', 'command', (event) -> event.preventDefault()
|
||||
|
||||
dispatchedEvent = new CustomEvent('command', bubbles: true)
|
||||
@@ -95,6 +106,14 @@ describe "CommandRegistry", ->
|
||||
grandchild.dispatchEvent(dispatchedEvent)
|
||||
expect(dispatchedEvent.preventDefault).toHaveBeenCalled()
|
||||
|
||||
it "forwards .abortKeyBinding() calls from the synthetic event to the original", ->
|
||||
registry.add '.child', 'command', (event) -> event.abortKeyBinding()
|
||||
|
||||
dispatchedEvent = new CustomEvent('command', bubbles: true)
|
||||
dispatchedEvent.abortKeyBinding = jasmine.createSpy('abortKeyBinding')
|
||||
grandchild.dispatchEvent(dispatchedEvent)
|
||||
expect(dispatchedEvent.abortKeyBinding).toHaveBeenCalled()
|
||||
|
||||
it "allows listeners to be removed via a disposable returned by ::add", ->
|
||||
calls = []
|
||||
|
||||
|
||||
+211
-16
@@ -88,6 +88,19 @@ describe "Config", ->
|
||||
expect(atom.config.getDefault('foo.bar')).toEqual initialDefaultValue
|
||||
expect(atom.config.getDefault('foo.bar')).not.toBe initialDefaultValue
|
||||
|
||||
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", ->
|
||||
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)
|
||||
expect(atom.config.getDefault('.source.coffee', 'foo.bar.baz')).toBe 42
|
||||
|
||||
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)
|
||||
@@ -99,6 +112,21 @@ describe "Config", ->
|
||||
expect(atom.config.isDefault('foo.same')).toBe false
|
||||
expect(atom.config.isDefault('foo.changes')).toBe false
|
||||
|
||||
describe "when scoped settings are used", ->
|
||||
it "returns false when a scoped setting was set by the user", ->
|
||||
expect(atom.config.isDefault('.source.coffee', 'foo.bar.baz')).toBe true
|
||||
|
||||
atom.config.addScopedSettings("default", ".source.coffee", foo: bar: baz: 42)
|
||||
expect(atom.config.isDefault('.source.coffee', 'foo.bar.baz')).toBe true
|
||||
|
||||
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
|
||||
expect(atom.config.isDefault('.source.coffee', 'foo.bar.baz')).toBe false
|
||||
|
||||
describe ".setDefaults(keyPath)", ->
|
||||
it "sets a default when the setting's key contains an escaped dot", ->
|
||||
atom.config.setDefaults("foo", 'a\\.b': 1, b: 2)
|
||||
expect(atom.config.get("foo")).toEqual 'a\\.b': 1, b: 2
|
||||
|
||||
describe ".toggle(keyPath)", ->
|
||||
it "negates the boolean value of the current key path value", ->
|
||||
atom.config.set('foo.a', 1)
|
||||
@@ -130,6 +158,66 @@ describe "Config", ->
|
||||
atom.config.restoreDefault('a.c')
|
||||
expect(atom.config.get('a.c')).toBeUndefined()
|
||||
|
||||
it "calls ::save()", ->
|
||||
atom.config.setDefaults('a', b: 3)
|
||||
atom.config.set('a.b', 4)
|
||||
atom.config.save.reset()
|
||||
|
||||
atom.config.restoreDefault('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.restoreDefault('.source.coffee', 'foo.bar.baz')
|
||||
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).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.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
|
||||
|
||||
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.save.reset()
|
||||
|
||||
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
|
||||
expect(atom.config.save.callCount).toBe 1
|
||||
|
||||
describe ".getSettings()", ->
|
||||
it "returns all settings including defaults", ->
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
atom.config.set("foo.ok", 12)
|
||||
|
||||
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'
|
||||
|
||||
describe ".pushAtKeyPath(keyPath, value)", ->
|
||||
it "pushes the given value to the array at the key path and updates observers", ->
|
||||
atom.config.set("foo.bar.baz", ["a"])
|
||||
@@ -200,7 +288,7 @@ describe "Config", ->
|
||||
|
||||
expect(CSON.writeFileSync.argsForCall[0][0]).toBe(path.join(atom.config.configDirPath, "atom.config.json"))
|
||||
writtenConfig = CSON.writeFileSync.argsForCall[0][1]
|
||||
expect(writtenConfig).toBe atom.config.settings
|
||||
expect(writtenConfig).toEqual global: atom.config.settings
|
||||
|
||||
describe "when ~/.atom/config.json doesn't exist", ->
|
||||
it "writes any non-default properties to ~/.atom/config.cson", ->
|
||||
@@ -214,9 +302,29 @@ describe "Config", ->
|
||||
atom.config.save()
|
||||
|
||||
expect(CSON.writeFileSync.argsForCall[0][0]).toBe(path.join(atom.config.configDirPath, "atom.config.cson"))
|
||||
CoffeeScript = require 'coffee-script'
|
||||
writtenConfig = CSON.writeFileSync.argsForCall[0][1]
|
||||
expect(writtenConfig).toEqual atom.config.settings
|
||||
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'
|
||||
|
||||
describe ".setDefaults(keyPath, defaults)", ->
|
||||
it "assigns any previously-unassigned keys to the object at the key path", ->
|
||||
@@ -320,6 +428,14 @@ describe "Config", ->
|
||||
atom.config.set('foo.bar.baz', "value 2")
|
||||
expect(observeHandler).not.toHaveBeenCalled()
|
||||
|
||||
it 'does not fire the callback for a similarly named keyPath', ->
|
||||
bazCatHandler = jasmine.createSpy("bazCatHandler")
|
||||
observeSubscription = atom.config.observe "foo.bar.bazCat", bazCatHandler
|
||||
|
||||
bazCatHandler.reset()
|
||||
atom.config.set('foo.bar.baz', "value 10")
|
||||
expect(bazCatHandler).not.toHaveBeenCalled()
|
||||
|
||||
describe ".initializeConfigDirectory()", ->
|
||||
beforeEach ->
|
||||
if fs.existsSync(dotAtomPath)
|
||||
@@ -356,6 +472,23 @@ describe "Config", ->
|
||||
afterEach ->
|
||||
fs.removeSync(dotAtomPath)
|
||||
|
||||
describe "when the config file contains scoped settings", ->
|
||||
beforeEach ->
|
||||
fs.writeFileSync atom.config.configFilePath, """
|
||||
global:
|
||||
foo:
|
||||
bar: 'baz'
|
||||
|
||||
'.source.ruby':
|
||||
foo:
|
||||
bar: 'more-specific'
|
||||
"""
|
||||
atom.config.loadUserConfig()
|
||||
|
||||
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'
|
||||
|
||||
describe "when the config file contains valid cson", ->
|
||||
beforeEach ->
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: bar: 'baz'")
|
||||
@@ -430,7 +563,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()
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: bar: 'baz'")
|
||||
fs.writeFileSync atom.config.configFilePath, """
|
||||
global:
|
||||
foo:
|
||||
bar: 'baz'
|
||||
scoped: false
|
||||
'.source.ruby':
|
||||
foo:
|
||||
scoped: true
|
||||
"""
|
||||
atom.config.loadUserConfig()
|
||||
atom.config.observeUserConfig()
|
||||
updatedHandler = jasmine.createSpy("updatedHandler")
|
||||
@@ -474,6 +615,38 @@ describe "Config", ->
|
||||
expect(atom.config.get('foo.bar')).toEqual ['baz', 'ok']
|
||||
expect(atom.config.get('foo.omg')).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()
|
||||
|
||||
fs.writeFileSync atom.config.configFilePath, """
|
||||
global:
|
||||
foo:
|
||||
scoped: false
|
||||
"""
|
||||
waitsFor 'update event', -> updatedHandler.callCount > 0
|
||||
runs ->
|
||||
expect(scopedSpy).toHaveBeenCalled()
|
||||
expect(atom.config.get(['.source.ruby'], 'foo.scoped')).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()
|
||||
|
||||
fs.writeFileSync atom.config.configFilePath, """
|
||||
global:
|
||||
foo:
|
||||
bar: 'baz'
|
||||
'.source.ruby':
|
||||
foo:
|
||||
scoped: true
|
||||
"""
|
||||
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
|
||||
|
||||
|
||||
describe "when the config file changes to omit a setting with a default", ->
|
||||
it "resets the setting back to the default", ->
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: { baz: 'new'}")
|
||||
@@ -863,12 +1036,27 @@ describe "Config", ->
|
||||
expect(atom.config.set('foo.bar.arr', ['two', 'three'])).toBe true
|
||||
expect(atom.config.get('foo.bar.arr')).toEqual ['two', 'three']
|
||||
|
||||
describe "when scoped settings are used", ->
|
||||
beforeEach ->
|
||||
schema =
|
||||
type: 'string'
|
||||
default: 'ok'
|
||||
scopes:
|
||||
'.source.js':
|
||||
default: 'omg'
|
||||
atom.config.setSchema('foo.bar.str', schema)
|
||||
|
||||
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'
|
||||
|
||||
describe "scoped settings", ->
|
||||
describe ".get(scopeDescriptor, keyPath)", ->
|
||||
it "returns the property with the most specific scope selector", ->
|
||||
atom.config.addScopedSettings(".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
atom.config.addScopedSettings(".source .string.quoted.double", foo: bar: baz: 22)
|
||||
atom.config.addScopedSettings(".source", foo: bar: baz: 11)
|
||||
atom.config.addScopedSettings("config", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
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
|
||||
@@ -876,8 +1064,8 @@ describe "Config", ->
|
||||
expect(atom.config.get([".text"], "foo.bar.baz")).toBeUndefined()
|
||||
|
||||
it "favors the most recently added properties in the event of a specificity tie", ->
|
||||
atom.config.addScopedSettings(".source.coffee .string.quoted.single", foo: bar: baz: 42)
|
||||
atom.config.addScopedSettings(".source.coffee .string.quoted.double", foo: bar: baz: 22)
|
||||
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
|
||||
@@ -887,11 +1075,18 @@ describe "Config", ->
|
||||
atom.config.setDefaults("foo", hasDefault: 'ok')
|
||||
expect(atom.config.get([".source.coffee", ".string.quoted.single"], "foo.hasDefault")).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.addScopedSettings("some-package", ".source.coffee", foo: bar: baz: 1)
|
||||
expect(atom.config.get([".source.coffee"], "foo.bar.baz")).toBe 100
|
||||
|
||||
describe ".set(scope, keyPath, value)", ->
|
||||
it "sets the value and overrides the others", ->
|
||||
atom.config.addScopedSettings(".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
atom.config.addScopedSettings(".source .string.quoted.double", foo: bar: baz: 22)
|
||||
atom.config.addScopedSettings(".source", foo: bar: baz: 11)
|
||||
atom.config.addScopedSettings("config", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
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
|
||||
|
||||
@@ -917,11 +1112,11 @@ describe "Config", ->
|
||||
expect(changeSpy).toHaveBeenCalledWith(12)
|
||||
changeSpy.reset()
|
||||
|
||||
disposable1 = atom.config.addScopedSettings(".source .string.quoted.double", foo: bar: baz: 22)
|
||||
disposable1 = atom.config.addScopedSettings("a", ".source .string.quoted.double", foo: bar: baz: 22)
|
||||
expect(changeSpy).toHaveBeenCalledWith(22)
|
||||
changeSpy.reset()
|
||||
|
||||
disposable2 = atom.config.addScopedSettings("a", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
disposable2 = atom.config.addScopedSettings("b", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
expect(changeSpy).toHaveBeenCalledWith(42)
|
||||
changeSpy.reset()
|
||||
|
||||
@@ -946,11 +1141,11 @@ describe "Config", ->
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: undefined, newValue: 12, keyPath})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable1 = atom.config.addScopedSettings(".source .string.quoted.double", foo: bar: baz: 22)
|
||||
disposable1 = atom.config.addScopedSettings("a", ".source .string.quoted.double", foo: bar: baz: 22)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: 22, keyPath})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable2 = atom.config.addScopedSettings("a", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
disposable2 = atom.config.addScopedSettings("b", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 42, keyPath})
|
||||
changeSpy.reset()
|
||||
|
||||
|
||||
@@ -56,6 +56,11 @@ describe "DisplayBuffer", ->
|
||||
buffer.delete([[8, 0], [10, 0]])
|
||||
expect(displayBuffer.getScrollTop()).toBe 60
|
||||
|
||||
it "updates the display buffer prior to invoking change handlers registered on the buffer", ->
|
||||
buffer.onDidChange -> expect(displayBuffer2.tokenizedLineForScreenRow(0).text).toBe "testing"
|
||||
displayBuffer2 = new DisplayBuffer({buffer, tabLength})
|
||||
buffer.setText("testing")
|
||||
|
||||
describe "soft wrapping", ->
|
||||
beforeEach ->
|
||||
displayBuffer.setSoftWrapped(true)
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"foo": "bar"
|
||||
}
|
||||
@@ -6,7 +6,7 @@ module.exports =
|
||||
activate: ->
|
||||
@activateCallCount++
|
||||
|
||||
atom.commands.add '.workspace', 'activation-command', =>
|
||||
atom.commands.add 'atom-workspace', 'activation-command', =>
|
||||
@activationCommandCallCount++
|
||||
|
||||
atom.workspaceView.getActiveView()?.command 'activation-command', =>
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "no events",
|
||||
"version": "0.1.0",
|
||||
"activationCommands": {".workspace": []}
|
||||
"activationCommands": {"atom-workspace": []}
|
||||
}
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
a { color: red }
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
@import "ui-variables";
|
||||
|
||||
.editor {
|
||||
atom-text-editor {
|
||||
padding-top: @component-padding;
|
||||
padding-right: @component-padding;
|
||||
padding-bottom: @component-padding;
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
.editor {
|
||||
atom-text-editor {
|
||||
padding-top: 1234px;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@padding: 4321px;
|
||||
|
||||
.editor {
|
||||
atom-text-editor {
|
||||
padding-top: @padding;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.editor {
|
||||
atom-text-editor {
|
||||
padding-top: 101px;
|
||||
padding-right: 101px;
|
||||
padding-bottom: 101px;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.editor {
|
||||
atom-text-editor {
|
||||
/* padding-top: 103px;
|
||||
padding-right: 103px;*/
|
||||
padding-bottom: 103px;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@number: 102px;
|
||||
|
||||
.editor {
|
||||
atom-text-editor {
|
||||
/* padding-top: 102px;*/
|
||||
padding-right: @number;
|
||||
padding-bottom: @number;
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"theme": "syntax",
|
||||
"stylesheets": ["editor.less"]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
@import "ui-variables";
|
||||
|
||||
.editor {
|
||||
atom-text-editor {
|
||||
padding-top: @component-padding;
|
||||
padding-right: @component-padding;
|
||||
padding-bottom: @component-padding;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.editor {
|
||||
atom-text-editor {
|
||||
padding-top: 10px;
|
||||
padding-right: 10px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.editor {
|
||||
atom-text-editor {
|
||||
padding-right: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@number: 30px;
|
||||
|
||||
.editor {
|
||||
atom-text-editor {
|
||||
padding-bottom: @number;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.editor {
|
||||
atom-text-editor {
|
||||
padding-top: 100px;
|
||||
padding-right: 100px;
|
||||
padding-bottom: 100px;
|
||||
|
||||
|
@@ -0,0 +1,92 @@
|
||||
path = require 'path'
|
||||
Module = require 'module'
|
||||
fs = require 'fs-plus'
|
||||
temp = require 'temp'
|
||||
ModuleCache = require '../src/module-cache'
|
||||
|
||||
describe 'ModuleCache', ->
|
||||
beforeEach ->
|
||||
spyOn(Module, '_findPath').andCallThrough()
|
||||
|
||||
it 'resolves atom shell module paths without hitting the filesystem', ->
|
||||
builtins = ModuleCache.cache.builtins
|
||||
expect(Object.keys(builtins).length).toBeGreaterThan 0
|
||||
|
||||
for builtinName, builtinPath of builtins
|
||||
expect(require.resolve(builtinName)).toBe builtinPath
|
||||
expect(fs.isFileSync(require.resolve(builtinName)))
|
||||
|
||||
expect(Module._findPath.callCount).toBe 0
|
||||
|
||||
it 'resolves relative core paths without hitting the filesystem', ->
|
||||
ModuleCache.add atom.getLoadSettings().resourcePath, {
|
||||
_atomModuleCache:
|
||||
extensions:
|
||||
'.json': [
|
||||
path.join('spec', 'fixtures', 'module-cache', 'file.json')
|
||||
]
|
||||
}
|
||||
expect(require('./fixtures/module-cache/file.json').foo).toBe 'bar'
|
||||
expect(Module._findPath.callCount).toBe 0
|
||||
|
||||
it 'resolves module paths when a compatible version is provided by core', ->
|
||||
packagePath = fs.realpathSync(temp.mkdirSync('atom-package'))
|
||||
ModuleCache.add packagePath, {
|
||||
_atomModuleCache:
|
||||
folders: [{
|
||||
paths: [
|
||||
''
|
||||
]
|
||||
dependencies:
|
||||
'underscore-plus': '*'
|
||||
}]
|
||||
}
|
||||
ModuleCache.add atom.getLoadSettings().resourcePath, {
|
||||
_atomModuleCache:
|
||||
dependencies: [{
|
||||
name: 'underscore-plus'
|
||||
version: require('underscore-plus/package.json').version
|
||||
path: path.join('node_modules', 'underscore-plus', 'lib', 'underscore-plus.js')
|
||||
}]
|
||||
}
|
||||
|
||||
indexPath = path.join(packagePath, 'index.js')
|
||||
fs.writeFileSync indexPath, """
|
||||
exports.load = function() { require('underscore-plus'); };
|
||||
"""
|
||||
|
||||
packageMain = require(indexPath)
|
||||
Module._findPath.reset()
|
||||
packageMain.load()
|
||||
expect(Module._findPath.callCount).toBe 0
|
||||
|
||||
it 'does not resolve module paths when no compatible version is provided by core', ->
|
||||
packagePath = fs.realpathSync(temp.mkdirSync('atom-package'))
|
||||
ModuleCache.add packagePath, {
|
||||
_atomModuleCache:
|
||||
folders: [{
|
||||
paths: [
|
||||
''
|
||||
]
|
||||
dependencies:
|
||||
'underscore-plus': '0.0.1'
|
||||
}]
|
||||
}
|
||||
ModuleCache.add atom.getLoadSettings().resourcePath, {
|
||||
_atomModuleCache:
|
||||
dependencies: [{
|
||||
name: 'underscore-plus'
|
||||
version: require('underscore-plus/package.json').version
|
||||
path: path.join('node_modules', 'underscore-plus', 'lib', 'underscore-plus.js')
|
||||
}]
|
||||
}
|
||||
|
||||
indexPath = path.join(packagePath, 'index.js')
|
||||
fs.writeFileSync indexPath, """
|
||||
exports.load = function() { require('underscore-plus'); };
|
||||
"""
|
||||
|
||||
packageMain = require(indexPath)
|
||||
Module._findPath.reset()
|
||||
expect(-> packageMain.load()).toThrow()
|
||||
expect(Module._findPath.callCount).toBe 1
|
||||
@@ -3,7 +3,7 @@ Package = require '../src/package'
|
||||
|
||||
describe "PackageManager", ->
|
||||
beforeEach ->
|
||||
atom.workspaceView = atom.workspace.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
|
||||
|
||||
describe "::loadPackage(name)", ->
|
||||
it "continues if the package has an invalid package.json", ->
|
||||
@@ -48,9 +48,10 @@ describe "PackageManager", ->
|
||||
describe "when called multiple times", ->
|
||||
it "it only calls activate on the package once", ->
|
||||
spyOn(Package.prototype, 'activateNow').andCallThrough()
|
||||
atom.packages.activatePackage('package-with-index')
|
||||
atom.packages.activatePackage('package-with-index')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-index')
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-index')
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-index')
|
||||
|
||||
@@ -138,7 +139,7 @@ describe "PackageManager", ->
|
||||
legacyCommandListener = jasmine.createSpy("legacyCommandListener")
|
||||
editorView.command 'activation-command', legacyCommandListener
|
||||
editorCommandListener = jasmine.createSpy("editorCommandListener")
|
||||
atom.commands.add '.editor', 'activation-command', editorCommandListener
|
||||
atom.commands.add 'atom-text-editor', 'activation-command', editorCommandListener
|
||||
editorView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
|
||||
expect(mainModule.activate.callCount).toBe 1
|
||||
expect(mainModule.legacyActivationCommandCallCount).toBe 1
|
||||
@@ -182,8 +183,10 @@ describe "PackageManager", ->
|
||||
pack.mainModule.someNumber = 77
|
||||
atom.packages.deactivatePackage("package-with-serialization")
|
||||
spyOn(pack.mainModule, 'activate').andCallThrough()
|
||||
atom.packages.activatePackage("package-with-serialization")
|
||||
expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77})
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-serialization")
|
||||
runs ->
|
||||
expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77})
|
||||
|
||||
it "logs warning instead of throwing an exception if the package fails to load", ->
|
||||
atom.config.set("core.disabledPackages", [])
|
||||
@@ -202,11 +205,13 @@ describe "PackageManager", ->
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])).toHaveLength 0
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
|
||||
|
||||
atom.packages.activatePackage("package-with-keymaps")
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-keymaps")
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe "test-1"
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])[0].command).toBe "test-2"
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
|
||||
runs ->
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe "test-1"
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])[0].command).toBe "test-2"
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
|
||||
|
||||
describe "when the metadata contains a 'keymaps' manifest", ->
|
||||
it "loads only the keymaps specified by the manifest, in the specified order", ->
|
||||
@@ -215,11 +220,13 @@ describe "PackageManager", ->
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])).toHaveLength 0
|
||||
|
||||
atom.packages.activatePackage("package-with-keymaps-manifest")
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-keymaps-manifest")
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe 'keymap-1'
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-n', target:element1[0])[0].command).toBe 'keymap-2'
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-y', target:element3[0])).toHaveLength 0
|
||||
runs ->
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe 'keymap-1'
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-n', target:element1[0])[0].command).toBe 'keymap-2'
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-y', target:element3[0])).toHaveLength 0
|
||||
|
||||
describe "menu loading", ->
|
||||
beforeEach ->
|
||||
@@ -232,14 +239,16 @@ describe "PackageManager", ->
|
||||
|
||||
expect(atom.contextMenu.templateForElement(element)).toEqual []
|
||||
|
||||
atom.packages.activatePackage("package-with-menus")
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-menus")
|
||||
|
||||
expect(atom.menu.template.length).toBe 2
|
||||
expect(atom.menu.template[0].label).toBe "Second to Last"
|
||||
expect(atom.menu.template[1].label).toBe "Last"
|
||||
expect(atom.contextMenu.templateForElement(element)[0].label).toBe "Menu item 1"
|
||||
expect(atom.contextMenu.templateForElement(element)[1].label).toBe "Menu item 2"
|
||||
expect(atom.contextMenu.templateForElement(element)[2].label).toBe "Menu item 3"
|
||||
runs ->
|
||||
expect(atom.menu.template.length).toBe 2
|
||||
expect(atom.menu.template[0].label).toBe "Second to Last"
|
||||
expect(atom.menu.template[1].label).toBe "Last"
|
||||
expect(atom.contextMenu.templateForElement(element)[0].label).toBe "Menu item 1"
|
||||
expect(atom.contextMenu.templateForElement(element)[1].label).toBe "Menu item 2"
|
||||
expect(atom.contextMenu.templateForElement(element)[2].label).toBe "Menu item 3"
|
||||
|
||||
describe "when the metadata contains a 'menus' manifest", ->
|
||||
it "loads only the menus specified by the manifest, in the specified order", ->
|
||||
@@ -247,13 +256,15 @@ describe "PackageManager", ->
|
||||
|
||||
expect(atom.contextMenu.templateForElement(element)).toEqual []
|
||||
|
||||
atom.packages.activatePackage("package-with-menus-manifest")
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-menus-manifest")
|
||||
|
||||
expect(atom.menu.template[0].label).toBe "Second to Last"
|
||||
expect(atom.menu.template[1].label).toBe "Last"
|
||||
expect(atom.contextMenu.templateForElement(element)[0].label).toBe "Menu item 2"
|
||||
expect(atom.contextMenu.templateForElement(element)[1].label).toBe "Menu item 1"
|
||||
expect(atom.contextMenu.templateForElement(element)[2]).toBeUndefined()
|
||||
runs ->
|
||||
expect(atom.menu.template[0].label).toBe "Second to Last"
|
||||
expect(atom.menu.template[1].label).toBe "Last"
|
||||
expect(atom.contextMenu.templateForElement(element)[0].label).toBe "Menu item 2"
|
||||
expect(atom.contextMenu.templateForElement(element)[1].label).toBe "Menu item 1"
|
||||
expect(atom.contextMenu.templateForElement(element)[2]).toBeUndefined()
|
||||
|
||||
describe "stylesheet loading", ->
|
||||
describe "when the metadata contains a 'stylesheets' manifest", ->
|
||||
@@ -270,12 +281,14 @@ describe "PackageManager", ->
|
||||
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
|
||||
atom.packages.activatePackage("package-with-stylesheets-manifest")
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-stylesheets-manifest")
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
expect($('#jasmine-content').css('font-size')).toBe '1px'
|
||||
runs ->
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
expect($('#jasmine-content').css('font-size')).toBe '1px'
|
||||
|
||||
describe "when the metadata does not contain a 'stylesheets' manifest", ->
|
||||
it "loads all stylesheets from the stylesheets directory", ->
|
||||
@@ -292,11 +305,22 @@ describe "PackageManager", ->
|
||||
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-stylesheets")
|
||||
|
||||
runs ->
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toBeNull()
|
||||
expect($('#jasmine-content').css('font-size')).toBe '3px'
|
||||
|
||||
it "assigns the stylesheet's context based on the filename", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-stylesheets")
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toBeNull()
|
||||
expect($('#jasmine-content').css('font-size')).toBe '3px'
|
||||
|
||||
runs ->
|
||||
element = atom.styles.getStyleElements().find (element) -> element.context is 'test-context'
|
||||
expect(element).toBeDefined()
|
||||
|
||||
describe "grammar loading", ->
|
||||
it "loads the package's grammars", ->
|
||||
|
||||
+18
-18
@@ -38,51 +38,51 @@ describe "Package", ->
|
||||
theme = null
|
||||
|
||||
beforeEach ->
|
||||
$("#jasmine-content").append $("<div class='editor'></div>")
|
||||
$("#jasmine-content").append $("<atom-text-editor></atom-text-editor>")
|
||||
|
||||
afterEach ->
|
||||
theme.deactivate() if theme?
|
||||
|
||||
describe "when the theme contains a single style file", ->
|
||||
it "loads and applies css", ->
|
||||
expect($(".editor").css("padding-bottom")).not.toBe "1234px"
|
||||
expect($("atom-text-editor").css("padding-bottom")).not.toBe "1234px"
|
||||
themePath = atom.project.resolve('packages/theme-with-index-css')
|
||||
theme = new ThemePackage(themePath)
|
||||
theme.activate()
|
||||
expect($(".editor").css("padding-top")).toBe "1234px"
|
||||
expect($("atom-text-editor").css("padding-top")).toBe "1234px"
|
||||
|
||||
it "parses, loads and applies less", ->
|
||||
expect($(".editor").css("padding-bottom")).not.toBe "1234px"
|
||||
expect($("atom-text-editor").css("padding-bottom")).not.toBe "1234px"
|
||||
themePath = atom.project.resolve('packages/theme-with-index-less')
|
||||
theme = new ThemePackage(themePath)
|
||||
theme.activate()
|
||||
expect($(".editor").css("padding-top")).toBe "4321px"
|
||||
expect($("atom-text-editor").css("padding-top")).toBe "4321px"
|
||||
|
||||
describe "when the theme contains a package.json file", ->
|
||||
it "loads and applies stylesheets from package.json in the correct order", ->
|
||||
expect($(".editor").css("padding-top")).not.toBe("101px")
|
||||
expect($(".editor").css("padding-right")).not.toBe("102px")
|
||||
expect($(".editor").css("padding-bottom")).not.toBe("103px")
|
||||
expect($("atom-text-editor").css("padding-top")).not.toBe("101px")
|
||||
expect($("atom-text-editor").css("padding-right")).not.toBe("102px")
|
||||
expect($("atom-text-editor").css("padding-bottom")).not.toBe("103px")
|
||||
|
||||
themePath = atom.project.resolve('packages/theme-with-package-file')
|
||||
theme = new ThemePackage(themePath)
|
||||
theme.activate()
|
||||
expect($(".editor").css("padding-top")).toBe("101px")
|
||||
expect($(".editor").css("padding-right")).toBe("102px")
|
||||
expect($(".editor").css("padding-bottom")).toBe("103px")
|
||||
expect($("atom-text-editor").css("padding-top")).toBe("101px")
|
||||
expect($("atom-text-editor").css("padding-right")).toBe("102px")
|
||||
expect($("atom-text-editor").css("padding-bottom")).toBe("103px")
|
||||
|
||||
describe "when the theme does not contain a package.json file and is a directory", ->
|
||||
it "loads all stylesheet files in the directory", ->
|
||||
expect($(".editor").css("padding-top")).not.toBe "10px"
|
||||
expect($(".editor").css("padding-right")).not.toBe "20px"
|
||||
expect($(".editor").css("padding-bottom")).not.toBe "30px"
|
||||
expect($("atom-text-editor").css("padding-top")).not.toBe "10px"
|
||||
expect($("atom-text-editor").css("padding-right")).not.toBe "20px"
|
||||
expect($("atom-text-editor").css("padding-bottom")).not.toBe "30px"
|
||||
|
||||
themePath = atom.project.resolve('packages/theme-without-package-file')
|
||||
theme = new ThemePackage(themePath)
|
||||
theme.activate()
|
||||
expect($(".editor").css("padding-top")).toBe "10px"
|
||||
expect($(".editor").css("padding-right")).toBe "20px"
|
||||
expect($(".editor").css("padding-bottom")).toBe "30px"
|
||||
expect($("atom-text-editor").css("padding-top")).toBe "10px"
|
||||
expect($("atom-text-editor").css("padding-right")).toBe "20px"
|
||||
expect($("atom-text-editor").css("padding-bottom")).toBe "30px"
|
||||
|
||||
describe "reloading a theme", ->
|
||||
beforeEach ->
|
||||
@@ -92,7 +92,7 @@ describe "Package", ->
|
||||
|
||||
it "reloads without readding to the stylesheets list", ->
|
||||
expect(theme.getStylesheetPaths().length).toBe 3
|
||||
theme.reloadStylesheet(theme.getStylesheetPaths()[0])
|
||||
theme.reloadStylesheets()
|
||||
expect(theme.getStylesheetPaths().length).toBe 3
|
||||
|
||||
describe "events", ->
|
||||
|
||||
@@ -19,7 +19,7 @@ describe "PaneContainerView", ->
|
||||
save: -> @saved = true
|
||||
isEqual: (other) -> @name is other?.name
|
||||
|
||||
container = atom.workspace.getView(atom.workspace.paneContainer).__spacePenView
|
||||
container = atom.views.getView(atom.workspace.paneContainer).__spacePenView
|
||||
pane1 = container.getRoot()
|
||||
pane1.activateItem(new TestView('1'))
|
||||
pane2 = pane1.splitRight(new TestView('2'))
|
||||
@@ -73,14 +73,14 @@ describe "PaneContainerView", ->
|
||||
|
||||
describe "serialization", ->
|
||||
it "can be serialized and deserialized, and correctly adjusts dimensions of deserialized panes after attach", ->
|
||||
newContainer = atom.workspace.getView(container.model.testSerialization()).__spacePenView
|
||||
expect(newContainer.find('.pane-row > :contains(1)')).toExist()
|
||||
expect(newContainer.find('.pane-row > .pane-column > :contains(2)')).toExist()
|
||||
expect(newContainer.find('.pane-row > .pane-column > :contains(3)')).toExist()
|
||||
newContainer = atom.views.getView(container.model.testSerialization()).__spacePenView
|
||||
expect(newContainer.find('atom-pane-axis.horizontal > :contains(1)')).toExist()
|
||||
expect(newContainer.find('atom-pane-axis.horizontal > atom-pane-axis.vertical > :contains(2)')).toExist()
|
||||
expect(newContainer.find('atom-pane-axis.horizontal > atom-pane-axis.vertical > :contains(3)')).toExist()
|
||||
|
||||
newContainer.height(200).width(300).attachToDom()
|
||||
expect(newContainer.find('.pane-row > :contains(1)').width()).toBe 150
|
||||
expect(newContainer.find('.pane-row > .pane-column > :contains(2)').height()).toBe 100
|
||||
expect(newContainer.find('atom-pane-axis.horizontal > :contains(1)').width()).toBe 150
|
||||
expect(newContainer.find('atom-pane-axis.horizontal > atom-pane-axis.vertical > :contains(2)').height()).toBe 100
|
||||
|
||||
describe "if there are empty panes after deserialization", ->
|
||||
beforeEach ->
|
||||
@@ -89,15 +89,15 @@ describe "PaneContainerView", ->
|
||||
|
||||
describe "if the 'core.destroyEmptyPanes' config option is false (the default)", ->
|
||||
it "leaves the empty panes intact", ->
|
||||
newContainer = atom.workspace.getView(container.model.testSerialization()).__spacePenView
|
||||
expect(newContainer.find('.pane-row > :contains(1)')).toExist()
|
||||
expect(newContainer.find('.pane-row > .pane-column > .pane').length).toBe 2
|
||||
newContainer = atom.views.getView(container.model.testSerialization()).__spacePenView
|
||||
expect(newContainer.find('atom-pane-axis.horizontal > :contains(1)')).toExist()
|
||||
expect(newContainer.find('atom-pane-axis.horizontal > atom-pane-axis.vertical > atom-pane').length).toBe 2
|
||||
|
||||
describe "if the 'core.destroyEmptyPanes' config option is true", ->
|
||||
it "removes empty panes on deserialization", ->
|
||||
atom.config.set('core.destroyEmptyPanes', true)
|
||||
newContainer = atom.workspace.getView(container.model.testSerialization()).__spacePenView
|
||||
expect(newContainer.find('.pane-row, .pane-column')).not.toExist()
|
||||
newContainer = atom.views.getView(container.model.testSerialization()).__spacePenView
|
||||
expect(newContainer.find('atom-pane-axis.horizontal, atom-pane-axis.vertical')).not.toExist()
|
||||
expect(newContainer.find('> :contains(1)')).toExist()
|
||||
|
||||
describe "pane-container:active-pane-item-changed", ->
|
||||
@@ -109,7 +109,7 @@ describe "PaneContainerView", ->
|
||||
item2b = new TestView('2b')
|
||||
item3a = new TestView('3a')
|
||||
|
||||
container = atom.workspace.getView(new PaneContainer).__spacePenView
|
||||
container = atom.views.getView(new PaneContainer).__spacePenView
|
||||
pane1 = container.getRoot()
|
||||
pane1.activateItem(item1a)
|
||||
container.attachToDom()
|
||||
@@ -259,7 +259,7 @@ describe "PaneContainerView", ->
|
||||
# |7|8|9|
|
||||
# -------
|
||||
|
||||
container = atom.workspace.getView(new PaneContainer).__spacePenView
|
||||
container = atom.views.getView(new PaneContainer).__spacePenView
|
||||
pane1 = container.getRoot()
|
||||
pane1.activateItem(new TestView('1'))
|
||||
pane4 = pane1.splitDown(new TestView('4'))
|
||||
|
||||
@@ -24,7 +24,7 @@ describe "PaneView", ->
|
||||
|
||||
beforeEach ->
|
||||
deserializerDisposable = atom.deserializers.add(TestView)
|
||||
container = atom.workspace.getView(new PaneContainer).__spacePenView
|
||||
container = atom.views.getView(new PaneContainer).__spacePenView
|
||||
containerModel = container.model
|
||||
view1 = new TestView(id: 'view-1', text: 'View 1')
|
||||
view2 = new TestView(id: 'view-2', text: 'View 2')
|
||||
@@ -131,9 +131,9 @@ describe "PaneView", ->
|
||||
describe "when the destroyed item is a model", ->
|
||||
it "removes the associated view", ->
|
||||
paneModel.activateItem(editor1)
|
||||
expect(pane.itemViews.find('.editor').length).toBe 1
|
||||
expect(pane.itemViews.find('atom-text-editor').length).toBe 1
|
||||
pane.destroyItem(editor1)
|
||||
expect(pane.itemViews.find('.editor').length).toBe 0
|
||||
expect(pane.itemViews.find('atom-text-editor').length).toBe 0
|
||||
|
||||
describe "when an item is moved within the same pane", ->
|
||||
it "emits a 'pane:item-moved' event with the item and the new index", ->
|
||||
@@ -289,7 +289,7 @@ describe "PaneView", ->
|
||||
expect(paneModel.isActive()).toBe true
|
||||
|
||||
describe "when a pane is split", ->
|
||||
it "builds the appropriate pane-row and pane-column views", ->
|
||||
it "builds the appropriateatom-pane-axis.horizontal and pane-column views", ->
|
||||
pane1 = pane
|
||||
pane1Model = pane.getModel()
|
||||
pane.activateItem(editor1)
|
||||
@@ -300,24 +300,24 @@ describe "PaneView", ->
|
||||
pane2 = containerModel.getView(pane2Model).__spacePenView
|
||||
pane3 = containerModel.getView(pane3Model).__spacePenView
|
||||
|
||||
expect(container.find('> .pane-row > .pane').toArray()).toEqual [pane1[0]]
|
||||
expect(container.find('> .pane-row > .pane-column > .pane').toArray()).toEqual [pane2[0], pane3[0]]
|
||||
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]]
|
||||
|
||||
pane1Model.destroy()
|
||||
expect(container.find('> .pane-column > .pane').toArray()).toEqual [pane2[0], pane3[0]]
|
||||
expect(container.find('> atom-pane-axis.vertical > atom-pane').toArray()).toEqual [pane2[0], pane3[0]]
|
||||
|
||||
describe "serialization", ->
|
||||
it "focuses the pane after attach only if had focus when serialized", ->
|
||||
container.attachToDom()
|
||||
pane.focus()
|
||||
|
||||
container2 = atom.workspace.getView(container.model.testSerialization()).__spacePenView
|
||||
container2 = atom.views.getView(container.model.testSerialization()).__spacePenView
|
||||
pane2 = container2.getRoot()
|
||||
container2.attachToDom()
|
||||
expect(pane2).toMatchSelector(':has(:focus)')
|
||||
|
||||
$(document.activeElement).blur()
|
||||
container3 = atom.workspace.getView(container.model.testSerialization()).__spacePenView
|
||||
container3 = atom.views.getView(container.model.testSerialization()).__spacePenView
|
||||
pane3 = container3.getRoot()
|
||||
container3.attachToDom()
|
||||
expect(pane3).not.toMatchSelector(':has(:focus)')
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
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] = []
|
||||
|
||||
class TestPanelContainerItem
|
||||
constructior: ->
|
||||
|
||||
class TestPanelContainerItemElement extends HTMLElement
|
||||
createdCallback: ->
|
||||
@classList.add('test-root')
|
||||
setModel: (@model) ->
|
||||
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
|
||||
|
||||
container = new PanelContainer({viewRegistry, location: 'left'})
|
||||
element = container.getView()
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
it 'has a location attribute with value from the model', ->
|
||||
expect(element.getAttribute('location')).toBe 'left'
|
||||
|
||||
it 'removes the element when the container is destroyed', ->
|
||||
expect(element.parentNode).toBe jasmineContent
|
||||
container.destroy()
|
||||
expect(element.parentNode).not.toBe jasmineContent
|
||||
|
||||
describe "adding and removing panels", ->
|
||||
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()})
|
||||
container.addPanel(panel1)
|
||||
expect(element.childNodes.length).toBe 1
|
||||
expect(element.childNodes[0].getAttribute('location')).toBe 'left'
|
||||
|
||||
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
|
||||
|
||||
panel2 = new Panel({viewRegistry, 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'
|
||||
|
||||
panel1.destroy()
|
||||
expect(element.childNodes.length).toBe 1
|
||||
|
||||
panel2.destroy()
|
||||
expect(element.childNodes.length).toBe 0
|
||||
|
||||
describe "when the container is at the bottom location", ->
|
||||
beforeEach ->
|
||||
container = new PanelContainer({viewRegistry, location: 'bottom'})
|
||||
element = container.getView()
|
||||
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'})
|
||||
container.addPanel(panel1)
|
||||
expect(element.childNodes.length).toBe 1
|
||||
expect(element.childNodes[0].getAttribute('location')).toBe 'bottom'
|
||||
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
|
||||
expect(panel1.getView()).toHaveClass 'one'
|
||||
|
||||
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem(), className: 'two'})
|
||||
container.addPanel(panel2)
|
||||
expect(element.childNodes.length).toBe 2
|
||||
expect(panel2.getView()).toHaveClass 'two'
|
||||
|
||||
panel1.destroy()
|
||||
expect(element.childNodes.length).toBe 1
|
||||
|
||||
panel2.destroy()
|
||||
expect(element.childNodes.length).toBe 0
|
||||
|
||||
describe "when the container is modal", ->
|
||||
beforeEach ->
|
||||
container = new PanelContainer({viewRegistry, location: 'modal'})
|
||||
element = container.getView()
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
it "allows only one panel to be visible at a time", ->
|
||||
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
|
||||
expect(panel1.getView().style.display).not.toBe 'none'
|
||||
|
||||
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel2)
|
||||
|
||||
expect(panel1.getView().style.display).toBe 'none'
|
||||
expect(panel2.getView().style.display).not.toBe 'none'
|
||||
|
||||
panel1.show()
|
||||
|
||||
expect(panel1.getView().style.display).not.toBe 'none'
|
||||
expect(panel2.getView().style.display).toBe 'none'
|
||||
@@ -0,0 +1,98 @@
|
||||
ViewRegistry = require '../src/view-registry'
|
||||
Panel = require '../src/panel'
|
||||
PanelContainer = require '../src/panel-container'
|
||||
|
||||
describe "PanelContainer", ->
|
||||
[container, viewRegistry] = []
|
||||
|
||||
class TestPanelItem
|
||||
constructior: ->
|
||||
|
||||
beforeEach ->
|
||||
viewRegistry = new ViewRegistry
|
||||
container = new PanelContainer({viewRegistry})
|
||||
|
||||
describe "::addPanel(panel)", ->
|
||||
it 'emits an onDidAddPanel event with the index the panel was inserted at', ->
|
||||
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
|
||||
panel1 = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(panel1)
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel: panel1, index: 0})
|
||||
|
||||
panel2 = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(panel2)
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel: panel2, index: 1})
|
||||
|
||||
describe "when a panel is destroyed", ->
|
||||
it 'emits an onDidRemovePanel event with the index of the removed item', ->
|
||||
container.onDidRemovePanel removePanelSpy = jasmine.createSpy()
|
||||
|
||||
panel1 = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(panel1)
|
||||
panel2 = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(panel2)
|
||||
|
||||
expect(removePanelSpy).not.toHaveBeenCalled()
|
||||
|
||||
panel2.destroy()
|
||||
expect(removePanelSpy).toHaveBeenCalledWith({panel: panel2, index: 1})
|
||||
|
||||
panel1.destroy()
|
||||
expect(removePanelSpy).toHaveBeenCalledWith({panel: panel1, index: 0})
|
||||
|
||||
describe "panel priority", ->
|
||||
describe 'left / top panel container', ->
|
||||
[initialPanel] = []
|
||||
beforeEach ->
|
||||
# 'left' logic is the same as 'top'
|
||||
container = new PanelContainer({viewRegistry, location: 'left'})
|
||||
initialPanel = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(initialPanel)
|
||||
|
||||
describe 'when a panel with low priority is added', ->
|
||||
it 'is inserted at the beginning of the list', ->
|
||||
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = new Panel(item: new TestPanelItem(), priority: 0)
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
expect(container.getPanels()[0]).toBe panel
|
||||
|
||||
describe 'when a panel with priority between two other panels is added', ->
|
||||
it 'is inserted at the between the two panels', ->
|
||||
panel = new Panel(item: new TestPanelItem(), priority: 1000)
|
||||
container.addPanel(panel)
|
||||
|
||||
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = new Panel(item: new TestPanelItem(), priority: 101)
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 1})
|
||||
expect(container.getPanels()[1]).toBe panel
|
||||
|
||||
describe 'right / bottom panel container', ->
|
||||
[initialPanel] = []
|
||||
beforeEach ->
|
||||
# 'bottom' logic is the same as 'right'
|
||||
container = new PanelContainer({viewRegistry, location: 'right'})
|
||||
initialPanel = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(initialPanel)
|
||||
|
||||
describe 'when a panel with high priority is added', ->
|
||||
it 'is inserted at the beginning of the list', ->
|
||||
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = new Panel(item: new TestPanelItem(), priority: 1000)
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
expect(container.getPanels()[0]).toBe panel
|
||||
|
||||
describe 'when a panel with low priority is added', ->
|
||||
it 'is inserted at the end of the list', ->
|
||||
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = new Panel(item: new TestPanelItem(), priority: 0)
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 1})
|
||||
expect(container.getPanels()[1]).toBe panel
|
||||
@@ -0,0 +1,65 @@
|
||||
ViewRegistry = require '../src/view-registry'
|
||||
Panel = require '../src/panel'
|
||||
PanelElement = require '../src/panel-element'
|
||||
|
||||
describe "PanelElement", ->
|
||||
[jasmineContent, element, panel, viewRegistry] = []
|
||||
|
||||
class TestPanelItem
|
||||
constructior: ->
|
||||
|
||||
class TestPanelItemElement extends HTMLElement
|
||||
createdCallback: ->
|
||||
@classList.add('test-root')
|
||||
setModel: (@model) ->
|
||||
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
|
||||
|
||||
it 'removes the element when the panel is destroyed', ->
|
||||
panel = new Panel({viewRegistry, item: new TestPanelItem})
|
||||
element = panel.getView()
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
expect(element.parentNode).toBe jasmineContent
|
||||
panel.destroy()
|
||||
expect(element.parentNode).not.toBe jasmineContent
|
||||
|
||||
describe "changing panel visibility", ->
|
||||
it 'initially renders panel created with visibile: false', ->
|
||||
panel = new Panel({viewRegistry, visible: false, item: new TestPanelItem})
|
||||
element = panel.getView()
|
||||
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()
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
expect(element.style.display).not.toBe 'none'
|
||||
|
||||
panel.hide()
|
||||
expect(element.style.display).toBe 'none'
|
||||
|
||||
panel.show()
|
||||
expect(element.style.display).not.toBe 'none'
|
||||
|
||||
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()
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
expect(element).toHaveClass 'some'
|
||||
expect(element).toHaveClass 'classes'
|
||||
@@ -0,0 +1,23 @@
|
||||
Panel = require '../src/panel'
|
||||
|
||||
describe "Panel", ->
|
||||
[panel] = []
|
||||
|
||||
class TestPanelItem
|
||||
constructior: ->
|
||||
|
||||
beforeEach ->
|
||||
panel = new Panel(item: new TestPanelItem())
|
||||
|
||||
describe "changing panel visibility", ->
|
||||
it 'emits an event when visibility changes', ->
|
||||
panel.onDidChangeVisible spy = jasmine.createSpy()
|
||||
|
||||
panel.hide()
|
||||
expect(panel.isVisible()).toBe false
|
||||
expect(spy).toHaveBeenCalledWith(false)
|
||||
spy.reset()
|
||||
|
||||
panel.show()
|
||||
expect(panel.isVisible()).toBe true
|
||||
expect(spy).toHaveBeenCalledWith(true)
|
||||
@@ -184,7 +184,7 @@ describe "SelectListView", ->
|
||||
describe "when the mini editor loses focus", ->
|
||||
it "triggers the cancelled hook and detaches the select list", ->
|
||||
spyOn(selectList, 'detach')
|
||||
filterEditorView.hiddenInput.trigger 'focusout'
|
||||
filterEditorView.trigger 'blur'
|
||||
expect(selectList.cancelled).toHaveBeenCalled()
|
||||
expect(selectList.detach).toHaveBeenCalled()
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ require '../src/window'
|
||||
atom.initialize()
|
||||
atom.restoreWindowDimensions()
|
||||
|
||||
require 'jasmine-json'
|
||||
require '../vendor/jasmine-jquery'
|
||||
path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
@@ -28,6 +29,7 @@ atom.packages.packageDirPaths.unshift(fixturePackagesPath)
|
||||
atom.keymaps.loadBundledKeymaps()
|
||||
keyBindingsToRestore = atom.keymaps.getKeyBindings()
|
||||
commandsToRestore = atom.commands.getSnapshot()
|
||||
styleElementsToRestore = atom.styles.getSnapshot()
|
||||
|
||||
window.addEventListener 'core:close', -> window.close()
|
||||
window.addEventListener 'beforeunload', ->
|
||||
@@ -43,8 +45,7 @@ Object.defineProperty document, 'title',
|
||||
|
||||
jasmine.getEnv().addEqualityTester(_.isEqual) # Use underscore's definition of equality for toEqual assertions
|
||||
|
||||
if process.platform is 'win32' and process.env.JANKY_SHA1
|
||||
# Use longer timeout on Windows CI
|
||||
if process.env.JANKY_SHA1 and process.platform is 'win32'
|
||||
jasmine.getEnv().defaultTimeoutInterval = 60000
|
||||
else
|
||||
jasmine.getEnv().defaultTimeoutInterval = 5000
|
||||
@@ -72,8 +73,8 @@ beforeEach ->
|
||||
atom.project = new Project(paths: [projectPath])
|
||||
atom.workspace = new Workspace()
|
||||
atom.keymaps.keyBindings = _.clone(keyBindingsToRestore)
|
||||
atom.commands.setRootNode(document.body)
|
||||
atom.commands.restoreSnapshot(commandsToRestore)
|
||||
atom.styles.restoreSnapshot(styleElementsToRestore)
|
||||
|
||||
window.resetTimeouts()
|
||||
atom.packages.packageStates = {}
|
||||
@@ -105,6 +106,7 @@ beforeEach ->
|
||||
config.set "editor.autoIndent", false
|
||||
config.set "core.disabledPackages", ["package-that-throws-an-exception",
|
||||
"package-with-broken-package-json", "package-with-broken-keymap"]
|
||||
config.set "editor.useShadowDOM", true
|
||||
config.load.reset()
|
||||
config.save.reset()
|
||||
|
||||
@@ -218,13 +220,13 @@ addCustomMatchers = (spec) ->
|
||||
@message = -> return "Expected element '" + @actual + "' or its descendants" + notText + " to have focus."
|
||||
element = @actual
|
||||
element = element.get(0) if element.jquery
|
||||
element.webkitMatchesSelector(":focus") or element.querySelector(":focus")
|
||||
element is document.activeElement or element.contains(document.activeElement)
|
||||
|
||||
toShow: ->
|
||||
notText = if @isNot then " not" else ""
|
||||
element = @actual
|
||||
element = element.get(0) if element.jquery
|
||||
@message = -> return "Expected element '#{element}' or its descendants #{notText} to show."
|
||||
@message = -> return "Expected element '#{element}' or its descendants#{notText} to show."
|
||||
element.style.display in ['block', 'inline-block', 'static', 'fixed']
|
||||
|
||||
window.keyIdentifierForKey = (key) ->
|
||||
@@ -337,12 +339,8 @@ window.setEditorWidthInChars = (editorView, widthInChars, charWidth=editorView.c
|
||||
$(window).trigger 'resize' # update width of editor view's on-screen lines
|
||||
|
||||
window.setEditorHeightInLines = (editorView, heightInLines, lineHeight=editorView.lineHeight) ->
|
||||
if editorView.hasClass('react')
|
||||
editorView.height(editorView.getEditor().getLineHeightInPixels() * heightInLines)
|
||||
editorView.component?.measureHeightAndWidth()
|
||||
else
|
||||
editorView.height(lineHeight * heightInLines + editorView.renderedLines.position().top)
|
||||
$(window).trigger 'resize' # update editor view's on-screen lines
|
||||
editorView.height(editorView.getEditor().getLineHeightInPixels() * heightInLines)
|
||||
editorView.component?.measureHeightAndWidth()
|
||||
|
||||
$.fn.resultOfTrigger = (type) ->
|
||||
event = $.Event(type)
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
StyleManager = require '../src/style-manager'
|
||||
|
||||
describe "StyleManager", ->
|
||||
[manager, addEvents, removeEvents, updateEvents] = []
|
||||
|
||||
beforeEach ->
|
||||
manager = new StyleManager
|
||||
addEvents = []
|
||||
removeEvents = []
|
||||
updateEvents = []
|
||||
|
||||
manager.onDidAddStyleElement (event) -> addEvents.push(event)
|
||||
manager.onDidRemoveStyleElement (event) -> removeEvents.push(event)
|
||||
manager.onDidUpdateStyleElement (event) -> updateEvents.push(event)
|
||||
|
||||
describe "::addStyleSheet(source, params)", ->
|
||||
it "adds a stylesheet based on the given source and returns a disposable allowing it to be removed", ->
|
||||
disposable = manager.addStyleSheet("a {color: red;}")
|
||||
|
||||
expect(addEvents.length).toBe 1
|
||||
expect(addEvents[0].textContent).toBe "a {color: red;}"
|
||||
|
||||
styleElements = manager.getStyleElements()
|
||||
expect(styleElements.length).toBe 1
|
||||
expect(styleElements[0].textContent).toBe "a {color: red;}"
|
||||
|
||||
disposable.dispose()
|
||||
|
||||
expect(removeEvents.length).toBe 1
|
||||
expect(removeEvents[0].textContent).toBe "a {color: red;}"
|
||||
expect(manager.getStyleElements().length).toBe 0
|
||||
|
||||
describe "when a sourcePath parameter is specified", ->
|
||||
it "ensures a maximum of one style element for the given source path, updating a previous if it exists", ->
|
||||
disposable1 = manager.addStyleSheet("a {color: red;}", sourcePath: '/foo/bar')
|
||||
|
||||
expect(addEvents.length).toBe 1
|
||||
expect(addEvents[0].getAttribute('source-path')).toBe '/foo/bar'
|
||||
|
||||
disposable2 = manager.addStyleSheet("a {color: blue;}", sourcePath: '/foo/bar')
|
||||
|
||||
expect(addEvents.length).toBe 1
|
||||
expect(updateEvents.length).toBe 1
|
||||
expect(updateEvents[0].getAttribute('source-path')).toBe '/foo/bar'
|
||||
expect(updateEvents[0].textContent).toBe "a {color: blue;}"
|
||||
|
||||
disposable2.dispose()
|
||||
addEvents = []
|
||||
|
||||
manager.addStyleSheet("a {color: yellow;}", sourcePath: '/foo/bar')
|
||||
|
||||
expect(addEvents.length).toBe 1
|
||||
expect(addEvents[0].getAttribute('source-path')).toBe '/foo/bar'
|
||||
expect(addEvents[0].textContent).toBe "a {color: yellow;}"
|
||||
|
||||
describe "when a group parameter is specified", ->
|
||||
it "inserts the stylesheet at the end of any existing stylesheets for the same group", ->
|
||||
manager.addStyleSheet("a {color: red}", group: 'a')
|
||||
manager.addStyleSheet("a {color: blue}", group: 'b')
|
||||
manager.addStyleSheet("a {color: green}", group: 'a')
|
||||
|
||||
expect(manager.getStyleElements().map (elt) -> elt.textContent).toEqual [
|
||||
"a {color: red}"
|
||||
"a {color: green}"
|
||||
"a {color: blue}"
|
||||
]
|
||||
@@ -0,0 +1,75 @@
|
||||
StylesElement = require '../src/styles-element'
|
||||
StyleManager = require '../src/style-manager'
|
||||
|
||||
describe "StylesElement", ->
|
||||
[element, addedStyleElements, removedStyleElements, updatedStyleElements] = []
|
||||
|
||||
beforeEach ->
|
||||
element = new StylesElement
|
||||
document.querySelector('#jasmine-content').appendChild(element)
|
||||
addedStyleElements = []
|
||||
removedStyleElements = []
|
||||
updatedStyleElements = []
|
||||
element.onDidAddStyleElement (element) -> addedStyleElements.push(element)
|
||||
element.onDidRemoveStyleElement (element) -> removedStyleElements.push(element)
|
||||
element.onDidUpdateStyleElement (element) -> updatedStyleElements.push(element)
|
||||
|
||||
it "renders a style tag for all currently active stylesheets in the style manager", ->
|
||||
initialChildCount = element.children.length
|
||||
|
||||
disposable1 = atom.styles.addStyleSheet("a {color: red;}")
|
||||
expect(element.children.length).toBe initialChildCount + 1
|
||||
expect(element.children[initialChildCount].textContent).toBe "a {color: red;}"
|
||||
expect(addedStyleElements).toEqual [element.children[initialChildCount]]
|
||||
|
||||
disposable2 = atom.styles.addStyleSheet("a {color: blue;}")
|
||||
expect(element.children.length).toBe initialChildCount + 2
|
||||
expect(element.children[initialChildCount + 1].textContent).toBe "a {color: blue;}"
|
||||
expect(addedStyleElements).toEqual [element.children[initialChildCount], element.children[initialChildCount + 1]]
|
||||
|
||||
disposable1.dispose()
|
||||
expect(element.children.length).toBe initialChildCount + 1
|
||||
expect(element.children[initialChildCount].textContent).toBe "a {color: blue;}"
|
||||
expect(removedStyleElements).toEqual [addedStyleElements[0]]
|
||||
|
||||
it "orders style elements by group", ->
|
||||
initialChildCount = element.children.length
|
||||
|
||||
atom.styles.addStyleSheet("a {color: red}", group: 'a')
|
||||
atom.styles.addStyleSheet("a {color: blue}", group: 'b')
|
||||
atom.styles.addStyleSheet("a {color: green}", group: 'a')
|
||||
|
||||
expect(element.children[initialChildCount].textContent).toBe "a {color: red}"
|
||||
expect(element.children[initialChildCount + 1].textContent).toBe "a {color: green}"
|
||||
expect(element.children[initialChildCount + 2].textContent).toBe "a {color: blue}"
|
||||
|
||||
it "updates existing style nodes when style elements are updated", ->
|
||||
initialChildCount = element.children.length
|
||||
|
||||
atom.styles.addStyleSheet("a {color: red;}", sourcePath: '/foo/bar')
|
||||
atom.styles.addStyleSheet("a {color: blue;}", sourcePath: '/foo/bar')
|
||||
|
||||
expect(element.children.length).toBe initialChildCount + 1
|
||||
expect(element.children[initialChildCount].textContent).toBe "a {color: blue;}"
|
||||
expect(updatedStyleElements).toEqual [element.children[initialChildCount]]
|
||||
|
||||
it "only includes style elements matching the 'context' attribute", ->
|
||||
initialChildCount = element.children.length
|
||||
|
||||
atom.styles.addStyleSheet("a {color: red;}", context: 'test-context')
|
||||
atom.styles.addStyleSheet("a {color: green;}")
|
||||
|
||||
expect(element.children.length).toBe initialChildCount + 1
|
||||
expect(element.children[initialChildCount].textContent).toBe "a {color: green;}"
|
||||
|
||||
element.setAttribute('context', 'test-context')
|
||||
|
||||
expect(element.children.length).toBe 1
|
||||
expect(element.children[0].textContent).toBe "a {color: red;}"
|
||||
|
||||
atom.styles.addStyleSheet("a {color: blue;}", context: 'test-context')
|
||||
atom.styles.addStyleSheet("a {color: yellow;}")
|
||||
|
||||
expect(element.children.length).toBe 2
|
||||
expect(element.children[0].textContent).toBe "a {color: red;}"
|
||||
expect(element.children[1].textContent).toBe "a {color: blue;}"
|
||||
@@ -277,7 +277,7 @@ describe "TextEditorComponent", ->
|
||||
expect(leafNodes[0].classList.contains('invisible-character')).toBe true
|
||||
expect(leafNodes[leafNodes.length - 1].classList.contains('invisible-character')).toBe true
|
||||
|
||||
it "displays newlines as their own token outside of the other tokens' scopes", ->
|
||||
it "displays newlines as their own token outside of the other tokens' scopeDescriptor", ->
|
||||
editor.setText "var\n"
|
||||
nextAnimationFrame()
|
||||
expect(component.lineNodeForScreenRow(0).innerHTML).toBe "<span class=\"source js\"><span class=\"storage modifier js\">var</span></span><span class=\"invisible-character\">#{invisibles.eol}</span>"
|
||||
@@ -446,12 +446,6 @@ describe "TextEditorComponent", ->
|
||||
foldedLineNode = component.lineNodeForScreenRow(4)
|
||||
expect(foldedLineNode.querySelector('.fold-marker')).toBeFalsy()
|
||||
|
||||
getLeafNodes = (node) ->
|
||||
if node.children.length > 0
|
||||
flatten(toArray(node.children).map(getLeafNodes))
|
||||
else
|
||||
[node]
|
||||
|
||||
describe "gutter rendering", ->
|
||||
[gutter] = []
|
||||
|
||||
@@ -704,16 +698,34 @@ describe "TextEditorComponent", ->
|
||||
expect(cursorRect.left).toBe rangeRect.left
|
||||
expect(cursorRect.width).toBe rangeRect.width
|
||||
|
||||
it "accounts for the width of paired characters when positioning cursors", ->
|
||||
atom.config.set('editor.fontFamily', 'sans-serif')
|
||||
editor.setText('he\u0301y') # e with an accent mark
|
||||
editor.setCursorBufferPosition([0, 3])
|
||||
nextAnimationFrame()
|
||||
|
||||
cursor = componentNode.querySelector('.cursor')
|
||||
cursorRect = cursor.getBoundingClientRect()
|
||||
|
||||
cursorLocationTextNode = component.lineNodeForScreenRow(0).querySelector('.source.js').firstChild
|
||||
range = document.createRange()
|
||||
range.setStart(cursorLocationTextNode, 3)
|
||||
range.setEnd(cursorLocationTextNode, 4)
|
||||
rangeRect = range.getBoundingClientRect()
|
||||
|
||||
expect(cursorRect.left).toBe rangeRect.left
|
||||
expect(cursorRect.width).toBe rangeRect.width
|
||||
|
||||
it "positions cursors correctly after character widths are changed via a stylesheet change", ->
|
||||
atom.config.set('editor.fontFamily', 'sans-serif')
|
||||
editor.setCursorScreenPosition([0, 16])
|
||||
nextAnimationFrame()
|
||||
|
||||
atom.themes.applyStylesheet 'test', """
|
||||
atom.styles.addStyleSheet """
|
||||
.function.js {
|
||||
font-weight: bold;
|
||||
}
|
||||
"""
|
||||
""", context: 'atom-text-editor'
|
||||
nextAnimationFrame() # update based on new measurements
|
||||
|
||||
cursor = componentNode.querySelector('.cursor')
|
||||
@@ -1236,6 +1248,22 @@ describe "TextEditorComponent", ->
|
||||
beforeEach ->
|
||||
linesNode = componentNode.querySelector('.lines')
|
||||
|
||||
describe "when the mouse is single-clicked below the last line", ->
|
||||
it "moves the cursor to the end of file buffer position", ->
|
||||
editor.setText('foo')
|
||||
editor.setCursorBufferPosition([0, 0])
|
||||
height = 4.5 * lineHeightInPixels
|
||||
wrapperNode.style.height = height + 'px'
|
||||
wrapperNode.style.width = 10 * charWidth + 'px'
|
||||
component.measureHeightAndWidth()
|
||||
nextAnimationFrame()
|
||||
|
||||
coordinates = clientCoordinatesForScreenPosition([0, 2])
|
||||
coordinates.clientY = height * 2
|
||||
linesNode.dispatchEvent(buildMouseEvent('mousedown', coordinates))
|
||||
nextAnimationFrame()
|
||||
expect(editor.getCursorScreenPosition()).toEqual [0, 3]
|
||||
|
||||
describe "when a non-folded line is single-clicked", ->
|
||||
describe "when no modifier keys are held down", ->
|
||||
it "moves the cursor to the nearest screen position", ->
|
||||
@@ -1509,8 +1537,9 @@ describe "TextEditorComponent", ->
|
||||
|
||||
it "transfers focus to the hidden input", ->
|
||||
expect(document.activeElement).toBe document.body
|
||||
componentNode.focus()
|
||||
expect(document.activeElement).toBe inputNode
|
||||
wrapperNode.focus()
|
||||
expect(document.activeElement).toBe wrapperNode
|
||||
expect(wrapperNode.shadowRoot.activeElement).toBe inputNode
|
||||
|
||||
it "adds the 'is-focused' class to the editor when the hidden input is focused", ->
|
||||
expect(document.activeElement).toBe document.body
|
||||
@@ -1639,12 +1668,13 @@ describe "TextEditorComponent", ->
|
||||
component.measureHeightAndWidth()
|
||||
nextAnimationFrame()
|
||||
|
||||
atom.themes.applyStylesheet "test", """
|
||||
atom.styles.addStyleSheet """
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
"""
|
||||
""", context: 'atom-text-editor'
|
||||
|
||||
nextAnimationFrame()
|
||||
|
||||
scrollbarCornerNode = componentNode.querySelector('.scrollbar-corner')
|
||||
@@ -1894,6 +1924,31 @@ describe "TextEditorComponent", ->
|
||||
expect(nextAnimationFrame).toBe noAnimationFrame
|
||||
expect(editor.lineTextForBufferRow(0)).toBe 'var quicksort = function () {'
|
||||
|
||||
it "groups events that occur close together in time into single undo entries", ->
|
||||
currentTime = 0
|
||||
spyOn(Date, 'now').andCallFake -> currentTime
|
||||
|
||||
atom.config.set('editor.undoGroupingInterval', 100)
|
||||
|
||||
editor.setText("")
|
||||
componentNode.dispatchEvent(buildTextInputEvent(data: 'x', target: inputNode))
|
||||
|
||||
currentTime += 99
|
||||
componentNode.dispatchEvent(buildTextInputEvent(data: 'y', target: inputNode))
|
||||
|
||||
currentTime += 99
|
||||
componentNode.dispatchEvent(new CustomEvent('editor:duplicate-lines', bubbles: true, cancelable: true))
|
||||
|
||||
currentTime += 100
|
||||
componentNode.dispatchEvent(new CustomEvent('editor:duplicate-lines', bubbles: true, cancelable: true))
|
||||
expect(editor.getText()).toBe "xy\nxy\nxy"
|
||||
|
||||
componentNode.dispatchEvent(new CustomEvent('core:undo', bubbles: true, cancelable: true))
|
||||
expect(editor.getText()).toBe "xy\nxy"
|
||||
|
||||
componentNode.dispatchEvent(new CustomEvent('core:undo', bubbles: true, cancelable: true))
|
||||
expect(editor.getText()).toBe ""
|
||||
|
||||
describe "when IME composition is used to insert international characters", ->
|
||||
inputNode = null
|
||||
|
||||
@@ -2214,7 +2269,6 @@ describe "TextEditorComponent", ->
|
||||
it "does not render invisible characters", ->
|
||||
atom.config.set('editor.invisibles', eol: 'E')
|
||||
atom.config.set('editor.showInvisibles', true)
|
||||
nextAnimationFrame()
|
||||
expect(component.lineNodeForScreenRow(0).textContent).toBe 'var quicksort = function () {'
|
||||
|
||||
it "does not assign an explicit line-height on the editor contents", ->
|
||||
@@ -2259,6 +2313,12 @@ describe "TextEditorComponent", ->
|
||||
editor.setGrammar(atom.syntax.nullGrammar)
|
||||
expect(wrapperNode.dataset.grammar).toBe 'text plain null-grammar'
|
||||
|
||||
describe "encoding data attributes", ->
|
||||
it "adds and updates the encoding data attribute based on the current encoding", ->
|
||||
expect(wrapperNode.dataset.encoding).toBe 'utf8'
|
||||
editor.setEncoding('utf16le')
|
||||
expect(wrapperNode.dataset.encoding).toBe 'utf16le'
|
||||
|
||||
describe "detaching and reattaching the editor (regression)", ->
|
||||
it "does not throw an exception", ->
|
||||
wrapperView.detach()
|
||||
@@ -2268,6 +2328,140 @@ describe "TextEditorComponent", ->
|
||||
|
||||
expect(editor.getCursorBufferPosition()).toEqual [0, 1]
|
||||
|
||||
describe 'scoped config settings', ->
|
||||
[coffeeEditor, coffeeComponent] = []
|
||||
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-coffee-script')
|
||||
waitsForPromise ->
|
||||
atom.project.open('coffee.coffee', autoIndent: false).then (o) -> coffeeEditor = o
|
||||
|
||||
afterEach: ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
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
|
||||
|
||||
editor.setEditorWidthInChars(20)
|
||||
coffeeEditor.setEditorWidthInChars(20)
|
||||
|
||||
it "wraps lines when editor.softWrap is true for a matching scope", ->
|
||||
expect(editor.lineTextForScreenRow(2)).toEqual ' if (items.length <= 1) return items;'
|
||||
expect(coffeeEditor.lineTextForScreenRow(3)).toEqual ' return items '
|
||||
|
||||
it 'updates the wrapped lines when editor.preferredLineLength changes', ->
|
||||
atom.config.set '.source.coffee', 'editor.preferredLineLength', 20
|
||||
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
|
||||
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
|
||||
expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if items.length <= 1'
|
||||
|
||||
atom.config.set '.source.coffee', 'editor.softWrap', true
|
||||
expect(coffeeEditor.lineTextForScreenRow(3)).toEqual ' return items '
|
||||
|
||||
it 'updates the wrapped lines when the grammar changes', ->
|
||||
editor.setGrammar(coffeeEditor.getGrammar())
|
||||
expect(editor.isSoftWrapped()).toBe true
|
||||
expect(editor.lineTextForScreenRow(0)).toEqual 'var quicksort = '
|
||||
|
||||
describe '::isSoftWrapped()', ->
|
||||
it 'returns the correct value based on the scoped settings', ->
|
||||
expect(editor.isSoftWrapped()).toBe false
|
||||
expect(coffeeEditor.isSoftWrapped()).toBe true
|
||||
|
||||
describe 'invisibles settings', ->
|
||||
[jsInvisibles, coffeeInvisibles] = []
|
||||
beforeEach ->
|
||||
jsInvisibles =
|
||||
eol: 'J'
|
||||
space: 'A'
|
||||
tab: 'V'
|
||||
cr: 'A'
|
||||
|
||||
coffeeInvisibles =
|
||||
eol: 'C'
|
||||
space: 'O'
|
||||
tab: 'F'
|
||||
cr: 'E'
|
||||
|
||||
atom.config.set '.source.js', 'editor.showInvisibles', true
|
||||
atom.config.set '.source.js', 'editor.invisibles', jsInvisibles
|
||||
|
||||
atom.config.set '.source.coffee', 'editor.showInvisibles', false
|
||||
atom.config.set '.source.coffee', 'editor.invisibles', coffeeInvisibles
|
||||
|
||||
editor.setText " a line with tabs\tand spaces \n"
|
||||
nextAnimationFrame()
|
||||
|
||||
it "renders the invisibles when editor.showInvisibles is true for a given grammar", ->
|
||||
expect(component.lineNodeForScreenRow(0).textContent).toBe "#{jsInvisibles.space}a line with tabs#{jsInvisibles.tab}and spaces#{jsInvisibles.space}#{jsInvisibles.eol}"
|
||||
|
||||
it "does not render the invisibles when editor.showInvisibles is false for a given grammar", ->
|
||||
editor.setGrammar(coffeeEditor.getGrammar())
|
||||
nextAnimationFrame()
|
||||
expect(component.lineNodeForScreenRow(0).textContent).toBe " a line with tabs and spaces "
|
||||
|
||||
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
|
||||
nextAnimationFrame()
|
||||
expect(component.lineNodeForScreenRow(0).textContent).toBe "#{coffeeInvisibles.space}a line with tabs#{coffeeInvisibles.tab}and spaces#{coffeeInvisibles.space}#{coffeeInvisibles.eol}"
|
||||
|
||||
newInvisibles =
|
||||
eol: 'N'
|
||||
space: 'E'
|
||||
tab: 'W'
|
||||
cr: 'I'
|
||||
atom.config.set '.source.coffee', 'editor.invisibles', newInvisibles
|
||||
nextAnimationFrame()
|
||||
expect(component.lineNodeForScreenRow(0).textContent).toBe "#{newInvisibles.space}a line with tabs#{newInvisibles.tab}and spaces#{newInvisibles.space}#{newInvisibles.eol}"
|
||||
|
||||
editor.setGrammar(jsGrammar)
|
||||
nextAnimationFrame()
|
||||
expect(component.lineNodeForScreenRow(0).textContent).toBe "#{jsInvisibles.space}a line with tabs#{jsInvisibles.tab}and spaces#{jsInvisibles.space}#{jsInvisibles.eol}"
|
||||
|
||||
describe 'editor.showIndentGuide', ->
|
||||
beforeEach ->
|
||||
atom.config.set '.source.js', 'editor.showIndentGuide', true
|
||||
atom.config.set '.source.coffee', 'editor.showIndentGuide', false
|
||||
|
||||
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))
|
||||
expect(line1LeafNodes[0].textContent).toBe ' '
|
||||
expect(line1LeafNodes[0].classList.contains('indent-guide')).toBe true
|
||||
expect(line1LeafNodes[1].classList.contains('indent-guide')).toBe false
|
||||
|
||||
editor.setGrammar(coffeeEditor.getGrammar())
|
||||
|
||||
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
|
||||
|
||||
it "removes the 'indent-guide' class when editor.showIndentGuide to false", ->
|
||||
line1LeafNodes = getLeafNodes(component.lineNodeForScreenRow(1))
|
||||
expect(line1LeafNodes[0].textContent).toBe ' '
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
buildMouseEvent = (type, properties...) ->
|
||||
properties = extend({bubbles: true, cancelable: true}, properties...)
|
||||
properties.detail ?= 1
|
||||
@@ -2304,3 +2498,9 @@ describe "TextEditorComponent", ->
|
||||
|
||||
lineHasClass = (screenRow, klass) ->
|
||||
component.lineNodeForScreenRow(screenRow).classList.contains(klass)
|
||||
|
||||
getLeafNodes = (node) ->
|
||||
if node.children.length > 0
|
||||
flatten(toArray(node.children).map(getLeafNodes))
|
||||
else
|
||||
[node]
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
TextEditorElement = require '../src/text-editor-element'
|
||||
|
||||
# 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
|
||||
describe "TextEditorElement", ->
|
||||
jasmineContent = null
|
||||
|
||||
beforeEach ->
|
||||
jasmineContent = document.body.querySelector('#jasmine-content')
|
||||
|
||||
describe "instantiation", ->
|
||||
it "honors the mini attribute", ->
|
||||
jasmineContent.innerHTML = "<atom-text-editor mini>"
|
||||
element = jasmineContent.firstChild
|
||||
expect(element.getModel().isMini()).toBe true
|
||||
|
||||
it "honors the placeholder-text attribute", ->
|
||||
jasmineContent.innerHTML = "<atom-text-editor placeholder-text='testing'>"
|
||||
element = jasmineContent.firstChild
|
||||
expect(element.getModel().getPlaceholderText()).toBe 'testing'
|
||||
|
||||
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", ->
|
||||
atom.config.set('editor.useShadowDOM', true)
|
||||
|
||||
element = new TextEditorElement
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
blurCalled = false
|
||||
element.addEventListener 'blur', -> blurCalled = true
|
||||
|
||||
element.focus()
|
||||
expect(blurCalled).toBe false
|
||||
expect(element.hasFocus()).toBe true
|
||||
expect(document.activeElement).toBe element
|
||||
expect(element.shadowRoot.activeElement).toBe element.shadowRoot.querySelector('input')
|
||||
|
||||
document.body.focus()
|
||||
expect(blurCalled).toBe true
|
||||
|
||||
describe "when the editor.useShadowDOM config option is false", ->
|
||||
afterEach ->
|
||||
document.head.querySelector('atom-styles[context="atom-text-editor"]').remove()
|
||||
|
||||
it "proxies focus/blur events to/from the hidden input", ->
|
||||
atom.config.set('editor.useShadowDOM', false)
|
||||
|
||||
element = new TextEditorElement
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
blurCalled = false
|
||||
element.addEventListener 'blur', -> blurCalled = true
|
||||
|
||||
element.focus()
|
||||
expect(blurCalled).toBe false
|
||||
expect(element.hasFocus()).toBe true
|
||||
expect(document.activeElement).toBe element.querySelector('input')
|
||||
|
||||
document.body.focus()
|
||||
expect(blurCalled).toBe true
|
||||
+179
-12
@@ -157,6 +157,19 @@ describe "TextEditor", ->
|
||||
|
||||
expect(observed).toEqual [__filename, undefined]
|
||||
|
||||
describe "encoding", ->
|
||||
it "notifies ::onDidChangeEncoding observers when the editor encoding changes", ->
|
||||
observed = []
|
||||
editor.onDidChangeEncoding (encoding) -> observed.push(encoding)
|
||||
|
||||
editor.setEncoding('utf16le')
|
||||
editor.setEncoding('utf16le')
|
||||
editor.setEncoding('utf16be')
|
||||
editor.setEncoding()
|
||||
editor.setEncoding()
|
||||
|
||||
expect(observed).toEqual ['utf16le', 'utf16be', 'utf8']
|
||||
|
||||
describe "cursor", ->
|
||||
describe ".getLastCursor()", ->
|
||||
it "returns the most recently created cursor", ->
|
||||
@@ -1259,7 +1272,6 @@ describe "TextEditor", ->
|
||||
editor.selectWordsContainingCursors()
|
||||
expect(editor.getSelectedText()).toBe 'var'
|
||||
|
||||
|
||||
describe "when the cursor is inside a region of whitespace", ->
|
||||
it "selects the whitespace region", ->
|
||||
editor.setCursorScreenPosition([5, 2])
|
||||
@@ -1277,6 +1289,29 @@ describe "TextEditor", ->
|
||||
editor.selectWordsContainingCursors()
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[12, 2], [12, 6]]
|
||||
|
||||
describe 'when editor.nonWordCharacters is set scoped to a grammar', ->
|
||||
coffeeEditor = null
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-coffee-script')
|
||||
waitsForPromise ->
|
||||
atom.project.open('coffee.coffee', autoIndent: false).then (o) -> coffeeEditor = o
|
||||
|
||||
it 'selects the correct surrounding word for the given scoped setting', ->
|
||||
coffeeEditor.setCursorBufferPosition [0, 9] # in the middle of quicksort
|
||||
coffeeEditor.selectWordsContainingCursors()
|
||||
expect(coffeeEditor.getSelectedBufferRange()).toEqual [[0, 6], [0, 15]]
|
||||
|
||||
atom.config.set '.source.coffee', 'editor.nonWordCharacters', 'qusort'
|
||||
|
||||
coffeeEditor.setCursorBufferPosition [0, 9]
|
||||
coffeeEditor.selectWordsContainingCursors()
|
||||
expect(coffeeEditor.getSelectedBufferRange()).toEqual [[0, 8], [0, 11]]
|
||||
|
||||
editor.setCursorBufferPosition [0, 7]
|
||||
editor.selectWordsContainingCursors()
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[0, 4], [0, 13]]
|
||||
|
||||
describe ".selectToFirstCharacterOfLine()", ->
|
||||
it "moves to the first character of the current line or the beginning of the line if it's already on the first character", ->
|
||||
editor.setCursorScreenPosition [0,5]
|
||||
@@ -1770,6 +1805,16 @@ describe "TextEditor", ->
|
||||
expect(willInsertSpy).toHaveBeenCalled()
|
||||
expect(didInsertSpy).not.toHaveBeenCalled()
|
||||
|
||||
describe "when the undo option is set to 'skip'", ->
|
||||
beforeEach ->
|
||||
editor.setSelectedBufferRange([[1, 2], [1, 2]])
|
||||
|
||||
it "does not undo the skipped operation", ->
|
||||
range = editor.insertText('x')
|
||||
range = editor.insertText('y', undo: 'skip')
|
||||
editor.undo()
|
||||
expect(buffer.lineForRow(1)).toBe ' yvar sort = function(items) {'
|
||||
|
||||
describe ".insertNewline()", ->
|
||||
describe "when there is a single cursor", ->
|
||||
describe "when the cursor is at the beginning of a line", ->
|
||||
@@ -3038,6 +3083,56 @@ describe "TextEditor", ->
|
||||
atom.workspace.open(null, softTabs: false).then (editor) ->
|
||||
expect(editor.getSoftTabs()).toBeFalsy()
|
||||
|
||||
describe '.getTabLength()', ->
|
||||
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
|
||||
|
||||
afterEach: ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
it 'returns correct values based on the scope of the set grammars', ->
|
||||
atom.config.set '.source.coffee', 'editor.tabLength', 6
|
||||
|
||||
expect(editor.getTabLength()).toBe 2
|
||||
expect(coffeeEditor.getTabLength()).toBe 6
|
||||
|
||||
it 'retokenizes when the tab length is updated via .setTabLength()', ->
|
||||
expect(editor.getTabLength()).toBe 2
|
||||
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 2
|
||||
|
||||
editor.setTabLength(6)
|
||||
expect(editor.getTabLength()).toBe 6
|
||||
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 6
|
||||
|
||||
changeHandler = jasmine.createSpy('changeHandler')
|
||||
editor.onDidChange(changeHandler)
|
||||
editor.setTabLength(6)
|
||||
expect(changeHandler).not.toHaveBeenCalled()
|
||||
|
||||
it 'retokenizes when the editor.tabLength setting is updated', ->
|
||||
expect(editor.getTabLength()).toBe 2
|
||||
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 2
|
||||
|
||||
atom.config.set '.source.js', 'editor.tabLength', 6
|
||||
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
|
||||
|
||||
expect(editor.getTabLength()).toBe 2
|
||||
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 2
|
||||
|
||||
editor.setGrammar(coffeeEditor.getGrammar())
|
||||
expect(editor.getTabLength()).toBe 6
|
||||
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 6
|
||||
|
||||
describe ".indentLevelForLine(line)", ->
|
||||
it "returns the indent level when the line has only leading whitespace", ->
|
||||
expect(editor.indentLevelForLine(" hello")).toBe(2)
|
||||
@@ -3077,14 +3172,15 @@ describe "TextEditor", ->
|
||||
expect(editor.tokenizedLineForScreenRow(0).tokens.length).toBeGreaterThan 1
|
||||
|
||||
describe "auto-indent", ->
|
||||
copyText = (text, {startColumn}={}) ->
|
||||
copyText = (text, {startColumn, textEditor}={}) ->
|
||||
startColumn ?= 0
|
||||
editor.setCursorBufferPosition([0, 0])
|
||||
editor.insertText(text)
|
||||
textEditor ?= editor
|
||||
textEditor.setCursorBufferPosition([0, 0])
|
||||
textEditor.insertText(text)
|
||||
numberOfNewlines = text.match(/\n/g)?.length
|
||||
endColumn = text.match(/[^\n]*$/)[0]?.length
|
||||
editor.getLastSelection().setBufferRange([[0,startColumn], [numberOfNewlines,endColumn]])
|
||||
editor.cutSelectedText()
|
||||
textEditor.getLastSelection().setBufferRange([[0,startColumn], [numberOfNewlines,endColumn]])
|
||||
textEditor.cutSelectedText()
|
||||
|
||||
describe "editor.autoIndent", ->
|
||||
describe "when editor.autoIndent is false (default)", ->
|
||||
@@ -3191,6 +3287,31 @@ describe "TextEditor", ->
|
||||
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", ->
|
||||
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 "editor.normalizeIndentOnPaste", ->
|
||||
beforeEach ->
|
||||
atom.config.set('editor.normalizeIndentOnPaste', true)
|
||||
@@ -3240,6 +3361,37 @@ describe "TextEditor", ->
|
||||
expect(editor.lineTextForBufferRow(3)).toBe " }"
|
||||
expect(editor.lineTextForBufferRow(4)).toBe ""
|
||||
|
||||
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.normalizeIndentOnPaste', true)
|
||||
atom.config.set('.source.coffee', 'editor.normalizeIndentOnPaste', false)
|
||||
|
||||
afterEach: ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
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 " }"
|
||||
|
||||
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 " }"
|
||||
|
||||
it "autoIndentSelectedRows auto-indents the selection", ->
|
||||
editor.setCursorBufferPosition([2, 0])
|
||||
editor.insertText("function() {\ninside=true\n}\n i=1\n")
|
||||
@@ -3252,10 +3404,18 @@ describe "TextEditor", ->
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " i=1"
|
||||
|
||||
describe "soft and hard tabs", ->
|
||||
afterEach ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
it "resets the tab style when tokenization is complete", ->
|
||||
editor.destroy()
|
||||
atom.project.open('sample-with-tabs-and-leading-comment.coffee').then (o) -> editor = o
|
||||
expect(editor.softTabs).toBe true
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.open('sample-with-tabs-and-leading-comment.coffee').then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
expect(editor.softTabs).toBe true
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-coffee-script')
|
||||
@@ -3263,9 +3423,6 @@ describe "TextEditor", ->
|
||||
runs ->
|
||||
expect(editor.softTabs).toBe false
|
||||
|
||||
atom.packages.deactivatePackage('language-coffee-script')
|
||||
atom.packages.unloadPackage('language-coffee-script')
|
||||
|
||||
describe ".destroy()", ->
|
||||
it "destroys all markers associated with the edit session", ->
|
||||
expect(buffer.getMarkerCount()).toBeGreaterThan 0
|
||||
@@ -3283,9 +3440,12 @@ describe "TextEditor", ->
|
||||
describe "when no text is selected", ->
|
||||
describe "when the line below isn't empty", ->
|
||||
it "joins the line below with the current line separated by a space and moves the cursor to the start of line that was moved up", ->
|
||||
editor.setCursorBufferPosition([0, Infinity])
|
||||
editor.insertText(' ')
|
||||
editor.setCursorBufferPosition([0])
|
||||
editor.joinLines()
|
||||
expect(editor.lineTextForBufferRow(0)).toBe 'var quicksort = function () { var sort = function(items) {'
|
||||
expect(editor.getCursorBufferPosition()).toEqual [0, 30]
|
||||
expect(editor.getCursorBufferPosition()).toEqual [0, 29]
|
||||
|
||||
describe "when the line below is empty", ->
|
||||
it "deletes the line below and moves the cursor to the end of the line", ->
|
||||
@@ -3301,6 +3461,13 @@ describe "TextEditor", ->
|
||||
editor.joinLines()
|
||||
expect(editor.lineTextForBufferRow(12)).toBe '};'
|
||||
|
||||
describe "when the line is empty", ->
|
||||
it "joins the line below with the current line with no added space", ->
|
||||
editor.setCursorBufferPosition([10])
|
||||
editor.joinLines()
|
||||
expect(editor.lineTextForBufferRow(10)).toBe 'return sort(Array.apply(this, arguments));'
|
||||
expect(editor.getCursorBufferPosition()).toEqual [10, 0]
|
||||
|
||||
describe "when text is selected", ->
|
||||
describe "when the selection does not span multiple lines", ->
|
||||
it "joins the line below with the current line separated by a space and retains the selected text", ->
|
||||
|
||||
@@ -2,18 +2,23 @@ textUtils = require '../src/text-utils'
|
||||
|
||||
describe 'text utilities', ->
|
||||
describe '.hasPairedCharacter(string)', ->
|
||||
it 'returns true when the string contains a surrogate pair or variation sequence', ->
|
||||
it 'returns true when the string contains a surrogate pair, variation sequence, or combined character', ->
|
||||
expect(textUtils.hasPairedCharacter('abc')).toBe false
|
||||
expect(textUtils.hasPairedCharacter('a\uD835\uDF97b\uD835\uDF97c')).toBe true
|
||||
expect(textUtils.hasPairedCharacter('\uD835\uDF97')).toBe true
|
||||
expect(textUtils.hasPairedCharacter('\u2714\uFE0E')).toBe true
|
||||
expect(textUtils.hasPairedCharacter('e\u0301')).toBe true
|
||||
|
||||
expect(textUtils.hasPairedCharacter('\uD835')).toBe false
|
||||
expect(textUtils.hasPairedCharacter('\uDF97')).toBe false
|
||||
expect(textUtils.hasPairedCharacter('\uFE0E')).toBe false
|
||||
expect(textUtils.hasPairedCharacter('\u0301')).toBe false
|
||||
|
||||
expect(textUtils.hasPairedCharacter('\uFE0E\uFE0E')).toBe false
|
||||
expect(textUtils.hasPairedCharacter('\u0301\u0301')).toBe false
|
||||
|
||||
describe '.isPairedCharacter(string, index)', ->
|
||||
it 'returns true when the index is the start of a high/low surrogate pair or variation sequence', ->
|
||||
it 'returns true when the index is the start of a high/low surrogate pair, variation sequence, or combined character', ->
|
||||
expect(textUtils.isPairedCharacter('a\uD835\uDF97b\uD835\uDF97c', 0)).toBe false
|
||||
expect(textUtils.isPairedCharacter('a\uD835\uDF97b\uD835\uDF97c', 1)).toBe true
|
||||
expect(textUtils.isPairedCharacter('a\uD835\uDF97b\uD835\uDF97c', 2)).toBe false
|
||||
@@ -21,12 +26,21 @@ describe 'text utilities', ->
|
||||
expect(textUtils.isPairedCharacter('a\uD835\uDF97b\uD835\uDF97c', 4)).toBe true
|
||||
expect(textUtils.isPairedCharacter('a\uD835\uDF97b\uD835\uDF97c', 5)).toBe false
|
||||
expect(textUtils.isPairedCharacter('a\uD835\uDF97b\uD835\uDF97c', 6)).toBe false
|
||||
|
||||
expect(textUtils.isPairedCharacter('a\u2714\uFE0E', 0)).toBe false
|
||||
expect(textUtils.isPairedCharacter('a\u2714\uFE0E', 1)).toBe true
|
||||
expect(textUtils.isPairedCharacter('a\u2714\uFE0E', 2)).toBe false
|
||||
expect(textUtils.isPairedCharacter('a\u2714\uFE0E', 3)).toBe false
|
||||
|
||||
expect(textUtils.isPairedCharacter('\uD835')).toBe false
|
||||
expect(textUtils.isPairedCharacter('\uDF97')).toBe false
|
||||
expect(textUtils.isPairedCharacter('\uFE0E')).toBe false
|
||||
expect(textUtils.isPairedCharacter('\uFE0E')).toBe false
|
||||
|
||||
expect(textUtils.isPairedCharacter('\uFE0E\uFE0E')).toBe false
|
||||
|
||||
expect(textUtils.isPairedCharacter('ae\u0301c', 0)).toBe false
|
||||
expect(textUtils.isPairedCharacter('ae\u0301c', 1)).toBe true
|
||||
expect(textUtils.isPairedCharacter('ae\u0301c', 2)).toBe false
|
||||
expect(textUtils.isPairedCharacter('ae\u0301c', 3)).toBe false
|
||||
expect(textUtils.isPairedCharacter('ae\u0301c', 4)).toBe false
|
||||
|
||||
@@ -85,25 +85,25 @@ describe "ThemeManager", ->
|
||||
runs ->
|
||||
reloadHandler.reset()
|
||||
expect($('style.theme')).toHaveLength 0
|
||||
atom.config.set('core.themes', ['atom-dark-syntax'])
|
||||
atom.config.set('core.themes', ['atom-dark-ui'])
|
||||
|
||||
waitsFor ->
|
||||
reloadHandler.callCount == 1
|
||||
|
||||
runs ->
|
||||
reloadHandler.reset()
|
||||
expect($('style.theme')).toHaveLength 1
|
||||
expect($('style.theme:eq(0)').attr('id')).toMatch /atom-dark-syntax/
|
||||
atom.config.set('core.themes', ['atom-light-syntax', 'atom-dark-syntax'])
|
||||
expect($('style[group=theme]')).toHaveLength 1
|
||||
expect($('style[group=theme]:eq(0)').attr('source-path')).toMatch /atom-dark-ui/
|
||||
atom.config.set('core.themes', ['atom-light-ui', 'atom-dark-ui'])
|
||||
|
||||
waitsFor ->
|
||||
reloadHandler.callCount == 1
|
||||
|
||||
runs ->
|
||||
reloadHandler.reset()
|
||||
expect($('style.theme')).toHaveLength 2
|
||||
expect($('style.theme:eq(0)').attr('id')).toMatch /atom-dark-syntax/
|
||||
expect($('style.theme:eq(1)').attr('id')).toMatch /atom-light-syntax/
|
||||
expect($('style[group=theme]')).toHaveLength 2
|
||||
expect($('style[group=theme]:eq(0)').attr('source-path')).toMatch /atom-dark-ui/
|
||||
expect($('style[group=theme]:eq(1)').attr('source-path')).toMatch /atom-light-ui/
|
||||
atom.config.set('core.themes', [])
|
||||
|
||||
waitsFor ->
|
||||
@@ -111,7 +111,7 @@ describe "ThemeManager", ->
|
||||
|
||||
runs ->
|
||||
reloadHandler.reset()
|
||||
expect($('style.theme')).toHaveLength 0
|
||||
expect($('style[group=theme]')).toHaveLength 1
|
||||
# atom-dark-ui has an directory path, the syntax one doesn't
|
||||
atom.config.set('core.themes', ['theme-with-index-less', 'atom-dark-ui'])
|
||||
|
||||
@@ -119,7 +119,7 @@ describe "ThemeManager", ->
|
||||
reloadHandler.callCount == 1
|
||||
|
||||
runs ->
|
||||
expect($('style.theme')).toHaveLength 2
|
||||
expect($('style[group=theme]')).toHaveLength 2
|
||||
importPaths = themeManager.getImportPaths()
|
||||
expect(importPaths.length).toBe 1
|
||||
expect(importPaths[0]).toContain 'atom-dark-ui'
|
||||
@@ -142,8 +142,8 @@ describe "ThemeManager", ->
|
||||
expect(stylesheetAddedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
|
||||
element = $('head style[id*="css.css"]')
|
||||
expect(element.attr('id')).toBe themeManager.stringToId(cssPath)
|
||||
element = $('head style[source-path*="css.css"]')
|
||||
expect(element.attr('source-path')).toBe themeManager.stringToId(cssPath)
|
||||
expect(element.text()).toBe fs.readFileSync(cssPath, 'utf8')
|
||||
expect(element[0].sheet).toBe stylesheetAddedHandler.argsForCall[0][0]
|
||||
|
||||
@@ -159,8 +159,8 @@ describe "ThemeManager", ->
|
||||
themeManager.requireStylesheet(lessPath)
|
||||
expect($('head style').length).toBe lengthBefore + 1
|
||||
|
||||
element = $('head style[id*="sample.less"]')
|
||||
expect(element.attr('id')).toBe themeManager.stringToId(lessPath)
|
||||
element = $('head style[source-path*="sample.less"]')
|
||||
expect(element.attr('source-path')).toBe themeManager.stringToId(lessPath)
|
||||
expect(element.text()).toBe """
|
||||
#header {
|
||||
color: #4d926f;
|
||||
@@ -178,9 +178,9 @@ describe "ThemeManager", ->
|
||||
|
||||
it "supports requiring css and less stylesheets without an explicit extension", ->
|
||||
themeManager.requireStylesheet path.join(__dirname, 'fixtures', 'css')
|
||||
expect($('head style[id*="css.css"]').attr('id')).toBe themeManager.stringToId(atom.project.resolve('css.css'))
|
||||
expect($('head style[source-path*="css.css"]').attr('source-path')).toBe themeManager.stringToId(atom.project.resolve('css.css'))
|
||||
themeManager.requireStylesheet path.join(__dirname, 'fixtures', 'sample')
|
||||
expect($('head style[id*="sample.less"]').attr('id')).toBe themeManager.stringToId(atom.project.resolve('sample.less'))
|
||||
expect($('head style[source-path*="sample.less"]').attr('source-path')).toBe themeManager.stringToId(atom.project.resolve('sample.less'))
|
||||
|
||||
$('head style[id*="css.css"]').remove()
|
||||
$('head style[id*="sample.less"]').remove()
|
||||
@@ -208,8 +208,8 @@ describe "ThemeManager", ->
|
||||
|
||||
describe "base stylesheet loading", ->
|
||||
beforeEach ->
|
||||
atom.workspaceView = atom.workspace.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView.append $$ -> @div class: 'editor'
|
||||
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView.append $('<atom-text-editor>')
|
||||
atom.workspaceView.attachToDom()
|
||||
|
||||
waitsForPromise ->
|
||||
@@ -217,7 +217,7 @@ describe "ThemeManager", ->
|
||||
|
||||
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'])
|
||||
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
|
||||
|
||||
waitsFor ->
|
||||
reloadHandler.callCount > 0
|
||||
@@ -227,14 +227,14 @@ describe "ThemeManager", ->
|
||||
expect(atom.workspaceView.css("background-color")).toBe "rgb(0, 0, 255)"
|
||||
|
||||
# from within the theme itself
|
||||
expect($(".editor").css("padding-top")).toBe "150px"
|
||||
expect($(".editor").css("padding-right")).toBe "150px"
|
||||
expect($(".editor").css("padding-bottom")).toBe "150px"
|
||||
expect($("atom-text-editor").css("padding-top")).toBe "150px"
|
||||
expect($("atom-text-editor").css("padding-right")).toBe "150px"
|
||||
expect($("atom-text-editor").css("padding-bottom")).toBe "150px"
|
||||
|
||||
describe "when there is a theme with incomplete variables", ->
|
||||
it "loads the correct values from the fallback ui-variables", ->
|
||||
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
|
||||
atom.config.set('core.themes', ['theme-with-incomplete-ui-variables'])
|
||||
atom.config.set('core.themes', ['theme-with-incomplete-ui-variables', 'theme-with-syntax-variables'])
|
||||
|
||||
waitsFor ->
|
||||
reloadHandler.callCount > 0
|
||||
@@ -244,14 +244,14 @@ describe "ThemeManager", ->
|
||||
expect(atom.workspaceView.css("background-color")).toBe "rgb(0, 0, 255)"
|
||||
|
||||
# from within the theme itself
|
||||
expect($(".editor").css("background-color")).toBe "rgb(0, 152, 255)"
|
||||
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'
|
||||
|
||||
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
|
||||
atom.config.set('core.themes', ['theme-with-ui-variables'])
|
||||
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
|
||||
|
||||
waitsFor ->
|
||||
reloadHandler.callCount > 0
|
||||
@@ -259,7 +259,9 @@ 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'
|
||||
|
||||
describe "when the user stylesheet changes", ->
|
||||
it "reloads it", ->
|
||||
@@ -308,24 +310,19 @@ describe "ThemeManager", ->
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
|
||||
describe "when a non-existent theme is present in the config", ->
|
||||
it "logs a warning but does not throw an exception (regression)", ->
|
||||
reloaded = false
|
||||
beforeEach ->
|
||||
spyOn(console, 'warn')
|
||||
atom.config.set('core.themes', ['non-existent-dark-ui', 'non-existent-dark-syntax'])
|
||||
|
||||
waitsForPromise ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
runs ->
|
||||
disposable = themeManager.onDidReloadAll ->
|
||||
disposable.dispose()
|
||||
reloaded = true
|
||||
spyOn(console, 'warn')
|
||||
expect(-> atom.config.set('core.themes', ['atom-light-ui', 'theme-really-does-not-exist'])).not.toThrow()
|
||||
|
||||
waitsFor -> reloaded
|
||||
|
||||
runs ->
|
||||
expect(console.warn.callCount).toBe 1
|
||||
expect(console.warn.argsForCall[0][0].length).toBeGreaterThan 0
|
||||
it 'uses the default dark UI and syntax themes and logs a warning', ->
|
||||
activeThemeNames = themeManager.getActiveNames()
|
||||
expect(console.warn.callCount).toBe 2
|
||||
expect(activeThemeNames.length).toBe(2)
|
||||
expect(activeThemeNames).toContain('atom-dark-ui')
|
||||
expect(activeThemeNames).toContain('atom-dark-syntax')
|
||||
|
||||
describe "when in safe mode", ->
|
||||
beforeEach ->
|
||||
|
||||
@@ -19,16 +19,16 @@ describe "TokenizedLine", ->
|
||||
expect(editor.tokenizedLineForScreenRow(2).isOnlyWhitespace()).toBe false
|
||||
|
||||
describe "::getScopeTree()", ->
|
||||
it "returns a tree whose inner nodes are scopes and whose leaf nodes are tokens in those scopes", ->
|
||||
it "returns a tree whose inner nodes are scopeDescriptor and whose leaf nodes are tokens in those scopeDescriptor", ->
|
||||
[tokens, tokenIndex] = []
|
||||
|
||||
ensureValidScopeTree = (scopeTree, scopes=[]) ->
|
||||
ensureValidScopeTree = (scopeTree, scopeDescriptor=[]) ->
|
||||
if scopeTree.children?
|
||||
for child in scopeTree.children
|
||||
ensureValidScopeTree(child, scopes.concat([scopeTree.scope]))
|
||||
ensureValidScopeTree(child, scopeDescriptor.concat([scopeTree.scope]))
|
||||
else
|
||||
expect(scopeTree).toBe tokens[tokenIndex++]
|
||||
expect(scopes).toEqual scopeTree.scopes
|
||||
expect(scopeDescriptor).toEqual scopeTree.scopes
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.open('coffee.coffee').then (o) -> editor = o
|
||||
|
||||
@@ -47,14 +47,6 @@ describe "Window", ->
|
||||
$(window).trigger 'window:close'
|
||||
expect(atom.close).toHaveBeenCalled()
|
||||
|
||||
it "emits the beforeunload event", ->
|
||||
$(window).off 'beforeunload'
|
||||
beforeunload = jasmine.createSpy('beforeunload').andReturn(false)
|
||||
$(window).on 'beforeunload', beforeunload
|
||||
|
||||
$(window).trigger 'window:close'
|
||||
expect(beforeunload).toHaveBeenCalled()
|
||||
|
||||
describe "beforeunload event", ->
|
||||
[beforeUnloadEvent] = []
|
||||
|
||||
@@ -122,7 +114,7 @@ describe "Window", ->
|
||||
buffer = atom.workspace.getActivePaneItem().buffer
|
||||
pane = atom.workspaceView.getActivePaneView()
|
||||
pane.splitRight(pane.copyActiveItem())
|
||||
expect(atom.workspaceView.find('.editor').length).toBe 2
|
||||
expect(atom.workspaceView.find('atom-text-editor').length).toBe 2
|
||||
|
||||
atom.removeEditorWindow()
|
||||
|
||||
|
||||
@@ -376,7 +376,7 @@ describe "Workspace", ->
|
||||
describe "when the project has no path", ->
|
||||
it "sets the title to 'untitled'", ->
|
||||
atom.project.setPath(undefined)
|
||||
expect(document.title).toBe 'untitled'
|
||||
expect(document.title).toBe 'untitled - Atom'
|
||||
|
||||
describe "when the project has a path", ->
|
||||
beforeEach ->
|
||||
@@ -386,25 +386,25 @@ describe "Workspace", ->
|
||||
describe "when there is an active pane item", ->
|
||||
it "sets the title to the pane item's title plus the project path", ->
|
||||
item = atom.workspace.getActivePaneItem()
|
||||
expect(document.title).toBe "#{item.getTitle()} - #{atom.project.getPaths()[0]}"
|
||||
expect(document.title).toBe "#{item.getTitle()} - #{atom.project.getPaths()[0]} - Atom"
|
||||
|
||||
describe "when the title of the active pane item changes", ->
|
||||
it "updates the window title based on the item's new title", ->
|
||||
editor = atom.workspace.getActivePaneItem()
|
||||
editor.buffer.setPath(path.join(temp.dir, 'hi'))
|
||||
expect(document.title).toBe "#{editor.getTitle()} - #{atom.project.getPaths()[0]}"
|
||||
expect(document.title).toBe "#{editor.getTitle()} - #{atom.project.getPaths()[0]} - Atom"
|
||||
|
||||
describe "when the active pane's item changes", ->
|
||||
it "updates the title to the new item's title plus the project path", ->
|
||||
atom.workspace.getActivePane().activateNextItem()
|
||||
item = atom.workspace.getActivePaneItem()
|
||||
expect(document.title).toBe "#{item.getTitle()} - #{atom.project.getPaths()[0]}"
|
||||
expect(document.title).toBe "#{item.getTitle()} - #{atom.project.getPaths()[0]} - Atom"
|
||||
|
||||
describe "when the last pane item is removed", ->
|
||||
it "updates the title to contain the project's path", ->
|
||||
atom.workspace.getActivePane().destroy()
|
||||
expect(atom.workspace.getActivePaneItem()).toBeUndefined()
|
||||
expect(document.title).toBe atom.project.getPaths()[0]
|
||||
expect(document.title).toBe "#{atom.project.getPaths()[0]} - Atom"
|
||||
|
||||
describe "when an inactive pane's item changes", ->
|
||||
it "does not update the title", ->
|
||||
@@ -422,7 +422,7 @@ describe "Workspace", ->
|
||||
document.title = null
|
||||
workspace2 = atom.workspace.testSerialization()
|
||||
item = atom.workspace.getActivePaneItem()
|
||||
expect(document.title).toBe "#{item.getTitle()} - #{atom.project.getPaths()[0]}"
|
||||
expect(document.title).toBe "#{item.getTitle()} - #{atom.project.getPaths()[0]} - Atom"
|
||||
workspace2.destroy()
|
||||
|
||||
describe "document edited status", ->
|
||||
@@ -456,3 +456,48 @@ describe "Workspace", ->
|
||||
|
||||
expect(item2.isModified()).toBe false
|
||||
expect(atom.setDocumentEdited).toHaveBeenCalledWith(false)
|
||||
|
||||
describe "adding panels", ->
|
||||
class TestPanel
|
||||
constructior: ->
|
||||
|
||||
describe '::addLeftPanel(model)', ->
|
||||
it 'adds a panel to the correct panel container', ->
|
||||
atom.workspace.panelContainers.left.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = atom.workspace.addLeftPanel(item: new TestPanel())
|
||||
|
||||
expect(panel).toBeDefined()
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
|
||||
describe '::addRightPanel(model)', ->
|
||||
it 'adds a panel to the correct panel container', ->
|
||||
atom.workspace.panelContainers.right.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = atom.workspace.addRightPanel(item: new TestPanel())
|
||||
|
||||
expect(panel).toBeDefined()
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
|
||||
describe '::addTopPanel(model)', ->
|
||||
it 'adds a panel to the correct panel container', ->
|
||||
atom.workspace.panelContainers.top.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = atom.workspace.addTopPanel(item: new TestPanel())
|
||||
|
||||
expect(panel).toBeDefined()
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
|
||||
describe '::addBottomPanel(model)', ->
|
||||
it 'adds a panel to the correct panel container', ->
|
||||
atom.workspace.panelContainers.bottom.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = atom.workspace.addBottomPanel(item: new TestPanel())
|
||||
|
||||
expect(panel).toBeDefined()
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
|
||||
describe '::addModalPanel(model)', ->
|
||||
it 'adds a panel to the correct panel container', ->
|
||||
atom.workspace.panelContainers.modal.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = atom.workspace.addModalPanel(item: new TestPanel())
|
||||
|
||||
expect(panel).toBeDefined()
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
expect(panel.getClassName()).toBe 'overlay from-top' # the default
|
||||
|
||||
@@ -13,7 +13,7 @@ describe "WorkspaceView", ->
|
||||
atom.project.setPaths([atom.project.resolve('dir')])
|
||||
pathToOpen = atom.project.resolve('a')
|
||||
atom.workspace = new Workspace
|
||||
atom.workspaceView = atom.workspace.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView.enableKeymap()
|
||||
atom.workspaceView.focus()
|
||||
|
||||
@@ -29,7 +29,7 @@ describe "WorkspaceView", ->
|
||||
atom.workspaceView.remove()
|
||||
atom.project = atom.deserializers.deserialize(projectState)
|
||||
atom.workspace = Workspace.deserialize(workspaceState)
|
||||
atom.workspaceView = atom.workspace.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView.attachToDom()
|
||||
|
||||
describe "when the serialized WorkspaceView has an unsaved buffer", ->
|
||||
@@ -49,7 +49,7 @@ describe "WorkspaceView", ->
|
||||
|
||||
expect(atom.workspaceView.getEditorViews().length).toBe 2
|
||||
expect(atom.workspaceView.getActivePaneView()).toBe atom.workspaceView.getPaneViews()[1]
|
||||
expect(document.title).toBe "untitled - #{atom.project.getPaths()[0]}"
|
||||
expect(document.title).toBe "untitled - #{atom.project.getPaths()[0]} - Atom"
|
||||
|
||||
describe "when there are open editors", ->
|
||||
it "constructs the view with the same panes", ->
|
||||
@@ -82,10 +82,10 @@ describe "WorkspaceView", ->
|
||||
simulateReload()
|
||||
|
||||
expect(atom.workspaceView.getEditorViews().length).toBe 4
|
||||
editorView1 = atom.workspaceView.panes.find('.pane-row > .pane .editor:eq(0)').view()
|
||||
editorView3 = atom.workspaceView.panes.find('.pane-row > .pane .editor:eq(1)').view()
|
||||
editorView2 = atom.workspaceView.panes.find('.pane-row > .pane-column > .pane .editor:eq(0)').view()
|
||||
editorView4 = atom.workspaceView.panes.find('.pane-row > .pane-column > .pane .editor:eq(1)').view()
|
||||
editorView1 = atom.workspaceView.panes.find('atom-pane-axis.horizontal > atom-pane atom-text-editor:eq(0)').view()
|
||||
editorView3 = atom.workspaceView.panes.find('atom-pane-axis.horizontal > atom-pane atom-text-editor:eq(1)').view()
|
||||
editorView2 = atom.workspaceView.panes.find('atom-pane-axis.horizontal > atom-pane-axis.vertical > atom-pane atom-text-editor:eq(0)').view()
|
||||
editorView4 = atom.workspaceView.panes.find('atom-pane-axis.horizontal > atom-pane-axis.vertical > atom-pane atom-text-editor:eq(1)').view()
|
||||
|
||||
expect(editorView1.getEditor().getPath()).toBe atom.project.resolve('a')
|
||||
expect(editorView2.getEditor().getPath()).toBe atom.project.resolve('b')
|
||||
@@ -106,7 +106,7 @@ describe "WorkspaceView", ->
|
||||
expect(editorView3).not.toHaveFocus()
|
||||
expect(editorView4).not.toHaveFocus()
|
||||
|
||||
expect(document.title).toBe "#{path.basename(editorView2.getEditor().getPath())} - #{atom.project.getPaths()[0]}"
|
||||
expect(document.title).toBe "#{path.basename(editorView2.getEditor().getPath())} - #{atom.project.getPaths()[0]} - Atom"
|
||||
|
||||
describe "where there are no open editors", ->
|
||||
it "constructs the view with no open editors", ->
|
||||
@@ -127,15 +127,11 @@ describe "WorkspaceView", ->
|
||||
expect(activePane).toHaveFocus()
|
||||
|
||||
describe "keymap wiring", ->
|
||||
commandHandler = null
|
||||
beforeEach ->
|
||||
commandHandler = jasmine.createSpy('commandHandler')
|
||||
atom.workspaceView.on('foo-command', commandHandler)
|
||||
|
||||
atom.keymaps.add('name', '*': {'x': 'foo-command'})
|
||||
|
||||
describe "when a keydown event is triggered in the WorkspaceView", ->
|
||||
it "triggers matching keybindings for that event", ->
|
||||
commandHandler = jasmine.createSpy('commandHandler')
|
||||
atom.workspaceView.on('foo-command', commandHandler)
|
||||
atom.keymaps.add('name', '*': {'x': 'foo-command'})
|
||||
event = keydownEvent 'x', target: atom.workspaceView[0]
|
||||
|
||||
atom.workspaceView.trigger(event)
|
||||
@@ -252,8 +248,8 @@ describe "WorkspaceView", ->
|
||||
|
||||
beforeEach ->
|
||||
atom.workspaceView.attachToDom()
|
||||
editorNode = atom.workspaceView.find('.editor')[0]
|
||||
editor = atom.workspaceView.find('.editor').view().getEditor()
|
||||
editorNode = atom.workspaceView.find('atom-text-editor')[0]
|
||||
editor = atom.workspaceView.find('atom-text-editor').view().getEditor()
|
||||
|
||||
it "updates the font-size based on the 'editor.fontSize' config value", ->
|
||||
initialCharWidth = editor.getDefaultCharWidth()
|
||||
@@ -274,3 +270,22 @@ describe "WorkspaceView", ->
|
||||
atom.config.set('editor.lineHeight', '30px')
|
||||
expect(getComputedStyle(editorNode).lineHeight).toBe atom.config.get('editor.lineHeight')
|
||||
expect(editor.getLineHeightInPixels()).not.toBe initialLineHeight
|
||||
|
||||
describe 'panel containers', ->
|
||||
workspaceElement = null
|
||||
beforeEach ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
|
||||
it 'inserts panel container elements in the correct places in the DOM', ->
|
||||
leftContainer = workspaceElement.querySelector('atom-panel-container[location="left"]')
|
||||
rightContainer = workspaceElement.querySelector('atom-panel-container[location="right"]')
|
||||
expect(leftContainer.nextSibling).toBe workspaceElement.verticalAxis
|
||||
expect(rightContainer.previousSibling).toBe workspaceElement.verticalAxis
|
||||
|
||||
topContainer = workspaceElement.querySelector('atom-panel-container[location="top"]')
|
||||
bottomContainer = workspaceElement.querySelector('atom-panel-container[location="bottom"]')
|
||||
expect(topContainer.nextSibling).toBe workspaceElement.paneContainer
|
||||
expect(bottomContainer.previousSibling).toBe workspaceElement.paneContainer
|
||||
|
||||
modalContainer = workspaceElement.querySelector('atom-panel-container[location="modal"]')
|
||||
expect(modalContainer.parentNode).toBe workspaceElement
|
||||
|
||||
+29
-4
@@ -14,6 +14,7 @@ fs = require 'fs-plus'
|
||||
|
||||
{$} = require './space-pen-extensions'
|
||||
WindowEventHandler = require './window-event-handler'
|
||||
StylesElement = require './styles-element'
|
||||
|
||||
# Essential: Atom global for dealing with packages, themes, menus, and the window.
|
||||
#
|
||||
@@ -29,7 +30,10 @@ class Atom extends Model
|
||||
#
|
||||
# Returns an Atom instance, fully initialized
|
||||
@loadOrCreate: (mode) ->
|
||||
@deserialize(@loadState(mode)) ? new this({mode, @version})
|
||||
startTime = Date.now()
|
||||
atom = @deserialize(@loadState(mode)) ? new this({mode, @version})
|
||||
atom.deserializeTimings.atom = Date.now() - startTime
|
||||
atom
|
||||
|
||||
# Deserializes the Atom environment from a state object
|
||||
@deserialize: (state) ->
|
||||
@@ -103,7 +107,7 @@ class Atom extends Model
|
||||
Section: Properties
|
||||
###
|
||||
|
||||
# Experimental: A {CommandRegistry} instance
|
||||
# Public: A {CommandRegistry} instance
|
||||
commands: null
|
||||
|
||||
# Public: A {Config} instance
|
||||
@@ -136,6 +140,9 @@ class Atom extends Model
|
||||
# Public: A {DeserializerManager} instance
|
||||
deserializers: null
|
||||
|
||||
# Public: A {ViewRegistry} instance
|
||||
views: null
|
||||
|
||||
# Public: A {Workspace} instance
|
||||
workspace: null
|
||||
|
||||
@@ -152,6 +159,7 @@ class Atom extends Model
|
||||
{@mode} = @state
|
||||
DeserializerManager = require './deserializer-manager'
|
||||
@deserializers = new DeserializerManager()
|
||||
@deserializeTimings = {}
|
||||
|
||||
# Sets up the basic services that should be available in all modes
|
||||
# (both spec and application).
|
||||
@@ -169,6 +177,7 @@ class Atom extends Model
|
||||
@executeJavaScriptInDevTools('InspectorFrontendAPI.showConsole()')
|
||||
@lastUncaughtError = Array::slice.call(arguments)
|
||||
@emit 'uncaught-error', arguments...
|
||||
@emitter.emit 'did-throw-error', arguments...
|
||||
|
||||
@unsubscribe()
|
||||
@setBodyPlatformClass()
|
||||
@@ -177,11 +186,13 @@ class Atom extends Model
|
||||
|
||||
Config = require './config'
|
||||
KeymapManager = require './keymap-extensions'
|
||||
ViewRegistry = require './view-registry'
|
||||
CommandRegistry = require './command-registry'
|
||||
PackageManager = require './package-manager'
|
||||
Clipboard = require './clipboard'
|
||||
Syntax = require './syntax'
|
||||
ThemeManager = require './theme-manager'
|
||||
StyleManager = require './style-manager'
|
||||
ContextMenuManager = require './context-menu-manager'
|
||||
MenuManager = require './menu-manager'
|
||||
{devMode, safeMode, resourcePath} = @getLoadSettings()
|
||||
@@ -196,11 +207,17 @@ class Atom extends Model
|
||||
# Make react.js faster
|
||||
process.env.NODE_ENV ?= 'production' unless devMode
|
||||
|
||||
# Set Atom's home so packages don't have to guess it
|
||||
process.env.ATOM_HOME = configDirPath
|
||||
|
||||
@config = new Config({configDirPath, resourcePath})
|
||||
@keymaps = new KeymapManager({configDirPath, resourcePath})
|
||||
@keymap = @keymaps # Deprecated
|
||||
@commands = new CommandRegistry
|
||||
@views = new ViewRegistry
|
||||
@packages = new PackageManager({devMode, configDirPath, resourcePath, safeMode})
|
||||
@styles = new StyleManager
|
||||
document.head.appendChild(new StylesElement)
|
||||
@themes = new ThemeManager({packageManager: @packages, configDirPath, resourcePath, safeMode})
|
||||
@contextMenu = new ContextMenuManager({resourcePath, devMode})
|
||||
@menu = new MenuManager({resourcePath})
|
||||
@@ -231,6 +248,15 @@ class Atom extends Model
|
||||
onDidBeep: (callback) ->
|
||||
@emitter.on 'did-beep', callback
|
||||
|
||||
# Extended: Invoke the given callback whenever there is an unhandled error.
|
||||
#
|
||||
# * `callback` {Function} to be called whenever there is an unhandled error
|
||||
# * `errorMessage` {String}
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
|
||||
onDidThrowError: (callback) ->
|
||||
@emitter.on 'did-throw-error', callback
|
||||
|
||||
###
|
||||
Section: Atom Details
|
||||
###
|
||||
@@ -586,7 +612,7 @@ class Atom extends Model
|
||||
|
||||
startTime = Date.now()
|
||||
@workspace = Workspace.deserialize(@state.workspace) ? new Workspace
|
||||
@workspaceView = @workspace.getView(@workspace).__spacePenView
|
||||
@workspaceView = @views.getView(@workspace).__spacePenView
|
||||
@deserializeTimings.workspace = Date.now() - startTime
|
||||
|
||||
@keymaps.defaultTarget = @workspaceView[0]
|
||||
@@ -597,7 +623,6 @@ class Atom extends Model
|
||||
delete @state.packageStates
|
||||
|
||||
deserializeEditorWindow: ->
|
||||
@deserializeTimings = {}
|
||||
@deserializePackageStates()
|
||||
@deserializeProject()
|
||||
@deserializeWorkspaceView()
|
||||
|
||||
@@ -10,24 +10,48 @@ _ = require 'underscore-plus'
|
||||
module.exports =
|
||||
class ApplicationMenu
|
||||
constructor: (@version) ->
|
||||
@menu = Menu.buildFromTemplate @getDefaultTemplate()
|
||||
Menu.setApplicationMenu @menu
|
||||
@windowTemplates = new WeakMap()
|
||||
@setActiveTemplate(@getDefaultTemplate())
|
||||
global.atomApplication.autoUpdateManager.on 'state-changed', (state) =>
|
||||
@showUpdateMenuItem(state)
|
||||
|
||||
# Public: Updates the entire menu with the given keybindings.
|
||||
#
|
||||
# window - The BrowserWindow this menu template is associated with.
|
||||
# template - The Object which describes the menu to display.
|
||||
# keystrokesByCommand - An Object where the keys are commands and the values
|
||||
# are Arrays containing the keystroke.
|
||||
update: (template, keystrokesByCommand) ->
|
||||
update: (window, template, keystrokesByCommand) ->
|
||||
@translateTemplate(template, keystrokesByCommand)
|
||||
@substituteVersion(template)
|
||||
@menu = Menu.buildFromTemplate(template)
|
||||
Menu.setApplicationMenu(@menu)
|
||||
@windowTemplates.set(window, template)
|
||||
@setActiveTemplate(template) if window is @lastFocusedWindow
|
||||
|
||||
setActiveTemplate: (template) ->
|
||||
unless _.isEqual(template, @activeTemplate)
|
||||
@activeTemplate = template
|
||||
@menu = Menu.buildFromTemplate(_.deepClone(template))
|
||||
Menu.setApplicationMenu(@menu)
|
||||
|
||||
@showUpdateMenuItem(global.atomApplication.autoUpdateManager.getState())
|
||||
|
||||
# Register a BrowserWindow with this application menu.
|
||||
addWindow: (window) ->
|
||||
@lastFocusedWindow ?= window
|
||||
|
||||
focusHandler = =>
|
||||
@lastFocusedWindow = window
|
||||
if template = @windowTemplates.get(window)
|
||||
@setActiveTemplate(template)
|
||||
|
||||
window.on 'focus', focusHandler
|
||||
window.once 'closed', =>
|
||||
@lastFocusedWindow = null if window is @lastFocusedWindow
|
||||
@windowTemplates.delete(window)
|
||||
window.removeListener 'focus', focusHandler
|
||||
|
||||
@enableWindowSpecificItems(true)
|
||||
|
||||
# Flattens the given menu and submenu items into an single Array.
|
||||
#
|
||||
# menu - A complete menu configuration object for atom-shell's menu API.
|
||||
|
||||
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