Comparar commits

...

179 Commits

Autor SHA1 Mensagem Data
Nathan Sobo 85b95ebda5 Re-render everything if scrolling more than a page 2014-05-06 17:08:52 -06:00
Nathan Sobo c6beefc3c2 Render each line as its own texture on the GPU 2014-05-06 12:45:25 -06:00
Nathan Sobo eb9b3eddd8 Correctly handle updates that replace all the lines 2014-05-06 12:45:09 -06:00
Nathan Sobo d33cad1a06 Incrementally update lines when scrolling and disable gutter
React seems to be taking a long time to diff gutter lines and lines
when scrolling. This is an experiment to remove that overhead.
2014-05-06 11:17:37 -06:00
Nathan Sobo 2688e7ff56 Start optimization experiment: Render lines manually
This is just setting innerHTML of the lines div every time, which is
obviously slow. Next step, draw only the newest lines unless the line
height has changed.
2014-05-06 10:17:07 -06:00
Nathan Sobo 3810167feb Only refresh editor scrollbars on stylesheet changes that require it
If a stylesheet is added or removed, we check if it contains a selector
for scrollbars before refreshing anything.
2014-05-05 18:58:45 -06:00
Nathan Sobo efc336bf8e Emit stylesheet-added/removed from ThemeManager w/ CSSStyleSheet objects
This enables subscribers to detect not just that stylesheets have
changed, but specifically how they have changed. This is used by the
React editor component to only refresh scrollbars when a stylesheet
that actually contains selectors for scrollbar elements is added or
removed.
2014-05-05 18:58:45 -06:00
Nathan Sobo dfcf2af1e1 Default scrollbar height/width to 15 when it's measure as 0
A 0 measurement indicates that overlay scrollbars are enabled, so we
just fall back to 15px in that case so the user can hover directly over
the scrollbar to scroll.
2014-05-05 18:58:45 -06:00
Nathan Sobo 084dae1775 Hide and show scrollbars before measuring them after stylesheet changes
We measure the scrollbar-corner node when there's a stylesheet change,
but Chromium won't apply the new style if it was already visible before
the change. This commit hides and shows it before measuring so we get
accurate values.
2014-05-05 18:58:45 -06:00
Nathan Sobo 1270af928f Explicitly assign dummy scrollbars to the correct width/height
Previously, dummy scrollbars were always 15px wide/tall. This caused
them to obscure the ability to click for the entire 15px region, even if
the actual scrollbar was styled to be much thinner. Now we explicitly
measure the size of scrollbars on mount and when the stylesheets change
and set the height/width explicitly.
2014-05-05 18:58:45 -06:00
Nathan Sobo 644d0c72c6 Hide scrollbar when not scrollable in a given direction 2014-05-05 18:58:45 -06:00
Nathan Sobo bbef96d583 Add a dummy scrollbar corner
Horizontal / vertical scrollbars render a 'corner' on the lower right
when they would otherwise overlap. I previously relied on drawing both
dummy scrollbars at their full width/height so the corner got rendered,
but that interfered with the display of the horizontal scrollbar in
certain circumstances because it was too wide to scroll. This commit
provides that behavior with an absolutely positioned div with the same
dimensions as the intersection of scrollbars when both are visible.
2014-05-05 18:58:44 -06:00
Nathan Sobo df373a0024 Don't allow spec window size to interfere with the size of the editor 2014-05-05 18:58:44 -06:00
Nathan Sobo db70a23c1a Don't obscure last character of long lines with vertical scrollbar
This entailed quite a few changes to dial in scrollbars. The scrollbars
are now adjusted in size to account for the width of the opposite
scrollbar. If the width or height are not explicitly constrained and we
are scrollable in the opposite direction that is constrained, we account
for the width of the opposite scrollbar in assigning a natural height
or width based on the content.
2014-05-05 18:58:44 -06:00
Nathan Sobo c5f73840f8 Account for gutter width in scrollWidth of horizontal scrollbar
Because the scrollbar now spans the entire editor but the scrollable
area does not include the gutter, we need to add the current width of
the gutter to the scroll width of the horizontal scrollbar to allow
it to scroll to the end of the longest lines.
2014-05-05 18:58:44 -06:00
Nathan Sobo f95e06cf64 Remove stray return in spec 2014-05-05 18:58:44 -06:00
Nathan Sobo 4f62352565 Update line number padding when max digits changes 2014-05-05 18:58:44 -06:00
Nathan Sobo 3f4274f724 Remove logging 2014-05-05 18:58:44 -06:00
Nathan Sobo 42c645c98e Fix specs that broke when accounting for horizontal scrollbar height 2014-05-05 18:58:44 -06:00
Nathan Sobo 55af1c1a46 Respect horizontal scrollbar when rendering the vertical, and vice versa
We set overflow to hidden in the opposite scroll direction only if we
can't actually scroll in that direction, causing the white square where
neither scrollbar overlaps to appear at the lower right corner.
2014-05-05 18:58:44 -06:00
Nathan Sobo 1ad394b1ea Update scrollTop to valid position when scrollbar disappears 2014-05-05 18:58:44 -06:00
Nathan Sobo 7a88376d78 Revert "Revert "Don't obscure the last line of the editor with the horizontal scrollbar""
This reverts commit 1d634e471e.
2014-05-05 18:58:44 -06:00
Kevin Sawicki 11eae4d5db Upgrade to language-gfm@0.33.0 2014-05-05 17:43:28 -07:00
Kevin Sawicki 0b786427f4 Set CFBundleTypeIconFile to file.icns
Closes #1726
2014-05-05 17:22:33 -07:00
Kevin Sawicki 4900dc6bcd Set LSHandlerRank to Alternate
This should prevent Atom from being the default editor for all these file
types and instead make it opt-in.

Closes #1808
2014-05-05 17:22:33 -07:00
Corey Johnson 637410a8c5 Upgrade to grunt-download-atom-shell@0.7.0 2014-05-05 17:10:35 -07:00
Kevin Sawicki 1d31a10dc4 Include original LICENSE.md in generated file 2014-05-05 16:01:05 -07:00
Kevin Sawicki db61de6cf3 Add .md extension to generated license 2014-05-05 15:55:34 -07:00
Kevin Sawicki c75d36ef93 Implement application:open-license in AtomWindow
Allows the LICENSE.md file to be opened even when no windows are
open.

Closes #1624
2014-05-05 15:54:47 -07:00
Kevin Sawicki 7bb6cd99eb Tweak README copy 2014-05-05 13:04:22 -07:00
Kevin Sawicki 3dbdaee25c Merge pull request #1898 from atom/open-source-release
Open Source Atom
2014-05-05 12:59:19 -07:00
Kevin Sawicki b458de0f2d Merge pull request #1921 from atom/ks-split-option-errors
Fix split option errors
2014-05-05 11:36:24 -07:00
Kevin Sawicki 240747ed76 💄 Tweak spec descriptions 2014-05-05 11:28:36 -07:00
Kevin Sawicki 8b5fd64dd4 Guard against PaneAxis as first child
Pane::findLeftmostSibling expected to return a Pane, not a PaneAxis
2014-05-05 11:28:36 -07:00
Kevin Sawicki 1c514bdc6b Split right when rightmost sibling is an axis
This was previously throwing an error when Workspace::open was called
with a split: right option and the rightmost sibling was a PaneAxis
since it was assuming findOrCreateRightmostSibling was always returning
a Pane, not a PaneAxis.
2014-05-05 11:28:36 -07:00
Kevin Sawicki f4d9abc789 Use ~ instead of ^ to support older npm versions 2014-05-05 11:07:43 -07:00
Kevin Sawicki e5197f6f0f Fench code block as sh 2014-05-05 11:06:36 -07:00
Kevin Sawicki 8f57246571 Upgrade to settings-view@0.114.0 2014-05-05 11:03:55 -07:00
Kevin Sawicki 7658107e3b Merge pull request #1920 from atom/new-brand-assets
New brand assets
2014-05-05 10:29:27 -07:00
Kevin Sawicki c33227830e Add file icon for all sizes 2014-05-05 10:22:28 -07:00
Kevin Sawicki 43f2153c86 Add icons for all sizes 2014-05-05 10:14:47 -07:00
Kevin Sawicki 084d84660a Update atom.icns with single 2x 512x512 2014-05-05 09:58:12 -07:00
Cameron McEfee 4120b34d22 larger icon graphic 2014-05-05 09:51:01 -07:00
Kevin Sawicki c4a0bce92f Upgrade to tabs@0.39.0 2014-05-05 09:49:44 -07:00
Kevin Sawicki 858c18114b Update file and app icons 2014-05-05 09:39:24 -07:00
Cameron McEfee 91f9302fc4 improve aliasing on the new icon 2014-05-05 09:33:02 -07:00
Kevin Sawicki 4f3bf04668 Update atom.icns with new icon 2014-05-05 09:19:17 -07:00
Kevin Sawicki 11c9417e8d Upgrade to scope-property-store@0.9.0 2014-05-05 08:51:59 -07:00
Kevin Sawicki db141d9d7f Upgrade to markdown-preview@0.69.0 2014-05-05 08:49:01 -07:00
Cameron McEfee 5624596c88 Update the icon png 2014-05-04 15:51:41 -07:00
Cameron McEfee cda7ca047c Logo in the docs 2014-05-04 15:48:25 -07:00
Cameron McEfee ac25ad3985 Logo in the readme 2014-05-04 15:42:45 -07:00
Kevin Sawicki 1bf4e7ab96 Upgrade to first-mate 1.5.3 2014-05-02 18:08:01 -07:00
Kevin Sawicki 49587ace05 Upgrade to tree-view@0.92.0 2014-05-02 11:12:10 -07:00
Ivan Žužak 54fb06d4b0 Upgrade to release-notes@0.28.0 2014-05-02 20:02:24 +02:00
Ivan Žužak 8f81b5dc63 Upgrade to find-and-replace@0.100.0 2014-05-02 20:00:47 +02:00
Kevin Sawicki d5e1649607 Upgrade to settings-view@0.113.0 2014-05-02 10:50:46 -07:00
Kevin Sawicki e2c1f6c0e2 Upgrade to markdown-preview@0.68.0 2014-05-02 10:16:01 -07:00
Kevin Sawicki 8ec7d1273c Cache handlerPath 2014-05-01 17:05:47 -07:00
Kevin Sawicki 7ffc5cc02b Terminate task before recreating 2014-05-01 17:05:28 -07:00
Kevin Sawicki aac27db552 Upgrade to grammar-selector@0.26.0 2014-05-01 16:04:45 -07:00
Kevin Sawicki 03acb1c40a Upgrade to markdown-preview@0.67.0 2014-05-01 15:38:38 -07:00
Kevin Sawicki 5eb332042e Merge pull request #1915 from atom/ks-safe-mode
Safe mode
2014-05-01 15:30:44 -07:00
Kevin Sawicki 66943c4820 Add application:open-safe command
This opens a new "safe mode" window similar to the application:open-dev
command
2014-05-01 15:20:22 -07:00
Kevin Sawicki 4ed9e34893 Tweak option description 2014-05-01 15:20:22 -07:00
Kevin Sawicki 4f4da78e54 Add --safe argument
This will launch Atom in "safe" mode where packages from ~/.atom
will not be loaded automatically or be resolveable by name.
2014-05-01 15:20:22 -07:00
Kevin Sawicki 832dfd057e Upgrade to tabs@0.38.0 2014-05-01 15:14:39 -07:00
Kevin Sawicki dd74280146 Set status to 0 if it is ignored
The statuses obtained via the background task do not include ignored
entries so don't put ignored entries into the cache when checking the
status individually.

This was causing the fuzzy finder to show ignored paths in the status
list view after an ignored file was saved.
2014-05-01 14:20:46 -07:00
Kevin Sawicki a7d1a68fb8 Upgrade to git-utils 1.3 2014-05-01 14:13:19 -07:00
Kevin Sawicki 6b8b454625 Upgrade to symbols-view@0.50.0 2014-05-01 13:12:05 -07:00
Kevin Sawicki 5c5b7df70d Upgrade to tree-view@0.91.0 2014-04-30 16:54:32 -07:00
Corey Johnson 7d3abda86f Fix Workspace::openLicense 2014-04-30 16:38:44 -07:00
Kevin Sawicki 7f824ffbb3 Merge pull request #1914 from atom/ks-open-to-column
Open to initial column
2014-04-30 16:21:49 -07:00
Corey Johnson 0b7475a4c1 Merge remote-tracking branch 'origin/master' into open-source-release
Conflicts:
	package.json
2014-04-30 16:11:44 -07:00
Kevin Sawicki cf62d3212c Use path.join instead of hard-coded separator 2014-04-30 16:07:26 -07:00
Kevin Sawicki b260cbb43a Call open on model instead of view 2014-04-30 16:07:26 -07:00
Kevin Sawicki 1367f08de8 Parse initial column from path to open argument 2014-04-30 16:07:26 -07:00
Kevin Sawicki 27b02a7981 Add initialColumn options to Workspace::open
This options works similarly to the existing initialLine option
2014-04-30 16:07:26 -07:00
Corey Johnson e62ae02c00 Update file.icns 2014-04-30 16:04:58 -07:00
Corey Johnson 233402dd33 Update atom icon 2014-04-30 15:52:13 -07:00
Corey Johnson 69821b7a6b Add .gitignore file to dot-atom.
This will help users who want to push their .atom directory to GitHub

Closes #1094
2014-04-30 14:41:23 -07:00
Kevin Sawicki efcffe5205 Remove unused grunt task 2014-04-30 14:31:43 -07:00
Kevin Sawicki 802e651b6e 📝 Link to apm repo 2014-04-30 14:18:11 -07:00
Kevin Sawicki 0e8b951050 Upper case pane to match File menu item 2014-04-30 14:10:41 -07:00
Corey Johnson 8ef97bd78e Add menu items for pane management on windows 2014-04-30 13:59:49 -07:00
Corey Johnson 6749988de1 Add menu items for pane management
Closes #1897
2014-04-30 13:57:37 -07:00
Kevin Sawicki 4a26f8f28b Merge pull request #1912 from atom/ks-whitespace-double-click
Whitespace double click
2014-04-30 10:10:26 -07:00
Kevin Sawicki a4ee412e96 Remove Math.max corrections to range
Editor::getTextInBufferRange will clip the specified range instead.
2014-04-30 09:58:37 -07:00
Kevin Sawicki 4f655d7de5 📝 Update comment to match behavior 2014-04-30 09:58:37 -07:00
Kevin Sawicki 33c02ef3e1 Mention double clicking in spec description 2014-04-30 09:58:37 -07:00
Kevin Sawicki aa4749f175 Select all adjacent whitespace on double click
Cursor::isSurroundedByWhitespace was use column 0 instead of the
position right before the cursor.
2014-04-30 09:58:37 -07:00
Kevin Sawicki 6ace49b0e8 Merge pull request #1911 from atom/ks-preserve-indentation-when-commenting
Preserve indentation when commenting
2014-04-30 09:58:17 -07:00
Kevin Sawicki 9cf642e910 Preserve indentation when commenting
Previously this happened only when the language did not have a
comment end pattern.
2014-04-30 09:50:11 -07:00
Kevin Sawicki 2990f36595 Remove unused publish release step 2014-04-30 09:43:01 -07:00
Kevin Sawicki 032fc86a4d Merge pull request #1913 from atom/ks-no-more-atom-master-builds
Stop uploading to atom-master-builds
2014-04-30 09:35:41 -07:00
Kevin Sawicki 868cbb680c Stop uploading to atom-master-builds
Packages using Travis now build against a release build
2014-04-30 09:29:05 -07:00
Kevin Sawicki 98d2aaf10e Upgrade to language-java@0.10.0 2014-04-30 09:17:00 -07:00
Kevin Sawicki f7dead17c0 Upgrade to markdown-preview@0.66.0 2014-04-30 09:09:15 -07:00
Cheng Zhao f3168b2672 Use "closed" event instead of "destroyed".
The meaning of "destroyed" event has changed since atom-shell v0.12.0,
fixes #1910.
2014-04-30 12:25:59 +08:00
Corey Johnson e8c62b501f Fix workspaceView spec 2014-04-29 16:59:15 -07:00
Nathan Sobo 6ff2b2a01e Fix undefined variables in tokenized-line-spec 2014-04-29 17:24:16 -06:00
Kevin Sawicki 960285a270 Unfocus EditorComponent spec 2014-04-29 16:11:20 -07:00
Kevin Sawicki 17cd979299 Upgrade to apm@0.45.0 2014-04-29 15:32:00 -07:00
Kevin Sawicki b5846f9755 Upgrade to atom-keymap@0.19.0
Closes #1908
2014-04-29 09:01:54 -07:00
Kevin Sawicki dd39ffdf3b Upgrade to settings-view@0.112.0 2014-04-29 08:25:04 -07:00
Cheng Zhao 368b871270 Merge pull request #1907 from atom/atom-shell-v0.12.0
Upgrade to atom-shell@0.12.0
2014-04-29 15:49:45 +08:00
Cheng Zhao 9c06b4d344 Some events of browser-window have changed. 2014-04-29 15:25:36 +08:00
Cheng Zhao f48241bc5e Use new IPC API of atom-shell. 2014-04-29 15:16:27 +08:00
Cheng Zhao a7b94e1709 Upgrade to atom-shell@0.12.0 2014-04-29 15:09:47 +08:00
probablycorey 3d2dedb49f Update the readme 2014-04-28 14:42:31 -07:00
probablycorey dd5ab8098e Use consistent version pattern
Use `^Z` `^Z.Z` or `^Z.Z.Z`
2014-04-28 14:27:11 -07:00
Kevin Sawicki f5b833c49c Upgrade to apm 0.43.0 2014-04-28 14:06:32 -07:00
Kevin Sawicki ba032be402 Upgrade to apm@0.42.0 2014-04-28 13:20:14 -07:00
Kevin Sawicki a96a448063 Upgrade to language-go@0.10.0 2014-04-28 10:52:12 -07:00
Kevin Sawicki faeed9f604 Upgrade to snippets@0.43.0 2014-04-25 14:57:07 -07:00
probablycorey 0a8f2422d3 Use public grunt-download-atom-shell 2014-04-24 17:37:24 -07:00
Kevin Sawicki 24dbe19a82 Upgrade to language-c@0.15.0 2014-04-24 16:45:44 -07:00
Kevin Sawicki 7d8901072c Upgrade to snippets@0.42.0 2014-04-24 16:23:23 -07:00
Kevin Sawicki 848a4e2052 Merge pull request #1904 from atom/ks-remove-apm-submodule
Remove apm submodule
2014-04-24 16:21:49 -07:00
Kevin Sawicki e8090b16f3 Move apm version to apm/package.json 2014-04-24 15:43:35 -07:00
Kevin Sawicki 950964eee3 Remove directory that no longer exists 2014-04-24 15:43:35 -07:00
Kevin Sawicki b403f76d81 Remove .gitmodules 2014-04-24 15:43:35 -07:00
Kevin Sawicki 8f2cdae0eb Install apm from npmjs.org 2014-04-24 15:43:35 -07:00
Corey Johnson fa4b3c8dea Merge pull request #1903 from atom/cj-add-deprecation-warning-to-specs
Remove all deprecated calls from core
2014-04-24 15:36:53 -07:00
Kevin Sawicki e76bbc0f13 Guard against deleted submodule 2014-04-24 15:12:08 -07:00
Corey Johnson c9a377d4ac Deprecate reopenItemSync 2014-04-24 14:28:09 -07:00
Corey Johnson c7e308bca0 Remove use of OpenSync from specs 2014-04-24 14:14:10 -07:00
Corey Johnson 5193e6e46b Upgrade to text-buffer@2.2.0 2014-04-24 14:13:57 -07:00
Kevin Sawicki 66628e8c52 Update broken link to publish doc 2014-04-24 13:56:14 -07:00
Corey Johnson bec65cf2ac Only fail on deprecations when core specs are run 2014-04-24 13:47:01 -07:00
Corey Johnson 606b249430 Upgrade to grim@0.10.0 2014-04-24 13:34:56 -07:00
Kevin Sawicki 8bc1b7e955 Prepare 0.93.0 release 2014-04-24 12:07:35 -07:00
Corey Johnson 2ceccf5239 Exclude EditorViews that are mini editors from WorkspaceView::eachEditorView
Fixes #1900
2014-04-24 09:26:04 -07:00
Nathan Sobo ad8bd98c9a Don't overwrite the file-scoped path variable 2014-04-24 10:13:01 -06:00
Nathan Sobo 6c4e138ec0 Upgrade to language-ruby@0.23.0 2014-04-24 09:52:45 -06:00
Kevin Sawicki 9ad1021c2d Upgrade to settings-view@0.111.0 2014-04-23 18:14:18 -07:00
Corey Johnson c03dec2783 Merge remote-tracking branch 'origin/master' into cj-add-deprecation-warning-to-specs 2014-04-23 16:51:14 -07:00
Corey Johnson 9d92a27ccf Remove deprecated method calls from project spec 2014-04-23 16:50:25 -07:00
Corey Johnson b652dc8fd8 Use workspace.open instead of project.open 2014-04-23 16:36:44 -07:00
Corey Johnson c1929540a3 Remove deprecated calls in pane view spec 2014-04-23 16:35:51 -07:00
Corey Johnson 1601423f30 Update deprecated calls in language mode spec 2014-04-23 16:31:00 -07:00
Corey Johnson 1de2c14e50 Use TextBuffer::getEndPosition 2014-04-23 16:30:38 -07:00
Corey Johnson c1907054b7 Remove deprecated methods from display buffer spec 2014-04-23 16:24:10 -07:00
Corey Johnson 5f524c1181 Remove deprecated calls from git spec 2014-04-23 16:22:44 -07:00
Corey Johnson b897603b66 Remove deprecated option from selection spec 2014-04-23 16:22:34 -07:00
Corey Johnson 0e5c530006 Remove rogue focused spec 2014-04-23 16:19:43 -07:00
Corey Johnson 4a60b5787a Remove deprecated calls from editor view spec 2014-04-23 16:18:48 -07:00
Corey Johnson 88cc69f87a Update enableKeymap spec helper 2014-04-23 16:18:36 -07:00
Corey Johnson 42e91defb9 Rename getEofPosition to getEndPosition 2014-04-23 16:06:32 -07:00
Nathan Sobo aeb5a84696 Do render indent guides for tokens with leading whitespace 2014-04-23 17:04:20 -06:00
Nathan Sobo 228836447c Only render trailing whitespace indent guides on whitespace-only lines
Fixes #1895
2014-04-23 16:58:10 -06:00
Kevin Sawicki 832cc40a7f Add .md extension 2014-04-23 15:36:57 -07:00
Corey Johnson d89b4534f1 Update the year 2014-04-23 15:35:33 -07:00
Corey Johnson 725f6f7cf2 Use MIT license 2014-04-23 15:34:29 -07:00
Kevin Sawicki b760d3e4fc Upgrade to markdown-preview@0.65.0 2014-04-23 13:21:51 -07:00
Nathan Sobo 1d634e471e Revert "Don't obscure the last line of the editor with the horizontal scrollbar"
This reverts commit babbdbf9e5.
2014-04-23 14:03:33 -06:00
Nathan Sobo babbdbf9e5 Don't obscure the last line of the editor with the horizontal scrollbar
This assumes the scrollbar is 15px high, which is incorrect when using
overlay scrollbars or when the scrollbar is styled to have a different
height. We'll need to measure it in a subsequent commit.
2014-04-23 13:59:35 -06:00
Nathan Sobo e9d820e8a8 💄 GutterComponent 2014-04-23 13:59:35 -06:00
Nathan Sobo 16e05347a7 Remove unneeded componentWillUnmount method
It's defined in the SubscriberMixin
2014-04-23 13:59:35 -06:00
Kevin Sawicki 2574ee5936 Prepare 0.92.0 release 2014-04-23 12:02:36 -07:00
Corey Johnson 38c25feee0 Remove deprecated calls to editor spec 2014-04-23 11:27:23 -07:00
Corey Johnson a15bb260c0 Update call to TextBuffer::rangeForRow 2014-04-22 17:52:07 -07:00
Corey Johnson 6b833043db Removed references to the isReversed option 2014-04-22 17:51:44 -07:00
Corey Johnson b30a2c9442 Remove deprecated calls from workspace view spec 2014-04-22 16:51:50 -07:00
Corey Johnson 3eb99c9391 Remove deprecated call from spec helper 2014-04-22 16:51:38 -07:00
Corey Johnson 10636b96bc buildBufferSync can't be deprecated because TokenizedBuffer uses it 2014-04-22 16:48:01 -07:00
Corey Johnson b5ac7c89a3 Update spec to match its description 2014-04-22 16:47:17 -07:00
Corey Johnson 01298bb470 Fix deprecation message 2014-04-22 16:22:23 -07:00
Corey Johnson 3bd7bfcbf1 Merge remote-tracking branch 'origin/master' into cj-add-deprecation-warning-to-specs 2014-04-22 16:06:04 -07:00
Corey Johnson 3e94c0be22 Remove deprecated methods from window spec 2014-04-22 14:19:13 -07:00
Corey Johnson db0cce6234 Remove focused spec 2014-04-22 14:19:01 -07:00
Corey Johnson f3d4cbbd8f Remove unnecessary fat arrows 2014-04-22 14:15:56 -07:00
Corey Johnson 81df4ed238 Change Workspace::reopenItemSync to use promises 2014-04-22 14:15:07 -07:00
Corey Johnson 7b756ec3f3 Remove calls to openSync from the workspace-spec 2014-04-22 11:24:27 -07:00
Corey Johnson 0d95718d1f Remove focused spec 2014-04-22 11:04:14 -07:00
Corey Johnson 1da23e8d04 Remove deprecations from atom-spec 2014-04-22 11:01:21 -07:00
Corey Johnson 43792d019a Output deprecation message 2014-04-22 11:01:05 -07:00
Corey Johnson ec0b4a2dc6 Move deprecation output to its own function 2014-04-22 10:44:25 -07:00
Corey Johnson 1083136dec Don't allow specs that call deprecated methods to pass 2014-04-22 10:11:52 -07:00
68 arquivos alterados com 1801 adições e 1001 exclusões
-1
Ver Arquivo
@@ -12,4 +12,3 @@ debug.log
docs/output
docs/includes
spec/fixtures/evil-files/
/apm
-3
Ver Arquivo
@@ -1,3 +0,0 @@
[submodule "vendor/apm"]
path = vendor/apm
url = https://github.com/atom/apm.git
-1
Ver Arquivo
@@ -1 +0,0 @@
Copyright 2014 GitHub, Inc.
+20
Ver Arquivo
@@ -0,0 +1,20 @@
Copyright (c) 2014 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+17 -5
Ver Arquivo
@@ -1,8 +1,15 @@
# Atom — The hackable editor
![Atom](https://cloud.githubusercontent.com/assets/72919/2874231/3af1db48-d3dd-11e3-98dc-6066f8bc766f.png)
![Atom](http://i.imgur.com/OrTvUAD.png)
Atom is a hackable text editor for the 21st century.
Check out our [guides and API documentation](https://atom.io/docs/latest).
Atom is open source and built on top of [atom-shell](http://github.com/atom/atom-shell).
Atom is designed to be customizable, but also usable without needing to edit a config file.
Atom is modern, approachable, and hackable to the core.
Visit [atom.io](http://atom.io)
to learn more.
## Installing
@@ -12,6 +19,11 @@ Atom will automatically update when a new release is available.
## Building
Follow the instructions in the [build docs][building].
```sh
git clone git@github.com:atom/atom.git
cd atom
script/build # Creates application at /Applications/Atom.app
```
[building]: https://github.com/atom/atom/blob/master/docs/building-atom.md
## Developing
Check out the [guides](https://atom.io/docs/latest) and the [API reference](atom.io/docs/api).
+2
Ver Arquivo
@@ -0,0 +1,2 @@
This folder is where [apm](https://github.com/atom/apm) is installed to so that
it is bundled with Atom.
+11
Ver Arquivo
@@ -0,0 +1,11 @@
{
"name": "atom-bundled-apm",
"description": "Atom's bundled APM",
"repository": {
"type": "git",
"url": "https://github.com/atom/atom.git"
},
"dependencies": {
"atom-package-manager": "0.45.0"
}
}
+1 -1
Ver Arquivo
@@ -18,7 +18,7 @@
"grunt-contrib-coffee": "~0.9.0",
"grunt-contrib-less": "~0.8.0",
"grunt-cson": "0.8.0",
"grunt-download-atom-shell": "git+https://atom-bot:467bac80a0017b96fb5be5cfc686f5e0cc607b10@github.com/atom/grunt-download-atom-shell#v0.6.1",
"grunt-download-atom-shell": "~0.7.0",
"grunt-lesslint": "0.13.0",
"grunt-markdown": "~0.4.0",
"grunt-peg": "~1.1.0",
+2 -2
Ver Arquivo
@@ -17,7 +17,7 @@ module.exports = (grunt) ->
licenseText = getLicenseText(dependencyLicenses)
if mode is 'save'
targetPath = path.join(grunt.config.get('atom.appDir'), 'LICENSE')
targetPath = path.join(grunt.config.get('atom.appDir'), 'LICENSE.md')
fs.writeFileSync(targetPath, licenseText)
else
console.log licenseText
@@ -26,7 +26,7 @@ module.exports = (grunt) ->
getLicenseText = (dependencyLicenses) ->
{keys} = require 'underscore-plus'
text = """
Copyright 2014 GitHub, Inc.
#{fs.readFileSync('LICENSE.md')}
This application bundles the following third-party packages in accordance
with the following licenses:\n\n
+5 -74
Ver Arquivo
@@ -29,21 +29,14 @@ module.exports = (gruntObject) ->
done = @async()
buildDir = grunt.config.get('atom.buildDir')
createBuildRelease (error, release) ->
zipApps buildDir, assets, (error) ->
return done(error) if error?
zipApps buildDir, assets, (error) ->
getAtomDraftRelease (error, release) ->
return done(error) if error?
uploadAssets release, buildDir, assets, (error) ->
assetNames = (asset.assetName for asset in assets)
deleteExistingAssets release, assetNames, (error) ->
return done(error) if error?
publishRelease release, (error) ->
return done(error) if error?
getAtomDraftRelease (error, release) ->
return done(error) if error?
assetNames = (asset.assetName for asset in assets)
deleteExistingAssets release, assetNames, (error) ->
return done(error) if error?
uploadAssets(release, buildDir, assets, done)
uploadAssets(release, buildDir, assets, done)
logError = (message, error, details) ->
grunt.log.error(message)
@@ -64,25 +57,6 @@ zipApps = (buildDir, assets, callback) ->
tasks.push(zip.bind(this, buildDir, sourceName, assetName))
async.parallel(tasks, callback)
getRelease = (callback) ->
options =
uri: 'https://api.github.com/repos/atom/atom-master-builds/releases'
method: 'GET'
headers: defaultHeaders
json: true
request options, (error, response, releases=[]) ->
if error? or response.statusCode isnt 200
logError('Fetching releases failed', error, releases)
callback(error ? new Error(response.statusCode))
else
if releases.length > maxReleases
deleteRelease(release) for release in releases[maxReleases..]
for release in releases when release.name is commitSha
callback(null, release)
return
callback()
getAtomDraftRelease = (callback) ->
atomRepo = new GitHub({repo: 'atom/atom', token})
atomRepo.getReleases (error, releases=[]) ->
@@ -125,35 +99,6 @@ deleteExistingAssets = (release, assetNames, callback) ->
tasks.push(deleteAsset.bind(this, asset.url))
async.parallel(tasks, callback)
createBuildRelease = (callback) ->
getRelease (error, release) ->
if error?
callback(error)
return
if release?
deleteExistingAssets release, (error) ->
callback(error, release)
return
options =
uri: 'https://api.github.com/repos/atom/atom-master-builds/releases'
method: 'POST'
headers: defaultHeaders
json:
tag_name: "v#{commitSha}"
target_commitish: 'master'
name: commitSha
body: "Build of [atom@#{commitSha.substring(0, 7)}](https://github.com/atom/atom/commits/#{commitSha})"
draft: true
prerelease: true
request options, (error, response, release={}) ->
if error? or response.statusCode isnt 201
logError('Creating release failed', error, release)
callback(error ? new Error(response.statusCode))
else
callback(null, release)
uploadAssets = (release, buildDir, assets, callback) ->
upload = (release, assetName, assetPath, callback) ->
options =
@@ -178,17 +123,3 @@ uploadAssets = (release, buildDir, assets, callback) ->
assetPath = path.join(buildDir, assetName)
tasks.push(upload.bind(this, release, assetName, assetPath))
async.parallel(tasks, callback)
publishRelease = (release, callback) ->
options =
uri: release.url
method: 'POST'
headers: defaultHeaders
json:
draft: false
request options, (error, response, body={}) ->
if error? or response.statusCode isnt 200
logError('Creating release failed', error, body)
callback(error ? new Error(response.statusCode))
else
callback()
-108
Ver Arquivo
@@ -1,108 +0,0 @@
async = require 'async'
request = require 'request'
# Configure and publish all packages in package.json to atom.io
#
# This task should be run whenever you want to be sure that atom.io contains
# all the packages and versions referenced in Atom's package.json file.
module.exports = (grunt) ->
{spawn} = require('./task-helpers')(grunt)
baseUrl = "https://atom.io/api/packages"
packageExists = (packageName, token, callback) ->
requestSettings =
url: "#{baseUrl}/#{packageName}"
json: true
headers:
authorization: token
request.get requestSettings, (error, response, body={}) ->
if error?
callback(error)
else
callback(null, response.statusCode is 404)
createPackage = (packageName, token, callback) ->
requestSettings =
url: baseUrl
json: true
headers:
authorization: token
method: 'POST'
body:
repository: "atom/#{packageName}"
request.get requestSettings, (error, response, body={}) ->
if error?
callback(error)
else if response.statusCode isnt 201
message = body.message ? body.error ? body
callback(new Error("Creating package failed: #{message}"))
else
callback()
createPackageVersion = (packageName, tag, token, callback) ->
requestSettings =
url: "#{baseUrl}/#{packageName}/versions"
json: true
method: 'POST'
headers:
authorization: token
body:
tag: tag
request.get requestSettings, (error, response, body={}) ->
if error?
callback(error)
else if response.statusCode isnt 201
message = body.message ? body.error ? body
if message is 'Version exists'
callback()
else
callback(new Error("Creating new version failed: #{message}"))
else
callback()
getToken = (callback) ->
if token = process.env.ATOM_ACCESS_TOKEN
callback(null, token)
else
spawn {cmd: 'security', args: ['-q', 'find-generic-password', '-ws', 'GitHub API Token']}, (error, result, code) ->
token = result.toString() unless error?
callback(error, token)
grunt.registerTask 'publish-packages', 'Publish all bundled packages', ->
done = @async()
getToken (error, token) ->
unless token
grunt.log.error('Token not found in keychain or ATOM_ACCESS_TOKEN environment variable')
done(false)
{packageDependencies} = grunt.file.readJSON('package.json') ? {}
tasks = []
for name, version of packageDependencies
do (name, version) ->
tasks.push (callback) ->
grunt.verbose.writeln("Publishing #{name}@#{version}")
tag = "v#{version}"
packageExists name, token, (error, exists) ->
if error?
callback(error)
return
if exists
createPackage name, token, (error) ->
if error?
callback(error)
else
createPackageVersion(name, tag, token, callback)
else
createPackageVersion(name, tag, token, callback)
async.waterfall tasks, (error) ->
if error?
grunt.log.error(error.message)
done(false)
else
done()
+1 -1
Ver Arquivo
@@ -1,6 +1,6 @@
# Welcome to the Atom API Documentation
![Atom](http://i.imgur.com/OrTvUAD.png)
![Atom](https://cloud.githubusercontent.com/assets/72919/2874231/3af1db48-d3dd-11e3-98dc-6066f8bc766f.png)
## FAQ
+2 -2
Ver Arquivo
@@ -21,7 +21,7 @@ To begin, press `cmd-shift-P` to bring up the [Command
Palette](https://github.com/atom/command-palette). Type "generate package" and
select the "Package Generator: Generate Package" command. Now we need to name
the package. Try to avoid naming your package with the *atom-* prefix, for
example we are going to call this package _ascii-art_.
example we are going to call this package _ascii-art_.
Atom will open a new window with the contents of our new _ascii-art_ package
displayed in the Tree View. Because this window is opened **after** the package
@@ -152,5 +152,5 @@ ASCII art professional!
* [Creating a package guide](creating-a-package.html) for more information
on the mechanics of packages
* [Publishing a package guide](publish-a-package.html) for more information
* [Publishing a package guide](publishing-a-package.html) for more information
on publishing your package to [atom.io](https://atom.io)
+5
Ver Arquivo
@@ -0,0 +1,5 @@
storage
compile-cache
dev
.npm
.node-gyp
+19
Ver Arquivo
@@ -134,6 +134,25 @@
submenu: [
{ label: 'Reload', command: 'window:reload' }
{ label: 'Toggle Full Screen', command: 'window:toggle-full-screen' }
{
label: 'Panes'
submenu: [
{ label: 'Split Up', command: 'pane:split-up' }
{ label: 'Split Down', command: 'pane:split-down' }
{ label: 'Split Left', command: 'pane:split-left' }
{ label: 'Split Right', command: 'pane:split-right' }
{ type: 'separator' }
{ label: 'Focus Next Pane', command: 'window:focus-next-pane' }
{ label: 'Focus Previous Pane', command: 'window:focus-previous-pane' }
{ type: 'separator' }
{ label: 'Focus Pane Above', command: 'window:focus-pane-above' }
{ label: 'Focus Pane Below', command: 'window:focus-pane-below' }
{ label: 'Focus Pane On Left', command: 'window:focus-pane-on-left' }
{ label: 'Focus Pane On Right', command: 'window:focus-pane-on-right' }
{ type: 'separator' }
{ label: 'Close Pane', command: 'pane:close' }
]
}
{
label: 'Developer'
submenu: [
+19
Ver Arquivo
@@ -88,6 +88,25 @@
submenu: [
{ label: '&Reload', command: 'window:reload' }
{ label: 'Toggle &Full Screen', command: 'window:toggle-full-screen' }
{
label: 'Panes'
submenu: [
{ label: 'Split Up', command: 'pane:split-up' }
{ label: 'Split Down', command: 'pane:split-down' }
{ label: 'Split Left', command: 'pane:split-left' }
{ label: 'Split Right', command: 'pane:split-right' }
{ type: 'separator' }
{ label: 'Focus Next Pane', command: 'window:focus-next-pane' }
{ label: 'Focus Previous Pane', command: 'window:focus-previous-pane' }
{ type: 'separator' }
{ label: 'Focus Pane Above', command: 'window:focus-pane-above' }
{ label: 'Focus Pane Below', command: 'window:focus-pane-below' }
{ label: 'Focus Pane On Left', command: 'window:focus-pane-on-left' }
{ label: 'Focus Pane On Right', command: 'window:focus-pane-on-right' }
{ type: 'separator' }
{ label: 'Close pane', command: 'pane:close' }
]
}
{
label: 'Developer'
submenu: [
+35 -30
Ver Arquivo
@@ -1,7 +1,7 @@
{
"name": "atom",
"productName": "Atom",
"version": "0.91.0",
"version": "0.93.0",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/browser/main.js",
"repository": {
@@ -11,48 +11,53 @@
"bugs": {
"url": "https://github.com/atom/atom/issues"
},
"license": "All Rights Reserved",
"atomShellVersion": "0.11.10",
"licenses": [
{
"type": "MIT",
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
}
],
"atomShellVersion": "0.12.0",
"dependencies": {
"async": "0.2.6",
"atom-keymap": "^0.18.0",
"atom-keymap": "^0.19.0",
"bootstrap": "git://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
"clear-cut": "0.4.0",
"coffee-script": "1.7.0",
"coffeestack": "0.7.0",
"delegato": "1.x",
"delegato": "^1",
"emissary": "^1.2.1",
"first-mate": "^1.5.2",
"first-mate": "^1.5.3",
"fs-plus": "^2.2.2",
"fstream": "0.1.24",
"fuzzaldrin": "~1.1",
"git-utils": "^1.2.2",
"grim": "0.9.0",
"fuzzaldrin": "^1.1",
"git-utils": "^1.3",
"grim": "0.10.0",
"guid": "0.0.10",
"jasmine-tagged": "^1.1.1",
"less-cache": "0.12.0",
"mixto": "1.x",
"mixto": "^1",
"mkdirp": "0.3.5",
"nslog": "0.5.0",
"oniguruma": "^1.0.6",
"optimist": "0.4.0",
"pathwatcher": "^1.2.1",
"property-accessors": "1.x",
"property-accessors": "^1",
"q": "^1.0.1",
"random-words": "0.0.1",
"react": "^0.10.0",
"reactionary": "^0.8.0",
"runas": "0.5.x",
"runas": "^0.5",
"scandal": "0.15.2",
"scoped-property-store": "^0.8.0",
"scoped-property-store": "^0.9.0",
"scrollbar-style": "^0.1.0",
"season": "^1.0.2",
"semver": "1.1.4",
"serializable": "1.x",
"serializable": "^1",
"space-pen": "3.1.1",
"temp": "0.5.0",
"text-buffer": "^2.1.0",
"theorist": "1.x",
"text-buffer": "^2.2.0",
"theorist": "^1",
"underscore-plus": "^1.2.1",
"vm-compatibility-layer": "0.1.0"
},
@@ -76,41 +81,41 @@
"dev-live-reload": "0.30.0",
"exception-reporting": "0.17.0",
"feedback": "0.30.0",
"find-and-replace": "0.99.0",
"find-and-replace": "0.100.0",
"fuzzy-finder": "0.50.0",
"git-diff": "0.28.0",
"go-to-line": "0.19.0",
"grammar-selector": "0.24.0",
"grammar-selector": "0.26.0",
"image-view": "0.33.0",
"keybinding-resolver": "0.17.0",
"link": "0.22.0",
"markdown-preview": "0.64.0",
"markdown-preview": "0.69.0",
"metrics": "0.32.0",
"open-on-github": "0.28.0",
"package-generator": "0.30.0",
"release-notes": "0.27.0",
"settings-view": "0.110.0",
"snippets": "0.41.0",
"release-notes": "0.28.0",
"settings-view": "0.114.0",
"snippets": "0.43.0",
"spell-check": "0.34.0",
"status-bar": "0.40.0",
"styleguide": "0.29.0",
"symbols-view": "0.49.0",
"tabs": "0.37.0",
"symbols-view": "0.50.0",
"tabs": "0.39.0",
"timecop": "0.18.0",
"tree-view": "0.90.0",
"tree-view": "0.92.0",
"update-package-dependencies": "0.6.0",
"welcome": "0.12.0",
"whitespace": "0.22.0",
"wrap-guide": "0.18.0",
"language-c": "0.14.0",
"language-c": "0.15.0",
"language-coffee-script": "0.22.0",
"language-css": "0.16.0",
"language-gfm": "0.31.0",
"language-gfm": "0.33.0",
"language-git": "0.9.0",
"language-go": "0.9.0",
"language-go": "0.10.0",
"language-html": "0.19.0",
"language-hyperlink": "0.9.0",
"language-java": "0.9.0",
"language-java": "0.10.0",
"language-javascript": "0.24.0",
"language-json": "0.8.0",
"language-less": "0.8.0",
@@ -120,7 +125,7 @@
"language-php": "0.14.0",
"language-property-list": "0.7.0",
"language-python": "0.15.0",
"language-ruby": "0.22.0",
"language-ruby": "0.23.0",
"language-ruby-on-rails": "0.12.0",
"language-sass": "0.10.0",
"language-shellscript": "0.8.0",
Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 191 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 284 KiB

Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Arquivo binário não exibido.
Arquivo binário não exibido.
+1 -5
Ver Arquivo
@@ -25,7 +25,6 @@ function executeCommands(commands, done, index) {
done(null);
}
var apmVendorPath = path.resolve(__dirname, '..', 'vendor', 'apm');
var apmInstallPath = path.resolve(__dirname, '..', 'apm');
if (!fs.existsSync(apmInstallPath))
fs.mkdirSync(apmInstallPath);
@@ -42,11 +41,8 @@ var packagesToDedupe = ['fs-plus', 'humanize-plus', 'oniguruma', 'roaster', 'sea
var echoNewLine = process.platform == 'win32' ? 'echo.' : 'echo';
var commands = [
'git submodule --quiet sync',
'git submodule --quiet update --recursive --init',
{command: 'npm' + npmFlags + 'install --quiet', options: {cwd: path.resolve(__dirname, '..', 'build'), ignoreStdout: true}},
{command: npmPath + npmFlags + 'install --quiet', options: {cwd: apmVendorPath, ignoreStdout: true}},
{command: npmPath + npmFlags + 'install --quiet ' + apmVendorPath, options: {cwd: apmInstallPath, ignoreStdout: true}},
{command: npmPath + npmFlags + 'install --quiet', options: {cwd: apmInstallPath, ignoreStdout: true}},
echoNewLine,
apmPath + ' clean ' + apmFlags,
apmPath + ' install --quiet ' + apmFlags,
-1
Ver Arquivo
@@ -18,7 +18,6 @@ var commands = [
[__dirname, '..', 'node_modules'],
[__dirname, '..', 'build', 'node_modules'],
[__dirname, '..', 'apm', 'node_modules'],
[__dirname, '..', 'vendor', 'apm', 'node_modules'],
[__dirname, '..', 'atom-shell'],
[home, '.atom', '.node-gyp'],
[home, '.atom', 'storage'],
+27 -24
Ver Arquivo
@@ -113,18 +113,21 @@ describe "the `atom` global", ->
promise
it "triggers the activation event on all handlers registered during activation", ->
atom.workspaceView.openSync()
editorView = atom.workspaceView.getActiveView()
eventHandler = jasmine.createSpy("activation-event")
editorView.command 'activation-event', eventHandler
editorView.trigger 'activation-event'
expect(mainModule.activate.callCount).toBe 1
expect(mainModule.activationEventCallCount).toBe 1
expect(eventHandler.callCount).toBe 1
editorView.trigger 'activation-event'
expect(mainModule.activationEventCallCount).toBe 2
expect(eventHandler.callCount).toBe 2
expect(mainModule.activate.callCount).toBe 1
waitsForPromise ->
atom.workspaceView.open()
runs ->
editorView = atom.workspaceView.getActiveView()
eventHandler = jasmine.createSpy("activation-event")
editorView.command 'activation-event', eventHandler
editorView.trigger 'activation-event'
expect(mainModule.activate.callCount).toBe 1
expect(mainModule.activationEventCallCount).toBe 1
expect(eventHandler.callCount).toBe 1
editorView.trigger 'activation-event'
expect(mainModule.activationEventCallCount).toBe 2
expect(eventHandler.callCount).toBe 2
expect(mainModule.activate.callCount).toBe 1
it "activates the package immediately when the events are empty", ->
mainModule = require './fixtures/packages/package-with-empty-activation-events/index'
@@ -170,28 +173,28 @@ describe "the `atom` global", ->
element2 = $$ -> @div class: 'test-2'
element3 = $$ -> @div class: 'test-3'
expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element1)).toHaveLength 0
expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element2)).toHaveLength 0
expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element3)).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
atom.packages.activatePackage("package-with-keymaps")
expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element1)[0].command).toBe "test-1"
expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element2)[0].command).toBe "test-2"
expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element3)).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe "test-1"
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])[0].command).toBe "test-2"
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
describe "when the metadata contains a 'keymaps' manifest", ->
it "loads only the keymaps specified by the manifest, in the specified order", ->
element1 = $$ -> @div class: 'test-1'
element3 = $$ -> @div class: 'test-3'
expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element1)).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])).toHaveLength 0
atom.packages.activatePackage("package-with-keymaps-manifest")
expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element1)[0].command).toBe 'keymap-1'
expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-n', element1)[0].command).toBe 'keymap-2'
expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-y', element3)).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe 'keymap-1'
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-n', target:element1[0])[0].command).toBe 'keymap-2'
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-y', target:element3[0])).toHaveLength 0
describe "menu loading", ->
beforeEach ->
@@ -377,8 +380,8 @@ describe "the `atom` global", ->
runs ->
atom.packages.deactivatePackage('package-with-keymaps')
expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', $$ -> @div class: 'test-1')).toHaveLength 0
expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', $$ -> @div class: 'test-2')).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:$$ -> @div class: 'test-1'[0])).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:$$ -> @div class: 'test-2'[0])).toHaveLength 0
it "removes the package's stylesheets", ->
waitsForPromise ->
+3 -1
Ver Arquivo
@@ -21,7 +21,7 @@ describe "DisplayBuffer", ->
describe "::copy()", ->
it "creates a new DisplayBuffer with the same initial state", ->
marker1 = displayBuffer.markBufferRange([[1, 2], [3, 4]], id: 1)
marker2 = displayBuffer.markBufferRange([[2, 3], [4, 5]], isReversed: true, id: 2)
marker2 = displayBuffer.markBufferRange([[2, 3], [4, 5]], reversed: true, id: 2)
marker3 = displayBuffer.markBufferPosition([5, 6], id: 3)
displayBuffer.createFold(3, 5)
@@ -979,6 +979,7 @@ describe "DisplayBuffer", ->
describe "::setScrollLeft", ->
beforeEach ->
displayBuffer.manageScrollPosition = true
displayBuffer.setLineHeight(10)
displayBuffer.setDefaultCharWidth(10)
it "disallows negative values", ->
@@ -1001,6 +1002,7 @@ describe "DisplayBuffer", ->
displayBuffer.manageScrollPosition = true
displayBuffer.setLineHeight(10)
displayBuffer.setDefaultCharWidth(10)
displayBuffer.setHorizontalScrollbarHeight(0)
displayBuffer.setHeight(50)
displayBuffer.setWidth(50)
+130 -3
Ver Arquivo
@@ -1,9 +1,9 @@
{extend, flatten, toArray} = require 'underscore-plus'
{extend, flatten, toArray, last} = require 'underscore-plus'
ReactEditorView = require '../src/react-editor-view'
nbsp = String.fromCharCode(160)
describe "EditorComponent", ->
[editor, wrapperView, component, node, verticalScrollbarNode, horizontalScrollbarNode] = []
[contentNode, editor, wrapperView, component, node, verticalScrollbarNode, horizontalScrollbarNode] = []
[lineHeightInPixels, charWidth, delayAnimationFrames, nextAnimationFrame] = []
beforeEach ->
@@ -22,7 +22,13 @@ describe "EditorComponent", ->
else
fn()
editor = atom.project.openSync('sample.js')
waitsForPromise ->
atom.project.open('sample.js').then (o) -> editor = o
runs ->
contentNode = document.querySelector('#jasmine-content')
contentNode.style.width = '1000px'
wrapperView = new ReactEditorView(editor)
wrapperView.attachToDom()
{component} = wrapperView
@@ -35,6 +41,9 @@ describe "EditorComponent", ->
verticalScrollbarNode = node.querySelector('.vertical-scrollbar')
horizontalScrollbarNode = node.querySelector('.horizontal-scrollbar')
afterEach ->
contentNode.style.width = ''
describe "line rendering", ->
it "renders only the currently-visible lines", ->
node.style.height = 4.5 * lineHeightInPixels + 'px'
@@ -185,6 +194,20 @@ describe "EditorComponent", ->
expect(lines[4].textContent).toBe "#{nbsp}3"
expect(lines[5].textContent).toBe "#{nbsp}"
it "pads line numbers to be right justified based on the maximum number of line number digits", ->
editor.getBuffer().setText([1..10].join('\n'))
lineNumberNodes = toArray(node.querySelectorAll('.line-number'))
for node, i in lineNumberNodes[0..8]
expect(node.textContent).toBe "#{nbsp}#{i + 1}"
expect(lineNumberNodes[9].textContent).toBe '10'
# Removes padding when the max number of digits goes down
editor.getBuffer().delete([[1, 0], [2, 0]])
lineNumberNodes = toArray(node.querySelectorAll('.line-number'))
for node, i in lineNumberNodes
expect(node.textContent).toBe "#{i + 1}"
describe "cursor rendering", ->
it "renders the currently visible cursors", ->
cursor1 = editor.getCursor()
@@ -526,6 +549,110 @@ describe "EditorComponent", ->
expect(editor.getScrollLeft()).toBe 100
it "does not obscure the last line with the horizontal scrollbar", ->
node.style.height = 4.5 * lineHeightInPixels + 'px'
node.style.width = 10 * charWidth + 'px'
component.measureHeightAndWidth()
editor.setScrollBottom(editor.getScrollHeight())
lastLineNode = last(node.querySelectorAll('.line'))
bottomOfLastLine = lastLineNode.getBoundingClientRect().bottom
topOfHorizontalScrollbar = horizontalScrollbarNode.getBoundingClientRect().top
expect(bottomOfLastLine).toBe topOfHorizontalScrollbar
# Scroll so there's no space below the last line when the horizontal scrollbar disappears
node.style.width = 100 * charWidth + 'px'
component.measureHeightAndWidth()
lastLineNode = last(node.querySelectorAll('.line'))
bottomOfLastLine = lastLineNode.getBoundingClientRect().bottom
bottomOfEditor = node.getBoundingClientRect().bottom
expect(bottomOfLastLine).toBe bottomOfEditor
it "does not obscure the last character of the longest line with the vertical scrollbar", ->
node.style.height = 7 * lineHeightInPixels + 'px'
node.style.width = 10 * charWidth + 'px'
component.measureHeightAndWidth()
editor.setScrollLeft(Infinity)
lineNodes = node.querySelectorAll('.line')
rightOfLongestLine = lineNodes[6].getBoundingClientRect().right
leftOfVerticalScrollbar = verticalScrollbarNode.getBoundingClientRect().left
expect(rightOfLongestLine).toBe leftOfVerticalScrollbar - 1 # Leave 1 px so the cursor is visible on the end of the line
it "only displays dummy scrollbars when scrollable in that direction", ->
expect(verticalScrollbarNode.style.display).toBe 'none'
expect(horizontalScrollbarNode.style.display).toBe 'none'
node.style.height = 4.5 * lineHeightInPixels + 'px'
node.style.width = '1000px'
component.measureHeightAndWidth()
expect(verticalScrollbarNode.style.display).toBe ''
expect(horizontalScrollbarNode.style.display).toBe 'none'
node.style.width = 10 * charWidth + 'px'
component.measureHeightAndWidth()
expect(verticalScrollbarNode.style.display).toBe ''
expect(horizontalScrollbarNode.style.display).toBe ''
node.style.height = 20 * lineHeightInPixels + 'px'
component.measureHeightAndWidth()
expect(verticalScrollbarNode.style.display).toBe 'none'
expect(horizontalScrollbarNode.style.display).toBe ''
it "makes the dummy scrollbar divs only as tall/wide as the actual scrollbars", ->
node.style.height = 4 * lineHeightInPixels + 'px'
node.style.width = 10 * charWidth + 'px'
component.measureHeightAndWidth()
atom.themes.applyStylesheet "test", """
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
"""
scrollbarCornerNode = node.querySelector('.scrollbar-corner')
expect(verticalScrollbarNode.offsetWidth).toBe 8
expect(horizontalScrollbarNode.offsetHeight).toBe 8
expect(scrollbarCornerNode.offsetWidth).toBe 8
expect(scrollbarCornerNode.offsetHeight).toBe 8
it "assigns the bottom/right of the scrollbars to the width of the opposite scrollbar if it is visible", ->
scrollbarCornerNode = node.querySelector('.scrollbar-corner')
expect(verticalScrollbarNode.style.bottom).toBe ''
expect(horizontalScrollbarNode.style.right).toBe ''
node.style.height = 4.5 * lineHeightInPixels + 'px'
node.style.width = '1000px'
component.measureHeightAndWidth()
expect(verticalScrollbarNode.style.bottom).toBe ''
expect(horizontalScrollbarNode.style.right).toBe verticalScrollbarNode.offsetWidth + 'px'
expect(scrollbarCornerNode.style.display).toBe 'none'
node.style.width = 10 * charWidth + 'px'
component.measureHeightAndWidth()
expect(verticalScrollbarNode.style.bottom).toBe horizontalScrollbarNode.offsetHeight + 'px'
expect(horizontalScrollbarNode.style.right).toBe verticalScrollbarNode.offsetWidth + 'px'
expect(scrollbarCornerNode.style.display).toBe ''
node.style.height = 20 * lineHeightInPixels + 'px'
component.measureHeightAndWidth()
expect(verticalScrollbarNode.style.bottom).toBe horizontalScrollbarNode.offsetHeight + 'px'
expect(horizontalScrollbarNode.style.right).toBe ''
expect(scrollbarCornerNode.style.display).toBe 'none'
it "accounts for the width of the gutter in the scrollWidth of the horizontal scrollbar", ->
gutterNode = node.querySelector('.gutter')
node.style.width = 10 * charWidth + 'px'
component.measureHeightAndWidth()
expect(horizontalScrollbarNode.scrollWidth).toBe gutterNode.offsetWidth + editor.getScrollWidth()
describe "when a mousewheel event occurs on the editor", ->
it "updates the horizontal or vertical scrollbar depending on which delta is greater (x or y)", ->
node.style.height = 4.5 * lineHeightInPixels + 'px'
+117 -56
Ver Arquivo
@@ -7,9 +7,12 @@ describe "Editor", ->
buffer.setText(buffer.getText().replace(/[ ]{2}/g, "\t"))
beforeEach ->
editor = atom.project.openSync('sample.js', autoIndent: false)
buffer = editor.buffer
lineLengths = buffer.getLines().map (line) -> line.length
waitsForPromise ->
atom.project.open('sample.js', autoIndent: false).then (o) -> editor = o
runs ->
buffer = editor.buffer
lineLengths = buffer.getLines().map (line) -> line.length
waitsForPromise ->
atom.packages.activatePackage('language-javascript')
@@ -17,7 +20,7 @@ describe "Editor", ->
describe "when the editor is deserialized", ->
it "restores selections and folds based on markers in the buffer", ->
editor.setSelectedBufferRange([[1, 2], [3, 4]])
editor.addSelectionForBufferRange([[5, 6], [7, 5]], isReversed: true)
editor.addSelectionForBufferRange([[5, 6], [7, 5]], reversed: true)
editor.foldBufferRow(4)
expect(editor.isFoldedAtBufferRow(4)).toBeTruthy()
@@ -31,15 +34,33 @@ describe "Editor", ->
editor2.destroy()
describe "when the editor is constructed with an initialLine option", ->
it "and positions the cursor on the specified line", ->
editor = atom.project.openSync('sample.js', initialLine: 2)
buffer = editor.buffer
expect(editor.getCursor().getBufferPosition().row).toEqual 2
it "positions the cursor on the specified line", ->
editor = null
waitsForPromise ->
atom.workspace.open('sample.less', initialLine: 5).then (o) -> editor = o
runs ->
buffer = editor.buffer
expect(editor.getCursor().getBufferPosition().row).toEqual 5
expect(editor.getCursor().getBufferPosition().column).toEqual 0
describe "when the editor is constructed with an initialColumn option", ->
it "positions the cursor on the specified column", ->
editor = null
waitsForPromise ->
atom.workspace.open('sample.less', initialColumn: 8).then (o) -> editor = o
runs ->
buffer = editor.buffer
expect(editor.getCursor().getBufferPosition().row).toEqual 0
expect(editor.getCursor().getBufferPosition().column).toEqual 8
describe ".copy()", ->
it "returns a different edit session with the same initial state", ->
editor.setSelectedBufferRange([[1, 2], [3, 4]])
editor.addSelectionForBufferRange([[5, 6], [7, 8]], isReversed: true)
editor.addSelectionForBufferRange([[5, 6], [7, 8]], reversed: true)
editor.foldBufferRow(4)
expect(editor.isFoldedAtBufferRow(4)).toBeTruthy()
@@ -57,21 +78,31 @@ describe "Editor", ->
describe "config defaults", ->
it "uses the `editor.tabLength`, `editor.softWrap`, and `editor.softTabs` config values", ->
editor1 = null
editor2 = null
atom.config.set('editor.tabLength', 4)
atom.config.set('editor.softWrap', true)
atom.config.set('editor.softTabs', false)
editor1 = atom.project.openSync('a')
expect(editor1.getTabLength()).toBe 4
expect(editor1.getSoftWrap()).toBe true
expect(editor1.getSoftTabs()).toBe false
atom.config.set('editor.tabLength', 100)
atom.config.set('editor.softWrap', false)
atom.config.set('editor.softTabs', true)
editor2 = atom.project.openSync('b')
expect(editor2.getTabLength()).toBe 100
expect(editor2.getSoftWrap()).toBe false
expect(editor2.getSoftTabs()).toBe true
waitsForPromise ->
atom.workspace.open('a').then (o) -> editor1 = o
runs ->
expect(editor1.getTabLength()).toBe 4
expect(editor1.getSoftWrap()).toBe true
expect(editor1.getSoftTabs()).toBe false
atom.config.set('editor.tabLength', 100)
atom.config.set('editor.softWrap', false)
atom.config.set('editor.softTabs', true)
waitsForPromise ->
atom.workspace.open('b').then (o) -> editor2 = o
runs ->
expect(editor2.getTabLength()).toBe 100
expect(editor2.getSoftWrap()).toBe false
expect(editor2.getSoftTabs()).toBe true
describe "title", ->
describe ".getTitle()", ->
@@ -667,6 +698,7 @@ describe "Editor", ->
editor.setHorizontalScrollMargin(2)
editor.setLineHeight(10)
editor.setDefaultCharWidth(10)
editor.setHorizontalScrollbarHeight(0)
editor.setHeight(5.5 * 10)
editor.setWidth(5.5 * 10)
@@ -759,7 +791,7 @@ describe "Editor", ->
expect(selection1.isReversed()).toBeFalsy()
it "merges selections when they intersect when moving up", ->
editor.setSelectedBufferRanges([[[0,9], [0,13]], [[1,10], [1,20]]], isReversed: true)
editor.setSelectedBufferRanges([[[0,9], [0,13]], [[1,10], [1,20]]], reversed: true)
[selection1, selection2] = editor.getSelections()
editor.selectUp()
@@ -770,7 +802,7 @@ describe "Editor", ->
expect(selection1.isReversed()).toBeTruthy()
it "merges selections when they intersect when moving left", ->
editor.setSelectedBufferRanges([[[0,9], [0,13]], [[0,14], [1,20]]], isReversed: true)
editor.setSelectedBufferRanges([[[0,9], [0,13]], [[0,14], [1,20]]], reversed: true)
[selection1, selection2] = editor.getSelections()
editor.selectLeft()
@@ -1107,6 +1139,7 @@ describe "Editor", ->
editor.setDefaultCharWidth(10)
editor.setHeight(50)
editor.setWidth(50)
editor.setHorizontalScrollbarHeight(0)
expect(editor.getScrollTop()).toBe 0
editor.setSelectedBufferRange([[5, 6], [6, 8]], autoscroll: true)
@@ -1339,10 +1372,14 @@ describe "Editor", ->
expect(selection.isEmpty()).toBeTruthy()
it "does not share selections between different edit sessions for the same buffer", ->
editor2 = atom.project.openSync('sample.js')
editor.setSelectedBufferRanges([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
editor2.setSelectedBufferRanges([[[8, 7], [6, 5]], [[4, 3], [2, 1]]])
expect(editor2.getSelectedBufferRanges()).not.toEqual editor.getSelectedBufferRanges()
editor2 = null
waitsForPromise ->
atom.project.open('sample.js').then (o) -> editor2 = o
runs ->
editor.setSelectedBufferRanges([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
editor2.setSelectedBufferRanges([[[8, 7], [6, 5]], [[4, 3], [2, 1]]])
expect(editor2.getSelectedBufferRanges()).not.toEqual editor.getSelectedBufferRanges()
describe "buffer manipulation", ->
describe ".insertText(text)", ->
@@ -2225,10 +2262,14 @@ describe "Editor", ->
it "does not explode if the current language mode has no comment regex", ->
editor.destroy()
editor = atom.project.openSync(null, autoIndent: false)
editor.setSelectedBufferRange([[4, 5], [4, 5]])
editor.toggleLineCommentsInSelection()
expect(buffer.lineForRow(4)).toBe " while(items.length > 0) {"
waitsForPromise ->
atom.workspace.open(null, autoIndent: false).then (o) -> editor = o
runs ->
editor.setSelectedBufferRange([[4, 5], [4, 5]])
editor.toggleLineCommentsInSelection()
expect(buffer.lineForRow(4)).toBe " while(items.length > 0) {"
it "uncomments when the line lacks the trailing whitespace in the comment regex", ->
editor.setCursorBufferPosition([10, 0])
@@ -2547,14 +2588,17 @@ describe "Editor", ->
describe "soft-tabs detection", ->
it "assigns soft / hard tabs based on the contents of the buffer, or uses the default if unknown", ->
editor = atom.project.openSync('sample.js', softTabs: false)
expect(editor.getSoftTabs()).toBeTruthy()
waitsForPromise ->
atom.workspace.open('sample.js', softTabs: false).then (editor) ->
expect(editor.getSoftTabs()).toBeTruthy()
editor = atom.project.openSync('sample-with-tabs.coffee', softTabs: true)
expect(editor.getSoftTabs()).toBeFalsy()
waitsForPromise ->
atom.workspace.open('sample-with-tabs.coffee', softTabs: true).then (editor) ->
expect(editor.getSoftTabs()).toBeFalsy()
editor = atom.project.openSync(null, softTabs: false)
expect(editor.getSoftTabs()).toBeFalsy()
waitsForPromise ->
atom.workspace.open(null, softTabs: false).then (editor) ->
expect(editor.getSoftTabs()).toBeFalsy()
describe ".indentLevelForLine(line)", ->
it "returns the indent level when the line has only leading whitespace", ->
@@ -2578,16 +2622,21 @@ describe "Editor", ->
describe "when a better-matched grammar is added to syntax", ->
it "switches to the better-matched grammar and re-tokenizes the buffer", ->
editor.destroy()
jsGrammar = atom.syntax.selectGrammar('a.js')
atom.syntax.removeGrammar(jsGrammar)
editor2 = atom.project.openSync('sample.js', autoIndent: false)
expect(editor2.getGrammar()).toBe atom.syntax.nullGrammar
expect(editor2.lineForScreenRow(0).tokens.length).toBe 1
waitsForPromise ->
atom.workspace.open('sample.js', autoIndent: false).then (o) -> editor = o
atom.syntax.addGrammar(jsGrammar)
expect(editor2.getGrammar()).toBe jsGrammar
expect(editor2.lineForScreenRow(0).tokens.length).toBeGreaterThan 1
runs ->
expect(editor.getGrammar()).toBe atom.syntax.nullGrammar
expect(editor.lineForScreenRow(0).tokens.length).toBe 1
atom.syntax.addGrammar(jsGrammar)
expect(editor.getGrammar()).toBe jsGrammar
expect(editor.lineForScreenRow(0).tokens.length).toBeGreaterThan 1
describe "auto-indent", ->
copyText = (text, {startColumn}={}) ->
@@ -2874,10 +2923,15 @@ describe "Editor", ->
expect(editor.shouldPromptToSave()).toBeFalsy()
buffer.setText('changed')
expect(editor.shouldPromptToSave()).toBeTruthy()
editor2 = atom.project.openSync('sample.js', autoIndent: false)
expect(editor.shouldPromptToSave()).toBeFalsy()
editor2.destroy()
expect(editor.shouldPromptToSave()).toBeTruthy()
editor2 = null
waitsForPromise ->
atom.project.open('sample.js', autoIndent: false).then (o) -> editor2 = o
runs ->
expect(editor.shouldPromptToSave()).toBeFalsy()
editor2.destroy()
expect(editor.shouldPromptToSave()).toBeTruthy()
describe "when the edit session contains surrogate pair characters", ->
it "correctly backspaces over them", ->
@@ -2973,12 +3027,15 @@ describe "Editor", ->
describe "when the grammar is added", ->
it "retokenizes existing buffers that contain tokens that match the injection selector", ->
editor = atom.project.openSync('sample.js')
editor.setText("// http://github.com")
waitsForPromise ->
atom.workspace.open('sample.js').then (o) -> editor = o
{tokens} = editor.lineForScreenRow(0)
expect(tokens[1].value).toBe " http://github.com"
expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"]
runs ->
editor.setText("// http://github.com")
{tokens} = editor.lineForScreenRow(0)
expect(tokens[1].value).toBe " http://github.com"
expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"]
waitsForPromise ->
atom.packages.activatePackage('language-hyperlink')
@@ -2990,12 +3047,15 @@ describe "Editor", ->
describe "when the grammar is updated", ->
it "retokenizes existing buffers that contain tokens that match the injection selector", ->
editor = atom.project.openSync('sample.js')
editor.setText("// SELECT * FROM OCTOCATS")
waitsForPromise ->
atom.workspace.open('sample.js').then (o) -> editor = o
{tokens} = editor.lineForScreenRow(0)
expect(tokens[1].value).toBe " SELECT * FROM OCTOCATS"
expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"]
runs ->
editor.setText("// SELECT * FROM OCTOCATS")
{tokens} = editor.lineForScreenRow(0)
expect(tokens[1].value).toBe " SELECT * FROM OCTOCATS"
expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"]
waitsForPromise ->
atom.packages.activatePackage('package-with-injection-selector')
@@ -3036,6 +3096,7 @@ describe "Editor", ->
editor.setDefaultCharWidth(10)
editor.setHeight(50)
editor.setWidth(50)
editor.setHorizontalScrollbarHeight(0)
expect(editor.getScrollTop()).toBe 0
expect(editor.getScrollLeft()).toBe 0
+174 -94
Ver Arquivo
@@ -7,22 +7,30 @@ path = require 'path'
temp = require 'temp'
describe "EditorView", ->
[buffer, editorView, editor, cachedLineHeight, cachedCharWidth] = []
[buffer, editorView, editor, cachedEditor, cachedLineHeight, cachedCharWidth, fart] = []
beforeEach ->
editor = atom.project.openSync('sample.js')
buffer = editor.buffer
editorView = new EditorView(editor)
editorView.lineOverdraw = 2
editorView.isFocused = true
editorView.enableKeymap()
editorView.calculateHeightInLines = ->
Math.ceil(@height() / @lineHeight)
editorView.attachToDom = ({ heightInLines, widthInChars } = {}) ->
heightInLines ?= @getEditor().getBuffer().getLineCount()
@height(getLineHeight() * heightInLines)
@width(getCharWidth() * widthInChars) if widthInChars
$('#jasmine-content').append(this)
waitsForPromise ->
atom.workspace.open('sample.js').then (o) -> editor = o
waitsForPromise ->
atom.workspace.open('sample.less').then (o) -> cachedEditor = o
runs ->
buffer = editor.buffer
editorView = new EditorView(editor)
editorView.lineOverdraw = 2
editorView.isFocused = true
editorView.enableKeymap()
editorView.calculateHeightInLines = ->
Math.ceil(@height() / @lineHeight)
editorView.attachToDom = ({ heightInLines, widthInChars } = {}) ->
heightInLines ?= @getEditor().getBuffer().getLineCount()
@height(getLineHeight() * heightInLines)
@width(getCharWidth() * widthInChars) if widthInChars
$('#jasmine-content').append(this)
waitsForPromise ->
atom.packages.activatePackage('language-text', sync: true)
@@ -41,7 +49,7 @@ describe "EditorView", ->
cachedCharWidth
calcDimensions = ->
editorForMeasurement = new EditorView(editor: atom.project.openSync('sample.js'))
editorForMeasurement = new EditorView({editor: cachedEditor})
editorForMeasurement.attachToDom()
cachedLineHeight = editorForMeasurement.lineHeight
cachedCharWidth = editorForMeasurement.charWidth
@@ -105,18 +113,23 @@ describe "EditorView", ->
describe "when the editor's file is modified on disk", ->
it "triggers an alert", ->
fileChangeHandler = null
filePath = path.join(temp.dir, 'atom-changed-file.txt')
fs.writeFileSync(filePath, "")
editor = atom.project.openSync(filePath)
editorView.edit(editor)
editor.insertText("now the buffer is modified")
fileChangeHandler = jasmine.createSpy('fileChange')
editor.buffer.file.on 'contents-changed', fileChangeHandler
waitsForPromise ->
atom.workspace.open(filePath).then (o) -> editor = o
spyOn(atom, "confirm")
runs ->
editorView.edit(editor)
editor.insertText("now the buffer is modified")
fs.writeFileSync(filePath, "a file change")
fileChangeHandler = jasmine.createSpy('fileChange')
editor.buffer.file.on 'contents-changed', fileChangeHandler
spyOn(atom, "confirm")
fs.writeFileSync(filePath, "a file change")
waitsFor "file to trigger contents-changed event", ->
fileChangeHandler.callCount > 0
@@ -133,8 +146,11 @@ describe "EditorView", ->
[newEditor, newBuffer] = []
beforeEach ->
newEditor = atom.project.openSync('two-hundred.txt')
newBuffer = newEditor.buffer
waitsForPromise ->
atom.workspace.open('two-hundred.txt').then (o) -> newEditor = o
runs ->
newBuffer = newEditor.buffer
it "updates the rendered lines, cursors, selections, scroll position, and event subscriptions to match the given edit session", ->
editorView.attachToDom(heightInLines: 5, widthInChars: 30)
@@ -170,17 +186,24 @@ describe "EditorView", ->
expect(editorView.lineElementForScreenRow(6).text()).toMatch /^ currentgoodbye/
it "triggers alert if edit session's buffer goes into conflict with changes on disk", ->
contentsConflictedHandler = null
filePath = path.join(temp.dir, 'atom-changed-file.txt')
fs.writeFileSync(filePath, "")
tempEditor = atom.project.openSync(filePath)
editorView.edit(tempEditor)
tempEditor.insertText("a buffer change")
tempEditor = null
spyOn(atom, "confirm")
waitsForPromise ->
atom.workspace.open(filePath).then (o) -> tempEditor = o
runs ->
editorView.edit(tempEditor)
tempEditor.insertText("a buffer change")
spyOn(atom, "confirm")
contentsConflictedHandler = jasmine.createSpy("contentsConflictedHandler")
tempEditor.on 'contents-conflicted', contentsConflictedHandler
fs.writeFileSync(filePath, "a file change")
contentsConflictedHandler = jasmine.createSpy("contentsConflictedHandler")
tempEditor.on 'contents-conflicted', contentsConflictedHandler
fs.writeFileSync(filePath, "a file change")
waitsFor ->
contentsConflictedHandler.callCount > 0
@@ -281,26 +304,34 @@ describe "EditorView", ->
it "emits event when editor view view receives a new buffer", ->
eventHandler = jasmine.createSpy('eventHandler')
editorView.on 'editor:path-changed', eventHandler
editorView.edit(atom.project.openSync(filePath))
expect(eventHandler).toHaveBeenCalled()
waitsForPromise ->
atom.workspace.open(filePath).then (editor) ->
editorView.edit(editor)
runs ->
expect(eventHandler).toHaveBeenCalled()
it "stops listening to events on previously set buffers", ->
eventHandler = jasmine.createSpy('eventHandler')
oldBuffer = editor.getBuffer()
newEditor = atom.project.openSync(filePath)
editorView.on 'editor:path-changed', eventHandler
newEditor = null
waitsForPromise ->
atom.workspace.open(filePath).then (o) -> newEditor = o
editorView.edit(newEditor)
expect(eventHandler).toHaveBeenCalled()
runs ->
editorView.on 'editor:path-changed', eventHandler
eventHandler.reset()
oldBuffer.saveAs(path.join(temp.dir, 'atom-bad.txt'))
expect(eventHandler).not.toHaveBeenCalled()
editorView.edit(newEditor)
expect(eventHandler).toHaveBeenCalled()
eventHandler.reset()
newEditor.getBuffer().saveAs(path.join(temp.dir, 'atom-new.txt'))
expect(eventHandler).toHaveBeenCalled()
eventHandler.reset()
oldBuffer.saveAs(path.join(temp.dir, 'atom-bad.txt'))
expect(eventHandler).not.toHaveBeenCalled()
eventHandler.reset()
newEditor.getBuffer().saveAs(path.join(temp.dir, 'atom-new.txt'))
expect(eventHandler).toHaveBeenCalled()
it "loads the grammar for the new path", ->
expect(editor.getGrammar().name).toBe 'JavaScript'
@@ -478,7 +509,7 @@ describe "EditorView", ->
expect(editor.getSelectedBufferRange()).toEqual [[3, 10], [3, 12]]
describe "when clicking between a word and a non-word", ->
describe "when double-clicking between a word and a non-word", ->
it "selects the word", ->
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
editorView.renderedLines.trigger mousedownEvent(editorView: editorView, point: [1, 21], originalEvent: {detail: 1})
@@ -501,6 +532,30 @@ describe "EditorView", ->
editorView.renderedLines.trigger 'mouseup'
expect(editor.getSelectedText()).toBe "{"
describe "when double-clicking on whitespace", ->
it "selects all adjacent whitespace", ->
editor.setText(" some text ")
editor.setCursorBufferPosition([0, 2])
editorView.renderedLines.trigger mousedownEvent(editorView: editorView, point: [0, 2], originalEvent: {detail: 1})
editorView.renderedLines.trigger 'mouseup'
editorView.renderedLines.trigger mousedownEvent(editorView: editorView, point: [0, 2], originalEvent: {detail: 2})
editorView.renderedLines.trigger 'mouseup'
expect(editor.getSelectedBufferRange()).toEqual [[0, 0], [0, 3]]
editor.setCursorBufferPosition([0, 8])
editorView.renderedLines.trigger mousedownEvent(editorView: editorView, point: [0, 8], originalEvent: {detail: 1})
editorView.renderedLines.trigger 'mouseup'
editorView.renderedLines.trigger mousedownEvent(editorView: editorView, point: [0, 8], originalEvent: {detail: 2})
editorView.renderedLines.trigger 'mouseup'
expect(editor.getSelectedBufferRange()).toEqual [[0, 7], [0, 9]]
editor.setCursorBufferPosition([0, 14])
editorView.renderedLines.trigger mousedownEvent(editorView: editorView, point: [0, 14], originalEvent: {detail: 1})
editorView.renderedLines.trigger 'mouseup'
editorView.renderedLines.trigger mousedownEvent(editorView: editorView, point: [0, 14], originalEvent: {detail: 2})
editorView.renderedLines.trigger 'mouseup'
expect(editor.getSelectedBufferRange()).toEqual [[0, 13], [0, 17]]
describe "triple/quardruple/etc-click", ->
it "selects the line under the cursor", ->
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
@@ -1529,14 +1584,18 @@ describe "EditorView", ->
describe "when autoscrolling at the end of the document", ->
it "renders lines properly", ->
editorView.edit(atom.project.openSync('two-hundred.txt'))
editorView.attachToDom(heightInLines: 5.5)
waitsForPromise ->
atom.workspace.open('two-hundred.txt').then (editor) ->
editorView.edit(editor)
expect(editorView.renderedLines.find('.line').length).toBe 8
runs ->
editorView.attachToDom(heightInLines: 5.5)
editor.moveCursorToBottom()
expect(editorView.renderedLines.find('.line').length).toBe 8
expect(editorView.renderedLines.find('.line').length).toBe 8
editor.moveCursorToBottom()
expect(editorView.renderedLines.find('.line').length).toBe 8
describe "when line has a character that could push it to be too tall (regression)", ->
it "does renders the line at a consistent height", ->
@@ -1784,10 +1843,14 @@ describe "EditorView", ->
expect(editor.bufferPositionForScreenPosition(editor.getCursorScreenPosition())).toEqual [3, 60]
it "does not wrap the lines of any newly assigned buffers", ->
otherEditor = atom.project.openSync()
otherEditor.buffer.setText([1..100].join(''))
editorView.edit(otherEditor)
expect(editorView.renderedLines.find('.line').length).toBe(1)
otherEditor = null
waitsForPromise ->
atom.workspace.open().then (o) -> otherEditor = o
runs ->
otherEditor.buffer.setText([1..100].join(''))
editorView.edit(otherEditor)
expect(editorView.renderedLines.find('.line').length).toBe(1)
it "unwraps lines when softwrap is disabled", ->
editorView.toggleSoftWrap()
@@ -1816,15 +1879,15 @@ describe "EditorView", ->
expect(editor.getCursorScreenPosition()).toEqual [11, 0]
it "calls .setWidthInChars() when the editor view is attached because now its dimensions are available to calculate it", ->
otherEditor = new EditorView(editor: atom.project.openSync('sample.js'))
spyOn(otherEditor, 'setWidthInChars')
otherEditorView = new EditorView(editor)
spyOn(otherEditorView, 'setWidthInChars')
otherEditor.editor.setSoftWrap(true)
expect(otherEditor.setWidthInChars).not.toHaveBeenCalled()
otherEditorView.editor.setSoftWrap(true)
expect(otherEditorView.setWidthInChars).not.toHaveBeenCalled()
otherEditor.simulateDomAttachment()
expect(otherEditor.setWidthInChars).toHaveBeenCalled()
otherEditor.remove()
otherEditorView.simulateDomAttachment()
expect(otherEditorView.setWidthInChars).toHaveBeenCalled()
otherEditorView.remove()
describe "when the editor view's width changes", ->
it "updates the width in characters on the edit session", ->
@@ -1975,15 +2038,19 @@ describe "EditorView", ->
describe "when the switching from an edit session for a long buffer to an edit session for a short buffer", ->
it "updates the line numbers to reflect the shorter buffer", ->
emptyEditor = atom.project.openSync(null)
editorView.edit(emptyEditor)
expect(editorView.gutter.lineNumbers.find('.line-number').length).toBe 1
emptyEditor = null
waitsForPromise ->
atom.workspace.open().then (o) -> emptyEditor = o
editorView.edit(editor)
expect(editorView.gutter.lineNumbers.find('.line-number').length).toBeGreaterThan 1
runs ->
editorView.edit(emptyEditor)
expect(editorView.gutter.lineNumbers.find('.line-number').length).toBe 1
editorView.edit(emptyEditor)
expect(editorView.gutter.lineNumbers.find('.line-number').length).toBe 1
editorView.edit(editor)
expect(editorView.gutter.lineNumbers.find('.line-number').length).toBeGreaterThan 1
editorView.edit(emptyEditor)
expect(editorView.gutter.lineNumbers.find('.line-number').length).toBe 1
describe "when the editor view is mini", ->
it "hides the gutter", ->
@@ -2203,10 +2270,13 @@ describe "EditorView", ->
describe "folding", ->
beforeEach ->
editor = atom.project.openSync('two-hundred.txt')
buffer = editor.buffer
editorView.edit(editor)
editorView.attachToDom()
waitsForPromise ->
atom.workspace.open('two-hundred.txt').then (o) -> editor = o
runs ->
buffer = editor.buffer
editorView.edit(editor)
editorView.attachToDom()
describe "when a fold-selection event is triggered", ->
it "folds the lines covered by the selection into a single line with a fold class and marker", ->
@@ -2260,7 +2330,7 @@ describe "EditorView", ->
it "adds/removes the 'fold-selected' class to the fold's line element and hides the cursor if it is on the fold line", ->
editor.createFold(2, 4)
editor.setSelectedBufferRange([[1, 0], [2, 0]], preserveFolds: true, isReversed: true)
editor.setSelectedBufferRange([[1, 0], [2, 0]], preserveFolds: true, reversed: true)
expect(editorView.lineElementForScreenRow(2)).toMatchSelector('.fold.fold-selected')
editor.setSelectedBufferRange([[1, 0], [1, 1]], preserveFolds: true)
@@ -2341,8 +2411,11 @@ describe "EditorView", ->
beforeEach ->
filePath = atom.project.resolve('git/working-dir/file.txt')
originalPathText = fs.readFileSync(filePath, 'utf8')
editor = atom.project.openSync(filePath)
editorView.edit(editor)
waitsForPromise ->
atom.workspace.open(filePath).then (o) -> editor = o
runs ->
editorView.edit(editor)
afterEach ->
fs.writeFileSync(filePath, originalPathText)
@@ -2816,7 +2889,7 @@ describe "EditorView", ->
describe "when the escape key is pressed on the editor view", ->
it "clears multiple selections if there are any, and otherwise allows other bindings to be handled", ->
atom.keymaps.bindKeys 'name', '.editor', {'escape': 'test-event'}
atom.keymaps.add 'name', '.editor': {'escape': 'test-event'}
testEventHandler = jasmine.createSpy("testEventHandler")
editorView.on 'test-event', testEventHandler
@@ -2833,22 +2906,26 @@ describe "EditorView", ->
describe "when the editor view is attached but invisible", ->
describe "when the editor view's text is changed", ->
it "redraws the editor view when it is next shown", ->
displayUpdatedHandler = null
atom.workspaceView = new WorkspaceView
atom.workspaceView.openSync('sample.js')
atom.workspaceView.attachToDom()
editorView = atom.workspaceView.getActiveView()
waitsForPromise ->
atom.workspaceView.open('sample.txt').then (o) -> editor = o
view = $$ -> @div id: 'view', tabindex: -1, 'View'
editorView.getPane().activateItem(view)
expect(editorView.isVisible()).toBeFalsy()
runs ->
atom.workspaceView.attachToDom()
editorView = atom.workspaceView.getActiveView()
editor.setText('hidden changes')
editor.setCursorBufferPosition([0,4])
view = $$ -> @div id: 'view', tabindex: -1, 'View'
editorView.getPane().activateItem(view)
expect(editorView.isVisible()).toBeFalsy()
displayUpdatedHandler = jasmine.createSpy("displayUpdatedHandler")
editorView.on 'editor:display-updated', displayUpdatedHandler
editorView.getPane().activateItem(editorView.getModel())
expect(editorView.isVisible()).toBeTruthy()
editor.setText('hidden changes')
editor.setCursorBufferPosition([0,4])
displayUpdatedHandler = jasmine.createSpy("displayUpdatedHandler")
editorView.on 'editor:display-updated', displayUpdatedHandler
editorView.getPane().activateItem(editorView.getModel())
expect(editorView.isVisible()).toBeTruthy()
waitsFor ->
displayUpdatedHandler.callCount is 1
@@ -2888,14 +2965,17 @@ describe "EditorView", ->
describe "when the editor view is removed", ->
it "fires a editor:will-be-removed event", ->
atom.workspaceView = new WorkspaceView
atom.workspaceView.openSync('sample.js')
atom.workspaceView.attachToDom()
editorView = atom.workspaceView.getActiveView()
waitsForPromise ->
atom.workspace.open('sample.js')
willBeRemovedHandler = jasmine.createSpy('willBeRemovedHandler')
editorView.on 'editor:will-be-removed', willBeRemovedHandler
editorView.getPane().destroyActiveItem()
expect(willBeRemovedHandler).toHaveBeenCalled()
runs ->
atom.workspaceView.attachToDom()
editorView = atom.workspaceView.getActiveView()
willBeRemovedHandler = jasmine.createSpy('willBeRemovedHandler')
editorView.on 'editor:will-be-removed', willBeRemovedHandler
editorView.getPane().destroyActiveItem()
expect(willBeRemovedHandler).toHaveBeenCalled()
describe "when setInvisibles is toggled (regression)", ->
it "renders inserted newlines properly", ->
+11 -5
Ver Arquivo
@@ -229,8 +229,11 @@ describe "Git", ->
[originalContent, editor] = []
beforeEach ->
editor = atom.project.openSync('sample.js')
originalContent = editor.getText()
waitsForPromise ->
atom.workspace.open('sample.js').then (o) -> editor = o
runs ->
originalContent = editor.getText()
afterEach ->
fs.writeFileSync(editor.getPath(), originalContent)
@@ -274,9 +277,12 @@ describe "Git", ->
project2?.destroy()
it "subscribes to all the serialized buffers in the project", ->
atom.project.openSync('sample.js')
project2 = atom.project.testSerialization()
buffer = project2.getBuffers()[0]
waitsForPromise ->
atom.workspace.open('sample.js')
runs ->
project2 = atom.project.testSerialization()
buffer = project2.getBuffers()[0]
waitsFor ->
buffer.loaded
+35 -18
Ver Arquivo
@@ -6,8 +6,10 @@ describe "LanguageMode", ->
describe "javascript", ->
beforeEach ->
editor = atom.project.openSync('sample.js', autoIndent: false)
{buffer, languageMode} = editor
waitsForPromise ->
atom.workspace.open('sample.js', autoIndent: false).then (o) ->
editor = o
{buffer, languageMode} = editor
waitsForPromise ->
atom.packages.activatePackage('language-javascript')
@@ -112,8 +114,10 @@ describe "LanguageMode", ->
describe "coffeescript", ->
beforeEach ->
editor = atom.project.openSync('coffee.coffee', autoIndent: false)
{buffer, languageMode} = editor
waitsForPromise ->
atom.workspace.open('coffee.coffee', autoIndent: false).then (o) ->
editor = o
{buffer, languageMode} = editor
waitsForPromise ->
atom.packages.activatePackage('language-coffee-script')
@@ -161,8 +165,10 @@ describe "LanguageMode", ->
describe "css", ->
beforeEach ->
editor = atom.project.openSync('css.css', autoIndent: false)
{buffer, languageMode} = editor
waitsForPromise ->
atom.workspace.open('css.css', autoIndent: false).then (o) ->
editor = o
{buffer, languageMode} = editor
waitsForPromise ->
atom.packages.activatePackage('language-css')
@@ -178,13 +184,13 @@ describe "LanguageMode", ->
languageMode.toggleLineCommentsForBufferRows(2, 2)
expect(buffer.lineForRow(0)).toBe "/*body {"
expect(buffer.lineForRow(1)).toBe " font-size: 1234px;*/"
expect(buffer.lineForRow(2)).toBe "/* width: 110%;*/"
expect(buffer.lineForRow(2)).toBe " /*width: 110%;*/"
expect(buffer.lineForRow(3)).toBe " font-weight: bold !important;"
languageMode.toggleLineCommentsForBufferRows(0, 1)
expect(buffer.lineForRow(0)).toBe "body {"
expect(buffer.lineForRow(1)).toBe " font-size: 1234px;"
expect(buffer.lineForRow(2)).toBe "/* width: 110%;*/"
expect(buffer.lineForRow(2)).toBe " /*width: 110%;*/"
expect(buffer.lineForRow(3)).toBe " font-weight: bold !important;"
it "uncomments lines with leading whitespace", ->
@@ -204,8 +210,10 @@ describe "LanguageMode", ->
describe "less", ->
beforeEach ->
editor = atom.project.openSync('sample.less', autoIndent: false)
{buffer, languageMode} = editor
waitsForPromise ->
atom.workspace.open('sample.less', autoIndent: false).then (o) ->
editor = o
{buffer, languageMode} = editor
waitsForPromise ->
atom.packages.activatePackage('language-less')
@@ -220,9 +228,11 @@ describe "LanguageMode", ->
describe "xml", ->
beforeEach ->
editor = atom.project.openSync('sample.xml', autoIndent: false)
editor.setText("<!-- test -->")
{buffer, languageMode} = editor
waitsForPromise ->
atom.workspace.open('sample.xml', autoIndent: false).then (o) ->
editor = o
editor.setText("<!-- test -->")
{buffer, languageMode} = editor
waitsForPromise ->
atom.packages.activatePackage('language-xml')
@@ -234,8 +244,10 @@ describe "LanguageMode", ->
describe "folding", ->
beforeEach ->
editor = atom.project.openSync('sample.js', autoIndent: false)
{buffer, languageMode} = editor
waitsForPromise ->
atom.workspace.open('sample.js', autoIndent: false).then (o) ->
editor = o
{buffer, languageMode} = editor
waitsForPromise ->
atom.packages.activatePackage('language-javascript')
@@ -319,8 +331,10 @@ describe "LanguageMode", ->
describe "folding with comments", ->
beforeEach ->
editor = atom.project.openSync('sample-with-comments.js', autoIndent: false)
{buffer, languageMode} = editor
waitsForPromise ->
atom.workspace.open('sample-with-comments.js', autoIndent: false).then (o) ->
editor = o
{buffer, languageMode} = editor
waitsForPromise ->
atom.packages.activatePackage('language-javascript')
@@ -385,7 +399,10 @@ describe "LanguageMode", ->
describe "css", ->
beforeEach ->
editor = atom.project.openSync('css.css', autoIndent: true)
waitsForPromise ->
atom.workspace.open('css.css', autoIndent: true).then (o) ->
editor = o
{buffer, languageMode} = editor
waitsForPromise ->
atom.packages.activatePackage('language-source')
+21 -10
Ver Arquivo
@@ -21,11 +21,16 @@ describe "PaneView", ->
container = new PaneContainerView
view1 = new TestView(id: 'view-1', text: 'View 1')
view2 = new TestView(id: 'view-2', text: 'View 2')
editor1 = atom.project.openSync('sample.js')
editor2 = atom.project.openSync('sample.txt')
pane = container.getRoot()
paneModel = pane.model
paneModel.addItems([view1, editor1, view2, editor2])
waitsForPromise ->
atom.workspace.open('sample.js').then (o) -> editor1 = o
waitsForPromise ->
atom.workspace.open('sample.txt').then (o) -> editor2 = o
runs ->
pane = container.getRoot()
paneModel = pane.model
paneModel.addItems([view1, editor1, view2, editor2])
afterEach ->
atom.deserializers.remove(TestView)
@@ -159,14 +164,20 @@ describe "PaneView", ->
describe "when an unmodifed buffer's path is deleted", ->
it "removes the pane item", ->
editor = null
jasmine.unspy(window, 'setTimeout')
filePath = temp.openSync('atom').path
editor = atom.project.openSync(filePath)
pane.activateItem(editor)
expect(pane.items).toHaveLength(5)
fs.removeSync(filePath)
waitsFor -> pane.items.length == 4
waitsForPromise ->
atom.workspace.open(filePath).then (o) -> editor = o
runs ->
pane.activateItem(editor)
expect(pane.items).toHaveLength(5)
fs.removeSync(filePath)
waitsFor ->
pane.items.length == 4
describe "when a pane is destroyed", ->
[pane2, pane2Model] = []
+67 -75
Ver Arquivo
@@ -18,62 +18,39 @@ describe "Project", ->
deserializedProject?.destroy()
it "does not include unretained buffers in the serialized state", ->
atom.project.bufferForPathSync('a')
expect(atom.project.getBuffers().length).toBe 1
waitsForPromise ->
atom.project.bufferForPath('a')
deserializedProject = atom.project.testSerialization()
expect(deserializedProject.getBuffers().length).toBe 0
runs ->
expect(atom.project.getBuffers().length).toBe 1
deserializedProject = atom.project.testSerialization()
expect(deserializedProject.getBuffers().length).toBe 0
it "listens for destroyed events on deserialized buffers and removes them when they are destroyed", ->
atom.project.openSync('a')
expect(atom.project.getBuffers().length).toBe 1
deserializedProject = atom.project.testSerialization()
waitsForPromise ->
atom.project.open('a')
expect(deserializedProject.getBuffers().length).toBe 1
deserializedProject.getBuffers()[0].destroy()
expect(deserializedProject.getBuffers().length).toBe 0
runs ->
expect(atom.project.getBuffers().length).toBe 1
deserializedProject = atom.project.testSerialization()
expect(deserializedProject.getBuffers().length).toBe 1
deserializedProject.getBuffers()[0].destroy()
expect(deserializedProject.getBuffers().length).toBe 0
describe "when an editor is saved and the project has no path", ->
it "sets the project's path to the saved file's parent directory", ->
tempFile = temp.openSync().path
atom.project.setPath(undefined)
expect(atom.project.getPath()).toBeUndefined()
editor = atom.project.openSync()
editor.saveAs(tempFile)
expect(atom.project.getPath()).toBe path.dirname(tempFile)
editor = null
describe ".openSync(path)", ->
[absolutePath, newBufferHandler] = []
beforeEach ->
absolutePath = require.resolve('./fixtures/dir/a')
newBufferHandler = jasmine.createSpy('newBufferHandler')
atom.project.on 'buffer-created', newBufferHandler
waitsForPromise ->
atom.project.open().then (o) -> editor = o
describe "when given an absolute path that hasn't been opened previously", ->
it "returns a new edit session for the given path and emits 'buffer-created'", ->
editor = atom.project.openSync(absolutePath)
expect(editor.buffer.getPath()).toBe absolutePath
expect(newBufferHandler).toHaveBeenCalledWith editor.buffer
describe "when given a relative path that hasn't been opened previously", ->
it "returns a new edit session for the given path (relative to the project root) and emits 'buffer-created'", ->
editor = atom.project.openSync('a')
expect(editor.buffer.getPath()).toBe absolutePath
expect(newBufferHandler).toHaveBeenCalledWith editor.buffer
describe "when passed the path to a buffer that has already been opened", ->
it "returns a new edit session containing previously opened buffer", ->
editor = atom.project.openSync(absolutePath)
newBufferHandler.reset()
expect(atom.project.openSync(absolutePath).buffer).toBe editor.buffer
expect(atom.project.openSync('a').buffer).toBe editor.buffer
expect(newBufferHandler).not.toHaveBeenCalled()
describe "when not passed a path", ->
it "returns a new edit session and emits 'buffer-created'", ->
editor = atom.project.openSync()
expect(editor.buffer.getPath()).toBeUndefined()
expect(newBufferHandler).toHaveBeenCalledWith(editor.buffer)
runs ->
editor.saveAs(tempFile)
expect(atom.project.getPath()).toBe path.dirname(tempFile)
describe ".open(path)", ->
[absolutePath, newBufferHandler] = []
@@ -106,14 +83,21 @@ describe "Project", ->
describe "when passed the path to a buffer that is currently opened", ->
it "returns a new edit session containing currently opened buffer", ->
editor = null
waitsForPromise ->
atom.project.open(absolutePath).then (o) -> editor = o
runs ->
newBufferHandler.reset()
expect(atom.project.openSync(absolutePath).buffer).toBe editor.buffer
expect(atom.project.openSync('a').buffer).toBe editor.buffer
expect(newBufferHandler).not.toHaveBeenCalled()
waitsForPromise ->
atom.project.open(absolutePath).then ({buffer}) ->
expect(buffer).toBe editor.buffer
waitsForPromise ->
atom.project.open('a').then ({buffer}) ->
expect(buffer).toBe editor.buffer
expect(newBufferHandler).not.toHaveBeenCalled()
describe "when not passed a path", ->
it "returns a new edit session and emits 'buffer-created'", ->
@@ -137,20 +121,6 @@ describe "Project", ->
runs ->
expect(totalBytes).toBe fs.statSync(filePath).size
describe ".bufferForPathSync(path)", ->
describe "when opening a previously opened path", ->
it "does not create a new buffer", ->
buffer = atom.project.bufferForPathSync("a").retain()
expect(atom.project.bufferForPathSync("a")).toBe buffer
alternativeBuffer = atom.project.bufferForPathSync("b").retain().release()
expect(alternativeBuffer).not.toBe buffer
buffer.release()
it "creates a new buffer if the previous buffer was destroyed", ->
buffer = atom.project.bufferForPathSync("a").retain().release()
expect(atom.project.bufferForPathSync("a").retain().release()).not.toBe buffer
describe ".bufferForPath(path)", ->
[buffer] = []
beforeEach ->
@@ -240,10 +210,15 @@ describe "Project", ->
describe "when a buffer is already open", ->
it "replaces properly and saves when not modified", ->
editor = atom.project.openSync('sample.js')
expect(editor.isModified()).toBeFalsy()
editor = null
results = []
waitsForPromise ->
atom.project.open('sample.js').then (o) -> editor = o
runs ->
expect(editor.isModified()).toBeFalsy()
waitsForPromise ->
atom.project.replace /items/gi, 'items', [filePath], (result) ->
results.push(result)
@@ -256,10 +231,12 @@ describe "Project", ->
expect(editor.isModified()).toBeFalsy()
it "does not replace when the path is not specified", ->
editor = atom.project.openSync('sample.js')
editor = atom.project.openSync('sample-with-comments.js')
editor = null
results = []
waitsForPromise ->
atom.project.open('sample-with-comments.js').then (o) -> editor = o
waitsForPromise ->
atom.project.replace /items/gi, 'items', [commentFilePath], (result) ->
results.push(result)
@@ -269,11 +246,16 @@ describe "Project", ->
expect(results[0].filePath).toBe commentFilePath
it "does NOT save when modified", ->
editor = atom.project.openSync('sample.js')
editor.buffer.setTextInRange([[0,0],[0,0]], 'omg')
expect(editor.isModified()).toBeTruthy()
editor = null
results = []
waitsForPromise ->
atom.project.open('sample.js').then (o) -> editor = o
runs ->
editor.buffer.setTextInRange([[0,0],[0,0]], 'omg')
expect(editor.isModified()).toBeTruthy()
waitsForPromise ->
atom.project.replace /items/gi, 'okthen', [filePath], (result) ->
results.push(result)
@@ -437,9 +419,14 @@ describe "Project", ->
expect(resultHandler).not.toHaveBeenCalled()
it "scans buffer contents if the buffer is modified", ->
editor = atom.project.openSync("a")
editor.setText("Elephant")
editor = null
results = []
waitsForPromise ->
atom.project.open('a').then (o) ->
editor = o
editor.setText("Elephant")
waitsForPromise ->
atom.project.scan /a|Elephant/, (result) -> results.push result
@@ -450,9 +437,14 @@ describe "Project", ->
expect(resultForA.matches[0].matchText).toBe 'Elephant'
it "ignores buffers outside the project", ->
editor = atom.project.openSync(temp.openSync().path)
editor.setText("Elephant")
editor = null
results = []
waitsForPromise ->
atom.project.open(temp.openSync().path).then (o) ->
editor = o
editor.setText("Elephant")
waitsForPromise ->
atom.project.scan /Elephant/, (result) -> results.push result
+1 -1
Ver Arquivo
@@ -58,7 +58,7 @@ describe "Selection", ->
describe "when only the selection's tail is moved (regression)", ->
it "emits the 'screen-range-changed' event", ->
selection.setBufferRange([[2, 0], [2, 10]], isReversed: true)
selection.setBufferRange([[2, 0], [2, 10]], reversed: true)
changeScreenRangeHandler = jasmine.createSpy('changeScreenRangeHandler')
selection.on 'screen-range-changed', changeScreenRangeHandler
+32 -1
Ver Arquivo
@@ -6,6 +6,7 @@ require '../vendor/jasmine-jquery'
path = require 'path'
_ = require 'underscore-plus'
fs = require 'fs-plus'
Grim = require 'grim'
KeymapManager = require '../src/keymap-extensions'
{$, WorkspaceView, Workspace} = require 'atom'
Config = require '../src/config'
@@ -37,6 +38,7 @@ jasmine.getEnv().defaultTimeoutInterval = 5000
specPackageName = null
specPackagePath = null
specProjectPath = null
isCoreSpec = false
{specDirectory, resourcePath} = atom.getLoadSettings()
@@ -46,7 +48,10 @@ if specDirectory
specPackageName = JSON.parse(fs.readFileSync(path.join(specPackagePath, 'package.json')))?.name
specProjectPath = path.join(specDirectory, 'fixtures')
isCoreSpec = specDirectory == fs.realpathSync(__dirname)
beforeEach ->
Grim.clearDeprecations() if isCoreSpec
$.fx.off = true
projectPath = specProjectPath ? path.join(@specDirectory, 'fixtures')
atom.project = new Project(path: projectPath)
@@ -124,6 +129,7 @@ afterEach ->
jasmine.unspy(atom, 'saveSync')
ensureNoPathSubscriptions()
atom.syntax.off()
ensureNoDeprecatedFunctionsCalled() if isCoreSpec
waits(0) # yield to ui thread to make screen update more frequently
ensureNoPathSubscriptions = ->
@@ -132,6 +138,27 @@ ensureNoPathSubscriptions = ->
if watchedPaths.length > 0
throw new Error("Leaking subscriptions for paths: " + watchedPaths.join(", "))
ensureNoDeprecatedFunctionsCalled = ->
deprecations = Grim.getDeprecations()
if deprecations.length > 0
originalPrepareStackTrace = Error.prepareStackTrace
Error.prepareStackTrace = (error, stack) ->
output = []
for deprecation in deprecations
output.push "#{deprecation.originName} is deprecated. #{deprecation.message}"
output.push _.multiplyString("-", output[output.length - 1].length)
for stack in deprecation.getStacks()
for {functionName, location} in stack
output.push "#{functionName} -- #{location}"
output.push ""
output.join("\n")
error = new Error("Deprecated function(s) #{deprecations.map(({originName}) -> originName).join ', '}) were called.")
error.stack
Error.prepareStackTrace = originalPrepareStackTrace
throw error
emitObject = jasmine.StringPrettyPrinter.prototype.emitObject
jasmine.StringPrettyPrinter.prototype.emitObject = (obj) ->
if obj.inspect
@@ -289,7 +316,11 @@ $.fn.resultOfTrigger = (type) ->
event.result
$.fn.enableKeymap = ->
@on 'keydown', (e) => atom.keymaps.handleKeyEvent(e)
@on 'keydown', (e) ->
originalEvent = e.originalEvent ? e
Object.defineProperty(originalEvent, 'target', get: -> e.target) unless originalEvent.target?
atom.keymaps.handleKeyboardEvent(originalEvent)
not e.originalEvent.defaultPrevented
$.fn.attachToDom = ->
@appendTo($('#jasmine-content'))
+32 -5
Ver Arquivo
@@ -131,15 +131,21 @@ describe "ThemeManager", ->
describe "requireStylesheet(path)", ->
it "synchronously loads css at the given path and installs a style tag for it in the head", ->
themeManager.on 'stylesheets-changed', stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
themeManager.on 'stylesheet-added', stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
cssPath = atom.project.resolve('css.css')
lengthBefore = $('head style').length
themeManager.requireStylesheet(cssPath)
expect($('head style').length).toBe lengthBefore + 1
expect(stylesheetAddedHandler).toHaveBeenCalled()
expect(stylesheetsChangedHandler).toHaveBeenCalled()
element = $('head style[id*="css.css"]')
expect(element.attr('id')).toBe themeManager.stringToId(cssPath)
expect(element.text()).toBe fs.readFileSync(cssPath, 'utf8')
expect(element[0].sheet).toBe stylesheetAddedHandler.argsForCall[0][0]
# doesn't append twice
themeManager.requireStylesheet(cssPath)
@@ -187,9 +193,18 @@ describe "ThemeManager", ->
themeManager.requireStylesheet(cssPath)
expect($(document.body).css('font-weight')).toBe("bold")
themeManager.on 'stylesheet-removed', stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
themeManager.on 'stylesheets-changed', stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
themeManager.removeStylesheet(cssPath)
expect($(document.body).css('font-weight')).not.toBe("bold")
expect(stylesheetRemovedHandler).toHaveBeenCalled()
stylesheet = stylesheetRemovedHandler.argsForCall[0][0]
expect(stylesheet instanceof CSSStyleSheet).toBe true
expect(stylesheet.cssRules[0].selectorText).toBe 'body'
expect(stylesheetsChangedHandler).toHaveBeenCalled()
describe "base stylesheet loading", ->
@@ -219,20 +234,21 @@ describe "ThemeManager", ->
describe "when the user stylesheet changes", ->
it "reloads it", ->
[stylesheetRemovedHandler, stylesheetAddedHandler, stylesheetsChangedHandler] = []
userStylesheetPath = path.join(temp.mkdirSync("atom"), 'styles.less')
fs.writeFileSync(userStylesheetPath, 'body {border-style: dotted !important;}')
spyOn(themeManager, 'getUserStylesheetPath').andReturn userStylesheetPath
themeManager.on 'stylesheets-changed', stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
waitsForPromise ->
themeManager.activateThemes()
runs ->
expect($(document.body).css('border-style')).toBe 'dotted'
expect(stylesheetsChangedHandler).toHaveBeenCalled()
stylesheetsChangedHandler.reset()
themeManager.on 'stylesheets-changed', stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
themeManager.on 'stylesheet-removed', stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
themeManager.on 'stylesheet-added', stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
spyOn(themeManager, 'loadUserStylesheet').andCallThrough()
expect($(document.body).css('border-style')).toBe 'dotted'
fs.writeFileSync(userStylesheetPath, 'body {border-style: dashed}')
waitsFor ->
@@ -240,7 +256,16 @@ describe "ThemeManager", ->
runs ->
expect($(document.body).css('border-style')).toBe 'dashed'
expect(stylesheetRemovedHandler).toHaveBeenCalled()
expect(stylesheetRemovedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dotted'
expect(stylesheetAddedHandler).toHaveBeenCalled()
expect(stylesheetAddedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dashed'
expect(stylesheetsChangedHandler).toHaveBeenCalled()
stylesheetRemovedHandler.reset()
stylesheetsChangedHandler.reset()
fs.removeSync(userStylesheetPath)
@@ -248,6 +273,8 @@ describe "ThemeManager", ->
themeManager.loadUserStylesheet.callCount is 2
runs ->
expect(stylesheetRemovedHandler).toHaveBeenCalled()
expect(stylesheetRemovedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dashed'
expect($(document.body).css('border-style')).toBe 'none'
expect(stylesheetsChangedHandler).toHaveBeenCalled()
+9 -5
Ver Arquivo
@@ -6,7 +6,7 @@ describe "TokenizedLine", ->
describe "::getScopeTree()", ->
it "returns a tree whose inner nodes are scopes and whose leaf nodes are tokens in those scopes", ->
editor = atom.project.openSync('coffee.coffee')
[tokens, tokenIndex] = []
ensureValidScopeTree = (scopeTree, scopes=[]) ->
if scopeTree.children?
@@ -16,7 +16,11 @@ describe "TokenizedLine", ->
expect(scopeTree).toBe tokens[tokenIndex++]
expect(scopes).toEqual scopeTree.scopes
tokenIndex = 0
tokens = editor.lineForScreenRow(1).tokens
scopeTree = editor.lineForScreenRow(1).getScopeTree()
ensureValidScopeTree(scopeTree)
waitsForPromise ->
atom.project.open('coffee.coffee').then (o) -> editor = o
runs ->
tokenIndex = 0
tokens = editor.lineForScreenRow(1).tokens
scopeTree = editor.lineForScreenRow(1).getScopeTree()
ensureValidScopeTree(scopeTree)
+37 -20
Ver Arquivo
@@ -64,27 +64,41 @@ describe "Window", ->
describe "when pane items are are modified", ->
it "prompts user to save and and calls workspaceView.confirmClose", ->
editor = null
spyOn(atom.workspaceView, 'confirmClose').andCallThrough()
spyOn(atom, "confirm").andReturn(2)
editor = atom.workspaceView.openSync("sample.js")
editor.insertText("I look different, I feel different.")
$(window).trigger(beforeUnloadEvent)
expect(atom.workspaceView.confirmClose).toHaveBeenCalled()
expect(atom.confirm).toHaveBeenCalled()
waitsForPromise ->
atom.workspace.open("sample.js").then (o) -> editor = o
runs ->
editor.insertText("I look different, I feel different.")
$(window).trigger(beforeUnloadEvent)
expect(atom.workspaceView.confirmClose).toHaveBeenCalled()
expect(atom.confirm).toHaveBeenCalled()
it "prompts user to save and handler returns true if don't save", ->
editor = null
spyOn(atom, "confirm").andReturn(2)
editor = atom.workspaceView.openSync("sample.js")
editor.insertText("I look different, I feel different.")
$(window).trigger(beforeUnloadEvent)
expect(atom.confirm).toHaveBeenCalled()
waitsForPromise ->
atom.workspace.open("sample.js").then (o) -> editor = o
runs ->
editor.insertText("I look different, I feel different.")
$(window).trigger(beforeUnloadEvent)
expect(atom.confirm).toHaveBeenCalled()
it "prompts user to save and handler returns false if dialog is canceled", ->
editor = null
spyOn(atom, "confirm").andReturn(1)
editor = atom.workspaceView.openSync("sample.js")
editor.insertText("I look different, I feel different.")
$(window).trigger(beforeUnloadEvent)
expect(atom.confirm).toHaveBeenCalled()
waitsForPromise ->
atom.workspace.open("sample.js").then (o) -> editor = o
runs ->
editor.insertText("I look different, I feel different.")
$(window).trigger(beforeUnloadEvent)
expect(atom.confirm).toHaveBeenCalled()
describe ".unloadEditorWindow()", ->
it "saves the serialized state of the window so it can be deserialized after reload", ->
@@ -100,15 +114,18 @@ describe "Window", ->
expect(atom.saveSync).toHaveBeenCalled()
it "unsubscribes from all buffers", ->
atom.workspaceView.openSync('sample.js')
buffer = atom.workspaceView.getActivePaneItem().buffer
pane = atom.workspaceView.getActivePaneView()
pane.splitRight(pane.copyActiveItem())
expect(atom.workspaceView.find('.editor').length).toBe 2
waitsForPromise ->
atom.workspace.open("sample.js")
atom.unloadEditorWindow()
runs ->
buffer = atom.workspace.getActivePaneItem().buffer
pane = atom.workspaceView.getActivePaneView()
pane.splitRight(pane.copyActiveItem())
expect(atom.workspaceView.find('.editor').length).toBe 2
expect(buffer.getSubscriptionCount()).toBe 0
atom.unloadEditorWindow()
expect(buffer.getSubscriptionCount()).toBe 0
describe "drag and drop", ->
buildDragEvent = (type, files) ->
+109 -80
Ver Arquivo
@@ -37,12 +37,17 @@ describe "Workspace", ->
describe "when called with a uri", ->
describe "when the active pane already has an editor for the given uri", ->
it "activates the existing editor on the active pane", ->
editor1 = workspace.openSync('a')
editor2 = workspace.openSync('b')
editor = null
editor1 = null
editor2 = null
waitsForPromise ->
workspace.open('a').then (o) -> editor = o
workspace.open('a').then (o) ->
editor1 = o
workspace.open('b').then (o) ->
editor2 = o
workspace.open('a').then (o) ->
editor = o
runs ->
expect(editor).toBe editor1
@@ -64,11 +69,21 @@ describe "Workspace", ->
describe "when the 'searchAllPanes' option is true", ->
describe "when an editor for the given uri is already open on an inactive pane", ->
it "activates the existing editor on the inactive pane, then activates that pane", ->
editor1 = workspace.openSync('a')
pane1 = workspace.activePane
pane2 = workspace.activePane.splitRight()
editor2 = workspace.openSync('b')
expect(workspace.activePaneItem).toBe editor2
editor1 = null
editor2 = null
pane1 = workspace.getActivePane()
pane2 = workspace.getActivePane().splitRight()
waitsForPromise ->
pane1.activate()
workspace.open('a').then (o) -> editor1 = o
waitsForPromise ->
pane2.activate()
workspace.open('b').then (o) -> editor2 = o
runs ->
expect(workspace.activePaneItem).toBe editor2
waitsForPromise ->
workspace.open('a', searchAllPanes: true)
@@ -112,6 +127,22 @@ describe "Workspace", ->
expect(pane1.items).toEqual [editor]
expect(pane2.items).toEqual []
describe "when a pane axis is the leftmost sibling of the current pane", ->
it "opens the new item in the current pane", ->
editor = null
pane1 = workspace.activePane
pane2 = pane1.splitLeft()
pane3 = pane2.splitDown()
pane1.activate()
expect(workspace.activePane).toBe pane1
waitsForPromise ->
workspace.open('a', split: 'left').then (o) -> editor = o
runs ->
expect(workspace.activePane).toBe pane1
expect(pane1.items).toEqual [editor]
describe "when the 'split' option is 'right'", ->
it "opens the editor in the rightmost pane of the current pane axis", ->
editor = null
@@ -136,6 +167,26 @@ describe "Workspace", ->
expect(pane1.items).toEqual []
expect(pane2.items).toEqual [editor]
describe "when a pane axis is the rightmost sibling of the current pane", ->
it "opens the new item in a new pane split to the right of the current pane", ->
editor = null
pane1 = workspace.activePane
pane2 = pane1.splitRight()
pane3 = pane2.splitDown()
pane1.activate()
expect(workspace.activePane).toBe pane1
pane4 = null
waitsForPromise ->
workspace.open('a', split: 'right').then (o) -> editor = o
runs ->
pane4 = workspace.getPanes().filter((p) -> p != pane1)[0]
expect(workspace.activePane).toBe pane4
expect(pane4.items).toEqual [editor]
expect(workspace.paneContainer.root.children[0]).toBe pane1
expect(workspace.paneContainer.root.children[1]).toBe pane4
describe "when passed a path that matches a custom opener", ->
it "returns the resource returned by the custom opener", ->
fooOpener = (pathToOpen, options) -> { foo: pathToOpen, options } if pathToOpen?.match(/\.foo/)
@@ -164,80 +215,55 @@ describe "Workspace", ->
runs ->
expect(newEditorHandler).toHaveBeenCalledWith editor
describe "::openSync(uri, options)", ->
[activePane, initialItemCount] = []
beforeEach ->
activePane = workspace.activePane
spyOn(activePane, 'activate')
initialItemCount = activePane.items.length
describe "when called without a uri", ->
it "adds and activates an empty editor on the active pane", ->
editor = workspace.openSync()
expect(activePane.items.length).toBe initialItemCount + 1
expect(activePane.activeItem).toBe editor
expect(editor.getPath()).toBeUndefined()
expect(activePane.activate).toHaveBeenCalled()
describe "when called with a uri", ->
describe "when the active pane already has an editor for the given uri", ->
it "activates the existing editor on the active pane", ->
editor1 = workspace.openSync('a')
editor2 = workspace.openSync('b')
expect(activePane.activeItem).toBe editor2
expect(activePane.items.length).toBe 2
editor = workspace.openSync(editor1.getPath())
expect(editor).toBe editor1
expect(activePane.activeItem).toBe editor
expect(activePane.activate).toHaveBeenCalled()
expect(activePane.items.length).toBe 2
describe "when the active pane does not have an editor for the given uri", ->
it "adds and activates a new editor for the given path on the active pane", ->
editor = workspace.openSync('a')
expect(activePane.items.length).toBe 1
expect(activePane.activeItem).toBe editor
expect(activePane.activate).toHaveBeenCalled()
describe "when the 'activatePane' option is false", ->
it "does not activate the active pane", ->
workspace.openSync('b', activatePane: false)
expect(activePane.activate).not.toHaveBeenCalled()
describe "::reopenItemSync()", ->
describe "::reopenItem()", ->
it "opens the uri associated with the last closed pane that isn't currently open", ->
pane = workspace.activePane
workspace.openSync('a')
workspace.openSync('b')
workspace.openSync('file1')
workspace.openSync()
waitsForPromise ->
workspace.open('a').then ->
workspace.open('b').then ->
workspace.open('file1').then ->
workspace.open()
# does not reopen items with no uri
expect(workspace.activePaneItem.getUri()).toBeUndefined()
pane.destroyActiveItem()
workspace.reopenItemSync()
expect(workspace.activePaneItem.getUri()).not.toBeUndefined()
runs ->
# does not reopen items with no uri
expect(workspace.activePaneItem.getUri()).toBeUndefined()
pane.destroyActiveItem()
# destroy all items
expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('file1')
pane.destroyActiveItem()
expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('b')
pane.destroyActiveItem()
expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('a')
pane.destroyActiveItem()
waitsForPromise ->
workspace.reopenItem()
# reopens items with uris
expect(workspace.activePaneItem).toBeUndefined()
workspace.reopenItemSync()
expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('a')
runs ->
expect(workspace.activePaneItem.getUri()).not.toBeUndefined()
# destroy all items
expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('file1')
pane.destroyActiveItem()
expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('b')
pane.destroyActiveItem()
expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('a')
pane.destroyActiveItem()
# reopens items with uris
expect(workspace.activePaneItem).toBeUndefined()
waitsForPromise ->
workspace.reopenItem()
runs ->
expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('a')
# does not reopen items that are already open
workspace.openSync('b')
expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('b')
workspace.reopenItemSync()
expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('file1')
waitsForPromise ->
workspace.open('b')
runs ->
expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('b')
waitsForPromise ->
workspace.reopenItem()
runs ->
expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('file1')
describe "::increase/decreaseFontSize()", ->
it "increases/decreases the font size without going below 1", ->
@@ -272,11 +298,14 @@ describe "Workspace", ->
describe "when an editor is copied", ->
it "emits an 'editor-created' event", ->
editor = null
handler = jasmine.createSpy('editorCreatedHandler')
workspace.on 'editor-created', handler
editor1 = workspace.openSync("a")
expect(handler.callCount).toBe 1
waitsForPromise ->
workspace.open("a").then (o) -> editor = o
editor2 = editor1.copy()
expect(handler.callCount).toBe 2
runs ->
expect(handler.callCount).toBe 1
editorCopy = editor.copy()
expect(handler.callCount).toBe 2
+91 -48
Ver Arquivo
@@ -2,6 +2,7 @@
Q = require 'q'
path = require 'path'
temp = require 'temp'
EditorView = require '../src/editor-view'
PaneView = require '../src/pane-view'
Workspace = require '../src/workspace'
@@ -14,9 +15,12 @@ describe "WorkspaceView", ->
atom.workspace = new Workspace
atom.workspaceView = new WorkspaceView(atom.workspace)
atom.workspaceView.enableKeymap()
atom.workspaceView.openSync(pathToOpen)
atom.workspaceView.focus()
waitsForPromise ->
atom.workspace.open(pathToOpen)
describe "@deserialize()", ->
viewState = null
@@ -32,17 +36,21 @@ describe "WorkspaceView", ->
describe "when the serialized WorkspaceView has an unsaved buffer", ->
it "constructs the view with the same panes", ->
atom.workspaceView.attachToDom()
atom.workspaceView.openSync()
editorView1 = atom.workspaceView.getActiveView()
buffer = editorView1.getEditor().getBuffer()
editorView1.splitRight()
expect(atom.workspaceView.getActivePaneView()).toBe atom.workspaceView.getPaneViews()[1]
simulateReload()
waitsForPromise ->
atom.workspace.open()
expect(atom.workspaceView.getEditorViews().length).toBe 2
expect(atom.workspaceView.getActivePaneView()).toBe atom.workspaceView.getPaneViews()[1]
expect(atom.workspaceView.title).toBe "untitled - #{atom.project.getPath()}"
runs ->
editorView1 = atom.workspaceView.getActiveView()
buffer = editorView1.getEditor().getBuffer()
editorView1.splitRight()
expect(atom.workspaceView.getActivePaneView()).toBe atom.workspaceView.getPaneViews()[1]
simulateReload()
expect(atom.workspaceView.getEditorViews().length).toBe 2
expect(atom.workspaceView.getActivePaneView()).toBe atom.workspaceView.getPaneViews()[1]
expect(atom.workspaceView.title).toBe "untitled - #{atom.project.getPath()}"
describe "when there are open editors", ->
it "constructs the view with the same panes", ->
@@ -50,42 +58,56 @@ describe "WorkspaceView", ->
pane1 = atom.workspaceView.getActivePaneView()
pane2 = pane1.splitRight()
pane3 = pane2.splitRight()
pane4 = pane2.splitDown()
pane2.activateItem(atom.project.openSync('b'))
pane3.activateItem(atom.project.openSync('../sample.js'))
pane3.activeItem.setCursorScreenPosition([2, 4])
pane4.activateItem(atom.project.openSync('../sample.txt'))
pane4.activeItem.setCursorScreenPosition([0, 2])
pane2.focus()
pane4 = null
simulateReload()
waitsForPromise ->
atom.workspace.open('b').then (editor) ->
pane2.activateItem(editor)
expect(atom.workspaceView.getEditorViews().length).toBe 4
editorView1 = atom.workspaceView.panes.find('.pane-row > .pane .editor:eq(0)').view()
editorView3 = atom.workspaceView.panes.find('.pane-row > .pane .editor:eq(1)').view()
editorView2 = atom.workspaceView.panes.find('.pane-row > .pane-column > .pane .editor:eq(0)').view()
editorView4 = atom.workspaceView.panes.find('.pane-row > .pane-column > .pane .editor:eq(1)').view()
waitsForPromise ->
atom.workspace.open('../sample.js').then (editor) ->
pane3.activateItem(editor)
expect(editorView1.getEditor().getPath()).toBe atom.project.resolve('a')
expect(editorView2.getEditor().getPath()).toBe atom.project.resolve('b')
expect(editorView3.getEditor().getPath()).toBe atom.project.resolve('../sample.js')
expect(editorView3.getEditor().getCursorScreenPosition()).toEqual [2, 4]
expect(editorView4.getEditor().getPath()).toBe atom.project.resolve('../sample.txt')
expect(editorView4.getEditor().getCursorScreenPosition()).toEqual [0, 2]
runs ->
pane3.activeItem.setCursorScreenPosition([2, 4])
pane4 = pane2.splitDown()
# ensure adjust pane dimensions is called
expect(editorView1.width()).toBeGreaterThan 0
expect(editorView2.width()).toBeGreaterThan 0
expect(editorView3.width()).toBeGreaterThan 0
expect(editorView4.width()).toBeGreaterThan 0
waitsForPromise ->
atom.workspace.open('../sample.txt').then (editor) ->
pane4.activateItem(editor)
# ensure correct editorView is focused again
expect(editorView2.isFocused).toBeTruthy()
expect(editorView1.isFocused).toBeFalsy()
expect(editorView3.isFocused).toBeFalsy()
expect(editorView4.isFocused).toBeFalsy()
runs ->
pane4.activeItem.setCursorScreenPosition([0, 2])
pane2.focus()
expect(atom.workspaceView.title).toBe "#{path.basename(editorView2.getEditor().getPath())} - #{atom.project.getPath()}"
simulateReload()
expect(atom.workspaceView.getEditorViews().length).toBe 4
editorView1 = atom.workspaceView.panes.find('.pane-row > .pane .editor:eq(0)').view()
editorView3 = atom.workspaceView.panes.find('.pane-row > .pane .editor:eq(1)').view()
editorView2 = atom.workspaceView.panes.find('.pane-row > .pane-column > .pane .editor:eq(0)').view()
editorView4 = atom.workspaceView.panes.find('.pane-row > .pane-column > .pane .editor:eq(1)').view()
expect(editorView1.getEditor().getPath()).toBe atom.project.resolve('a')
expect(editorView2.getEditor().getPath()).toBe atom.project.resolve('b')
expect(editorView3.getEditor().getPath()).toBe atom.project.resolve('../sample.js')
expect(editorView3.getEditor().getCursorScreenPosition()).toEqual [2, 4]
expect(editorView4.getEditor().getPath()).toBe atom.project.resolve('../sample.txt')
expect(editorView4.getEditor().getCursorScreenPosition()).toEqual [0, 2]
# ensure adjust pane dimensions is called
expect(editorView1.width()).toBeGreaterThan 0
expect(editorView2.width()).toBeGreaterThan 0
expect(editorView3.width()).toBeGreaterThan 0
expect(editorView4.width()).toBeGreaterThan 0
# ensure correct editorView is focused again
expect(editorView2).toHaveFocus()
expect(editorView1).not.toHaveFocus()
expect(editorView3).not.toHaveFocus()
expect(editorView4).not.toHaveFocus()
expect(atom.workspaceView.title).toBe "#{path.basename(editorView2.getEditor().getPath())} - #{atom.project.getPath()}"
describe "where there are no open editors", ->
it "constructs the view with no open editors", ->
@@ -101,9 +123,9 @@ describe "WorkspaceView", ->
it "hands off focus to the active pane", ->
activePane = atom.workspaceView.getActivePaneView()
$('body').focus()
expect(activePane.hasFocus()).toBe false
expect(activePane).not.toHaveFocus()
atom.workspaceView.focus()
expect(activePane.hasFocus()).toBe true
expect(activePane).toHaveFocus()
describe "keymap wiring", ->
commandHandler = null
@@ -111,7 +133,7 @@ describe "WorkspaceView", ->
commandHandler = jasmine.createSpy('commandHandler')
atom.workspaceView.on('foo-command', commandHandler)
atom.keymaps.bindKeys('name', '*', 'x': 'foo-command')
atom.keymaps.add('name', '*': {'x': 'foo-command'})
describe "when a keydown event is triggered in the WorkspaceView", ->
it "triggers matching keybindings for that event", ->
@@ -128,7 +150,8 @@ describe "WorkspaceView", ->
describe "when the project has a path", ->
beforeEach ->
atom.workspaceView.openSync('b')
waitsForPromise ->
atom.workspace.open('b')
describe "when there is an active pane item", ->
it "sets the title to the pane item's title plus the project path", ->
@@ -143,7 +166,7 @@ describe "WorkspaceView", ->
describe "when the active pane's item changes", ->
it "updates the title to the new item's title plus the project path", ->
atom.workspaceView.getActivePaneView().showNextItem()
atom.workspaceView.getActivePaneView().activateNextItem()
item = atom.workspace.getActivePaneItem()
expect(atom.workspaceView.title).toBe "#{item.getTitle()} - #{atom.project.getPath()}"
@@ -158,7 +181,7 @@ describe "WorkspaceView", ->
pane = atom.workspaceView.getActivePaneView()
pane.splitRight()
initialTitle = atom.workspaceView.title
pane.showNextItem()
pane.activateNextItem()
expect(atom.workspaceView.title).toBe initialTitle
describe "when the root view is deserialized", ->
@@ -222,6 +245,14 @@ describe "WorkspaceView", ->
expect(count).toBe 1
expect(callbackEditor).toBe atom.workspaceView.getActiveView()
it "does not invoke the callback for mini editors", ->
editorViewCreatedHandler = jasmine.createSpy('editorViewCreatedHandler')
atom.workspaceView.eachEditorView(editorViewCreatedHandler)
editorViewCreatedHandler.reset()
miniEditor = new EditorView(mini: true)
atom.workspaceView.append(miniEditor)
expect(editorViewCreatedHandler).not.toHaveBeenCalled()
it "returns a subscription that can be disabled", ->
count = 0
callback = (editor) -> count++
@@ -237,10 +268,22 @@ describe "WorkspaceView", ->
describe "core:close", ->
it "closes the active pane item until all that remains is a single empty pane", ->
atom.config.set('core.destroyEmptyPanes', true)
atom.project.openSync('../sample.txt')
expect(atom.workspaceView.getActivePaneView().getItems()).toHaveLength 1
paneView1 = atom.workspaceView.getActivePaneView()
editorView = atom.workspaceView.getActiveView()
editorView.splitRight()
paneView2 = atom.workspaceView.getActivePaneView()
expect(paneView1).not.toBe paneView2
expect(atom.workspaceView.getPaneViews()).toHaveLength 2
atom.workspaceView.trigger('core:close')
expect(atom.workspaceView.getActivePaneView().getItems()).toHaveLength 1
expect(atom.workspaceView.getPaneViews()).toHaveLength 1
atom.workspaceView.trigger('core:close')
expect(atom.workspaceView.getActivePaneView().getItems()).toHaveLength 0
expect(atom.workspaceView.getPaneViews()).toHaveLength 1
describe "the scrollbar visibility class", ->
it "has a class based on the style of the scrollbar", ->
+14 -14
Ver Arquivo
@@ -148,7 +148,7 @@ class Atom extends Model
ThemeManager = require './theme-manager'
ContextMenuManager = require './context-menu-manager'
MenuManager = require './menu-manager'
{devMode, resourcePath} = @getLoadSettings()
{devMode, safeMode, resourcePath} = @getLoadSettings()
configDirPath = @getConfigDirPath()
# Add 'src/exports' to module search path.
@@ -163,7 +163,7 @@ class Atom extends Model
@config = new Config({configDirPath, resourcePath})
@keymaps = new KeymapManager({configDirPath, resourcePath})
@keymap = @keymaps # Deprecated
@packages = new PackageManager({devMode, configDirPath, resourcePath})
@packages = new PackageManager({devMode, configDirPath, resourcePath, safeMode})
@themes = new ThemeManager({packageManager: @packages, configDirPath, resourcePath})
@contextMenu = new ContextMenuManager(devMode)
@menu = new MenuManager({resourcePath})
@@ -340,7 +340,7 @@ class Atom extends Model
# options - An {Object} with the following keys:
# :pathsToOpen - An {Array} of {String} paths to open.
open: (options) ->
ipc.sendChannel('open', options)
ipc.send('open', options)
# Public: Open a confirm dialog.
#
@@ -394,50 +394,50 @@ class Atom extends Model
# Public: Open the dev tools for the current window.
openDevTools: ->
ipc.sendChannel('call-window-method', 'openDevTools')
ipc.send('call-window-method', 'openDevTools')
# Public: Toggle the visibility of the dev tools for the current window.
toggleDevTools: ->
ipc.sendChannel('call-window-method', 'toggleDevTools')
ipc.send('call-window-method', 'toggleDevTools')
# Public: Execute code in dev tools.
executeJavaScriptInDevTools: (code) ->
ipc.sendChannel('call-window-method', 'executeJavaScriptInDevTools', code)
ipc.send('call-window-method', 'executeJavaScriptInDevTools', code)
# Public: Reload the current window.
reload: ->
ipc.sendChannel('call-window-method', 'restart')
ipc.send('call-window-method', 'restart')
# Public: Focus the current window.
focus: ->
ipc.sendChannel('call-window-method', 'focus')
ipc.send('call-window-method', 'focus')
$(window).focus()
# Public: Show the current window.
show: ->
ipc.sendChannel('call-window-method', 'show')
ipc.send('call-window-method', 'show')
# Public: Hide the current window.
hide: ->
ipc.sendChannel('call-window-method', 'hide')
ipc.send('call-window-method', 'hide')
# Public: Set the size of current window.
#
# width - The {Number} of pixels.
# height - The {Number} of pixels.
setSize: (width, height) ->
ipc.sendChannel('call-window-method', 'setSize', width, height)
ipc.send('call-window-method', 'setSize', width, height)
# Public: Set the position of current window.
#
# x - The {Number} of pixels.
# y - The {Number} of pixels.
setPosition: (x, y) ->
ipc.sendChannel('call-window-method', 'setPosition', x, y)
ipc.send('call-window-method', 'setPosition', x, y)
# Public: Move current window to the center of the screen.
center: ->
ipc.sendChannel('call-window-method', 'center')
ipc.send('call-window-method', 'center')
# Schedule the window to be shown and focused on the next tick.
#
@@ -472,7 +472,7 @@ class Atom extends Model
# Public: Set the full screen state of the current window.
setFullScreen: (fullScreen=false) ->
ipc.sendChannel('call-window-method', 'setFullScreen', fullScreen)
ipc.send('call-window-method', 'setFullScreen', fullScreen)
# Public: Is the current window in full screen mode?
isFullScreen: ->
+38 -28
Ver Arquivo
@@ -59,7 +59,7 @@ class AtomApplication
exit: (status) -> app.exit(status)
constructor: (options) ->
{@resourcePath, @version, @devMode} = options
{@resourcePath, @version, @devMode, @safeMode} = options
global.atomApplication = this
@pidsToOpenWindows = {}
@@ -77,15 +77,15 @@ class AtomApplication
@openWithOptions(options)
# Opens a new window based on the options provided.
openWithOptions: ({pathsToOpen, urlsToOpen, test, pidToKillWhenClosed, devMode, newWindow, specDirectory, logFile}) ->
openWithOptions: ({pathsToOpen, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, specDirectory, logFile}) ->
if test
@runSpecs({exitWhenDone: true, @resourcePath, specDirectory, logFile})
else if pathsToOpen.length > 0
@openPaths({pathsToOpen, pidToKillWhenClosed, newWindow, devMode})
@openPaths({pathsToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode})
else if urlsToOpen.length > 0
@openUrl({urlToOpen, devMode}) for urlToOpen in urlsToOpen
@openUrl({urlToOpen, devMode, safeMode}) for urlToOpen in urlsToOpen
else
@openPath({pidToKillWhenClosed, newWindow, devMode}) # Always open a editor window if this is the first instance of Atom.
@openPath({pidToKillWhenClosed, newWindow, devMode, safeMode}) # Always open a editor window if this is the first instance of Atom.
# Public: Removes the {AtomWindow} from the global window list.
removeWindow: (window) ->
@@ -140,6 +140,7 @@ class AtomApplication
@on 'application:open-file', -> @promptForPath(type: 'file')
@on 'application:open-folder', -> @promptForPath(type: 'folder')
@on 'application:open-dev', -> @promptForPath(devMode: true)
@on 'application:open-safe', -> @promptForPath(safeMode: true)
@on 'application:inspect', ({x,y, atomWindow}) ->
atomWindow ?= @focusedWindow()
atomWindow?.browserWindow.inspectElement(x, y)
@@ -166,6 +167,7 @@ class AtomApplication
@openPathOnEvent('application:open-your-keymap', 'atom://.atom/keymap')
@openPathOnEvent('application:open-your-snippets', 'atom://.atom/snippets')
@openPathOnEvent('application:open-your-stylesheet', 'atom://.atom/stylesheet')
@openPathOnEvent('application:open-license', path.join(@resourcePath, 'LICENSE.md'))
app.on 'window-all-closed', ->
app.quit() if process.platform in ['win32', 'linux']
@@ -184,14 +186,14 @@ class AtomApplication
app.on 'open-url', (event, urlToOpen) =>
event.preventDefault()
@openUrl({urlToOpen, @devMode})
@openUrl({urlToOpen, @devMode, @safeMode})
app.on 'activate-with-no-open-windows', (event) =>
event.preventDefault()
@emit('application:new-window')
# A request from the associated render process to open a new render process.
ipc.on 'open', (processId, routingId, options) =>
ipc.on 'open', (event, options) =>
if options?
if options.pathsToOpen?.length > 0
@openPaths(options)
@@ -200,21 +202,21 @@ class AtomApplication
else
@promptForPath()
ipc.on 'update-application-menu', (processId, routingId, template, keystrokesByCommand) =>
ipc.on 'update-application-menu', (event, template, keystrokesByCommand) =>
@applicationMenu.update(template, keystrokesByCommand)
ipc.on 'run-package-specs', (processId, routingId, specDirectory) =>
ipc.on 'run-package-specs', (event, specDirectory) =>
@runSpecs({resourcePath: global.devResourcePath, specDirectory: specDirectory, exitWhenDone: false})
ipc.on 'command', (processId, routingId, command) =>
ipc.on 'command', (event, command) =>
@emit(command)
ipc.on 'window-command', (processId, routingId, command, args...) ->
win = BrowserWindow.fromProcessIdAndRoutingId(processId, routingId)
ipc.on 'window-command', (event, command, args...) ->
win = BrowserWindow.fromWebContents(event.sender)
win.emit(command, args...)
ipc.on 'call-window-method', (processId, routingId, method, args...) ->
win = BrowserWindow.fromProcessIdAndRoutingId(processId, routingId)
ipc.on 'call-window-method', (event, method, args...) ->
win = BrowserWindow.fromWebContents(event.sender)
win[method](args...)
# Public: Executes the given command.
@@ -288,8 +290,10 @@ class AtomApplication
# :pidToKillWhenClosed - The integer of the pid to kill
# :newWindow - Boolean of whether this should be opened in a new window.
# :devMode - Boolean to control the opened window's dev mode.
openPaths: ({pathsToOpen, pidToKillWhenClosed, newWindow, devMode}) ->
@openPath({pathToOpen, pidToKillWhenClosed, newWindow, devMode}) for pathToOpen in pathsToOpen ? []
# :safeMode - Boolean to control the opened window's safe mode.
openPaths: ({pathsToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode}) ->
for pathToOpen in pathsToOpen ? []
@openPath({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode})
# Public: Opens a single path, in an existing window if possible.
#
@@ -298,13 +302,16 @@ class AtomApplication
# :pidToKillWhenClosed - The integer of the pid to kill
# :newWindow - Boolean of whether this should be opened in a new window.
# :devMode - Boolean to control the opened window's dev mode.
# :safeMode - Boolean to control the opened window's safe mode.
# :windowDimensions - Object with height and width keys.
openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, windowDimensions}={}) ->
openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions}={}) ->
if pathToOpen
[basename, initialLine] = path.basename(pathToOpen).split(':')
if initialLine
pathToOpen = "#{path.dirname(pathToOpen)}/#{basename}"
initialLine -= 1 # Convert line numbers to a base of 0
[basename, initialLine, initialColumn] = path.basename(pathToOpen).split(':')
pathToOpen = path.join(path.dirname(pathToOpen), basename) if initialLine
# Convert line numbers to a base of 0
initialLine -= 1 if initialLine
initialColumn -= 1 if initialColumn
unless devMode
existingWindow = @windowForPath(pathToOpen) unless pidToKillWhenClosed or newWindow
@@ -320,12 +327,12 @@ class AtomApplication
bootstrapScript ?= require.resolve('../window-bootstrap')
resourcePath ?= @resourcePath
openedWindow = new AtomWindow({pathToOpen, initialLine, bootstrapScript, resourcePath, devMode, windowDimensions})
openedWindow = new AtomWindow({pathToOpen, initialLine, initialColumn, bootstrapScript, resourcePath, devMode, safeMode, windowDimensions})
if pidToKillWhenClosed?
@pidsToOpenWindows[pidToKillWhenClosed] = openedWindow
openedWindow.browserWindow.on 'destroyed', =>
openedWindow.browserWindow.on 'closed', =>
@killProcessForWindow(openedWindow)
# Kill all processes associated with opened windows.
@@ -355,7 +362,8 @@ class AtomApplication
# options -
# :urlToOpen - The atom:// url to open.
# :devMode - Boolean to control the opened window's dev mode.
openUrl: ({urlToOpen, devMode}) ->
# :safeMode - Boolean to control the opened window's safe mode.
openUrl: ({urlToOpen, devMode, safeMode}) ->
unless @packages?
PackageManager = require '../package-manager'
fs = require 'fs-plus'
@@ -371,7 +379,7 @@ class AtomApplication
packagePath = @packages.resolvePackagePath(packageName)
bootstrapScript = path.resolve(packagePath, pack.urlMain)
windowDimensions = @focusedWindow()?.getDimensions()
new AtomWindow({bootstrapScript, @resourcePath, devMode, urlToOpen, windowDimensions})
new AtomWindow({bootstrapScript, @resourcePath, devMode, safeMode, urlToOpen, windowDimensions})
else
console.log "Package '#{pack.name}' does not have a url main: #{urlToOpen}"
else
@@ -414,8 +422,10 @@ class AtomApplication
# :type - A String which specifies the type of the dialog, could be 'file',
# 'folder' or 'all'. The 'all' is only available on OS X.
# :devMode - A Boolean which controls whether any newly opened windows
# should be in dev mode or not.
promptForPath: ({type, devMode}={}) ->
# should be in dev mode or not.
# :safeMode - A Boolean which controls whether any newly opened windows
# should be in safe mode or not.
promptForPath: ({type, devMode, safeMode}={}) ->
type ?= 'all'
properties =
switch type
@@ -424,4 +434,4 @@ class AtomApplication
when 'all' then ['openFile', 'openDirectory']
else throw new Error("#{type} is an invalid type for promptForPath")
dialog.showOpenDialog title: 'Open', properties: properties.concat(['multiSelections', 'createDirectory']), (pathsToOpen) =>
@openPaths({pathsToOpen, devMode})
@openPaths({pathsToOpen, devMode, safeMode})
+8 -9
Ver Arquivo
@@ -2,7 +2,6 @@ BrowserWindow = require 'browser-window'
ContextMenu = require './context-menu'
app = require 'app'
dialog = require 'dialog'
ipc = require 'ipc'
path = require 'path'
fs = require 'fs'
url = require 'url'
@@ -21,7 +20,7 @@ class AtomWindow
isSpec: null
constructor: (settings={}) ->
{@resourcePath, pathToOpen, initialLine, @isSpec, @exitWhenDone} = settings
{@resourcePath, pathToOpen, initialLine, initialColumn, @isSpec, @exitWhenDone} = settings
global.atomApplication.addWindow(this)
@browserWindow = new BrowserWindow show: false, title: 'Atom', icon: @constructor.iconPath
@@ -48,7 +47,7 @@ class AtomWindow
@browserWindow.loadUrl @getUrl(loadSettings)
@browserWindow.focusOnWebView() if @isSpec
@openPath(pathToOpen, initialLine)
@openPath(pathToOpen, initialLine, initialColumn)
getUrl: (loadSettingsObj) ->
# Ignore the windowState when passing loadSettings via URL, since it could
@@ -81,7 +80,7 @@ class AtomWindow
false
handleEvents: ->
@browserWindow.on 'destroyed', =>
@browserWindow.on 'closed', =>
global.atomApplication.removeWindow(this)
@browserWindow.on 'unresponsive', =>
@@ -94,7 +93,7 @@ class AtomWindow
detail: 'The editor is not responding. Would you like to force close it or just keep waiting?'
@browserWindow.destroy() if chosen is 0
@browserWindow.on 'crashed', =>
@browserWindow.webContents.on 'crashed', =>
global.atomApplication.exit(100) if @exitWhenDone
chosen = dialog.showMessageBox @browserWindow,
@@ -114,12 +113,12 @@ class AtomWindow
@browserWindow.on 'blur', =>
@browserWindow.focusOnWebView()
openPath: (pathToOpen, initialLine) ->
openPath: (pathToOpen, initialLine, initialColumn) ->
if @loaded
@focus()
@sendCommand('window:open-path', {pathToOpen, initialLine})
@sendCommand('window:open-path', {pathToOpen, initialLine, initialColumn})
else
@browserWindow.once 'window:loaded', => @openPath(pathToOpen, initialLine)
@browserWindow.once 'window:loaded', => @openPath(pathToOpen, initialLine, initialColumn)
sendCommand: (command, args...) ->
if @isSpecWindow()
@@ -136,7 +135,7 @@ class AtomWindow
sendCommandToBrowserWindow: (command, args...) ->
action = if args[0]?.contextCommand then 'context-command' else 'command'
ipc.sendChannel @browserWindow.getProcessId(), @browserWindow.getRoutingId(), action, command, args...
@browserWindow.webContents.send action, command, args...
getDimensions: ->
[x, y] = @browserWindow.getPosition()
+3 -1
Ver Arquivo
@@ -73,6 +73,7 @@ parseCommandLine = ->
options.alias('l', 'log-file').string('l').describe('l', 'Log all output to file.')
options.alias('n', 'new-window').boolean('n').describe('n', 'Open a new window.')
options.alias('s', 'spec-directory').string('s').describe('s', 'Set the spec directory (default: Atom\'s spec directory).')
options.boolean('safe').describe('safe', 'Do not load packages from ~/.atom/packages or ~/.atom/dev/packages.')
options.alias('t', 'test').boolean('t').describe('t', 'Run the specified specs and exit with error code on failures.')
options.alias('v', 'version').boolean('v').describe('v', 'Print the version.')
options.alias('w', 'wait').boolean('w').describe('w', 'Wait for window to be closed before returning.')
@@ -88,6 +89,7 @@ parseCommandLine = ->
executedFrom = args['executed-from']
devMode = args['dev']
safeMode = args['safe']
pathsToOpen = args._
pathsToOpen = [executedFrom] if executedFrom and pathsToOpen.length is 0
test = args['test']
@@ -107,6 +109,6 @@ parseCommandLine = ->
catch
resourcePath = path.dirname(path.dirname(__dirname))
{resourcePath, pathsToOpen, executedFrom, test, version, pidToKillWhenClosed, devMode, newWindow, specDirectory, logFile}
{resourcePath, pathsToOpen, executedFrom, test, version, pidToKillWhenClosed, devMode, safeMode, newWindow, specDirectory, logFile}
start()
+3 -3
Ver Arquivo
@@ -138,13 +138,13 @@ class Cursor extends Model
# Public: Identifies if the cursor is surrounded by whitespace.
#
# "Surrounded" here means that all characters before and after the cursor is
# whitespace.
# "Surrounded" here means that the character directly before and after the
# cursor are both whitespace.
#
# Returns a {Boolean}.
isSurroundedByWhitespace: ->
{row, column} = @getBufferPosition()
range = [[row, Math.min(0, column - 1)], [row, Math.max(0, column + 1)]]
range = [[row, column - 1], [row, column + 1]]
/^\s+$/.test @editor.getTextInBufferRange(range)
# Public: Returns whether the cursor is currently between a word and non-word
+62 -7
Ver Arquivo
@@ -32,6 +32,8 @@ class DisplayBuffer extends Model
verticalScrollMargin: 2
horizontalScrollMargin: 6
horizontalScrollbarHeight: 15
verticalScrollbarWidth: 15
constructor: ({tabLength, @editorWidthInChars, @tokenizedBuffer, buffer}={}) ->
super
@@ -111,32 +113,83 @@ class DisplayBuffer extends Model
getHorizontalScrollMargin: -> @horizontalScrollMargin
setHorizontalScrollMargin: (@horizontalScrollMargin) -> @horizontalScrollMargin
getHeight: -> @height ? @getScrollHeight()
getHorizontalScrollbarHeight: -> @horizontalScrollbarHeight
setHorizontalScrollbarHeight: (@horizontalScrollbarHeight) -> @horizontalScrollbarHeight
getVerticalScrollbarWidth: -> @verticalScrollbarWidth
setVerticalScrollbarWidth: (@verticalScrollbarWidth) -> @verticalScrollbarWidth
getHeight: ->
if @height?
@height
else
if @horizontallyScrollable()
@getScrollHeight() + @getHorizontalScrollbarHeight()
else
@getScrollHeight()
setHeight: (@height) -> @height
getWidth: -> @width ? @getScrollWidth()
getClientHeight: (reentrant) ->
if @horizontallyScrollable(reentrant)
@getHeight() - @getHorizontalScrollbarHeight()
else
@getHeight()
getClientWidth: (reentrant) ->
if @verticallyScrollable(reentrant)
@getWidth() - @getVerticalScrollbarWidth()
else
@getWidth()
horizontallyScrollable: (reentrant) ->
return false unless @width?
return false if @getSoftWrap()
if reentrant
@getScrollWidth() > @getWidth()
else
@getScrollWidth() > @getClientWidth(true)
verticallyScrollable: (reentrant) ->
return false unless @height?
if reentrant
@getScrollHeight() > @getHeight()
else
@getScrollHeight() > @getClientHeight(true)
getWidth: ->
if @width?
@width
else
if @verticallyScrollable()
@getScrollWidth() + @getVerticalScrollbarWidth()
else
@getScrollWidth()
setWidth: (newWidth) ->
oldWidth = @width
@width = newWidth
@updateWrappedScreenLines() if newWidth isnt oldWidth and @softWrap
@setScrollTop(@getScrollTop()) # Ensure scrollTop is still valid in case horizontal scrollbar disappeared
@width
getScrollTop: -> @scrollTop
setScrollTop: (scrollTop) ->
if @manageScrollPosition
@scrollTop = Math.max(0, Math.min(@getScrollHeight() - @getHeight(), scrollTop))
@scrollTop = Math.max(0, Math.min(@getScrollHeight() - @getClientHeight(), scrollTop))
else
@scrollTop = scrollTop
getScrollBottom: -> @scrollTop + @height
setScrollBottom: (scrollBottom) ->
@setScrollTop(scrollBottom - @height)
@setScrollTop(scrollBottom - @getClientHeight())
@getScrollBottom()
getScrollLeft: -> @scrollLeft
setScrollLeft: (scrollLeft) ->
if @manageScrollPosition
@scrollLeft = Math.max(0, Math.min(@getScrollWidth() - @getWidth(), scrollLeft))
@scrollLeft = Math.max(0, Math.min(@getScrollWidth() - @getClientWidth(), scrollLeft))
@scrollLeft
else
@scrollLeft = scrollLeft
@@ -151,6 +204,8 @@ class DisplayBuffer extends Model
getDefaultCharWidth: -> @defaultCharWidth
setDefaultCharWidth: (@defaultCharWidth) -> @defaultCharWidth
getCursorWidth: -> 1
getScopedCharWidth: (scopeNames, char) ->
@getScopedCharWidths(scopeNames)[char]
@@ -178,13 +233,13 @@ class DisplayBuffer extends Model
@getLineCount() * @getLineHeight()
getScrollWidth: ->
@getMaxLineLength() * @getDefaultCharWidth()
(@getMaxLineLength() * @getDefaultCharWidth()) + @getCursorWidth()
getVisibleRowRange: ->
unless @getLineHeight() > 0
throw new Error("You must assign a non-zero lineHeight before calling ::getVisibleRowRange()")
heightInLines = Math.ceil(@getHeight() / @getLineHeight()) + 1
heightInLines = Math.ceil(@getClientHeight() / @getLineHeight()) + 1
startRow = Math.floor(@getScrollTop() / @getLineHeight())
endRow = Math.min(@getLineCount(), Math.ceil(startRow + heightInLines))
[startRow, endRow]
+81 -8
Ver Arquivo
@@ -5,6 +5,7 @@ React = require 'react'
GutterComponent = require './gutter-component'
EditorScrollViewComponent = require './editor-scroll-view-component'
ScrollbarComponent = require './scrollbar-component'
ScrollbarCornerComponent = require './scrollbar-corner-component'
SubscriberMixin = require './subscriber-mixin'
module.exports =
@@ -20,10 +21,15 @@ EditorComponent = React.createClass
cursorsMoved: false
preservedRowRange: null
scrollingVertically: false
gutterWidth: 0
refreshingScrollbars: false
measuringScrollbars: true
render: ->
{focused, fontSize, lineHeight, fontFamily, showIndentGuide} = @state
{editor, cursorBlinkPeriod, cursorBlinkResumeDelay} = @props
maxLineNumberDigits = editor.getScreenLineCount().toString().length
if @isMounted()
renderedRowRange = @getRenderedRowRange()
scrollHeight = editor.getScrollHeight()
@@ -31,15 +37,20 @@ EditorComponent = React.createClass
scrollTop = editor.getScrollTop()
scrollLeft = editor.getScrollLeft()
lineHeightInPixels = editor.getLineHeight()
horizontalScrollbarHeight = editor.getHorizontalScrollbarHeight()
verticalScrollbarWidth = editor.getVerticalScrollbarWidth()
verticallyScrollable = editor.verticallyScrollable()
horizontallyScrollable = editor.horizontallyScrollable()
className = 'editor editor-colors react'
className += ' is-focused' if focused
div className: className, style: {fontSize, lineHeight, fontFamily}, tabIndex: -1,
GutterComponent {
editor, renderedRowRange, scrollTop, scrollHeight,
lineHeight: lineHeightInPixels, @pendingChanges
}
# GutterComponent {
# editor, renderedRowRange, maxLineNumberDigits, scrollTop, scrollHeight,
# lineHeight: lineHeightInPixels, fontSize, fontFamily, @pendingChanges,
# onWidthChanged: @onGutterWidthChanged
# }
EditorScrollViewComponent {
ref: 'scrollView', editor, fontSize, fontFamily, showIndentGuide
@@ -55,6 +66,10 @@ EditorComponent = React.createClass
onScroll: @onVerticalScroll
scrollTop: scrollTop
scrollHeight: scrollHeight
visible: verticallyScrollable and not @refreshingScrollbars and not @measuringScrollbars
scrollableInOppositeDirection: horizontallyScrollable
verticalScrollbarWidth: verticalScrollbarWidth
horizontalScrollbarHeight: horizontalScrollbarHeight
ScrollbarComponent
ref: 'horizontalScrollbar'
@@ -62,7 +77,19 @@ EditorComponent = React.createClass
orientation: 'horizontal'
onScroll: @onHorizontalScroll
scrollLeft: scrollLeft
scrollWidth: scrollWidth
scrollWidth: scrollWidth + @gutterWidth
visible: horizontallyScrollable and not @refreshingScrollbars and not @measuringScrollbars
scrollableInOppositeDirection: verticallyScrollable
verticalScrollbarWidth: verticalScrollbarWidth
horizontalScrollbarHeight: horizontalScrollbarHeight
# Also used to measure the height/width of scrollbars after the initial render
ScrollbarCornerComponent
ref: 'scrollbarCorner'
visible: not @refreshingScrollbars and (@measuringScrollbars or horizontallyScrollable and verticallyScrollable)
measuringScrollbars: @measuringScrollbars
height: horizontalScrollbarHeight
width: verticalScrollbarWidth
getRenderedRowRange: ->
renderedRowRange = @props.editor.getVisibleRowRange()
@@ -86,6 +113,8 @@ EditorComponent = React.createClass
@observeEditor()
@listenForDOMEvents()
@listenForCommands()
@measureScrollbars()
@subscribe atom.themes, 'stylesheet-added stylsheet-removed', @onStylesheetsChanged
@props.editor.setVisible(true)
@requestUpdate()
@@ -99,6 +128,8 @@ EditorComponent = React.createClass
componentDidUpdate: ->
@pendingChanges.length = 0
@cursorsMoved = false
@refreshingScrollbars = false
@measureScrollbars() if @measuringScrollbars
@props.parentView.trigger 'editor:display-updated'
observeEditor: ->
@@ -230,6 +261,16 @@ EditorComponent = React.createClass
@subscribe atom.config.observe 'editor.fontSize', @setFontSize
@subscribe atom.config.observe 'editor.showIndentGuide', @setShowIndentGuide
measureScrollbars: ->
@measuringScrollbars = false
{editor} = @props
scrollbarCornerNode = @refs.scrollbarCorner.getDOMNode()
width = (scrollbarCornerNode.offsetWidth - scrollbarCornerNode.clientWidth) or 15
height = (scrollbarCornerNode.offsetHeight - scrollbarCornerNode.clientHeight) or 15
editor.setVerticalScrollbarWidth(width)
editor.setHorizontalScrollbarHeight(height)
setFontSize: (fontSize) ->
@setState({fontSize})
@@ -285,6 +326,35 @@ EditorComponent = React.createClass
event.preventDefault()
onStylesheetsChanged: (stylesheet) ->
# Only update when the scrollbar is changed
return unless @containsScrollbarSelector(stylesheet)
# Believe it or not, proper handling of changes to scrollbar styles requires
# three DOM updates.
# Scrollbar style changes won't apply to scrollbars that are already
# visible, so first we need to hide scrollbars so we can redisplay them and
# force Chromium to apply updates.
@refreshingScrollbars = true
@requestUpdate()
# Next, we display only the scrollbar corner so we can measure the new
# scrollbar dimensions. The ::measuringScrollbars property will be set back
# to false after the scrollbars are measured.
@measuringScrollbars = true
@requestUpdate()
# Finally, we restore the scrollbars based on the newly-measured dimensions
# if the editor's content and dimensions require them to be visible.
@requestUpdate()
containsScrollbarSelector: (stylesheet) ->
for rule in stylesheet.cssRules
if rule.selectorText?.indexOf('scrollbar') > -1
return true
false
clearPreservedRowRange: ->
@preservedRowRange = null
@scrollingVertically = false
@@ -312,10 +382,10 @@ EditorComponent = React.createClass
@requestUpdate() if editor.selectionIntersectsVisibleRowRange(selection)
onScrollTopChanged: ->
@preservedRowRange = @getRenderedRowRange()
# @preservedRowRange = @getRenderedRowRange()
@scrollingVertically = true
@clearPreservedRowRangeAfterDelay ?= debounce(@clearPreservedRowRange, 200)
@clearPreservedRowRangeAfterDelay()
# @clearPreservedRowRangeAfterDelay ?= debounce(@clearPreservedRowRange, 200)
# @clearPreservedRowRangeAfterDelay()
@requestUpdate()
onSelectionRemoved: (selection) ->
@@ -325,6 +395,9 @@ EditorComponent = React.createClass
onCursorsMoved: ->
@cursorsMoved = true
onGutterWidthChanged: (@gutterWidth) ->
@requestUpdate()
requestUpdate: ->
if @batchingUpdates
@updateRequested = true
+8 -6
Ver Arquivo
@@ -182,17 +182,19 @@ EditorScrollViewComponent = React.createClass
measureHeightAndWidth: ->
return unless @isMounted()
node = @getDOMNode()
computedStyle = getComputedStyle(node)
{editor} = @props
node = @getDOMNode()
editorNode = node.parentNode
{position} = getComputedStyle(editorNode)
{width, height} = editorNode.style
unless computedStyle.height is '0px'
clientHeight = node.clientHeight
if position is 'absolute' or height
clientHeight = node.clientHeight
editor.setHeight(clientHeight) if clientHeight > 0
unless computedStyle.width is '0px'
if position is 'absolute' or width
clientWidth = node.clientWidth
editor.setWidth(clientWidth) if clientHeight > 0
editor.setWidth(clientWidth) if clientWidth > 0
focus: ->
@refs.input.focus()
+4 -2
Ver Arquivo
@@ -472,7 +472,7 @@ class EditorView extends View
$(document).off 'mouseup', finalizeSelections
unless @editor.isDestroyed()
@editor.mergeIntersectingSelections(isReversed: @editor.getLastSelection().isReversed())
@editor.mergeIntersectingSelections(reversed: @editor.getLastSelection().isReversed())
@editor.finalizeSelections()
@syncCursorAnimations()
@@ -1482,10 +1482,12 @@ class EditorView extends View
html = @buildEmptyLineHtml(showIndentGuide, eolInvisibles, htmlEolInvisibles, indentation, editor, mini)
line.push(html) if html
else
firstTrailingWhitespacePosition = text.search(/\s*$/)
lineIsWhitespaceOnly = firstTrailingWhitespacePosition is 0
position = 0
for token in tokens
@updateScopeStack(line, scopeStack, token.scopes)
hasIndentGuide = not mini and showIndentGuide
hasIndentGuide = not mini and showIndentGuide and token.hasLeadingWhitespace or (token.hasTrailingWhitespace and lineIsWhitespaceOnly)
line.push(token.getValueAsHtml({invisibles, hasIndentGuide}))
position += token.value.length
+25 -15
Ver Arquivo
@@ -152,7 +152,7 @@ class Editor extends Model
@delegatesProperties '$lineHeight', '$defaultCharWidth', '$height', '$width',
'$scrollTop', '$scrollLeft', 'manageScrollPosition', toProperty: 'displayBuffer'
constructor: ({@softTabs, initialLine, tabLength, softWrap, @displayBuffer, buffer, registerEditor, suppressCursorCreation}) ->
constructor: ({@softTabs, initialLine, initialColumn, tabLength, softWrap, @displayBuffer, buffer, registerEditor, suppressCursorCreation}) ->
super
@cursors = []
@@ -170,11 +170,9 @@ class Editor extends Model
@subscribeToDisplayBuffer()
if @getCursors().length is 0 and not suppressCursorCreation
if initialLine
position = [initialLine, 0]
else
position = [0, 0]
@addCursorAtBufferPosition(position)
initialLine = Math.max(parseInt(initialLine) or 0, 0)
initialColumn = Math.max(parseInt(initialColumn) or 0, 0)
@addCursorAtBufferPosition([initialLine, initialColumn])
@languageMode = new LanguageMode(this)
@@ -410,13 +408,13 @@ class Editor extends Model
saveAs: (filePath) -> @buffer.saveAs(filePath)
checkoutHead: ->
if path = @getPath()
atom.project.getRepo()?.checkoutHead(path)
if filePath = @getPath()
atom.project.getRepo()?.checkoutHead(filePath)
# Copies the current file path to the native clipboard.
copyPathToClipboard: ->
path = @getPath()
atom.clipboard.write(path) if path?
if filePath = @getPath()
atom.clipboard.write(filePath)
# Public: Returns the {String} path of this editor's text buffer.
getPath: -> @buffer.getPath()
@@ -466,7 +464,7 @@ class Editor extends Model
# options - An options hash with an `includeNewline` key.
#
# Returns a {Range}.
bufferRangeForBufferRow: (row, options) -> @buffer.rangeForRow(row, options)
bufferRangeForBufferRow: (row, {includeNewline}={}) -> @buffer.rangeForRow(row, includeNewline)
# Public: Returns a {String} representing the contents of the line at the
# given buffer row.
@@ -895,7 +893,7 @@ class Editor extends Model
endRow = row
insertPosition = Point.fromObject([startRow - insertDelta])
endPosition = Point.min([endRow + 1], @buffer.getEofPosition())
endPosition = Point.min([endRow + 1], @buffer.getEndPosition())
lines = @buffer.getTextInRange([[startRow], endPosition])
if endPosition.row is lastRow and endPosition.column > 0 and not @buffer.lineEndingForRow(endPosition.row)
lines = "#{lines}\n"
@@ -954,7 +952,7 @@ class Editor extends Model
lines = @buffer.getTextInRange([[startRow], endPosition])
@buffer.deleteRows(startRow, endRow)
insertPosition = Point.min([startRow + insertDelta], @buffer.getEofPosition())
insertPosition = Point.min([startRow + insertDelta], @buffer.getEndPosition())
if insertPosition.row is @buffer.getLastRow() and insertPosition.column > 0
lines = "\n#{lines}"
@@ -1483,7 +1481,7 @@ class Editor extends Model
selectToScreenPosition: (position) ->
lastSelection = @getLastSelection()
lastSelection.selectToScreenPosition(position)
@mergeIntersectingSelections(isReversed: lastSelection.isReversed())
@mergeIntersectingSelections(reversed: lastSelection.isReversed())
# Public: Move the cursor of each selection one character rightward while
# preserving the selection's tail position.
@@ -1710,7 +1708,7 @@ class Editor extends Model
# Calls the given function with each selection, then merges selections in the
# reversed orientation
expandSelectionsBackward: (fn) ->
@mergeIntersectingSelections isReversed: true, =>
@mergeIntersectingSelections reversed: true, =>
fn(selection) for selection in @getSelections()
finalizeSelections: ->
@@ -1840,6 +1838,8 @@ class Editor extends Model
setHeight: (height) -> @displayBuffer.setHeight(height)
getHeight: -> @displayBuffer.getHeight()
getClientHeight: -> @displayBuffer.getClientHeight()
setWidth: (width) -> @displayBuffer.setWidth(width)
getWidth: -> @displayBuffer.getWidth()
@@ -1878,6 +1878,16 @@ class Editor extends Model
scrollToBufferPosition: (bufferPosition) -> @displayBuffer.scrollToBufferPosition(bufferPosition)
horizontallyScrollable: -> @displayBuffer.horizontallyScrollable()
verticallyScrollable: -> @displayBuffer.verticallyScrollable()
getHorizontalScrollbarHeight: -> @displayBuffer.getHorizontalScrollbarHeight()
setHorizontalScrollbarHeight: (height) -> @displayBuffer.setHorizontalScrollbarHeight(height)
getVerticalScrollbarWidth: -> @displayBuffer.getVerticalScrollbarWidth()
setVerticalScrollbarWidth: (width) -> @displayBuffer.setVerticalScrollbarWidth(width)
# Deprecated: Call {::joinLines} instead.
joinLine: ->
deprecate("Use Editor::joinLines() instead")
+6 -3
Ver Arquivo
@@ -135,6 +135,7 @@ class Git
relativePath = @relativize(path)
currentPathStatus = @statuses[relativePath] ? 0
pathStatus = repo.getStatus(repo.relativize(path)) ? 0
pathStatus = 0 if repo.isStatusIgnored(pathStatus)
if pathStatus > 0
@statuses[relativePath] = pathStatus
else
@@ -344,8 +345,10 @@ class Git
# Refreshes the current git status in an outside process and asynchronously
# updates the relevant properties.
refreshStatus: ->
handlerPath = require.resolve('./repository-status-handler')
@statusTask = Task.once handlerPath, @getPath(), ({statuses, upstream, branch, submodules}) =>
@handlerPath ?= require.resolve('./repository-status-handler')
@statusTask?.terminate()
@statusTask = Task.once @handlerPath, @getPath(), ({statuses, upstream, branch, submodules}) =>
statusesUnchanged = _.isEqual(statuses, @statuses) and
_.isEqual(upstream, @upstream) and
_.isEqual(branch, @branch) and
@@ -357,6 +360,6 @@ class Git
@submodules = submodules
for submodulePath, submoduleRepo of @getRepo().submodules
submoduleRepo.upstream = submodules[submodulePath].upstream
submoduleRepo.upstream = submodules[submodulePath]?.upstream ? {ahead: 0, behind: 0}
@emit 'statuses-changed' unless statusesUnchanged
+19 -15
Ver Arquivo
@@ -8,18 +8,19 @@ GutterComponent = React.createClass
displayName: 'GutterComponent'
mixins: [SubscriberMixin]
lastMeasuredWidth: null
render: ->
div className: 'gutter',
@renderLineNumbers() if @isMounted()
renderLineNumbers: ->
{editor, renderedRowRange, scrollTop, scrollHeight} = @props
{editor, renderedRowRange, maxLineNumberDigits, scrollTop, scrollHeight} = @props
[startRow, endRow] = renderedRowRange
charWidth = editor.getDefaultCharWidth()
lineHeight = editor.getLineHeight()
maxDigits = editor.getLastBufferRow().toString().length
style =
width: charWidth * (maxDigits + 1.5)
width: charWidth * (maxLineNumberDigits + 1.5)
height: scrollHeight
WebkitTransform: "translate3d(0, #{-scrollTop}px, 0)"
@@ -33,30 +34,33 @@ GutterComponent = React.createClass
lastBufferRow = bufferRow
lineNumber = (bufferRow + 1).toString()
key = tokenizedLines[i]?.id
key = tokenizedLines[i].id
screenRow = startRow + i
lineNumbers.push(LineNumberComponent({key, lineNumber, maxDigits, bufferRow, screenRow, lineHeight}))
lineNumbers.push(LineNumberComponent({key, lineNumber, maxLineNumberDigits, bufferRow, screenRow, lineHeight}))
lastBufferRow = bufferRow
div className: 'line-numbers', style: style,
lineNumbers
componentWillUnmount: ->
@unsubscribe()
# Only update the gutter if the visible row range has changed or if a
# non-zero-delta change to the screen lines has occurred within the current
# visible row range.
shouldComponentUpdate: (newProps) ->
{renderedRowRange, pendingChanges, scrollTop} = @props
return true unless isEqualForProperties(newProps, @props, 'renderedRowRange', 'scrollTop', 'lineHeight')
return true unless isEqualForProperties(newProps, @props, 'renderedRowRange', 'scrollTop', 'lineHeight', 'fontSize')
{renderedRowRange, pendingChanges} = newProps
for change in pendingChanges when change.screenDelta > 0 or change.bufferDelta > 0
return true unless change.end <= renderedRowRange.start or renderedRowRange.end <= change.start
false
componentDidUpdate: (oldProps) ->
unless @lastMeasuredWidth? and isEqualForProperties(oldProps, @props, 'maxLineNumberDigits', 'fontSize', 'fontFamily')
width = @getDOMNode().offsetWidth
if width isnt @lastMeasuredWidth
@lastMeasuredWidth = width
@props.onWidthChanged(width)
LineNumberComponent = React.createClass
displayName: 'LineNumberComponent'
@@ -70,9 +74,9 @@ LineNumberComponent = React.createClass
dangerouslySetInnerHTML: {__html: @buildInnerHTML()}
buildInnerHTML: ->
{lineNumber, maxDigits} = @props
if lineNumber.length < maxDigits
padding = multiplyString('&nbsp;', maxDigits - lineNumber.length)
{lineNumber, maxLineNumberDigits} = @props
if lineNumber.length < maxLineNumberDigits
padding = multiplyString('&nbsp;', maxLineNumberDigits - lineNumber.length)
padding + lineNumber + @iconDivHTML
else
lineNumber + @iconDivHTML
@@ -80,4 +84,4 @@ LineNumberComponent = React.createClass
iconDivHTML: '<div class="icon-right"></div>'
shouldComponentUpdate: (newProps) ->
not isEqualForProperties(newProps, @props, 'lineHeight', 'screenRow')
not isEqualForProperties(newProps, @props, 'lineHeight', 'screenRow', 'maxLineNumberDigits')
+2 -1
Ver Arquivo
@@ -60,7 +60,8 @@ class LanguageMode
buffer.setTextInRange([[end, endColumn], [end, endLength]], "")
else
buffer.transact ->
buffer.insert([start, 0], commentStartString)
indentLength = buffer.lineForRow(start).match(/^\s*/)?[0].length ? 0
buffer.insert([start, indentLength], commentStartString)
buffer.insert([end, buffer.lineLengthForRow(end)], commentEndString)
else
if shouldUncomment and start isnt end
+79 -53
Ver Arquivo
@@ -1,7 +1,8 @@
React = require 'react'
{div, span} = require 'reactionary'
{debounce, isEqual, isEqualForProperties, multiplyString} = require 'underscore-plus'
{debounce, isEqual, isEqualForProperties, multiplyString, toArray} = require 'underscore-plus'
{$$} = require 'space-pen'
EditorView = require './editor-view'
DummyLineNode = $$(-> @div className: 'line', style: 'position: absolute; visibility: hidden;', => @span 'x')[0]
AcceptFilter = {acceptNode: -> NodeFilter.FILTER_ACCEPT}
@@ -11,15 +12,7 @@ LinesComponent = React.createClass
displayName: 'LinesComponent'
render: ->
if @isMounted()
{editor, renderedRowRange, lineHeight, showIndentGuide} = @props
[startRow, endRow] = renderedRowRange
lines =
for tokenizedLine, i in editor.linesForScreenRows(startRow, endRow - 1)
LineComponent({key: tokenizedLine.id, tokenizedLine, showIndentGuide, lineHeight, screenRow: startRow + i})
div {className: 'lines'}, lines
div className: 'lines'
componentWillMount: ->
@measuredLines = new WeakSet
@@ -37,9 +30,14 @@ LinesComponent = React.createClass
false
componentDidUpdate: (prevProps) ->
if not prevProps.renderedRowRange? or prevProps.lineHeight isnt @props.lineHeight
@renderLines()
else
@updateRenderedLines(prevProps.renderedRowRange)
@measureLineHeightAndCharWidth() unless isEqualForProperties(prevProps, @props, 'fontSize', 'fontFamily', 'lineHeight')
@clearScopedCharWidths() unless isEqualForProperties(prevProps, @props, 'fontSize', 'fontFamily')
@measureCharactersInNewLines() unless @props.scrollingVertically
# @clearScopedCharWidths() unless isEqualForProperties(prevProps, @props, 'fontSize', 'fontFamily')
# @measureCharactersInNewLines() unless @props.scrollingVertically
measureLineHeightAndCharWidth: ->
node = @getDOMNode()
@@ -52,6 +50,75 @@ LinesComponent = React.createClass
editor.setLineHeight(lineHeight)
editor.setDefaultCharWidth(charWidth)
renderLines: ->
[startRow, endRow] = @props.renderedRowRange
@getDOMNode().innerHTML = @buildHTMLForScreenRowRange(startRow, endRow)
updateRenderedLines: (oldRenderedRowRange) ->
[oldStartRow, oldEndRow] = oldRenderedRowRange
[newStartRow, newEndRow] = @props.renderedRowRange
node = @getDOMNode()
if newEndRow <= oldStartRow or newStartRow >= oldEndRow
@renderLines()
return
if newEndRow > oldEndRow
for lineNode in @buildLineNodesForScreenRowRange(oldEndRow, newEndRow)
node.appendChild(lineNode)
else if newEndRow < oldEndRow
extraLineCount = oldEndRow - newEndRow
while extraLineCount > 0
node.removeChild(node.lastChild)
extraLineCount--
if newStartRow < oldStartRow
oldFirstLineNode = node.firstChild
for lineNode in @buildLineNodesForScreenRowRange(newStartRow, Math.min(newEndRow, oldStartRow))
node.insertBefore(lineNode, oldFirstLineNode)
else if newStartRow > oldStartRow
extraLineCount = newStartRow - oldStartRow
while extraLineCount > 0
node.removeChild(node.firstChild)
extraLineCount--
buildLineNodesForScreenRowRange: (startRow, endRow) ->
wrapper = document.createElement('div')
wrapper.innerHTML = @buildHTMLForScreenRowRange(startRow, endRow)
toArray(wrapper.children)
buildHTMLForScreenRowRange: (startRow, endRow) ->
{editor} = @props
linesHTML = ""
for tokenizedLine, i in editor.linesForScreenRows(startRow, endRow - 1)
linesHTML += @buildHTMLForTokenizedLine(tokenizedLine, startRow + i)
linesHTML
buildHTMLForTokenizedLine: (screenLine, screenRow) ->
{tokens, text, lineEnding, fold, isSoftWrapped} = screenLine
{editor, lineHeight, showIndentGuide, mini} = @props
attributes =
class: "line"
style: "-webkit-transform: translate3d(0, #{screenRow * lineHeight}px, 0)"
if fold
attributes.class += " fold"
attributes['fold-id'] = fold.id
# invisibles = @invisibles if @showInvisibles
# eolInvisibles = @getEndOfLineInvisibles(screenLine)
# htmlEolInvisibles = @buildHtmlEndOfLineInvisibles(screenLine)
invisibles = {}
eolInvisibles = {}
htmlEolInvisibles = ""
indentation = EditorView.buildIndentation(screenRow, editor)
EditorView.buildLineHtml({tokens, text, lineEnding, fold, isSoftWrapped, invisibles, eolInvisibles, htmlEolInvisibles, attributes, showIndentGuide, indentation, editor, mini})
measureCharactersInNewLines: ->
[visibleStartRow, visibleEndRow] = @props.renderedRowRange
node = @getDOMNode()
@@ -97,44 +164,3 @@ LinesComponent = React.createClass
clearScopedCharWidths: ->
@measuredLines.clear()
@props.editor.clearScopedCharWidths()
LineComponent = React.createClass
displayName: 'LineComponent'
render: ->
{screenRow, lineHeight} = @props
style =
top: screenRow * lineHeight
position: 'absolute'
div className: 'line', style: style, 'data-screen-row': screenRow, dangerouslySetInnerHTML: {__html: @buildInnerHTML()}
buildInnerHTML: ->
if @props.tokenizedLine.text.length is 0
@buildEmptyLineHTML()
else
@buildScopeTreeHTML(@props.tokenizedLine.getScopeTree())
buildEmptyLineHTML: ->
{showIndentGuide, tokenizedLine} = @props
{indentLevel, tabLength} = tokenizedLine
if showIndentGuide and indentLevel > 0
indentSpan = "<span class='indent-guide'>#{multiplyString(' ', tabLength)}</span>"
multiplyString(indentSpan, indentLevel + 1)
else
"&nbsp;"
buildScopeTreeHTML: (scopeTree) ->
if scopeTree.children?
html = "<span class='#{scopeTree.scope.replace(/\./g, ' ')}'>"
html += @buildScopeTreeHTML(child) for child in scopeTree.children
html += "</span>"
html
else
"<span>#{scopeTree.getValueAsHtml({hasIndentGuide: @props.showIndentGuide})}</span>"
shouldComponentUpdate: (newProps) ->
not isEqualForProperties(newProps, @props, 'showIndentGuide', 'lineHeight', 'screenRow')
+1 -1
Ver Arquivo
@@ -112,7 +112,7 @@ class MenuManager
sendToBrowserProcess: (template, keystrokesByCommand) ->
keystrokesByCommand = @filterMultipleKeystroke(keystrokesByCommand)
ipc.sendChannel 'update-application-menu', template, keystrokesByCommand
ipc.send 'update-application-menu', template, keystrokesByCommand
normalizeLabel: (label) ->
return undefined unless label?
+6 -4
Ver Arquivo
@@ -27,10 +27,12 @@ module.exports =
class PackageManager
Emitter.includeInto(this)
constructor: ({configDirPath, devMode, @resourcePath}) ->
@packageDirPaths = [path.join(configDirPath, "packages")]
if devMode
@packageDirPaths.unshift(path.join(configDirPath, "dev", "packages"))
constructor: ({configDirPath, devMode, safeMode, @resourcePath}) ->
@packageDirPaths = []
unless safeMode
if devMode
@packageDirPaths.push(path.join(configDirPath, "dev", "packages"))
@packageDirPaths.push(path.join(configDirPath, "packages"))
@loadedPackages = {}
@activePackages = {}
+1 -1
Ver Arquivo
@@ -103,7 +103,7 @@ class PaneView extends View
# Deprecated: Use ::activateNextItem
showNextItem: ->
deprecate("Use PaneView::destroyItem instead")
deprecate("Use PaneView::activateNextItem instead")
@activateNextItem()
# Deprecated: Use ::activatePreviousItem
+13 -5
Ver Arquivo
@@ -339,18 +339,26 @@ class Pane extends Model
newPane.activate()
newPane
# If the parent is a horizontal axis, returns its first child;
# otherwise this pane.
# If the parent is a horizontal axis, returns its first child if it is a pane;
# otherwise returns this pane.
findLeftmostSibling: ->
if @parent.orientation is 'horizontal'
@parent.children[0]
[leftmostSibling] = @parent.children
if leftmostSibling instanceof PaneAxis
this
else
leftmostSibling
else
this
# If the parent is a horizontal axis, returns its last child;
# If the parent is a horizontal axis, returns its last child if it is a pane;
# otherwise returns a new pane created by splitting this pane rightward.
findOrCreateRightmostSibling: ->
if @parent.orientation is 'horizontal'
last(@parent.children)
rightmostSibling = last(@parent.children)
if rightmostSibling instanceof PaneAxis
@splitRight()
else
rightmostSibling
else
@splitRight()
+1 -2
Ver Arquivo
@@ -165,9 +165,8 @@ class Project extends Model
bufferForId: (id) ->
_.find @buffers, (buffer) -> buffer.id is id
# DEPRECATED
# Still needed when deserializing a tokenized buffer
buildBufferSync: (absoluteFilePath) ->
deprecate("Use Project::buildBuffer instead")
buffer = new TextBuffer({filePath: absoluteFilePath})
@addBuffer(buffer)
buffer.loadSync()
+18 -5
Ver Arquivo
@@ -1,13 +1,24 @@
React = require 'react'
{div} = require 'reactionary'
{isEqualForProperties} = require 'underscore-plus'
{extend, isEqualForProperties} = require 'underscore-plus'
module.exports =
ScrollbarComponent = React.createClass
render: ->
{orientation, className, scrollHeight, scrollWidth} = @props
{orientation, className, scrollHeight, scrollWidth, visible} = @props
{scrollableInOppositeDirection, horizontalScrollbarHeight, verticalScrollbarWidth} = @props
div {className, @onScroll},
style = {}
style.display = 'none' unless visible
switch orientation
when 'vertical'
style.width = verticalScrollbarWidth
style.bottom = horizontalScrollbarHeight if scrollableInOppositeDirection
when 'horizontal'
style.height = horizontalScrollbarHeight
style.right = verticalScrollbarWidth if scrollableInOppositeDirection
div {className, style, @onScroll},
switch orientation
when 'vertical'
div className: 'scrollbar-content', style: {height: scrollHeight}
@@ -21,11 +32,13 @@ ScrollbarComponent = React.createClass
throw new Error("Must specify an orientation property of 'vertical' or 'horizontal'")
shouldComponentUpdate: (newProps) ->
return true if newProps.visible isnt @props.visible
switch @props.orientation
when 'vertical'
not isEqualForProperties(newProps, @props, 'scrollHeight', 'scrollTop')
not isEqualForProperties(newProps, @props, 'scrollHeight', 'scrollTop', 'scrollableInOppositeDirection')
when 'horizontal'
not isEqualForProperties(newProps, @props, 'scrollWidth', 'scrollLeft')
not isEqualForProperties(newProps, @props, 'scrollWidth', 'scrollLeft', 'scrollableInOppositeDirection')
componentDidUpdate: ->
{orientation, scrollTop, scrollLeft} = @props
+18
Ver Arquivo
@@ -0,0 +1,18 @@
React = require 'react'
{div} = require 'reactionary'
module.exports =
ScrollbarComponent = React.createClass
render: ->
{visible, measuringScrollbars, width, height} = @props
if measuringScrollbars
height = 25
width = 25
display = 'none' unless visible
div className: 'scrollbar-corner', style: {display, width, height},
div style:
height: height + 1
width: width + 1
+2 -2
Ver Arquivo
@@ -150,7 +150,7 @@ class Selection extends Model
@modifySelection =>
if @initialScreenRange
if position.isLessThan(@initialScreenRange.start)
@marker.setScreenRange([position, @initialScreenRange.end], isReversed: true)
@marker.setScreenRange([position, @initialScreenRange.end], reversed: true)
else
@marker.setScreenRange([@initialScreenRange.start, position])
else
@@ -298,7 +298,7 @@ class Selection extends Model
newBufferRange = @editor.buffer.setTextInRange(oldBufferRange, text, pick(options, 'undo'))
if options.select
@setBufferRange(newBufferRange, isReversed: wasReversed)
@setBufferRange(newBufferRange, reversed: wasReversed)
else
@cursor.setBufferPosition(newBufferRange.end, skipAtomicTokens: true) if wasReversed
+16 -8
Ver Arquivo
@@ -158,10 +158,10 @@ class ThemeManager
# load path.
#
# Returns the absolute path to the required stylesheet.
requireStylesheet: (stylesheetPath, ttype = 'bundled', htmlElement) ->
requireStylesheet: (stylesheetPath, type = 'bundled', htmlElement) ->
if fullPath = @resolveStylesheet(stylesheetPath)
content = @loadStylesheet(fullPath)
@applyStylesheet(fullPath, content, ttype = 'bundled', htmlElement)
@applyStylesheet(fullPath, content, type = 'bundled', htmlElement)
else
throw new Error("Could not find a file at path '#{stylesheetPath}'")
@@ -192,16 +192,24 @@ class ThemeManager
removeStylesheet: (stylesheetPath) ->
fullPath = @resolveStylesheet(stylesheetPath) ? stylesheetPath
@stylesheetElementForId(@stringToId(fullPath)).remove()
@emit 'stylesheets-changed'
element = @stylesheetElementForId(@stringToId(fullPath))
if element.length > 0
stylesheet = element[0].sheet
element.remove()
@emit 'stylesheet-removed', stylesheet
@emit 'stylesheets-changed'
applyStylesheet: (path, text, ttype = 'bundled', htmlElement=$('html')) ->
applyStylesheet: (path, text, type = 'bundled', htmlElement=$('html')) ->
styleElement = @stylesheetElementForId(@stringToId(path), htmlElement)
if styleElement.length
@emit 'stylesheet-removed', styleElement[0].sheet
styleElement.text(text)
else
if htmlElement.find("head style.#{ttype}").length
htmlElement.find("head style.#{ttype}:last").after "<style class='#{ttype}' id='#{@stringToId(path)}'>#{text}</style>"
styleElement = $("<style class='#{type}' id='#{@stringToId(path)}'>#{text}</style>")
if htmlElement.find("head style.#{type}").length
htmlElement.find("head style.#{type}:last").after(styleElement)
else
htmlElement.find("head").append "<style class='#{ttype}' id='#{@stringToId(path)}'>#{text}</style>"
htmlElement.find("head").append(styleElement)
@emit 'stylesheet-added', styleElement[0].sheet
@emit 'stylesheets-changed'
+1 -1
Ver Arquivo
@@ -318,7 +318,7 @@ class TokenizedBuffer extends Model
position
findClosingBracket: (startBufferPosition) ->
range = [startBufferPosition, @buffer.getEofPosition()]
range = [startBufferPosition, @buffer.getEndPosition()]
position = null
depth = 0
@iterateTokensInBufferRange range, (token, startPosition, { stop }) ->
+2 -2
Ver Arquivo
@@ -27,9 +27,9 @@ class WindowEventHandler
@subscribe $(window), 'blur', -> $("body").addClass('is-blurred')
@subscribe $(window), 'window:open-path', (event, {pathToOpen, initialLine}) ->
@subscribe $(window), 'window:open-path', (event, {pathToOpen, initialLine, initialColumn}) ->
unless fs.isDirectorySync(pathToOpen)
atom.workspaceView?.open(pathToOpen, {initialLine})
atom.workspace?.open(pathToOpen, {initialLine, initialColumn})
@subscribe $(window), 'beforeunload', =>
confirmed = atom.workspaceView?.confirmClose()
+34 -31
Ver Arquivo
@@ -57,7 +57,7 @@ class WorkspaceView extends View
Delegator.includeInto(this)
@delegatesProperty 'fullScreen', 'destroyedItemUris', toProperty: 'model'
@delegatesMethods 'open', 'openSync', 'reopenItemSync',
@delegatesMethods 'open', 'openSync',
'saveActivePaneItem', 'saveActivePaneItemAs', 'saveAll', 'destroyActivePaneItem',
'destroyActivePane', 'increaseFontSize', 'decreaseFontSize', toProperty: 'model'
@@ -106,33 +106,34 @@ class WorkspaceView extends View
@on 'pane-container:active-pane-item-changed', => @updateTitle()
@on 'pane:active-item-title-changed', '.active.pane', => @updateTitle()
@command 'application:about', -> ipc.sendChannel('command', 'application:about')
@command 'application:run-all-specs', -> ipc.sendChannel('command', 'application:run-all-specs')
@command 'application:run-benchmarks', -> ipc.sendChannel('command', 'application:run-benchmarks')
@command 'application:show-settings', -> ipc.sendChannel('command', 'application:show-settings')
@command 'application:quit', -> ipc.sendChannel('command', 'application:quit')
@command 'application:hide', -> ipc.sendChannel('command', 'application:hide')
@command 'application:hide-other-applications', -> ipc.sendChannel('command', 'application:hide-other-applications')
@command 'application:unhide-all-applications', -> ipc.sendChannel('command', 'application:unhide-all-applications')
@command 'application:new-window', -> ipc.sendChannel('command', 'application:new-window')
@command 'application:new-file', -> ipc.sendChannel('command', 'application:new-file')
@command 'application:open', -> ipc.sendChannel('command', 'application:open')
@command 'application:open-file', -> ipc.sendChannel('command', 'application:open-file')
@command 'application:open-folder', -> ipc.sendChannel('command', 'application:open-folder')
@command 'application:open-dev', -> ipc.sendChannel('command', 'application:open-dev')
@command 'application:minimize', -> ipc.sendChannel('command', 'application:minimize')
@command 'application:zoom', -> ipc.sendChannel('command', 'application:zoom')
@command 'application:bring-all-windows-to-front', -> ipc.sendChannel('command', 'application:bring-all-windows-to-front')
@command 'application:open-your-config', -> ipc.sendChannel('command', 'application:open-your-config')
@command 'application:open-your-init-script', -> ipc.sendChannel('command', 'application:open-your-init-script')
@command 'application:open-your-keymap', -> ipc.sendChannel('command', 'application:open-your-keymap')
@command 'application:open-your-snippets', -> ipc.sendChannel('command', 'application:open-your-snippets')
@command 'application:open-your-stylesheet', -> ipc.sendChannel('command', 'application:open-your-stylesheet')
@command 'application:about', -> ipc.send('command', 'application:about')
@command 'application:run-all-specs', -> ipc.send('command', 'application:run-all-specs')
@command 'application:run-benchmarks', -> ipc.send('command', 'application:run-benchmarks')
@command 'application:show-settings', -> ipc.send('command', 'application:show-settings')
@command 'application:quit', -> ipc.send('command', 'application:quit')
@command 'application:hide', -> ipc.send('command', 'application:hide')
@command 'application:hide-other-applications', -> ipc.send('command', 'application:hide-other-applications')
@command 'application:unhide-all-applications', -> ipc.send('command', 'application:unhide-all-applications')
@command 'application:new-window', -> ipc.send('command', 'application:new-window')
@command 'application:new-file', -> ipc.send('command', 'application:new-file')
@command 'application:open', -> ipc.send('command', 'application:open')
@command 'application:open-file', -> ipc.send('command', 'application:open-file')
@command 'application:open-folder', -> ipc.send('command', 'application:open-folder')
@command 'application:open-dev', -> ipc.send('command', 'application:open-dev')
@command 'application:open-safe', -> ipc.send('command', 'application:open-safe')
@command 'application:minimize', -> ipc.send('command', 'application:minimize')
@command 'application:zoom', -> ipc.send('command', 'application:zoom')
@command 'application:bring-all-windows-to-front', -> ipc.send('command', 'application:bring-all-windows-to-front')
@command 'application:open-your-config', -> ipc.send('command', 'application:open-your-config')
@command 'application:open-your-init-script', -> ipc.send('command', 'application:open-your-init-script')
@command 'application:open-your-keymap', -> ipc.send('command', 'application:open-your-keymap')
@command 'application:open-your-snippets', -> ipc.send('command', 'application:open-your-snippets')
@command 'application:open-your-stylesheet', -> ipc.send('command', 'application:open-your-stylesheet')
@command 'application:open-license', => @model.openLicense()
@command 'window:install-shell-commands', => @installShellCommands()
@command 'window:run-package-specs', => ipc.sendChannel('run-package-specs', path.join(atom.project.getPath(), 'spec'))
@command 'window:run-package-specs', -> ipc.send('run-package-specs', path.join(atom.project.getPath(), 'spec'))
@command 'window:increase-font-size', => @increaseFontSize()
@command 'window:decrease-font-size', => @decreaseFontSize()
@command 'window:reset-font-size', => @model.resetFontSize()
@@ -147,10 +148,10 @@ class WorkspaceView extends View
@command 'window:toggle-invisibles', -> atom.config.toggle("editor.showInvisibles")
@command 'window:log-deprecation-warnings', -> logDeprecationWarnings()
@command 'window:toggle-auto-indent', =>
@command 'window:toggle-auto-indent', ->
atom.config.toggle("editor.autoIndent")
@command 'pane:reopen-closed-item', => @reopenItemSync()
@command 'pane:reopen-closed-item', => @getModel().reopenItem()
@command 'core:close', => if @getModel().getActivePaneItem()? then @destroyActivePaneItem() else @destroyActivePane()
@command 'core:save', => @saveActivePaneItem()
@@ -170,11 +171,11 @@ class WorkspaceView extends View
detailedMessage: error.message
resourcePath = atom.getLoadSettings().resourcePath
CommandInstaller.installAtomCommand resourcePath, true, (error) =>
CommandInstaller.installAtomCommand resourcePath, true, (error) ->
if error?
showErrorDialog(error)
else
CommandInstaller.installApmCommand resourcePath, true, (error) =>
CommandInstaller.installApmCommand resourcePath, true, (error) ->
if error?
showErrorDialog(error)
else
@@ -320,15 +321,17 @@ class WorkspaceView extends View
@panes.getPaneViews()
# Public: Register a function to be called for every current and future
# editor view in the workspace.
# editor view in the workspace (only includes {EditorView}s that are pane
# items).
#
# callback - A {Function} with an {EditorView} as its only argument.
#
# Returns a subscription object with an `.off` method that you can call to
# unregister the callback.
eachEditorView: (callback) ->
callback(editor) for editor in @getEditorViews()
attachedCallback = (e, editor) -> callback(editor)
callback(editorView) for editorView in @getEditorViews()
attachedCallback = (e, editorView) ->
callback(editorView) unless editorView.mini
@on('editor:attached', attachedCallback)
off: => @off('editor:attached', attachedCallback)
+18 -4
Ver Arquivo
@@ -84,6 +84,8 @@ class Workspace extends Model
# options - An optional options {Object}
# :initialLine - A {Number} indicating which row to move the cursor to
# initially. Defaults to `0`.
# :initialColumn - A {Number} indicating which column to move the cursor to
# initially. Defaults to `0`.
# :split - Either 'left' or 'right'. If 'left', the item will be opened in
# leftmost pane of the current active pane's row. If 'right', the
# item will be opened in the rightmost pane of the current active
@@ -114,7 +116,7 @@ class Workspace extends Model
# Public: Open Atom's license in the active pane.
openLicense: ->
@open(join(atom.getLoadSettings().resourcePath, 'LICENSE'))
@open(join(atom.getLoadSettings().resourcePath, 'LICENSE.md'))
# Synchronously open the given URI in the active pane. **Only use this method
# in specs. Calling this in production code will block the UI thread and
@@ -124,12 +126,14 @@ class Workspace extends Model
# options - An optional options {Object}
# :initialLine - A {Number} indicating which row to move the cursor to
# initially. Defaults to `0`.
# :initialColumn - A {Number} indicating which column to move the cursor to
# initially. Defaults to `0`.
# :activatePane - A {Boolean} indicating whether to call {Pane::activate} on
# the containing pane. Defaults to `true`.
openSync: (uri='', options={}) ->
deprecate("Don't use the `changeFocus` option") if options.changeFocus?
{initialLine} = options
{initialLine, initialColumn} = options
# TODO: Remove deprecated changeFocus option
activatePane = options.activatePane ? options.changeFocus ? true
uri = atom.project.resolve(uri)
@@ -137,7 +141,7 @@ class Workspace extends Model
item = @activePane.itemForUri(uri)
if uri
item ?= opener(uri, options) for opener in @getOpeners() when !item
item ?= atom.project.openSync(uri, {initialLine})
item ?= atom.project.openSync(uri, {initialLine, initialColumn})
@activePane.activateItem(item)
@itemOpened(item)
@@ -165,9 +169,19 @@ class Workspace extends Model
.catch (error) ->
console.error(error.stack ? error)
# Public: Reopen the last-closed item's URI if it hasn't already been
# Public: Asynchronously reopens the last-closed item's URI if it hasn't already been
# reopened.
#
# Returns a promise that is resolved when the item is opened
reopenItem: ->
if uri = @destroyedItemUris.pop()
@open(uri)
else
Q()
# Deprecated
reopenItemSync: ->
deprecate("Use Workspace::reopenItem instead")
if uri = @destroyedItemUris.pop()
@openSync(uri)
+15
Ver Arquivo
@@ -14,6 +14,10 @@
.lines {
z-index: -1;
.line {
position: absolute;
}
}
.horizontal-scrollbar {
@@ -32,6 +36,17 @@
}
}
.vertical-scrollbar {
overflow-x: hidden;
}
.scrollbar-corner {
position: absolute;
overflow: auto;
bottom: 0;
right: 0;
}
.scroll-view {
overflow: hidden;
}
externo
-1
Submodule vendor/apm deleted from d349e45263