Comparar commits
1262 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 834176f7b7 | |||
| 3f3284a8db | |||
| ff308d366c | |||
| 04c0824822 | |||
| f38fb2a924 | |||
| 04caea9bb0 | |||
| f39114a95c | |||
| 435e081402 | |||
| 36aa3834d3 | |||
| 50a751b8e6 | |||
| 40570c0b99 | |||
| 025c6111b3 | |||
| 667315aff5 | |||
| c1f8065caf | |||
| 70e1d14f96 | |||
| 7625e5352d | |||
| 6e3c945fa2 | |||
| f8b17b6b3c | |||
| d55f5cba78 | |||
| f0a19e3f67 | |||
| 465c13e292 | |||
| be1d4ee5dc | |||
| 238cf60882 | |||
| 60a3cebfab | |||
| 8f8165e289 | |||
| d3b3fdefc9 | |||
| 49937b2956 | |||
| 40b32930cf | |||
| 61fa1c4230 | |||
| 6a0a842de4 | |||
| c141448e9f | |||
| 61166bf365 | |||
| 9c24e5a23d | |||
| 883f7e1f5a | |||
| d9b1b7b399 | |||
| d1bdda5b3e | |||
| a3f3b7e032 | |||
| 3228de7ead | |||
| 5a64b09924 | |||
| b0c17aa98f | |||
| 9f5f4f2c10 | |||
| 335339ef61 | |||
| 291bf7fe08 | |||
| 40eaf69ab0 | |||
| 55ac855de1 | |||
| 2e219f288d | |||
| 09fbd46869 | |||
| 10ceb34426 | |||
| 5ba5215f5d | |||
| 3bf348e51f | |||
| 0afd8a1392 | |||
| 55b5debd7f | |||
| 229277f764 | |||
| af1b0b5736 | |||
| ae4f92cc52 | |||
| 66b27ad52a | |||
| dddd17c11b | |||
| 05f54d427d | |||
| ffbb18a0f8 | |||
| b6fe72ef9e | |||
| 4070e5fb25 | |||
| ed4acb02d8 | |||
| ab96e5b5fd | |||
| f357f694b3 | |||
| 2a02375c4d | |||
| e452b88fec | |||
| 0f83fe54f9 | |||
| 3e5666f183 | |||
| 260f72d2b5 | |||
| 84deefb6b1 | |||
| 5afceb3951 | |||
| 72be16736c | |||
| 789d9c8eff | |||
| 858ac5bf79 | |||
| 9db804b413 | |||
| c7525e8cff | |||
| 7198a919bf | |||
| aebdfb4cf6 | |||
| 7b1f8cc7da | |||
| 17aa6f958c | |||
| 3e10f491b4 | |||
| 3487ab9b11 | |||
| f6545d4002 | |||
| 408cac4632 | |||
| bb5a440651 | |||
| 5883e27c60 | |||
| 1d073173d4 | |||
| 601b311496 | |||
| d4835e1d8e | |||
| 6f9f087e11 | |||
| b6a9e1b576 | |||
| efea16848a | |||
| 8aa1784c4a | |||
| 2d3ae1b44d | |||
| efc730dc2f | |||
| 70dd3675e6 | |||
| 30ae93b9d9 | |||
| aa5a094cbe | |||
| ab75f3122f | |||
| 359491fc3f | |||
| 444eb0e5e5 | |||
| 522d446366 | |||
| f8949adf38 | |||
| 01d62653f2 | |||
| 35a48f0cfb | |||
| f7103bbed6 | |||
| 7e6b7ada54 | |||
| 5e2f8a3ae3 | |||
| 4bda13ec74 | |||
| 42f3605465 | |||
| e7e4196fa6 | |||
| 68801aacdb | |||
| 13956edfb5 | |||
| 3a7564b59e | |||
| 4e0928600f | |||
| 417134c799 | |||
| b2638c8bad | |||
| 27bf096fbc | |||
| 4fa6f631a9 | |||
| 6e7968861d | |||
| fc59d9c503 | |||
| 163b52efb0 | |||
| d4ed8a0b73 | |||
| d7106a6b4c | |||
| 4b867ddc7a | |||
| b5dfaff426 | |||
| 7eba55d009 | |||
| abbb21bf47 | |||
| ff4d4f047f | |||
| 9e21ea39bd | |||
| 11dbee0290 | |||
| de4936efc8 | |||
| 846d81abf5 | |||
| a8e4638612 | |||
| 4134f5efe4 | |||
| 1c5acc059e | |||
| c01a24f293 | |||
| 571ce5bddd | |||
| 5237e687ee | |||
| fe74dfdf4e | |||
| 250c21f00a | |||
| e6dbea09fe | |||
| 47ef54a072 | |||
| 86e9778adb | |||
| aeffef30c6 | |||
| 7ae25d34e7 | |||
| e6e6028683 | |||
| f3e8f11d07 | |||
| 6e8a626de2 | |||
| 21e4d8a064 | |||
| 733e06fa8c | |||
| db84b7952c | |||
| 557562d8c8 | |||
| b1fdb48e9e | |||
| 0a920b18d7 | |||
| 289b22c782 | |||
| 6d498aad3b | |||
| 53fbfb8b27 | |||
| a2adbff3e9 | |||
| 48a68d87f5 | |||
| bcc6adff4f | |||
| 9435f852dd | |||
| 569c403d56 | |||
| 6ad9531e5c | |||
| 56687027b6 | |||
| 6bd8702421 | |||
| c69b5fc0a0 | |||
| 1131b33a83 | |||
| 651eb78315 | |||
| 3e77b9b7c0 | |||
| e77b4a54dd | |||
| 3b6e40fbd8 | |||
| 161edfd15a | |||
| 2a81687d38 | |||
| 05ea381c0a | |||
| 63c9da02f6 | |||
| 5a02303b58 | |||
| 1c95a55740 | |||
| 3e260eea56 | |||
| 965afc2c37 | |||
| d15d1572ef | |||
| 133f3f45ab | |||
| b731f7cbdc | |||
| 8f6053c53f | |||
| 0c749537a1 | |||
| f6bb7fc089 | |||
| 805c621ac6 | |||
| 7fe567521e | |||
| e48748122f | |||
| 1291cf19fb | |||
| 336afc32c2 | |||
| a81393320c | |||
| 3e407296ad | |||
| 7c8451e178 | |||
| 90592a70be | |||
| 914e4e6342 | |||
| 86e623e9db | |||
| 70df5a5c0a | |||
| dba1e22ded | |||
| dc21e8707f | |||
| 52c19a5dcd | |||
| 5ae040f688 | |||
| c511a71488 | |||
| 04b0ed9704 | |||
| 2c9241506b | |||
| 326f5fc646 | |||
| 705c57158d | |||
| a50f62dc93 | |||
| eb9d4ba816 | |||
| 6cb085b341 | |||
| 1ffe459b1e | |||
| effe7e8070 | |||
| b5676adf8a | |||
| 1909f24d5c | |||
| a947a357f4 | |||
| d8be03850b | |||
| 641698330f | |||
| 55913626cc | |||
| af2f155082 | |||
| b9e90f2fdd | |||
| 621c247a75 | |||
| 2f6f374cc7 | |||
| aac64e3a9b | |||
| 9de0ba17b2 | |||
| 57699e6245 | |||
| 8a6e72f21f | |||
| 0f912c97b9 | |||
| 4946eec367 | |||
| db571a2fbf | |||
| 22c62b3107 | |||
| 83327eeabb | |||
| 8e286194f1 | |||
| 691c7ee585 | |||
| 48b693c1c1 | |||
| 7a3893c7bb | |||
| 06165b2167 | |||
| f82c59d865 | |||
| 29f15d0f20 | |||
| 99c07decf2 | |||
| 851034c8d3 | |||
| 3a85148f69 | |||
| f87f7c358a | |||
| df579a9295 | |||
| b90670ff2d | |||
| 67dc703c18 | |||
| c508f76af0 | |||
| a8c1f2d0a5 | |||
| 7ad992e52f | |||
| 87fb0b46f7 | |||
| 873818ee52 | |||
| 523a255e48 | |||
| 5e21d1ca5b | |||
| 0703788209 | |||
| c0c941b8db | |||
| e3a0339fe3 | |||
| c4265776b3 | |||
| ae49fd50b7 | |||
| cdbbec91f0 | |||
| dbb0ff9830 | |||
| 99f899dc4a | |||
| 2b9b4a48ef | |||
| b516f5a74d | |||
| 05bbc480b0 | |||
| c0e2ed4282 | |||
| d3c2cd756a | |||
| 1ff9da5f7a | |||
| d3422786c3 | |||
| ebbfaa23ce | |||
| 29ad748aa4 | |||
| d753a7f38d | |||
| 1e4fb5b4bc | |||
| cfd2722348 | |||
| ae0bffc4ea | |||
| 3d8f3883d1 | |||
| 81532d52f7 | |||
| 0b34e46a1a | |||
| 539e4e0745 | |||
| 1f925078e9 | |||
| a564da1eb0 | |||
| dca36d1307 | |||
| 3f67252757 | |||
| a7db555030 | |||
| 3bd7edb94e | |||
| a9227b5f43 | |||
| 659c05c825 | |||
| 5ea64f8b11 | |||
| 70af6198bd | |||
| 1aa391a207 | |||
| 03a6d10703 | |||
| 24add494ae | |||
| c5aa446bc2 | |||
| fbcef99aac | |||
| 8fa8519924 | |||
| 5a36988930 | |||
| 65cae0f68d | |||
| 7f14965ca8 | |||
| 8c36d2673b | |||
| 7f2d9984b8 | |||
| d43702f017 | |||
| 690d32cca9 | |||
| d870cb8f36 | |||
| 7cd080786c | |||
| a8a251c457 | |||
| 9574458feb | |||
| 692bf534b6 | |||
| f35346c507 | |||
| 78f7ff6ee7 | |||
| 71470f88ad | |||
| 4b4af946cf | |||
| 5163d0f810 | |||
| 08388d87c0 | |||
| 9c53d6f014 | |||
| c9e5ff6606 | |||
| 2fced0c1bc | |||
| 271af5dd99 | |||
| 6c2bb26e77 | |||
| 70a23b0107 | |||
| c6a76e6c62 | |||
| 535724fa84 | |||
| 14dcf50683 | |||
| 882261e782 | |||
| acb9bdaf33 | |||
| 713d82a895 | |||
| a33706ddbc | |||
| 2551313b58 | |||
| 877fa40a49 | |||
| cee7539e35 | |||
| 7ca5ece68a | |||
| 5471e9bccc | |||
| b60b9f3e3a | |||
| 12f78dd957 | |||
| e74244fc25 | |||
| 65ba95a449 | |||
| 370ad23f7c | |||
| cea4db5381 | |||
| 345617e0f3 | |||
| 78c24fb737 | |||
| 01b48d2a0a | |||
| 45a9bd21fc | |||
| db83375293 | |||
| a4a25576a2 | |||
| e88eb3012e | |||
| d7063c0932 | |||
| 34cb5d6012 | |||
| 95e9686b37 | |||
| b1916069de | |||
| 9223361c22 | |||
| 7556b85806 | |||
| b74554ad4c | |||
| b34367ad44 | |||
| cf3e1177ab | |||
| 74b2f26540 | |||
| b89202f82c | |||
| 9487609f0c | |||
| da63c6bab2 | |||
| a00b3b2cc9 | |||
| 0888d8ac60 | |||
| b895f7074d | |||
| 7b73d6749d | |||
| 67c3a41a60 | |||
| c25ab0db43 | |||
| 9979ae4b09 | |||
| a9294aebc3 | |||
| f161f5352e | |||
| 4f826a70f8 | |||
| 1d365db9df | |||
| b9feed8eb4 | |||
| 475dc6074c | |||
| 40d93cd0cf | |||
| 99d70b4a4e | |||
| 87cdc1a45d | |||
| e7a7e86dea | |||
| b6c669a292 | |||
| 44d70aaa5b | |||
| 2b63f8a4ee | |||
| 8225f759bf | |||
| 2d58d9c8b5 | |||
| 548018e9b2 | |||
| 9bd2eec4bc | |||
| b8fcbe9451 | |||
| 861dff107a | |||
| ebb02bcd37 | |||
| fcb72049e1 | |||
| 039e61e960 | |||
| 002f9ca2b1 | |||
| 726b04ef80 | |||
| 20b64dd744 | |||
| a3d2924484 | |||
| d225966374 | |||
| 6d23fa1620 | |||
| 682d84dea0 | |||
| 969e5b65df | |||
| 8e5f4ced21 | |||
| bbdd304834 | |||
| 5360b719f2 | |||
| 17a9e397f3 | |||
| f01f0eb90b | |||
| 53d16098ca | |||
| cb34539508 | |||
| 1221a140aa | |||
| 776a8e935a | |||
| 096255f283 | |||
| 327749b6c5 | |||
| cd3bd048fd | |||
| d79807fbe5 | |||
| 7a67619216 | |||
| 496e49a5b9 | |||
| 08decbe533 | |||
| 37fc8b5945 | |||
| f88c805466 | |||
| e8cd59eaef | |||
| 600005de15 | |||
| aaa788b8da | |||
| 9a70fdc3d9 | |||
| 48f161b63a | |||
| f032dacebb | |||
| a296364e53 | |||
| 5ba86b3dbc | |||
| 790f134d7c | |||
| 32353a31eb | |||
| 0bae432109 | |||
| d8a4280df1 | |||
| dccb2c295c | |||
| 2a94e4a33c | |||
| 3371ceadf3 | |||
| 070ca1a4bb | |||
| 157a753bfb | |||
| 0849f1ea84 | |||
| c4f5a3516b | |||
| 08f39c6a5a | |||
| 69aa34954f | |||
| d6d7d3942c | |||
| c3acd8cf0c | |||
| 12f58f0478 | |||
| 66e6a481a4 | |||
| de27dce6bf | |||
| 6c19a58c7c | |||
| c294208f87 | |||
| d7f3add250 | |||
| a93ef05e13 | |||
| 8241918b6e | |||
| 8aae7b983e | |||
| ad4f464d7c | |||
| 352f1e34ab | |||
| 2cdae3c6c1 | |||
| 5df944e804 | |||
| 762f8c2e5a | |||
| 41c96a82a9 | |||
| 5a51d3a0c9 | |||
| d79eb8eed3 | |||
| 9bb6bdf666 | |||
| 0ab282340f | |||
| 393f6bdd35 | |||
| a4b2f3aa4b | |||
| ee4c7e996f | |||
| 59bf16fed3 | |||
| 99917a536e | |||
| 61a82fa0e4 | |||
| 0bca0810b9 | |||
| 7d910000a2 | |||
| af67671f60 | |||
| 0079007bb6 | |||
| c2fa20c543 | |||
| aa5870570f | |||
| 0e0d62b54c | |||
| 37542e3117 | |||
| 90e89ebaf9 | |||
| e4939a8d6d | |||
| 50ddb8e3cc | |||
| c61e36c7d3 | |||
| 3035242daf | |||
| cfc965c135 | |||
| 1bc879a9b0 | |||
| 6225acbe8b | |||
| bdf68ba15f | |||
| bbef8083d5 | |||
| f2f88cb343 | |||
| a42de1e9be | |||
| 1c97eb977e | |||
| d13fd495e4 | |||
| c49ef1fd9d | |||
| e011be3428 | |||
| f993b78479 | |||
| 86ef06ebb1 | |||
| 9f27e53bf1 | |||
| 720770e2ba | |||
| e86b8c1a66 | |||
| 3b9d25ae92 | |||
| 9ee6a3d430 | |||
| 162713e5b5 | |||
| 83659272ac | |||
| abadc9805c | |||
| ad269357b7 | |||
| ae323d2083 | |||
| cef24a3979 | |||
| 7220c61e98 | |||
| 6e40f3b2f9 | |||
| c4811a8fb7 | |||
| c7242ec964 | |||
| d37bd14a62 | |||
| 3d2d8c491f | |||
| b05a83a6ce | |||
| 0d68430bb8 | |||
| d75485a2d8 | |||
| e54bc0fbaa | |||
| cf9208bc02 | |||
| 35fd19f3ef | |||
| 97bcdcc9b0 | |||
| fc441ef5e2 | |||
| 01c4fe5340 | |||
| 431fab1a43 | |||
| 0e62c98768 | |||
| f8026bb005 | |||
| ef889a50ed | |||
| c3c91ae6c3 | |||
| c073d042b8 | |||
| ecf237697b | |||
| 4b8fd222f1 | |||
| 62a1888c6b | |||
| 176d73dfcc | |||
| c0704edb0d | |||
| fb53f85573 | |||
| 6610447e09 | |||
| 9f7560bb89 | |||
| a853a27857 | |||
| 154fe4006f | |||
| 17feb91876 | |||
| 5bdf8a14a7 | |||
| 1196e5a264 | |||
| a4ae314b00 | |||
| c9390b61de | |||
| 2811663177 | |||
| 4dc89f1b1e | |||
| b0a9eefa04 | |||
| aa9728c004 | |||
| dc55d42491 | |||
| d3b06542a5 | |||
| 9c154a2f5a | |||
| 6b1868efd5 | |||
| e50887aab8 | |||
| c6ca03fa49 | |||
| a15deaef81 | |||
| 461cca2d22 | |||
| d15728321c | |||
| 9164b0ea3b | |||
| 59a80dcd60 | |||
| 72354ebf32 | |||
| a56cea2408 | |||
| cc28eaf6d2 | |||
| 283c76ad3c | |||
| a71a524ec7 | |||
| a2f7ec9d73 | |||
| 26d696a93d | |||
| 30aa47026d | |||
| ec6bfbb9e6 | |||
| d986ab0293 | |||
| c7f5321d14 | |||
| cb868bab4c | |||
| 024d7f8d88 | |||
| 1022d8ab4b | |||
| 760e6c6c29 | |||
| beae15ef7f | |||
| 5cb084d568 | |||
| f72daffdbb | |||
| 4aba8fef7e | |||
| 75853e2f9c | |||
| 3baeb3797f | |||
| 7d0452f093 | |||
| 7edcadb50a | |||
| fc198b6e17 | |||
| 86f8944aaf | |||
| dda0e7f4ce | |||
| e1ff6ab327 | |||
| 2b87f4bcb5 | |||
| 3190c0c517 | |||
| a1d8ee86f9 | |||
| ebbea64b3d | |||
| a20f04149c | |||
| b46e03437c | |||
| ccd32cd084 | |||
| 6b5d16173b | |||
| 237d71417d | |||
| 590bfa0c86 | |||
| 881c21829b | |||
| 34f96b2ea2 | |||
| c989557b5e | |||
| 0a07e862c2 | |||
| 0eaec57f7b | |||
| 5873a03145 | |||
| 3ff8f35863 | |||
| 6c52bcf20c | |||
| 5975548cec | |||
| 3742dadbb9 | |||
| 919f541685 | |||
| 8bebfdb871 | |||
| cda8382902 | |||
| dfbf0de961 | |||
| 4a9e397be0 | |||
| e10a578c04 | |||
| 2bd8456923 | |||
| c5f0126078 | |||
| 28500e189b | |||
| a62e90820d | |||
| 853e8e8f17 | |||
| 1da47dbbbd | |||
| f96ac09c36 | |||
| d6852cab15 | |||
| 75f01f87da | |||
| f901007892 | |||
| a7a6236b26 | |||
| ef47bdab3f | |||
| 8cf999f73b | |||
| 20b44500d1 | |||
| e0ebc661f2 | |||
| d38711e2bf | |||
| 753f47ef21 | |||
| e202ecd1b6 | |||
| 02557d36c2 | |||
| eabad3dcef | |||
| 6ad099260e | |||
| ebfd921807 | |||
| 83c77b6e4b | |||
| cbe5593381 | |||
| 32e59ce238 | |||
| 654a4392a4 | |||
| 8457c74f2f | |||
| 88366cb5d4 | |||
| c70c819aa2 | |||
| 4ac8aba31f | |||
| 776e431cc5 | |||
| 5a966240b9 | |||
| 27f0c525ac | |||
| 00170804e5 | |||
| d7e5f05f83 | |||
| 3ce641f53b | |||
| 27ca957629 | |||
| 84d0abc52c | |||
| 41c62e8628 | |||
| 1515690302 | |||
| 2be658b894 | |||
| d3e1c004fb | |||
| 62924dfcd1 | |||
| 770e97efff | |||
| 2704d2f15a | |||
| 957e45944a | |||
| 16fd14d295 | |||
| 20daed176b | |||
| 8c11c4a4c6 | |||
| 7cb44b69ef | |||
| d37cfb9042 | |||
| 986753981d | |||
| 970bde9361 | |||
| 7b55946abf | |||
| c74f6bb615 | |||
| 63f2ab3088 | |||
| 742ec6df0d | |||
| 864f9bc2b4 | |||
| 73896d100e | |||
| 193001d793 | |||
| 052f9580f2 | |||
| 2daf70f0e5 | |||
| fca9ed07e6 | |||
| e725a8ffeb | |||
| 23c67c53dc | |||
| c6fc0d050d | |||
| 6e913c47ef | |||
| a245624211 | |||
| 8af8caca55 | |||
| bbeb4be5b1 | |||
| 449da91216 | |||
| 521647e8ac | |||
| d863638c24 | |||
| 651df12f9b | |||
| 83706647d1 | |||
| 59fb4a839e | |||
| 04e23f581a | |||
| 4574a9e35d | |||
| a2eb4d9303 | |||
| c0a845bc56 | |||
| 1ace5a313c | |||
| 161eb3c3d2 | |||
| 6632a1c63d | |||
| ce5eff100c | |||
| 1bf9e14f9f | |||
| 94f40f0ed9 | |||
| 640881a15e | |||
| ee6c4d7b65 | |||
| a37aeba909 | |||
| 2449fda01d | |||
| b572594f92 | |||
| fbde059748 | |||
| 6084ef52e7 | |||
| a9f4dfc6b7 | |||
| 8032d6dab2 | |||
| 01ec449fce | |||
| e79d66497c | |||
| a205c6d190 | |||
| 2911b395ee | |||
| 64c25f17df | |||
| 9d3082ec95 | |||
| 034a377c5e | |||
| f0fbdc9842 | |||
| 96804096e9 | |||
| e2c41136f3 | |||
| 8b20e2e031 | |||
| 722d8cb48b | |||
| a73e6e5bd0 | |||
| 4cf68ef017 | |||
| b037395551 | |||
| 7a26a16511 | |||
| 30fc3d9e66 | |||
| 7de2ad34aa | |||
| 1bba631ab7 | |||
| cbf4087a3a | |||
| a3d72f5e6a | |||
| aeaa2fad06 | |||
| a219b90eea | |||
| 7086c60e6b | |||
| 0af4c82f36 | |||
| acf5ab816e | |||
| 6aa8c8bab9 | |||
| b5c939dee1 | |||
| 90d9315d45 | |||
| 7de2f57088 | |||
| 1488867063 | |||
| 59d62d48db | |||
| 97c2fc09f0 | |||
| 16d2e41309 | |||
| 13f66fb2ae | |||
| d6a8217e94 | |||
| 8e649e3008 | |||
| 8dffb45fd7 | |||
| c34ce0d2d0 | |||
| 61daf1cc36 | |||
| 1201fb6a5d | |||
| 7a5a329393 | |||
| f447781e01 | |||
| 070d9d0b46 | |||
| 49b4671076 | |||
| 28a0e94bb9 | |||
| ab2c5bfc35 | |||
| 80c64deb21 | |||
| 69af432965 | |||
| e788612ef4 | |||
| 62803efde0 | |||
| 01696b4d11 | |||
| 2c2dc61fa0 | |||
| 66ce001961 | |||
| 3aa6cc827c | |||
| c2304e1124 | |||
| 07f8f0915c | |||
| 7725c78c5e | |||
| 0624720634 | |||
| 64731bff46 | |||
| 878c393e8e | |||
| 84064a811c | |||
| 3c932d6d91 | |||
| a24d1d1af7 | |||
| edb5b43d64 | |||
| ac496e1fa4 | |||
| 103f3f8597 | |||
| 9842baedce | |||
| aaa916f78d | |||
| b463d9d876 | |||
| 7f6a4cccaf | |||
| d5e30e83f6 | |||
| d16c0e9e41 | |||
| bd8ac3bb32 | |||
| 87edff1e42 | |||
| 96f35d3cde | |||
| 7e45ffa4c3 | |||
| 6af69b0fc7 | |||
| 99e02570d1 | |||
| e1f4b7415a | |||
| 823cfcac57 | |||
| de6ccd8c08 | |||
| 2135d3be83 | |||
| 1c3720c160 | |||
| 6c72b13adc | |||
| 1404904d24 | |||
| db243936b4 | |||
| 6e72627e9e | |||
| 3d36ba7ecc | |||
| a7c0d6073f | |||
| f25b468272 | |||
| 2d0fb8ee6b | |||
| d875becc7a | |||
| cb72af63fd | |||
| f7187f1d5a | |||
| 700acdc5a2 | |||
| 18016ae9df | |||
| a30faa5bea | |||
| 05a113bb7a | |||
| f5d4ece9cd | |||
| 3bda37c56c | |||
| 62b52cb70a | |||
| a4fe594441 | |||
| 9d0e46126b | |||
| cb1bb4a691 | |||
| d3a24c3749 | |||
| 092849835e | |||
| b24ade4de5 | |||
| 0f77a2eef9 | |||
| 662c2fc9d3 | |||
| 510b1a7068 | |||
| c4f9914df6 | |||
| 2140ce3beb | |||
| a597bca75e | |||
| 2895aae121 | |||
| 4e20d93f03 | |||
| 1cc4e2e045 | |||
| 9fb427c468 | |||
| a9bd061144 | |||
| 0736b28abf | |||
| 9ac5b67b6e | |||
| 25601d691d | |||
| 0d1c11764b | |||
| 729ff461f1 | |||
| 0360a1918c | |||
| 23f21bcda2 | |||
| 800d65e3de | |||
| 5ce9b3ac55 | |||
| f86191dff8 | |||
| 412793697f | |||
| 3274ef9fb9 | |||
| f8e2231dfc | |||
| 837eaccd16 | |||
| 4f3570b56b | |||
| 8918a42b3b | |||
| bd77a02207 | |||
| eebbb99fc8 | |||
| 2b27c0b440 | |||
| 8e69b0c4a0 | |||
| 532744b4eb | |||
| ddd89ed6d1 | |||
| 5a53e5b96a | |||
| 69f84f7e6d | |||
| e2c65345ab | |||
| f47bcddf10 | |||
| 5e19230809 | |||
| f8961fbd53 | |||
| bef750cb1f | |||
| 4e2f06aec7 | |||
| 02c47ba1ea | |||
| f6cb59be47 | |||
| 397871a012 | |||
| 10239e0466 | |||
| 69ef99481b | |||
| fc20de82ce | |||
| 0232da27f5 | |||
| ba452e2400 | |||
| 9b5b8e7528 | |||
| 6e65947d54 | |||
| 93c5e241f3 | |||
| e0c61136a6 | |||
| c5cc13ddb3 | |||
| fd47c89f9d | |||
| 34ad902cb3 | |||
| 9678418e56 | |||
| 691d6c3b5f | |||
| 431555195a | |||
| b0aa5e6c88 | |||
| b3c2417578 | |||
| 7f882b00f5 | |||
| 3a9aa80914 | |||
| 3af3a0d27e | |||
| 7e415ffdb7 | |||
| e70c696fef | |||
| b2258d9b8a | |||
| 40eab806c4 | |||
| 319455f2da | |||
| 63867ba803 | |||
| 65ffd21574 | |||
| 393552a4b6 | |||
| 444c18be34 | |||
| dca096b8e3 | |||
| 57a03e7884 | |||
| fe1819f587 | |||
| aa157af93e | |||
| 0e58e03de7 | |||
| e011c80b07 | |||
| 9ae007a6d7 | |||
| 9dc59b9807 | |||
| 15689ebfb5 | |||
| 6250419fcb | |||
| 70621afe62 | |||
| 6f29710d88 | |||
| 7b07d7116b | |||
| f175086865 | |||
| c6071a9802 | |||
| ac138c1dc8 | |||
| 85b7261d31 | |||
| d47348e8f9 | |||
| 56df7bdbe3 | |||
| 1ea909d4db | |||
| c748fc49bb | |||
| 3bd1ec08e1 | |||
| caa6f9b06e | |||
| 32045a3f22 | |||
| 736952d0a2 | |||
| 684f15ab89 | |||
| 4238e031da | |||
| a457d8a849 | |||
| 0b3c0fc622 | |||
| a3d82e9414 | |||
| 37165f3293 | |||
| f2507fc9d4 | |||
| 7515fd94ba | |||
| 8cc1029bbf | |||
| 85363f8eaa | |||
| c5b3f18783 | |||
| 7738eeeacc | |||
| c6116468e4 | |||
| 2a2d0b60f7 | |||
| 9a5fddbcbb | |||
| 25c737de56 | |||
| 8ad8be2583 | |||
| f29f8e37d1 | |||
| b922f01257 | |||
| c1ec87c41b | |||
| c8aea97f16 | |||
| c9587a8638 | |||
| 15fc7a8bc5 | |||
| 76eb3b4c72 | |||
| c03d34f535 | |||
| 7cfdcf0c1b | |||
| d3a46b6bc9 | |||
| cc27f2dbb6 | |||
| 54ce852be4 | |||
| 83ad1fe8af | |||
| dcbf730129 | |||
| 39868a2330 | |||
| 5d00ca8bb6 | |||
| 772726ca96 | |||
| 00275d95ec | |||
| 242df788e6 | |||
| 3295b9b0dd | |||
| 2a9c78ef92 | |||
| a896d71948 | |||
| e3e0df7728 | |||
| 0acd3ebd4b | |||
| 82f0a68419 | |||
| 9a95c3acef | |||
| 22eb16352c | |||
| 5355310cc7 | |||
| 9f9ca0a2cf | |||
| 29970acaa9 | |||
| 8c0b9017c2 | |||
| e9890810d3 | |||
| 0e201d539a | |||
| 6a0e7cfb24 | |||
| e13defc0f7 | |||
| 3326cf357f | |||
| 9c78b9832b | |||
| 662b8b30a1 | |||
| caa15e42ac | |||
| 75410e07da | |||
| 72727c2a81 | |||
| adaee84933 | |||
| d761684212 | |||
| 307d4984a2 | |||
| 09711d5a88 | |||
| 2e1239345e | |||
| 8d6325b081 | |||
| 8a8144defa | |||
| ed867666ed | |||
| 84ff28ee69 | |||
| 97f032c66f | |||
| 18ea3bcb99 | |||
| 8da4ed147b | |||
| edd1f46ad2 | |||
| cfb1501720 | |||
| 17ceb34140 | |||
| c551b58490 | |||
| 6c736ace1a | |||
| 4ff2429f71 | |||
| 01499fe674 | |||
| c4d26f6405 | |||
| bd93f243dc | |||
| 1663315323 | |||
| ffb041a160 | |||
| f5f9de1bf8 | |||
| 2f47e8a462 | |||
| 119b446c3b | |||
| c2042ad74a | |||
| 361f8ec770 | |||
| 48a5123202 | |||
| 0f1d155685 | |||
| d3a6e79428 | |||
| 5f7f5b5367 | |||
| 2fe647c950 | |||
| 683f8e06f8 | |||
| bc4173f856 | |||
| 8443f0e2b9 | |||
| b9e2c47321 | |||
| 8099c46c8e | |||
| a3f046b948 | |||
| 911ca0d846 | |||
| 88d1ba2271 | |||
| bbfd9b8178 | |||
| 3818dee175 | |||
| 6d34de68ac | |||
| 10fb929a1b | |||
| d1a610dcb6 | |||
| 17364cd528 | |||
| c67f8493e0 | |||
| 1a90588752 | |||
| 4f4b840f67 | |||
| 77158738e6 | |||
| 27d0743edc | |||
| 9aca6a4489 | |||
| 866fd69008 | |||
| d9a942d6c6 | |||
| 6f0920c04b | |||
| 2e4893c786 | |||
| 5871bee791 | |||
| adea792b78 | |||
| 36f1ebfb6f | |||
| a45e38cd8a | |||
| 46b95318a1 | |||
| 50086df804 | |||
| 52e049bedc | |||
| a6640f6da7 | |||
| 2f82fb2ceb | |||
| c50c25b2d4 | |||
| 89733300a5 | |||
| b9658e23f4 | |||
| 1757ff18f2 | |||
| a26cb6023e | |||
| ccd631a934 | |||
| ab980d78d2 | |||
| f5951425c3 | |||
| 74992b1397 | |||
| 4b07b803b3 | |||
| 94f871e37e | |||
| 4a8a741ef0 | |||
| 162d5a0e0d | |||
| a22cf44b49 | |||
| 10bad42e7a | |||
| 8a6753905c | |||
| 73354f56f4 | |||
| 43c9e21f1d | |||
| ba21f0b0d8 | |||
| 0ee953fe26 | |||
| a68b9a793f | |||
| fb4361e976 | |||
| f9d866fa32 | |||
| 0c4da92d6b | |||
| 6377c7ebf4 | |||
| 08ecba72e6 | |||
| 38b286f989 | |||
| df7f816c88 | |||
| ca1220a682 | |||
| 9bb6c3cc3d | |||
| 4a8ac85ffb | |||
| c4177aba3e | |||
| 3206fdce9e | |||
| 0346e5809a | |||
| 99704517bb | |||
| 783ef730e2 | |||
| e81db5d706 | |||
| a0f75f1639 | |||
| d0893ccdaf | |||
| a9c7842a50 | |||
| 544c759fd1 | |||
| 759dbc061d | |||
| 56c9f75e8c | |||
| 635f288050 | |||
| cc8b7b13b3 | |||
| 4020ed1535 | |||
| e999ef00e7 | |||
| f16ea63a95 | |||
| 754f995c91 | |||
| ac8a67822e | |||
| 1c7926dea6 | |||
| 2bd8015a9d | |||
| 09e8aa0571 | |||
| 364e06483c | |||
| 2d07d6662c | |||
| 3d53749771 | |||
| eeadd823e6 | |||
| 8a5bd357cd | |||
| 79ee887c9a | |||
| 37d0a7f7e5 | |||
| ed4324dedc | |||
| d2da914151 | |||
| ca39e7f7de | |||
| 7bf2b7237e | |||
| c264855f87 | |||
| a5f2a44a45 | |||
| 4960a63bd8 | |||
| 42621805a7 | |||
| fed55b8896 | |||
| 73daa4bb74 | |||
| 92546c60b3 | |||
| 2fa91e5dfb | |||
| aac0913b8b | |||
| acc75ca859 | |||
| 8eb4e13df8 | |||
| 087d9c1da6 | |||
| 18336076a8 | |||
| 7fee5f5f25 | |||
| c2f04a00d2 | |||
| cc927123f9 | |||
| 97b426429b | |||
| 3686530943 | |||
| 621ef450da | |||
| 1e08bcd634 | |||
| ede468d4c9 | |||
| 1278f88dd9 | |||
| 6faf3bd827 | |||
| 92a2b52f53 | |||
| 8135458670 | |||
| 160a1cd690 | |||
| 2d3a133790 | |||
| af5384cd51 | |||
| 27423fcc15 | |||
| cdb5fe15d2 | |||
| 608c2b5354 | |||
| 121350f8e5 | |||
| 7bcc91e7d2 | |||
| b192622ad8 | |||
| 778e6f4492 | |||
| 8614777af4 | |||
| cce49da18c | |||
| 66bfefc09d | |||
| 29e883cf36 | |||
| 381d5b91b2 | |||
| b744997201 | |||
| 0357872558 | |||
| 844186f5fc | |||
| 0a818cfdd7 | |||
| cd1a17fb0a | |||
| 9abab27ba7 | |||
| 0faff626d1 | |||
| c355ade477 | |||
| 18818c9ba5 | |||
| b4ca3e46e6 | |||
| 262ba6be20 | |||
| 50c5d12ced | |||
| d6d51155ac | |||
| b100310764 | |||
| 7ac3e6d9a5 | |||
| 2742995541 | |||
| b8c0c125a2 | |||
| d78eb3d142 | |||
| 36769c35fc | |||
| e6c0c38894 | |||
| 1f77450f7e | |||
| c4204eb9e9 | |||
| 9a393a6ec9 | |||
| bbe02fc6b0 | |||
| 9fbc6d4f02 | |||
| e620121953 | |||
| 41c8878769 | |||
| d2834fa651 | |||
| 4155c53bd6 | |||
| d3538502c5 | |||
| 90a17de8bd | |||
| a82ea86a05 | |||
| 22c4992788 | |||
| 2a5d034248 | |||
| ed3c37c101 | |||
| 558e5e52c5 | |||
| 92d16a9d0a | |||
| f224a6d5f0 | |||
| 16f95a1420 | |||
| 0231d02877 | |||
| 6d2b70b3d9 | |||
| 49b825aeb3 | |||
| 357299a700 | |||
| 88df674dd6 | |||
| 31afa0abd5 | |||
| b11accec6d | |||
| defa869d5c | |||
| 8d4be6ab57 | |||
| 9976166902 | |||
| 8ea277ef77 | |||
| d85b8bfaf3 | |||
| d9e15d937e | |||
| 908ff5d3cd | |||
| 35b4ba3066 | |||
| f90e47daef | |||
| 5440dd68a7 | |||
| 11205d9eaa | |||
| 34e37fce7c | |||
| 3402c8dcd1 | |||
| 3921a63f67 | |||
| 5ecaf5dfc4 | |||
| 475f92351f | |||
| 0a5b378425 | |||
| 157774f552 | |||
| 320c12134a | |||
| 280b451835 | |||
| 4ee03fe590 | |||
| db1652f1ed | |||
| 8013ff7775 | |||
| c24475c2c8 | |||
| 580c639265 | |||
| 4c33549371 | |||
| 7be5553ba1 | |||
| 43936a1faf | |||
| e3c44bf551 | |||
| 6b0636d331 | |||
| cb0ee735be | |||
| 036dc06bac | |||
| 7155ec4b73 | |||
| 86ea4d94bb | |||
| 6a2021ac98 | |||
| 6fe05064eb | |||
| dd5c9ff6d4 | |||
| 29179d0bbc | |||
| f6400a4097 | |||
| e170b9f56b | |||
| 2ea8418c66 | |||
| c20a4a3084 | |||
| 0be64f9902 | |||
| 5300fefef4 | |||
| 2602e6ec0a | |||
| 1a22fc3c68 | |||
| 6d02861f11 | |||
| 57ed190ea3 | |||
| 436d7de817 | |||
| a9feed2e4a | |||
| 8b04e94d09 | |||
| 5c5576c39d | |||
| 2b957beeda | |||
| 832aeffd4f | |||
| 5d08ecdcb2 | |||
| 997529774c | |||
| 48d20ff1ec | |||
| 0793f291d1 | |||
| 8d479328ec | |||
| 569326e76a | |||
| 8372b84e9f | |||
| eda55156e5 | |||
| c40a526302 | |||
| 540b038ced | |||
| ce1ebec253 | |||
| 44e121c997 | |||
| 3579404bed | |||
| 1e19860409 | |||
| eab4b578a3 | |||
| 2878196e0a | |||
| 1c037411e9 | |||
| 68144681b2 | |||
| 484a516bd6 | |||
| fa6e84415b | |||
| 7117634ba8 | |||
| a108c283cf | |||
| 3dc61f4a7a | |||
| 9685e3f1db | |||
| b2c70f9e69 | |||
| d7a3ffa9de | |||
| 18ed91a402 | |||
| e991b3d10c | |||
| f1b7f9ca30 | |||
| e1e510e473 | |||
| d042d15a50 | |||
| fe9fec733d | |||
| 06095e57d7 | |||
| 126d0d1b3c |
@@ -13,5 +13,3 @@ debug.log
|
||||
docs/output
|
||||
docs/includes
|
||||
spec/fixtures/evil-files/
|
||||
resources/linux/Atom.desktop
|
||||
resources/linux/debian/control
|
||||
|
||||
+16
@@ -6,10 +6,25 @@ Visit [atom.io](https://atom.io) to learn more.
|
||||
|
||||
## Installing
|
||||
|
||||
### Mac OS X
|
||||
|
||||
Download the latest [Atom release](https://github.com/atom/atom/releases/latest).
|
||||
|
||||
Atom will automatically update when a new release is available.
|
||||
|
||||
### Windows
|
||||
|
||||
Install the [Atom chocolatey package](https://chocolatey.org/packages/Atom).
|
||||
|
||||
1. Install [chocolatey](https://chocolatey.org).
|
||||
2. Close and reopen your command prompt or PowerShell window.
|
||||
3. Run `cinst Atom`
|
||||
4. In the future run `cup Atom` to upgrade to the latest release.
|
||||
|
||||
You can also download a `.zip` file from the [releases page](https://github.com/atom/atom/releases/latest).
|
||||
The Windows version does not currently automatically update so you will need to
|
||||
manually upgrade to future releases by re-downloading the `.zip` file.
|
||||
|
||||
## Building
|
||||
|
||||
* [Linux](docs/build-instructions/linux.md)
|
||||
@@ -18,4 +33,5 @@ Atom will automatically update when a new release is available.
|
||||
* [Windows](docs/build-instructions/windows.md)
|
||||
|
||||
## Developing
|
||||
|
||||
Check out the [guides](https://atom.io/docs/latest) and the [API reference](https://atom.io/docs/api).
|
||||
|
||||
+1
-1
@@ -6,6 +6,6 @@
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "0.70.0"
|
||||
"atom-package-manager": "0.93.2"
|
||||
}
|
||||
}
|
||||
|
||||
+7
-2
@@ -69,6 +69,11 @@ elif [ $OS == 'Linux' ]; then
|
||||
SCRIPT=$(readlink -f "$0")
|
||||
USR_DIRECTORY=$(readlink -f $(dirname $SCRIPT)/..)
|
||||
ATOM_PATH="$USR_DIRECTORY/share/atom/atom"
|
||||
DOT_ATOM_DIR="$HOME/.atom"
|
||||
|
||||
if [ ! -d "$DOT_ATOM_DIR" ]; then
|
||||
mkdir -p "$DOT_ATOM_DIR"
|
||||
fi
|
||||
|
||||
: ${TMPDIR:=/tmp}
|
||||
|
||||
@@ -79,9 +84,9 @@ elif [ $OS == 'Linux' ]; then
|
||||
exit $?
|
||||
else
|
||||
(
|
||||
nohup "$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@" > "$TMPDIR/atom-nohup.out" 2>&1
|
||||
nohup "$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@" > "$DOT_ATOM_DIR/nohup.out" 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
cat "$TMPDIR/atom-nohup.out"
|
||||
cat "$DOT_ATOM_DIR/nohup.out"
|
||||
exit $?
|
||||
fi
|
||||
) &
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
require '../src/window'
|
||||
Atom = require '../src/atom'
|
||||
atom = new Atom()
|
||||
window.atom = Atom.loadOrCreate('spec')
|
||||
atom.show() unless atom.getLoadSettings().exitWhenDone
|
||||
window.atom = atom
|
||||
|
||||
@@ -9,5 +9,4 @@ window.atom = atom
|
||||
atom.openDevTools()
|
||||
|
||||
document.title = "Benchmark Suite"
|
||||
benchmarkSuite = require.resolve('./benchmark-suite')
|
||||
runSpecSuite(benchmarkSuite, true)
|
||||
runSpecSuite('../benchmark/benchmark-suite', atom.getLoadSettings().logFile)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
require '../spec/spec-helper'
|
||||
|
||||
path = require 'path'
|
||||
{$, _, Point, fs} = require 'atom'
|
||||
{$, Point} = require 'atom'
|
||||
_ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
Project = require '../src/project'
|
||||
TokenizedBuffer = require '../src/tokenized-buffer'
|
||||
|
||||
@@ -101,7 +103,7 @@ $.fn.resultOfTrigger = (type) ->
|
||||
event.result
|
||||
|
||||
$.fn.enableKeymap = ->
|
||||
@on 'keydown', (e) => window.keymap.handleKeyEvent(e)
|
||||
@on 'keydown', (e) -> window.keymap.handleKeyEvent(e)
|
||||
|
||||
$.fn.attachToDom = ->
|
||||
$('#jasmine-content').append(this)
|
||||
|
||||
@@ -53,7 +53,7 @@ describe "editorView.", ->
|
||||
|
||||
describe "at-end.", ->
|
||||
beforeEach ->
|
||||
editorView.moveCursorToBottom()
|
||||
editorView.moveToBottom()
|
||||
|
||||
benchmark "insert-delete", ->
|
||||
editorView.insertText('"')
|
||||
@@ -62,8 +62,8 @@ describe "editorView.", ->
|
||||
describe "empty-vs-set-innerHTML.", ->
|
||||
[firstRow, lastRow] = []
|
||||
beforeEach ->
|
||||
firstRow = editorView.getFirstVisibleScreenRow()
|
||||
lastRow = editorView.getLastVisibleScreenRow()
|
||||
firstRow = editorView.getModel().getFirstVisibleScreenRow()
|
||||
lastRow = editorView.getModel().getLastVisibleScreenRow()
|
||||
|
||||
benchmark "build-gutter-html.", 1000, ->
|
||||
editorView.gutter.renderLineNumbers(null, firstRow, lastRow)
|
||||
@@ -97,13 +97,13 @@ describe "editorView.", ->
|
||||
describe "multiple-lines.", ->
|
||||
[firstRow, lastRow] = []
|
||||
beforeEach ->
|
||||
firstRow = editorView.getFirstVisibleScreenRow()
|
||||
lastRow = editorView.getLastVisibleScreenRow()
|
||||
firstRow = editorView.getModel().getFirstVisibleScreenRow()
|
||||
lastRow = editorView.getModel().getLastVisibleScreenRow()
|
||||
|
||||
benchmark "cache-entire-visible-area", 100, ->
|
||||
for i in [firstRow..lastRow]
|
||||
line = editorView.lineElementForScreenRow(i)[0]
|
||||
editorView.positionLeftForLineAndColumn(line, i, Math.max(0, editorView.lineLengthForBufferRow(i)))
|
||||
editorView.positionLeftForLineAndColumn(line, i, Math.max(0, editorView.getModel().lineTextForBufferRow(i).length))
|
||||
|
||||
describe "text-rendering.", ->
|
||||
beforeEach ->
|
||||
@@ -178,7 +178,7 @@ describe "editorView.", ->
|
||||
atom.workspaceView.openSync('huge.js')
|
||||
|
||||
benchmark "moving-to-eof.", 1, ->
|
||||
editorView.moveCursorToBottom()
|
||||
editorView.moveToBottom()
|
||||
|
||||
describe "on-first-line.", ->
|
||||
benchmark "inserting-newline", 5, ->
|
||||
@@ -195,11 +195,11 @@ describe "editorView.", ->
|
||||
endPosition = null
|
||||
|
||||
beforeEach ->
|
||||
editorView.moveCursorToBottom()
|
||||
editorView.moveToBottom()
|
||||
endPosition = editorView.getCursorScreenPosition()
|
||||
|
||||
benchmark "move-to-beginning-of-word", ->
|
||||
editorView.moveCursorToBeginningOfWord()
|
||||
editorView.moveToBeginningOfWord()
|
||||
editorView.setCursorScreenPosition(endPosition)
|
||||
|
||||
benchmark "insert", ->
|
||||
|
||||
Arquivo executável
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env coffee
|
||||
|
||||
{spawn, exec} = require 'child_process'
|
||||
fs = require 'fs'
|
||||
os = require 'os'
|
||||
path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
temp = require 'temp'
|
||||
|
||||
directoryToOpen = temp.mkdirSync('browser-process-startup-')
|
||||
socketPath = path.join(os.tmpdir(), 'atom.sock')
|
||||
numberOfRuns = 10
|
||||
|
||||
deleteSocketFile = ->
|
||||
try
|
||||
fs.unlinkSync(socketPath) if fs.existsSync(socketPath)
|
||||
catch error
|
||||
console.error(error)
|
||||
|
||||
launchAtom = (callback) ->
|
||||
deleteSocketFile()
|
||||
|
||||
cmd = 'atom'
|
||||
args = ['--safe', '--new-window', '--foreground', directoryToOpen]
|
||||
atomProcess = spawn(cmd, args)
|
||||
|
||||
output = ''
|
||||
startupTimes = []
|
||||
dataListener = (data) ->
|
||||
output += data
|
||||
if match = /App load time: (\d+)/.exec(output)
|
||||
startupTime = parseInt(match[1])
|
||||
atomProcess.stderr.removeListener 'data', dataListener
|
||||
atomProcess.kill()
|
||||
exec 'pkill -9 Atom', (error) ->
|
||||
console.error(error) if error?
|
||||
callback(startupTime)
|
||||
|
||||
atomProcess.stderr.on 'data', dataListener
|
||||
|
||||
startupTimes = []
|
||||
collector = (startupTime) ->
|
||||
startupTimes.push(startupTime)
|
||||
if startupTimes.length < numberOfRuns
|
||||
launchAtom(collector)
|
||||
else
|
||||
maxTime = _.max(startupTimes)
|
||||
minTime = _.min(startupTimes)
|
||||
totalTime = startupTimes.reduce (previousValue=0, currentValue) -> previousValue + currentValue
|
||||
console.log "Startup Runs: #{startupTimes.length}"
|
||||
console.log "First run time: #{startupTimes[0]}ms"
|
||||
console.log "Max time: #{maxTime}ms"
|
||||
console.log "Min time: #{minTime}ms"
|
||||
console.log "Average time: #{Math.round(totalTime/startupTimes.length)}ms"
|
||||
|
||||
launchAtom(collector)
|
||||
+15
-10
@@ -40,7 +40,10 @@ module.exports = (grunt) ->
|
||||
appName = if process.platform is 'darwin' then 'Atom.app' else 'Atom'
|
||||
buildDir = grunt.option('build-dir') ? path.join(tmpDir, 'atom-build')
|
||||
installDir = grunt.option('install-dir')
|
||||
atomShellDownloadDir = path.join(os.tmpdir(), 'atom-cached-atom-shells')
|
||||
|
||||
home = if process.platform is 'win32' then process.env.USERPROFILE else process.env.HOME
|
||||
atomShellDownloadDir = path.join(home, '.atom', 'atom-shell')
|
||||
|
||||
symbolsDir = path.join(buildDir, 'Atom.breakpad.syms')
|
||||
shellAppDir = path.join(buildDir, appName)
|
||||
if process.platform is 'win32'
|
||||
@@ -57,7 +60,7 @@ module.exports = (grunt) ->
|
||||
contentsDir = shellAppDir
|
||||
appDir = path.join(shellAppDir, 'resources', 'app')
|
||||
installDir ?= process.env.INSTALL_PREFIX ? '/usr/local'
|
||||
killCommand ='pkill -9 Atom'
|
||||
killCommand ='pkill -9 atom'
|
||||
|
||||
coffeeConfig =
|
||||
glob_to_multiple:
|
||||
@@ -93,6 +96,8 @@ module.exports = (grunt) ->
|
||||
csonConfig =
|
||||
options:
|
||||
rootObject: true
|
||||
cachePath: path.join(home, '.atom', 'compile-cache', 'grunt-cson')
|
||||
|
||||
glob_to_multiple:
|
||||
expand: true
|
||||
src: [
|
||||
@@ -125,7 +130,7 @@ module.exports = (grunt) ->
|
||||
|
||||
atom: {appDir, appName, symbolsDir, buildDir, contentsDir, installDir, shellAppDir}
|
||||
|
||||
docsOutputDir: 'docs/output/api'
|
||||
docsOutputDir: 'docs/output'
|
||||
|
||||
coffee: coffeeConfig
|
||||
|
||||
@@ -139,12 +144,7 @@ module.exports = (grunt) ->
|
||||
|
||||
coffeelint:
|
||||
options:
|
||||
no_empty_param_list:
|
||||
level: 'error'
|
||||
max_line_length:
|
||||
level: 'ignore'
|
||||
indentation:
|
||||
level: 'ignore'
|
||||
configFile: 'coffeelint.json'
|
||||
src: [
|
||||
'dot-atom/**/*.coffee'
|
||||
'exports/**/*.coffee'
|
||||
@@ -225,9 +225,14 @@ module.exports = (grunt) ->
|
||||
grunt.registerTask('compile', ['coffee', 'prebuild-less', 'cson', 'peg'])
|
||||
grunt.registerTask('lint', ['coffeelint', 'csslint', 'lesslint'])
|
||||
grunt.registerTask('test', ['shell:kill-atom', 'run-specs'])
|
||||
grunt.registerTask('ci', ['output-disk-space', 'download-atom-shell', 'build', 'dump-symbols', 'set-version', 'check-licenses', 'lint', 'test', 'codesign', 'publish-build'])
|
||||
grunt.registerTask('docs', ['markdown:guides', 'build-docs'])
|
||||
|
||||
|
||||
ciTasks = ['output-disk-space', 'download-atom-shell', 'build']
|
||||
ciTasks.push('dump-symbols') unless process.platform is 'win32'
|
||||
ciTasks.push('set-version', 'check-licenses', 'lint', 'test', 'codesign', 'publish-build')
|
||||
grunt.registerTask('ci', ciTasks)
|
||||
|
||||
defaultTasks = ['download-atom-shell', 'build', 'set-version']
|
||||
defaultTasks.push 'install' unless process.platform is 'linux'
|
||||
grunt.registerTask('default', defaultTasks)
|
||||
|
||||
+10
-9
@@ -7,17 +7,18 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "~0.2.9",
|
||||
"biscotto": ">=2.1.1 <3.0",
|
||||
"donna": "1.0.1",
|
||||
"tello": "1.0.2",
|
||||
"formidable": "~1.0.14",
|
||||
"fs-plus": "2.x",
|
||||
"github-releases": "~0.2.0",
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-cli": "~0.1.9",
|
||||
"grunt-coffeelint": "git+https://github.com/atom/grunt-coffeelint.git",
|
||||
"grunt-contrib-csslint": "~0.1.2",
|
||||
"grunt-coffeelint": "git+https://github.com/atom/grunt-coffeelint.git#cfb99aa99811d52687969532bd5a98011ed95bfe",
|
||||
"grunt-contrib-coffee": "~0.9.0",
|
||||
"grunt-contrib-csslint": "~0.1.2",
|
||||
"grunt-contrib-less": "~0.8.0",
|
||||
"grunt-cson": "0.8.0",
|
||||
"grunt-cson": "0.10.0",
|
||||
"grunt-download-atom-shell": "~0.8.0",
|
||||
"grunt-lesslint": "0.13.0",
|
||||
"grunt-markdown": "~0.4.0",
|
||||
@@ -26,16 +27,16 @@
|
||||
"harmony-collections": "~0.3.8",
|
||||
"json-front-matter": "~0.1.3",
|
||||
"legal-eagle": "~0.4.0",
|
||||
"minidump": "~0.7",
|
||||
"read-package-json": "1.1.8",
|
||||
"minidump": "~0.8",
|
||||
"normalize-package-data": "0.2.12",
|
||||
"npm": "~1.4.5",
|
||||
"rcedit": "~0.1.2",
|
||||
"read-package-json": "1.1.8",
|
||||
"request": "~2.27.0",
|
||||
"rimraf": "~2.2.2",
|
||||
"runas": "0.5.x",
|
||||
"runas": "~1.0.1",
|
||||
"underscore-plus": "1.x",
|
||||
"unzip": "~0.1.9",
|
||||
"vm-compatibility-layer": "~0.1.0",
|
||||
"npm": "~1.4.5"
|
||||
"vm-compatibility-layer": "~0.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@ module.exports = (grunt) ->
|
||||
mkdir path.dirname(buildDir)
|
||||
|
||||
if process.platform is 'darwin'
|
||||
cp 'atom-shell/Atom.app', shellAppDir
|
||||
cp 'atom-shell/Atom.app', shellAppDir, filter: /default_app/
|
||||
else
|
||||
cp 'atom-shell', shellAppDir
|
||||
cp 'atom-shell', shellAppDir, filter: /default_app/
|
||||
|
||||
mkdir appDir
|
||||
|
||||
@@ -45,19 +45,45 @@ module.exports = (grunt) ->
|
||||
path.join('git-utils', 'deps')
|
||||
path.join('oniguruma', 'deps')
|
||||
path.join('less', 'dist')
|
||||
path.join('less', 'test')
|
||||
path.join('bootstrap', 'docs')
|
||||
path.join('bootstrap', 'examples')
|
||||
path.join('bootstrap', '_config.yml')
|
||||
path.join('bootstrap', '_includes')
|
||||
path.join('bootstrap', '_layouts')
|
||||
path.join('npm', 'doc')
|
||||
path.join('npm', 'html')
|
||||
path.join('npm', 'man')
|
||||
path.join('npm', 'node_modules', '.bin', 'beep')
|
||||
path.join('npm', 'node_modules', '.bin', 'clear')
|
||||
path.join('npm', 'node_modules', '.bin', 'starwars')
|
||||
path.join('pegjs', 'examples')
|
||||
path.join('plist', 'tests')
|
||||
path.join('xmldom', 'test')
|
||||
path.join('jasmine-reporters', 'ext')
|
||||
path.join('jasmine-node', 'node_modules', 'gaze')
|
||||
path.join('jasmine-node', 'spec')
|
||||
path.join('node_modules', 'nan')
|
||||
path.join('build', 'binding.Makefile')
|
||||
path.join('build', 'config.gypi')
|
||||
path.join('build', 'gyp-mac-tool')
|
||||
path.join('build', 'Makefile')
|
||||
path.join('build', 'Release', 'obj.target')
|
||||
path.join('build', 'Release', 'obj')
|
||||
path.join('build', 'Release', '.deps')
|
||||
path.join('vendor', 'apm')
|
||||
path.join('resources', 'mac')
|
||||
path.join('resources', 'win')
|
||||
|
||||
# These are only require in dev mode when the grammar isn't precompiled
|
||||
path.join('atom-keymap', 'node_modules', 'loophole')
|
||||
path.join('atom-keymap', 'node_modules', 'pegjs')
|
||||
path.join('atom-keymap', 'node_modules', '.bin', 'pegjs')
|
||||
path.join('snippets', 'node_modules', 'loophole')
|
||||
path.join('snippets', 'node_modules', 'pegjs')
|
||||
path.join('snippets', 'node_modules', '.bin', 'pegjs')
|
||||
|
||||
'.DS_Store'
|
||||
'.jshintrc'
|
||||
'.npmignore'
|
||||
'.pairs'
|
||||
'.travis.yml'
|
||||
]
|
||||
ignoredPaths = ignoredPaths.map (ignoredPath) -> _.escapeRegExp(ignoredPath)
|
||||
|
||||
@@ -65,21 +91,56 @@ module.exports = (grunt) ->
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('spellchecker', 'vendor', 'hunspell') + path.sep)}.*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('build', 'Release') + path.sep)}.*\\.pdb"
|
||||
|
||||
# Ignore *.cc and *.h files from native modules
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('ctags', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('git-utils', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('keytar', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('nslog', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('oniguruma', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('pathwatcher', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('runas', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('scrollbar-style', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('spellchecker', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
|
||||
# Ignore build files
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.sep)}binding\\.gyp$"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.sep)}.+\\.target.mk$"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.sep)}linker\\.lock$"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('build', 'Release') + path.sep)}.+\\.node\\.dSYM"
|
||||
|
||||
# Hunspell dictionaries are only not needed on OS X.
|
||||
if process.platform is 'darwin'
|
||||
ignoredPaths.push path.join('spellchecker', 'vendor', 'hunspell_dictionaries')
|
||||
ignoredPaths = ignoredPaths.map (ignoredPath) -> "(#{ignoredPath})"
|
||||
|
||||
testFolderPattern = new RegExp("#{_.escapeRegExp(path.sep)}te?sts?#{_.escapeRegExp(path.sep)}")
|
||||
exampleFolderPattern = new RegExp("#{_.escapeRegExp(path.sep)}examples?#{_.escapeRegExp(path.sep)}")
|
||||
benchmarkFolderPattern = new RegExp("#{_.escapeRegExp(path.sep)}benchmarks?#{_.escapeRegExp(path.sep)}")
|
||||
|
||||
nodeModulesFilter = new RegExp(ignoredPaths.join('|'))
|
||||
filterNodeModule = (pathToCopy) ->
|
||||
return true if benchmarkFolderPattern.test(pathToCopy)
|
||||
|
||||
pathToCopy = path.resolve(pathToCopy)
|
||||
nodeModulesFilter.test(pathToCopy) or testFolderPattern.test(pathToCopy) or exampleFolderPattern.test(pathToCopy)
|
||||
|
||||
packageFilter = new RegExp("(#{ignoredPaths.join('|')})|(.+\\.(cson|coffee)$)")
|
||||
filterPackage = (pathToCopy) ->
|
||||
return true if benchmarkFolderPattern.test(pathToCopy)
|
||||
|
||||
pathToCopy = path.resolve(pathToCopy)
|
||||
packageFilter.test(pathToCopy) or testFolderPattern.test(pathToCopy) or exampleFolderPattern.test(pathToCopy)
|
||||
|
||||
for directory in nonPackageDirectories
|
||||
cp directory, path.join(appDir, directory), filter: nodeModulesFilter
|
||||
cp directory, path.join(appDir, directory), filter: filterNodeModule
|
||||
|
||||
for directory in packageDirectories
|
||||
cp directory, path.join(appDir, directory), filter: packageFilter
|
||||
cp directory, path.join(appDir, directory), filter: filterPackage
|
||||
|
||||
cp 'spec', path.join(appDir, 'spec')
|
||||
cp 'src', path.join(appDir, 'src'), filter: /.+\.(cson|coffee)$/
|
||||
cp 'static', path.join(appDir, 'static')
|
||||
cp 'apm', path.join(appDir, 'apm'), filter: nodeModulesFilter
|
||||
cp 'apm', path.join(appDir, 'apm'), filter: filterNodeModule
|
||||
|
||||
if process.platform is 'darwin'
|
||||
grunt.file.recurse path.join('resources', 'mac'), (sourcePath, rootDirectory, subDirectory='', filename) ->
|
||||
@@ -87,9 +148,6 @@ module.exports = (grunt) ->
|
||||
grunt.file.copy(sourcePath, path.resolve(appDir, '..', subDirectory, filename))
|
||||
|
||||
if process.platform is 'win32'
|
||||
cp path.join('resources', 'win', 'msvcp100.dll'), path.join(shellAppDir, 'msvcp100.dll')
|
||||
cp path.join('resources', 'win', 'msvcr100.dll'), path.join(shellAppDir, 'msvcr100.dll')
|
||||
|
||||
# Set up chocolatey ignore and gui files
|
||||
fs.writeFileSync path.join(appDir, 'apm', 'node_modules', 'atom-package-manager', 'bin', 'node.exe.ignore'), ''
|
||||
fs.writeFileSync path.join(appDir, 'node_modules', 'symbols-view', 'vendor', 'ctags-win32.exe.ignore'), ''
|
||||
|
||||
+28
-151
@@ -1,162 +1,39 @@
|
||||
path = require 'path'
|
||||
|
||||
async = require 'async'
|
||||
fs = require 'fs-plus'
|
||||
request = require 'request'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
donna = require 'donna'
|
||||
tello = require 'tello'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{rm} = require('./task-helpers')(grunt)
|
||||
getClassesToInclude = ->
|
||||
modulesPath = path.resolve(__dirname, '..', '..', 'node_modules')
|
||||
classes = {}
|
||||
fs.traverseTreeSync modulesPath, (modulePath) ->
|
||||
return true unless path.basename(modulePath) is 'package.json'
|
||||
return true unless fs.isFileSync(modulePath)
|
||||
|
||||
cmd = path.join('node_modules', '.bin', 'coffee')
|
||||
commonArgs = [path.join('build', 'node_modules', '.bin', 'biscotto'), '--']
|
||||
opts =
|
||||
stdio: 'inherit'
|
||||
apiPath = path.join(path.dirname(modulePath), 'api.json')
|
||||
if fs.isFileSync(apiPath)
|
||||
_.extend(classes, grunt.file.readJSON(apiPath).classes)
|
||||
true
|
||||
classes
|
||||
|
||||
sortClasses = (classes) ->
|
||||
sortedClasses = {}
|
||||
for className in Object.keys(classes).sort()
|
||||
sortedClasses[className] = classes[className]
|
||||
sortedClasses
|
||||
|
||||
grunt.registerTask 'build-docs', 'Builds the API docs in src', ->
|
||||
done = @async()
|
||||
|
||||
docsOutputDir = grunt.config.get('docsOutputDir')
|
||||
|
||||
downloadIncludes (error, includePaths) ->
|
||||
if error?
|
||||
done(error)
|
||||
else
|
||||
rm(docsOutputDir)
|
||||
args = [
|
||||
commonArgs...
|
||||
'--title', 'Atom API Documentation'
|
||||
'-o', docsOutputDir
|
||||
'-r', 'docs/README.md'
|
||||
'--stability', '1'
|
||||
'src/'
|
||||
includePaths...
|
||||
]
|
||||
grunt.util.spawn({cmd, args, opts}, done)
|
||||
metadata = donna.generateMetadata(['.'])
|
||||
api = tello.digest(metadata)
|
||||
_.extend(api.classes, getClassesToInclude())
|
||||
api.classes = sortClasses(api.classes)
|
||||
|
||||
grunt.registerTask 'lint-docs', 'Generate stats about the doc coverage', ->
|
||||
done = @async()
|
||||
downloadIncludes (error, includePaths) ->
|
||||
if error?
|
||||
done(error)
|
||||
else
|
||||
args = [
|
||||
commonArgs...
|
||||
'--noOutput'
|
||||
'src/'
|
||||
includePaths...
|
||||
]
|
||||
grunt.util.spawn({cmd, args, opts}, done)
|
||||
|
||||
grunt.registerTask 'missing-docs', 'Generate stats about the doc coverage', ->
|
||||
done = @async()
|
||||
downloadIncludes (error, includePaths) ->
|
||||
if error?
|
||||
done(error)
|
||||
else
|
||||
args = [
|
||||
commonArgs...
|
||||
'--noOutput'
|
||||
'--missing'
|
||||
'src/'
|
||||
includePaths...
|
||||
]
|
||||
grunt.util.spawn({cmd, args, opts}, done)
|
||||
|
||||
grunt.registerTask 'copy-docs', 'Copies over latest API docs to atom-docs', ->
|
||||
done = @async()
|
||||
|
||||
fetchTag = (args..., callback) ->
|
||||
cmd = 'git'
|
||||
args = ['describe', '--abbrev=0', '--tags']
|
||||
grunt.util.spawn {cmd, args}, (error, result) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else
|
||||
callback(null, String(result).trim())
|
||||
|
||||
copyDocs = (tag, callback) ->
|
||||
cmd = 'cp'
|
||||
args = ['-r', 'docs/output/', "../atom.io/public/docs/api/#{tag}/"]
|
||||
|
||||
fs.exists "../atom.io/public/docs/api/", (exists) ->
|
||||
if exists
|
||||
grunt.util.spawn {cmd, args}, (error, result) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else
|
||||
callback(null, tag)
|
||||
else
|
||||
grunt.log.error "../atom.io/public/docs/api/ doesn't exist"
|
||||
return false
|
||||
|
||||
grunt.util.async.waterfall [fetchTag, copyDocs], done
|
||||
|
||||
grunt.registerTask 'deploy-docs', 'Publishes latest API docs to atom-docs.githubapp.com', ->
|
||||
done = @async()
|
||||
docsRepoArgs = ['--work-tree=../atom-docs/', '--git-dir=../atom-docs/.git/']
|
||||
|
||||
fetchTag = (args..., callback) ->
|
||||
cmd = 'git'
|
||||
args = ['describe', '--abbrev=0', '--tags']
|
||||
grunt.util.spawn {cmd, args}, (error, result) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else
|
||||
callback(null, String(result).trim().split('.')[0..1].join('.'))
|
||||
|
||||
stageDocs = (tag, callback) ->
|
||||
cmd = 'git'
|
||||
args = [docsRepoArgs..., 'add', "public/#{tag}"]
|
||||
grunt.util.spawn({cmd, args, opts}, callback)
|
||||
|
||||
fetchSha = (args..., callback) ->
|
||||
cmd = 'git'
|
||||
args = ['rev-parse', 'HEAD']
|
||||
grunt.util.spawn {cmd, args}, (error, result) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else
|
||||
callback(null, String(result).trim())
|
||||
|
||||
commitChanges = (sha, callback) ->
|
||||
cmd = 'git'
|
||||
args = [docsRepoArgs..., 'commit', "-m Update API docs to #{sha}"]
|
||||
grunt.util.spawn({cmd, args, opts}, callback)
|
||||
|
||||
pushOrigin = (args..., callback) ->
|
||||
cmd = 'git'
|
||||
args = [docsRepoArgs..., 'push', 'origin', 'master']
|
||||
grunt.util.spawn({cmd, args, opts}, callback)
|
||||
|
||||
pushHeroku = (args..., callback) ->
|
||||
cmd = 'git'
|
||||
args = [docsRepoArgs..., 'push', 'heroku', 'master']
|
||||
grunt.util.spawn({cmd, args, opts}, callback)
|
||||
|
||||
grunt.util.async.waterfall [fetchTag, stageDocs, fetchSha, commitChanges, pushOrigin, pushHeroku], done
|
||||
|
||||
downloadFileFromRepo = ({repo, file}, callback) ->
|
||||
uri = "https://raw.github.com/atom/#{repo}/master/#{file}"
|
||||
request uri, (error, response, contents) ->
|
||||
return callback(error) if error?
|
||||
downloadPath = path.join('docs', 'includes', repo, file)
|
||||
fs.writeFile downloadPath, contents, (error) ->
|
||||
callback(error, downloadPath)
|
||||
|
||||
downloadIncludes = (callback) ->
|
||||
includes = [
|
||||
{repo: 'atom-keymap', file: 'src/keymap-manager.coffee'}
|
||||
{repo: 'atom-keymap', file: 'src/key-binding.coffee'}
|
||||
{repo: 'first-mate', file: 'src/grammar.coffee'}
|
||||
{repo: 'first-mate', file: 'src/grammar-registry.coffee'}
|
||||
{repo: 'node-pathwatcher', file: 'src/directory.coffee'}
|
||||
{repo: 'node-pathwatcher', file: 'src/file.coffee'}
|
||||
{repo: 'space-pen', file: 'src/space-pen.coffee'}
|
||||
{repo: 'text-buffer', file: 'src/marker.coffee'}
|
||||
{repo: 'text-buffer', file: 'src/point.coffee'}
|
||||
{repo: 'text-buffer', file: 'src/range.coffee'}
|
||||
{repo: 'text-buffer', file: 'src/text-buffer.coffee'}
|
||||
{repo: 'theorist', file: 'src/model.coffee'}
|
||||
]
|
||||
|
||||
async.map(includes, downloadFileFromRepo, callback)
|
||||
apiJson = JSON.stringify(api, null, 2)
|
||||
apiJsonPath = path.join(docsOutputDir, 'api.json')
|
||||
grunt.file.write(apiJsonPath, apiJson)
|
||||
|
||||
@@ -4,17 +4,13 @@ _ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
runas = null
|
||||
|
||||
fillTemplate = (filePath, data) ->
|
||||
template = _.template(String(fs.readFileSync(filePath + '.in')))
|
||||
filled = template(data)
|
||||
fs.writeFileSync(filePath, filled)
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{cp, mkdir, rm} = require('./task-helpers')(grunt)
|
||||
|
||||
grunt.registerTask 'install', 'Install the built application', ->
|
||||
installDir = grunt.config.get('atom.installDir')
|
||||
shellAppDir = grunt.config.get('atom.shellAppDir')
|
||||
|
||||
if process.platform is 'win32'
|
||||
runas ?= require 'runas'
|
||||
copyFolder = path.resolve 'script', 'copy-folder.cmd'
|
||||
@@ -32,7 +28,6 @@ module.exports = (grunt) ->
|
||||
shareDir = path.join(installDir, 'share', 'atom')
|
||||
|
||||
iconName = path.join(shareDir,'resources','app','resources','atom.png')
|
||||
desktopFile = path.join('resources', 'linux', 'Atom.desktop')
|
||||
|
||||
mkdir binDir
|
||||
cp 'atom.sh', path.join(binDir, 'atom')
|
||||
@@ -42,13 +37,17 @@ module.exports = (grunt) ->
|
||||
|
||||
# Create Atom.desktop if installation not in temporary folder
|
||||
tmpDir = if process.env.TMPDIR? then process.env.TMPDIR else '/tmp'
|
||||
desktopInstallFile = path.join(installDir,'share','applications','Atom.desktop')
|
||||
if installDir.indexOf(tmpDir) isnt 0
|
||||
mkdir path.dirname(desktopInstallFile)
|
||||
desktopFile = path.join('resources', 'linux', 'Atom.desktop.in')
|
||||
desktopInstallFile = path.join(installDir, 'share', 'applications', 'Atom.desktop')
|
||||
|
||||
{description} = grunt.file.readJSON('package.json')
|
||||
installDir = path.join(installDir,'.') # To prevent "Exec=/usr/local//share/atom/atom"
|
||||
fillTemplate(desktopFile, {description, installDir, iconName})
|
||||
cp desktopFile, desktopInstallFile
|
||||
iconName = path.join(shareDir, 'resources', 'app', 'resources', 'atom.png')
|
||||
installDir = path.join(installDir, '.') # To prevent "Exec=/usr/local//share/atom/atom"
|
||||
template = _.template(String(fs.readFileSync(desktopFile)))
|
||||
filled = template({description, installDir, iconName})
|
||||
|
||||
grunt.file.write(desktopInstallFile, filled)
|
||||
|
||||
# Create relative symbol link for apm.
|
||||
process.chdir(binDir)
|
||||
|
||||
@@ -2,16 +2,27 @@ fs = require 'fs'
|
||||
path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
fillTemplate = (filePath, data) ->
|
||||
template = _.template(String(fs.readFileSync(filePath + '.in')))
|
||||
filled = template(data)
|
||||
fs.writeFileSync(filePath, filled)
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{spawn} = 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
|
||||
|
||||
getInstalledSize = (buildDir, callback) ->
|
||||
cmd = 'du'
|
||||
args = ['-sk', path.join(buildDir, 'Atom')]
|
||||
spawn {cmd, args}, (error, {stdout}) ->
|
||||
installedSize = stdout.split(/\s+/)?[0] or '200000' # default to 200MB
|
||||
callback(null, installedSize)
|
||||
|
||||
grunt.registerTask 'mkdeb', 'Create debian package', ->
|
||||
done = @async()
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
|
||||
if process.arch is 'ia32'
|
||||
arch = 'i386'
|
||||
@@ -25,15 +36,17 @@ module.exports = (grunt) ->
|
||||
maintainer = 'GitHub <atom@github.com>'
|
||||
installDir = '/usr'
|
||||
iconName = 'atom'
|
||||
data = {name, version, description, section, arch, maintainer, installDir, iconName}
|
||||
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)
|
||||
icon = path.join('resources', 'atom.png')
|
||||
|
||||
control = path.join('resources', 'linux', 'debian', 'control')
|
||||
fillTemplate(control, data)
|
||||
desktop = path.join('resources', 'linux', 'Atom.desktop')
|
||||
fillTemplate(desktop, data)
|
||||
icon = path.join('resources', 'atom.png')
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
|
||||
cmd = path.join('script', 'mkdeb')
|
||||
args = [version, arch, control, desktop, icon, buildDir]
|
||||
spawn({cmd, args}, done)
|
||||
cmd = path.join('script', 'mkdeb')
|
||||
args = [version, arch, controlFilePath, desktopFilePath, icon, buildDir]
|
||||
spawn {cmd, args}, (error) ->
|
||||
if error?
|
||||
done(error)
|
||||
else
|
||||
grunt.log.ok "Created #{buildDir}/atom-#{version}-#{arch}.deb"
|
||||
done()
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
path = require 'path'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
grunt.registerTask 'output-build-filetypes', 'Log counts for each filetype in the built application', ->
|
||||
shellAppDir = grunt.config.get('atom.shellAppDir')
|
||||
|
||||
types = {}
|
||||
grunt.file.recurse shellAppDir, (absolutePath, rootPath, relativePath, fileName) ->
|
||||
extension = path.extname(fileName) or fileName
|
||||
types[extension] ?= 0
|
||||
types[extension]++
|
||||
|
||||
extensions = Object.keys(types).sort (extension1, extension2) ->
|
||||
diff = types[extension2] - types[extension1]
|
||||
if diff is 0
|
||||
extension1.toLowerCase().localeCompare(extension2.toLowerCase())
|
||||
else
|
||||
diff
|
||||
|
||||
extensions.forEach (extension) ->
|
||||
grunt.log.error "#{extension}: #{types[extension]}"
|
||||
@@ -0,0 +1,18 @@
|
||||
path = require 'path'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
grunt.registerTask 'output-long-paths', 'Log long paths in the built application', ->
|
||||
shellAppDir = grunt.config.get('atom.shellAppDir')
|
||||
|
||||
longPaths = []
|
||||
grunt.file.recurse shellAppDir, (absolutePath, rootPath, relativePath, fileName) ->
|
||||
if relativePath
|
||||
fullPath = path.join(relativePath, fileName)
|
||||
else
|
||||
fullPath = fileName
|
||||
longPaths.push(fullPath) if fullPath.length >= 200
|
||||
|
||||
longPaths.sort (longPath1, longPath2) -> longPath2.length - longPath1.length
|
||||
|
||||
longPaths.forEach (longPath) ->
|
||||
grunt.log.error "#{longPath.length} character path: #{longPath}"
|
||||
@@ -9,10 +9,12 @@ module.exports = (grunt) ->
|
||||
['atom-dark-ui', 'atom-light-syntax']
|
||||
['atom-dark-ui', 'solarized-dark-syntax']
|
||||
['atom-dark-ui', 'base16-tomorrow-dark-theme']
|
||||
['atom-dark-ui', 'base16-tomorrow-light-theme']
|
||||
['atom-light-ui', 'atom-light-syntax']
|
||||
['atom-light-ui', 'atom-dark-syntax']
|
||||
['atom-light-ui', 'solarized-dark-syntax']
|
||||
['atom-light-ui', 'base16-tomorrow-dark-theme']
|
||||
['atom-light-ui', 'base16-tomorrow-light-theme']
|
||||
]
|
||||
|
||||
directory = path.join(grunt.config.get('atom.appDir'), 'less-compile-cache')
|
||||
|
||||
@@ -17,6 +17,7 @@ defaultHeaders =
|
||||
|
||||
module.exports = (gruntObject) ->
|
||||
grunt = 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'
|
||||
@@ -24,8 +25,10 @@ module.exports = (gruntObject) ->
|
||||
tasks.unshift('build-docs', 'prepare-docs') if process.platform is 'darwin'
|
||||
grunt.task.run(tasks)
|
||||
|
||||
grunt.registerTask 'prepare-docs', 'Move the build docs to the build dir', ->
|
||||
fs.copySync(grunt.config.get('docsOutputDir'), path.join(grunt.config.get('atom.buildDir'), 'atom-docs'))
|
||||
grunt.registerTask 'prepare-docs', 'Move api.json to atom-api.json', ->
|
||||
docsOutputDir = grunt.config.get('docsOutputDir')
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
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()
|
||||
@@ -46,7 +49,7 @@ getAssets = ->
|
||||
[
|
||||
{assetName: 'atom-mac.zip', sourcePath: 'Atom.app'}
|
||||
{assetName: 'atom-mac-symbols.zip', sourcePath: 'Atom.breakpad.syms'}
|
||||
{assetName: 'atom-docs.zip', sourcePath: 'atom-docs'}
|
||||
{assetName: 'atom-api.json', sourcePath: 'atom-api.json'}
|
||||
]
|
||||
else
|
||||
[
|
||||
@@ -70,7 +73,7 @@ zipAssets = (buildDir, assets, callback) ->
|
||||
callback(error)
|
||||
|
||||
tasks = []
|
||||
for {assetName, sourcePath} in assets
|
||||
for {assetName, sourcePath} in assets when path.extname(assetName) is '.zip'
|
||||
fs.removeSync(path.join(buildDir, assetName))
|
||||
tasks.push(zip.bind(this, buildDir, sourcePath, assetName))
|
||||
async.parallel(tasks, callback)
|
||||
|
||||
@@ -45,8 +45,8 @@ module.exports = (grunt) ->
|
||||
|
||||
strings =
|
||||
CompanyName: 'GitHub, Inc.'
|
||||
FileDescription: 'The hackable editor'
|
||||
LegalCopyright: 'Copyright (C) 2013 GitHub, Inc. All rights reserved'
|
||||
FileDescription: 'Atom'
|
||||
LegalCopyright: 'Copyright (C) 2014 GitHub, Inc. All rights reserved'
|
||||
ProductName: 'Atom'
|
||||
ProductVersion: version
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ fs = require 'fs'
|
||||
path = require 'path'
|
||||
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
async = require 'async'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
@@ -10,18 +9,27 @@ module.exports = (grunt) ->
|
||||
|
||||
packageSpecQueue = null
|
||||
|
||||
getAppPath = ->
|
||||
contentsDir = grunt.config.get('atom.contentsDir')
|
||||
switch process.platform
|
||||
when 'darwin'
|
||||
path.join(contentsDir, 'MacOS', 'Atom')
|
||||
when 'linux'
|
||||
path.join(contentsDir, 'atom')
|
||||
when 'win32'
|
||||
path.join(contentsDir, 'atom.exe')
|
||||
|
||||
runPackageSpecs = (callback) ->
|
||||
failedPackages = []
|
||||
rootDir = grunt.config.get('atom.shellAppDir')
|
||||
contentsDir = grunt.config.get('atom.contentsDir')
|
||||
resourcePath = process.cwd()
|
||||
if process.platform is 'darwin'
|
||||
appPath = path.join(contentsDir, 'MacOS', 'Atom')
|
||||
else if process.platform is 'win32'
|
||||
appPath = path.join(contentsDir, 'atom.exe')
|
||||
appPath = getAppPath()
|
||||
|
||||
# Ensure application is executable on Linux
|
||||
fs.chmodSync(appPath, '755') if process.platform is 'linux'
|
||||
|
||||
packageSpecQueue = async.queue (packagePath, callback) ->
|
||||
if process.platform is 'darwin'
|
||||
if process.platform in ['darwin', 'linux']
|
||||
options =
|
||||
cmd: appPath
|
||||
args: ['--test', "--resource-path=#{resourcePath}", "--spec-directory=#{path.join(packagePath, 'spec')}"]
|
||||
@@ -57,15 +65,11 @@ module.exports = (grunt) ->
|
||||
packageSpecQueue.drain = -> callback(null, failedPackages)
|
||||
|
||||
runCoreSpecs = (callback) ->
|
||||
contentsDir = grunt.config.get('atom.contentsDir')
|
||||
if process.platform is 'darwin'
|
||||
appPath = path.join(contentsDir, 'MacOS', 'Atom')
|
||||
else if process.platform is 'win32'
|
||||
appPath = path.join(contentsDir, 'atom.exe')
|
||||
appPath = getAppPath()
|
||||
resourcePath = process.cwd()
|
||||
coreSpecsPath = path.resolve('spec')
|
||||
|
||||
if process.platform is 'darwin'
|
||||
if process.platform in ['darwin', 'linux']
|
||||
options =
|
||||
cmd: appPath
|
||||
args: ['--test', "--resource-path=#{resourcePath}", "--spec-directory=#{coreSpecsPath}"]
|
||||
@@ -90,7 +94,7 @@ module.exports = (grunt) ->
|
||||
|
||||
# TODO: This should really be parallel on both platforms, however our
|
||||
# fixtures step on each others toes currently.
|
||||
if process.platform is 'darwin'
|
||||
if process.platform in ['darwin', 'linux']
|
||||
method = async.parallel
|
||||
else if process.platform is 'win32'
|
||||
method = async.series
|
||||
@@ -103,4 +107,9 @@ module.exports = (grunt) ->
|
||||
failures.push "atom core" if coreSpecFailed
|
||||
|
||||
grunt.log.error("[Error]".red + " #{failures.join(', ')} spec(s) failed") if failures.length > 0
|
||||
done(!coreSpecFailed and failedPackages.length == 0)
|
||||
|
||||
if process.platform is 'win32' and process.env.JANKY_SHA1
|
||||
# Package specs are still flaky on Windows CI
|
||||
done(!coreSpecFailed)
|
||||
else
|
||||
done(!coreSpecFailed and failedPackages.length == 0)
|
||||
|
||||
@@ -7,7 +7,7 @@ module.exports = (grunt) ->
|
||||
grunt.fatal("Cannot copy non-existent #{source.cyan} to #{destination.cyan}")
|
||||
|
||||
copyFile = (sourcePath, destinationPath) ->
|
||||
return if filter?.test(sourcePath)
|
||||
return if filter?(sourcePath) or filter?.test?(sourcePath)
|
||||
|
||||
stats = fs.lstatSync(sourcePath)
|
||||
if stats.isSymbolicLink()
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"max_line_length": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"no_empty_param_list": {
|
||||
"level": "error"
|
||||
},
|
||||
"arrow_spacing": {
|
||||
"level": "error"
|
||||
},
|
||||
"no_interpolation_in_single_quotes": {
|
||||
"level": "error"
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ character of the current line:
|
||||
class EditorView
|
||||
listenForEvents: ->
|
||||
@command 'editor:move-to-first-character-of-line', =>
|
||||
@editor.moveCursorToFirstCharacterOfLine()
|
||||
@editor.moveToFirstCharacterOfLine()
|
||||
```
|
||||
|
||||
The `::command` method is basically an enhanced version of jQuery's `::on`
|
||||
|
||||
+50
-8
@@ -1,4 +1,4 @@
|
||||
## Atom.io package and update API
|
||||
# Atom.io package and update API
|
||||
|
||||
This guide describes the web API used by [apm](https://github.com/atom/apm) and
|
||||
Atom. The vast majority of use cases are met by the `apm` command-line tool,
|
||||
@@ -8,6 +8,8 @@ and making sure you have pushed your git tag. In fact, Atom itself shells out to
|
||||
uses `apm`, see the [PackageManager class](https://github.com/atom/settings-view/blob/master/lib/package-manager.coffee)
|
||||
in the `settings-view` package.
|
||||
|
||||
*This API should be considered pre-release and is subject to change (though significant breaking changes are unlikely).*
|
||||
|
||||
### Authorization
|
||||
|
||||
For calls to the API that require authentication, provide a valid token from your
|
||||
@@ -17,12 +19,18 @@ For calls to the API that require authentication, provide a valid token from you
|
||||
|
||||
All requests that take parameters require `application/json`.
|
||||
|
||||
## Resources
|
||||
# API Resources
|
||||
|
||||
### Packages
|
||||
## Packages
|
||||
|
||||
### Listing packages
|
||||
|
||||
#### GET /api/packages
|
||||
|
||||
Parameters:
|
||||
|
||||
- **page** (optional)
|
||||
|
||||
Returns a list of all packages in the following format:
|
||||
```json
|
||||
[
|
||||
@@ -40,6 +48,17 @@ Returns a list of all packages in the following format:
|
||||
]
|
||||
```
|
||||
|
||||
Results are paginated 30 at a time, and links to the next and last pages are
|
||||
provided in the `Link` header:
|
||||
|
||||
```
|
||||
Link: <https://www.atom.io/api/packages?page=1>; rel="self",
|
||||
<https://www.atom.io/api/packages?page=41>; rel="last",
|
||||
<https://www.atom.io/api/packages?page=2>; rel="next"
|
||||
```
|
||||
|
||||
### Showing package details
|
||||
|
||||
#### GET /api/packages/:package_name
|
||||
|
||||
Returns package details and versions for a single package
|
||||
@@ -68,6 +87,8 @@ Returns:
|
||||
}
|
||||
```
|
||||
|
||||
### Creating a package
|
||||
|
||||
#### POST /api/packages
|
||||
|
||||
Create a new package; requires authentication.
|
||||
@@ -92,6 +113,7 @@ Returns:
|
||||
- The package.json at owner/repo isn't valid
|
||||
- **409** - A package by that name already exists
|
||||
|
||||
### Deleting a package
|
||||
|
||||
#### DELETE /api/packages/:package_name
|
||||
|
||||
@@ -103,6 +125,13 @@ Returns:
|
||||
- **400** - Repository is inaccessible
|
||||
- **401** - Unauthorized
|
||||
|
||||
### Renaming a package
|
||||
|
||||
Packages are renamed by publishing a new version with the name changed in `package.json`
|
||||
See [Creating a new package version](#creating-a-new-package-version) for details.
|
||||
|
||||
Requests made to the previous name will forward to the new name.
|
||||
|
||||
### Package Versions
|
||||
|
||||
#### GET /api/packages/:package_name/versions/:version_name
|
||||
@@ -144,7 +173,9 @@ Returns `package.json` with `dist` key added for e.g. tarball download:
|
||||
|
||||
#### POST /api/packages/:package_name/versions
|
||||
|
||||
Creates a new package version from a git tag; requires authentication.
|
||||
Creates a new package version from a git tag; requires authentication. If `rename`
|
||||
is not `true`, the `name` field in `package.json` *must* match the current package
|
||||
name.
|
||||
|
||||
#### Parameters
|
||||
|
||||
@@ -152,14 +183,15 @@ Creates a new package version from a git tag; requires authentication.
|
||||
that the version name will not be taken from the tag, but from the `version`
|
||||
key in the `package.json` file at that ref. The authenticating user *must* have
|
||||
access to the package repository.
|
||||
- **rename** - Boolean indicating whether this version contains a new name for the package.
|
||||
|
||||
#### Returns
|
||||
|
||||
- **201** - Successfully created. Returns created version.
|
||||
- **400** - Git tag not found / Repository inaccessible
|
||||
- **400** - Git tag not found / Repository inaccessible / package.json invalid
|
||||
- **409** - Version exists
|
||||
|
||||
### Delete a version
|
||||
### Deleting a version
|
||||
|
||||
#### DELETE /api/packages/:package_name/versions/:version_name
|
||||
|
||||
@@ -172,7 +204,9 @@ you'll need to increment the version when republishing.
|
||||
Returns 204 No Content
|
||||
|
||||
|
||||
### Stars
|
||||
## Stars
|
||||
|
||||
### Listing user stars
|
||||
|
||||
#### GET /api/users/:login/stars
|
||||
|
||||
@@ -186,18 +220,24 @@ List the authenticated user's starred packages; requires authentication.
|
||||
|
||||
Return value is similar to **GET /api/packages**
|
||||
|
||||
### Starring a package
|
||||
|
||||
#### POST /api/packages/:name/star
|
||||
|
||||
Star a package; requires authentication.
|
||||
|
||||
Returns a package.
|
||||
|
||||
### Unstarring a package
|
||||
|
||||
#### DELETE /api/packages/:name/star
|
||||
|
||||
Unstar a package; requires authentication.
|
||||
|
||||
Returns 204 No Content.
|
||||
|
||||
### Listing a package's stargazers
|
||||
|
||||
#### GET /api/packages/:name/stargazers
|
||||
|
||||
List the users that have starred a package.
|
||||
@@ -211,7 +251,9 @@ Returns a list of user objects:
|
||||
]
|
||||
```
|
||||
|
||||
### Atom updates
|
||||
## Atom updates
|
||||
|
||||
### Listing Atom updates
|
||||
|
||||
#### GET /api/updates
|
||||
|
||||
|
||||
@@ -6,38 +6,70 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
|
||||
|
||||
* OS with 64-bit or 32-bit architecture
|
||||
* C++ toolchain
|
||||
* on Ubuntu/Debian: `sudo apt-get install build-essential`
|
||||
* on Fedora: `sudo yum --assumeyes install make gcc gcc-c++ glibc-devel`
|
||||
* [node.js](http://nodejs.org/download/) v0.10.x
|
||||
* [Ubuntu/Debian/Mint instructions](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os)
|
||||
* [Fedora instructions](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#fedora)
|
||||
* [npm](http://www.npmjs.org/) v1.4.x
|
||||
* `npm` comes with node.js so no explicit installation is needed here.
|
||||
* You can check `npm` 1.4 or above is installed by running `npm -v`.
|
||||
* libgnome-keyring-dev
|
||||
* on Ubuntu/Debian: `sudo apt-get install libgnome-keyring-dev`
|
||||
* on Fedora: `sudo yum --assumeyes install libgnome-keyring-devel`
|
||||
* on other distributions refer to the manual on how to install packages
|
||||
* `npm config set python /usr/bin/python2 -g` to ensure that gyp uses Python 2
|
||||
* This command may require `sudo` depending on how you have
|
||||
[configured npm](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
|
||||
* Git
|
||||
* on Ubuntu/Debian: `sudo apt-get install git`
|
||||
* on Fedora: `sudo yum install git-core`
|
||||
* [Git](http://git-scm.com/)
|
||||
* [Node.js](http://nodejs.org/download/) v0.10.x
|
||||
* [npm](http://www.npmjs.org/) v1.4.x (bundled with Node.js)
|
||||
* `npm -v` to check the version.
|
||||
* `npm config set python /usr/bin/python2 -g` to ensure that gyp uses python2.
|
||||
* You might need to run this command as `sudo`, depending on how you have set up [npm](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
|
||||
* development headers for [GNOME Keyring](https://wiki.gnome.org/Projects/GnomeKeyring)
|
||||
|
||||
### Ubuntu / Debian
|
||||
|
||||
* `sudo apt-get install build-essential git libgnome-keyring-dev`
|
||||
* Instructions for [Node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
|
||||
|
||||
### Fedora
|
||||
|
||||
* `sudo yum --assumeyes install make gcc gcc-c++ glibc-devel git-core libgnome-keyring-devel`
|
||||
* 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`
|
||||
* `export PYTHON=/usr/bin/python2` before building Atom.
|
||||
|
||||
## Instructions
|
||||
|
||||
```sh
|
||||
git clone https://github.com/atom/atom
|
||||
cd atom
|
||||
script/build # Creates application at $TMPDIR/atom-build/Atom
|
||||
sudo script/grunt install # Installs command to /usr/local/bin/atom
|
||||
script/grunt mkdeb # Generates a .deb package at $TMPDIR/atom-build
|
||||
```
|
||||
If you have problems with permissions don't forget to prefix with `sudo`
|
||||
|
||||
From the cloned repository directory:
|
||||
|
||||
1. Build:
|
||||
|
||||
```sh
|
||||
$ script/build
|
||||
```
|
||||
This will create the atom application at `$TMPDIR/atom-build/Atom`.
|
||||
2. Install the `atom` and `apm` commands to `/usr/local/bin` by executing:
|
||||
|
||||
```sh
|
||||
$ sudo script/grunt install
|
||||
```
|
||||
3. *Optionally*, you may generate a `.deb` package at `$TMPDIR/atom-build`:
|
||||
|
||||
```sh
|
||||
$ script/grunt mkdeb
|
||||
```
|
||||
|
||||
Use the newly installed atom by restarting any running atom instances.
|
||||
|
||||
## Advanced Options
|
||||
|
||||
### Custom install directory
|
||||
|
||||
```sh
|
||||
sudo script/grunt install --install-dir /install/atom/here
|
||||
```
|
||||
|
||||
### Custom build directory
|
||||
|
||||
```sh
|
||||
script/build --build-dir /build/atom/here
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
||||
### Exception: "TypeError: Unable to watch path"
|
||||
|
||||
If you get following error with a big traceback right after Atom starts:
|
||||
@@ -56,7 +88,7 @@ this is the reason for this error you can issue
|
||||
and restart Atom. If Atom now works fine, you can make this setting permanent:
|
||||
|
||||
```sh
|
||||
echo 32768 > /proc/sys/fs/inotify/max_user_watches
|
||||
echo 32768 | sudo tee -a /proc/sys/fs/inotify/max_user_watches
|
||||
```
|
||||
|
||||
See also https://github.com/atom/atom/issues/2082.
|
||||
@@ -64,10 +96,19 @@ See also https://github.com/atom/atom/issues/2082.
|
||||
### /usr/bin/env: node: No such file or directory
|
||||
|
||||
If you get this notice when attempting to `script/build`, you either do not
|
||||
have nodejs installed, or node isn't identified as nodejs on your machine.
|
||||
have Node.js installed, or node isn't identified as Node.js on your machine.
|
||||
If it's the latter, entering `sudo ln -s /usr/bin/nodejs /usr/bin/node` into
|
||||
your terminal may fix the issue.
|
||||
|
||||
#### You can also use Alternatives
|
||||
|
||||
On some variants (mostly Debian based distros) it's preferable for you to use
|
||||
Alternatives so that changes to the binary paths can be fixed or altered easily:
|
||||
|
||||
```sh
|
||||
sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 1 --slave /usr/bin/js js /usr/bin/nodejs
|
||||
```
|
||||
|
||||
### Linux build error reports in atom/atom
|
||||
* Use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Alinux&type=Issues)
|
||||
to get a list of reports about build errors on Linux.
|
||||
|
||||
@@ -35,10 +35,14 @@
|
||||
|
||||
## 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. You need to have Posix tools in your `%PATH%` (i.e. `grep`,
|
||||
`sed`, et al.), which isn't the default configuration when you install Git. To
|
||||
fix this, you probably need to fiddle with your system PATH.
|
||||
You don't. You can use your existing Git! GitHub for Windows's Git Shell is just
|
||||
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.
|
||||
|
||||
If none of this works, do install Github for Windows and use its Git shell. Makes life easier.
|
||||
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -62,5 +66,24 @@ fix this, you probably need to fiddle with your system PATH.
|
||||
* https://github.com/TooTallNate/node-gyp/issues/297
|
||||
* 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`:
|
||||
|
||||
```
|
||||
$env:GYP_MSVS_VERSION=2013
|
||||
```
|
||||
|
||||
* Other `node-gyp` errors on first build attempt, even though the right node and python versions are installed.
|
||||
* Do try the build command one more time, as experience shows it often works on second try in many of these cases.
|
||||
|
||||
|
||||
### Windows build error reports in atom/atom
|
||||
* Use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Awindows&type=Issues) to get a list of reports about build errors on Windows.
|
||||
* If all fails, use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Awindows&type=Issues) to get a list of reports about build errors on Windows, and see if yours has already been reported.
|
||||
|
||||
* If it hasn't, please open a new issue with your Windows version 32/64bit and a print/screenshot of your build output, incl. the node and python versions.
|
||||
|
||||
@@ -227,15 +227,16 @@ or one of its parents has the `tree-view` class applied to it.
|
||||
|
||||
You can also add separators and submenus to your context menus. To add a
|
||||
submenu, pass in another object instead of a command. To add a separator, use
|
||||
`-` for the name and command of the item.
|
||||
`-` for the command of the item.
|
||||
|
||||
```coffeescript
|
||||
'context-menu':
|
||||
'.workspace':
|
||||
'Inspect Element': 'core:inspect'
|
||||
'-': '-'
|
||||
'Separator': '-'
|
||||
'Text':
|
||||
'Select All': 'core:select-all'
|
||||
'Another Separator': '-'
|
||||
'Deleted Selected Text': 'core:delete'
|
||||
```
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ You can open this file in an editor from the _Atom > Open Your Config_ menu.
|
||||
- `showInvisibles`: Whether to render placeholders for invisible characters (defaults to `false`)
|
||||
- `showIndentGuide`: Show/hide indent indicators within the editor
|
||||
- `showLineNumbers`: Show/hide line numbers within the gutter
|
||||
- `softWrap`: Enable/disable soft wrapping of text within the editor
|
||||
- `softWrapped`: Enable/disable soft wrapping of text within the editor
|
||||
- `softWrapAtPreferredLineLength`: Enable/disable soft line wrapping at `preferredLineLength`
|
||||
- `tabLength`: Number of spaces within a tab (defaults to `2`)
|
||||
- `fuzzyFinder`
|
||||
|
||||
@@ -53,7 +53,7 @@ module.exports =
|
||||
|
||||
convert: ->
|
||||
# This assumes the active pane item is an editor
|
||||
editor = atom.workspace.activePaneItem
|
||||
editor = atom.workspace.getActivePaneItem()
|
||||
editor.insertText('Hello, World!')
|
||||
```
|
||||
|
||||
@@ -131,8 +131,8 @@ inserting 'Hello, World!' convert the selected text to ASCII art.
|
||||
```coffeescript
|
||||
convert: ->
|
||||
# This assumes the active pane item is an editor
|
||||
editor = atom.workspace.activePaneItem
|
||||
selection = editor.getSelection()
|
||||
editor = atom.workspace.getActivePaneItem()
|
||||
selection = editor.getLastSelection()
|
||||
|
||||
figlet = require 'figlet'
|
||||
figlet selection.getText(), {font: "Larry 3D 2"}, (error, asciiArt) ->
|
||||
|
||||
@@ -11,4 +11,4 @@
|
||||
# atom.workspaceView.eachEditorView (editorView) ->
|
||||
# editor = editorView.getEditor()
|
||||
# if path.extname(editor.getPath()) is '.md'
|
||||
# editor.setSoftWrap(true)
|
||||
# editor.setSoftWrapped(true)
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
# 'enter': 'editor:newline'
|
||||
#
|
||||
# '.workspace':
|
||||
# 'ctrl-P': 'core:move-up'
|
||||
# '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
|
||||
|
||||
@@ -22,3 +22,5 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
|
||||
module.exports.View = View
|
||||
module.exports.WorkspaceView = require '../src/workspace-view'
|
||||
module.exports.Workspace = require '../src/workspace'
|
||||
module.exports.React = require 'react-atom-fork'
|
||||
module.exports.Reactionary = require 'reactionary-atom-fork'
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
# Sublime Parity
|
||||
'tab': 'editor:indent'
|
||||
'enter': 'editor:newline'
|
||||
'num-enter': 'editor:newline'
|
||||
'shift-tab': 'editor:outdent-selected-rows'
|
||||
'ctrl-K': 'editor:delete-line'
|
||||
|
||||
@@ -27,7 +26,6 @@
|
||||
'tab': 'core:focus-next'
|
||||
'shift-tab': 'core:focus-previous'
|
||||
'enter': 'native!'
|
||||
'num-enter': 'native!'
|
||||
'backspace': 'native!'
|
||||
'shift-backspace': 'native!'
|
||||
'delete': 'native!'
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
'cmd-O': 'application:open-dev'
|
||||
'cmd-alt-ctrl-s': 'application:run-all-specs'
|
||||
'enter': 'core:confirm'
|
||||
'num-enter': 'core:confirm'
|
||||
'escape': 'core:cancel'
|
||||
'up': 'core:move-up'
|
||||
'down': 'core:move-down'
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
'body':
|
||||
# Atom Specific
|
||||
'enter': 'core:confirm'
|
||||
'num-enter': 'core:confirm'
|
||||
'escape': 'core:cancel'
|
||||
'up': 'core:move-up'
|
||||
'down': 'core:move-down'
|
||||
@@ -11,10 +10,12 @@
|
||||
'ctrl-shift-i': 'window:toggle-dev-tools'
|
||||
'ctrl-alt-p': 'window:run-package-specs'
|
||||
'ctrl-alt-s': 'application:run-all-specs'
|
||||
'ctrl-shift-o': 'application:open-dev'
|
||||
'ctrl-alt-o': 'application:open-dev'
|
||||
'ctrl-shift-o': 'application:open-folder'
|
||||
'F11': 'window:toggle-full-screen'
|
||||
|
||||
# Sublime Parity
|
||||
'ctrl-,': 'application:show-settings'
|
||||
'ctrl-N': 'application:new-window'
|
||||
'ctrl-W': 'window:close'
|
||||
'ctrl-o': 'application:open-file'
|
||||
@@ -26,6 +27,7 @@
|
||||
'ctrl-w': 'core:close'
|
||||
'ctrl-z': 'core:undo'
|
||||
'ctrl-y': 'core:redo'
|
||||
'ctrl-shift-z': 'core:redo'
|
||||
'ctrl-x': 'core:cut'
|
||||
'ctrl-c': 'core:copy'
|
||||
'ctrl-v': 'core:paste'
|
||||
@@ -38,7 +40,7 @@
|
||||
'shift-pageup': 'core:select-page-up'
|
||||
'shift-pagedown': 'core:select-page-down'
|
||||
'delete': 'core:delete'
|
||||
'shift-delete': 'core:delete'
|
||||
'shift-delete': 'core:cut'
|
||||
'pageup': 'core:page-up'
|
||||
'pagedown': 'core:page-down'
|
||||
'backspace': 'core:backspace'
|
||||
@@ -95,6 +97,7 @@
|
||||
'ctrl-alt-shift-p': 'editor:log-cursor-scope'
|
||||
'ctrl-k ctrl-u': 'editor:upper-case'
|
||||
'ctrl-k ctrl-l': 'editor:lower-case'
|
||||
'ctrl-l': 'editor:select-line'
|
||||
|
||||
'.workspace .editor:not(.mini)':
|
||||
# Atom specific
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
# Atom Specific
|
||||
'enter': 'core:confirm'
|
||||
'num-enter': 'core:confirm'
|
||||
'escape': 'core:cancel'
|
||||
'up': 'core:move-up'
|
||||
'down': 'core:move-down'
|
||||
@@ -18,6 +17,7 @@
|
||||
'F11': 'window:toggle-full-screen'
|
||||
|
||||
# Sublime Parity
|
||||
'ctrl-,': 'application:show-settings'
|
||||
'ctrl-N': 'application:new-window'
|
||||
'ctrl-W': 'window:close'
|
||||
'ctrl-o': 'application:open-file'
|
||||
@@ -25,8 +25,10 @@
|
||||
'ctrl-n': 'application:new-file'
|
||||
'ctrl-s': 'core:save'
|
||||
'ctrl-S': 'core:save-as'
|
||||
'ctrl-f4': 'core:close'
|
||||
'ctrl-w': 'core:close'
|
||||
'ctrl-z': 'core:undo'
|
||||
'ctrl-shift-z': 'core:redo'
|
||||
'ctrl-y': 'core:redo'
|
||||
'ctrl-x': 'core:cut'
|
||||
'ctrl-c': 'core:copy'
|
||||
@@ -40,7 +42,7 @@
|
||||
'shift-pageup': 'core:select-page-up'
|
||||
'shift-pagedown': 'core:select-page-down'
|
||||
'delete': 'core:delete'
|
||||
'shift-delete': 'core:delete'
|
||||
'shift-delete': 'core:cut'
|
||||
'pageup': 'core:page-up'
|
||||
'pagedown': 'core:page-down'
|
||||
'backspace': 'core:backspace'
|
||||
@@ -82,12 +84,15 @@
|
||||
'ctrl-delete': 'editor:delete-to-end-of-word'
|
||||
'ctrl-home': 'core:move-to-top'
|
||||
'ctrl-end': 'core:move-to-bottom'
|
||||
'ctrl-shift-home': 'core:select-to-top'
|
||||
'ctrl-shift-end': 'core:select-to-bottom'
|
||||
|
||||
# Sublime Parity
|
||||
'ctrl-a': 'core:select-all'
|
||||
'ctrl-alt-shift-p': 'editor:log-cursor-scope'
|
||||
'ctrl-k ctrl-u': 'editor:upper-case'
|
||||
'ctrl-k ctrl-l': 'editor:lower-case'
|
||||
'ctrl-l': 'editor:select-line'
|
||||
|
||||
'.workspace .editor:not(.mini)':
|
||||
# Atom specific
|
||||
|
||||
+14
-2
@@ -18,6 +18,8 @@
|
||||
{ type: 'separator' }
|
||||
{ label: 'Install Shell Commands', command: 'window:install-shell-commands' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Services', submenu: [] }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Hide Atom', command: 'application:hide' }
|
||||
{ label: 'Hide Others', command: 'application:hide-other-applications' }
|
||||
{ label: 'Show All', command: 'application:unhide-all-applications' }
|
||||
@@ -37,7 +39,7 @@
|
||||
{ label: 'Save As...', command: 'core:save-as' }
|
||||
{ label: 'Save All', command: 'window:save-all' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Close Buffer', command: 'core:close' }
|
||||
{ label: 'Close Tab', command: 'core:close' }
|
||||
{ label: 'Close Pane', command: 'pane:close' }
|
||||
{ label: 'Close Window', command: 'window:close' }
|
||||
]
|
||||
@@ -164,7 +166,7 @@
|
||||
]
|
||||
}
|
||||
{ type: 'separator' }
|
||||
{ label: 'Toggle Soft Wrap', command: 'editor:toggle-soft-wrap' }
|
||||
{ label: 'Toggle Soft Wrap', command: 'editor:toggle-soft-wrapped' }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -192,3 +194,13 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.overlayer':
|
||||
'Undo': 'core:undo'
|
||||
'Redo': 'core:redo'
|
||||
'Cut': 'core:cut'
|
||||
'Copy': 'core:copy'
|
||||
'Paste': 'core:paste'
|
||||
'Delete': 'core:delete'
|
||||
'Select All': 'core:select-all'
|
||||
|
||||
+21
-15
@@ -8,14 +8,12 @@
|
||||
{ label: 'Open Folder...', command: 'application:open-folder' }
|
||||
{ label: 'Reopen Last &Item', command: 'pane:reopen-closed-item' }
|
||||
{ type: 'separator' }
|
||||
{ label: '&Preferences...', command: 'application:show-settings' }
|
||||
{ type: 'separator' }
|
||||
{ label: '&Save', command: 'core:save' }
|
||||
{ label: 'Save &As...', command: 'core:save-as' }
|
||||
{ label: 'Save A&ll', command: 'window:save-all' }
|
||||
{ type: 'separator' }
|
||||
{ label: '&Close Buffer', command: 'core:close' }
|
||||
{ label: 'Close All &Buffers', command: 'pane:close' }
|
||||
{ label: '&Close Tab', command: 'core:close' }
|
||||
{ label: 'Close &Pane', command: 'pane:close' }
|
||||
{ label: 'Clos&e Window', command: 'window:close' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Quit', command: 'application:quit' }
|
||||
@@ -80,6 +78,14 @@
|
||||
{ label: 'Fold Level 9', command: 'editor:fold-at-indent-level-9' }
|
||||
]
|
||||
}
|
||||
{ type: 'separator' }
|
||||
{ label: '&Preferences', command: 'application:show-settings' }
|
||||
{ label: 'Open Your Config', command: 'application:open-your-config' }
|
||||
{ label: 'Open Your Init Script', command: 'application:open-your-init-script' }
|
||||
{ label: 'Open Your Keymap', command: 'application:open-your-keymap' }
|
||||
{ label: 'Open Your Snippets', command: 'application:open-your-snippets' }
|
||||
{ label: 'Open Your Stylesheet', command: 'application:open-your-stylesheet' }
|
||||
{ type: 'separator' }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -98,7 +104,7 @@
|
||||
]
|
||||
}
|
||||
{ type: 'separator' }
|
||||
{ label: 'Toggle Soft &Wrap', command: 'editor:toggle-soft-wrap' }
|
||||
{ label: 'Toggle Soft &Wrap', command: 'editor:toggle-soft-wrapped' }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -133,16 +139,6 @@
|
||||
submenu: []
|
||||
}
|
||||
|
||||
{
|
||||
label: '&Window'
|
||||
submenu: [
|
||||
{ label: 'Mi&nimize', command: 'application:minimize' }
|
||||
{ label: 'Ma&ximize', command: 'application:zoom' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Bring &All to Front', command: 'application:bring-all-windows-to-front' }
|
||||
]
|
||||
}
|
||||
|
||||
{
|
||||
label: '&Help'
|
||||
submenu: [
|
||||
@@ -155,3 +151,13 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.overlayer':
|
||||
'Undo': 'core:undo'
|
||||
'Redo': 'core:redo'
|
||||
'Cut': 'core:cut'
|
||||
'Copy': 'core:copy'
|
||||
'Paste': 'core:paste'
|
||||
'Delete': 'core:delete'
|
||||
'Select All': 'core:select-all'
|
||||
|
||||
+18
-13
@@ -9,13 +9,18 @@
|
||||
{ label: 'Reopen Last &Item', command: 'pane:reopen-closed-item' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Se&ttings', command: 'application:show-settings' }
|
||||
{ label: 'Open Your Config', command: 'application:open-your-config' }
|
||||
{ label: 'Open Your Init Script', command: 'application:open-your-init-script' }
|
||||
{ label: 'Open Your Keymap', command: 'application:open-your-keymap' }
|
||||
{ label: 'Open Your Snippets', command: 'application:open-your-snippets' }
|
||||
{ label: 'Open Your Stylesheet', command: 'application:open-your-stylesheet' }
|
||||
{ type: 'separator' }
|
||||
{ label: '&Save', command: 'core:save' }
|
||||
{ label: 'Save &As...', command: 'core:save-as' }
|
||||
{ label: 'Save A&ll', command: 'window:save-all' }
|
||||
{ type: 'separator' }
|
||||
{ label: '&Close Buffer', command: 'core:close' }
|
||||
{ label: 'Close All &Buffers', command: 'pane:close' }
|
||||
{ label: '&Close Tab', command: 'core:close' }
|
||||
{ label: 'Close &Pane', command: 'pane:close' }
|
||||
{ label: 'Clos&e Window', command: 'window:close' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'E&xit', command: 'application:quit' }
|
||||
@@ -117,7 +122,7 @@
|
||||
]
|
||||
}
|
||||
{ type: 'separator' }
|
||||
{ label: 'Toggle Soft &Wrap', command: 'editor:toggle-soft-wrap' }
|
||||
{ label: 'Toggle Soft &Wrap', command: 'editor:toggle-soft-wrapped' }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -152,16 +157,6 @@
|
||||
submenu: []
|
||||
}
|
||||
|
||||
{
|
||||
label: '&Window'
|
||||
submenu: [
|
||||
{ label: 'Mi&nimize', command: 'application:minimize' }
|
||||
{ label: 'Ma&ximize', command: 'application:zoom' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Bring &All to Front', command: 'application:bring-all-windows-to-front' }
|
||||
]
|
||||
}
|
||||
|
||||
{
|
||||
label: '&Help'
|
||||
submenu: [
|
||||
@@ -174,3 +169,13 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.overlayer':
|
||||
'Undo': 'core:undo'
|
||||
'Redo': 'core:redo'
|
||||
'Cut': 'core:cut'
|
||||
'Copy': 'core:copy'
|
||||
'Paste': 'core:paste'
|
||||
'Delete': 'core:delete'
|
||||
'Select All': 'core:select-all'
|
||||
|
||||
+81
-78
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "0.109.0",
|
||||
"version": "0.127.0",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/browser/main.js",
|
||||
"repository": {
|
||||
@@ -17,126 +17,129 @@
|
||||
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
|
||||
}
|
||||
],
|
||||
"atomShellVersion": "0.13.3",
|
||||
"atomShellVersion": "0.16.2",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "^0.27.0",
|
||||
"atom-keymap": "^2.1.0",
|
||||
"bootstrap": "git+https://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
|
||||
"clear-cut": "0.4.0",
|
||||
"coffee-script": "1.7.0",
|
||||
"coffeestack": "0.7.0",
|
||||
"delegato": "^1",
|
||||
"emissary": "^1.2.1",
|
||||
"first-mate": "^1.7.1",
|
||||
"fs-plus": "^2.2.3",
|
||||
"emissary": "^1.3.1",
|
||||
"event-kit": "0.7.1",
|
||||
"first-mate": "^2.1.0",
|
||||
"fs-plus": "^2.2.6",
|
||||
"fstream": "0.1.24",
|
||||
"fuzzaldrin": "^1.1",
|
||||
"git-utils": "^1.3",
|
||||
"grim": "0.11.0",
|
||||
"fuzzaldrin": "^2.1",
|
||||
"git-utils": "^2.1.4",
|
||||
"grim": "0.12.0",
|
||||
"guid": "0.0.10",
|
||||
"jasmine-tagged": "^1.1.2",
|
||||
"less-cache": "0.12.0",
|
||||
"less-cache": "0.14.0",
|
||||
"mixto": "^1",
|
||||
"mkdirp": "0.3.5",
|
||||
"nslog": "0.5.0",
|
||||
"oniguruma": "^1.0.6",
|
||||
"nslog": "^1.0.1",
|
||||
"oniguruma": "^3.0.4",
|
||||
"optimist": "0.4.0",
|
||||
"pathwatcher": "^1.3.2",
|
||||
"pathwatcher": "^2.1.1",
|
||||
"property-accessors": "^1",
|
||||
"q": "^1.0.1",
|
||||
"random-words": "0.0.1",
|
||||
"react-atom-fork": "^0.10.0",
|
||||
"reactionary-atom-fork": "^0.9.0",
|
||||
"runas": "0.5.4",
|
||||
"scandal": "0.16.0",
|
||||
"react-atom-fork": "^0.11.1",
|
||||
"reactionary-atom-fork": "^1.0.0",
|
||||
"runas": "1.0.1",
|
||||
"scandal": "1.0.0",
|
||||
"scoped-property-store": "^0.9.0",
|
||||
"scrollbar-style": "^0.4.0",
|
||||
"scrollbar-style": "^1.0.2",
|
||||
"season": "^1.0.2",
|
||||
"semver": "1.1.4",
|
||||
"serializable": "^1",
|
||||
"space-pen": "3.2.0",
|
||||
"space-pen": "3.4.7",
|
||||
"temp": "0.7.0",
|
||||
"text-buffer": "^2.4.2",
|
||||
"theorist": "^1",
|
||||
"underscore-plus": "^1.5.0",
|
||||
"text-buffer": "^3.2.4",
|
||||
"theorist": "^1.0.2",
|
||||
"underscore-plus": "^1.5.1",
|
||||
"vm-compatibility-layer": "0.1.0"
|
||||
},
|
||||
"packageDependencies": {
|
||||
"atom-dark-syntax": "0.19.0",
|
||||
"atom-dark-ui": "0.32.0",
|
||||
"atom-dark-ui": "0.34.0",
|
||||
"atom-light-syntax": "0.20.0",
|
||||
"atom-light-ui": "0.28.0",
|
||||
"base16-tomorrow-dark-theme": "0.19.0",
|
||||
"solarized-dark-syntax": "0.20.0",
|
||||
"solarized-light-syntax": "0.11.0",
|
||||
"archive-view": "0.33.0",
|
||||
"autocomplete": "0.28.0",
|
||||
"autoflow": "0.17.0",
|
||||
"autosave": "0.14.0",
|
||||
"background-tips": "0.15.0",
|
||||
"bookmarks": "0.26.0",
|
||||
"bracket-matcher": "0.48.0",
|
||||
"atom-light-ui": "0.29.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.36.0",
|
||||
"autocomplete": "0.32.0",
|
||||
"autoflow": "0.18.0",
|
||||
"autosave": "0.17.0",
|
||||
"background-tips": "0.16.0",
|
||||
"bookmarks": "0.28.0",
|
||||
"bracket-matcher": "0.55.0",
|
||||
"command-palette": "0.24.0",
|
||||
"deprecation-cop": "0.7.0",
|
||||
"dev-live-reload": "0.31.0",
|
||||
"exception-reporting": "0.18.0",
|
||||
"deprecation-cop": "0.10.0",
|
||||
"dev-live-reload": "0.34.0",
|
||||
"exception-reporting": "0.20.0",
|
||||
"feedback": "0.33.0",
|
||||
"find-and-replace": "0.124.0",
|
||||
"fuzzy-finder": "0.56.0",
|
||||
"git-diff": "0.34.0",
|
||||
"go-to-line": "0.23.0",
|
||||
"grammar-selector": "0.27.0",
|
||||
"find-and-replace": "0.134.0",
|
||||
"fuzzy-finder": "0.58.0",
|
||||
"git-diff": "0.39.0",
|
||||
"go-to-line": "0.25.0",
|
||||
"grammar-selector": "0.29.0",
|
||||
"image-view": "0.36.0",
|
||||
"keybinding-resolver": "0.18.0",
|
||||
"link": "0.24.0",
|
||||
"markdown-preview": "0.89.0",
|
||||
"metrics": "0.32.0",
|
||||
"open-on-github": "0.29.0",
|
||||
"incompatible-packages": "0.9.0",
|
||||
"keybinding-resolver": "0.19.0",
|
||||
"link": "0.25.0",
|
||||
"markdown-preview": "0.101.0",
|
||||
"metrics": "0.34.0",
|
||||
"open-on-github": "0.30.0",
|
||||
"package-generator": "0.31.0",
|
||||
"release-notes": "0.32.0",
|
||||
"settings-view": "0.132.0",
|
||||
"snippets": "0.47.0",
|
||||
"spell-check": "0.38.0",
|
||||
"status-bar": "0.41.0",
|
||||
"styleguide": "0.29.0",
|
||||
"symbols-view": "0.59.0",
|
||||
"tabs": "0.44.0",
|
||||
"timecop": "0.21.0",
|
||||
"tree-view": "0.108.0",
|
||||
"release-notes": "0.36.0",
|
||||
"settings-view": "0.142.0",
|
||||
"snippets": "0.52.0",
|
||||
"spell-check": "0.42.0",
|
||||
"status-bar": "0.44.0",
|
||||
"styleguide": "0.30.0",
|
||||
"symbols-view": "0.63.0",
|
||||
"tabs": "0.50.0",
|
||||
"timecop": "0.22.0",
|
||||
"tree-view": "0.115.0",
|
||||
"update-package-dependencies": "0.6.0",
|
||||
"welcome": "0.17.0",
|
||||
"whitespace": "0.23.0",
|
||||
"welcome": "0.18.0",
|
||||
"whitespace": "0.25.0",
|
||||
"wrap-guide": "0.21.0",
|
||||
|
||||
"language-c": "0.21.0",
|
||||
"language-coffee-script": "0.24.0",
|
||||
"language-c": "0.28.0",
|
||||
"language-coffee-script": "0.30.0",
|
||||
"language-css": "0.17.0",
|
||||
"language-gfm": "0.42.0",
|
||||
"language-gfm": "0.48.0",
|
||||
"language-git": "0.9.0",
|
||||
"language-go": "0.13.0",
|
||||
"language-html": "0.22.0",
|
||||
"language-hyperlink": "0.10.0",
|
||||
"language-go": "0.17.0",
|
||||
"language-html": "0.26.0",
|
||||
"language-hyperlink": "0.12.0",
|
||||
"language-java": "0.11.0",
|
||||
"language-javascript": "0.33.0",
|
||||
"language-javascript": "0.39.0",
|
||||
"language-json": "0.8.0",
|
||||
"language-less": "0.12.0",
|
||||
"language-make": "0.10.0",
|
||||
"language-less": "0.15.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.15.0",
|
||||
"language-property-list": "0.7.0",
|
||||
"language-python": "0.18.0",
|
||||
"language-ruby": "0.31.0",
|
||||
"language-ruby-on-rails": "0.15.0",
|
||||
"language-sass": "0.13.0",
|
||||
"language-python": "0.19.0",
|
||||
"language-ruby": "0.36.0",
|
||||
"language-ruby-on-rails": "0.18.0",
|
||||
"language-sass": "0.21.0",
|
||||
"language-shellscript": "0.8.0",
|
||||
"language-source": "0.7.0",
|
||||
"language-sql": "0.8.0",
|
||||
"language-source": "0.8.0",
|
||||
"language-sql": "0.10.0",
|
||||
"language-text": "0.6.0",
|
||||
"language-todo": "0.10.0",
|
||||
"language-todo": "0.11.0",
|
||||
"language-toml": "0.12.0",
|
||||
"language-xml": "0.15.0",
|
||||
"language-yaml": "0.11.0"
|
||||
"language-xml": "0.20.0",
|
||||
"language-yaml": "0.17.0"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -5,4 +5,5 @@ Exec=<%= installDir %>/share/atom/atom %U
|
||||
Icon=<%= iconName %>
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;Utility;TextEditor;
|
||||
Categories=GNOME;GTK;Utility;TextEditor;Development;
|
||||
MimeType=text/plain;
|
||||
|
||||
@@ -3,6 +3,6 @@ Version: <%= version %>
|
||||
Section: <%= section %>
|
||||
Priority: optional
|
||||
Architecture: <%= arch %>
|
||||
Installed-Size: `du -ks usr|cut -f 1`
|
||||
Installed-Size: <%= installedSize %>
|
||||
Maintainer: <%= maintainer %>
|
||||
Description: <%= description %>
|
||||
|
||||
Arquivo binário não exibido.
Arquivo binário não exibido.
+26
-5
@@ -44,23 +44,44 @@ function bootstrap() {
|
||||
var apmInstallCommand = npmPath + npmFlags + 'install';
|
||||
var apmInstallOptions = {cwd: apmInstallPath};
|
||||
var moduleInstallCommand = apmPath + ' install' + apmFlags;
|
||||
var dedupeCommand = apmPath + ' dedupe' + apmFlags;
|
||||
var dedupeApmCommand = apmPath + ' dedupe' + apmFlags;
|
||||
var dedupeNpmCommand = npmPath + npmFlags + 'dedupe';
|
||||
|
||||
if (process.argv.indexOf('--no-quiet') === -1) {
|
||||
buildInstallCommand += ' --quiet';
|
||||
apmInstallCommand += ' --quiet';
|
||||
moduleInstallCommand += ' --quiet';
|
||||
dedupeCommand += ' --quiet';
|
||||
dedupeApmCommand += ' --quiet';
|
||||
dedupeNpmCommand += ' --quiet';
|
||||
buildInstallOptions.ignoreStdout = true;
|
||||
apmInstallOptions.ignoreStdout = true;
|
||||
}
|
||||
|
||||
// apm ships with 32-bit node so make sure its native modules are compiled
|
||||
// for a 32-bit target architecture
|
||||
if (process.env.JANKY_SHA1 && process.platform === 'win32')
|
||||
apmInstallCommand += ' --arch=ia32';
|
||||
|
||||
var commands = [
|
||||
{command: buildInstallCommand, message: 'Installing build modules...', options: buildInstallOptions},
|
||||
{command: apmInstallCommand, message: 'Installing apm...', options: apmInstallOptions},
|
||||
{
|
||||
command: buildInstallCommand,
|
||||
message: 'Installing build modules...',
|
||||
options: buildInstallOptions
|
||||
},
|
||||
{
|
||||
command: apmInstallCommand,
|
||||
message: 'Installing apm...',
|
||||
options: apmInstallOptions
|
||||
},
|
||||
apmPath + ' clean' + apmFlags,
|
||||
moduleInstallCommand,
|
||||
dedupeCommand + ' ' + packagesToDedupe.join(' '),
|
||||
dedupeApmCommand + ' ' + packagesToDedupe.join(' '),
|
||||
{
|
||||
command: dedupeNpmCommand + ' request semver',
|
||||
options: {
|
||||
cwd: path.resolve(__dirname, '..', 'apm', 'node_modules', 'atom-package-manager')
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
process.chdir(path.dirname(__dirname));
|
||||
|
||||
@@ -24,6 +24,7 @@ var commands = [
|
||||
[home, '.atom', 'storage'],
|
||||
[home, '.atom', '.npm'],
|
||||
[home, '.atom', 'compile-cache'],
|
||||
[home, '.atom', 'atom-shell'],
|
||||
[tmpdir, 'atom-build'],
|
||||
[tmpdir, 'atom-cached-atom-shells'],
|
||||
];
|
||||
|
||||
+5
-4
@@ -13,21 +13,22 @@ CONTROL_FILE="$3"
|
||||
DESKTOP_FILE="$4"
|
||||
ICON_FILE="$5"
|
||||
DEB_PATH="$6"
|
||||
FILE_MODE=755
|
||||
|
||||
TARGET_ROOT="`mktemp -d`"
|
||||
chmod 755 "$TARGET_ROOT"
|
||||
TARGET="$TARGET_ROOT/atom-$VERSION-$ARCH"
|
||||
|
||||
mkdir -p "$TARGET/usr"
|
||||
mkdir -m $FILE_MODE -p "$TARGET/usr"
|
||||
env INSTALL_PREFIX="$TARGET/usr" script/grunt install
|
||||
|
||||
mkdir -p "$TARGET/DEBIAN"
|
||||
mkdir -m $FILE_MODE -p "$TARGET/DEBIAN"
|
||||
cp "$CONTROL_FILE" "$TARGET/DEBIAN/control"
|
||||
|
||||
mkdir -p "$TARGET/usr/share/applications"
|
||||
mkdir -m $FILE_MODE -p "$TARGET/usr/share/applications"
|
||||
cp "$DESKTOP_FILE" "$TARGET/usr/share/applications"
|
||||
|
||||
mkdir -p "$TARGET/usr/share/pixmaps"
|
||||
mkdir -m $FILE_MODE -p "$TARGET/usr/share/pixmaps"
|
||||
cp "$ICON_FILE" "$TARGET/usr/share/pixmaps"
|
||||
|
||||
dpkg-deb -b "$TARGET"
|
||||
|
||||
@@ -119,14 +119,14 @@ class AtomReporter extends View
|
||||
grim.clearDeprecations()
|
||||
|
||||
handleEvents: ->
|
||||
$(document).on "click", ".spec-toggle", ({currentTarget}) =>
|
||||
$(document).on "click", ".spec-toggle", ({currentTarget}) ->
|
||||
element = $(currentTarget)
|
||||
specFailures = element.parent().find('.spec-failures')
|
||||
specFailures.toggle()
|
||||
element.toggleClass('folded')
|
||||
false
|
||||
|
||||
$(document).on "click", ".deprecation-toggle", ({currentTarget}) =>
|
||||
$(document).on "click", ".deprecation-toggle", ({currentTarget}) ->
|
||||
element = $(currentTarget)
|
||||
deprecationList = $(document).find('.deprecation-list')
|
||||
deprecationList.toggle()
|
||||
|
||||
+36
-16
@@ -241,15 +241,15 @@ describe "the `atom` global", ->
|
||||
two = atom.themes.stringToId(two)
|
||||
three = atom.themes.stringToId(three)
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(one)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
|
||||
atom.packages.activatePackage("package-with-stylesheets-manifest")
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).toExist()
|
||||
expect(atom.themes.stylesheetElementForId(two)).toExist()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
|
||||
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", ->
|
||||
@@ -263,14 +263,14 @@ describe "the `atom` global", ->
|
||||
two = atom.themes.stringToId(two)
|
||||
three = atom.themes.stringToId(three)
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(one)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
|
||||
atom.packages.activatePackage("package-with-stylesheets")
|
||||
expect(atom.themes.stylesheetElementForId(one)).toExist()
|
||||
expect(atom.themes.stylesheetElementForId(two)).toExist()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toExist()
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toBeNull()
|
||||
expect($('#jasmine-content').css('font-size')).toBe '3px'
|
||||
|
||||
describe "grammar loading", ->
|
||||
@@ -493,13 +493,14 @@ describe "the `atom` global", ->
|
||||
expect(atom.config.get('core.disabledPackages')).toContain packageName
|
||||
|
||||
describe "with themes", ->
|
||||
reloadedHandler = null
|
||||
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
atom.themes.activateThemes()
|
||||
|
||||
afterEach ->
|
||||
atom.themes.deactivateThemes()
|
||||
atom.config.unobserve('core.themes')
|
||||
|
||||
it ".enablePackage() and .disablePackage() enables and disables a theme", ->
|
||||
packageName = 'theme-with-package-file'
|
||||
@@ -517,13 +518,17 @@ describe "the `atom` global", ->
|
||||
expect(atom.config.get('core.themes')).toContain packageName
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
# disabling of theme
|
||||
reloadedHandler = jasmine.createSpy('reloadedHandler')
|
||||
reloadedHandler.reset()
|
||||
atom.themes.onDidReloadAll reloadedHandler
|
||||
|
||||
pack = atom.packages.disablePackage(packageName)
|
||||
|
||||
waitsFor ->
|
||||
not (pack in atom.packages.getActivePackages())
|
||||
reloadedHandler.callCount is 1
|
||||
|
||||
runs ->
|
||||
expect(atom.packages.getActivePackages()).not.toContain pack
|
||||
expect(atom.config.get('core.themes')).not.toContain packageName
|
||||
expect(atom.config.get('core.themes')).not.toContain packageName
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
@@ -531,7 +536,22 @@ describe "the `atom` global", ->
|
||||
describe ".isReleasedVersion()", ->
|
||||
it "returns false if the version is a SHA and true otherwise", ->
|
||||
version = '0.1.0'
|
||||
spyOn(atom.constructor, 'getVersion').andCallFake -> version
|
||||
spyOn(atom, 'getVersion').andCallFake -> version
|
||||
expect(atom.isReleasedVersion()).toBe true
|
||||
version = '36b5518'
|
||||
expect(atom.isReleasedVersion()).toBe false
|
||||
|
||||
describe "window:update-available", ->
|
||||
it "is triggered when the auto-updater sends the update-downloaded event", ->
|
||||
updateAvailableHandler = jasmine.createSpy("update-available-handler")
|
||||
atom.workspaceView.on 'window:update-available', updateAvailableHandler
|
||||
autoUpdater = require('remote').require('auto-updater')
|
||||
autoUpdater.emit 'update-downloaded', null, "notes", "version"
|
||||
|
||||
waitsFor ->
|
||||
updateAvailableHandler.callCount > 0
|
||||
|
||||
runs ->
|
||||
[event, version, notes] = updateAvailableHandler.mostRecentCall.args
|
||||
expect(notes).toBe 'notes'
|
||||
expect(version).toBe 'version'
|
||||
|
||||
@@ -23,6 +23,18 @@ describe "Config", ->
|
||||
retrievedValue.array[1].b = 2.1
|
||||
expect(atom.config.get('value')).toEqual(array: [1, b: 2, 3])
|
||||
|
||||
it "merges defaults into the returned value if both the assigned value and the default value are objects", ->
|
||||
atom.config.setDefaults("foo", a: 1, b: 2)
|
||||
atom.config.set("foo", a: 3)
|
||||
expect(atom.config.get("foo")).toEqual {a: 3, b: 2}
|
||||
|
||||
atom.config.set("foo", 7)
|
||||
expect(atom.config.get("foo")).toBe 7
|
||||
|
||||
atom.config.set("bar.baz", a: 3)
|
||||
atom.config.setDefaults("bar", baz: 7)
|
||||
expect(atom.config.get("bar.baz")).toEqual {a: 3}
|
||||
|
||||
describe ".set(keyPath, value)", ->
|
||||
it "allows a key path's value to be written", ->
|
||||
expect(atom.config.set("foo.bar.baz", 42)).toBe 42
|
||||
|
||||
@@ -6,7 +6,8 @@ describe "ContextMenuManager", ->
|
||||
[contextMenu] = []
|
||||
|
||||
beforeEach ->
|
||||
contextMenu = new ContextMenuManager
|
||||
{resourcePath} = atom.getLoadSettings()
|
||||
contextMenu = new ContextMenuManager({resourcePath})
|
||||
|
||||
describe "adding definitions", ->
|
||||
it 'loads', ->
|
||||
@@ -30,6 +31,16 @@ describe "ContextMenuManager", ->
|
||||
expect(contextMenu.definitions['.selector'][0].command).toEqual 'command'
|
||||
expect(contextMenu.definitions['.selector'].length).toBe 1
|
||||
|
||||
it 'allows multiple separators', ->
|
||||
contextMenu.add 'file-path',
|
||||
'.selector':
|
||||
'separator1': '-'
|
||||
'separator2': '-'
|
||||
|
||||
expect(contextMenu.definitions['.selector'].length).toBe 2
|
||||
expect(contextMenu.definitions['.selector'][0].type).toEqual 'separator'
|
||||
expect(contextMenu.definitions['.selector'][1].type).toEqual 'separator'
|
||||
|
||||
it 'allows duplicate commands with different labels', ->
|
||||
contextMenu.add 'file-path',
|
||||
'.selector':
|
||||
|
||||
+159
-133
@@ -9,7 +9,7 @@ describe "DisplayBuffer", ->
|
||||
buffer = atom.project.bufferForPathSync('sample.js')
|
||||
displayBuffer = new DisplayBuffer({buffer, tabLength})
|
||||
changeHandler = jasmine.createSpy 'changeHandler'
|
||||
displayBuffer.on 'changed', changeHandler
|
||||
displayBuffer.onDidChange changeHandler
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-javascript')
|
||||
@@ -58,7 +58,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
describe "soft wrapping", ->
|
||||
beforeEach ->
|
||||
displayBuffer.setSoftWrap(true)
|
||||
displayBuffer.setSoftWrapped(true)
|
||||
displayBuffer.setEditorWidthInChars(50)
|
||||
changeHandler.reset()
|
||||
|
||||
@@ -67,48 +67,48 @@ describe "DisplayBuffer", ->
|
||||
it "uses the preferred line length as the soft wrap column when it is less than the configured soft wrap column", ->
|
||||
atom.config.set('editor.preferredLineLength', 100)
|
||||
atom.config.set('editor.softWrapAtPreferredLineLength', true)
|
||||
expect(displayBuffer.lineForRow(10).text).toBe ' return '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' return '
|
||||
|
||||
atom.config.set('editor.preferredLineLength', 5)
|
||||
expect(displayBuffer.lineForRow(10).text).toBe 'funct'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe 'funct'
|
||||
|
||||
atom.config.set('editor.softWrapAtPreferredLineLength', false)
|
||||
expect(displayBuffer.lineForRow(10).text).toBe ' return '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' return '
|
||||
|
||||
describe "when the line is shorter than the max line length", ->
|
||||
it "renders the line unchanged", ->
|
||||
expect(displayBuffer.lineForRow(0).text).toBe buffer.lineForRow(0)
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe buffer.lineForRow(0)
|
||||
|
||||
describe "when the line is empty", ->
|
||||
it "renders the empty line", ->
|
||||
expect(displayBuffer.lineForRow(13).text).toBe ''
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(13).text).toBe ''
|
||||
|
||||
describe "when there is a non-whitespace character at the max length boundary", ->
|
||||
describe "when there is whitespace before the boundary", ->
|
||||
it "wraps the line at the end of the first whitespace preceding the boundary", ->
|
||||
expect(displayBuffer.lineForRow(10).text).toBe ' return '
|
||||
expect(displayBuffer.lineForRow(11).text).toBe 'sort(left).concat(pivot).concat(sort(right));'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' return '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(11).text).toBe 'sort(left).concat(pivot).concat(sort(right));'
|
||||
|
||||
describe "when there is no whitespace before the boundary", ->
|
||||
it "wraps the line exactly at the boundary since there's no more graceful place to wrap it", ->
|
||||
buffer.setTextInRange([[0, 0], [1, 0]], 'abcdefghijklmnopqrstuvwxyz\n')
|
||||
displayBuffer.setEditorWidthInChars(10)
|
||||
expect(displayBuffer.lineForRow(0).text).toBe 'abcdefghij'
|
||||
expect(displayBuffer.lineForRow(1).text).toBe 'klmnopqrst'
|
||||
expect(displayBuffer.lineForRow(2).text).toBe 'uvwxyz'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe 'abcdefghij'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe 'klmnopqrst'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe 'uvwxyz'
|
||||
|
||||
describe "when there is a whitespace character at the max length boundary", ->
|
||||
it "wraps the line at the first non-whitespace character following the boundary", ->
|
||||
expect(displayBuffer.lineForRow(3).text).toBe ' var pivot = items.shift(), current, left = [], '
|
||||
expect(displayBuffer.lineForRow(4).text).toBe 'right = [];'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe ' var pivot = items.shift(), current, left = [], '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe 'right = [];'
|
||||
|
||||
describe "when there are hard tabs", ->
|
||||
beforeEach ->
|
||||
buffer.setText(buffer.getText().replace(new RegExp(' ', 'g'), '\t'))
|
||||
|
||||
it "correctly tokenizes the hard tabs", ->
|
||||
expect(displayBuffer.lineForRow(3).tokens[0].isHardTab).toBeTruthy()
|
||||
expect(displayBuffer.lineForRow(3).tokens[1].isHardTab).toBeTruthy()
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).tokens[0].isHardTab).toBeTruthy()
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).tokens[1].isHardTab).toBeTruthy()
|
||||
|
||||
describe "when the buffer changes", ->
|
||||
describe "when buffer lines are updated", ->
|
||||
@@ -121,57 +121,57 @@ describe "DisplayBuffer", ->
|
||||
describe "when the update makes a soft-wrapped line shorter than the max line length", ->
|
||||
it "rewraps the line and emits a change event", ->
|
||||
buffer.delete([[6, 24], [6, 42]])
|
||||
expect(displayBuffer.lineForRow(7).text).toBe ' current < pivot ? : right.push(current);'
|
||||
expect(displayBuffer.lineForRow(8).text).toBe ' }'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(7).text).toBe ' current < pivot ? : right.push(current);'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(8).text).toBe ' }'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[[event]]= changeHandler.argsForCall
|
||||
|
||||
expect(event).toEqual(start: 7, end: 8, screenDelta: -1, bufferDelta: 0)
|
||||
|
||||
describe "when the update causes a line to softwrap an additional time", ->
|
||||
describe "when the update causes a line to soft wrap an additional time", ->
|
||||
it "rewraps the line and emits a change event", ->
|
||||
buffer.insert([6, 28], '1234567890')
|
||||
expect(displayBuffer.lineForRow(7).text).toBe ' current < pivot ? '
|
||||
expect(displayBuffer.lineForRow(8).text).toBe 'left1234567890.push(current) : '
|
||||
expect(displayBuffer.lineForRow(9).text).toBe 'right.push(current);'
|
||||
expect(displayBuffer.lineForRow(10).text).toBe ' }'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(7).text).toBe ' current < pivot ? '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(8).text).toBe 'left1234567890.push(current) : '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(9).text).toBe 'right.push(current);'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' }'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 7, end: 8, screenDelta: 1, bufferDelta: 0)
|
||||
|
||||
describe "when buffer lines are inserted", ->
|
||||
it "inserts / updates wrapped lines and emits a change event", ->
|
||||
buffer.insert([6, 21], '1234567890 abcdefghij 1234567890\nabcdefghij')
|
||||
expect(displayBuffer.lineForRow(7).text).toBe ' current < pivot1234567890 abcdefghij '
|
||||
expect(displayBuffer.lineForRow(8).text).toBe '1234567890'
|
||||
expect(displayBuffer.lineForRow(9).text).toBe 'abcdefghij ? left.push(current) : '
|
||||
expect(displayBuffer.lineForRow(10).text).toBe 'right.push(current);'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(7).text).toBe ' current < pivot1234567890 abcdefghij '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(8).text).toBe '1234567890'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(9).text).toBe 'abcdefghij ? left.push(current) : '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe 'right.push(current);'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 7, end: 8, screenDelta: 2, bufferDelta: 1)
|
||||
|
||||
describe "when buffer lines are removed", ->
|
||||
it "removes lines and emits a change event", ->
|
||||
buffer.setTextInRange([[3, 21], [7, 5]], ';')
|
||||
expect(displayBuffer.lineForRow(3).text).toBe ' var pivot = items;'
|
||||
expect(displayBuffer.lineForRow(4).text).toBe ' return '
|
||||
expect(displayBuffer.lineForRow(5).text).toBe 'sort(left).concat(pivot).concat(sort(right));'
|
||||
expect(displayBuffer.lineForRow(6).text).toBe ' };'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe ' var pivot = items;'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe ' return '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(5).text).toBe 'sort(left).concat(pivot).concat(sort(right));'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(6).text).toBe ' };'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 3, end: 9, screenDelta: -6, bufferDelta: -4)
|
||||
|
||||
describe "when a newline is inserted, deleted, and re-inserted at the end of a wrapped line (regression)", ->
|
||||
it "correctly renders the original wrapped line", ->
|
||||
buffer = atom.project.buildBufferSync(null, '')
|
||||
displayBuffer = new DisplayBuffer({buffer, tabLength, editorWidthInChars: 30, softWrap: true})
|
||||
displayBuffer = new DisplayBuffer({buffer, tabLength, editorWidthInChars: 30, softWrapped: true})
|
||||
|
||||
buffer.insert([0, 0], "the quick brown fox jumps over the lazy dog.")
|
||||
buffer.insert([0, Infinity], '\n')
|
||||
buffer.delete([[0, Infinity], [1, 0]])
|
||||
buffer.insert([0, Infinity], '\n')
|
||||
|
||||
expect(displayBuffer.lineForRow(0).text).toBe "the quick brown fox jumps over "
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "the lazy dog."
|
||||
expect(displayBuffer.lineForRow(2).text).toBe ""
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe "the quick brown fox jumps over "
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "the lazy dog."
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe ""
|
||||
|
||||
describe "position translation", ->
|
||||
it "translates positions accounting for wrapped lines", ->
|
||||
@@ -204,9 +204,9 @@ describe "DisplayBuffer", ->
|
||||
describe ".setEditorWidthInChars(length)", ->
|
||||
it "changes the length at which lines are wrapped and emits a change event for all screen lines", ->
|
||||
displayBuffer.setEditorWidthInChars(40)
|
||||
expect(tokensText displayBuffer.lineForRow(4).tokens).toBe 'left = [], right = [];'
|
||||
expect(tokensText displayBuffer.lineForRow(5).tokens).toBe ' while(items.length > 0) {'
|
||||
expect(tokensText displayBuffer.lineForRow(12).tokens).toBe 'sort(left).concat(pivot).concat(sort(rig'
|
||||
expect(tokensText displayBuffer.tokenizedLineForScreenRow(4).tokens).toBe 'left = [], right = [];'
|
||||
expect(tokensText displayBuffer.tokenizedLineForScreenRow(5).tokens).toBe ' while(items.length > 0) {'
|
||||
expect(tokensText displayBuffer.tokenizedLineForScreenRow(12).tokens).toBe 'sort(left).concat(pivot).concat(sort(rig'
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 0, end: 15, screenDelta: 3, bufferDelta: 0)
|
||||
|
||||
it "only allows positive widths to be assigned", ->
|
||||
@@ -220,10 +220,10 @@ describe "DisplayBuffer", ->
|
||||
displayBuffer.setWidth(50)
|
||||
displayBuffer.manageScrollPosition = true
|
||||
|
||||
displayBuffer.setSoftWrap(false)
|
||||
displayBuffer.setSoftWrapped(false)
|
||||
displayBuffer.setScrollLeft(Infinity)
|
||||
expect(displayBuffer.getScrollLeft()).toBeGreaterThan 0
|
||||
displayBuffer.setSoftWrap(true)
|
||||
displayBuffer.setSoftWrapped(true)
|
||||
expect(displayBuffer.getScrollLeft()).toBe 0
|
||||
displayBuffer.setScrollLeft(10)
|
||||
expect(displayBuffer.getScrollLeft()).toBe 0
|
||||
@@ -234,7 +234,7 @@ describe "DisplayBuffer", ->
|
||||
buffer.release()
|
||||
buffer = atom.project.bufferForPathSync('two-hundred.txt')
|
||||
displayBuffer = new DisplayBuffer({buffer, tabLength})
|
||||
displayBuffer.on 'changed', changeHandler
|
||||
displayBuffer.onDidChange changeHandler
|
||||
|
||||
describe "when folds are created and destroyed", ->
|
||||
describe "when a fold spans multiple lines", ->
|
||||
@@ -242,7 +242,7 @@ describe "DisplayBuffer", ->
|
||||
fold = displayBuffer.createFold(4, 7)
|
||||
expect(fold).toBeDefined()
|
||||
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
|
||||
expect(line4.fold).toBe fold
|
||||
expect(line4.text).toMatch /^4-+/
|
||||
expect(line5.text).toBe '8'
|
||||
@@ -251,7 +251,7 @@ describe "DisplayBuffer", ->
|
||||
changeHandler.reset()
|
||||
|
||||
fold.destroy()
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
|
||||
expect(line4.fold).toBeUndefined()
|
||||
expect(line4.text).toMatch /^4-+/
|
||||
expect(line5.text).toBe '5'
|
||||
@@ -262,7 +262,7 @@ describe "DisplayBuffer", ->
|
||||
it "renders a fold placeholder for the folded line but does not skip any lines", ->
|
||||
fold = displayBuffer.createFold(4, 4)
|
||||
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
|
||||
expect(line4.fold).toBe fold
|
||||
expect(line4.text).toMatch /^4-+/
|
||||
expect(line5.text).toBe '5'
|
||||
@@ -275,7 +275,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
fold.destroy()
|
||||
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
|
||||
expect(line4.fold).toBeUndefined()
|
||||
expect(line4.text).toMatch /^4-+/
|
||||
expect(line5.text).toBe '5'
|
||||
@@ -287,13 +287,13 @@ describe "DisplayBuffer", ->
|
||||
innerFold = displayBuffer.createFold(6, 7)
|
||||
outerFold = displayBuffer.createFold(4, 8)
|
||||
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
|
||||
expect(line4.fold).toBe outerFold
|
||||
expect(line4.text).toMatch /4-+/
|
||||
expect(line5.text).toMatch /9-+/
|
||||
|
||||
outerFold.destroy()
|
||||
[line4, line5, line6, line7] = displayBuffer.linesForRows(4, 7)
|
||||
[line4, line5, line6, line7] = displayBuffer.tokenizedLinesForScreenRows(4, 7)
|
||||
expect(line4.fold).toBeUndefined()
|
||||
expect(line4.text).toMatch /^4-+/
|
||||
expect(line5.text).toBe '5'
|
||||
@@ -305,7 +305,7 @@ describe "DisplayBuffer", ->
|
||||
innerFold = displayBuffer.createFold(4, 6)
|
||||
outerFold = displayBuffer.createFold(4, 8)
|
||||
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
|
||||
expect(line4.fold).toBe outerFold
|
||||
expect(line4.text).toMatch /4-+/
|
||||
expect(line5.text).toMatch /9-+/
|
||||
@@ -326,14 +326,14 @@ describe "DisplayBuffer", ->
|
||||
|
||||
innerFold = displayBuffer.createFold(2, 5)
|
||||
expect(changeHandler).not.toHaveBeenCalled()
|
||||
[line0, line1] = displayBuffer.linesForRows(0, 1)
|
||||
[line0, line1] = displayBuffer.tokenizedLinesForScreenRows(0, 1)
|
||||
expect(line0.fold).toBe outerFold
|
||||
expect(line1.fold).toBeUndefined()
|
||||
|
||||
changeHandler.reset()
|
||||
innerFold.destroy()
|
||||
expect(changeHandler).not.toHaveBeenCalled()
|
||||
[line0, line1] = displayBuffer.linesForRows(0, 1)
|
||||
[line0, line1] = displayBuffer.tokenizedLinesForScreenRows(0, 1)
|
||||
expect(line0.fold).toBe outerFold
|
||||
expect(line1.fold).toBeUndefined()
|
||||
|
||||
@@ -342,10 +342,8 @@ describe "DisplayBuffer", ->
|
||||
fold2 = displayBuffer.createFold(4, 9)
|
||||
fold1 = displayBuffer.createFold(0, 4)
|
||||
|
||||
displayBuffer.logLines(0, 20)
|
||||
|
||||
expect(displayBuffer.lineForRow(0).text).toMatch /^0/
|
||||
expect(displayBuffer.lineForRow(1).text).toMatch /^10/
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toMatch /^0/
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toMatch /^10/
|
||||
|
||||
describe "when there is another display buffer pointing to the same buffer", ->
|
||||
it "does not create folds in the other display buffer", ->
|
||||
@@ -365,19 +363,19 @@ describe "DisplayBuffer", ->
|
||||
buffer.setTextInRange([[1, 0], [5, 1]], 'party!')
|
||||
|
||||
it "removes the fold and replaces the selection with the new text", ->
|
||||
expect(displayBuffer.lineForRow(0).text).toBe "0"
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "party!"
|
||||
expect(displayBuffer.lineForRow(2).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(3).text).toMatch /^9-+/
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe "0"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "party!"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold2
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toMatch /^9-+/
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 1, end: 3, screenDelta: -2, bufferDelta: -4)
|
||||
|
||||
describe "when the changes is subsequently undone", ->
|
||||
xit "restores destroyed folds", ->
|
||||
buffer.undo()
|
||||
expect(displayBuffer.lineForRow(2).text).toBe '2'
|
||||
expect(displayBuffer.lineForRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.lineForRow(3).text).toBe '5'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe '2'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe '5'
|
||||
|
||||
describe "when the old range surrounds two nested folds", ->
|
||||
it "removes both folds and replaces the selection with the new text", ->
|
||||
@@ -386,9 +384,9 @@ describe "DisplayBuffer", ->
|
||||
|
||||
buffer.setTextInRange([[1, 0], [10, 0]], 'goodbye')
|
||||
|
||||
expect(displayBuffer.lineForRow(0).text).toBe "0"
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "goodbye10"
|
||||
expect(displayBuffer.lineForRow(2).text).toBe "11"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe "0"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "goodbye10"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe "11"
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 1, end: 3, screenDelta: -2, bufferDelta: -9)
|
||||
|
||||
@@ -405,42 +403,42 @@ describe "DisplayBuffer", ->
|
||||
it "updates the buffer and re-positions subsequent folds", ->
|
||||
buffer.setTextInRange([[0, 0], [1, 1]], 'abc')
|
||||
|
||||
expect(displayBuffer.lineForRow(0).text).toBe "abc"
|
||||
expect(displayBuffer.lineForRow(1).fold).toBe fold1
|
||||
expect(displayBuffer.lineForRow(2).text).toBe "5"
|
||||
expect(displayBuffer.lineForRow(3).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(4).text).toMatch /^9-+/
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe "abc"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).fold).toBe fold1
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe "5"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).fold).toBe fold2
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toMatch /^9-+/
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 0, end: 1, screenDelta: -1, bufferDelta: -1)
|
||||
changeHandler.reset()
|
||||
|
||||
fold1.destroy()
|
||||
expect(displayBuffer.lineForRow(0).text).toBe "abc"
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "2"
|
||||
expect(displayBuffer.lineForRow(3).text).toMatch /^4-+/
|
||||
expect(displayBuffer.lineForRow(4).text).toBe "5"
|
||||
expect(displayBuffer.lineForRow(5).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(6).text).toMatch /^9-+/
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe "abc"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "2"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toMatch /^4-+/
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe "5"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(5).fold).toBe fold2
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(6).text).toMatch /^9-+/
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 1, end: 1, screenDelta: 2, bufferDelta: 0)
|
||||
|
||||
describe "when the old range straddles the beginning of a fold", ->
|
||||
it "destroys the fold", ->
|
||||
buffer.setTextInRange([[1, 1], [3, 0]], "a\nb\nc\nd\n")
|
||||
expect(displayBuffer.lineForRow(1).text).toBe '1a'
|
||||
expect(displayBuffer.lineForRow(2).text).toBe 'b'
|
||||
expect(displayBuffer.lineForRow(2).fold).toBeUndefined()
|
||||
expect(displayBuffer.lineForRow(3).text).toBe 'c'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe '1a'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe 'b'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBeUndefined()
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe 'c'
|
||||
|
||||
describe "when the old range follows a fold", ->
|
||||
it "re-positions the screen ranges for the change event based on the preceding fold", ->
|
||||
buffer.setTextInRange([[10, 0], [11, 0]], 'abc')
|
||||
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "1"
|
||||
expect(displayBuffer.lineForRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.lineForRow(3).text).toBe "5"
|
||||
expect(displayBuffer.lineForRow(4).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(5).text).toMatch /^9-+/
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "1"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe "5"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).fold).toBe fold2
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(5).text).toMatch /^9-+/
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 6, end: 7, screenDelta: -1, bufferDelta: -1)
|
||||
|
||||
@@ -451,12 +449,12 @@ describe "DisplayBuffer", ->
|
||||
expect(fold1.getStartRow()).toBe 2
|
||||
expect(fold1.getEndRow()).toBe 5
|
||||
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "1"
|
||||
expect(displayBuffer.lineForRow(2).text).toBe "2"
|
||||
expect(displayBuffer.lineForRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.lineForRow(3).text).toMatch "5"
|
||||
expect(displayBuffer.lineForRow(4).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(5).text).toMatch /^9-+/
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "1"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe "2"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toMatch "5"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).fold).toBe fold2
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(5).text).toMatch /^9-+/
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 2, end: 2, screenDelta: 0, bufferDelta: 1)
|
||||
|
||||
@@ -466,12 +464,12 @@ describe "DisplayBuffer", ->
|
||||
expect(fold1.getStartRow()).toBe 2
|
||||
expect(fold1.getEndRow()).toBe 7
|
||||
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "1"
|
||||
expect(displayBuffer.lineForRow(2).text).toBe "2"
|
||||
expect(displayBuffer.lineForRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.lineForRow(3).text).toMatch "5"
|
||||
expect(displayBuffer.lineForRow(4).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(5).text).toMatch /^9-+/
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "1"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe "2"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toMatch "5"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).fold).toBe fold2
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(5).text).toMatch /^9-+/
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 2, end: 2, screenDelta: 0, bufferDelta: 3)
|
||||
|
||||
@@ -480,21 +478,21 @@ describe "DisplayBuffer", ->
|
||||
it "destroys the fold", ->
|
||||
fold2.destroy()
|
||||
buffer.setTextInRange([[3, 0], [6, 0]], 'a\n')
|
||||
expect(displayBuffer.lineForRow(2).text).toBe '2'
|
||||
expect(displayBuffer.lineForRow(2).fold).toBeUndefined()
|
||||
expect(displayBuffer.lineForRow(3).text).toBe 'a'
|
||||
expect(displayBuffer.lineForRow(4).text).toBe '6'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe '2'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBeUndefined()
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe 'a'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe '6'
|
||||
|
||||
describe "when the old range is contained to a single line in-between two folds", ->
|
||||
it "re-renders the line with the placeholder and re-positions the second fold", ->
|
||||
buffer.insert([5, 0], 'abc\n')
|
||||
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "1"
|
||||
expect(displayBuffer.lineForRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.lineForRow(3).text).toMatch "abc"
|
||||
expect(displayBuffer.lineForRow(4).text).toBe "5"
|
||||
expect(displayBuffer.lineForRow(5).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(6).text).toMatch /^9-+/
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "1"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toMatch "abc"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe "5"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(5).fold).toBe fold2
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(6).text).toMatch /^9-+/
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 3, end: 3, screenDelta: 1, bufferDelta: 1)
|
||||
|
||||
@@ -547,15 +545,15 @@ describe "DisplayBuffer", ->
|
||||
displayBuffer.createFold(1, 9)
|
||||
displayBuffer.createFold(11, 12)
|
||||
|
||||
expect(displayBuffer.lineForRow(1).text).toBe '1'
|
||||
expect(displayBuffer.lineForRow(2).text).toBe '10'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe '1'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe '10'
|
||||
|
||||
displayBuffer.unfoldBufferRow(2)
|
||||
expect(displayBuffer.lineForRow(1).text).toBe '1'
|
||||
expect(displayBuffer.lineForRow(2).text).toBe '2'
|
||||
expect(displayBuffer.lineForRow(7).fold).toBeDefined()
|
||||
expect(displayBuffer.lineForRow(8).text).toMatch /^9-+/
|
||||
expect(displayBuffer.lineForRow(10).fold).toBeDefined()
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe '1'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe '2'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(7).fold).toBeDefined()
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(8).text).toMatch /^9-+/
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).fold).toBeDefined()
|
||||
|
||||
describe ".outermostFoldsInBufferRowRange(startRow, endRow)", ->
|
||||
it "returns the outermost folds entirely contained in the given row range, exclusive of end row", ->
|
||||
@@ -570,7 +568,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
describe "::clipScreenPosition(screenPosition, wrapBeyondNewlines: false, wrapAtSoftNewlines: false, skipAtomicTokens: false)", ->
|
||||
beforeEach ->
|
||||
displayBuffer.setSoftWrap(true)
|
||||
displayBuffer.setSoftWrapped(true)
|
||||
displayBuffer.setEditorWidthInChars(50)
|
||||
|
||||
it "allows valid positions", ->
|
||||
@@ -645,7 +643,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
it "correctly translates positions on soft wrapped lines containing tabs", ->
|
||||
buffer.setText('\t\taa bb cc dd ee ff gg')
|
||||
displayBuffer.setSoftWrap(true)
|
||||
displayBuffer.setSoftWrapped(true)
|
||||
displayBuffer.setEditorWidthInChars(10)
|
||||
expect(displayBuffer.screenPositionForBufferPosition([0, 10], wrapAtSoftNewlines: true)).toEqual [1, 0]
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([1, 0])).toEqual [0, 10]
|
||||
@@ -688,7 +686,7 @@ describe "DisplayBuffer", ->
|
||||
expect(marker2.getScreenRange()).toEqual [[5, 4], [5, 10]]
|
||||
|
||||
it "emits a 'marker-created' event on the DisplayBuffer whenever a marker is created", ->
|
||||
displayBuffer.on 'marker-created', markerCreatedHandler = jasmine.createSpy("markerCreatedHandler")
|
||||
displayBuffer.onDidCreateMarker markerCreatedHandler = jasmine.createSpy("markerCreatedHandler")
|
||||
|
||||
marker1 = displayBuffer.markScreenRange([[5, 4], [5, 10]])
|
||||
expect(markerCreatedHandler).toHaveBeenCalledWith(marker1)
|
||||
@@ -724,7 +722,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
beforeEach ->
|
||||
marker = displayBuffer.markScreenRange([[5, 4], [5, 10]])
|
||||
marker.on 'changed', markerChangedHandler = jasmine.createSpy("markerChangedHandler")
|
||||
marker.onDidChange markerChangedHandler = jasmine.createSpy("markerChangedHandler")
|
||||
|
||||
it "triggers the 'changed' event whenever the markers head's screen position changes in the buffer or on screen", ->
|
||||
marker.setHeadScreenPosition([8, 20])
|
||||
@@ -861,8 +859,8 @@ describe "DisplayBuffer", ->
|
||||
|
||||
it "updates markers before emitting buffer change events, but does not notify their observers until the change event", ->
|
||||
marker2 = displayBuffer.markBufferRange([[8, 1], [8, 1]])
|
||||
marker2.on 'changed', marker2ChangedHandler = jasmine.createSpy("marker2ChangedHandler")
|
||||
displayBuffer.on 'changed', changeHandler = jasmine.createSpy("changeHandler").andCallFake -> onDisplayBufferChange()
|
||||
marker2.onDidChange marker2ChangedHandler = jasmine.createSpy("marker2ChangedHandler")
|
||||
displayBuffer.onDidChange changeHandler = jasmine.createSpy("changeHandler").andCallFake -> onDisplayBufferChange()
|
||||
|
||||
# New change ----
|
||||
|
||||
@@ -888,7 +886,7 @@ describe "DisplayBuffer", ->
|
||||
marker2ChangedHandler.reset()
|
||||
|
||||
marker3 = displayBuffer.markBufferRange([[8, 1], [8, 2]])
|
||||
marker3.on 'changed', marker3ChangedHandler = jasmine.createSpy("marker3ChangedHandler")
|
||||
marker3.onDidChange marker3ChangedHandler = jasmine.createSpy("marker3ChangedHandler")
|
||||
|
||||
onDisplayBufferChange = ->
|
||||
# calls change handler first
|
||||
@@ -934,7 +932,7 @@ describe "DisplayBuffer", ->
|
||||
expect(marker3ChangedHandler).toHaveBeenCalled()
|
||||
|
||||
it "updates the position of markers before emitting change events that aren't caused by a buffer change", ->
|
||||
displayBuffer.on 'changed', changeHandler = jasmine.createSpy("changeHandler").andCallFake ->
|
||||
displayBuffer.onDidChange changeHandler = jasmine.createSpy("changeHandler").andCallFake ->
|
||||
# calls change handler first
|
||||
expect(markerChangedHandler).not.toHaveBeenCalled()
|
||||
# but still updates the markers
|
||||
@@ -1000,16 +998,16 @@ describe "DisplayBuffer", ->
|
||||
expect(marker.isValid()).toBeFalsy()
|
||||
expect(displayBuffer.getMarker(marker.id)).toBeUndefined()
|
||||
|
||||
it "emits 'destroyed' events when markers are destroyed", ->
|
||||
it "notifies ::onDidDestroy observers when markers are destroyed", ->
|
||||
destroyedHandler = jasmine.createSpy("destroyedHandler")
|
||||
marker = displayBuffer.markScreenRange([[5, 4], [5, 10]])
|
||||
marker.on 'destroyed', destroyedHandler
|
||||
marker.onDidDestroy destroyedHandler
|
||||
marker.destroy()
|
||||
expect(destroyedHandler).toHaveBeenCalled()
|
||||
destroyedHandler.reset()
|
||||
|
||||
marker2 = displayBuffer.markScreenRange([[5, 4], [5, 10]])
|
||||
marker2.on 'destroyed', destroyedHandler
|
||||
marker2.onDidDestroy destroyedHandler
|
||||
buffer.getMarker(marker2.id).destroy()
|
||||
expect(destroyedHandler).toHaveBeenCalled()
|
||||
|
||||
@@ -1039,21 +1037,49 @@ describe "DisplayBuffer", ->
|
||||
expect(start.top).toBe 5 * 20
|
||||
expect(start.left).toBe (4 * 10) + (6 * 11)
|
||||
|
||||
describe 'when there are multiple DisplayBuffers for a buffer', ->
|
||||
describe 'when a marker is created', ->
|
||||
it 'the second display buffer will not emit a marker-created event when the marker has been deleted in the first marker-created event', ->
|
||||
displayBuffer2 = new DisplayBuffer({buffer, tabLength})
|
||||
displayBuffer.onDidCreateMarker markerCreated1 = jasmine.createSpy().andCallFake (marker) -> marker.destroy()
|
||||
displayBuffer2.onDidCreateMarker markerCreated2 = jasmine.createSpy()
|
||||
|
||||
displayBuffer.markBufferRange([[0, 0], [1, 5]], {})
|
||||
|
||||
expect(markerCreated1).toHaveBeenCalled()
|
||||
expect(markerCreated2).not.toHaveBeenCalled()
|
||||
|
||||
describe "decorations", ->
|
||||
it "can add decorations associated with markers and remove them", ->
|
||||
decoration = {type: 'gutter', class: 'one'}
|
||||
[marker, decoration, decorationProperties] = []
|
||||
beforeEach ->
|
||||
marker = displayBuffer.markBufferRange([[2, 13], [3, 15]])
|
||||
decorationProperties = {type: 'gutter', class: 'one'}
|
||||
decoration = displayBuffer.decorateMarker(marker, decorationProperties)
|
||||
|
||||
decorationObject = displayBuffer.addDecorationForMarker(marker, decoration)
|
||||
expect(decorationObject).toBeDefined()
|
||||
expect(decorationObject.getParams()).toBe decoration
|
||||
expect(displayBuffer.decorationForId(decoration.id)).toBe decorationObject
|
||||
expect(displayBuffer.decorationsForScreenRowRange(2, 3)[marker.id][0]).toBe decorationObject
|
||||
it "can add decorations associated with markers and remove them", ->
|
||||
expect(decoration).toBeDefined()
|
||||
expect(decoration.getProperties()).toBe decorationProperties
|
||||
expect(displayBuffer.decorationForId(decoration.id)).toBe decoration
|
||||
expect(displayBuffer.decorationsForScreenRowRange(2, 3)[marker.id][0]).toBe decoration
|
||||
|
||||
displayBuffer.removeDecorationForMarker(marker, decoration)
|
||||
decoration.destroy()
|
||||
expect(displayBuffer.decorationsForScreenRowRange(2, 3)[marker.id]).not.toBeDefined()
|
||||
expect(displayBuffer.decorationForId(decoration.id)).not.toBeDefined()
|
||||
|
||||
it "will not fail if the decoration is removed twice", ->
|
||||
decoration.destroy()
|
||||
decoration.destroy()
|
||||
expect(displayBuffer.decorationForId(decoration.id)).not.toBeDefined()
|
||||
|
||||
describe "when a decoration is updated via Decoration::update()", ->
|
||||
it "emits an 'updated' event containing the new and old params", ->
|
||||
decoration.onDidChangeProperties updatedSpy = jasmine.createSpy()
|
||||
decoration.setProperties type: 'gutter', class: 'two'
|
||||
|
||||
{oldProperties, newProperties} = updatedSpy.mostRecentCall.args[0]
|
||||
expect(oldProperties).toEqual decorationProperties
|
||||
expect(newProperties).toEqual type: 'gutter', class: 'two', id: decoration.id
|
||||
|
||||
describe "::setScrollTop", ->
|
||||
beforeEach ->
|
||||
displayBuffer.manageScrollPosition = true
|
||||
@@ -1145,7 +1171,7 @@ describe "DisplayBuffer", ->
|
||||
it "recomputes the scroll width when the scoped character widths change in a batch", ->
|
||||
operatorWidth = 20
|
||||
|
||||
displayBuffer.on 'character-widths-changed', changedSpy = jasmine.createSpy()
|
||||
displayBuffer.onDidChangeCharacterWidths changedSpy = jasmine.createSpy()
|
||||
|
||||
displayBuffer.batchCharacterMeasurement ->
|
||||
displayBuffer.setScopedCharWidth(['source.js', 'keyword.operator.js'], '<', operatorWidth)
|
||||
|
||||
+795
-483
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+589
-349
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
externo
BIN
Arquivo binário não exibido.
|
Antes Largura: | Altura: | Tamanho: 392 B |
externo
-1
@@ -1 +0,0 @@
|
||||
this tests files with no extensions
|
||||
gerado
externo
gerado
externo
+1
@@ -0,0 +1 @@
|
||||
throw new Error("this simulates a native module's failure to load")
|
||||
gerado
externo
+4
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "native-module",
|
||||
"main": "./main.js"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "package-with-incompatible-native-module",
|
||||
"version": "1.0",
|
||||
"main": "./main.js"
|
||||
}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
'fileTypes': ['package-with-infinite-loop-grammar']
|
||||
'name': 'package-with-infinite-loop-grammar'
|
||||
'scopeName': 'source.package-with-infinite-loop-grammar'
|
||||
|
||||
# This grammar should loop forever if the line contains an `a`
|
||||
'patterns': [
|
||||
{
|
||||
'name': 'start'
|
||||
'begin': '^'
|
||||
'end': '$'
|
||||
'patterns': [
|
||||
{
|
||||
name: 'negative-look-ahead'
|
||||
match: "(?!a)"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1 +0,0 @@
|
||||
This is a hidden file. Don't even try to load it as a snippet
|
||||
@@ -1 +0,0 @@
|
||||
This file isn't CSON, but shouldn't be a big deal
|
||||
@@ -1,4 +0,0 @@
|
||||
".test":
|
||||
"Test Snippet":
|
||||
prefix: "test"
|
||||
body: "testing 123"
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"theme": "ui",
|
||||
"stylesheets": ["editor.less"]
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
@import "ui-variables";
|
||||
|
||||
.editor {
|
||||
padding-top: @component-padding;
|
||||
padding-right: @component-padding;
|
||||
padding-bottom: @component-padding;
|
||||
|
||||
color: @input-background-color;
|
||||
background-color: @background-color-info; // From the fallback variables, not overridden
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
// This does not contain all of the ui-variables available.
|
||||
@app-background-color: #00f; // Changed
|
||||
@input-background-color: #f00; // Changed
|
||||
@@ -1,3 +0,0 @@
|
||||
@import "stylesheets/first";
|
||||
@import "stylesheets/second";
|
||||
@import "stylesheets/last";
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"theme": "ui"
|
||||
}
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
.editor {
|
||||
padding-top: 101px;
|
||||
padding-right: 101px;
|
||||
padding-bottom: 101px;
|
||||
|
||||
color: red;
|
||||
}
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
.editor {
|
||||
/* padding-top: 103px;
|
||||
padding-right: 103px;*/
|
||||
padding-bottom: 103px;
|
||||
}
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
@import "ui-variables";
|
||||
|
||||
@number: 102px;
|
||||
|
||||
.editor {
|
||||
/* padding-top: 102px;*/
|
||||
padding-right: @number;
|
||||
padding-bottom: @number;
|
||||
}
|
||||
-75
@@ -1,75 +0,0 @@
|
||||
// Variables different from the original are marked 'Changed'
|
||||
|
||||
@text-color: #333;
|
||||
@text-color-subtle: #777;
|
||||
@text-color-highlight: #111;
|
||||
@text-color-selected: @text-color-highlight;
|
||||
|
||||
@text-color-info: #5293d8;
|
||||
@text-color-success: #1fe977;
|
||||
@text-color-warning: #f78a46;
|
||||
@text-color-error: #c00;
|
||||
|
||||
@background-color-info: #0098ff;
|
||||
@background-color-success: #17ca65;
|
||||
@background-color-warning: #ff4800;
|
||||
@background-color-error: #c00;
|
||||
@background-color-highlight: rgba(255, 255, 255, 0.10);
|
||||
@background-color-selected: @background-color-highlight;
|
||||
|
||||
@app-background-color: #00f; // Changed
|
||||
|
||||
@base-background-color: #fff;
|
||||
@base-border-color: #eee;
|
||||
|
||||
@pane-item-background-color: @base-background-color;
|
||||
@pane-item-border-color: @base-border-color;
|
||||
|
||||
@input-background-color: #f00; // Changed
|
||||
@input-border-color: @base-border-color;
|
||||
|
||||
@tool-panel-background-color: #f4f4f4;
|
||||
@tool-panel-border-color: @base-border-color;
|
||||
|
||||
@inset-panel-background-color: #eee;
|
||||
@inset-panel-border-color: @base-border-color;
|
||||
|
||||
@panel-heading-background-color: #ddd;
|
||||
@panel-heading-border-color: transparent;
|
||||
|
||||
@overlay-background-color: #f4f4f4;
|
||||
@overlay-border-color: @base-border-color;
|
||||
|
||||
@button-background-color: #ccc;
|
||||
@button-background-color-hover: lighten(@button-background-color, 5%);
|
||||
@button-background-color-selected: @button-background-color-hover;
|
||||
@button-border-color: #aaa;
|
||||
|
||||
@tab-bar-background-color: #fff;
|
||||
@tab-bar-border-color: darken(@tab-background-color-active, 10%);
|
||||
@tab-background-color: #f4f4f4;
|
||||
@tab-background-color-active: #fff;
|
||||
@tab-border-color: @base-border-color;
|
||||
|
||||
@tree-view-background-color: @tool-panel-background-color;
|
||||
@tree-view-border-color: @tool-panel-border-color;
|
||||
|
||||
@ui-site-color-1: @background-color-success; // green
|
||||
@ui-site-color-2: @background-color-info; // blue
|
||||
@ui-site-color-3: @background-color-warning; // orange
|
||||
@ui-site-color-4: #db2ff4; // purple
|
||||
@ui-site-color-5: #f5e11d; // yellow
|
||||
|
||||
@font-size: 12px;
|
||||
|
||||
@disclosure-arrow-size: 12px;
|
||||
|
||||
@component-padding: 150px;
|
||||
@component-icon-padding: 5px;
|
||||
@component-icon-size: 16px;
|
||||
@component-line-height: 25px;
|
||||
@component-border-radius: 2px;
|
||||
|
||||
@tab-height: 30px;
|
||||
|
||||
@font-family: Arial;
|
||||
@@ -1 +0,0 @@
|
||||
Hello World!
|
||||
@@ -1 +0,0 @@
|
||||
Goodbye World!
|
||||
@@ -1 +0,0 @@
|
||||
Hello World!
|
||||
@@ -1 +0,0 @@
|
||||
Goodbye World!
|
||||
-1
@@ -1 +0,0 @@
|
||||
#header {
|
||||
externo
-71
@@ -1,71 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>fileTypes</key>
|
||||
<array>
|
||||
<string>txt</string>
|
||||
</array>
|
||||
<key>keyEquivalent</key>
|
||||
<string>^~P</string>
|
||||
<key>name</key>
|
||||
<string>Plain Text</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.item.text</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>^\s*(•).*$\n?</string>
|
||||
<key>name</key>
|
||||
<string>meta.bullet-point.strong.text</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.item.text</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>^\s*(·).*$\n?</string>
|
||||
<key>name</key>
|
||||
<string>meta.bullet-point.light.text</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.item.text</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>^\s*(\*).*$\n?</string>
|
||||
<key>name</key>
|
||||
<string>meta.bullet-point.star.text</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>^([ \t]*)(?=\S)</string>
|
||||
<key>contentName</key>
|
||||
<string>meta.paragraph.text</string>
|
||||
<key>end</key>
|
||||
<string>^(?!\1(?=\S))</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>scopeName</key>
|
||||
<string>text.plain</string>
|
||||
<key>uuid</key>
|
||||
<string>3130E4FA-B10E-11D9-9F75-000D93589AF6</string>
|
||||
</dict>
|
||||
</plist>
|
||||
externo
-1
@@ -1 +0,0 @@
|
||||
dir
|
||||
externo
-1
@@ -1 +0,0 @@
|
||||
sample.js
|
||||
externo
-1
@@ -1 +0,0 @@
|
||||
a
|
||||
+47
-15
@@ -111,14 +111,46 @@ describe "Git", ->
|
||||
fs.writeFileSync(filePath, 'ch ch changes')
|
||||
repo.getPathStatus(filePath)
|
||||
statusHandler = jasmine.createSpy('statusHandler')
|
||||
repo.on 'status-changed', statusHandler
|
||||
repo.onDidChangeStatus statusHandler
|
||||
repo.checkoutHead(filePath)
|
||||
expect(statusHandler.callCount).toBe 1
|
||||
expect(statusHandler.argsForCall[0][0..1]).toEqual [filePath, 0]
|
||||
expect(statusHandler.argsForCall[0][0]).toEqual {path: filePath, pathStatus: 0}
|
||||
|
||||
repo.checkoutHead(filePath)
|
||||
expect(statusHandler.callCount).toBe 1
|
||||
|
||||
describe ".checkoutHeadForEditor(editor)", ->
|
||||
[filePath, editor] = []
|
||||
|
||||
beforeEach ->
|
||||
workingDirPath = copyRepository()
|
||||
repo = new Git(workingDirPath)
|
||||
filePath = path.join(workingDirPath, 'a.txt')
|
||||
fs.writeFileSync(filePath, 'ch ch changes')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open(filePath)
|
||||
|
||||
runs ->
|
||||
editor = atom.workspace.getActiveEditor()
|
||||
|
||||
it "displays a confirmation dialog by default", ->
|
||||
spyOn(atom, 'confirm').andCallFake ({buttons}) -> buttons.OK()
|
||||
atom.config.set('editor.confirmCheckoutHeadRevision', true)
|
||||
|
||||
repo.checkoutHeadForEditor(editor)
|
||||
|
||||
expect(fs.readFileSync(filePath, 'utf8')).toBe ''
|
||||
|
||||
it "does not display a dialog when confirmation is disabled", ->
|
||||
spyOn(atom, 'confirm')
|
||||
atom.config.set('editor.confirmCheckoutHeadRevision', false)
|
||||
|
||||
repo.checkoutHeadForEditor(editor)
|
||||
|
||||
expect(fs.readFileSync(filePath, 'utf8')).toBe ''
|
||||
expect(atom.confirm).not.toHaveBeenCalled()
|
||||
|
||||
describe ".destroy()", ->
|
||||
it "throws an exception when any method is called after it is called", ->
|
||||
repo = new Git(require.resolve('./fixtures/git/master.git/HEAD'))
|
||||
@@ -135,11 +167,11 @@ describe "Git", ->
|
||||
|
||||
it "trigger a status-changed event when the new status differs from the last cached one", ->
|
||||
statusHandler = jasmine.createSpy("statusHandler")
|
||||
repo.on 'status-changed', statusHandler
|
||||
repo.onDidChangeStatus statusHandler
|
||||
fs.writeFileSync(filePath, '')
|
||||
status = repo.getPathStatus(filePath)
|
||||
expect(statusHandler.callCount).toBe 1
|
||||
expect(statusHandler.argsForCall[0][0..1]).toEqual [filePath, status]
|
||||
expect(statusHandler.argsForCall[0][0]).toEqual {path: filePath, pathStatus: status}
|
||||
|
||||
fs.writeFileSync(filePath, 'abc')
|
||||
status = repo.getPathStatus(filePath)
|
||||
@@ -176,7 +208,7 @@ describe "Git", ->
|
||||
it "returns status information for all new and modified files", ->
|
||||
fs.writeFileSync(modifiedPath, 'making this path modified')
|
||||
statusHandler = jasmine.createSpy('statusHandler')
|
||||
repo.on 'statuses-changed', statusHandler
|
||||
repo.onDidChangeStatuses statusHandler
|
||||
repo.refreshStatus()
|
||||
|
||||
waitsFor ->
|
||||
@@ -200,19 +232,19 @@ describe "Git", ->
|
||||
editor.insertNewline()
|
||||
|
||||
statusHandler = jasmine.createSpy('statusHandler')
|
||||
atom.project.getRepo().on 'status-changed', statusHandler
|
||||
atom.project.getRepo().onDidChangeStatus statusHandler
|
||||
editor.save()
|
||||
expect(statusHandler.callCount).toBe 1
|
||||
expect(statusHandler).toHaveBeenCalledWith editor.getPath(), 256
|
||||
expect(statusHandler).toHaveBeenCalledWith {path: editor.getPath(), pathStatus: 256}
|
||||
|
||||
it "emits a status-changed event when a buffer is reloaded", ->
|
||||
fs.writeFileSync(editor.getPath(), 'changed')
|
||||
|
||||
statusHandler = jasmine.createSpy('statusHandler')
|
||||
atom.project.getRepo().on 'status-changed', statusHandler
|
||||
atom.project.getRepo().onDidChangeStatus statusHandler
|
||||
editor.getBuffer().reload()
|
||||
expect(statusHandler.callCount).toBe 1
|
||||
expect(statusHandler).toHaveBeenCalledWith editor.getPath(), 256
|
||||
expect(statusHandler).toHaveBeenCalledWith {path: editor.getPath(), pathStatus: 256}
|
||||
editor.getBuffer().reload()
|
||||
expect(statusHandler.callCount).toBe 1
|
||||
|
||||
@@ -220,11 +252,11 @@ describe "Git", ->
|
||||
fs.writeFileSync(editor.getPath(), 'changed')
|
||||
|
||||
statusHandler = jasmine.createSpy('statusHandler')
|
||||
atom.project.getRepo().on 'status-changed', statusHandler
|
||||
editor.getBuffer().emit 'path-changed'
|
||||
atom.project.getRepo().onDidChangeStatus statusHandler
|
||||
editor.getBuffer().emitter.emit 'did-change-path'
|
||||
expect(statusHandler.callCount).toBe 1
|
||||
expect(statusHandler).toHaveBeenCalledWith editor.getPath(), 256
|
||||
editor.getBuffer().emit 'path-changed'
|
||||
expect(statusHandler).toHaveBeenCalledWith {path: editor.getPath(), pathStatus: 256}
|
||||
editor.getBuffer().emitter.emit 'did-change-path'
|
||||
expect(statusHandler.callCount).toBe 1
|
||||
|
||||
describe "when a project is deserialized", ->
|
||||
@@ -251,7 +283,7 @@ describe "Git", ->
|
||||
buffer.append('changes')
|
||||
|
||||
statusHandler = jasmine.createSpy('statusHandler')
|
||||
project2.getRepo().on 'status-changed', statusHandler
|
||||
project2.getRepo().onDidChangeStatus statusHandler
|
||||
buffer.save()
|
||||
expect(statusHandler.callCount).toBe 1
|
||||
expect(statusHandler).toHaveBeenCalledWith buffer.getPath(), 256
|
||||
expect(statusHandler).toHaveBeenCalledWith {path: buffer.getPath(), pathStatus: 256}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
fs = require 'fs'
|
||||
|
||||
module.exports.runSpecSuite = (specSuite, logFile, logErrors=true) ->
|
||||
{$, $$} = require 'atom'
|
||||
{$, $$} = require '../src/space-pen-extensions'
|
||||
|
||||
window[key] = value for key, value of require '../vendor/jasmine'
|
||||
|
||||
{TerminalReporter} = require 'jasmine-tagged'
|
||||
|
||||
@@ -275,46 +275,46 @@ describe "LanguageMode", ->
|
||||
it "folds every foldable line", ->
|
||||
languageMode.foldAll()
|
||||
|
||||
fold1 = editor.lineForScreenRow(0).fold
|
||||
fold1 = editor.tokenizedLineForScreenRow(0).fold
|
||||
expect([fold1.getStartRow(), fold1.getEndRow()]).toEqual [0, 12]
|
||||
fold1.destroy()
|
||||
|
||||
fold2 = editor.lineForScreenRow(1).fold
|
||||
fold2 = editor.tokenizedLineForScreenRow(1).fold
|
||||
expect([fold2.getStartRow(), fold2.getEndRow()]).toEqual [1, 9]
|
||||
fold2.destroy()
|
||||
|
||||
fold3 = editor.lineForScreenRow(4).fold
|
||||
fold3 = editor.tokenizedLineForScreenRow(4).fold
|
||||
expect([fold3.getStartRow(), fold3.getEndRow()]).toEqual [4, 7]
|
||||
|
||||
describe ".foldBufferRow(bufferRow)", ->
|
||||
describe "when bufferRow can be folded", ->
|
||||
it "creates a fold based on the syntactic region starting at the given row", ->
|
||||
languageMode.foldBufferRow(1)
|
||||
fold = editor.lineForScreenRow(1).fold
|
||||
fold = editor.tokenizedLineForScreenRow(1).fold
|
||||
expect(fold.getStartRow()).toBe 1
|
||||
expect(fold.getEndRow()).toBe 9
|
||||
|
||||
describe "when bufferRow can't be folded", ->
|
||||
it "searches upward for the first row that begins a syntatic region containing the given buffer row (and folds it)", ->
|
||||
languageMode.foldBufferRow(8)
|
||||
fold = editor.lineForScreenRow(1).fold
|
||||
fold = editor.tokenizedLineForScreenRow(1).fold
|
||||
expect(fold.getStartRow()).toBe 1
|
||||
expect(fold.getEndRow()).toBe 9
|
||||
|
||||
describe "when the bufferRow is already folded", ->
|
||||
it "searches upward for the first row that begins a syntatic region containing the folded row (and folds it)", ->
|
||||
languageMode.foldBufferRow(2)
|
||||
expect(editor.lineForScreenRow(1).fold).toBeDefined()
|
||||
expect(editor.lineForScreenRow(0).fold).not.toBeDefined()
|
||||
expect(editor.tokenizedLineForScreenRow(1).fold).toBeDefined()
|
||||
expect(editor.tokenizedLineForScreenRow(0).fold).not.toBeDefined()
|
||||
|
||||
languageMode.foldBufferRow(1)
|
||||
expect(editor.lineForScreenRow(0).fold).toBeDefined()
|
||||
expect(editor.tokenizedLineForScreenRow(0).fold).toBeDefined()
|
||||
|
||||
describe "when the bufferRow is in a multi-line comment", ->
|
||||
it "searches upward and downward for surrounding comment lines and folds them as a single fold", ->
|
||||
buffer.insert([1,0], " //this is a comment\n // and\n //more docs\n\n//second comment")
|
||||
languageMode.foldBufferRow(1)
|
||||
fold = editor.lineForScreenRow(1).fold
|
||||
fold = editor.tokenizedLineForScreenRow(1).fold
|
||||
expect(fold.getStartRow()).toBe 1
|
||||
expect(fold.getEndRow()).toBe 3
|
||||
|
||||
@@ -322,7 +322,7 @@ describe "LanguageMode", ->
|
||||
it "searches upward for the first row that begins a syntatic region containing the folded row (and folds it)", ->
|
||||
buffer.insert([1,0], " //this is a single line comment\n")
|
||||
languageMode.foldBufferRow(1)
|
||||
fold = editor.lineForScreenRow(0).fold
|
||||
fold = editor.tokenizedLineForScreenRow(0).fold
|
||||
expect(fold.getStartRow()).toBe 0
|
||||
expect(fold.getEndRow()).toBe 13
|
||||
|
||||
@@ -357,38 +357,38 @@ describe "LanguageMode", ->
|
||||
it "folds every foldable line", ->
|
||||
languageMode.foldAll()
|
||||
|
||||
fold1 = editor.lineForScreenRow(0).fold
|
||||
fold1 = editor.tokenizedLineForScreenRow(0).fold
|
||||
expect([fold1.getStartRow(), fold1.getEndRow()]).toEqual [0, 19]
|
||||
fold1.destroy()
|
||||
|
||||
fold2 = editor.lineForScreenRow(1).fold
|
||||
fold2 = editor.tokenizedLineForScreenRow(1).fold
|
||||
expect([fold2.getStartRow(), fold2.getEndRow()]).toEqual [1, 4]
|
||||
|
||||
fold3 = editor.lineForScreenRow(2).fold.destroy()
|
||||
fold3 = editor.tokenizedLineForScreenRow(2).fold.destroy()
|
||||
|
||||
fold4 = editor.lineForScreenRow(3).fold
|
||||
fold4 = editor.tokenizedLineForScreenRow(3).fold
|
||||
expect([fold4.getStartRow(), fold4.getEndRow()]).toEqual [6, 8]
|
||||
|
||||
describe ".foldAllAtIndentLevel()", ->
|
||||
it "folds every foldable range at a given indentLevel", ->
|
||||
languageMode.foldAllAtIndentLevel(2)
|
||||
|
||||
fold1 = editor.lineForScreenRow(6).fold
|
||||
fold1 = editor.tokenizedLineForScreenRow(6).fold
|
||||
expect([fold1.getStartRow(), fold1.getEndRow()]).toEqual [6, 8]
|
||||
fold1.destroy()
|
||||
|
||||
fold2 = editor.lineForScreenRow(11).fold
|
||||
fold2 = editor.tokenizedLineForScreenRow(11).fold
|
||||
expect([fold2.getStartRow(), fold2.getEndRow()]).toEqual [11, 14]
|
||||
fold2.destroy()
|
||||
|
||||
it "does not fold anything but the indentLevel", ->
|
||||
languageMode.foldAllAtIndentLevel(0)
|
||||
|
||||
fold1 = editor.lineForScreenRow(0).fold
|
||||
fold1 = editor.tokenizedLineForScreenRow(0).fold
|
||||
expect([fold1.getStartRow(), fold1.getEndRow()]).toEqual [0, 19]
|
||||
fold1.destroy()
|
||||
|
||||
fold2 = editor.lineForScreenRow(5).fold
|
||||
fold2 = editor.tokenizedLineForScreenRow(5).fold
|
||||
expect(fold2).toBeFalsy()
|
||||
|
||||
describe ".isFoldableAtBufferRow(bufferRow)", ->
|
||||
|
||||
@@ -1,8 +1,39 @@
|
||||
{$} = require 'atom'
|
||||
path = require 'path'
|
||||
Package = require '../src/package'
|
||||
ThemePackage = require '../src/theme-package'
|
||||
|
||||
describe "Package", ->
|
||||
describe "when the package contains incompatible native modules", ->
|
||||
beforeEach ->
|
||||
spyOn(atom, 'inDevMode').andReturn(false)
|
||||
|
||||
it "does not activate it", ->
|
||||
packagePath = atom.project.resolve('packages/package-with-incompatible-native-module')
|
||||
pack = new Package(packagePath)
|
||||
expect(pack.isCompatible()).toBe false
|
||||
expect(pack.incompatibleModules[0].name).toBe 'native-module'
|
||||
expect(pack.incompatibleModules[0].path).toBe path.join(packagePath, 'node_modules', 'native-module')
|
||||
|
||||
it "caches the incompatible native modules in local storage", ->
|
||||
packagePath = atom.project.resolve('packages/package-with-incompatible-native-module')
|
||||
cacheKey = null
|
||||
cacheItem = null
|
||||
|
||||
spyOn(global.localStorage, 'setItem').andCallFake (key, item) ->
|
||||
cacheKey = key
|
||||
cacheItem = item
|
||||
spyOn(global.localStorage, 'getItem').andCallFake (key) ->
|
||||
return cacheItem if cacheKey is key
|
||||
|
||||
expect(new Package(packagePath).isCompatible()).toBe false
|
||||
expect(global.localStorage.getItem.callCount).toBe 1
|
||||
expect(global.localStorage.setItem.callCount).toBe 1
|
||||
|
||||
expect(new Package(packagePath).isCompatible()).toBe false
|
||||
expect(global.localStorage.getItem.callCount).toBe 2
|
||||
expect(global.localStorage.setItem.callCount).toBe 1
|
||||
|
||||
describe "theme", ->
|
||||
theme = null
|
||||
|
||||
@@ -71,6 +102,6 @@ describe "Package", ->
|
||||
theme.activate()
|
||||
|
||||
it "deactivated event fires on .deactivate()", ->
|
||||
theme.on 'deactivated', spy = jasmine.createSpy()
|
||||
theme.onDidDeactivate spy = jasmine.createSpy()
|
||||
theme.deactivate()
|
||||
expect(spy).toHaveBeenCalled()
|
||||
|
||||
@@ -27,42 +27,91 @@ describe "PaneContainer", ->
|
||||
|
||||
it "preserves the active pane across serialization, independent of focus", ->
|
||||
pane3A.activate()
|
||||
expect(containerA.activePane).toBe pane3A
|
||||
expect(containerA.getActivePane()).toBe pane3A
|
||||
|
||||
containerB = containerA.testSerialization()
|
||||
[pane1B, pane2B, pane3B] = containerB.getPanes()
|
||||
expect(containerB.activePane).toBe pane3B
|
||||
expect(containerB.getActivePane()).toBe pane3B
|
||||
|
||||
describe "::activePane", ->
|
||||
it "does not allow the root pane to be destroyed", ->
|
||||
container = new PaneContainer
|
||||
container.getRoot().destroy()
|
||||
expect(container.getRoot()).toBeDefined()
|
||||
expect(container.getRoot().isDestroyed()).toBe false
|
||||
|
||||
describe "::getActivePane()", ->
|
||||
[container, pane1, pane2] = []
|
||||
|
||||
beforeEach ->
|
||||
container = new PaneContainer
|
||||
pane1 = container.root
|
||||
pane1 = container.getRoot()
|
||||
|
||||
it "references the first pane if no pane has been made active", ->
|
||||
expect(container.activePane).toBe pane1
|
||||
expect(pane1.active).toBe true
|
||||
it "returns the first pane if no pane has been made active", ->
|
||||
expect(container.getActivePane()).toBe pane1
|
||||
expect(pane1.isActive()).toBe true
|
||||
|
||||
it "references the most pane on which ::activate was most recently called", ->
|
||||
it "returns the most pane on which ::activate() was most recently called", ->
|
||||
pane2 = pane1.splitRight()
|
||||
pane2.activate()
|
||||
expect(container.activePane).toBe pane2
|
||||
expect(pane1.active).toBe false
|
||||
expect(pane2.active).toBe true
|
||||
expect(container.getActivePane()).toBe pane2
|
||||
expect(pane1.isActive()).toBe false
|
||||
expect(pane2.isActive()).toBe true
|
||||
pane1.activate()
|
||||
expect(container.activePane).toBe pane1
|
||||
expect(pane1.active).toBe true
|
||||
expect(pane2.active).toBe false
|
||||
expect(container.getActivePane()).toBe pane1
|
||||
expect(pane1.isActive()).toBe true
|
||||
expect(pane2.isActive()).toBe false
|
||||
|
||||
it "is reassigned to the next pane if the current active pane is destroyed", ->
|
||||
it "returns the next pane if the current active pane is destroyed", ->
|
||||
pane2 = pane1.splitRight()
|
||||
pane2.activate()
|
||||
pane2.destroy()
|
||||
expect(container.activePane).toBe pane1
|
||||
expect(pane1.active).toBe true
|
||||
expect(container.getActivePane()).toBe pane1
|
||||
expect(pane1.isActive()).toBe true
|
||||
|
||||
it "does not allow the root pane to be destroyed", ->
|
||||
pane1.destroy()
|
||||
expect(container.root).toBe pane1
|
||||
expect(pane1.isDestroyed()).toBe false
|
||||
describe "::onDidChangeActivePaneItem()", ->
|
||||
[container, pane1, pane2, observed] = []
|
||||
|
||||
beforeEach ->
|
||||
container = new PaneContainer(root: new Pane(items: [new Object, new Object]))
|
||||
container.getRoot().splitRight(items: [new Object, new Object])
|
||||
[pane1, pane2] = container.getPanes()
|
||||
|
||||
observed = []
|
||||
container.onDidChangeActivePaneItem (item) -> observed.push(item)
|
||||
|
||||
it "invokes observers when the active item of the active pane changes", ->
|
||||
pane2.activateNextItem()
|
||||
pane2.activateNextItem()
|
||||
expect(observed).toEqual [pane2.itemAtIndex(1), pane2.itemAtIndex(0)]
|
||||
|
||||
it "invokes observers when the active pane changes", ->
|
||||
pane1.activate()
|
||||
pane2.activate()
|
||||
expect(observed).toEqual [pane1.itemAtIndex(0), pane2.itemAtIndex(0)]
|
||||
|
||||
describe "::observePanes()", ->
|
||||
it "invokes observers with all current and future panes", ->
|
||||
container = new PaneContainer
|
||||
container.getRoot().splitRight()
|
||||
[pane1, pane2] = container.getPanes()
|
||||
|
||||
observed = []
|
||||
container.observePanes (pane) -> observed.push(pane)
|
||||
|
||||
pane3 = pane2.splitDown()
|
||||
pane4 = pane2.splitRight()
|
||||
|
||||
expect(observed).toEqual [pane1, pane2, pane3, pane4]
|
||||
|
||||
describe "::observePaneItems()", ->
|
||||
it "invokes observers with all current and future pane items", ->
|
||||
container = new PaneContainer(root: new Pane(items: [new Object, new Object]))
|
||||
container.getRoot().splitRight(items: [new Object])
|
||||
[pane1, pane2] = container.getPanes()
|
||||
observed = []
|
||||
container.observePaneItems (pane) -> observed.push(pane)
|
||||
|
||||
pane3 = pane2.splitDown(items: [new Object])
|
||||
pane3.addItems([new Object, new Object])
|
||||
|
||||
expect(observed).toEqual container.getPaneItems()
|
||||
|
||||
+218
-107
@@ -21,39 +21,83 @@ describe "Pane", ->
|
||||
describe "construction", ->
|
||||
it "sets the active item to the first item", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B")])
|
||||
expect(pane.activeItem).toBe pane.items[0]
|
||||
expect(pane.getActiveItem()).toBe pane.itemAtIndex(0)
|
||||
|
||||
it "compacts the items array", ->
|
||||
pane = new Pane(items: [undefined, new Item("A"), null, new Item("B")])
|
||||
expect(pane.items.length).toBe 2
|
||||
expect(pane.activeItem).toBe pane.items[0]
|
||||
expect(pane.getItems().length).toBe 2
|
||||
expect(pane.getActiveItem()).toBe pane.itemAtIndex(0)
|
||||
|
||||
describe "::activate()", ->
|
||||
[container, pane1, pane2] = []
|
||||
|
||||
beforeEach ->
|
||||
container = new PaneContainer(root: new Pane)
|
||||
container.getRoot().splitRight()
|
||||
[pane1, pane2] = container.getPanes()
|
||||
|
||||
it "changes the active pane on the container", ->
|
||||
expect(container.getActivePane()).toBe pane2
|
||||
pane1.activate()
|
||||
expect(container.getActivePane()).toBe pane1
|
||||
pane2.activate()
|
||||
expect(container.getActivePane()).toBe pane2
|
||||
|
||||
it "invokes ::onDidChangeActivePane observers on the container", ->
|
||||
observed = []
|
||||
container.onDidChangeActivePane (activePane) -> observed.push(activePane)
|
||||
|
||||
pane1.activate()
|
||||
pane1.activate()
|
||||
pane2.activate()
|
||||
pane1.activate()
|
||||
expect(observed).toEqual [pane1, pane2, pane1]
|
||||
|
||||
it "invokes ::onDidChangeActive observers on the relevant panes", ->
|
||||
observed = []
|
||||
pane1.onDidChangeActive (active) -> observed.push(active)
|
||||
pane1.activate()
|
||||
pane2.activate()
|
||||
expect(observed).toEqual [true, false]
|
||||
|
||||
it "invokes ::onDidActivate() observers", ->
|
||||
eventCount = 0
|
||||
pane1.onDidActivate -> eventCount++
|
||||
pane1.activate()
|
||||
pane1.activate()
|
||||
pane2.activate()
|
||||
expect(eventCount).toBe 2
|
||||
|
||||
describe "::addItem(item, index)", ->
|
||||
it "adds the item at the given index", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B")])
|
||||
[item1, item2] = pane.items
|
||||
[item1, item2] = pane.getItems()
|
||||
item3 = new Item("C")
|
||||
pane.addItem(item3, 1)
|
||||
expect(pane.items).toEqual [item1, item3, item2]
|
||||
expect(pane.getItems()).toEqual [item1, item3, item2]
|
||||
|
||||
it "adds the item after the active item ", ->
|
||||
it "adds the item after the active item if no index is provided", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
|
||||
[item1, item2, item3] = pane.items
|
||||
[item1, item2, item3] = pane.getItems()
|
||||
pane.activateItem(item2)
|
||||
item4 = new Item("D")
|
||||
pane.addItem(item4)
|
||||
expect(pane.items).toEqual [item1, item2, item4, item3]
|
||||
expect(pane.getItems()).toEqual [item1, item2, item4, item3]
|
||||
|
||||
it "sets the active item after adding the first item", ->
|
||||
pane = new Pane
|
||||
item = new Item("A")
|
||||
events = []
|
||||
pane.on 'item-added', -> events.push('item-added')
|
||||
pane.$activeItem.changes.onValue -> events.push('active-item-changed')
|
||||
|
||||
pane.addItem(item)
|
||||
expect(pane.activeItem).toBe item
|
||||
expect(events).toEqual ['item-added', 'active-item-changed']
|
||||
expect(pane.getActiveItem()).toBe item
|
||||
|
||||
it "invokes ::onDidAddItem() observers", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B")])
|
||||
events = []
|
||||
pane.onDidAddItem (event) -> events.push(event)
|
||||
|
||||
item = new Item("C")
|
||||
pane.addItem(item, 1)
|
||||
expect(events).toEqual [{item, index: 1}]
|
||||
|
||||
describe "::activateItem(item)", ->
|
||||
pane = null
|
||||
@@ -62,83 +106,102 @@ describe "Pane", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B")])
|
||||
|
||||
it "changes the active item to the current item", ->
|
||||
expect(pane.activeItem).toBe pane.items[0]
|
||||
pane.activateItem(pane.items[1])
|
||||
expect(pane.activeItem).toBe pane.items[1]
|
||||
expect(pane.getActiveItem()).toBe pane.itemAtIndex(0)
|
||||
pane.activateItem(pane.itemAtIndex(1))
|
||||
expect(pane.getActiveItem()).toBe pane.itemAtIndex(1)
|
||||
|
||||
it "adds the given item if it isn't present in ::items", ->
|
||||
item = new Item("C")
|
||||
pane.activateItem(item)
|
||||
expect(item in pane.items).toBe true
|
||||
expect(pane.activeItem).toBe item
|
||||
expect(item in pane.getItems()).toBe true
|
||||
expect(pane.getActiveItem()).toBe item
|
||||
|
||||
it "invokes ::onDidChangeActiveItem() observers", ->
|
||||
observed = []
|
||||
pane.onDidChangeActiveItem (item) -> observed.push(item)
|
||||
pane.activateItem(pane.itemAtIndex(1))
|
||||
expect(observed).toEqual [pane.itemAtIndex(1)]
|
||||
|
||||
describe "::activateNextItem() and ::activatePreviousItem()", ->
|
||||
it "sets the active item to the next/previous item, looping around at either end", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
|
||||
[item1, item2, item3] = pane.items
|
||||
[item1, item2, item3] = pane.getItems()
|
||||
|
||||
expect(pane.activeItem).toBe item1
|
||||
expect(pane.getActiveItem()).toBe item1
|
||||
pane.activatePreviousItem()
|
||||
expect(pane.activeItem).toBe item3
|
||||
expect(pane.getActiveItem()).toBe item3
|
||||
pane.activatePreviousItem()
|
||||
expect(pane.activeItem).toBe item2
|
||||
expect(pane.getActiveItem()).toBe item2
|
||||
pane.activateNextItem()
|
||||
expect(pane.activeItem).toBe item3
|
||||
expect(pane.getActiveItem()).toBe item3
|
||||
pane.activateNextItem()
|
||||
expect(pane.activeItem).toBe item1
|
||||
expect(pane.getActiveItem()).toBe item1
|
||||
|
||||
describe "::activateItemAtIndex(index)", ->
|
||||
it "activates the item at the given index", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
|
||||
[item1, item2, item3] = pane.items
|
||||
[item1, item2, item3] = pane.getItems()
|
||||
pane.activateItemAtIndex(2)
|
||||
expect(pane.activeItem).toBe item3
|
||||
expect(pane.getActiveItem()).toBe item3
|
||||
pane.activateItemAtIndex(1)
|
||||
expect(pane.activeItem).toBe item2
|
||||
expect(pane.getActiveItem()).toBe item2
|
||||
pane.activateItemAtIndex(0)
|
||||
expect(pane.activeItem).toBe item1
|
||||
expect(pane.getActiveItem()).toBe item1
|
||||
|
||||
# Doesn't fail with out-of-bounds indices
|
||||
pane.activateItemAtIndex(100)
|
||||
expect(pane.activeItem).toBe item1
|
||||
expect(pane.getActiveItem()).toBe item1
|
||||
pane.activateItemAtIndex(-1)
|
||||
expect(pane.activeItem).toBe item1
|
||||
expect(pane.getActiveItem()).toBe item1
|
||||
|
||||
describe "::destroyItem(item)", ->
|
||||
[pane, item1, item2, item3] = []
|
||||
|
||||
beforeEach ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
|
||||
[item1, item2, item3] = pane.items
|
||||
[item1, item2, item3] = pane.getItems()
|
||||
|
||||
it "removes the item from the items list", ->
|
||||
expect(pane.activeItem).toBe item1
|
||||
it "removes the item from the items list and destroyes it", ->
|
||||
expect(pane.getActiveItem()).toBe item1
|
||||
pane.destroyItem(item2)
|
||||
expect(item2 in pane.items).toBe false
|
||||
expect(pane.activeItem).toBe item1
|
||||
expect(item2 in pane.getItems()).toBe false
|
||||
expect(item2.isDestroyed()).toBe true
|
||||
expect(pane.getActiveItem()).toBe item1
|
||||
|
||||
pane.destroyItem(item1)
|
||||
expect(item1 in pane.items).toBe false
|
||||
expect(item1 in pane.getItems()).toBe false
|
||||
expect(item1.isDestroyed()).toBe true
|
||||
|
||||
it "invokes ::onWillDestroyItem() observers before destroying the item", ->
|
||||
events = []
|
||||
pane.onWillDestroyItem (event) ->
|
||||
expect(item2.isDestroyed()).toBe false
|
||||
events.push(event)
|
||||
|
||||
pane.destroyItem(item2)
|
||||
expect(item2.isDestroyed()).toBe true
|
||||
expect(events).toEqual [{item: item2, index: 1}]
|
||||
|
||||
it "invokes ::onDidRemoveItem() observers", ->
|
||||
events = []
|
||||
pane.onDidRemoveItem (event) -> events.push(event)
|
||||
pane.destroyItem(item2)
|
||||
expect(events).toEqual [{item: item2, index: 1, destroyed: true}]
|
||||
|
||||
describe "when the destroyed item is the active item and is the first item", ->
|
||||
it "activates the next item", ->
|
||||
expect(pane.activeItem).toBe item1
|
||||
expect(pane.getActiveItem()).toBe item1
|
||||
pane.destroyItem(item1)
|
||||
expect(pane.activeItem).toBe item2
|
||||
expect(pane.getActiveItem()).toBe item2
|
||||
|
||||
describe "when the destroyed item is the active item and is not the first item", ->
|
||||
beforeEach ->
|
||||
pane.activateItem(item2)
|
||||
|
||||
it "activates the previous item", ->
|
||||
expect(pane.activeItem).toBe item2
|
||||
expect(pane.getActiveItem()).toBe item2
|
||||
pane.destroyItem(item2)
|
||||
expect(pane.activeItem).toBe item1
|
||||
|
||||
it "emits 'item-removed' with the item, its index, and true indicating the item is being destroyed", ->
|
||||
pane.on 'item-removed', itemRemovedHandler = jasmine.createSpy("itemRemovedHandler")
|
||||
pane.destroyItem(item2)
|
||||
expect(itemRemovedHandler).toHaveBeenCalledWith(item2, 1, true)
|
||||
expect(pane.getActiveItem()).toBe item1
|
||||
|
||||
describe "if the item is modified", ->
|
||||
itemUri = null
|
||||
@@ -157,7 +220,7 @@ describe "Pane", ->
|
||||
pane.destroyItem(item1)
|
||||
|
||||
expect(item1.save).toHaveBeenCalled()
|
||||
expect(item1 in pane.items).toBe false
|
||||
expect(item1 in pane.getItems()).toBe false
|
||||
expect(item1.isDestroyed()).toBe true
|
||||
|
||||
describe "when the item has no uri", ->
|
||||
@@ -170,7 +233,7 @@ describe "Pane", ->
|
||||
|
||||
expect(atom.showSaveDialogSync).toHaveBeenCalled()
|
||||
expect(item1.saveAs).toHaveBeenCalledWith("/selected/path")
|
||||
expect(item1 in pane.items).toBe false
|
||||
expect(item1 in pane.getItems()).toBe false
|
||||
expect(item1.isDestroyed()).toBe true
|
||||
|
||||
describe "if the [Don't Save] option is selected", ->
|
||||
@@ -179,7 +242,7 @@ describe "Pane", ->
|
||||
pane.destroyItem(item1)
|
||||
|
||||
expect(item1.save).not.toHaveBeenCalled()
|
||||
expect(item1 in pane.items).toBe false
|
||||
expect(item1 in pane.getItems()).toBe false
|
||||
expect(item1.isDestroyed()).toBe true
|
||||
|
||||
describe "if the [Cancel] option is selected", ->
|
||||
@@ -188,7 +251,7 @@ describe "Pane", ->
|
||||
pane.destroyItem(item1)
|
||||
|
||||
expect(item1.save).not.toHaveBeenCalled()
|
||||
expect(item1 in pane.items).toBe true
|
||||
expect(item1 in pane.getItems()).toBe true
|
||||
expect(item1.isDestroyed()).toBe false
|
||||
|
||||
describe "when the last item is destroyed", ->
|
||||
@@ -197,7 +260,7 @@ describe "Pane", ->
|
||||
expect(atom.config.get('core.destroyEmptyPanes')).toBe false
|
||||
pane.destroyItem(item) for item in pane.getItems()
|
||||
expect(pane.isDestroyed()).toBe false
|
||||
expect(pane.activeItem).toBeUndefined()
|
||||
expect(pane.getActiveItem()).toBeUndefined()
|
||||
expect(-> pane.saveActiveItem()).not.toThrow()
|
||||
expect(-> pane.saveActiveItemAs()).not.toThrow()
|
||||
|
||||
@@ -210,10 +273,10 @@ describe "Pane", ->
|
||||
describe "::destroyActiveItem()", ->
|
||||
it "destroys the active item", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B")])
|
||||
activeItem = pane.activeItem
|
||||
activeItem = pane.getActiveItem()
|
||||
pane.destroyActiveItem()
|
||||
expect(activeItem.isDestroyed()).toBe true
|
||||
expect(activeItem in pane.items).toBe false
|
||||
expect(activeItem in pane.getItems()).toBe false
|
||||
|
||||
it "does not throw an exception if there are no more items", ->
|
||||
pane = new Pane
|
||||
@@ -222,27 +285,40 @@ describe "Pane", ->
|
||||
describe "::destroyItems()", ->
|
||||
it "destroys all items", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
|
||||
[item1, item2, item3] = pane.items
|
||||
[item1, item2, item3] = pane.getItems()
|
||||
pane.destroyItems()
|
||||
expect(item1.isDestroyed()).toBe true
|
||||
expect(item2.isDestroyed()).toBe true
|
||||
expect(item3.isDestroyed()).toBe true
|
||||
expect(pane.items).toEqual []
|
||||
expect(pane.getItems()).toEqual []
|
||||
|
||||
describe "::observeItems()", ->
|
||||
it "invokes the observer with all current and future items", ->
|
||||
pane = new Pane(items: [new Item, new Item])
|
||||
[item1, item2] = pane.getItems()
|
||||
|
||||
observed = []
|
||||
pane.observeItems (item) -> observed.push(item)
|
||||
|
||||
item3 = new Item
|
||||
pane.addItem(item3)
|
||||
|
||||
expect(observed).toEqual [item1, item2, item3]
|
||||
|
||||
describe "when an item emits a destroyed event", ->
|
||||
it "removes it from the list of items", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
|
||||
[item1, item2, item3] = pane.items
|
||||
pane.items[1].destroy()
|
||||
expect(pane.items).toEqual [item1, item3]
|
||||
[item1, item2, item3] = pane.getItems()
|
||||
pane.itemAtIndex(1).destroy()
|
||||
expect(pane.getItems()).toEqual [item1, item3]
|
||||
|
||||
describe "::destroyInactiveItems()", ->
|
||||
it "destroys all items but the active item", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
|
||||
[item1, item2, item3] = pane.items
|
||||
[item1, item2, item3] = pane.getItems()
|
||||
pane.activateItem(item2)
|
||||
pane.destroyInactiveItems()
|
||||
expect(pane.items).toEqual [item2]
|
||||
expect(pane.getItems()).toEqual [item2]
|
||||
|
||||
describe "::saveActiveItem()", ->
|
||||
pane = null
|
||||
@@ -253,30 +329,30 @@ describe "Pane", ->
|
||||
|
||||
describe "when the active item has a uri", ->
|
||||
beforeEach ->
|
||||
pane.activeItem.uri = "test"
|
||||
pane.getActiveItem().uri = "test"
|
||||
|
||||
describe "when the active item has a save method", ->
|
||||
it "saves the current item", ->
|
||||
pane.activeItem.save = jasmine.createSpy("save")
|
||||
pane.getActiveItem().save = jasmine.createSpy("save")
|
||||
pane.saveActiveItem()
|
||||
expect(pane.activeItem.save).toHaveBeenCalled()
|
||||
expect(pane.getActiveItem().save).toHaveBeenCalled()
|
||||
|
||||
describe "when the current item has no save method", ->
|
||||
it "does nothing", ->
|
||||
expect(pane.activeItem.save).toBeUndefined()
|
||||
expect(pane.getActiveItem().save).toBeUndefined()
|
||||
pane.saveActiveItem()
|
||||
|
||||
describe "when the current item has no uri", ->
|
||||
describe "when the current item has a saveAs method", ->
|
||||
it "opens a save dialog and saves the current item as the selected path", ->
|
||||
pane.activeItem.saveAs = jasmine.createSpy("saveAs")
|
||||
pane.getActiveItem().saveAs = jasmine.createSpy("saveAs")
|
||||
pane.saveActiveItem()
|
||||
expect(atom.showSaveDialogSync).toHaveBeenCalled()
|
||||
expect(pane.activeItem.saveAs).toHaveBeenCalledWith('/selected/path')
|
||||
expect(pane.getActiveItem().saveAs).toHaveBeenCalledWith('/selected/path')
|
||||
|
||||
describe "when the current item has no saveAs method", ->
|
||||
it "does nothing", ->
|
||||
expect(pane.activeItem.saveAs).toBeUndefined()
|
||||
expect(pane.getActiveItem().saveAs).toBeUndefined()
|
||||
pane.saveActiveItem()
|
||||
expect(atom.showSaveDialogSync).not.toHaveBeenCalled()
|
||||
|
||||
@@ -289,22 +365,22 @@ describe "Pane", ->
|
||||
|
||||
describe "when the current item has a saveAs method", ->
|
||||
it "opens the save dialog and calls saveAs on the item with the selected path", ->
|
||||
pane.activeItem.path = __filename
|
||||
pane.activeItem.saveAs = jasmine.createSpy("saveAs")
|
||||
pane.getActiveItem().path = __filename
|
||||
pane.getActiveItem().saveAs = jasmine.createSpy("saveAs")
|
||||
pane.saveActiveItemAs()
|
||||
expect(atom.showSaveDialogSync).toHaveBeenCalledWith(__filename)
|
||||
expect(pane.activeItem.saveAs).toHaveBeenCalledWith('/selected/path')
|
||||
expect(pane.getActiveItem().saveAs).toHaveBeenCalledWith('/selected/path')
|
||||
|
||||
describe "when the current item does not have a saveAs method", ->
|
||||
it "does nothing", ->
|
||||
expect(pane.activeItem.saveAs).toBeUndefined()
|
||||
expect(pane.getActiveItem().saveAs).toBeUndefined()
|
||||
pane.saveActiveItemAs()
|
||||
expect(atom.showSaveDialogSync).not.toHaveBeenCalled()
|
||||
|
||||
describe "::itemForUri(uri)", ->
|
||||
it "returns the item for which a call to .getUri() returns the given uri", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C"), new Item("D")])
|
||||
[item1, item2, item3] = pane.items
|
||||
[item1, item2, item3] = pane.getItems()
|
||||
item1.uri = "a"
|
||||
item2.uri = "b"
|
||||
expect(pane.itemForUri("a")).toBe item1
|
||||
@@ -312,24 +388,32 @@ describe "Pane", ->
|
||||
expect(pane.itemForUri("bogus")).toBeUndefined()
|
||||
|
||||
describe "::moveItem(item, index)", ->
|
||||
it "moves the item to the given index and emits an 'item-moved' event with the item and its new index", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C"), new Item("D")])
|
||||
[item1, item2, item3, item4] = pane.items
|
||||
pane.on 'item-moved', itemMovedHandler = jasmine.createSpy("itemMovedHandler")
|
||||
[pane, item1, item2, item3, item4] = []
|
||||
|
||||
beforeEach ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C"), new Item("D")])
|
||||
[item1, item2, item3, item4] = pane.getItems()
|
||||
|
||||
it "moves the item to the given index and invokes ::onDidMoveItem observers", ->
|
||||
pane.moveItem(item1, 2)
|
||||
expect(pane.getItems()).toEqual [item2, item3, item1, item4]
|
||||
expect(itemMovedHandler).toHaveBeenCalledWith(item1, 2)
|
||||
itemMovedHandler.reset()
|
||||
|
||||
pane.moveItem(item2, 3)
|
||||
expect(pane.getItems()).toEqual [item3, item1, item4, item2]
|
||||
expect(itemMovedHandler).toHaveBeenCalledWith(item2, 3)
|
||||
itemMovedHandler.reset()
|
||||
|
||||
pane.moveItem(item2, 1)
|
||||
expect(pane.getItems()).toEqual [item3, item2, item1, item4]
|
||||
expect(itemMovedHandler).toHaveBeenCalledWith(item2, 1)
|
||||
|
||||
it "invokes ::onDidMoveItem() observers", ->
|
||||
events = []
|
||||
pane.onDidMoveItem (event) -> events.push(event)
|
||||
|
||||
pane.moveItem(item1, 2)
|
||||
pane.moveItem(item2, 3)
|
||||
expect(events).toEqual [
|
||||
{item: item1, oldIndex: 0, newIndex: 2}
|
||||
{item: item2, oldIndex: 0, newIndex: 3}
|
||||
]
|
||||
|
||||
describe "::moveItemToPane(item, pane, index)", ->
|
||||
[container, pane1, pane2] = []
|
||||
@@ -339,13 +423,20 @@ describe "Pane", ->
|
||||
pane1 = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
|
||||
container = new PaneContainer(root: pane1)
|
||||
pane2 = pane1.splitRight(items: [new Item("D"), new Item("E")])
|
||||
[item1, item2, item3] = pane1.items
|
||||
[item4, item5] = pane2.items
|
||||
[item1, item2, item3] = pane1.getItems()
|
||||
[item4, item5] = pane2.getItems()
|
||||
|
||||
it "moves the item to the given pane at the given index", ->
|
||||
pane1.moveItemToPane(item2, pane2, 1)
|
||||
expect(pane1.items).toEqual [item1, item3]
|
||||
expect(pane2.items).toEqual [item4, item2, item5]
|
||||
expect(pane1.getItems()).toEqual [item1, item3]
|
||||
expect(pane2.getItems()).toEqual [item4, item2, item5]
|
||||
|
||||
it "invokes ::onDidRemoveItem() observers", ->
|
||||
events = []
|
||||
pane1.onDidRemoveItem (event) -> events.push(event)
|
||||
pane1.moveItemToPane(item2, pane2, 1)
|
||||
|
||||
expect(events).toEqual [{item: item2, index: 1, destroyed: false}]
|
||||
|
||||
describe "when the moved item the last item in the source pane", ->
|
||||
beforeEach ->
|
||||
@@ -368,22 +459,27 @@ describe "Pane", ->
|
||||
[pane1, container] = []
|
||||
|
||||
beforeEach ->
|
||||
pane1 = new Pane(items: ["A"])
|
||||
pane1 = new Pane(items: [new Item("A")])
|
||||
container = new PaneContainer(root: pane1)
|
||||
|
||||
describe "::splitLeft(params)", ->
|
||||
describe "when the parent is the container root", ->
|
||||
it "replaces itself with a row and inserts a new pane to the left of itself", ->
|
||||
pane2 = pane1.splitLeft(items: ["B"])
|
||||
pane3 = pane1.splitLeft(items: ["C"])
|
||||
pane2 = pane1.splitLeft(items: [new Item("B")])
|
||||
pane3 = pane1.splitLeft(items: [new Item("C")])
|
||||
expect(container.root.orientation).toBe 'horizontal'
|
||||
expect(container.root.children).toEqual [pane2, pane3, pane1]
|
||||
|
||||
describe "when `copyActiveItem: true` is passed in the params", ->
|
||||
it "duplicates the active item", ->
|
||||
pane2 = pane1.splitLeft(copyActiveItem: true)
|
||||
expect(pane2.getActiveItem()).toEqual pane1.getActiveItem()
|
||||
|
||||
describe "when the parent is a column", ->
|
||||
it "replaces itself with a row and inserts a new pane to the left of itself", ->
|
||||
pane1.splitDown()
|
||||
pane2 = pane1.splitLeft(items: ["B"])
|
||||
pane3 = pane1.splitLeft(items: ["C"])
|
||||
pane2 = pane1.splitLeft(items: [new Item("B")])
|
||||
pane3 = pane1.splitLeft(items: [new Item("C")])
|
||||
row = container.root.children[0]
|
||||
expect(row.orientation).toBe 'horizontal'
|
||||
expect(row.children).toEqual [pane2, pane3, pane1]
|
||||
@@ -391,16 +487,21 @@ describe "Pane", ->
|
||||
describe "::splitRight(params)", ->
|
||||
describe "when the parent is the container root", ->
|
||||
it "replaces itself with a row and inserts a new pane to the right of itself", ->
|
||||
pane2 = pane1.splitRight(items: ["B"])
|
||||
pane3 = pane1.splitRight(items: ["C"])
|
||||
pane2 = pane1.splitRight(items: [new Item("B")])
|
||||
pane3 = pane1.splitRight(items: [new Item("C")])
|
||||
expect(container.root.orientation).toBe 'horizontal'
|
||||
expect(container.root.children).toEqual [pane1, pane3, pane2]
|
||||
|
||||
describe "when `copyActiveItem: true` is passed in the params", ->
|
||||
it "duplicates the active item", ->
|
||||
pane2 = pane1.splitRight(copyActiveItem: true)
|
||||
expect(pane2.getActiveItem()).toEqual pane1.getActiveItem()
|
||||
|
||||
describe "when the parent is a column", ->
|
||||
it "replaces itself with a row and inserts a new pane to the right of itself", ->
|
||||
pane1.splitDown()
|
||||
pane2 = pane1.splitRight(items: ["B"])
|
||||
pane3 = pane1.splitRight(items: ["C"])
|
||||
pane2 = pane1.splitRight(items: [new Item("B")])
|
||||
pane3 = pane1.splitRight(items: [new Item("C")])
|
||||
row = container.root.children[0]
|
||||
expect(row.orientation).toBe 'horizontal'
|
||||
expect(row.children).toEqual [pane1, pane3, pane2]
|
||||
@@ -408,16 +509,21 @@ describe "Pane", ->
|
||||
describe "::splitUp(params)", ->
|
||||
describe "when the parent is the container root", ->
|
||||
it "replaces itself with a column and inserts a new pane above itself", ->
|
||||
pane2 = pane1.splitUp(items: ["B"])
|
||||
pane3 = pane1.splitUp(items: ["C"])
|
||||
pane2 = pane1.splitUp(items: [new Item("B")])
|
||||
pane3 = pane1.splitUp(items: [new Item("C")])
|
||||
expect(container.root.orientation).toBe 'vertical'
|
||||
expect(container.root.children).toEqual [pane2, pane3, pane1]
|
||||
|
||||
describe "when `copyActiveItem: true` is passed in the params", ->
|
||||
it "duplicates the active item", ->
|
||||
pane2 = pane1.splitUp(copyActiveItem: true)
|
||||
expect(pane2.getActiveItem()).toEqual pane1.getActiveItem()
|
||||
|
||||
describe "when the parent is a row", ->
|
||||
it "replaces itself with a column and inserts a new pane above itself", ->
|
||||
pane1.splitRight()
|
||||
pane2 = pane1.splitUp(items: ["B"])
|
||||
pane3 = pane1.splitUp(items: ["C"])
|
||||
pane2 = pane1.splitUp(items: [new Item("B")])
|
||||
pane3 = pane1.splitUp(items: [new Item("C")])
|
||||
column = container.root.children[0]
|
||||
expect(column.orientation).toBe 'vertical'
|
||||
expect(column.children).toEqual [pane2, pane3, pane1]
|
||||
@@ -425,16 +531,21 @@ describe "Pane", ->
|
||||
describe "::splitDown(params)", ->
|
||||
describe "when the parent is the container root", ->
|
||||
it "replaces itself with a column and inserts a new pane below itself", ->
|
||||
pane2 = pane1.splitDown(items: ["B"])
|
||||
pane3 = pane1.splitDown(items: ["C"])
|
||||
pane2 = pane1.splitDown(items: [new Item("B")])
|
||||
pane3 = pane1.splitDown(items: [new Item("C")])
|
||||
expect(container.root.orientation).toBe 'vertical'
|
||||
expect(container.root.children).toEqual [pane1, pane3, pane2]
|
||||
|
||||
describe "when `copyActiveItem: true` is passed in the params", ->
|
||||
it "duplicates the active item", ->
|
||||
pane2 = pane1.splitDown(copyActiveItem: true)
|
||||
expect(pane2.getActiveItem()).toEqual pane1.getActiveItem()
|
||||
|
||||
describe "when the parent is a row", ->
|
||||
it "replaces itself with a column and inserts a new pane below itself", ->
|
||||
pane1.splitRight()
|
||||
pane2 = pane1.splitDown(items: ["B"])
|
||||
pane3 = pane1.splitDown(items: ["C"])
|
||||
pane2 = pane1.splitDown(items: [new Item("B")])
|
||||
pane3 = pane1.splitDown(items: [new Item("C")])
|
||||
column = container.root.children[0]
|
||||
expect(column.orientation).toBe 'vertical'
|
||||
expect(column.children).toEqual [pane1, pane3, pane2]
|
||||
@@ -455,7 +566,7 @@ describe "Pane", ->
|
||||
pane2 = pane1.splitRight()
|
||||
|
||||
it "destroys the pane's destroyable items", ->
|
||||
[item1, item2] = pane1.items
|
||||
[item1, item2] = pane1.getItems()
|
||||
pane1.destroy()
|
||||
expect(item1.isDestroyed()).toBe true
|
||||
expect(item2.isDestroyed()).toBe true
|
||||
@@ -493,12 +604,12 @@ describe "Pane", ->
|
||||
|
||||
it "can serialize and deserialize the pane and all its items", ->
|
||||
newPane = pane.testSerialization()
|
||||
expect(newPane.items).toEqual pane.items
|
||||
expect(newPane.getItems()).toEqual pane.getItems()
|
||||
|
||||
it "restores the active item on deserialization", ->
|
||||
pane.activateItemAtIndex(1)
|
||||
newPane = pane.testSerialization()
|
||||
expect(newPane.activeItem).toEqual newPane.items[1]
|
||||
expect(newPane.getActiveItem()).toEqual newPane.itemAtIndex(1)
|
||||
|
||||
it "does not include items that cannot be deserialized", ->
|
||||
spyOn(console, 'warn')
|
||||
@@ -506,8 +617,8 @@ describe "Pane", ->
|
||||
pane.activateItem(unserializable)
|
||||
|
||||
newPane = pane.testSerialization()
|
||||
expect(newPane.activeItem).toEqual pane.items[0]
|
||||
expect(newPane.items.length).toBe pane.items.length - 1
|
||||
expect(newPane.getActiveItem()).toEqual pane.itemAtIndex(0)
|
||||
expect(newPane.getItems().length).toBe pane.getItems().length - 1
|
||||
|
||||
it "includes the pane's focus state in the serialized state", ->
|
||||
pane.focus()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
PaneContainerView = require '../src/pane-container-view'
|
||||
PaneView = require '../src/pane-view'
|
||||
fs = require 'fs-plus'
|
||||
{Emitter} = require 'event-kit'
|
||||
{$, View} = require 'atom'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
@@ -12,9 +13,14 @@ describe "PaneView", ->
|
||||
@deserialize: ({id, text}) -> new TestView({id, text})
|
||||
@content: ({id, text}) -> @div class: 'test-view', id: id, tabindex: -1, text
|
||||
initialize: ({@id, @text}) ->
|
||||
@emitter = new Emitter
|
||||
serialize: -> { deserializer: 'TestView', @id, @text }
|
||||
getUri: -> @id
|
||||
isEqual: (other) -> other? and @id == other.id and @text == other.text
|
||||
changeTitle: ->
|
||||
@emitter.emit 'did-change-title', 'title'
|
||||
onDidChangeTitle: (callback) ->
|
||||
@emitter.on 'did-change-title', callback
|
||||
|
||||
beforeEach ->
|
||||
atom.deserializers.add(TestView)
|
||||
@@ -29,7 +35,7 @@ describe "PaneView", ->
|
||||
|
||||
runs ->
|
||||
pane = container.getRoot()
|
||||
paneModel = pane.model
|
||||
paneModel = pane.getModel()
|
||||
paneModel.addItems([view1, editor1, view2, editor2])
|
||||
|
||||
afterEach ->
|
||||
@@ -37,7 +43,7 @@ describe "PaneView", ->
|
||||
|
||||
describe "when the active pane item changes", ->
|
||||
it "hides all item views except the active one", ->
|
||||
expect(pane.activeItem).toBe view1
|
||||
expect(pane.getActiveItem()).toBe view1
|
||||
expect(view1.css('display')).not.toBe 'none'
|
||||
|
||||
pane.activateItem(view2)
|
||||
@@ -48,7 +54,7 @@ describe "PaneView", ->
|
||||
itemChangedHandler = jasmine.createSpy("itemChangedHandler")
|
||||
container.on 'pane:active-item-changed', itemChangedHandler
|
||||
|
||||
expect(pane.activeItem).toBe view1
|
||||
expect(pane.getActiveItem()).toBe view1
|
||||
paneModel.activateItem(view2)
|
||||
paneModel.activateItem(view2)
|
||||
|
||||
@@ -145,22 +151,47 @@ describe "PaneView", ->
|
||||
expect(view1.data('preservative')).toBe 1234
|
||||
|
||||
describe "when the title of the active item changes", ->
|
||||
it "emits pane:active-item-title-changed", ->
|
||||
activeItemTitleChangedHandler = jasmine.createSpy("activeItemTitleChangedHandler")
|
||||
pane.on 'pane:active-item-title-changed', activeItemTitleChangedHandler
|
||||
describe 'when there is no onDidChangeTitle method', ->
|
||||
beforeEach ->
|
||||
view1.onDidChangeTitle = null
|
||||
view2.onDidChangeTitle = null
|
||||
|
||||
expect(pane.activeItem).toBe view1
|
||||
pane.activateItem(view2)
|
||||
pane.activateItem(view1)
|
||||
|
||||
view2.trigger 'title-changed'
|
||||
expect(activeItemTitleChangedHandler).not.toHaveBeenCalled()
|
||||
it "emits pane:active-item-title-changed", ->
|
||||
activeItemTitleChangedHandler = jasmine.createSpy("activeItemTitleChangedHandler")
|
||||
pane.on 'pane:active-item-title-changed', activeItemTitleChangedHandler
|
||||
|
||||
view1.trigger 'title-changed'
|
||||
expect(activeItemTitleChangedHandler).toHaveBeenCalled()
|
||||
activeItemTitleChangedHandler.reset()
|
||||
expect(pane.getActiveItem()).toBe view1
|
||||
|
||||
pane.activateItem(view2)
|
||||
view2.trigger 'title-changed'
|
||||
expect(activeItemTitleChangedHandler).toHaveBeenCalled()
|
||||
view2.trigger 'title-changed'
|
||||
expect(activeItemTitleChangedHandler).not.toHaveBeenCalled()
|
||||
|
||||
view1.trigger 'title-changed'
|
||||
expect(activeItemTitleChangedHandler).toHaveBeenCalled()
|
||||
activeItemTitleChangedHandler.reset()
|
||||
|
||||
pane.activateItem(view2)
|
||||
view2.trigger 'title-changed'
|
||||
expect(activeItemTitleChangedHandler).toHaveBeenCalled()
|
||||
|
||||
describe 'when there is a onDidChangeTitle method', ->
|
||||
it "emits pane:active-item-title-changed", ->
|
||||
activeItemTitleChangedHandler = jasmine.createSpy("activeItemTitleChangedHandler")
|
||||
pane.on 'pane:active-item-title-changed', activeItemTitleChangedHandler
|
||||
|
||||
expect(pane.getActiveItem()).toBe view1
|
||||
view2.changeTitle()
|
||||
expect(activeItemTitleChangedHandler).not.toHaveBeenCalled()
|
||||
|
||||
view1.changeTitle()
|
||||
expect(activeItemTitleChangedHandler).toHaveBeenCalled()
|
||||
activeItemTitleChangedHandler.reset()
|
||||
|
||||
pane.activateItem(view2)
|
||||
view2.changeTitle()
|
||||
expect(activeItemTitleChangedHandler).toHaveBeenCalled()
|
||||
|
||||
describe "when an unmodifed buffer's path is deleted", ->
|
||||
it "removes the pane item", ->
|
||||
@@ -246,7 +277,7 @@ describe "PaneView", ->
|
||||
|
||||
it "transfers focus to the active view", ->
|
||||
focusHandler = jasmine.createSpy("focusHandler")
|
||||
pane.activeItem.on 'focus', focusHandler
|
||||
pane.getActiveItem().on 'focus', focusHandler
|
||||
pane.focus()
|
||||
expect(focusHandler).toHaveBeenCalled()
|
||||
|
||||
@@ -259,7 +290,7 @@ describe "PaneView", ->
|
||||
describe "when a pane is split", ->
|
||||
it "builds the appropriate pane-row and pane-column views", ->
|
||||
pane1 = pane
|
||||
pane1Model = pane.model
|
||||
pane1Model = pane.getModel()
|
||||
pane.activateItem(editor1)
|
||||
|
||||
pane2Model = pane1Model.splitRight(items: [pane1Model.copyActiveItem()])
|
||||
|
||||
@@ -190,6 +190,11 @@ describe "Project", ->
|
||||
expect(atom.project.getPath()?).toBeFalsy()
|
||||
expect(atom.project.getRootDirectory()?).toBeFalsy()
|
||||
|
||||
it "normalizes the path to remove consecutive slashes, ., and .. segments", ->
|
||||
atom.project.setPath("#{require.resolve('./fixtures/dir/a')}#{path.sep}b#{path.sep}#{path.sep}..")
|
||||
expect(atom.project.getPath()).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
expect(atom.project.getRootDirectory().path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
|
||||
describe ".replace()", ->
|
||||
[filePath, commentFilePath, sampleContent, sampleCommentContent] = []
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ describe "Editor", ->
|
||||
logLines()
|
||||
throw new Error("Invalid buffer row #{actualBufferRow} for screen row #{screenRow}", )
|
||||
|
||||
actualScreenLine = editor.lineForScreenRow(screenRow)
|
||||
actualScreenLine = editor.tokenizedLineForScreenRow(screenRow)
|
||||
unless actualScreenLine.text is referenceScreenLine.text
|
||||
logLines()
|
||||
throw new Error("Invalid line text at screen row #{screenRow}")
|
||||
@@ -50,9 +50,9 @@ describe "Editor", ->
|
||||
|
||||
randomlyMutateEditor = ->
|
||||
if Math.random() < .2
|
||||
softWrap = not editor.getSoftWrap()
|
||||
steps.push(['setSoftWrap', softWrap])
|
||||
editor.setSoftWrap(softWrap)
|
||||
softWrapped = not editor.isSoftWrapped()
|
||||
steps.push(['setSoftWrapped', softWrapped])
|
||||
editor.setSoftWrapped(softWrapped)
|
||||
else
|
||||
range = getRandomRange()
|
||||
text = getRandomText()
|
||||
@@ -79,11 +79,11 @@ describe "Editor", ->
|
||||
text
|
||||
|
||||
getReferenceScreenLines = ->
|
||||
if editor.getSoftWrap()
|
||||
if editor.isSoftWrapped()
|
||||
screenLines = []
|
||||
bufferRows = []
|
||||
for bufferRow in [0..tokenizedBuffer.getLastRow()]
|
||||
for screenLine in softWrapLine(tokenizedBuffer.lineForScreenRow(bufferRow))
|
||||
for screenLine in softWrapLine(tokenizedBuffer.tokenizedLineForRow(bufferRow))
|
||||
screenLines.push(screenLine)
|
||||
bufferRows.push(bufferRow)
|
||||
else
|
||||
|
||||
@@ -6,7 +6,7 @@ describe "Selection", ->
|
||||
beforeEach ->
|
||||
buffer = atom.project.bufferForPathSync('sample.js')
|
||||
editor = new Editor(buffer: buffer, tabLength: 2)
|
||||
selection = editor.getSelection()
|
||||
selection = editor.getLastSelection()
|
||||
|
||||
afterEach ->
|
||||
buffer.destroy()
|
||||
@@ -57,10 +57,10 @@ describe "Selection", ->
|
||||
expect(selection.isReversed()).toBeFalsy()
|
||||
|
||||
describe "when only the selection's tail is moved (regression)", ->
|
||||
it "emits the 'screen-range-changed' event", ->
|
||||
it "notifies ::onDidChangeRange observers", ->
|
||||
selection.setBufferRange([[2, 0], [2, 10]], reversed: true)
|
||||
changeScreenRangeHandler = jasmine.createSpy('changeScreenRangeHandler')
|
||||
selection.on 'screen-range-changed', changeScreenRangeHandler
|
||||
selection.onDidChangeRange changeScreenRangeHandler
|
||||
|
||||
buffer.insert([2, 5], 'abc')
|
||||
expect(changeScreenRangeHandler).toHaveBeenCalled()
|
||||
|
||||
@@ -28,7 +28,7 @@ atom.keymaps.loadBundledKeymaps()
|
||||
keyBindingsToRestore = atom.keymaps.getKeyBindings()
|
||||
|
||||
$(window).on 'core:close', -> window.close()
|
||||
$(window).on 'unload', ->
|
||||
$(window).on 'beforeunload', ->
|
||||
atom.storeWindowDimensions()
|
||||
atom.saveSync()
|
||||
$('html,body').css('overflow', 'auto')
|
||||
@@ -95,7 +95,6 @@ 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 "core.useReactEditor", true
|
||||
config.save.reset()
|
||||
atom.config = config
|
||||
|
||||
@@ -130,14 +129,15 @@ afterEach ->
|
||||
atom.project?.destroy()
|
||||
atom.project = null
|
||||
|
||||
atom.themes.removeStylesheet('global-editor-styles')
|
||||
|
||||
delete atom.state.packageStates
|
||||
|
||||
$('#jasmine-content').empty() unless window.debugContent
|
||||
|
||||
jasmine.unspy(atom, 'saveSync')
|
||||
ensureNoPathSubscriptions()
|
||||
atom.syntax.off()
|
||||
ensureNoDeprecatedFunctionsCalled() if isCoreSpec
|
||||
atom.syntax.clearObservers()
|
||||
waits(0) # yield to ui thread to make screen update more frequently
|
||||
|
||||
ensureNoPathSubscriptions = ->
|
||||
@@ -209,6 +209,13 @@ addCustomMatchers = (spec) ->
|
||||
element = element.get(0) if element.jquery
|
||||
element.webkitMatchesSelector(":focus") or element.querySelector(":focus")
|
||||
|
||||
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."
|
||||
element.style.display in ['block', 'inline-block', 'static', 'fixed']
|
||||
|
||||
window.keyIdentifierForKey = (key) ->
|
||||
if key.length > 1 # named key
|
||||
key
|
||||
@@ -318,9 +325,13 @@ window.setEditorWidthInChars = (editorView, widthInChars, charWidth=editorView.c
|
||||
editorView.width(charWidth * widthInChars + editorView.gutter.outerWidth())
|
||||
$(window).trigger 'resize' # update width of editor view's on-screen lines
|
||||
|
||||
window.setEditorHeightInLines = (editorView, heightInChars, charHeight=editorView.lineHeight) ->
|
||||
editorView.height(charHeight * heightInChars + editorView.renderedLines.position().top)
|
||||
$(window).trigger 'resize' # update 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
|
||||
|
||||
$.fn.resultOfTrigger = (type) ->
|
||||
event = $.Event(type)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
_ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
{Git} = require 'atom'
|
||||
path = require 'path'
|
||||
require './spec-helper'
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ describe "ThemeManager", ->
|
||||
|
||||
describe "when the core.themes config value changes", ->
|
||||
it "add/removes stylesheets to reflect the new config value", ->
|
||||
themeManager.on 'reloaded', reloadHandler = jasmine.createSpy()
|
||||
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
|
||||
spyOn(themeManager, 'getUserStylesheetPath').andCallFake -> null
|
||||
|
||||
waitsForPromise ->
|
||||
@@ -131,8 +131,8 @@ describe "ThemeManager", ->
|
||||
|
||||
describe "requireStylesheet(path)", ->
|
||||
it "synchronously loads css at the given path and installs a style tag for it in the head", ->
|
||||
themeManager.on 'stylesheets-changed', stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
themeManager.on 'stylesheet-added', stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
|
||||
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
themeManager.onDidAddStylesheet stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
|
||||
cssPath = atom.project.resolve('css.css')
|
||||
lengthBefore = $('head style').length
|
||||
|
||||
@@ -193,8 +193,8 @@ describe "ThemeManager", ->
|
||||
themeManager.requireStylesheet(cssPath)
|
||||
expect($(document.body).css('font-weight')).toBe("bold")
|
||||
|
||||
themeManager.on 'stylesheet-removed', stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
|
||||
themeManager.on 'stylesheets-changed', stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
themeManager.onDidRemoveStylesheet stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
|
||||
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
|
||||
themeManager.removeStylesheet(cssPath)
|
||||
|
||||
@@ -217,7 +217,7 @@ describe "ThemeManager", ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
it "loads the correct values from the theme's ui-variables file", ->
|
||||
themeManager.on 'reloaded', reloadHandler = jasmine.createSpy()
|
||||
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
|
||||
atom.config.set('core.themes', ['theme-with-ui-variables'])
|
||||
|
||||
waitsFor ->
|
||||
@@ -232,6 +232,36 @@ describe "ThemeManager", ->
|
||||
expect($(".editor").css("padding-right")).toBe "150px"
|
||||
expect($(".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'])
|
||||
|
||||
waitsFor ->
|
||||
reloadHandler.callCount > 0
|
||||
|
||||
runs ->
|
||||
# an override loaded in the base css
|
||||
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)"
|
||||
|
||||
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'])
|
||||
|
||||
waitsFor ->
|
||||
reloadHandler.callCount > 0
|
||||
|
||||
runs ->
|
||||
# `theme-` twice as it prefixes the name with `theme-`
|
||||
expect(atom.workspaceView).toHaveClass 'theme-theme-with-ui-variables'
|
||||
expect(atom.workspaceView).not.toHaveClass 'theme-atom-dark-ui'
|
||||
|
||||
describe "when the user stylesheet changes", ->
|
||||
it "reloads it", ->
|
||||
[stylesheetRemovedHandler, stylesheetAddedHandler, stylesheetsChangedHandler] = []
|
||||
@@ -243,9 +273,9 @@ describe "ThemeManager", ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
runs ->
|
||||
themeManager.on 'stylesheets-changed', stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
themeManager.on 'stylesheet-removed', stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
|
||||
themeManager.on 'stylesheet-added', stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
|
||||
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
themeManager.onDidRemoveStylesheet stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
|
||||
themeManager.onDidAddStylesheet stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
|
||||
spyOn(themeManager, 'loadUserStylesheet').andCallThrough()
|
||||
|
||||
expect($(document.body).css('border-style')).toBe 'dotted'
|
||||
@@ -286,7 +316,9 @@ describe "ThemeManager", ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
runs ->
|
||||
themeManager.once 'reloaded', -> reloaded = true
|
||||
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()
|
||||
|
||||
@@ -295,3 +327,59 @@ describe "ThemeManager", ->
|
||||
runs ->
|
||||
expect(console.warn.callCount).toBe 1
|
||||
expect(console.warn.argsForCall[0][0].length).toBeGreaterThan 0
|
||||
|
||||
describe "when in safe mode", ->
|
||||
beforeEach ->
|
||||
themeManager = new ThemeManager({packageManager: atom.packages, resourcePath, configDirPath, safeMode: true})
|
||||
|
||||
describe 'when the enabled UI and syntax themes are bundled with Atom', ->
|
||||
beforeEach ->
|
||||
atom.config.set('core.themes', ['atom-light-ui', 'atom-dark-syntax'])
|
||||
|
||||
waitsForPromise ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
it 'uses the enabled themes', ->
|
||||
activeThemeNames = themeManager.getActiveNames()
|
||||
expect(activeThemeNames.length).toBe(2)
|
||||
expect(activeThemeNames).toContain('atom-light-ui')
|
||||
expect(activeThemeNames).toContain('atom-dark-syntax')
|
||||
|
||||
describe 'when the enabled UI and syntax themes are not bundled with Atom', ->
|
||||
beforeEach ->
|
||||
atom.config.set('core.themes', ['installed-dark-ui', 'installed-dark-syntax'])
|
||||
|
||||
waitsForPromise ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
it 'uses the default dark UI and syntax themes', ->
|
||||
activeThemeNames = themeManager.getActiveNames()
|
||||
expect(activeThemeNames.length).toBe(2)
|
||||
expect(activeThemeNames).toContain('atom-dark-ui')
|
||||
expect(activeThemeNames).toContain('atom-dark-syntax')
|
||||
|
||||
describe 'when the enabled UI theme is not bundled with Atom', ->
|
||||
beforeEach ->
|
||||
atom.config.set('core.themes', ['installed-dark-ui', 'atom-light-syntax'])
|
||||
|
||||
waitsForPromise ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
it 'uses the default dark UI theme', ->
|
||||
activeThemeNames = themeManager.getActiveNames()
|
||||
expect(activeThemeNames.length).toBe(2)
|
||||
expect(activeThemeNames).toContain('atom-dark-ui')
|
||||
expect(activeThemeNames).toContain('atom-light-syntax')
|
||||
|
||||
describe 'when the enabled syntax theme is not bundled with Atom', ->
|
||||
beforeEach ->
|
||||
atom.config.set('core.themes', ['atom-light-ui', 'installed-dark-syntax'])
|
||||
|
||||
waitsForPromise ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
it 'uses the default dark syntax theme', ->
|
||||
activeThemeNames = themeManager.getActiveNames()
|
||||
expect(activeThemeNames.length).toBe(2)
|
||||
expect(activeThemeNames).toContain('atom-light-ui')
|
||||
expect(activeThemeNames).toContain('atom-dark-syntax')
|
||||
|
||||
@@ -18,7 +18,7 @@ class TimeReporter extends jasmine.Reporter
|
||||
log ?= (line) -> console.log(line)
|
||||
log "Longest running suites:"
|
||||
suites = _.map(window.timedSuites, (key, value) -> [value, key])
|
||||
for suite in _.sortBy(suites, (suite) => -suite[1])[0...number]
|
||||
for suite in _.sortBy(suites, (suite) -> -suite[1])[0...number]
|
||||
time = Math.round(suite[1] / 100) / 10
|
||||
log " #{suite[0]} (#{time}s)"
|
||||
undefined
|
||||
|
||||
+223
-158
@@ -1,4 +1,5 @@
|
||||
TokenizedBuffer = require '../src/tokenized-buffer'
|
||||
TextBuffer = require 'text-buffer'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
describe "TokenizedBuffer", ->
|
||||
@@ -12,6 +13,9 @@ describe "TokenizedBuffer", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-javascript')
|
||||
|
||||
afterEach ->
|
||||
tokenizedBuffer?.destroy()
|
||||
|
||||
startTokenizing = (tokenizedBuffer) ->
|
||||
tokenizedBuffer.setVisible(true)
|
||||
|
||||
@@ -37,7 +41,7 @@ describe "TokenizedBuffer", ->
|
||||
buffer = atom.project.bufferForPathSync('sample.js')
|
||||
tokenizedBuffer = new TokenizedBuffer({buffer})
|
||||
startTokenizing(tokenizedBuffer)
|
||||
tokenizedBuffer.on "changed", changeHandler = jasmine.createSpy('changeHandler')
|
||||
tokenizedBuffer.onDidChange changeHandler = jasmine.createSpy('changeHandler')
|
||||
|
||||
afterEach ->
|
||||
tokenizedBuffer.destroy()
|
||||
@@ -45,38 +49,38 @@ describe "TokenizedBuffer", ->
|
||||
|
||||
describe "on construction", ->
|
||||
it "initially creates un-tokenized screen lines, then tokenizes lines chunk at a time in the background", ->
|
||||
line0 = tokenizedBuffer.lineForScreenRow(0)
|
||||
line0 = tokenizedBuffer.tokenizedLineForRow(0)
|
||||
expect(line0.tokens.length).toBe 1
|
||||
expect(line0.tokens[0]).toEqual(value: line0.text, scopes: ['source.js'])
|
||||
|
||||
line11 = tokenizedBuffer.lineForScreenRow(11)
|
||||
line11 = tokenizedBuffer.tokenizedLineForRow(11)
|
||||
expect(line11.tokens.length).toBe 2
|
||||
expect(line11.tokens[0]).toEqual(value: " ", scopes: ['source.js'], isAtomic: true)
|
||||
expect(line11.tokens[1]).toEqual(value: "return sort(Array.apply(this, arguments));", scopes: ['source.js'])
|
||||
|
||||
# background tokenization has not begun
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).ruleStack).toBeUndefined()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).ruleStack).toBeUndefined()
|
||||
|
||||
# tokenize chunk 1
|
||||
advanceClock()
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.lineForScreenRow(4).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).ruleStack?).toBeFalsy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(4).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).ruleStack?).toBeFalsy()
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 0, end: 4, delta: 0)
|
||||
changeHandler.reset()
|
||||
|
||||
# tokenize chunk 2
|
||||
advanceClock()
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.lineForScreenRow(9).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.lineForScreenRow(10).ruleStack?).toBeFalsy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(9).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(10).ruleStack?).toBeFalsy()
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 5, end: 9, delta: 0)
|
||||
changeHandler.reset()
|
||||
|
||||
# tokenize last chunk
|
||||
advanceClock()
|
||||
expect(tokenizedBuffer.lineForScreenRow(10).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.lineForScreenRow(12).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(10).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(12).ruleStack?).toBeTruthy()
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 10, end: 12, delta: 0)
|
||||
|
||||
describe "when the buffer is partially tokenized", ->
|
||||
@@ -130,8 +134,8 @@ describe "TokenizedBuffer", ->
|
||||
expect(tokenizedBuffer.firstInvalidRow()).toBe 5
|
||||
buffer.setTextInRange([[6, 0], [7, 0]], "\n\n\n")
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(6).ruleStack?).toBeFalsy()
|
||||
expect(tokenizedBuffer.lineForScreenRow(7).ruleStack?).toBeFalsy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(6).ruleStack?).toBeFalsy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(7).ruleStack?).toBeFalsy()
|
||||
|
||||
changeHandler.reset()
|
||||
expect(tokenizedBuffer.firstInvalidRow()).toBe 5
|
||||
@@ -145,10 +149,10 @@ describe "TokenizedBuffer", ->
|
||||
it "updates tokens to reflect the change", ->
|
||||
buffer.setTextInRange([[0, 0], [2, 0]], "foo()\n7\n")
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[1]).toEqual(value: '(', scopes: ['source.js', 'meta.brace.round.js'])
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[0]).toEqual(value: '7', scopes: ['source.js', 'constant.numeric.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[1]).toEqual(value: '(', scopes: ['source.js', 'meta.brace.round.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[0]).toEqual(value: '7', scopes: ['source.js', 'constant.numeric.js'])
|
||||
# line 2 is unchanged
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[2]).toEqual(value: 'if', scopes: ['source.js', 'keyword.control.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[2]).toEqual(value: 'if', scopes: ['source.js', 'keyword.control.js'])
|
||||
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
@@ -160,7 +164,7 @@ describe "TokenizedBuffer", ->
|
||||
buffer.insert([5, 30], '/* */')
|
||||
changeHandler.reset()
|
||||
buffer.insert([2, 0], '/*')
|
||||
expect(tokenizedBuffer.lineForScreenRow(3).tokens[0].scopes).toEqual ['source.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopes).toEqual ['source.js']
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
delete event.bufferChange
|
||||
@@ -168,9 +172,9 @@ describe "TokenizedBuffer", ->
|
||||
changeHandler.reset()
|
||||
|
||||
advanceClock()
|
||||
expect(tokenizedBuffer.lineForScreenRow(3).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.lineForScreenRow(4).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
delete event.bufferChange
|
||||
@@ -181,23 +185,23 @@ describe "TokenizedBuffer", ->
|
||||
buffer.insert([5, 0], '*/')
|
||||
|
||||
buffer.insert([1, 0], 'var ')
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
|
||||
describe "when lines are both updated and removed", ->
|
||||
it "updates tokens to reflect the change", ->
|
||||
buffer.setTextInRange([[1, 0], [3, 0]], "foo()")
|
||||
|
||||
# previous line 0 remains
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[0]).toEqual(value: 'var', scopes: ['source.js', 'storage.modifier.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[0]).toEqual(value: 'var', scopes: ['source.js', 'storage.modifier.js'])
|
||||
|
||||
# previous line 3 should be combined with input to form line 1
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[0]).toEqual(value: 'foo', scopes: ['source.js'])
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[6]).toEqual(value: '=', scopes: ['source.js', 'keyword.operator.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[0]).toEqual(value: 'foo', scopes: ['source.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[6]).toEqual(value: '=', scopes: ['source.js', 'keyword.operator.js'])
|
||||
|
||||
# lines below deleted regions should be shifted upward
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[2]).toEqual(value: 'while', scopes: ['source.js', 'keyword.control.js'])
|
||||
expect(tokenizedBuffer.lineForScreenRow(3).tokens[4]).toEqual(value: '=', scopes: ['source.js', 'keyword.operator.js'])
|
||||
expect(tokenizedBuffer.lineForScreenRow(4).tokens[4]).toEqual(value: '<', scopes: ['source.js', 'keyword.operator.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[2]).toEqual(value: 'while', scopes: ['source.js', 'keyword.control.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[4]).toEqual(value: '=', scopes: ['source.js', 'keyword.operator.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[4]).toEqual(value: '<', scopes: ['source.js', 'keyword.operator.js'])
|
||||
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
@@ -210,8 +214,8 @@ describe "TokenizedBuffer", ->
|
||||
changeHandler.reset()
|
||||
|
||||
buffer.setTextInRange([[2, 0], [3, 0]], '/*')
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[0].scopes).toEqual ['source.js', 'comment.block.js', 'punctuation.definition.comment.js']
|
||||
expect(tokenizedBuffer.lineForScreenRow(3).tokens[0].scopes).toEqual ['source.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[0].scopes).toEqual ['source.js', 'comment.block.js', 'punctuation.definition.comment.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopes).toEqual ['source.js']
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
delete event.bufferChange
|
||||
@@ -219,8 +223,8 @@ describe "TokenizedBuffer", ->
|
||||
changeHandler.reset()
|
||||
|
||||
advanceClock()
|
||||
expect(tokenizedBuffer.lineForScreenRow(3).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.lineForScreenRow(4).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
delete event.bufferChange
|
||||
@@ -231,19 +235,19 @@ describe "TokenizedBuffer", ->
|
||||
buffer.setTextInRange([[1, 0], [2, 0]], "foo()\nbar()\nbaz()\nquux()")
|
||||
|
||||
# previous line 0 remains
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[0]).toEqual( value: 'var', scopes: ['source.js', 'storage.modifier.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[0]).toEqual( value: 'var', scopes: ['source.js', 'storage.modifier.js'])
|
||||
|
||||
# 3 new lines inserted
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[0]).toEqual(value: 'foo', scopes: ['source.js'])
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[0]).toEqual(value: 'bar', scopes: ['source.js'])
|
||||
expect(tokenizedBuffer.lineForScreenRow(3).tokens[0]).toEqual(value: 'baz', scopes: ['source.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[0]).toEqual(value: 'foo', scopes: ['source.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[0]).toEqual(value: 'bar', scopes: ['source.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0]).toEqual(value: 'baz', scopes: ['source.js'])
|
||||
|
||||
# previous line 2 is joined with quux() on line 4
|
||||
expect(tokenizedBuffer.lineForScreenRow(4).tokens[0]).toEqual(value: 'quux', scopes: ['source.js'])
|
||||
expect(tokenizedBuffer.lineForScreenRow(4).tokens[4]).toEqual(value: 'if', scopes: ['source.js', 'keyword.control.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[0]).toEqual(value: 'quux', scopes: ['source.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[4]).toEqual(value: 'if', scopes: ['source.js', 'keyword.control.js'])
|
||||
|
||||
# previous line 3 is pushed down to become line 5
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).tokens[4]).toEqual(value: '=', scopes: ['source.js', 'keyword.operator.js'])
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[4]).toEqual(value: '=', scopes: ['source.js', 'keyword.operator.js'])
|
||||
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
@@ -260,17 +264,17 @@ describe "TokenizedBuffer", ->
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
delete event.bufferChange
|
||||
expect(event).toEqual(start: 2, end: 2, delta: 2)
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[0].scopes).toEqual ['source.js', 'comment.block.js', 'punctuation.definition.comment.js']
|
||||
expect(tokenizedBuffer.lineForScreenRow(3).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.lineForScreenRow(4).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).tokens[0].scopes).toEqual ['source.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[0].scopes).toEqual ['source.js', 'comment.block.js', 'punctuation.definition.comment.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[0].scopes).toEqual ['source.js']
|
||||
changeHandler.reset()
|
||||
|
||||
advanceClock() # tokenize invalidated lines in background
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.lineForScreenRow(6).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.lineForScreenRow(7).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.lineForScreenRow(8).tokens[0].scopes).not.toBe ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(6).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(7).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(8).tokens[0].scopes).not.toBe ['source.js', 'comment.block.js']
|
||||
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
@@ -281,13 +285,13 @@ describe "TokenizedBuffer", ->
|
||||
it "tokenizes the initial chunk synchronously, then tokenizes the remaining lines in the background", ->
|
||||
commentBlock = _.multiplyString("// a comment\n", tokenizedBuffer.chunkSize + 2)
|
||||
buffer.insert([0,0], commentBlock)
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.lineForScreenRow(4).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).ruleStack?).toBeFalsy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(4).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).ruleStack?).toBeFalsy()
|
||||
|
||||
advanceClock()
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.lineForScreenRow(6).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).ruleStack?).toBeTruthy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(6).ruleStack?).toBeTruthy()
|
||||
|
||||
describe ".findOpeningBracket(closingBufferPosition)", ->
|
||||
it "returns the position of the matching bracket, skipping any nested brackets", ->
|
||||
@@ -298,18 +302,18 @@ describe "TokenizedBuffer", ->
|
||||
expect(tokenizedBuffer.findClosingBracket([1, 29])).toEqual [9, 2]
|
||||
|
||||
it "tokenizes leading whitespace based on the new tab length", ->
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).tokens[0].isAtomic).toBeTruthy()
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).tokens[0].value).toBe " "
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).tokens[1].isAtomic).toBeTruthy()
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).tokens[1].value).toBe " "
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[0].isAtomic).toBeTruthy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[0].value).toBe " "
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[1].isAtomic).toBeTruthy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[1].value).toBe " "
|
||||
|
||||
tokenizedBuffer.setTabLength(4)
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).tokens[0].isAtomic).toBeTruthy()
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).tokens[0].value).toBe " "
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).tokens[1].isAtomic).toBeFalsy()
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).tokens[1].value).toBe " current "
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[0].isAtomic).toBeTruthy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[0].value).toBe " "
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[1].isAtomic).toBeFalsy()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[1].value).toBe " current "
|
||||
|
||||
describe "when the buffer contains hard-tabs", ->
|
||||
beforeEach ->
|
||||
@@ -331,7 +335,7 @@ describe "TokenizedBuffer", ->
|
||||
|
||||
it "renders each tab as its own atomic token with a value of size tabLength", ->
|
||||
tabAsSpaces = _.multiplyString(' ', tokenizedBuffer.getTabLength())
|
||||
screenLine0 = tokenizedBuffer.lineForScreenRow(0)
|
||||
screenLine0 = tokenizedBuffer.tokenizedLineForRow(0)
|
||||
expect(screenLine0.text).toBe "# Econ 101#{tabAsSpaces}"
|
||||
{ tokens } = screenLine0
|
||||
|
||||
@@ -343,7 +347,7 @@ describe "TokenizedBuffer", ->
|
||||
expect(tokens[2].isAtomic).toBeTruthy()
|
||||
expect(tokens[3].value).toBe ""
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).text).toBe "#{tabAsSpaces} buy()#{tabAsSpaces}while supply > demand"
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).text).toBe "#{tabAsSpaces} buy()#{tabAsSpaces}while supply > demand"
|
||||
|
||||
it "aligns the hard tabs to the correct tab stop column", ->
|
||||
buffer.setText """
|
||||
@@ -355,62 +359,62 @@ describe "TokenizedBuffer", ->
|
||||
tokenizedBuffer.setTabLength(4)
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).text).toBe "1 2 3 4"
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[1].screenDelta).toBe 3
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).text).toBe "1 2 3 4"
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[1].screenDelta).toBe 3
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).text).toBe "12 3 4 5"
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[1].screenDelta).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).text).toBe "12 3 4 5"
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[1].screenDelta).toBe 2
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).text).toBe "123 4 5 6"
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[1].screenDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).text).toBe "123 4 5 6"
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[1].screenDelta).toBe 1
|
||||
|
||||
tokenizedBuffer.setTabLength(3)
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).text).toBe "1 2 3 4"
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[1].screenDelta).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).text).toBe "1 2 3 4"
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[1].screenDelta).toBe 2
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).text).toBe "12 3 4 5"
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[1].screenDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).text).toBe "12 3 4 5"
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[1].screenDelta).toBe 1
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).text).toBe "123 4 5 6"
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[1].screenDelta).toBe 3
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).text).toBe "123 4 5 6"
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[1].screenDelta).toBe 3
|
||||
|
||||
tokenizedBuffer.setTabLength(2)
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).text).toBe "1 2 3 4"
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[1].screenDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).text).toBe "1 2 3 4"
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[1].screenDelta).toBe 1
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).text).toBe "12 3 4 5"
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[1].screenDelta).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).text).toBe "12 3 4 5"
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[1].screenDelta).toBe 2
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).text).toBe "123 4 5 6"
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[1].screenDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).text).toBe "123 4 5 6"
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[1].screenDelta).toBe 1
|
||||
|
||||
tokenizedBuffer.setTabLength(1)
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).text).toBe "1 2 3 4"
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[1].screenDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).text).toBe "1 2 3 4"
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[1].screenDelta).toBe 1
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).text).toBe "12 3 4 5"
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[1].screenDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).text).toBe "12 3 4 5"
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[1].screenDelta).toBe 1
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).text).toBe "123 4 5 6"
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[1].screenDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).text).toBe "123 4 5 6"
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[1].bufferDelta).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[1].screenDelta).toBe 1
|
||||
|
||||
describe "when the buffer contains UTF-8 surrogate pairs", ->
|
||||
beforeEach ->
|
||||
@@ -431,7 +435,7 @@ describe "TokenizedBuffer", ->
|
||||
buffer.release()
|
||||
|
||||
it "renders each UTF-8 surrogate pair as its own atomic token", ->
|
||||
screenLine0 = tokenizedBuffer.lineForScreenRow(0)
|
||||
screenLine0 = tokenizedBuffer.tokenizedLineForRow(0)
|
||||
expect(screenLine0.text).toBe "'abc\uD835\uDF97def'"
|
||||
{ tokens } = screenLine0
|
||||
|
||||
@@ -443,7 +447,7 @@ describe "TokenizedBuffer", ->
|
||||
expect(tokens[3].value).toBe "def"
|
||||
expect(tokens[4].value).toBe "'"
|
||||
|
||||
screenLine1 = tokenizedBuffer.lineForScreenRow(1)
|
||||
screenLine1 = tokenizedBuffer.tokenizedLineForRow(1)
|
||||
expect(screenLine1.text).toBe "//\uD835\uDF97xyz"
|
||||
{ tokens } = screenLine1
|
||||
|
||||
@@ -464,7 +468,7 @@ describe "TokenizedBuffer", ->
|
||||
|
||||
runs ->
|
||||
tokenizedBuffer = editor.displayBuffer.tokenizedBuffer
|
||||
tokenizedBuffer.on 'tokenized', tokenizedHandler
|
||||
tokenizedBuffer.onDidTokenize tokenizedHandler
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
expect(tokenizedHandler.callCount).toBe(1)
|
||||
|
||||
@@ -479,7 +483,7 @@ describe "TokenizedBuffer", ->
|
||||
tokenizedBuffer = editor.displayBuffer.tokenizedBuffer
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
|
||||
tokenizedBuffer.on 'tokenized', tokenizedHandler
|
||||
tokenizedBuffer.onDidTokenize tokenizedHandler
|
||||
editor.getBuffer().insert([0, 0], "'")
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
expect(tokenizedHandler).not.toHaveBeenCalled()
|
||||
@@ -495,7 +499,7 @@ describe "TokenizedBuffer", ->
|
||||
|
||||
runs ->
|
||||
tokenizedBuffer = editor.displayBuffer.tokenizedBuffer
|
||||
tokenizedBuffer.on 'tokenized', tokenizedHandler
|
||||
tokenizedBuffer.onDidTokenize tokenizedHandler
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
tokenizedHandler.reset()
|
||||
|
||||
@@ -521,7 +525,7 @@ describe "TokenizedBuffer", ->
|
||||
tokenizedBuffer.setGrammar(atom.syntax.selectGrammar('test.erb'))
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
|
||||
{tokens} = tokenizedBuffer.lineForScreenRow(0)
|
||||
{tokens} = tokenizedBuffer.tokenizedLineForRow(0)
|
||||
expect(tokens[0]).toEqual value: "<div class='name'>", scopes: ["text.html.ruby"]
|
||||
|
||||
waitsForPromise ->
|
||||
@@ -529,7 +533,7 @@ describe "TokenizedBuffer", ->
|
||||
|
||||
runs ->
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
{tokens} = tokenizedBuffer.lineForScreenRow(0)
|
||||
{tokens} = tokenizedBuffer.tokenizedLineForRow(0)
|
||||
expect(tokens[0]).toEqual value: '<', scopes: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.begin.html"]
|
||||
|
||||
describe ".tokenForPosition(position)", ->
|
||||
@@ -584,51 +588,112 @@ describe "TokenizedBuffer", ->
|
||||
atom.config.set('editor.tabLength', 0)
|
||||
expect(tokenizedBuffer.tokenForPosition([0,0]).value).toBe ' '
|
||||
|
||||
describe "when the invisibles value changes", ->
|
||||
beforeEach ->
|
||||
|
||||
it "updates the tokens with the appropriate invisible characters", ->
|
||||
buffer = new TextBuffer(text: " \t a line with tabs\tand \tspaces \t ")
|
||||
tokenizedBuffer = new TokenizedBuffer({buffer})
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
|
||||
tokenizedBuffer.setInvisibles(space: 'S', tab: 'T')
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).text).toBe "SST Sa line with tabsTand T spacesSTS"
|
||||
# Also needs to work for copies
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).copy().text).toBe "SST Sa line with tabsTand T spacesSTS"
|
||||
|
||||
it "assigns endOfLineInvisibles to tokenized lines", ->
|
||||
buffer = new TextBuffer(text: "a line that ends in a carriage-return-line-feed \r\na line that ends in just a line-feed\na line with no ending")
|
||||
tokenizedBuffer = new TokenizedBuffer({buffer})
|
||||
|
||||
atom.config.set('editor.showInvisibles', true)
|
||||
tokenizedBuffer.setInvisibles(cr: 'R', eol: 'N')
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).endOfLineInvisibles).toEqual ['R', 'N']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).endOfLineInvisibles).toEqual ['N']
|
||||
|
||||
# Lines ending in soft wraps get no invisibles
|
||||
[left, right] = tokenizedBuffer.tokenizedLineForRow(0).softWrapAt(20)
|
||||
expect(left.endOfLineInvisibles).toBe null
|
||||
expect(right.endOfLineInvisibles).toEqual ['R', 'N']
|
||||
|
||||
tokenizedBuffer.setInvisibles(cr: 'R', eol: false)
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).endOfLineInvisibles).toEqual ['R']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).endOfLineInvisibles).toEqual []
|
||||
|
||||
describe "leading and trailing whitespace", ->
|
||||
beforeEach ->
|
||||
buffer = atom.project.bufferForPathSync('sample.js')
|
||||
tokenizedBuffer = new TokenizedBuffer({buffer})
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
|
||||
it "sets ::hasLeadingWhitespace to true on tokens that have leading whitespace", ->
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[0].hasLeadingWhitespace).toBe false
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[0].hasLeadingWhitespace).toBe true
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[1].hasLeadingWhitespace).toBe false
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[0].hasLeadingWhitespace).toBe true
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[1].hasLeadingWhitespace).toBe true
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[2].hasLeadingWhitespace).toBe false
|
||||
it "assigns ::firstNonWhitespaceIndex on tokens that have leading whitespace", ->
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[0].firstNonWhitespaceIndex).toBe null
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[0].firstNonWhitespaceIndex).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[1].firstNonWhitespaceIndex).toBe null
|
||||
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[0].firstNonWhitespaceIndex).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[1].firstNonWhitespaceIndex).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[2].firstNonWhitespaceIndex).toBe null
|
||||
|
||||
# The 4th token *has* leading whitespace, but isn't entirely whitespace
|
||||
buffer.insert([5, 0], ' ')
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).tokens[3].hasLeadingWhitespace).toBe true
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).tokens[4].hasLeadingWhitespace).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[3].firstNonWhitespaceIndex).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[4].firstNonWhitespaceIndex).toBe null
|
||||
|
||||
# Lines that are *only* whitespace are not considered to have leading whitespace
|
||||
buffer.insert([10, 0], ' ')
|
||||
expect(tokenizedBuffer.lineForScreenRow(10).tokens[0].hasLeadingWhitespace).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(10).tokens[0].firstNonWhitespaceIndex).toBe null
|
||||
|
||||
it "sets ::hasTrailingWhitespace to true on tokens that have trailing whitespace", ->
|
||||
it "assigns ::firstTrailingWhitespaceIndex on tokens that have trailing whitespace", ->
|
||||
buffer.insert([0, Infinity], ' ')
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[11].hasTrailingWhitespace).toBe false
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[12].hasTrailingWhitespace).toBe true
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[11].firstTrailingWhitespaceIndex).toBe null
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[12].firstTrailingWhitespaceIndex).toBe 0
|
||||
|
||||
# The last token *has* trailing whitespace, but isn't entirely whitespace
|
||||
buffer.setTextInRange([[2, 39], [2, 40]], ' ')
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[14].hasTrailingWhitespace).toBe false
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[15].hasTrailingWhitespace).toBe true
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[14].firstTrailingWhitespaceIndex).toBe null
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[15].firstTrailingWhitespaceIndex).toBe 6
|
||||
|
||||
# Lines that are *only* whitespace are considered to have trailing whitespace
|
||||
buffer.insert([10, 0], ' ')
|
||||
expect(tokenizedBuffer.lineForScreenRow(10).tokens[0].hasTrailingWhitespace).toBe true
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(10).tokens[0].firstTrailingWhitespaceIndex).toBe 0
|
||||
|
||||
it "only marks trailing whitespace on the last segment of a soft-wrapped line", ->
|
||||
buffer.insert([0, Infinity], ' ')
|
||||
tokenizedLine = tokenizedBuffer.lineForScreenRow(0)
|
||||
tokenizedLine = tokenizedBuffer.tokenizedLineForRow(0)
|
||||
[segment1, segment2] = tokenizedLine.softWrapAt(16)
|
||||
expect(segment1.tokens[5].value).toBe ' '
|
||||
expect(segment1.tokens[5].hasTrailingWhitespace).toBe false
|
||||
expect(segment1.tokens[5].firstTrailingWhitespaceIndex).toBe null
|
||||
expect(segment2.tokens[6].value).toBe ' '
|
||||
expect(segment2.tokens[6].hasTrailingWhitespace).toBe true
|
||||
expect(segment2.tokens[6].firstTrailingWhitespaceIndex).toBe 0
|
||||
|
||||
it "sets leading and trailing whitespace correctly on a line with invisible characters that is copied", ->
|
||||
buffer.setText(" \t a line with tabs\tand \tspaces \t ")
|
||||
|
||||
tokenizedBuffer.setInvisibles(space: 'S', tab: 'T')
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
|
||||
line = tokenizedBuffer.tokenizedLineForRow(0).copy()
|
||||
expect(line.tokens[0].firstNonWhitespaceIndex).toBe 2
|
||||
expect(line.tokens[line.tokens.length - 1].firstTrailingWhitespaceIndex).toBe 0
|
||||
|
||||
it "sets the ::firstNonWhitespaceIndex and ::firstTrailingWhitespaceIndex correctly when tokens are split for soft-wrapping", ->
|
||||
tokenizedBuffer.setInvisibles(space: 'S')
|
||||
buffer.setText(" token ")
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
token = tokenizedBuffer.tokenizedLines[0].tokens[0]
|
||||
|
||||
[leftToken, rightToken] = token.splitAt(1)
|
||||
expect(leftToken.hasInvisibleCharacters).toBe true
|
||||
expect(leftToken.firstNonWhitespaceIndex).toBe 1
|
||||
expect(leftToken.firstTrailingWhitespaceIndex).toBe null
|
||||
|
||||
expect(leftToken.hasInvisibleCharacters).toBe true
|
||||
expect(rightToken.firstNonWhitespaceIndex).toBe null
|
||||
expect(rightToken.firstTrailingWhitespaceIndex).toBe 5
|
||||
|
||||
describe "indent level", ->
|
||||
beforeEach ->
|
||||
@@ -638,84 +703,84 @@ describe "TokenizedBuffer", ->
|
||||
|
||||
describe "when the line is non-empty", ->
|
||||
it "has an indent level based on the leading whitespace on the line", ->
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).indentLevel).toBe 0
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).indentLevel).toBe 1
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).indentLevel).toBe 0
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).indentLevel).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).indentLevel).toBe 2
|
||||
buffer.insert([2, 0], ' ')
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).indentLevel).toBe 2.5
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).indentLevel).toBe 2.5
|
||||
|
||||
describe "when the line is empty", ->
|
||||
it "assumes the indentation level of the first non-empty line below or above if one exists", ->
|
||||
buffer.insert([12, 0], ' ')
|
||||
buffer.insert([12, Infinity], '\n\n')
|
||||
expect(tokenizedBuffer.lineForScreenRow(13).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.lineForScreenRow(14).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(13).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(14).indentLevel).toBe 2
|
||||
|
||||
buffer.insert([1, Infinity], '\n\n')
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.lineForScreenRow(3).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(3).indentLevel).toBe 2
|
||||
|
||||
buffer.setText('\n\n\n')
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).indentLevel).toBe 0
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).indentLevel).toBe 0
|
||||
|
||||
describe "when the changed lines are surrounded by whitespace-only lines", ->
|
||||
it "updates the indentLevel of empty lines that precede the change", ->
|
||||
expect(tokenizedBuffer.lineForScreenRow(12).indentLevel).toBe 0
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(12).indentLevel).toBe 0
|
||||
|
||||
buffer.insert([12, 0], '\n')
|
||||
buffer.insert([13, 0], ' ')
|
||||
expect(tokenizedBuffer.lineForScreenRow(12).indentLevel).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(12).indentLevel).toBe 1
|
||||
|
||||
it "updates empty line indent guides when the empty line is the last line", ->
|
||||
buffer.insert([12, 2], '\n')
|
||||
|
||||
# The newline and he tab need to be in two different operations to surface the bug
|
||||
buffer.insert([12, 0], ' ')
|
||||
expect(tokenizedBuffer.lineForScreenRow(13).indentLevel).toBe 1
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(13).indentLevel).toBe 1
|
||||
|
||||
buffer.insert([12, 0], ' ')
|
||||
expect(tokenizedBuffer.lineForScreenRow(13).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.lineForScreenRow(14)).not.toBeDefined()
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(13).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(14)).not.toBeDefined()
|
||||
|
||||
it "updates the indentLevel of empty lines surrounding a change that inserts lines", ->
|
||||
# create some new lines
|
||||
buffer.insert([7, 0], '\n\n')
|
||||
buffer.insert([5, 0], '\n\n')
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).indentLevel).toBe 3
|
||||
expect(tokenizedBuffer.lineForScreenRow(6).indentLevel).toBe 3
|
||||
expect(tokenizedBuffer.lineForScreenRow(9).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.lineForScreenRow(10).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.lineForScreenRow(11).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).indentLevel).toBe 3
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(6).indentLevel).toBe 3
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(9).indentLevel).toBe 3
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(10).indentLevel).toBe 3
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(11).indentLevel).toBe 2
|
||||
|
||||
tokenizedBuffer.on "changed", changeHandler = jasmine.createSpy('changeHandler')
|
||||
tokenizedBuffer.onDidChange changeHandler = jasmine.createSpy('changeHandler')
|
||||
|
||||
buffer.setTextInRange([[7, 0], [8, 65]], ' one\n two\n three\n four')
|
||||
|
||||
delete changeHandler.argsForCall[0][0].bufferChange
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 5, end: 8, delta: 2)
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 5, end: 10, delta: 2)
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).indentLevel).toBe 4
|
||||
expect(tokenizedBuffer.lineForScreenRow(6).indentLevel).toBe 4
|
||||
expect(tokenizedBuffer.lineForScreenRow(11).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.lineForScreenRow(12).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.lineForScreenRow(13).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).indentLevel).toBe 4
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(6).indentLevel).toBe 4
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(11).indentLevel).toBe 4
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(12).indentLevel).toBe 4
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(13).indentLevel).toBe 2
|
||||
|
||||
it "updates the indentLevel of empty lines surrounding a change that removes lines", ->
|
||||
# create some new lines
|
||||
buffer.insert([7, 0], '\n\n')
|
||||
buffer.insert([5, 0], '\n\n')
|
||||
|
||||
tokenizedBuffer.on "changed", changeHandler = jasmine.createSpy('changeHandler')
|
||||
tokenizedBuffer.onDidChange changeHandler = jasmine.createSpy('changeHandler')
|
||||
|
||||
buffer.setTextInRange([[7, 0], [8, 65]], ' ok')
|
||||
|
||||
delete changeHandler.argsForCall[0][0].bufferChange
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 5, end: 8, delta: -1)
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 5, end: 10, delta: -1)
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(5).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.lineForScreenRow(6).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.lineForScreenRow(7).indentLevel).toBe 2 # new text
|
||||
expect(tokenizedBuffer.lineForScreenRow(8).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.lineForScreenRow(9).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.lineForScreenRow(10).indentLevel).toBe 2 # }
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(6).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(7).indentLevel).toBe 2 # new text
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(8).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(9).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(10).indentLevel).toBe 2 # }
|
||||
|
||||
@@ -10,13 +10,13 @@ describe "TokenizedLine", ->
|
||||
atom.project.open('coffee.coffee').then (o) -> editor = o
|
||||
|
||||
it "returns true when the line is only whitespace", ->
|
||||
expect(editor.lineForScreenRow(3).isOnlyWhitespace()).toBe true
|
||||
expect(editor.lineForScreenRow(7).isOnlyWhitespace()).toBe true
|
||||
expect(editor.lineForScreenRow(23).isOnlyWhitespace()).toBe true
|
||||
expect(editor.tokenizedLineForScreenRow(3).isOnlyWhitespace()).toBe true
|
||||
expect(editor.tokenizedLineForScreenRow(7).isOnlyWhitespace()).toBe true
|
||||
expect(editor.tokenizedLineForScreenRow(23).isOnlyWhitespace()).toBe true
|
||||
|
||||
it "returns false when the line is not only whitespace", ->
|
||||
expect(editor.lineForScreenRow(0).isOnlyWhitespace()).toBe false
|
||||
expect(editor.lineForScreenRow(2).isOnlyWhitespace()).toBe false
|
||||
expect(editor.tokenizedLineForScreenRow(0).isOnlyWhitespace()).toBe false
|
||||
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", ->
|
||||
@@ -35,6 +35,6 @@ describe "TokenizedLine", ->
|
||||
|
||||
runs ->
|
||||
tokenIndex = 0
|
||||
tokens = editor.lineForScreenRow(1).tokens
|
||||
scopeTree = editor.lineForScreenRow(1).getScopeTree()
|
||||
tokens = editor.tokenizedLineForScreenRow(1).tokens
|
||||
scopeTree = editor.tokenizedLineForScreenRow(1).getScopeTree()
|
||||
ensureValidScopeTree(scopeTree)
|
||||
|
||||
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