Comparar commits

...

106 Commits

Autor SHA1 Mensagem Data
Corey Johnson & Kevin Sawicki b56f4a129f Mention fixed freeze 2013-04-29 12:15:10 -07:00
Corey Johnson & Kevin Sawicki 0d8a6782b3 Stop tokenizing line when the same rule is pushed more than once
Previously Rails classes would infinitly loop if the Ruby on Rails
grammar was loaded but the Ruby grammar had not been. This occurred
because a rule was continually pushing itself on the stack but never
advancing.

Now if the position does not advance and the last two rules in the
stack have the same scope the last rule is popped and the entire line
is tokenized with the current scopes.

Closes #524 #486
2013-04-29 12:10:40 -07:00
Corey Johnson fe219ed159 💄 2013-04-29 12:10:40 -07:00
probablycorey 6ee24cc50e 💄 2013-04-29 12:10:40 -07:00
Kevin Sawicki 5a84814e27 Undasherize the namespace when no event exists
This would present the new-window event as "New Window"
instead of "New-window".
2013-04-29 10:49:31 -07:00
Kevin Sawicki 994138c7a6 Mention meta-N command 2013-04-29 10:29:46 -07:00
Kevin Sawicki df6809e705 Bind meta-N to open a new untitled editor 2013-04-29 10:27:39 -07:00
Kevin Sawicki 71aa9802d5 Move default keys from keymap.coffee to atom.cson 2013-04-29 10:11:21 -07:00
Kevin Sawicki 8b98a7793d Include Java grammar in fenced code blocks 2013-04-28 06:50:03 -07:00
Kevin Sawicki b4cbffd978 Wait for execute promise to prevent leaking subscriptions 2013-04-27 07:58:56 -07:00
Kevin Sawicki 53dde09523 Mark config panels as internal
The doc spec was failing since these classes were added with
no docs and weren't marked as internal so the coverage dropped
below 80%.
2013-04-27 07:40:06 -07:00
Kevin Sawicki 8af73449fe Set no max width on img elements in image view 2013-04-27 07:21:23 -07:00
Kevin Sawicki d2b513bd5e Bind meta-_ to zoom out in image view 2013-04-27 07:19:34 -07:00
Kevin Sawicki c54766a08a Don't show indent guide in mini editor 2013-04-26 17:31:54 -07:00
probablycorey 8a7aa8083c Add show inded guide 2013-04-26 15:36:58 -07:00
probablycorey d1a26b9f81 Style editors like input fields 2013-04-26 15:36:58 -07:00
probablycorey 655fec2f18 Redraw editors when panel appears
If not done, the editors have zero height.
2013-04-26 15:36:58 -07:00
probablycorey 2d5bb8bd8b Move open .atom button to config menu 2013-04-26 15:36:58 -07:00
probablycorey bd7542cb0a Use mini-editors instead of inputs 2013-04-26 15:36:58 -07:00
probablycorey f06c9a5bc8 Don't respond to observe events when the editor value doesn't change 2013-04-26 15:36:58 -07:00
probablycorey 9f85ba4f7d Empty editors trigger config to delete the associated config key 2013-04-26 15:36:58 -07:00
Corey Johnson & Nathan Sobo b878be27a0 Revert to default font when setFontFamily is set to null/undefined 2013-04-26 15:36:58 -07:00
Corey Johnson & Nathan Sobo 1b98bf706e Setting value to null/undefined removes key from config 2013-04-26 15:36:58 -07:00
Corey Johnson & Nathan Sobo c923b561e2 💄 2013-04-26 15:36:57 -07:00
probablycorey e72e1c9c56 Remove log 2013-04-26 15:36:57 -07:00
probablycorey ecad6bc2a8 Don't allow float or int Editor's to have NaN as a value 2013-04-26 15:36:57 -07:00
probablycorey cedea831f7 Config panel handles binding for Editors 2013-04-26 15:36:57 -07:00
probablycorey 1b4fbdb065 Allow html attributes to be applied to Editors 2013-04-26 15:36:57 -07:00
Corey Johnson & Nathan Sobo c5cd39308d Add "open .atom" button to general config view 2013-04-26 15:36:57 -07:00
Nathan Sobo 083e6f26bd Style the general config panel w/ bootstrap 2013-04-26 15:36:57 -07:00
Nathan Sobo 15f95cb2a3 Add some explanatory text about cascading themes 2013-04-26 15:36:57 -07:00
Nathan Sobo b6d1f37249 Make theme name text non-selectable 2013-04-26 15:36:14 -07:00
Nathan Sobo 232978ea9d Themes can be disabled by clicking their 'x' icon in the enabled list 2013-04-26 15:36:14 -07:00
Nathan Sobo 5afe0a758c Allow stylesheets with ' characters in their filename 2013-04-26 15:36:14 -07:00
Nathan Sobo d3fa5b0f85 🙊 2013-04-26 15:36:13 -07:00
Nathan Sobo ad0bcc3851 Update enabled themes list when config key is updated 2013-04-26 15:36:13 -07:00
Nathan Sobo b110f430ee Update 'config.themes' config key when enabled themes list is sorted 2013-04-26 15:36:13 -07:00
Nathan Sobo 7993e3ab39 WIP: don't allow duplicates to be dragged 2013-04-26 15:36:13 -07:00
Nathan Sobo 540c543984 Add a styled but non-functional themes config panel 2013-04-26 15:36:13 -07:00
Nathan Sobo af02d9f0fd Use config defaults to default themes to atom-dark-* 2013-04-26 15:36:13 -07:00
Nathan Sobo 36d0b2c735 No need for jQuery UI in package config panel 2013-04-26 15:36:13 -07:00
Nathan Sobo 7518864938 Set initial size of config window to 800x600 2013-04-26 15:36:13 -07:00
Nathan Sobo 2d00d3e07e Import variables.less into config.less so it can be compiled alone
We try to compile all stylesheets across the board, but now many of
our stylesheets are imported into a master `atom.less` stylesheet. The
config stylesheet would compile fine when included from `atom.less`,
but alone it fails because it doesn't have the variables. We should
probably only try to pre-compile stylesheets we intend to require
directly… using a manifest maybe?
2013-04-26 15:36:13 -07:00
Nathan Sobo 0d520e9930 Add a package config panel with the list of enabled packages 2013-04-26 15:36:13 -07:00
Nathan Sobo b70ff1b164 Don't assign window.jQuery in jasmine-jquery.js helper
I wrap it in a function wrapper to ensure that the assignment
`var jQuery` doesn't end up assigning a window global.
2013-04-26 15:36:13 -07:00
Nathan Sobo ba6d3a1124 Use bootstrap to style editor config panel 2013-04-26 15:36:13 -07:00
Nathan Sobo ac65e288df Pull config stylesheet into atom.less 2013-04-26 15:36:12 -07:00
Nathan Sobo c5e34c60f8 Don't explode if 'core.themes' config key is undefined 2013-04-26 15:36:12 -07:00
Nathan Sobo 5a291e8188 Use bootstrap stacked nav-pills for panels menu in config window 2013-04-26 15:36:12 -07:00
Nathan Sobo ab5156c5e3 Clear out some styling cruft that will be replaced by bootstrap stuff 2013-04-26 15:36:12 -07:00
Nathan Sobo 360a3076a8 Fix jqueryui-browser npm version 2013-04-26 15:36:12 -07:00
Nathan Sobo 0af9564d1a Styling 💄 2013-04-26 15:36:12 -07:00
Nathan Sobo 21f83ea938 Add 'x' icon to enabled themes list 2013-04-26 15:36:12 -07:00
Nathan Sobo 81c1769770 Allow available themes to be dragged to sortable 'enabled themes' list
Still not doing anything with the sort update events.
2013-04-26 15:36:12 -07:00
Nathan Sobo 0620d19f26 Require jquery-ui-sortable and -draggable in the general config panel.
This commit has a hack to make window.jQuery available during the
duration of the requiring of jquery-ui. Once we're done requiring
jQuery, the global is removed from window once again.

Issue #494 has an alternative idea of enhancing require to allow the
requiring script to specify the value of global variables in the script
being required.
2013-04-26 15:36:12 -07:00
Nathan Sobo 46acb6da2c Style themes and packages lists 2013-04-26 15:36:12 -07:00
Nathan Sobo e8a66ded01 🙊 2013-04-26 15:36:12 -07:00
Nathan Sobo c90579956f Un-f 2013-04-26 15:36:11 -07:00
Nathan Sobo d857cc7d77 List available themes in general config panel 2013-04-26 15:36:11 -07:00
Nathan Sobo 495230435f Allow packages to be enabled / disabled from general config panel 2013-04-26 15:36:11 -07:00
Nathan Sobo 707ed3c51a Make config panels to scroll vertically if needed 2013-04-26 15:36:11 -07:00
Nathan Sobo 027bada7d5 Add editor.nonWordCharacters to editor config panel 2013-04-26 15:36:11 -07:00
Nathan Sobo 58add85f09 Add editor.showLineNumbers option 2013-04-26 15:36:11 -07:00
Nathan Sobo 7359101bac Add core.hideGitIgnoredFiles option 2013-04-26 15:36:11 -07:00
Nathan Sobo 4e787ceb43 Fix typo 2013-04-26 15:36:11 -07:00
Nathan Sobo ff76911e4c Move autosave to general config panel 2013-04-26 15:36:11 -07:00
Nathan Sobo f0cddf9f32 Serialize the state of the config window on refresh 2013-04-26 15:36:11 -07:00
Nathan Sobo c32c894d23 Add more editor config properties 2013-04-26 15:34:48 -07:00
Nathan Sobo 422d89a7ed Handle checkbox fields in config panel 2013-04-26 15:34:48 -07:00
Nathan Sobo 5e0dd80366 Remove overkill assertions 2013-04-26 15:34:48 -07:00
Nathan Sobo bfbdfb46a8 Use id instead of name for config key path 2013-04-26 15:32:48 -07:00
Nathan Sobo 91e3fbd2d8 Allow native event handling for non-editor input elements
This allows arrow keys, tab, etc. to work properly inside input
elements.
2013-04-26 15:32:48 -07:00
Nathan Sobo 6c640133f1 Add 'native!' keymap override to let the browser handle the keystroke
This allows us to selectively opt out of handling key events with the
keymap for certain elements. In particular, it will be useful for
allowing the standard native behavior in input elements by overriding
global bindings for arrow keys, backspace, etc.
2013-04-26 15:32:47 -07:00
Nathan Sobo bb287cb465 Add ConfigPanel superclass that can bind fields to config values
When you give a config field a `name` attribute based on a config key
path, such as 'editor.fontSize', it is automatically kept in sync with
the config value. You can also specify a `type` attribute of 'int' or
'float' to automatically convert the field value to a numeric type.
Specifying a type of 'string' is optional to signal no conversion.
2013-04-26 15:32:47 -07:00
Nathan Sobo 252159afcf Add super basic styling to config view and 2 non-functional panels 2013-04-26 15:32:47 -07:00
Nathan Sobo 6c43fd5c9d Set up dev tools event handler when binding default keys 2013-04-26 15:32:47 -07:00
Nathan Sobo 2f60ffcfce Add ability to add panels to the config view 2013-04-26 15:32:47 -07:00
Nathan Sobo 8980a97895 Add atom.activatePackageConfig, which is called in config windows
This calls an optional `activateConfig` method on the package's main
module, which allows it to add a configuration interface to the
`configView`.
2013-04-26 15:32:47 -07:00
Nathan Sobo 160b80b47f Open a custom config window on 'open-user-configuration' event 2013-04-26 15:32:47 -07:00
Nathan Sobo df064ddd21 Use isDevMode method to determine whether to use bundle resource path 2013-04-26 15:32:46 -07:00
Nathan Sobo 9d2d3d5c00 Rename window methods to distinguish editor window from config window 2013-04-26 15:32:46 -07:00
Nathan Sobo f62e81bca8 Add config.observeUserConfig 2013-04-26 15:32:46 -07:00
Nathan Sobo ab1b90804e Add specs for successful calls to .loadUserConfig 2013-04-26 15:31:18 -07:00
Nathan Sobo 9fe264ded4 💄 2013-04-26 15:31:18 -07:00
Corey Johnson & Kevin Sawicki 0e3f9297fb Only pass instances of EditSession to CommandInterpreter 2013-04-26 14:54:15 -07:00
Garen Torikian 7fdfd71382 💄 2013-04-26 14:45:18 -07:00
Garen Torikian bb40ad6177 💄 all the things 2013-04-26 13:49:12 -07:00
Kevin Sawicki e3295059a0 Mention bug fixes and new features 2013-04-26 09:53:17 -07:00
Kevin Sawicki 4940439f4b Include ruby grammar for fenced ruby blocks 2013-04-26 08:58:43 -07:00
Kevin Sawicki dccd5ec8ba Include XML grammar for fenced XML blocks 2013-04-26 08:56:13 -07:00
Kevin Sawicki 0ca1204b89 Use standard headings in command logger
Now that we have bootstrap we no longer need these
tweaks to headings.
2013-04-25 18:44:25 -07:00
Kevin Sawicki c8d76edea1 Always return created view 2013-04-25 18:44:25 -07:00
Kevin Sawicki 1d9aa7c5e1 Use relative require path 2013-04-25 18:44:25 -07:00
Nathan Sobo 3a05731f2d Eliminate EditSession references from tokenized-buffer-spec 2013-04-25 17:16:51 -06:00
Nathan Sobo 9c7ff78fc8 Move language-specific integration tests to text-mate-grammar-spec 2013-04-25 17:15:27 -06:00
Nathan Sobo 89fe8e1628 Add TextMateGrammar.tokenizeLines convenience method
It can be used in specs to test parsing. It takes a block of text,
splits it into lines, and then tokenizes them, returning an array
of token arrays, one for each line.
2013-04-25 17:15:27 -06:00
Nathan Sobo 7e0ac1db9c Default TokenizedBuffer options hash to {} 2013-04-25 17:15:27 -06:00
Kevin Sawicki 20073c9d34 Upgrade to git-utils 0.15 2013-04-25 15:39:22 -07:00
Nathan Sobo 4fdc9fba63 Eliminate EditSession dependencies in DisplayBuffer spec 2013-04-25 16:18:39 -06:00
Nathan Sobo 0d78098dbf Make TokenizedBuffer select its own grammar, not LanguageMode
This is part of an effort to disentangle LanguageMode, DisplayBuffer,
and TokenizedBuffer. It should be easy to create a DisplayBuffer
without creating an EditSession… let's get the dependencies flowing
in a single direction.
2013-04-25 15:13:00 -06:00
Nathan Sobo ee31114b32 💄 whitespace 2013-04-25 14:06:53 -06:00
Nathan Sobo 0f623b3d08 Move structural folding logic to LanguageMode
DisplayBuffer should just focus on providing basic support for folding.
Scanning the structure of the code, looking at scopes, etc is more the
domain of the LanguageMode object.
2013-04-25 14:06:53 -06:00
Nathan Sobo 1ac55413d9 Define class properties with :, not = 2013-04-25 14:06:53 -06:00
Nathan Sobo 60f945aafd Move structural folding specs to edit-session-spec
Structural folding should really be handled at the edit session level
so that the DisplayBuffer doesn't need access to the LanguageMode. It
should only be concerned with the raw ability to create folds.
2013-04-25 14:06:53 -06:00
Nathan Sobo ca3b0c97da 💄 getter renames 2013-04-25 14:06:52 -06:00
Kevin Sawicki c50b7fd99e 💄 2013-04-25 11:27:59 -07:00
75 arquivos alterados com 1645 adições e 497 exclusões
+7
Ver Arquivo
@@ -1,3 +1,10 @@
* Fixed: Freeze when editing a RoR class
* Added: meta-N to open a new untitled editor in the current window
* Fixed: Styling in command logger
* Added: XML and Ruby syntax highlighting in Markdown files
* Fixed: Error when editing files in a HEAD-less Git repository
* Fixed: Invisible characters not being visible when enabled
* Added: Editor gutter now displays Git status for lines
+2 -2
Ver Arquivo
@@ -3,8 +3,8 @@ ATOM_PATH=/Applications/Atom.app
if [ ! -d $ATOM_PATH ]; then sleep 5; fi # Wait for Atom to reappear, Sparkle may be replacing it.
if [ ! -d $ATOM_PATH ]; then
echo "Atom Application not found at '$ATOM_PATH'" >&2
if [ ! -d $ATOM_PATH ]; then
echo "Atom application not found at '$ATOM_PATH'" >&2
exit 1
fi
-1
Ver Arquivo
@@ -25,7 +25,6 @@ keymap.bindKeys '*',
'meta-w': 'close'
'alt-meta-i': 'show-console'
$(document).on 'close', -> window.close()
$(document).on 'show-console', -> atom.toggleDevTools()
defaultCount = 100
window.pbenchmark = (args...) -> window.benchmark(args..., profile: true)
+1 -1
Ver Arquivo
@@ -154,7 +154,7 @@ its own namespace.
### Glossary of Config Keys
- core
- disablePackages: An array of package names to disable
- disabledPackages: An array of package names to disable
- hideGitIgnoredFiles: Whether files in the .gitignore should be hidden
- ignoredNames: File names to ignore across all of atom (not fully implemented)
- themes: An array of theme names to load, in cascading order
+1
Ver Arquivo
@@ -20,6 +20,7 @@ class AtomCefClient;
- (void)open:(NSString *)path;
- (void)openDev:(NSString *)path;
- (void)open:(NSString *)path pidToKillWhenWindowCloses:(NSNumber *)pid;
- (void)openConfig;
- (IBAction)runSpecs:(id)sender;
- (IBAction)runBenchmarks:(id)sender;
- (void)runSpecsThenExit:(BOOL)exitWhenDone;
+10
Ver Arquivo
@@ -191,6 +191,16 @@
[[AtomWindowController alloc] initDevWithPath:path];
}
- (void)openConfig {
for (NSWindow *window in [self windows]) {
if ([[window windowController] isConfig]) {
[window makeKeyAndOrderFront:nil];
return;
}
}
[[AtomWindowController alloc] initConfig];
}
- (IBAction)runSpecs:(id)sender {
[self runSpecsThenExit:NO];
}
+3
Ver Arquivo
@@ -46,6 +46,9 @@ bool AtomCefClient::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
else if (name == "newWindow") {
NewWindow();
}
else if (name == "openConfig") {
OpenConfig();
}
else if (name == "toggleDevTools") {
ToggleDevTools(browser);
}
+1
Ver Arquivo
@@ -116,6 +116,7 @@ class AtomCefClient : public CefClient,
void OpenDev(std::string path);
void OpenDev();
void NewWindow();
void OpenConfig();
void ToggleDevTools(CefRefPtr<CefBrowser> browser);
void ShowDevTools(CefRefPtr<CefBrowser> browser);
void Confirm(int replyId,
+4
Ver Arquivo
@@ -74,6 +74,10 @@ void AtomCefClient::NewWindow() {
[(AtomApplication *)[AtomApplication sharedApplication] open:nil];
}
void AtomCefClient::OpenConfig() {
[(AtomApplication *)[AtomApplication sharedApplication] openConfig];
}
void AtomCefClient::Confirm(int replyId,
std::string message,
std::string detailedMessage,
+4
Ver Arquivo
@@ -18,19 +18,23 @@ class AtomCefClient;
BOOL _runningSpecs;
BOOL _exitWhenDone;
BOOL _isConfig;
}
@property (nonatomic, retain) IBOutlet NSSplitView *splitView;
@property (nonatomic, retain) IBOutlet NSView *webView;
@property (nonatomic, retain) IBOutlet NSView *devToolsView;
@property (nonatomic, retain) NSString *pathToOpen;
@property (nonatomic) BOOL isConfig;
- (id)initWithPath:(NSString *)path;
- (id)initDevWithPath:(NSString *)path;
- (id)initInBackground;
- (id)initConfig;
- (id)initSpecsThenExit:(BOOL)exitWhenDone;
- (id)initBenchmarksThenExit:(BOOL)exitWhenDone;
- (void)setPidToKillOnClose:(NSNumber *)pid;
- (BOOL)isDevMode;
- (void)toggleDevTools;
- (void)showDevTools;
+15 -8
Ver Arquivo
@@ -11,6 +11,7 @@
@synthesize webView=_webView;
@synthesize devToolsView=_devToolsView;
@synthesize pathToOpen=_pathToOpen;
@synthesize isConfig=_isConfig;
- (void)dealloc {
[_splitView release];
@@ -95,6 +96,12 @@
[self setWindowFrameAutosaveName:@"AtomWindow"];
NSColor *background = [NSColor colorWithDeviceRed:(51.0/255.0) green:(51.0/255.0f) blue:(51.0/255.0f) alpha:1.0];
[self.window setBackgroundColor:background];
if (self.isConfig) {
NSRect frame = self.window.frame;
frame.size.width = 800;
frame.size.height = 600;
[self.window setFrame:frame display: YES];
}
[self showWindow:self];
}
@@ -103,9 +110,7 @@
- (id)initWithPath:(NSString *)path {
_pathToOpen = [path retain];
AtomApplication *atomApplication = (AtomApplication *)[AtomApplication sharedApplication];
BOOL useBundleResourcePath = [atomApplication.arguments objectForKey:@"dev"] == nil;
return [self initWithBootstrapScript:@"window-bootstrap" background:NO useBundleResourcePath:useBundleResourcePath];
return [self initWithBootstrapScript:@"window-bootstrap" background:NO useBundleResourcePath:![self isDevMode]];
}
- (id)initDevWithPath:(NSString *)path {
@@ -114,10 +119,7 @@
}
- (id)initInBackground {
AtomApplication *atomApplication = (AtomApplication *)[AtomApplication sharedApplication];
BOOL useBundleResourcePath = [atomApplication.arguments objectForKey:@"dev"] == nil;
[self initWithBootstrapScript:@"window-bootstrap" background:YES useBundleResourcePath:useBundleResourcePath];
[self initWithBootstrapScript:@"window-bootstrap" background:YES useBundleResourcePath:![self isDevMode]];
[self.window setFrame:NSMakeRect(0, 0, 0, 0) display:NO];
[self.window setExcludedFromWindowsMenu:YES];
[self.window setCollectionBehavior:NSWindowCollectionBehaviorStationary];
@@ -136,6 +138,11 @@
return [self initWithBootstrapScript:@"benchmark-bootstrap" background:NO useBundleResourcePath:NO];
}
- (id)initConfig {
_isConfig = true;
return [self initWithBootstrapScript:@"config-bootstrap" background:NO useBundleResourcePath:![self isDevMode]];
}
- (void)addBrowserToView:(NSView *)view url:(const char *)url cefHandler:(CefRefPtr<AtomCefClient>)cefClient {
CefBrowserSettings settings;
[self populateBrowserSettings:settings];
@@ -271,7 +278,7 @@
[_devButton setHidden:NO];
}
- (bool)isDevMode {
- (BOOL)isDevMode {
NSString *bundleResourcePath = [[NSBundle bundleForClass:self.class] resourcePath];
return ![_resourcePath isEqualToString:bundleResourcePath];
}
+3 -2
Ver Arquivo
@@ -7,7 +7,7 @@
"ctags": "0.3.0",
"oniguruma": "0.11.0",
"mkdirp": "0.3.5",
"git-utils": "0.14.0",
"git-utils": "0.15.0",
"underscore": "1.4.4",
"d3": "3.0.8",
"coffee-cache": "0.1.0",
@@ -18,7 +18,8 @@
"pathwatcher": "0.3.0",
"plist": "git://github.com/nathansobo/node-plist.git",
"space-pen": "git://github.com/nathansobo/space-pen.git",
"less": "git://github.com/nathansobo/less.js.git"
"less": "git://github.com/nathansobo/less.js.git",
"jqueryui-browser": "1.10.2-1"
},
"devDependencies" : {
+12
Ver Arquivo
@@ -181,6 +181,18 @@ describe "the `atom` global", ->
atom.activatePackage('ruby.tmbundle', sync: true)
expect(syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBe '# '
describe ".activatePackageConfig(id)", ->
it "calls the optional .activateConfigMenu method on the package's main module", ->
pack = atom.activatePackageConfig('package-with-activate-config')
expect(pack.mainModule.activateCalled).toBeFalsy()
expect(pack.mainModule.activateConfigCalled).toBeTruthy()
it "loads the package's config defaults", ->
expect(config.get('package-with-config-defaults.numbers.one')).toBeUndefined()
atom.activatePackageConfig('package-with-config-defaults')
expect(config.get('package-with-config-defaults.numbers.one')).toBe 1
expect(config.get('package-with-config-defaults.numbers.two')).toBe 2
describe ".deactivatePackage(id)", ->
describe "atom packages", ->
it "calls `deactivate` on the package's main module", ->
+82
Ver Arquivo
@@ -0,0 +1,82 @@
ConfigPanel = require 'config-panel'
Editor = require 'editor'
describe "ConfigPanel", ->
it "automatically binds named input fields to their corresponding config keys", ->
class TestPanel extends ConfigPanel
@content: ->
@div =>
@input outlet: 'intInput', id: 'foo.int', type: 'int'
@input outlet: 'floatInput', id: 'foo.float', type: 'float'
@input outlet: 'stringInput', id: 'foo.string', type: 'string'
@input outlet: 'booleanInput', id: 'foo.boolean', type: 'checkbox'
config.set('foo.int', 22)
config.set('foo.boolean', true)
panel = new TestPanel
expect(panel.intInput.val()).toBe '22'
expect(panel.floatInput.val()).toBe ''
expect(panel.stringInput.val()).toBe ''
expect(panel.booleanInput.attr('checked')).toBeTruthy()
config.set('foo.int', 10)
expect(panel.intInput.val()).toBe '10'
expect(panel.floatInput.val()).toBe ''
expect(panel.stringInput.val()).toBe ''
config.set('foo.string', 'hey')
expect(panel.intInput.val()).toBe '10'
expect(panel.floatInput.val()).toBe ''
expect(panel.stringInput.val()).toBe 'hey'
config.set('foo.boolean', false)
expect(panel.booleanInput.attr('checked')).toBeFalsy()
panel.intInput.val('90.2').change()
expect(config.get('foo.int')).toBe 90
panel.floatInput.val('90.2').change()
expect(config.get('foo.float')).toBe 90.2
panel.stringInput.val('moo').change()
expect(config.get('foo.string')).toBe 'moo'
it "automatically binds named editors to their corresponding config keys", ->
class TestPanel extends ConfigPanel
@content: ->
@div =>
@subview 'intEditor', new Editor(mini: true, attributes: { id: 'foo.int', type: 'int' })
@subview 'floatEditor', new Editor(mini: true, attributes: { id: 'foo.float', type: 'float' })
@subview 'stringEditor', new Editor(mini: true, attributes: { id: 'foo.string', type: 'string' })
config.set('foo.int', 1)
config.set('foo.float', 1.1)
config.set('foo.string', 'I think therefore I am.')
panel = new TestPanel
expect(panel.intEditor.getText()).toBe '1'
expect(panel.floatEditor.getText()).toBe '1.1'
expect(panel.stringEditor.getText()).toBe 'I think therefore I am.'
config.set('foo.int', 2)
config.set('foo.float', 2.2)
config.set('foo.string', 'We are what we think.')
expect(panel.intEditor.getText()).toBe '2'
expect(panel.floatEditor.getText()).toBe '2.2'
expect(panel.stringEditor.getText()).toBe 'We are what we think.'
panel.intEditor.setText('3')
panel.floatEditor.setText('3.3')
panel.stringEditor.setText('All limitations are self imposed.')
window.advanceClock(10000) # wait for contents-modified to be triggered
expect(config.get('foo.int')).toBe 3
expect(config.get('foo.float')).toBe 3.3
expect(config.get('foo.string')).toBe 'All limitations are self imposed.'
panel.intEditor.setText('not an int')
panel.floatEditor.setText('not a float')
panel.stringEditor.setText('')
window.advanceClock(10000) # wait for contents-modified to be triggered
expect(config.get('foo.int')).toBe 0
expect(config.get('foo.float')).toBe 0
expect(config.get('foo.string')).toBe undefined
+73 -12
Ver Arquivo
@@ -100,6 +100,11 @@ describe "Config", ->
config.set('foo.bar.baz', "value 1")
expect(observeHandler).toHaveBeenCalledWith("value 1")
it "fires the callback when the observed value is deleted", ->
observeHandler.reset() # clear the initial call
config.set('foo.bar.baz', undefined)
expect(observeHandler).toHaveBeenCalledWith(undefined)
it "fires the callback when the full key path goes into and out of existence", ->
observeHandler.reset() # clear the initial call
config.set("foo.bar", undefined)
@@ -110,7 +115,7 @@ describe "Config", ->
config.set("foo.bar.baz", "i'm back")
expect(observeHandler).toHaveBeenCalledWith("i'm back")
describe "initializeConfigDirectory()", ->
describe ".initializeConfigDirectory()", ->
beforeEach ->
config.configDirPath = '/tmp/dot-atom-dir'
expect(fsUtils.exists(config.configDirPath)).toBeFalsy()
@@ -148,20 +153,76 @@ describe "Config", ->
expect(fsUtils.isFile(fsUtils.join(config.configDirPath, 'themes/atom-dark-syntax.css'))).toBeTruthy()
expect(fsUtils.isFile(fsUtils.join(config.configDirPath, 'themes/atom-light-syntax.css'))).toBeTruthy()
describe "when the config file is not parseable", ->
describe ".loadUserConfig()", ->
beforeEach ->
config.configDirPath = '/tmp/dot-atom-dir'
config.configFilePath = fsUtils.join(config.configDirPath, "config.cson")
expect(fsUtils.exists(config.configDirPath)).toBeFalsy()
config.configDirPath = '/tmp/dot-atom-dir'
config.configFilePath = fsUtils.join(config.configDirPath, "config.cson")
expect(fsUtils.exists(config.configDirPath)).toBeFalsy()
afterEach ->
fsUtils.remove('/tmp/dot-atom-dir') if fsUtils.exists('/tmp/dot-atom-dir')
it "logs an error to the console and does not overwrite the config file", ->
config.save.reset()
spyOn(console, 'error')
fsUtils.write(config.configFilePath, "{{{{{")
describe "when the config file contains valid cson", ->
beforeEach ->
fsUtils.write(config.configFilePath, "foo: bar: 'baz'")
config.loadUserConfig()
it "updates the config data based on the file contents", ->
expect(config.get("foo.bar")).toBe 'baz'
describe "when the config file contains invalid cson", ->
beforeEach ->
spyOn(console, 'error')
fsUtils.write(config.configFilePath, "{{{{{")
it "logs an error to the console and does not overwrite the config file on a subsequent save", ->
config.loadUserConfig()
expect(console.error).toHaveBeenCalled()
config.set("hair", "blonde") # trigger a save
expect(config.save).not.toHaveBeenCalled()
describe ".observeUserConfig()", ->
updatedHandler = null
beforeEach ->
config.configDirPath = '/tmp/dot-atom-dir'
config.configFilePath = fsUtils.join(config.configDirPath, "config.cson")
expect(fsUtils.exists(config.configDirPath)).toBeFalsy()
fsUtils.write(config.configFilePath, "foo: bar: 'baz'")
config.loadUserConfig()
config.set("hair", "blonde") # trigger a save
expect(console.error).toHaveBeenCalled()
expect(config.save).not.toHaveBeenCalled()
config.observeUserConfig()
updatedHandler = jasmine.createSpy("updatedHandler")
config.on 'updated', updatedHandler
afterEach ->
config.unobserveUserConfig()
fsUtils.remove('/tmp/dot-atom-dir') if fsUtils.exists('/tmp/dot-atom-dir')
describe "when the config file changes to contain valid cson", ->
it "updates the config data", ->
fsUtils.write(config.configFilePath, "foo: { bar: 'quux', baz: 'bar'}")
waitsFor 'update event', -> updatedHandler.callCount > 0
runs ->
expect(config.get('foo.bar')).toBe 'quux'
expect(config.get('foo.baz')).toBe 'bar'
describe "when the config file changes to contain invalid cson", ->
beforeEach ->
spyOn(console, 'error')
fsUtils.write(config.configFilePath, "}}}")
waitsFor "error to be logged", -> console.error.callCount > 0
it "logs a warning and does not update config data", ->
expect(updatedHandler.callCount).toBe 0
expect(config.get('foo.bar')).toBe 'baz'
config.set("hair", "blonde") # trigger a save
expect(config.save).not.toHaveBeenCalled()
describe "when the config file subsequently changes again to contain valid cson", ->
beforeEach ->
fsUtils.write(config.configFilePath, "foo: bar: 'baz'")
waitsFor 'update event', -> updatedHandler.callCount > 0
it "updates the config data and resumes saving", ->
config.set("hair", "blonde")
expect(config.save).toHaveBeenCalled()
+46
Ver Arquivo
@@ -0,0 +1,46 @@
ConfigView = require 'config-view'
{$$} = require 'space-pen'
describe "ConfigView", ->
configView = null
beforeEach ->
configView = new ConfigView
describe "serialization", ->
it "remembers which panel was visible", ->
configView.showPanel('Editor')
newConfigView = deserialize(configView.serialize())
configView.remove()
newConfigView.attachToDom()
expect(newConfigView.activePanelName).toBe 'Editor'
it "shows the previously active panel if it is added after deserialization", ->
configView.addPanel('Panel 1', $$ -> @div id: 'panel-1')
configView.showPanel('Panel 1')
newConfigView = deserialize(configView.serialize())
configView.remove()
newConfigView.attachToDom()
newConfigView.addPanel('Panel 1', $$ -> @div id: 'panel-1')
expect(newConfigView.activePanelName).toBe 'Panel 1'
describe ".addPanel(name, view)", ->
it "adds a menu entry to the left and a panel that can be activated by clicking it", ->
configView.addPanel('Panel 1', $$ -> @div id: 'panel-1')
configView.addPanel('Panel 2', $$ -> @div id: 'panel-2')
expect(configView.panelMenu.find('li a:contains(Panel 1)')).toExist()
expect(configView.panelMenu.find('li a:contains(Panel 2)')).toExist()
expect(configView.panelMenu.children(':first')).toHaveClass 'active'
configView.attachToDom()
configView.panelMenu.find('li a:contains(Panel 1)').click()
expect(configView.panelMenu.children('.active').length).toBe 1
expect(configView.panelMenu.find('li:contains(Panel 1)')).toHaveClass('active')
expect(configView.panels.find('#panel-1')).toBeVisible()
expect(configView.panels.find('#panel-2')).toBeHidden()
configView.panelMenu.find('li a:contains(Panel 2)').click()
expect(configView.panelMenu.children('.active').length).toBe 1
expect(configView.panelMenu.find('li:contains(Panel 2)')).toHaveClass('active')
expect(configView.panels.find('#panel-1')).toBeHidden()
expect(configView.panels.find('#panel-2')).toBeVisible()
+19 -120
Ver Arquivo
@@ -3,24 +3,24 @@ Buffer = require 'text-buffer'
_ = require 'underscore'
describe "DisplayBuffer", ->
[editSession, displayBuffer, buffer, changeHandler, tabLength] = []
[displayBuffer, buffer, changeHandler, tabLength] = []
beforeEach ->
tabLength = 2
atom.activatePackage('javascript.tmbundle', sync: true)
editSession = project.buildEditSession('sample.js', { tabLength })
{ buffer, displayBuffer } = editSession
changeHandler = jasmine.createSpy 'changeHandler'
displayBuffer.on 'changed', changeHandler
buffer = project.bufferForPath('sample.js')
displayBuffer = new DisplayBuffer(buffer, { tabLength })
displayBuffer.on 'changed', changeHandler = jasmine.createSpy 'changeHandler'
afterEach ->
editSession.destroy()
displayBuffer.destroy()
buffer.release()
describe "when the buffer changes", ->
it "renders line numbers correctly", ->
originalLineCount = displayBuffer.lineCount()
originalLineCount = displayBuffer.getLineCount()
oneHundredLines = [0..100].join("\n")
buffer.insert([0,0], oneHundredLines)
expect(displayBuffer.lineCount()).toBe 100 + originalLineCount
expect(displayBuffer.getLineCount()).toBe 100 + originalLineCount
describe "soft wrapping", ->
beforeEach ->
@@ -60,9 +60,8 @@ describe "DisplayBuffer", ->
describe "when whitespace is added after the max line length", ->
it "adds whitespace to the end of the current line and wraps an empty line", ->
fiftyCharacters = _.multiplyString("x", 50)
editSession.buffer.setText(fiftyCharacters)
editSession.setCursorBufferPosition([0, 51])
editSession.insertText(" ")
buffer.setText(fiftyCharacters)
buffer.insert([0, 51], " ")
describe "when the update makes a soft-wrapped line shorter than the max line length", ->
it "rewraps the line and emits a change event", ->
@@ -142,100 +141,14 @@ describe "DisplayBuffer", ->
expect(changeHandler).toHaveBeenCalledWith(start: 0, end: 15, screenDelta: 3, bufferDelta: 0)
describe "structural folding", ->
describe ".unfoldAll()", ->
it "unfolds every folded line", ->
displayBuffer.foldBufferRow(0)
displayBuffer.foldBufferRow(1)
displayBuffer.unfoldAll()
expect(Object.keys(displayBuffer.activeFolds).length).toBe 0
describe ".foldAll()", ->
it "folds every foldable line", ->
displayBuffer.foldAll()
fold = displayBuffer.lineForRow(0).fold
expect(fold).toBeDefined()
expect([fold.startRow, fold.endRow]).toEqual [0,12]
expect(Object.keys(displayBuffer.activeFolds).length).toBe(3)
expect(displayBuffer.activeFolds[1].length).toBe(1)
expect(displayBuffer.activeFolds[4].length).toBe(1)
it "doesn't fold lines that are already folded", ->
displayBuffer.foldBufferRow(4)
displayBuffer.foldAll()
expect(Object.keys(displayBuffer.activeFolds).length).toBe(3)
expect(displayBuffer.activeFolds[0].length).toBe(1)
expect(displayBuffer.activeFolds[1].length).toBe(1)
expect(displayBuffer.activeFolds[4].length).toBe(1)
describe ".foldBufferRow(bufferRow)", ->
describe "when bufferRow can be folded", ->
it "creates a fold based on the syntactic region starting at the given row", ->
displayBuffer.foldBufferRow(1)
fold = displayBuffer.lineForRow(1).fold
expect(fold.startRow).toBe 1
expect(fold.endRow).toBe 9
describe "when bufferRow can't be folded", ->
it "searches upward for the first row that begins a syntatic region containing the given buffer row (and folds it)", ->
displayBuffer.foldBufferRow(8)
fold = displayBuffer.lineForRow(1).fold
expect(fold.startRow).toBe 1
expect(fold.endRow).toBe 9
describe "when the bufferRow is already folded", ->
it "searches upward for the first row that begins a syntatic region containing the folded row (and folds it)", ->
displayBuffer.foldBufferRow(2)
expect(displayBuffer.lineForRow(1).fold).toBeDefined()
expect(displayBuffer.lineForRow(0).fold).not.toBeDefined()
displayBuffer.foldBufferRow(1)
expect(displayBuffer.lineForRow(0).fold).toBeDefined()
describe "when the bufferRow is in a multi-line comment", ->
it "searches upward and downward for surrounding comment lines and folds them as a single fold", ->
buffer.insert([1,0], " //this is a comment\n // and\n //more docs\n\n//second comment")
displayBuffer.foldBufferRow(1)
fold = displayBuffer.lineForRow(1).fold
expect(fold.startRow).toBe 1
expect(fold.endRow).toBe 3
describe "when the bufferRow is a single-line comment", ->
it "searches upward for the first row that begins a syntatic region containing the folded row (and folds it)", ->
buffer.insert([1,0], " //this is a single line comment\n")
displayBuffer.foldBufferRow(1)
fold = displayBuffer.lineForRow(0).fold
expect(fold.startRow).toBe 0
expect(fold.endRow).toBe 13
describe ".unfoldBufferRow(bufferRow)", ->
describe "when bufferRow can be unfolded", ->
it "destroys a fold based on the syntactic region starting at the given row", ->
displayBuffer.foldBufferRow(1)
expect(displayBuffer.lineForRow(1).fold).toBeDefined()
displayBuffer.unfoldBufferRow(1)
expect(displayBuffer.lineForRow(1).fold).toBeUndefined()
describe "when bufferRow can't be unfolded", ->
it "does not throw an error", ->
expect(displayBuffer.lineForRow(1).fold).toBeUndefined()
displayBuffer.unfoldBufferRow(1)
expect(displayBuffer.lineForRow(1).fold).toBeUndefined()
describe "primitive folding", ->
editSession2 = null
beforeEach ->
editSession2 = project.buildEditSession('two-hundred.txt')
{ buffer, displayBuffer } = editSession2
displayBuffer.destroy()
buffer.release()
buffer = project.bufferForPath('two-hundred.txt')
displayBuffer = new DisplayBuffer(buffer, { tabLength })
displayBuffer.on 'changed', changeHandler
afterEach ->
editSession2.destroy()
describe "when folds are created and destroyed", ->
describe "when a fold spans multiple lines", ->
it "replaces the lines spanned by the fold with a placeholder that references the fold object", ->
@@ -530,20 +443,6 @@ describe "DisplayBuffer", ->
expect(displayBuffer.lineForRow(8).text).toMatch /^9-+/
expect(displayBuffer.lineForRow(10).fold).toBeDefined()
describe "when the line being deleted preceeds a fold", ->
describe "when the command is undone", ->
it "restores the line and preserves the fold", ->
editSession.setCursorBufferPosition([4])
editSession.foldCurrentRow()
expect(editSession.isFoldedAtScreenRow(4)).toBeTruthy()
editSession.setCursorBufferPosition([3])
editSession.deleteLine()
expect(editSession.isFoldedAtScreenRow(3)).toBeTruthy()
expect(buffer.lineForRow(3)).toBe ' while(items.length > 0) {'
editSession.undo()
expect(editSession.isFoldedAtScreenRow(4)).toBeTruthy()
expect(buffer.lineForRow(3)).toBe ' var pivot = items.shift(), current, left = [], right = [];'
describe ".clipScreenPosition(screenPosition, wrapBeyondNewlines: false, wrapAtSoftNewlines: false, skipAtomicTokens: false)", ->
beforeEach ->
displayBuffer.setSoftWrapColumn(50)
@@ -617,7 +516,7 @@ describe "DisplayBuffer", ->
describe "markers", ->
beforeEach ->
displayBuffer.foldBufferRow(4)
displayBuffer.createFold(4, 7)
describe "marker creation and manipulation", ->
it "allows markers to be created in terms of both screen and buffer coordinates", ->
@@ -690,7 +589,7 @@ describe "DisplayBuffer", ->
}
observeHandler.reset()
displayBuffer.unfoldBufferRow(4)
displayBuffer.destroyFoldsContainingBufferRow(4)
expect(observeHandler).toHaveBeenCalled()
expect(observeHandler.argsForCall[0][0]).toEqual {
oldHeadScreenPosition: [8, 23]
@@ -706,7 +605,7 @@ describe "DisplayBuffer", ->
}
observeHandler.reset()
displayBuffer.foldBufferRow(4)
displayBuffer.createFold(4, 7)
expect(observeHandler).toHaveBeenCalled()
expect(observeHandler.argsForCall[0][0]).toEqual {
oldHeadScreenPosition: [11, 23]
@@ -793,7 +692,7 @@ describe "DisplayBuffer", ->
it "allows observation subscriptions to be cancelled", ->
subscription.cancel()
displayBuffer.setMarkerHeadScreenPosition(marker, [8, 20])
displayBuffer.unfoldBufferRow(4)
displayBuffer.destroyFoldsContainingBufferRow(4)
expect(observeHandler).not.toHaveBeenCalled()
it "updates the position of markers before emitting buffer change events, but does not notify their observers until the change event", ->
@@ -822,7 +721,7 @@ describe "DisplayBuffer", ->
expect(displayBuffer.getMarkerTailScreenPosition(marker)).toEqual [8, 4]
displayBuffer.on 'changed', changeHandler
displayBuffer.unfoldBufferRow(4)
displayBuffer.destroyFoldsContainingBufferRow(4)
expect(changeHandler).toHaveBeenCalled()
expect(observeHandler).toHaveBeenCalled()
+95 -4
Ver Arquivo
@@ -2111,11 +2111,89 @@ describe "EditSession", ->
expect(cursor3.getBufferPosition()).toEqual [1,2]
describe "folding", ->
describe "structural folding", ->
it "maintains cursor buffer position when a fold is created/destroyed", ->
editSession.setCursorBufferPosition([5,5])
describe ".unfoldAll()", ->
it "unfolds every folded line", ->
initialScreenLineCount = editSession.getScreenLineCount()
editSession.foldBufferRow(0)
editSession.foldBufferRow(1)
expect(editSession.getScreenLineCount()).toBeLessThan initialScreenLineCount
editSession.unfoldAll()
expect(editSession.getScreenLineCount()).toBe initialScreenLineCount
describe ".foldAll()", ->
it "folds every foldable line", ->
editSession.foldAll()
expect(editSession.getCursorBufferPosition()).toEqual([5,5])
fold1 = editSession.lineForScreenRow(0).fold
expect([fold1.startRow, fold1.endRow]).toEqual [0, 12]
fold1.destroy()
fold2 = editSession.lineForScreenRow(1).fold
expect([fold2.startRow, fold2.endRow]).toEqual [1, 9]
fold2.destroy()
fold3 = editSession.lineForScreenRow(4).fold
expect([fold3.startRow, fold3.endRow]).toEqual [4, 7]
describe ".foldBufferRow(bufferRow)", ->
describe "when bufferRow can be folded", ->
it "creates a fold based on the syntactic region starting at the given row", ->
editSession.foldBufferRow(1)
fold = editSession.lineForScreenRow(1).fold
expect(fold.startRow).toBe 1
expect(fold.endRow).toBe 9
describe "when bufferRow can't be folded", ->
it "searches upward for the first row that begins a syntatic region containing the given buffer row (and folds it)", ->
editSession.foldBufferRow(8)
fold = editSession.lineForScreenRow(1).fold
expect(fold.startRow).toBe 1
expect(fold.endRow).toBe 9
describe "when the bufferRow is already folded", ->
it "searches upward for the first row that begins a syntatic region containing the folded row (and folds it)", ->
editSession.foldBufferRow(2)
expect(editSession.lineForScreenRow(1).fold).toBeDefined()
expect(editSession.lineForScreenRow(0).fold).not.toBeDefined()
editSession.foldBufferRow(1)
expect(editSession.lineForScreenRow(0).fold).toBeDefined()
describe "when the bufferRow is in a multi-line comment", ->
it "searches upward and downward for surrounding comment lines and folds them as a single fold", ->
buffer.insert([1,0], " //this is a comment\n // and\n //more docs\n\n//second comment")
editSession.foldBufferRow(1)
fold = editSession.lineForScreenRow(1).fold
expect(fold.startRow).toBe 1
expect(fold.endRow).toBe 3
describe "when the bufferRow is a single-line comment", ->
it "searches upward for the first row that begins a syntatic region containing the folded row (and folds it)", ->
buffer.insert([1,0], " //this is a single line comment\n")
editSession.foldBufferRow(1)
fold = editSession.lineForScreenRow(0).fold
expect(fold.startRow).toBe 0
expect(fold.endRow).toBe 13
describe ".unfoldBufferRow(bufferRow)", ->
describe "when bufferRow can be unfolded", ->
it "destroys a fold based on the syntactic region starting at the given row", ->
editSession.foldBufferRow(1)
expect(editSession.lineForScreenRow(1).fold).toBeDefined()
editSession.unfoldBufferRow(1)
expect(editSession.lineForScreenRow(1).fold).toBeUndefined()
describe "when bufferRow can't be unfolded", ->
it "does not throw an error", ->
expect(editSession.lineForScreenRow(1).fold).toBeUndefined()
editSession.unfoldBufferRow(1)
expect(editSession.lineForScreenRow(1).fold).toBeUndefined()
it "maintains cursor buffer position when a folding/unfolding", ->
editSession.setCursorBufferPosition([5,5])
editSession.foldAll()
expect(editSession.getCursorBufferPosition()).toEqual([5,5])
describe ".deleteLine()", ->
it "deletes the first line when the cursor is there", ->
@@ -2194,6 +2272,19 @@ describe "EditSession", ->
expect(buffer.lineForRow(6)).toBe(line7)
expect(buffer.getLineCount()).toBe(count - 1)
describe "when the line being deleted preceeds a fold, and the command is undone", ->
it "restores the line and preserves the fold", ->
editSession.setCursorBufferPosition([4])
editSession.foldCurrentRow()
expect(editSession.isFoldedAtScreenRow(4)).toBeTruthy()
editSession.setCursorBufferPosition([3])
editSession.deleteLine()
expect(editSession.isFoldedAtScreenRow(3)).toBeTruthy()
expect(buffer.lineForRow(3)).toBe ' while(items.length > 0) {'
editSession.undo()
expect(editSession.isFoldedAtScreenRow(4)).toBeTruthy()
expect(buffer.lineForRow(3)).toBe ' var pivot = items.shift(), current, left = [], right = [];'
describe ".transpose()", ->
it "swaps two characters", ->
editSession.buffer.setText("abc")
+8
Ver Arquivo
@@ -1760,6 +1760,14 @@ describe "Editor", ->
miniEditor.setText(" a line with tabs\tand spaces ")
expect(miniEditor.renderedLines.find('.line').text()).toBe "#{space}a line with tabs#{tab} and spaces#{space}"
it "doesn't show the indent guide", ->
config.set "editor.showIndentGuide", true
miniEditor = new Editor(mini: true)
miniEditor.attachToDom()
miniEditor.setText(" and indented line")
expect(miniEditor.renderedLines.find('.indent-guide').length).toBe 0
it "lets you set the grammar", ->
miniEditor = new Editor(mini: true)
miniEditor.setText("var something")
+8
Ver Arquivo
@@ -165,6 +165,14 @@ describe "Keymap", ->
expect(deleteCharHandler).not.toHaveBeenCalled()
expect(insertCharHandler).not.toHaveBeenCalled()
describe "when the event matches a 'native!' binding", ->
it "returns true, allowing the browser's native key handling to process the event", ->
keymap.bindKeys '.grandchild-node', 'x': 'native!'
nativeHandler = jasmine.createSpy("nativeHandler")
fragment.on 'native!', nativeHandler
expect(keymap.handleKeyEvent(keydownEvent('x', target: fragment.find('.grandchild-node')[0]))).toBe true
expect(nativeHandler).not.toHaveBeenCalled()
describe "when at least one binding partially matches the event's keystroke", ->
[quitHandler, closeOtherWindowsHandler] = []
-12
Ver Arquivo
@@ -8,18 +8,6 @@ describe "LanguageMode", ->
afterEach ->
editSession.destroy()
describe "common behavior", ->
beforeEach ->
atom.activatePackage('javascript.tmbundle', sync: true)
editSession = project.buildEditSession('sample.js', autoIndent: false)
{ buffer, languageMode } = editSession
describe "language detection", ->
it "uses the file name as the file type if it has no extension", ->
jsEditSession = project.buildEditSession('js', autoIndent: false)
expect(jsEditSession.languageMode.grammar.name).toBe "JavaScript"
jsEditSession.destroy()
describe "javascript", ->
beforeEach ->
atom.activatePackage('javascript.tmbundle', sync: true)
+41
Ver Arquivo
@@ -0,0 +1,41 @@
PackageConfigPanel = require 'package-config-panel'
describe "PackageConfigPanel", ->
[panel, configObserver] = []
beforeEach ->
configObserver = jasmine.createSpy("configObserver")
observeSubscription = config.observe('core.disabledPackages', configObserver)
config.set('core.disabledPackages', ['toml', 'wrap-guide'])
configObserver.reset()
panel = new PackageConfigPanel
it "lists all available packages, with an unchecked checkbox next to packages in the core.disabledPackages array", ->
treeViewTr = panel.packageTableBody.find("tr[name='tree-view']")
expect(treeViewTr).toExist()
expect(treeViewTr.find("input[type='checkbox']").attr('checked')).toBeTruthy()
tomlTr = panel.packageTableBody.find("tr[name='toml']")
expect(tomlTr).toExist()
expect(tomlTr.find("input[type='checkbox']").attr('checked')).toBeFalsy()
wrapGuideTr = panel.packageTableBody.find("tr[name='wrap-guide']")
expect(wrapGuideTr).toExist()
expect(wrapGuideTr.find("input[type='checkbox']").attr('checked')).toBeFalsy()
describe "when the core.disabledPackages array changes", ->
it "updates the checkboxes for newly disabled / enabled packages", ->
config.set('core.disabledPackages', ['wrap-guide', 'tree-view'])
expect(panel.find("tr[name='tree-view'] input[type='checkbox']").attr('checked')).toBeFalsy()
expect(panel.find("tr[name='toml'] input[type='checkbox']").attr('checked')).toBeTruthy()
expect(panel.find("tr[name='wrap-guide'] input[type='checkbox']").attr('checked')).toBeFalsy()
describe "when a checkbox is unchecked", ->
it "adds the package name to the disabled packages array", ->
panel.find("tr[name='tree-view'] input[type='checkbox']").attr('checked', false).change()
expect(configObserver).toHaveBeenCalledWith(['toml', 'wrap-guide', 'tree-view'])
describe "when a checkbox is checked", ->
it "removes the package name from the disabled packages array", ->
panel.find("tr[name='toml'] input[type='checkbox']").attr('checked', true).change()
expect(configObserver).toHaveBeenCalledWith(['wrap-guide'])
+8
Ver Arquivo
@@ -354,3 +354,11 @@ describe "RootView", ->
rootView.open(require.resolve('fixtures/sample.txt'))
expect(count).toBe 1
expect(callbackBuffer).toBe rootView.getActiveView().getBuffer()
describe "when a 'new-editor' event is triggered", ->
it "opens a new untitled editor", ->
itemCount = rootView.getActivePane().getItems().length
rootView.trigger 'new-editor'
expect(rootView.getActivePaneItem().getPath()).toBeUndefined()
expect(rootView.getActivePaneItem().getBuffer().fileExists()).toBeFalsy()
expect(rootView.getActivePane().getItems().length).toBe itemCount + 1
+110
Ver Arquivo
@@ -487,3 +487,113 @@ describe "TextMateGrammar", ->
{tokens} = editSession.lineForScreenRow(0)
expect(tokens[2].value).toBe "SELECT"
expect(tokens[2].scopes).toEqual ["source.js", "comment.line.double-slash.js", "keyword.other.DML.sql"]
describe "when the position doesn't advance and rule includes $self and matches itself", ->
it "token the entire line using the rule", ->
grammar = new TextMateGrammar
name: "test"
scopeName: "source"
repository: {}
patterns: [
{
name: "text"
begin: "(?=forever)"
end: "whatevs"
patterns: [
include: "$self"
]
}
]
{tokens} = grammar.tokenizeLine("forever and ever")
expect(tokens.length).toBe 1
expect(tokens[0].value).toBe "forever and ever"
expect(tokens[0].scopes).toEqual ["source", "text"]
describe "language-specific integration tests", ->
lines = null
describe "Git commit messages", ->
beforeEach ->
atom.activatePackage('git.tmbundle', sync: true)
grammar = syntax.selectGrammar('COMMIT_EDITMSG')
lines = grammar.tokenizeLines """
longggggggggggggggggggggggggggggggggggggggggggggggg
# Please enter the commit message for your changes. Lines starting
"""
it "correctly parses a long line", ->
tokens = lines[0]
expect(tokens[0].value).toBe "longggggggggggggggggggggggggggggggggggggggggggggggg"
expect(tokens[0].scopes).toEqual ["text.git-commit", "meta.scope.message.git-commit", "invalid.deprecated.line-too-long.git-commit"]
it "correctly parses the number sign of the first comment line", ->
tokens = lines[1]
expect(tokens[0].value).toBe "#"
expect(tokens[0].scopes).toEqual ["text.git-commit", "meta.scope.metadata.git-commit", "comment.line.number-sign.git-commit", "punctuation.definition.comment.git-commit"]
describe "C++", ->
beforeEach ->
atom.activatePackage('c.tmbundle', sync: true)
grammar = syntax.selectGrammar('includes.cc')
lines = grammar.tokenizeLines """
#include "a.h"
#include "b.h"
"""
it "correctly parses the first include line", ->
tokens = lines[0]
expect(tokens[0].value).toBe "#"
expect(tokens[0].scopes).toEqual ["source.c++", "meta.preprocessor.c.include"]
expect(tokens[1].value).toBe 'include'
expect(tokens[1].scopes).toEqual ["source.c++", "meta.preprocessor.c.include", "keyword.control.import.include.c"]
it "correctly parses the second include line", ->
tokens = lines[1]
expect(tokens[0].value).toBe "#"
expect(tokens[0].scopes).toEqual ["source.c++", "meta.preprocessor.c.include"]
expect(tokens[1].value).toBe 'include'
expect(tokens[1].scopes).toEqual ["source.c++", "meta.preprocessor.c.include", "keyword.control.import.include.c"]
describe "Ruby", ->
beforeEach ->
grammar = syntax.selectGrammar('hello.rb')
lines = grammar.tokenizeLines """
a = {
"b" => "c",
}
"""
it "doesn't loop infinitely (regression)", ->
expect(_.pluck(lines[0], 'value').join('')).toBe 'a = {'
expect(_.pluck(lines[1], 'value').join('')).toBe ' "b" => "c",'
expect(_.pluck(lines[2], 'value').join('')).toBe '}'
expect(_.pluck(lines[3], 'value').join('')).toBe ''
describe "Objective-C", ->
beforeEach ->
atom.activatePackage('c.tmbundle', sync: true)
atom.activatePackage('objective-c.tmbundle', sync: true)
grammar = syntax.selectGrammar('function.mm')
lines = grammar.tokenizeLines """
void test() {
NSString *a = @"a\\nb";
}
"""
it "correctly parses variable type when it is a built-in Cocoa class", ->
tokens = lines[1]
expect(tokens[0].value).toBe "NSString"
expect(tokens[0].scopes).toEqual ["source.objc++", "meta.function.c", "meta.block.c", "support.class.cocoa"]
it "correctly parses the semicolon at the end of the line", ->
tokens = lines[1]
lastToken = _.last(tokens)
expect(lastToken.value).toBe ";"
expect(lastToken.scopes).toEqual ["source.objc++", "meta.function.c", "meta.block.c"]
it "correctly parses the string characters before the escaped character", ->
tokens = lines[1]
expect(tokens[2].value).toBe '@"'
expect(tokens[2].scopes).toEqual ["source.objc++", "meta.function.c", "meta.block.c", "string.quoted.double.objc", "punctuation.definition.string.begin.objc"]
+49
Ver Arquivo
@@ -0,0 +1,49 @@
$ = require 'jquery'
ThemeConfigPanel = require 'theme-config-panel'
describe "ThemeConfigPanel", ->
panel = null
beforeEach ->
config.set('core.themes', ['atom-dark-ui', 'atom-dark-syntax'])
panel = new ThemeConfigPanel
describe "when an enabled theme is reloced in the themes list", ->
it "updates the 'core.themes' config key to reflect the new order", ->
li = panel.enabledThemes.children(':first').detach()
panel.enabledThemes.append(li)
panel.enabledThemes.sortable('option', 'update')()
expect(config.get('core.themes')).toEqual ['atom-dark-syntax', 'atom-dark-ui']
describe "when a theme is dragged into the enabled themes list", ->
it "updates the 'core.themes' config key to reflect the themes in the enabled list", ->
dragHelper = panel.availableThemes.find("li[name='atom-light-ui']").clone()
panel.enabledThemes.prepend(dragHelper)
panel.enabledThemes.sortable('option', 'receive')(null, helper: dragHelper[0])
panel.enabledThemes.sortable('option', 'update')()
expect(config.get('core.themes')).toEqual ['atom-light-ui', 'atom-dark-ui', 'atom-dark-syntax']
describe "when the theme is already present in the enabled list", ->
it "removes the previous instance of the theme, updating the order based on the location of drag", ->
dragHelper = panel.availableThemes.find("li[name='atom-dark-ui']").clone()
panel.enabledThemes.append(dragHelper)
panel.enabledThemes.sortable('option', 'receive')(null, helper: dragHelper[0])
panel.enabledThemes.sortable('option', 'update')()
expect(config.get('core.themes')).toEqual ['atom-dark-syntax', 'atom-dark-ui']
dragHelper = panel.availableThemes.find("li[name='atom-dark-ui']").clone()
panel.enabledThemes.prepend(dragHelper)
panel.enabledThemes.sortable('option', 'receive')(null, helper: dragHelper[0])
panel.enabledThemes.sortable('option', 'update')()
expect(config.get('core.themes')).toEqual ['atom-dark-ui', 'atom-dark-syntax']
describe "when the disable icon is clicked on a theme li", ->
it "removes the theme from the list and the 'core.themes' array", ->
panel.enabledThemes.find('li:first .disable-theme').click()
expect(panel.getEnabledThemeNames()).toEqual ['atom-dark-syntax']
expect(config.get('core.themes')).toEqual ['atom-dark-syntax']
describe "when the 'core.config' key is updated", ->
it "refreshes the enabled themes list", ->
config.set('core.themes', ['atom-light-ui', 'atom-light-syntax'])
expect(panel.getEnabledThemeNames()).toEqual ['atom-light-ui', 'atom-light-syntax']
+18 -138
Ver Arquivo
@@ -1,11 +1,10 @@
TokenizedBuffer = require 'tokenized-buffer'
LanguageMode = require 'language-mode'
Buffer = require 'text-buffer'
Range = require 'range'
_ = require 'underscore'
describe "TokenizedBuffer", ->
[editSession, tokenizedBuffer, buffer, changeHandler] = []
[tokenizedBuffer, buffer, changeHandler] = []
beforeEach ->
atom.activatePackage('javascript.tmbundle', sync: true)
@@ -19,15 +18,14 @@ describe "TokenizedBuffer", ->
describe "when the buffer contains soft-tabs", ->
beforeEach ->
editSession = project.buildEditSession('sample.js', autoIndent: false)
buffer = editSession.buffer
tokenizedBuffer = editSession.displayBuffer.tokenizedBuffer
editSession.setVisible(true)
changeHandler = jasmine.createSpy('changeHandler')
tokenizedBuffer.on "changed", changeHandler
buffer = project.bufferForPath('sample.js')
tokenizedBuffer = new TokenizedBuffer(buffer)
tokenizedBuffer.setVisible(true)
tokenizedBuffer.on "changed", changeHandler = jasmine.createSpy('changeHandler')
afterEach ->
editSession.destroy()
tokenizedBuffer.destroy()
buffer.release()
describe "on construction", ->
it "initially creates un-tokenized screen lines, then tokenizes lines chunk at a time in the background", ->
@@ -300,21 +298,20 @@ describe "TokenizedBuffer", ->
describe "when the buffer contains hard-tabs", ->
beforeEach ->
atom.activatePackage('coffee-script-tmbundle', sync: true)
tabLength = 2
editSession = project.buildEditSession('sample-with-tabs.coffee', { tabLength })
buffer = editSession.buffer
tokenizedBuffer = editSession.displayBuffer.tokenizedBuffer
editSession.setVisible(true)
buffer = project.bufferForPath('sample-with-tabs.coffee')
tokenizedBuffer = new TokenizedBuffer(buffer)
tokenizedBuffer.setVisible(true)
afterEach ->
editSession.destroy()
tokenizedBuffer.destroy()
buffer.release()
describe "when the buffer is fully tokenized", ->
beforeEach ->
fullyTokenize(tokenizedBuffer)
it "renders each tab as its own atomic token with a value of size tabLength", ->
tabAsSpaces = _.multiplyString(' ', editSession.getTabLength())
tabAsSpaces = _.multiplyString(' ', tokenizedBuffer.tabLength)
screenLine0 = tokenizedBuffer.lineForScreenRow(0)
expect(screenLine0.text).toBe "# Econ 101#{tabAsSpaces}"
{ tokens } = screenLine0
@@ -328,16 +325,15 @@ describe "TokenizedBuffer", ->
expect(tokenizedBuffer.lineForScreenRow(2).text).toBe "#{tabAsSpaces} buy()#{tabAsSpaces}while supply > demand"
describe "when the language mode emits a 'grammar-updated' event based on an included grammar being activated", ->
describe "when the grammar is updated because a grammar it includes is activated", ->
it "retokenizes the buffer", ->
atom.activatePackage('ruby.tmbundle', sync: true)
atom.activatePackage('ruby-on-rails-tmbundle', sync: true)
editSession = project.buildEditSession()
editSession.setVisible(true)
editSession.setGrammar(syntax.selectGrammar('test.erb'))
editSession.buffer.setText("<div class='name'><%= User.find(2).full_name %></div>")
tokenizedBuffer = editSession.displayBuffer.tokenizedBuffer
buffer = project.bufferForPath(null, "<div class='name'><%= User.find(2).full_name %></div>")
tokenizedBuffer = new TokenizedBuffer(buffer)
tokenizedBuffer.setGrammar(syntax.selectGrammar('test.erb'))
tokenizedBuffer.setVisible(true)
fullyTokenize(tokenizedBuffer)
{tokens} = tokenizedBuffer.lineForScreenRow(0)
@@ -347,119 +343,3 @@ describe "TokenizedBuffer", ->
fullyTokenize(tokenizedBuffer)
{tokens} = tokenizedBuffer.lineForScreenRow(0)
expect(tokens[0]).toEqual value: '<', scopes: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.begin.html"]
describe "when a Git commit message file is tokenized", ->
beforeEach ->
atom.activatePackage('git.tmbundle', sync: true)
editSession = project.buildEditSession('COMMIT_EDITMSG', autoIndent: false)
buffer = editSession.buffer
tokenizedBuffer = editSession.displayBuffer.tokenizedBuffer
editSession.setVisible(true)
fullyTokenize(tokenizedBuffer)
afterEach ->
editSession.destroy()
it "correctly parses a long line", ->
longLine = tokenizedBuffer.lineForScreenRow(0)
expect(longLine.text).toBe "longggggggggggggggggggggggggggggggggggggggggggggggg"
{ tokens } = longLine
expect(tokens[0].value).toBe "longggggggggggggggggggggggggggggggggggggggggggggggg"
expect(tokens[0].scopes).toEqual ["text.git-commit", "meta.scope.message.git-commit", "invalid.deprecated.line-too-long.git-commit"]
it "correctly parses the number sign of the first comment line", ->
commentLine = tokenizedBuffer.lineForScreenRow(1)
expect(commentLine.text).toBe "# Please enter the commit message for your changes. Lines starting"
{ tokens } = commentLine
expect(tokens[0].value).toBe "#"
expect(tokens[0].scopes).toEqual ["text.git-commit", "meta.scope.metadata.git-commit", "comment.line.number-sign.git-commit", "punctuation.definition.comment.git-commit"]
describe "when a C++ source file is tokenized", ->
beforeEach ->
atom.activatePackage('c.tmbundle', sync: true)
editSession = project.buildEditSession('includes.cc', autoIndent: false)
buffer = editSession.buffer
tokenizedBuffer = editSession.displayBuffer.tokenizedBuffer
editSession.setVisible(true)
fullyTokenize(tokenizedBuffer)
afterEach ->
editSession.destroy()
it "correctly parses the first include line", ->
longLine = tokenizedBuffer.lineForScreenRow(0)
expect(longLine.text).toBe '#include "a.h"'
{ tokens } = longLine
expect(tokens[0].value).toBe "#"
expect(tokens[0].scopes).toEqual ["source.c++", "meta.preprocessor.c.include"]
expect(tokens[1].value).toBe 'include'
expect(tokens[1].scopes).toEqual ["source.c++", "meta.preprocessor.c.include", "keyword.control.import.include.c"]
it "correctly parses the second include line", ->
commentLine = tokenizedBuffer.lineForScreenRow(1)
expect(commentLine.text).toBe '#include "b.h"'
{ tokens } = commentLine
expect(tokens[0].value).toBe "#"
expect(tokens[0].scopes).toEqual ["source.c++", "meta.preprocessor.c.include"]
expect(tokens[1].value).toBe 'include'
expect(tokens[1].scopes).toEqual ["source.c++", "meta.preprocessor.c.include", "keyword.control.import.include.c"]
describe "when a Ruby source file is tokenized", ->
beforeEach ->
editSession = project.buildEditSession('hello.rb', autoIndent: false)
buffer = editSession.buffer
tokenizedBuffer = editSession.displayBuffer.tokenizedBuffer
editSession.setVisible(true)
fullyTokenize(tokenizedBuffer)
afterEach ->
editSession.destroy()
it "doesn't loop infinitely (regression)", ->
expect(tokenizedBuffer.lineForScreenRow(0).text).toBe 'a = {'
expect(tokenizedBuffer.lineForScreenRow(1).text).toBe ' "b" => "c",'
expect(tokenizedBuffer.lineForScreenRow(2).text).toBe '}'
expect(tokenizedBuffer.lineForScreenRow(3).text).toBe ''
describe "when an Objective-C source file is tokenized", ->
beforeEach ->
atom.activatePackage('c.tmbundle', sync: true)
atom.activatePackage('objective-c.tmbundle', sync: true)
editSession = project.buildEditSession('function.mm', autoIndent: false)
buffer = editSession.buffer
tokenizedBuffer = editSession.displayBuffer.tokenizedBuffer
editSession.setVisible(true)
fullyTokenize(tokenizedBuffer)
afterEach ->
editSession.destroy()
it "correctly parses variable type when it is a built-in Cocoa class", ->
commentLine = tokenizedBuffer.lineForScreenRow(1)
expect(commentLine.text).toBe 'NSString *a = @"a\\nb";'
{ tokens } = commentLine
expect(tokens[0].value).toBe "NSString"
expect(tokens[0].scopes).toEqual ["source.objc++", "meta.function.c", "meta.block.c", "support.class.cocoa"]
it "correctly parses the semicolon at the end of the line", ->
commentLine = tokenizedBuffer.lineForScreenRow(1)
expect(commentLine.text).toBe 'NSString *a = @"a\\nb";'
{ tokens } = commentLine
lastToken = tokens.length - 1
expect(lastToken).toBeGreaterThan 0
expect(tokens[lastToken].value).toBe ";"
expect(tokens[lastToken].scopes).toEqual ["source.objc++", "meta.function.c", "meta.block.c"]
it "correctly parses the string characters before the escaped character", ->
commentLine = tokenizedBuffer.lineForScreenRow(1)
expect(commentLine.text).toBe 'NSString *a = @"a\\nb";'
{ tokens } = commentLine
expect(tokens[2].value).toBe '@"'
expect(tokens[2].scopes).toEqual ["source.objc++", "meta.function.c", "meta.block.c", "string.quoted.double.objc", "punctuation.definition.string.begin.objc"]
+7 -7
Ver Arquivo
@@ -8,11 +8,11 @@ describe "Window", ->
beforeEach ->
spyOn(atom, 'getPathToOpen').andReturn(project.getPath())
window.handleWindowEvents()
window.deserializeWindowState()
window.deserializeEditorWindow()
projectPath = project.getPath()
afterEach ->
window.shutdown()
window.unloadEditorWindow()
$(window).off 'beforeunload'
describe "when the window is loaded", ->
@@ -120,7 +120,7 @@ describe "Window", ->
removeStylesheet(cssPath)
expect($(document.body).css('font-weight')).not.toBe("bold")
describe ".shutdown()", ->
describe ".unloadEditorWindow()", ->
it "saves the serialized state of the window so it can be deserialized after reload", ->
projectPath = project.getPath()
expect(atom.getWindowState()).toEqual {}
@@ -130,7 +130,7 @@ describe "Window", ->
projectState = JSON.parse(JSON.stringify(project.serialize()))
syntaxState = JSON.parse(JSON.stringify(syntax.serialize()))
window.shutdown()
window.unloadEditorWindow()
windowState = atom.getWindowState()
expect(windowState.rootView).toEqual rootViewState
@@ -145,14 +145,14 @@ describe "Window", ->
rootView.getActivePane().splitRight()
expect(window.rootView.find('.editor').length).toBe 2
window.shutdown()
window.unloadEditorWindow()
expect(buffer.subscriptionCount()).toBe 0
it "only serializes window state the first time it is called", ->
window.shutdown()
window.shutdown()
window.unloadEditorWindow()
window.unloadEditorWindow()
expect(atom.saveWindowState.callCount).toBe 1
describe ".installAtomCommand(commandPath)", ->
-2
Ver Arquivo
@@ -1,2 +0,0 @@
longggggggggggggggggggggggggggggggggggggggggggggggg
# Please enter the commit message for your changes. Lines starting
-3
Ver Arquivo
@@ -1,3 +0,0 @@
void test() {
NSString *a = @"a\nb";
}
-3
Ver Arquivo
@@ -1,3 +0,0 @@
a = {
"b" => "c",
}
-2
Ver Arquivo
@@ -1,2 +0,0 @@
#include "a.h"
#include "b.h"
@@ -0,0 +1,3 @@
module.exports =
activate: -> @activateCalled = true
activateConfig: -> @activateConfigCalled = true
+2 -2
Ver Arquivo
@@ -2,7 +2,7 @@ require 'window'
window.setUpEnvironment()
nakedLoad 'jasmine-jquery'
$ = require 'jquery'
$ = jQuery = require 'jquery'
_ = require 'underscore'
Keymap = require 'keymap'
Config = require 'config'
@@ -23,7 +23,6 @@ keymap.loadBundledKeymaps()
[bindingSetsToRestore, bindingSetsByFirstKeystrokeToRestore] = []
$(window).on 'core:close', -> window.close()
$(window).on 'toggle-dev-tools', (e) -> atom.toggleDevTools()
$('html,body').css('overflow', 'auto')
jasmine.getEnv().addEqualityTester(_.isEqual) # Use underscore's definition of equality for toEqual assertions
@@ -57,6 +56,7 @@ beforeEach ->
config.set "editor.fontSize", 16
config.set "editor.autoIndent", false
config.set "core.disabledPackages", ["package-that-throws-an-exception"]
config.save.reset()
# make editor display updates synchronous
spyOn(Editor.prototype, 'requestDisplayUpdate').andCallFake -> @updateDisplay()
+14 -3
Ver Arquivo
@@ -31,7 +31,7 @@ describe "underscore extensions", ->
expect(_.endsWith("test.txt", ".tx")).toBeFalsy()
expect(_.endsWith("test.txt", "test")).toBeFalsy()
describe "camelize(string)", ->
describe "_.camelize(string)", ->
it "converts `string` to camel case", ->
expect(_.camelize("corey_dale_johnson")).toBe "coreyDaleJohnson"
expect(_.camelize("corey-dale-johnson")).toBe "coreyDaleJohnson"
@@ -39,14 +39,14 @@ describe "underscore extensions", ->
expect(_.camelize("coreyDaleJohnson")).toBe "coreyDaleJohnson"
expect(_.camelize("CoreyDaleJohnson")).toBe "CoreyDaleJohnson"
describe "dasherize(string)", ->
describe "_.dasherize(string)", ->
it "converts `string` to use dashes", ->
expect(_.dasherize("corey_dale_johnson")).toBe "corey-dale-johnson"
expect(_.dasherize("coreyDaleJohnson")).toBe "corey-dale-johnson"
expect(_.dasherize("CoreyDaleJohnson")).toBe "corey-dale-johnson"
expect(_.dasherize("corey-dale-johnson")).toBe "corey-dale-johnson"
describe "underscore(string)", ->
describe "_.underscore(string)", ->
it "converts `string` to use underscores", ->
expect(_.underscore("corey-dale-johnson")).toBe "corey_dale_johnson"
expect(_.underscore("coreyDaleJohnson")).toBe "corey_dale_johnson"
@@ -65,3 +65,14 @@ describe "underscore extensions", ->
array = ['a', 'b', 'c']
_.spliceWithArray(array, 1, 1, ['v', 'w', 'x', 'y', 'z'], 2)
expect(array).toEqual ['a', 'v', 'w', 'x', 'y', 'z', 'c']
describe "_.humanizeEventName(eventName)", ->
describe "when no namespace exists", ->
it "undasherizes and capitalizes the event name", ->
expect(_.humanizeEventName('nonamespace')).toBe 'Nonamespace'
expect(_.humanizeEventName('no-name-space')).toBe 'No Name Space'
describe "when a namespaces exists", ->
it "space separates the undasherized/capitalized versions of the namespace and event name", ->
expect(_.humanizeEventName('space:final-frontier')).toBe 'Space: Final Frontier'
expect(_.humanizeEventName('star-trek:the-next-generation')).toBe 'Star Trek: The Next Generation'
+21 -6
Ver Arquivo
@@ -37,11 +37,7 @@ class AtomPackage extends Package
this
activate: ({immediate}={}) ->
keymap.add(path, map) for [path, map] in @keymaps
applyStylesheet(path, content) for [path, content] in @stylesheets
syntax.addGrammar(grammar) for grammar in @grammars
syntax.addProperties(path, selector, properties) for [path, selector, properties] in @scopedProperties
@activateResources()
if @metadata.activationEvents? and not immediate
@subscribeToActivationEvents()
else
@@ -55,6 +51,18 @@ class AtomPackage extends Package
catch e
console.warn "Failed to activate package named '#{@name}'", e.stack
activateConfig: ->
@activateResources()
if @requireMainModule()
config.setDefaults(@name, @mainModule.configDefaults)
@mainModule?.activateConfig?()
activateResources: ->
keymap.add(path, map) for [path, map] in @keymaps
applyStylesheet(path, content) for [path, content] in @stylesheets
syntax.addGrammar(grammar) for grammar in @grammars
syntax.addProperties(path, selector, properties) for [path, selector, properties] in @scopedProperties
loadMetadata: ->
if metadataPath = fsUtils.resolveExtension(fsUtils.join(@path, 'package'), ['json', 'cson'])
@metadata = CSON.readObject(metadataPath)
@@ -101,11 +109,18 @@ class AtomPackage extends Package
deactivate: ->
@unsubscribeFromActivationEvents()
@deactivateResources()
@mainModule?.deactivate?()
deactivateConfig: ->
@deactivateResources()
@mainModule?.deactivateConfig?()
deactivateResources: ->
syntax.removeGrammar(grammar) for grammar in @grammars
syntax.removeProperties(path) for [path] in @scopedProperties
keymap.remove(path) for [path] in @keymaps
removeStylesheet(path) for [path] in @stylesheets
@mainModule?.deactivate?()
requireMainModule: ->
return @mainModule if @mainModule
+35 -7
Ver Arquivo
@@ -57,8 +57,17 @@ _.extend atom,
getActivePackages: ->
_.clone(@activePackages)
activatePackageConfigs: ->
@activatePackageConfig(pack.path) for pack in @getLoadedPackages()
activatePackageConfig: (id, options) ->
if pack = @loadPackage(id, options)
@activePackages.push(pack)
pack.activateConfig()
pack
loadPackages: ->
@loadPackage(path) for path in @getPackagePaths() when not @isPackageDisabled(path)
@loadPackage(path) for path in @getAvailablePackagePaths() when not @isPackageDisabled(path)
loadPackage: (id, options) ->
if @isPackageDisabled(id)
@@ -91,19 +100,31 @@ _.extend atom,
if path = @resolvePackagePath(id)
_.include(config.get('core.disabledPackages') ? [], fsUtils.base(path))
getPackagePaths: ->
getAvailablePackagePaths: ->
packagePaths = []
for packageDirPath in config.packageDirPaths
for packagePath in fsUtils.list(packageDirPath)
packagePaths.push(packagePath) if fsUtils.isDirectory(packagePath)
_.uniq(packagePaths)
getAvailablePackageNames: ->
fsUtils.base(path) for path in @getAvailablePackagePaths()
loadThemes: ->
themeNames = config.get("core.themes") ? ['atom-dark-ui', 'atom-dark-syntax']
themeNames = config.get("core.themes")
themeNames = [themeNames] unless _.isArray(themeNames)
@loadTheme(themeName) for themeName in themeNames
@loadUserStylesheet()
getAvailableThemePaths: ->
themePaths = []
for themeDirPath in config.themeDirPaths
themePaths.push(fsUtils.list(themeDirPath, ['', '.tmTheme', '.css', 'less'])...)
_.uniq(themePaths)
getAvailableThemeNames: ->
fsUtils.base(path).split('.')[0] for path in @getAvailableThemePaths()
loadTheme: (name) ->
@loadedThemes.push Theme.load(name)
@@ -126,6 +147,9 @@ _.extend atom,
newWindow: (args...) ->
@sendMessageToBrowserProcess('newWindow', args)
openConfig: ->
@sendMessageToBrowserProcess('openConfig')
restartRendererProcess: ->
@sendMessageToBrowserProcess('restartRendererProcess')
@@ -239,12 +263,16 @@ _.extend atom,
null
getSavedWindowState: ->
if pathToOpen = window.location.params.pathToOpen
localStorage[pathToOpen]
storageKey = switch @windowMode
when 'editor' then window.location.params.pathToOpen
when 'config' then 'config'
localStorage[storageKey] if storageKey
saveWindowState: ->
if pathToOpen = @getPathToOpen()
localStorage[pathToOpen] = JSON.stringify(@getWindowState())
storageKey = switch @windowMode
when 'editor' then @getPathToOpen()
when 'config' then 'config'
localStorage[storageKey] = JSON.stringify(@getWindowState())
update: ->
@sendMessageToBrowserProcess('update')
+53
Ver Arquivo
@@ -0,0 +1,53 @@
$ = require 'jquery'
{View} = require 'space-pen'
###
# Internal #
###
module.exports =
class ConfigPanel extends View
initialize: ->
@bindFormFields()
@bindEditors()
bindFormFields: ->
for input in @find('input[id]').toArray()
do (input) =>
input = $(input)
name = input.attr('id')
type = input.attr('type')
@observeConfig name, (value) ->
if type is 'checkbox'
input.attr('checked', value)
else
input.val(value) if value
input.on 'change', ->
value = input.val()
config.set name, switch type
when 'int'
parseInt(value)
when 'float'
parseFloat(value)
when 'checkbox'
!!input.attr('checked')
else
value
bindEditors: ->
for editor in @find('.editor[id]').views()
do (editor) =>
name = editor.attr('id')
type = editor.attr('type')
@observeConfig name, (value) ->
return if value?.toString() == editor.getText()
value ?= ""
editor.setText(value.toString())
editor.getBuffer().on 'contents-modified', ->
value = editor.getText()
if type == 'int' then value = parseInt(value) or 0
if type == 'float' then value = parseFloat(value) or 0
if value == "" then value = undefined
config.set name, value
+69
Ver Arquivo
@@ -0,0 +1,69 @@
{View, $$} = require 'space-pen'
$ = require 'jquery'
_ = require 'underscore'
GeneralConfigPanel = require 'general-config-panel'
EditorConfigPanel = require 'editor-config-panel'
ThemeConfigPanel = require 'theme-config-panel'
PackageConfigPanel = require 'package-config-panel'
###
# Internal #
###
module.exports =
class ConfigView extends View
registerDeserializer(this)
@deserialize: ({activePanelName}) ->
view = new ConfigView()
view.showPanel(activePanelName)
view
@content: ->
@div id: 'config-view', =>
@div id: 'config-menu', =>
@ul id: 'panels-menu', class: 'nav nav-pills nav-stacked', outlet: 'panelMenu'
@button "open .atom", id: 'open-dot-atom', class: 'btn btn-default btn-small'
@div id: 'panels', outlet: 'panels'
initialize: ->
@panelsByName = {}
document.title = "Atom Configuration"
@on 'click', '#panels-menu li a', (e) =>
@showPanel($(e.target).closest('li').attr('name'))
@on 'click', '#open-dot-atom', ->
atom.open(config.configDirPath)
@addPanel('General', new GeneralConfigPanel)
@addPanel('Editor', new EditorConfigPanel)
@addPanel('Themes', new ThemeConfigPanel)
@addPanel('Installed Packages', new PackageConfigPanel)
addPanel: (name, panel) ->
panelItem = $$ -> @li name: name, => @a name
@panelMenu.append(panelItem)
panel.hide()
@panelsByName[name] = panel
@panels.append(panel)
@showPanel(name) if @getPanelCount() is 1 or @panelToShow is name
getPanelCount: ->
_.values(@panelsByName).length
showPanel: (name) ->
if @panelsByName[name]
@panels.children().hide()
@panelMenu.children('.active').removeClass('active')
@panelsByName[name].show()
for editorElement in @panelsByName[name].find(".editor")
$(editorElement).view().redraw()
@panelMenu.children("[name='#{name}']").addClass('active')
@activePanelName = name
@panelToShow = null
else
@panelToShow = name
serialize: ->
deserializer: @constructor.name
activePanelName: @activePanelName
+12
Ver Arquivo
@@ -4,6 +4,7 @@ EventEmitter = require 'event-emitter'
CSON = require 'cson'
fs = require 'fs'
async = require 'async'
pathWatcher = require 'pathwatcher'
configDirPath = fsUtils.absolute("~/.atom")
bundledPackagesDirPath = fsUtils.join(resourcePath, "src/packages")
@@ -67,17 +68,28 @@ class Config
load: ->
@initializeConfigDirectory()
@loadUserConfig()
@observeUserConfig()
loadUserConfig: ->
if fsUtils.exists(@configFilePath)
try
userConfig = CSON.readObject(@configFilePath)
_.extend(@settings, userConfig)
@configFileHasErrors = false
@trigger 'updated'
catch e
@configFileHasErrors = true
console.error "Failed to load user config '#{@configFilePath}'", e.message
console.error e.stack
observeUserConfig: ->
@watchSubscription ?= pathWatcher.watch @configFilePath, (eventType) =>
@loadUserConfig() if eventType is 'change' and @watchSubscription?
unobserveUserConfig: ->
@watchSubscription?.close()
@watchSubscription = null
# Public: Retrieves the setting for the given key.
#
# keyPath - The {String} name of the key to retrieve
+1
Ver Arquivo
@@ -17,6 +17,7 @@ class Cursor
###
# Internal #
###
constructor: ({@editSession, @marker}) ->
@updateVisibility()
@editSession.observeMarker @marker, (e) =>
+16 -55
Ver Arquivo
@@ -13,7 +13,6 @@ module.exports =
class DisplayBuffer
@idCounter: 1
lineMap: null
languageMode: null
tokenizedBuffer: null
activeFolds: null
foldsById: null
@@ -25,13 +24,13 @@ class DisplayBuffer
constructor: (@buffer, options={}) ->
@id = @constructor.idCounter++
@languageMode = options.languageMode
@tokenizedBuffer = new TokenizedBuffer(@buffer, options)
@softWrapColumn = options.softWrapColumn ? Infinity
@activeFolds = {}
@foldsById = {}
@markers = {}
@buildLineMap()
@tokenizedBuffer.on 'grammar-changed', (grammar) => @trigger 'grammar-changed', grammar
@tokenizedBuffer.on 'changed', @handleTokenizedBufferChange
@buffer.on 'markers-updated', @handleMarkersUpdated
@@ -97,56 +96,6 @@ class DisplayBuffer
bufferRowsForScreenRows: (startRow, endRow) ->
@lineMap.bufferRowsForScreenRows(startRow, endRow)
# Public: Folds all the foldable lines in the buffer.
foldAll: ->
for currentRow in [0..@buffer.getLastRow()]
[startRow, endRow] = @languageMode.rowRangeForFoldAtBufferRow(currentRow) ? []
continue unless startRow?
@createFold(startRow, endRow)
# Public: Unfolds all the foldable lines in the buffer.
unfoldAll: ->
for row in [@buffer.getLastRow()..0]
@activeFolds[row]?.forEach (fold) => @destroyFold(fold)
rowRangeForCommentAtBufferRow: (row) ->
return unless @tokenizedBuffer.lineForScreenRow(row).isComment()
startRow = row
for currentRow in [row-1..0]
break if @buffer.isRowBlank(currentRow)
break unless @tokenizedBuffer.lineForScreenRow(currentRow).isComment()
startRow = currentRow
endRow = row
for currentRow in [row+1..@buffer.getLastRow()]
break if @buffer.isRowBlank(currentRow)
break unless @tokenizedBuffer.lineForScreenRow(currentRow).isComment()
endRow = currentRow
return [startRow, endRow] if startRow isnt endRow
# Public: Given a buffer row, this folds it.
#
# bufferRow - A {Number} indicating the buffer row
foldBufferRow: (bufferRow) ->
for currentRow in [bufferRow..0]
rowRange = @rowRangeForCommentAtBufferRow(currentRow)
rowRange ?= @languageMode.rowRangeForFoldAtBufferRow(currentRow)
[startRow, endRow] = rowRange ? []
continue unless startRow? and startRow <= bufferRow <= endRow
fold = @largestFoldStartingAtBufferRow(startRow)
continue if fold
@createFold(startRow, endRow)
return
# Public: Given a buffer row, this unfolds it.
#
# bufferRow - A {Number} indicating the buffer row
unfoldBufferRow: (bufferRow) ->
@largestFoldContainingBufferRow(bufferRow)?.destroy()
# Public: Creates a new fold between two row numbers.
#
# startRow - The row {Number} to start folding at
@@ -202,6 +151,9 @@ class DisplayBuffer
for fold in new Array(folds...)
fold.destroy() if fold.getBufferRange().containsRow(bufferRow)
foldsStartingAtBufferRow: (bufferRow) ->
new Array((@activeFolds[bufferRow] ? [])...)
# Public: Given a buffer row, this returns the largest fold that starts there.
#
# Largest is defined as the fold whose difference between its start and end points
@@ -288,14 +240,14 @@ class DisplayBuffer
# Public: Gets the number of lines in the buffer.
#
# Returns a {Number}.
lineCount: ->
@lineMap.screenLineCount()
getLineCount: ->
@lineMap.getScreenLineCount()
# Public: Gets the number of the last row in the buffer.
#
# Returns a {Number}.
getLastRow: ->
@lineCount() - 1
@getLineCount() - 1
# Public: Gets the length of the longest screen line.
#
@@ -355,6 +307,15 @@ class DisplayBuffer
setTabLength: (tabLength) ->
@tokenizedBuffer.setTabLength(tabLength)
getGrammar: ->
@tokenizedBuffer.grammar
setGrammar: (grammar) ->
@tokenizedBuffer.setGrammar(grammar)
reloadGrammar: ->
@tokenizedBuffer.reloadGrammar()
# Public: Given a position, this clips it to a real position.
#
# For example, if `position`'s row exceeds the row count of the buffer,
+38 -9
Ver Arquivo
@@ -62,7 +62,7 @@ class EditSession
@subscribe @displayBuffer, "changed", (e) =>
@trigger 'screen-lines-changed', e
@languageMode.on 'grammar-changed', => @handleGrammarChange()
@displayBuffer.on 'grammar-changed', => @handleGrammarChange()
getViewClass: ->
require 'editor'
@@ -162,14 +162,17 @@ class EditSession
#
# softWrapColumn - A {Number} defining the soft wrap limit
setSoftWrapColumn: (@softWrapColumn) -> @displayBuffer.setSoftWrapColumn(@softWrapColumn)
# Public: Defines whether to use soft tabs.
#
# softTabs - A {Boolean} which, if `true`, indicates that you want soft tabs.
setSoftTabs: (@softTabs) ->
# Public: Retrieves whether soft tabs are enabled.
#
# Returns a {Boolean}.
getSoftWrap: -> @softWrap
# Public: Defines whether to use soft wrapping of text.
#
# softTabs - A {Boolean} which, if `true`, indicates that you want soft wraps.
@@ -256,14 +259,17 @@ class EditSession
# Public: Saves the buffer.
save: -> @buffer.save()
# Public: Saves the buffer at a specific path.
#
# path - The path to save at.
saveAs: (path) -> @buffer.saveAs(path)
# Public: Retrieves the current buffer's file extension.
#
# Returns a {String}.
getFileExtension: -> @buffer.getExtension()
# Public: Retrieves the current buffer's file path.
#
# Returns a {String}.
@@ -283,30 +289,36 @@ class EditSession
#
# Returns a {String}.
getBuffer: -> @buffer
# Public: Retrieves the current buffer's URI.
#
# Returns a {String}.
getUri: -> @getPath()
# Public: Given a buffer row, identifies if it is blank.
#
# bufferRow - A buffer row {Number} to check
#
# Returns a {Boolean}.
isBufferRowBlank: (bufferRow) -> @buffer.isRowBlank(bufferRow)
# Public: Given a buffer row, this finds the next row that's blank.
#
# bufferRow - A buffer row {Number} to check
#
# Returns a {Number}, or `null` if there's no other blank row.
nextNonBlankBufferRow: (bufferRow) -> @buffer.nextNonBlankRow(bufferRow)
# Public: Finds the last point in the current buffer.
#
# Returns a {Point} representing the last position.
getEofBufferPosition: -> @buffer.getEofPosition()
# Public: Finds the last line in the current buffer.
#
# Returns a {Number}.
getLastBufferRow: -> @buffer.getLastRow()
# Public: Given a buffer row, this retrieves the range for that line.
#
# row - A {Number} identifying the row
@@ -315,34 +327,40 @@ class EditSession
#
# Returns a {Range}.
bufferRangeForBufferRow: (row, options) -> @buffer.rangeForRow(row, options)
# Public: Given a buffer row, this retrieves that line.
#
# row - A {Number} identifying the row
#
# Returns a {String}.
lineForBufferRow: (row) -> @buffer.lineForRow(row)
# Public: Given a buffer row, this retrieves that line's length.
#
# row - A {Number} identifying the row
#
# Returns a {Number}.
lineLengthForBufferRow: (row) -> @buffer.lineLengthForRow(row)
# Public: Scans for text in the buffer, calling a function on each match.
#
# regex - A {RegExp} representing the text to find
# range - A {Range} in the buffer to search within
# iterator - A {Function} that's called on each match
scanInBufferRange: (args...) -> @buffer.scanInRange(args...)
# Public: Scans for text in the buffer _backwards_, calling a function on each match.
#
# regex - A {RegExp} representing the text to find
# range - A {Range} in the buffer to search within
# iterator - A {Function} that's called on each match
backwardsScanInBufferRange: (args...) -> @buffer.backwardsScanInRange(args...)
# Public: Identifies if the {Buffer} is modified (and not saved).
#
# Returns a {Boolean}.
isModified: -> @buffer.isModified()
# Public: Identifies if the modified buffer should let you know if it's closing
# without being saved.
#
@@ -394,12 +412,14 @@ class EditSession
#
# Returns the new, clipped {Point}. Note that this could be the same as `position` if no clipping was performed.
clipScreenPosition: (screenPosition, options) -> @displayBuffer.clipScreenPosition(screenPosition, options)
# Public: Gets the line for the given screen row.
#
# screenRow - A {Number} indicating the screen row.
#
# Returns a {String}.
lineForScreenRow: (row) -> @displayBuffer.lineForRow(row)
# Public: Gets the lines for the given screen row boundaries.
#
# start - A {Number} indicating the beginning screen row.
@@ -407,18 +427,22 @@ class EditSession
#
# Returns an {Array} of {String}s.
linesForScreenRows: (start, end) -> @displayBuffer.linesForRows(start, end)
# Public: Gets the number of screen rows.
#
# Returns a {Number}.
screenLineCount: -> @displayBuffer.lineCount()
getScreenLineCount: -> @displayBuffer.getLineCount()
# Public: Gets the length of the longest screen line.
#
# Returns a {Number}.
maxScreenLineLength: -> @displayBuffer.maxLineLength()
# Public: Gets the number of the last row in the buffer.
#
# Returns a {Number}.
getLastScreenRow: -> @displayBuffer.getLastRow()
# Public: Given a starting and ending row, this converts every row into a buffer position.
#
# startRow - The row {Number} to start at
@@ -426,22 +450,26 @@ class EditSession
#
# Returns an {Array} of {Range}s.
bufferRowsForScreenRows: (startRow, endRow) -> @displayBuffer.bufferRowsForScreenRows(startRow, endRow)
# Public: Retrieves the grammar's token scopes for a buffer position.
#
# bufferPosition - A {Point} in the {Buffer}
#
# Returns an {Array} of {String}s.
scopesForBufferPosition: (bufferPosition) -> @displayBuffer.scopesForBufferPosition(bufferPosition)
# Public: Retrieves the grammar's token for a buffer position.
#
# bufferPosition - A {Point} in the {Buffer}
#
# Returns a {Token}.
tokenForBufferPosition: (bufferPosition) -> @displayBuffer.tokenForBufferPosition(bufferPosition)
# Public: Retrieves the grammar's token scopes for the line with the most recently added cursor.
#
# Returns an {Array} of {String}s.
getCursorScopes: -> @getCursor().getScopes()
# Internal:
logScreenLines: (start, end) -> @displayBuffer.logLines(start, end)
@@ -617,11 +645,11 @@ class EditSession
# Public: Folds all the rows.
foldAll: ->
@displayBuffer.foldAll()
@languageMode.foldAll()
# Public: Unfolds all the rows.
unfoldAll: ->
@displayBuffer.unfoldAll()
@languageMode.unfoldAll()
# Public: Folds the current row.
foldCurrentRow: ->
@@ -632,7 +660,7 @@ class EditSession
#
# bufferRow - A {Number} indicating the buffer row
foldBufferRow: (bufferRow) ->
@displayBuffer.foldBufferRow(bufferRow)
@languageMode.foldBufferRow(bufferRow)
# Public: Unfolds the current row.
unfoldCurrentRow: ->
@@ -643,7 +671,7 @@ class EditSession
#
# bufferRow - A {Number} indicating the buffer row
unfoldBufferRow: (bufferRow) ->
@displayBuffer.unfoldBufferRow(bufferRow)
@languageMode.unfoldBufferRow(bufferRow)
# Public: Folds all selections.
foldSelection: ->
@@ -1576,17 +1604,18 @@ class EditSession
# Public: Retrieves the current {EditSession}'s grammar.
#
# Returns a {String} indicating the language's grammar rules.
getGrammar: -> @languageMode.grammar
getGrammar: ->
@displayBuffer.getGrammar()
# Public: Sets the current {EditSession}'s grammar.
#
# grammar - A {String} indicating the language's grammar rules.
setGrammar: (grammar) ->
@languageMode.setGrammar(grammar)
@displayBuffer.setGrammar(grammar)
# Public: Reloads the current grammar.
reloadGrammar: ->
@languageMode.reloadGrammar()
@displayBuffer.reloadGrammar()
# Internal:
handleGrammarChange: ->
+64
Ver Arquivo
@@ -0,0 +1,64 @@
ConfigPanel = require 'config-panel'
Editor = require 'editor'
###
# Internal #
###
module.exports =
class EditorConfigPanel extends ConfigPanel
@content: ->
@form class: 'form-horizontal', =>
@fieldset =>
@legend "Editor Settings"
@div class: 'control-group', =>
@label class: 'control-label', "Font Size:"
@div class: 'controls', =>
@subview "fontSizeEditor", new Editor(mini: true, attributes: {id: 'editor.fontSize', type: 'int', style: 'width: 40px'})
@div class: 'control-group', =>
@label class: 'control-label', "Font Family:"
@div class: 'controls', =>
@subview "fontFamilyEditor", new Editor(mini: true, attributes: {id: 'editor.fontFamily', type: 'string'})
@div class: 'control-group', =>
@div class: 'controls', =>
@div class: 'checkbox', =>
@label for: 'editor.autoIndent', =>
@input id: 'editor.autoIndent', type: 'checkbox'
@text 'Auto-Indent'
@div class: 'controls', =>
@div class: 'checkbox', =>
@label for: 'editor.autoIndentOnPaste', =>
@input id: 'editor.autoIndentOnPaste', type: 'checkbox'
@text 'Auto-Indent on Paste'
@div class: 'controls', =>
@div class: 'checkbox', =>
@label for: 'editor.showLineNumbers', =>
@input id: 'editor.showLineNumbers', type: 'checkbox'
@text 'Show Line Numbers'
@div class: 'controls', =>
@div class: 'checkbox', =>
@label for: 'editor.showInvisibles', =>
@input id: 'editor.showInvisibles', type: 'checkbox'
@text 'Show Invisible Characters'
@div class: 'controls', =>
@div class: 'checkbox', =>
@label for: 'editor.showIndentGuide', =>
@input id: 'editor.showIndentGuide', type: 'checkbox'
@text 'Show Indent Guide'
@div class: 'control-group', =>
@label class: 'control-label', for: 'editor.preferredLineLength', "Preferred Line Length:"
@div class: 'controls', =>
@subview "preferredLineLengthEditor", new Editor(mini: true, attributes: {id: 'editor.preferredLineLength', type: 'int', style: 'width: 40px'})
@div class: 'control-group', =>
@label class: 'control-label', for: 'editor.nonWordCharacters', "Non-Word Characters:"
@div class: 'controls', =>
@subview "nonWordCharactersEditor", new Editor(mini: true, attributes: {id: 'editor.nonWordCharacters', type: 'string'})
+127 -11
Ver Arquivo
@@ -31,7 +31,9 @@ class Editor extends View
###
@content: (params) ->
@div class: @classes(params), tabindex: -1, =>
attributes = { class: @classes(params), tabindex: -1 }
_.extend(attributes, params.attributes) if params.attributes
@div attributes, =>
@subview 'gutter', new Gutter
@input class: 'hidden-input', outlet: 'hiddenInput'
@div class: 'scroll-view', outlet: 'scrollView', =>
@@ -196,137 +198,173 @@ class Editor extends View
#
# Returns a {Cursor}.
getCursor: -> @activeEditSession.getCursor()
# Public: Retrieves an array of all the cursors.
#
# Returns a {[Cursor]}.
getCursors: -> @activeEditSession.getCursors()
# Public: Adds a cursor at the provided `screenPosition`.
#
# screenPosition - An {Array} of two numbers: the screen row, and the screen column.
#
# Returns the new {Cursor}.
addCursorAtScreenPosition: (screenPosition) -> @activeEditSession.addCursorAtScreenPosition(screenPosition)
# Public: Adds a cursor at the provided `bufferPosition`.
#
# bufferPosition - An {Array} of two numbers: the buffer row, and the buffer column.
#
# Returns the new {Cursor}.
addCursorAtBufferPosition: (bufferPosition) -> @activeEditSession.addCursorAtBufferPosition(bufferPosition)
# Public: Moves every cursor up one row.
moveCursorUp: -> @activeEditSession.moveCursorUp()
# Public: Moves every cursor down one row.
moveCursorDown: -> @activeEditSession.moveCursorDown()
# Public: Moves every cursor left one column.
moveCursorLeft: -> @activeEditSession.moveCursorLeft()
# Public: Moves every cursor right one column.
moveCursorRight: -> @activeEditSession.moveCursorRight()
# Public: Moves every cursor to the beginning of the current word.
moveCursorToBeginningOfWord: -> @activeEditSession.moveCursorToBeginningOfWord()
# Public: Moves every cursor to the end of the current word.
moveCursorToEndOfWord: -> @activeEditSession.moveCursorToEndOfWord()
# Public: Moves the cursor to the beginning of the next word.
moveCursorToBeginningOfNextWord: -> @activeEditSession.moveCursorToBeginningOfNextWord()
# Public: Moves every cursor to the top of the buffer.
moveCursorToTop: -> @activeEditSession.moveCursorToTop()
# Public: Moves every cursor to the bottom of the buffer.
moveCursorToBottom: -> @activeEditSession.moveCursorToBottom()
# Public: Moves every cursor to the beginning of the line.
moveCursorToBeginningOfLine: -> @activeEditSession.moveCursorToBeginningOfLine()
# Public: Moves every cursor to the first non-whitespace character of the line.
moveCursorToFirstCharacterOfLine: -> @activeEditSession.moveCursorToFirstCharacterOfLine()
# Public: Moves every cursor to the end of the line.
moveCursorToEndOfLine: -> @activeEditSession.moveCursorToEndOfLine()
# Public: Moves the selected line up one row.
moveLineUp: -> @activeEditSession.moveLineUp()
# Public: Moves the selected line down one row.
moveLineDown: -> @activeEditSession.moveLineDown()
# Public: Sets the cursor based on a given screen position.
#
# position - An {Array} of two numbers: the screen row, and the screen column.
# options - An object with properties based on {Cursor.setScreenPosition}.
#
setCursorScreenPosition: (position, options) -> @activeEditSession.setCursorScreenPosition(position, options)
# Public: Duplicates the current line.
#
# If more than one cursor is present, only the most recently added one is considered.
duplicateLine: -> @activeEditSession.duplicateLine()
# Public: Joins the current line with the one below it.
#
# Multiple cursors are considered equally. If there's a selection in the editor,
# all the lines are joined together.
joinLine: -> @activeEditSession.joinLine()
# Public: Gets the current screen position.
#
# Returns an {Array} of two numbers: the screen row, and the screen column.
getCursorScreenPosition: -> @activeEditSession.getCursorScreenPosition()
# Public: Gets the current screen row.
#
# Returns a {Number}.
getCursorScreenRow: -> @activeEditSession.getCursorScreenRow()
# Public: Sets the cursor based on a given buffer position.
#
# position - An {Array} of two numbers: the buffer row, and the buffer column.
# options - An object with properties based on {Cursor.setBufferPosition}.
#
setCursorBufferPosition: (position, options) -> @activeEditSession.setCursorBufferPosition(position, options)
# Public: Gets the current buffer position of the cursor.
#
# Returns an {Array} of two numbers: the buffer row, and the buffer column.
getCursorBufferPosition: -> @activeEditSession.getCursorBufferPosition()
# Public: Retrieves the range for the current paragraph.
#
# A paragraph is defined as a block of text surrounded by empty lines.
#
# Returns a {Range}.
getCurrentParagraphBufferRange: -> @activeEditSession.getCurrentParagraphBufferRange()
# Public: Gets the word located under the cursor.
#
# options - An object with properties based on {Cursor.getBeginningOfCurrentWordBufferPosition}.
#
# Returns a {String}.
getWordUnderCursor: (options) -> @activeEditSession.getWordUnderCursor(options)
# Public: Gets the selection at the specified index.
#
# index - The id {Number} of the selection
#
# Returns a {Selection}.
getSelection: (index) -> @activeEditSession.getSelection(index)
# Public: Gets the last selection, _i.e._ the most recently added.
#
# Returns a {Selection}.
getSelections: -> @activeEditSession.getSelections()
# Public: Gets all selections, ordered by their position in the buffer.
#
# Returns an {Array} of {Selection}s.
getSelectionsOrderedByBufferPosition: -> @activeEditSession.getSelectionsOrderedByBufferPosition()
# Public: Gets the very last selection, as it's ordered in the buffer.
#
# Returns a {Selection}.
getLastSelectionInBuffer: -> @activeEditSession.getLastSelectionInBuffer()
# Public: Gets the currently selected text.
#
# Returns a {String}.
getSelectedText: -> @activeEditSession.getSelectedText()
# Public: Gets the buffer ranges of all the {Selection}s.
#
# This is ordered by their buffer position.
#
# Returns an {Array} of {Range}s.
getSelectedBufferRanges: -> @activeEditSession.getSelectedBufferRanges()
# Public: Gets the buffer range of the most recently added {Selection}.
#
# Returns a {Range}.
getSelectedBufferRange: -> @activeEditSession.getSelectedBufferRange()
# Public: Given a buffer range, this removes all previous selections and creates a new selection for it.
#
# bufferRange - A {Range} in the buffer
# options - A hash of options
setSelectedBufferRange: (bufferRange, options) -> @activeEditSession.setSelectedBufferRange(bufferRange, options)
# Public: Given an array of buffer ranges, this removes all previous selections and creates new selections for them.
#
# bufferRanges - An {Array} of {Range}s in the buffer
# options - A hash of options
setSelectedBufferRanges: (bufferRanges, options) -> @activeEditSession.setSelectedBufferRanges(bufferRanges, options)
# Public: Given a buffer range, this adds a new selection for it.
#
# bufferRange - A {Range} in the buffer
@@ -334,38 +372,55 @@ class Editor extends View
#
# Returns the new {Selection}.
addSelectionForBufferRange: (bufferRange, options) -> @activeEditSession.addSelectionForBufferRange(bufferRange, options)
# Public: Selects the text one position right of the cursor.
selectRight: -> @activeEditSession.selectRight()
# Public: Selects the text one position left of the cursor.
selectLeft: -> @activeEditSession.selectLeft()
# Public: Selects all the text one position above the cursor.
selectUp: -> @activeEditSession.selectUp()
# Public: Selects all the text one position below the cursor.
selectDown: -> @activeEditSession.selectDown()
# Public: Selects all the text from the current cursor position to the top of the buffer.
selectToTop: -> @activeEditSession.selectToTop()
# Public: Selects all the text from the current cursor position to the bottom of the buffer.
selectToBottom: -> @activeEditSession.selectToBottom()
# Public: Selects all the text in the buffer.
selectAll: -> @activeEditSession.selectAll()
# Public: Selects all the text from the current cursor position to the beginning of the line.
selectToBeginningOfLine: -> @activeEditSession.selectToBeginningOfLine()
# Public: Selects all the text from the current cursor position to the end of the line.
selectToEndOfLine: -> @activeEditSession.selectToEndOfLine()
# Public: Moves the current selection down one row.
addSelectionBelow: -> @activeEditSession.addSelectionBelow()
# Public: Moves the current selection up one row.
addSelectionAbove: -> @activeEditSession.addSelectionAbove()
# Public: Selects all the text from the current cursor position to the beginning of the word.
selectToBeginningOfWord: -> @activeEditSession.selectToBeginningOfWord()
# Public: Selects all the text from the current cursor position to the end of the word.
selectToEndOfWord: -> @activeEditSession.selectToEndOfWord()
# Public: Selects all the text from the current cursor position to the beginning of the next word.
selectToBeginningOfNextWord: -> @activeEditSession.selectToBeginningOfNextWord()
# Public: Selects the current word.
selectWord: -> @activeEditSession.selectWord()
# Public: Selects the current line.
selectLine: -> @activeEditSession.selectLine()
# Public: Selects the text from the current cursor position to a given position.
#
# position - An instance of {Point}, with a given `row` and `column`.
@@ -376,64 +431,89 @@ class Editor extends View
# to the position of the selection after it. The last selection is transferred to the
# position of the first.
transpose: -> @activeEditSession.transpose()
# Public: Turns the current selection into upper case.
upperCase: -> @activeEditSession.upperCase()
# Public: Turns the current selection into lower case.
lowerCase: -> @activeEditSession.lowerCase()
# Public: Clears every selection. TODO
clearSelections: -> @activeEditSession.clearSelections()
# Public: Performs a backspace, removing the character found behind the cursor position.
backspace: -> @activeEditSession.backspace()
# Public: Performs a backspace to the beginning of the current word, removing characters found there.
backspaceToBeginningOfWord: -> @activeEditSession.backspaceToBeginningOfWord()
# Public: Performs a backspace to the beginning of the current line, removing characters found there.
backspaceToBeginningOfLine: -> @activeEditSession.backspaceToBeginningOfLine()
# Public: Performs a delete, removing the character found ahead the cursor position.
delete: -> @activeEditSession.delete()
# Public: Performs a delete to the end of the current word, removing characters found there.
deleteToEndOfWord: -> @activeEditSession.deleteToEndOfWord()
# Public: Performs a delete to the end of the current line, removing characters found there.
deleteLine: -> @activeEditSession.deleteLine()
# Public: Performs a cut to the end of the current line.
#
# Characters are removed, but the text remains in the clipboard.
cutToEndOfLine: -> @activeEditSession.cutToEndOfLine()
# Public: Inserts text at the current cursor positions.
#
# text - A {String} representing the text to insert.
# options - A set of options equivalent to {Selection.insertText}.
insertText: (text, options) -> @activeEditSession.insertText(text, options)
# Public: Inserts a new line at the current cursor positions.
insertNewline: -> @activeEditSession.insertNewline()
# Internal:
consolidateSelections: (e) -> e.abortKeyBinding() unless @activeEditSession.consolidateSelections()
# Public: Inserts a new line below the current cursor positions.
insertNewlineBelow: -> @activeEditSession.insertNewlineBelow()
# Public: Inserts a new line above the current cursor positions.
insertNewlineAbove: -> @activeEditSession.insertNewlineAbove()
# Public: Indents the current line.
#
# options - A set of options equivalent to {Selection.indent}.
indent: (options) -> @activeEditSession.indent(options)
# Public: TODO
autoIndent: (options) -> @activeEditSession.autoIndentSelectedRows()
# Public: Indents the selected rows.
indentSelectedRows: -> @activeEditSession.indentSelectedRows()
# Public: Outdents the selected rows.
outdentSelectedRows: -> @activeEditSession.outdentSelectedRows()
# Public: Cuts the selected text.
cutSelection: -> @activeEditSession.cutSelectedText()
# Public: Copies the selected text.
copySelection: -> @activeEditSession.copySelectedText()
# Public: Pastes the text in the clipboard.
#
# options - A set of options equivalent to {Selection.insertText}.
paste: (options) -> @activeEditSession.pasteText(options)
# Public: Undos the last {Buffer} change.
undo: -> @activeEditSession.undo()
# Public: Redos the last {Buffer} change.
redo: -> @activeEditSession.redo()
# Public: Creates a new fold between two row numbers.
#
# startRow - The row {Number} to start folding at
@@ -441,36 +521,46 @@ class Editor extends View
#
# Returns the new {Fold}.
createFold: (startRow, endRow) -> @activeEditSession.createFold(startRow, endRow)
# Public: Folds the current row.
foldCurrentRow: -> @activeEditSession.foldCurrentRow()
# Public: Unfolds the current row.
unfoldCurrentRow: -> @activeEditSession.unfoldCurrentRow()
# Public: Folds all the rows.
foldAll: -> @activeEditSession.foldAll()
# Public: Unfolds all the rows.
unfoldAll: -> @activeEditSession.unfoldAll()
# Public: Folds the most recent selection.
foldSelection: -> @activeEditSession.foldSelection()
# Public: Given the id of a {Fold}, this removes it.
#
# foldId - The fold id {Number} to remove
destroyFold: (foldId) -> @activeEditSession.destroyFold(foldId)
# Public: Removes any {Fold}s found that contain the given buffer row.
#
# bufferRow - The buffer row {Number} to check against
destroyFoldsContainingBufferRow: (bufferRow) -> @activeEditSession.destroyFoldsContainingBufferRow(bufferRow)
# Public: Determines if the given screen row is folded.
#
# screenRow - A {Number} indicating the screen row.
#
# Returns `true` if the screen row is folded, `false` otherwise.
isFoldedAtScreenRow: (screenRow) -> @activeEditSession.isFoldedAtScreenRow(screenRow)
# Public: Determines if the given buffer row is folded.
#
# screenRow - A {Number} indicating the buffer row.
#
# Returns `true` if the buffer row is folded, `false` otherwise.
isFoldedAtBufferRow: (bufferRow) -> @activeEditSession.isFoldedAtBufferRow(bufferRow)
# Public: Determines if the given row that the cursor is at is folded.
#
# Returns `true` if the row is folded, `false` otherwise.
@@ -482,6 +572,7 @@ class Editor extends View
#
# Returns a {String}.
lineForScreenRow: (screenRow) -> @activeEditSession.lineForScreenRow(screenRow)
# Public: Gets the lines for the given screen row boundaries.
#
# start - A {Number} indicating the beginning screen row.
@@ -489,24 +580,29 @@ class Editor extends View
#
# Returns an {Array} of {String}s.
linesForScreenRows: (start, end) -> @activeEditSession.linesForScreenRows(start, end)
# Public: Gets the number of screen rows.
#
# Returns a {Number}.
screenLineCount: -> @activeEditSession.screenLineCount()
getScreenLineCount: -> @activeEditSession.getScreenLineCount()
# Public: Defines the limit at which the buffer begins to soft wrap text.
#
# softWrapColumn - A {Number} defining the soft wrap limit
setSoftWrapColumn: (softWrapColumn) ->
softWrapColumn ?= @calcSoftWrapColumn()
@activeEditSession.setSoftWrapColumn(softWrapColumn) if softWrapColumn
# Public: Gets the length of the longest screen line.
#
# Returns a {Number}.
maxScreenLineLength: -> @activeEditSession.maxScreenLineLength()
# Public: Gets the text in the last screen row.
#
# Returns a {String}.
getLastScreenRow: -> @activeEditSession.getLastScreenRow()
# Public: Given a position, this clips it to a real position.
#
# For example, if `position`'s row exceeds the row count of the buffer,
@@ -553,6 +649,7 @@ class Editor extends View
#
# Returns a {Range}.
bufferRangeForScreenRange: (range) -> @activeEditSession.bufferRangeForScreenRange(range)
# Public: Given a starting and ending row, this converts every row into a buffer position.
#
# startRow - The row {Number} to start at
@@ -560,13 +657,17 @@ class Editor extends View
#
# Returns an {Array} of {Range}s.
bufferRowsForScreenRows: (startRow, endRow) -> @activeEditSession.bufferRowsForScreenRows(startRow, endRow)
# Public: Gets the number of the last row in the buffer.
#
# Returns a {Number}.
getLastScreenRow: -> @activeEditSession.getLastScreenRow()
# Internal:
logCursorScope: ->
console.log @activeEditSession.getCursorScopes()
# Public: Emulates the "page down" key, where the last row of a buffer scrolls to become the first.
pageDown: ->
newScrollTop = @scrollTop() + @scrollView[0].clientHeight
@@ -618,48 +719,58 @@ class Editor extends View
# Public: Checks out the current HEAD revision of the file.
checkoutHead: -> @getBuffer().checkoutHead()
# Public: Replaces the current buffer contents.
#
# text - A {String} containing the new buffer contents.
setText: (text) -> @activeEditSession.setText(text)
# Public: Retrieves the current buffer contents.
#
# Returns a {String}.
getText: -> @activeEditSession.getText()
# Public: Retrieves the current buffer's file path.
#
# Returns a {String}.
getPath: -> @activeEditSession?.getPath()
# Public: Gets the number of lines in a file.
#
# Returns a {Number}.
getLineCount: -> @getBuffer().getLineCount()
# Public: Gets the row number of the last line.
#
# Returns a {Number}.
getLastBufferRow: -> @getBuffer().getLastRow()
# Public: Given a range, returns the lines of text within it.
#
# range - A {Range} object specifying your points of interest
#
# Returns a {String} of the combined lines.
getTextInRange: (range) -> @getBuffer().getTextInRange(range)
# Public: Finds the last point in the current buffer.
#
# Returns a {Point} representing the last position.
getEofPosition: -> @getBuffer().getEofPosition()
# Public: Given a row, returns the line of text.
#
# row - A {Number} indicating the row.
#
# Returns a {String}.
lineForBufferRow: (row) -> @getBuffer().lineForRow(row)
# Public: Given a row, returns the length of the line of text.
#
# row - A {Number} indicating the row
#
# Returns a {Number}.
lineLengthForBufferRow: (row) -> @getBuffer().lineLengthForRow(row)
# Public: Given a buffer row, this retrieves the range for that line.
#
# row - A {Number} identifying the row
@@ -668,12 +779,14 @@ class Editor extends View
#
# Returns a {Range}.
rangeForBufferRow: (row) -> @getBuffer().rangeForRow(row)
# Public: Scans for text in the buffer, calling a function on each match.
#
# regex - A {RegExp} representing the text to find
# range - A {Range} in the buffer to search within
# iterator - A {Function} that's called on each match
scanInBufferRange: (args...) -> @getBuffer().scanInRange(args...)
# Public: Scans for text in the buffer _backwards_, calling a function on each match.
#
# regex - A {RegExp} representing the text to find
@@ -887,7 +1000,7 @@ class Editor extends View
# Public: Scrolls the editor to the bottom.
scrollToBottom: ->
@scrollBottom(@screenLineCount() * @lineHeight)
@scrollBottom(@getScreenLineCount() * @lineHeight)
# Public: Scrolls the editor to the position of the most recently added cursor.
#
@@ -1042,14 +1155,17 @@ class Editor extends View
#
# fontFamily - A {String} identifying the CSS `font-family`,
setFontFamily: (fontFamily) ->
return if fontFamily == undefined
headTag = $("head")
styleTag = headTag.find("style.editor-font-family")
if styleTag.length == 0
styleTag = $$ -> @style class: 'editor-font-family'
headTag.append styleTag
styleTag.text(".editor {font-family: #{fontFamily}}")
if fontFamily?
if styleTag.length == 0
styleTag = $$ -> @style class: 'editor-font-family'
headTag.append styleTag
styleTag.text(".editor {font-family: #{fontFamily}}")
else
styleTag.remove()
@redraw()
# Public: Gets the font family for the editor.
@@ -1156,7 +1272,7 @@ class Editor extends View
fragment.remove()
updateLayerDimensions: ->
height = @lineHeight * @screenLineCount()
height = @lineHeight * @getScreenLineCount()
unless @layerHeight == height
@renderedLines.height(height)
@underlayer.css('min-height', height)
@@ -1281,7 +1397,7 @@ class Editor extends View
intactRanges = [{start: @firstRenderedScreenRow, end: @lastRenderedScreenRow, domStart: 0}]
if @showIndentGuide
if not @mini and @showIndentGuide
trailingEmptyLineChanges = []
for change in @pendingChanges
continue unless change.bufferDelta?
@@ -1497,7 +1613,7 @@ class Editor extends View
updateScopeStack(token.scopes)
hasLeadingWhitespace = position < firstNonWhitespacePosition
hasTrailingWhitespace = position + token.value.length > firstTrailingWhitespacePosition
hasIndentGuide = @showIndentGuide and (hasLeadingWhitespace or lineIsWhitespaceOnly)
hasIndentGuide = not @mini and @showIndentGuide and (hasLeadingWhitespace or lineIsWhitespaceOnly)
line.push(token.getValueAsHtml({invisibles, hasLeadingWhitespace, hasTrailingWhitespace, hasIndentGuide}))
position += token.value.length
+26
Ver Arquivo
@@ -0,0 +1,26 @@
ConfigPanel = require 'config-panel'
{$$} = require 'space-pen'
$ = require 'jquery'
_ = require 'underscore'
###
# Internal #
###
module.exports =
class GeneralConfigPanel extends ConfigPanel
@content: ->
@form id: 'general-config-panel', class: 'form-horizontal', =>
@fieldset =>
@legend "General Settings"
@div class: 'control-group', =>
@div class: 'checkbox', =>
@label for: 'editor.hideGitIgnoredFiles', =>
@input id: 'editor.hideGitIgnoredFiles', type: 'checkbox'
@text 'Hide Git-Ignored Files'
@div class: 'checkbox', =>
@label for: 'core.autosave', =>
@input id: 'core.autosave', type: 'checkbox'
@text 'Auto-Save on Focus Change'
+6 -5
Ver Arquivo
@@ -10,6 +10,7 @@ GitUtils = require 'git-utils'
# Ultimately, this is an overlay to the native [git-utils](https://github.com/atom/node-git) model.
module.exports =
class Git
# Public: Creates a new `Git` instance.
#
# path - The git repository to open
@@ -98,7 +99,7 @@ class Git
getWorkingDirectory: ->
@getRepo().getWorkingDirectory()
# Public: Retrieves the reference or SHA-1 that `HEAD` points to.
# Public: Retrieves the reference or SHA-1 that `HEAD` points to.
#
# This can be `refs/heads/master`, or a full SHA-1 if the repository is in a detached `HEAD` state.
#
@@ -170,7 +171,7 @@ class Git
relativize: (path) ->
@getRepo().relativize(path)
# Public: Retrieves a shortened version of {.getHead}.
# Public: Retrieves a shortened version of {.getHead}.
#
# This removes the leading segments of `refs/heads`, `refs/tags`, or `refs/remotes`.
# It also shortenes the SHA-1 of a detached `HEAD` to 7 characters.
@@ -179,7 +180,7 @@ class Git
getShortHead: ->
@getRepo().getShortHead()
# Public: Restore the contents of a path in the working directory and index to the version at `HEAD`.
# Public: Restore the contents of a path in the working directory and index to the version at `HEAD`.
#
# This is essentially the same as running:
# ```
@@ -239,7 +240,7 @@ class Git
#
# path - The {String} path (relative to the repository)
# text - The {String} to compare against the `HEAD` contents
#
#
# Returns an object with two keys, `ahead` and `behind`. These will always be greater than zero.
getLineDiffs: (path, text) ->
@getRepo().getLineDiffs(@relativize(path), text)
@@ -259,6 +260,6 @@ class Git
@statusTask.one 'task-completed', =>
@statusTask = null
@statusTask.start()
_.extend Git.prototype, Subscriber
_.extend Git.prototype, EventEmitter
+11 -17
Ver Arquivo
@@ -30,19 +30,11 @@ class Keymap
@bindingSetsByFirstKeystroke = {}
bindDefaultKeys: ->
@add
'body':
'meta-n': 'new-window'
'meta-,': 'open-user-configuration'
'meta-o': 'open'
'meta-O': 'open-dev'
'meta-w': 'core:close'
'alt-meta-i': 'toggle-dev-tools'
$(document).command 'new-window', => atom.newWindow()
$(document).command 'open-user-configuration', => atom.open(config.configDirPath)
$(document).command 'open-user-configuration', => atom.openConfig()
$(document).command 'open', => atom.open()
$(document).command 'open-dev', => atom.openDev()
$(document).command 'toggle-dev-tools', => atom.toggleDevTools()
loadBundledKeymaps: ->
@loadDirectory(fsUtils.resolveOnLoadPath('keymaps'))
@@ -52,23 +44,23 @@ class Keymap
loadDirectory: (directoryPath) ->
@load(filePath) for filePath in fsUtils.list(directoryPath, ['.cson', '.json'])
load: (path) ->
@add(path, CSON.readObject(path))
add: (args...) ->
name = args.shift() if args.length > 1
keymap = args.shift()
for selector, bindings of keymap
@bindKeys(name, selector, bindings)
remove: (name) ->
for bindingSet in @bindingSets.filter((bindingSet) -> bindingSet.name is name)
_.remove(@bindingSets, bindingSet)
for keystrokes of bindingSet.commandsByKeystrokes
keystroke = keystrokes.split(' ')[0]
_.remove(@bindingSetsByFirstKeystroke[keystroke], bindingSet)
bindKeys: (args...) ->
name = args.shift() if args.length > 2
[selector, bindings] = args
@@ -78,7 +70,7 @@ class Keymap
keystroke = keystrokes.split(' ')[0] # only index by first keystroke
@bindingSetsByFirstKeystroke[keystroke] ?= []
@bindingSetsByFirstKeystroke[keystroke].push(bindingSet)
unbindKeys: (selector, bindings) ->
bindingSet = _.detect @bindingSets, (bindingSet) ->
bindingSet.selector is selector and bindingSet.bindings is bindings
@@ -86,7 +78,7 @@ class Keymap
if bindingSet
console.log "binding set", bindingSet
_.remove(@bindingSets, bindingSet)
bindingsForElement: (element) ->
keystrokeMap = {}
currentNode = $(element)
@@ -112,7 +104,9 @@ class Keymap
candidateBindingSets = @bindingSetsForNode(currentNode, bindingSetsForFirstKeystroke)
for bindingSet in candidateBindingSets
command = bindingSet.commandForEvent(event)
if command
if command is 'native!'
return true
else if command
continue if @triggerCommandEvent(event, command)
return false
else if command == false
+25
Ver Arquivo
@@ -52,7 +52,32 @@
'meta-9': 'pane:show-item-9'
'meta-T': 'pane:reopen-closed-item'
'meta-n': 'new-window'
'meta-N': 'new-editor'
'meta-,': 'open-user-configuration'
'meta-o': 'open'
'meta-O': 'open-dev'
'meta-w': 'core:close'
'alt-meta-i': 'toggle-dev-tools'
'.tool-panel':
'meta-escape': 'tool-panel:unfocus'
'escape': 'core:close'
'meta-w': 'noop'
# allow standard input fields to work correctly
'input:not(.hidden-input)':
'left': 'native!'
'right': 'native!'
'tab': 'native!'
'shift-tab': 'native!'
'shift-left': 'native!'
'shift-right': 'native!'
'backspace': 'native!'
'shift-backspace': 'native!'
'delete': 'native!'
'meta-z': 'native!'
'meta-Z': 'native!'
'meta-x': 'native!'
'meta-c': 'native!'
'meta-v': 'native!'
+1
Ver Arquivo
@@ -41,4 +41,5 @@
'meta-+': 'image-view:zoom-in'
'meta-=': 'image-view:zoom-in'
'meta--': 'image-view:zoom-out'
'meta-_': 'image-view:zoom-out'
'meta-0': 'image-view:reset-zoom'
+9
Ver Arquivo
@@ -22,3 +22,12 @@
'alt-h': 'editor:backspace-to-beginning-of-word'
'alt-d': 'editor:delete-to-end-of-word'
'ctrl-k': 'editor:cut-to-end-of-line'
# allow standard input fields to work correctly
'input:not(.hidden-input)':
'ctrl-b': 'native!'
'ctrl-f': 'native!'
'ctrl-F': 'native!'
'ctrl-B': 'native!'
'ctrl-h': 'native!'
'ctrl-d': 'native!'
+48 -22
Ver Arquivo
@@ -11,9 +11,9 @@ Subscriber = require 'subscriber'
module.exports =
class LanguageMode
buffer = null
grammar = null
editSession = null
buffer: null
grammar: null
editSession: null
currentGrammarScore: null
# Public: Sets up a `LanguageMode` for the given {EditSession}.
@@ -21,28 +21,11 @@ class LanguageMode
# editSession - The {EditSession} to associate with
constructor: (@editSession) ->
@buffer = @editSession.buffer
@reloadGrammar()
@subscribe syntax, 'grammar-added', (grammar) =>
newScore = grammar.getScore(@buffer.getPath(), @buffer.getText())
@setGrammar(grammar, newScore) if newScore > @currentGrammarScore
# Internal:
destroy: ->
@unsubscribe()
setGrammar: (grammar, score) ->
return if grammar is @grammar
@unsubscribe(@grammar) if @grammar
@grammar = grammar
@currentGrammarScore = score ? grammar.getScore(@buffer.getPath(), @buffer.getText())
@subscribe @grammar, 'grammar-updated', => @trigger 'grammar-updated'
@trigger 'grammar-changed', grammar
reloadGrammar: ->
if grammar = syntax.selectGrammar(@buffer.getPath(), @buffer.getText())
@setGrammar(grammar)
else
throw new Error("No grammar found for path: #{path}")
# Public: Wraps the lines between two rows in comments.
#
@@ -91,6 +74,34 @@ class LanguageMode
for row in [start..end]
buffer.insert([row, 0], commentStartString)
# Public: Folds all the foldable lines in the buffer.
foldAll: ->
for currentRow in [0..@buffer.getLastRow()]
[startRow, endRow] = @rowRangeForFoldAtBufferRow(currentRow) ? []
continue unless startRow?
@editSession.createFold(startRow, endRow)
# Public: Unfolds all the foldable lines in the buffer.
unfoldAll: ->
for row in [@buffer.getLastRow()..0]
fold.destroy() for fold in @editSession.displayBuffer.foldsStartingAtBufferRow(row)
foldBufferRow: (bufferRow) ->
for currentRow in [bufferRow..0]
rowRange = @rowRangeForCommentAtBufferRow(currentRow)
rowRange ?= @rowRangeForFoldAtBufferRow(currentRow)
[startRow, endRow] = rowRange ? []
continue unless startRow? and startRow <= bufferRow <= endRow
fold = @editSession.displayBuffer.largestFoldStartingAtBufferRow(startRow)
return @editSession.createFold(startRow, endRow) unless fold
# Public: Given a buffer row, this unfolds it.
#
# bufferRow - A {Number} indicating the buffer row
unfoldBufferRow: (bufferRow) ->
@editSession.displayBuffer.largestFoldContainingBufferRow(bufferRow)?.destroy()
doesBufferRowStartFold: (bufferRow) ->
return false if @editSession.isBufferRowBlank(bufferRow)
nextNonEmptyRow = @editSession.nextNonBlankBufferRow(bufferRow)
@@ -114,9 +125,24 @@ class LanguageMode
[bufferRow, foldEndRow]
rowRangeForCommentAtBufferRow: (row) ->
return unless @editSession.displayBuffer.tokenizedBuffer.lineForScreenRow(row).isComment()
startRow = row
for currentRow in [row-1..0]
break if @buffer.isRowBlank(currentRow)
break unless @editSession.displayBuffer.tokenizedBuffer.lineForScreenRow(currentRow).isComment()
startRow = currentRow
endRow = row
for currentRow in [row+1..@buffer.getLastRow()]
break if @buffer.isRowBlank(currentRow)
break unless @editSession.displayBuffer.tokenizedBuffer.lineForScreenRow(currentRow).isComment()
endRow = currentRow
return [startRow, endRow] if startRow isnt endRow
# Public: Given a buffer row, this returns a suggested indentation level.
#
# The indentation level provided is based on the current {LanguageMode}.
# The indentation level provided is based on the current {LanguageMode}.
#
# bufferRow - A {Number} indicating the buffer row
#
+4 -2
Ver Arquivo
@@ -62,14 +62,14 @@ class LineMap
bufferRows
screenLineCount: ->
getScreenLineCount: ->
@screenLines.length
# Retrieves the last screen row in the buffer.
#
# Returns an {Integer}.
lastScreenRow: ->
@screenLineCount() - 1
@getScreenLineCount() - 1
clipScreenPosition: (screenPosition, options={}) ->
{ wrapBeyondNewlines, wrapAtSoftNewlines } = options
@@ -139,6 +139,7 @@ class LineMap
currentBufferRow = nextBufferRow
[screenRow, screenLines]
# Public: Given a buffer range, this converts it into a screen position.
#
# screenPosition - An object that represents a buffer position. It can be either
@@ -172,6 +173,7 @@ class LineMap
start = @screenPositionForBufferPosition(bufferRange.start)
end = @screenPositionForBufferPosition(bufferRange.end)
new Range(start, end)
# Public: Given a screen range, this converts it into a buffer position.
#
# screenRange - The {Range} to convert
+41
Ver Arquivo
@@ -0,0 +1,41 @@
ConfigPanel = require 'config-panel'
{$$} = require 'space-pen'
$ = require 'jquery'
_ = require 'underscore'
###
# Internal #
###
module.exports =
class PackageConfigPanel extends ConfigPanel
@content: ->
@div =>
@legend "Installed Packages"
@table id: 'packages', class: "table table-striped", =>
@thead =>
@tr =>
@th "Package Name"
@th class: 'package-enabled', "Enable"
@tbody outlet: 'packageTableBody', =>
for name in atom.getAvailablePackageNames().sort()
@tr name: name, =>
@td name
@td class: 'package-enabled', => @input type: 'checkbox'
initialize: ->
@on 'change', '#packages input[type=checkbox]', (e) ->
checkbox = $(e.target)
name = checkbox.closest('tr').attr('name')
if checkbox.attr('checked')
_.remove(config.get('core.disabledPackages'), name)
else
config.get('core.disabledPackages').push(name)
config.update()
@observeConfig 'core.disabledPackages', (disabledPackages) =>
@packageTableBody.find("input[type='checkbox']").attr('checked', true)
for name in disabledPackages
@packageTableBody.find("tr[name='#{name}'] input[type='checkbox']").attr('checked', false)
+4 -3
Ver Arquivo
@@ -1,15 +1,16 @@
Point = require 'point'
_ = require 'underscore'
# Public: Indicates a region within the editor.
# Public: Indicates a region within the editor.
#
# To better visualize how this works, imagine a rectangle.
# Each quadrant of the rectangle is analogus to a range, as ranges contain a
# Each quadrant of the rectangle is analogus to a range, as ranges contain a
# starting row and a starting column, as well as an ending row, and an ending column.
#
# Each `Range` is actually constructed of two `Point` objects, labelled `start` and `end`.
module.exports =
class Range
# Public: Constructs a `Range` from a given object.
#
# object - This can be an {Array} (`[startRow, startColumn, endRow, endColumn]`) or an object `{start: Point, end: Point}`
@@ -58,7 +59,7 @@ class Range
# Public: Identifies if two `Range`s are equal.
#
# All four points (`start.row`, `start.column`, `end.row`, `end.column`) must be
# All four points (`start.row`, `start.column`, `end.row`, `end.column`) must be
# equal for this method to return `true`.
#
# other - A different {Range} to check against
+5 -2
Ver Arquivo
@@ -23,6 +23,7 @@ class RootView extends View
@configDefaults:
ignoredNames: [".git", ".svn", ".DS_Store"]
disabledPackages: []
themes: ['atom-dark-ui', 'atom-dark-syntax']
###
# Internal:
@@ -33,13 +34,12 @@ class RootView extends View
@div id: 'horizontal', outlet: 'horizontal', =>
@div id: 'vertical', outlet: 'vertical', =>
@subview 'panes', panes ? new PaneContainer
@deserialize: ({ panes }) ->
panes = deserialize(panes) if panes?.deserializer is 'PaneContainer'
new RootView({panes})
initialize: ->
@command 'toggle-dev-tools', => atom.toggleDevTools()
@on 'focus', (e) => @handleFocus(e)
@subscribe $(window), 'focus', (e) =>
@handleFocus(e) if document.activeElement is document.body
@@ -74,6 +74,9 @@ class RootView extends View
@command 'pane:reopen-closed-item', =>
@panes.reopenItem()
@command 'new-editor', =>
@open()
serialize: ->
version: RootView.version
deserializer: 'RootView'
+21 -3
Ver Arquivo
@@ -117,6 +117,7 @@ class TextMateGrammar
ruleStack = new Array(ruleStack...) # clone ruleStack
tokens = []
position = 0
loop
scopes = scopesFromStack(ruleStack)
previousRuleStackLength = ruleStack.length
@@ -154,13 +155,30 @@ class TextMateGrammar
))
break
if position == previousPosition and ruleStack.length == previousRuleStackLength
console.error("Popping rule because it loops at column #{position} of line '#{line}'", _.clone(ruleStack))
ruleStack.pop()
if position == previousPosition
if ruleStack.length == previousRuleStackLength
console.error("Popping rule because it loops at column #{position} of line '#{line}'", _.clone(ruleStack))
ruleStack.pop()
[penultimateRule, lastRule] = ruleStack[-2..]
if lastRule? and penultimateRule.scopeName == lastRule.scopeName
ruleStack.pop()
tokens.push(new Token(
value: line[position...line.length]
scopes: scopes
))
break
ruleStack.forEach (rule) -> rule.clearAnchorPosition()
{ tokens, ruleStack }
tokenizeLines: (text) ->
lines = text.split('\n')
ruleStack = null
for line, i in lines
{ tokens, ruleStack } = @tokenizeLine(line, ruleStack, i is 0)
tokens
getMaxTokensPerLine: ->
@maxTokensPerLine
+2
Ver Arquivo
@@ -38,6 +38,8 @@ class TextMatePackage extends Package
for { selector, properties } in @scopedProperties
syntax.addProperties(@path, selector, properties)
activateConfig: -> # noop
deactivate: ->
syntax.removeGrammar(grammar) for grammar in @grammars
syntax.removeProperties(@path)
+73
Ver Arquivo
@@ -0,0 +1,73 @@
ConfigPanel = require 'config-panel'
{$$} = require 'space-pen'
$ = require 'jquery'
_ = require 'underscore'
###
# Internal #
###
window.jQuery = $
require 'jqueryui-browser/ui/jquery.ui.core'
require 'jqueryui-browser/ui/jquery.ui.widget'
require 'jqueryui-browser/ui/jquery.ui.mouse'
require 'jqueryui-browser/ui/jquery.ui.sortable'
require 'jqueryui-browser/ui/jquery.ui.draggable'
delete window.jQuery
module.exports =
class ThemeConfigPanel extends ConfigPanel
@content: ->
@div id: 'themes-config', =>
@legend "Themes"
@div id: 'theme-picker', =>
@div class: 'panel', =>
@div class: 'panel-heading', "Enabled Themes"
@ol id: 'enabled-themes', class: 'list-group list-group-flush', outlet: 'enabledThemes'
@div class: 'panel', =>
@div class: 'panel-heading', "Available Themes"
@ol id: 'available-themes', class: 'list-group list-group-flush', outlet: 'availableThemes'
constructor: ->
super
for name in atom.getAvailableThemeNames()
@availableThemes.append(@buildThemeLi(name, draggable: true))
@observeConfig "core.themes", (enabledThemes) =>
@enabledThemes.empty()
for name in enabledThemes ? []
@enabledThemes.append(@buildThemeLi(name))
@enabledThemes.sortable
receive: (e, ui) => @enabledThemeReceived($(ui.helper))
update: => @enabledThemesUpdated()
@on "click", "#enabled-themes .disable-theme", (e) =>
$(e.target).closest('li').remove()
@enabledThemesUpdated()
buildThemeLi: (name, {draggable} = {}) ->
li = $$ ->
@li class: 'list-group-item', name: name, =>
@div class: 'disable-theme pull-right'
@text name
if draggable
li.draggable
connectToSortable: '#enabled-themes'
appendTo: '#themes-config'
helper: (e) ->
target = $(e.target)
target.clone().width(target.width())
else
li
enabledThemeReceived: (helper) ->
name = helper.attr('name')
@enabledThemes.find("[name='#{name}']:not('.ui-draggable')").remove()
@enabledThemes.find(".ui-draggable").removeClass('ui-draggable')
enabledThemesUpdated: ->
config.set('core.themes', @getEnabledThemeNames())
getEnabledThemeNames: ->
$(li).attr('name') for li in @enabledThemes.children().toArray()
+32 -9
Ver Arquivo
@@ -14,7 +14,8 @@ module.exports =
class TokenizedBuffer
@idCounter: 1
languageMode: null
grammar: null
currentGrammarScore: null
tabLength: null
buffer: null
aceAdaptor: null
@@ -23,15 +24,36 @@ class TokenizedBuffer
invalidRows: null
visible: false
constructor: (@buffer, { @languageMode, @tabLength }) ->
constructor: (@buffer, { @tabLength } = {}) ->
@tabLength ?= 2
@id = @constructor.idCounter++
@subscribe syntax, 'grammar-added grammar-updated', (grammar) =>
if grammar.injectionSelector?
@resetScreenLines() if @hasTokenForSelector(grammar.injectionSelector)
else
newScore = grammar.getScore(@buffer.getPath(), @buffer.getText())
@setGrammar(grammar, newScore) if newScore > @currentGrammarScore
@on 'grammar-changed grammar-updated', => @resetScreenLines()
@subscribe @buffer, "changed.tokenized-buffer#{@id}", (e) => @handleBufferChange(e)
@reloadGrammar()
setGrammar: (grammar, score) ->
return if grammar is @grammar
@unsubscribe(@grammar) if @grammar
@grammar = grammar
@currentGrammarScore = score ? grammar.getScore(@buffer.getPath(), @buffer.getText())
@subscribe @grammar, 'grammar-updated', => @resetScreenLines()
@resetScreenLines()
@buffer.on "changed.tokenized-buffer#{@id}", (e) => @handleBufferChange(e)
@languageMode.on 'grammar-changed grammar-updated', => @resetScreenLines()
@subscribe syntax, 'grammar-updated grammar-added', (grammar) =>
if grammar.injectionSelector? and @hasTokenForSelector(grammar.injectionSelector)
@resetScreenLines()
@trigger 'grammar-changed', grammar
reloadGrammar: ->
if grammar = syntax.selectGrammar(@buffer.getPath(), @buffer.getText())
@setGrammar(grammar)
else
throw new Error("No grammar found for path: #{path}")
hasTokenForSelector: (selector) ->
for {tokens} in @screenLines
@@ -154,13 +176,13 @@ class TokenizedBuffer
buildPlaceholderScreenLineForRow: (row) ->
line = @buffer.lineForRow(row)
tokens = [new Token(value: line, scopes: [@languageMode.grammar.scopeName])]
tokens = [new Token(value: line, scopes: [@grammar.scopeName])]
new ScreenLine({tokens, @tabLength})
buildTokenizedScreenLineForRow: (row, ruleStack) ->
line = @buffer.lineForRow(row)
lineEnding = @buffer.lineEndingForRow(row)
{ tokens, ruleStack } = @languageMode.tokenizeLine(line, ruleStack, row is 0)
{ tokens, ruleStack } = @grammar.tokenizeLine(line, ruleStack, row is 0)
new ScreenLine({tokens, ruleStack, @tabLength, lineEnding})
lineForScreenRow: (row) ->
@@ -180,6 +202,7 @@ class TokenizedBuffer
@screenLines[position.row].tokenAtBufferColumn(position.column)
destroy: ->
@unsubscribe()
@buffer.off ".tokenized-buffer#{@id}"
iterateTokensInBufferRange: (bufferRange, iterator) ->
+34 -6
Ver Arquivo
@@ -35,27 +35,41 @@ window.setUpEnvironment = ->
requireStylesheet(nativeStylesheetPath)
# This method is only called when opening a real application window
window.startup = ->
window.startEditorWindow = ->
directory = _.find ['/opt/boxen', '/opt/github', '/usr/local'], (dir) -> fsUtils.isDirectory(dir)
if directory
installAtomCommand(fsUtils.join(directory, 'bin/atom'))
else
console.warn "Failed to install `atom` binary"
atom.windowMode = 'editor'
handleWindowEvents()
handleDragDrop()
config.load()
keymap.loadBundledKeymaps()
atom.loadThemes()
atom.loadPackages()
deserializeWindowState()
deserializeEditorWindow()
atom.activatePackages()
keymap.loadUserKeymaps()
atom.requireUserInitScript()
$(window).on 'beforeunload', -> shutdown(); false
$(window).on 'beforeunload', -> unloadEditorWindow(); false
$(window).focus()
window.shutdown = ->
window.startConfigWindow = ->
atom.windowMode = 'config'
handleWindowEvents()
config.load()
keymap.loadBundledKeymaps()
atom.loadThemes()
atom.loadPackages()
deserializeConfigWindow()
atom.activatePackageConfigs()
keymap.loadUserKeymaps()
$(window).on 'beforeunload', -> unloadConfigWindow(); false
$(window).focus()
window.unloadEditorWindow = ->
return if not project and not rootView
atom.setWindowState('pathToOpen', project.getPath())
atom.setWindowState('project', project.serialize())
@@ -88,6 +102,14 @@ window.installAtomCommand = (commandPath, done) ->
else
fs.chmod(commandPath, 0o755, commandPath)
window.unloadConfigWindow = ->
return if not configView
atom.setWindowState('configView', configView.serialize())
atom.saveWindowState()
configView.remove()
window.configView = null
$(window).off('focus blur before')
window.handleWindowEvents = ->
$(window).command 'window:toggle-full-screen', => atom.toggleFullScreen()
$(window).on 'focus', -> $("body").removeClass('is-blurred')
@@ -107,7 +129,7 @@ window.onDrop = (e) ->
for file in e.originalEvent.dataTransfer.files
atom.open(file.path)
window.deserializeWindowState = ->
window.deserializeEditorWindow = ->
RootView = require 'root-view'
Project = require 'project'
Git = require 'git'
@@ -130,8 +152,14 @@ window.deserializeWindowState = ->
window.git?.destroy()
window.git = Git.open(project.getPath())
window.deserializeConfigWindow = ->
ConfigView = require 'config-view'
windowState = atom.getWindowState()
window.configView = deserialize(windowState.configView) ? new ConfigView()
$(rootViewParentSelector).append(configView)
window.stylesheetElementForId = (id) ->
$("head style[id='#{id}']")
$("""head style[id="#{id}"]""")
window.resolveStylesheet = (path) ->
if fsUtils.extension(path).length > 0
+8
Ver Arquivo
@@ -0,0 +1,8 @@
date = new Date().getTime()
require 'atom'
require 'window'
window.setUpEnvironment()
window.startConfigWindow()
atom.show()
console.log "Load time: #{new Date().getTime() - date}"
@@ -6,8 +6,8 @@ module.exports =
class CommandLoggerView extends ScrollView
@content: (rootView) ->
@div class: 'command-logger', tabindex: -1, =>
@h1 class: 'category-header', outlet: 'categoryHeader'
@h1 class: 'category-summary', outlet: 'categorySummary'
@h4 class: 'category-header', outlet: 'categoryHeader'
@h5 class: 'category-summary', outlet: 'categorySummary'
@div class: 'tree-map', outlet: 'treeMap'
eventLog: null
@@ -35,6 +35,7 @@ module.exports =
{@eventLog}
createView: ->
unless @commandLoggerView
CommandLoggerView = require 'command-logger/lib/command-logger-view'
unless @commandLoggerView?
CommandLoggerView = require './command-logger-view'
@commandLoggerView = new CommandLoggerView
@commandLoggerView
@@ -4,6 +4,7 @@ RegexAddress = require './commands/regex-address'
CompositeCommand = require './commands/composite-command'
PreviewList = require './preview-list'
Editor = require 'editor'
EditSession = require 'edit-session'
{SyntaxError} = require('pegjs').parser
_ = require 'underscore'
@@ -122,7 +123,9 @@ class CommandPanelView extends View
@errorMessages.empty()
try
@commandInterpreter.eval(command, rootView.getActivePaneItem()).done ({operationsToPreview, errorMessages}) =>
activePaneItem = rootView.getActivePaneItem()
editSession = activePaneItem if activePaneItem instanceof EditSession
@commandInterpreter.eval(command, editSession).done ({operationsToPreview, errorMessages}) =>
@loadingMessage.hide()
@history.push(command)
@historyIndex = @history.length
@@ -548,3 +548,13 @@ describe "CommandPanel", ->
previewList.trigger 'command-panel:expand-result'
expect(previewList.find('li.path:first-child ul.matches')).toBeVisible()
expect(previewList.find('li.path:first-child')).toHaveClass 'selected'
describe "when the active pane item is not an EditSession", ->
it "doesn't throw an error (regression)", ->
rootView.open('binary-file.png')
rootView.trigger 'command-panel:toggle'
executePromise = null
expect(-> executePromise = commandPanel.execute('Xx/sort/')).not.toThrow()
waitsForPromise -> executePromise
+30
Ver Arquivo
@@ -79,6 +79,36 @@
'name': 'markup.code.css.gfm'
'patterns': ['include': 'source.css']
}
{
'begin': '^```xml$'
'beginCaptures':
'0': 'name': 'support.gfm'
'end': '^```$'
'endCaptures':
'0': 'name': 'support.gfm'
'name': 'markup.code.xml.gfm'
'patterns': ['include': 'text.xml']
}
{
'begin': '^```(ruby|rb)$'
'beginCaptures':
'0': 'name': 'support.gfm'
'end': '^```$'
'endCaptures':
'0': 'name': 'support.gfm'
'name': 'markup.code.ruby.gfm'
'patterns': ['include': 'source.ruby']
}
{
'begin': '^```java$'
'beginCaptures':
'0': 'name': 'support.gfm'
'end': '^```$'
'endCaptures':
'0': 'name': 'support.gfm'
'name': 'markup.code.java.gfm'
'patterns': ['include': 'source.java']
}
{
'begin': '^```.*$'
'beginCaptures':
@@ -192,8 +192,7 @@ describe "StatusBar", ->
it "hides the label when the current grammar is the null grammar", ->
rootView.attachToDom()
editor.activeEditSession.languageMode.grammar = syntax.nullGrammar
editor.activeEditSession.trigger 'grammar-changed'
editor.activeEditSession.setGrammar(syntax.nullGrammar)
expect(statusBar.find('.grammar-name')).toBeHidden()
editor.reloadGrammar()
expect(statusBar.find('.grammar-name')).toBeVisible()
+7 -2
Ver Arquivo
@@ -106,8 +106,13 @@ module.exports =
done(null, paths)
filterExtensions: (paths, extensions) ->
extensions = extensions.map (ext) -> '.' + ext.replace(/^\./, '')
paths.filter (path) => _.include(extensions, @extension(path))
extensions = extensions.map (ext) ->
if ext is ''
ext
else
'.' + ext.replace(/^\./, '')
paths.filter (path) =>
_.include(extensions, @extension(path))
listTree: (rootPath) ->
paths = []
+5 -2
Ver Arquivo
@@ -62,7 +62,7 @@ _.mixin
humanizeEventName: (eventName, eventDoc) ->
[namespace, event] = eventName.split(':')
return _.capitalize(namespace) unless event?
return _.undasherize(namespace) unless event?
namespaceDoc = _.undasherize(namespace)
eventDoc ?= _.undasherize(event)
@@ -139,7 +139,10 @@ _.mixin
key = keys.shift()
object[key] ?= {}
object = object[key]
object[keys.shift()] = value
if value?
object[keys.shift()] = value
else
delete object[keys.shift()]
compactObject: (object) ->
newObject = {}
+1 -1
Ver Arquivo
@@ -4,6 +4,6 @@ require 'atom'
require 'window'
window.setUpEnvironment()
window.startup()
window.startEditorWindow()
setTimeout((-> atom.show()), 0)
console.log "Load time: #{new Date().getTime() - date}"
+1
Ver Arquivo
@@ -1,5 +1,6 @@
@import "bootstrap/less/bootstrap.less";
@import "root-view.less";
@import "config.less";
@import "overlay.less";
@import "popover-list.less";
@import "notification.less";
+145
Ver Arquivo
@@ -0,0 +1,145 @@
@import "bootstrap/less/variables.less";
@import "octicon-mixins.less";
#config-view {
height: 100%;
width: 100%;
background: white;
display: -webkit-flex;
#config-menu {
display: -webkit-flex;
-webkit-flex-direction: column;
#panels-menu {
width: 150px;
margin-left: @line-height-base;
margin-top: @line-height-base;
-webkit-flex-grow: 1;
li a {
cursor: pointer;
}
}
#open-dot-atom {
width: 150px;
margin-left: @line-height-base;
margin-bottom: @line-height-base;
}
}
#panels {
-webkit-flex: 1;
-webkit-flex-flow: column;
display: -webkit-flex;
padding: @line-height-base;
position: relative;
overflow-y: auto;
> div {
-webkit-flex: 1;
}
.editor {
padding-left: 0.25em;
border: 1px solid #aaa;
box-shadow: 1px 1px 1px 0 #888 inset;
}
}
#themes-config {
height: 100%;
display: -webkit-flex;
-webkit-flex-flow: column;
#theme-picker {
-webkit-flex: 1;
display: -webkit-flex;
min-height: 0;
.panel {
-webkit-flex: 1;
display: -webkit-flex;
-webkit-flex-flow: column;
min-height: 0;
&:first-child { margin-right: @line-height-base / 2; }
&:last-child { margin-left: @line-height-base / 2; }
.panel-heading {
margin-bottom: 0;
}
ol {
margin-top: 0;
-webkit-flex: 1;
min-height: 0;
overflow: auto;
li {
-webkit-user-select: none;
cursor: default;
padding-right: 15px;
&:first-child { border-top: 0; }
}
}
#enabled-themes {
li:hover .disable-theme {
.mini-icon(x);
color: #888;
cursor: pointer;
&:hover { color: #000; }
}
}
}
}
li.ui-draggable-dragging, li.ui-sortable-helper {
border: 0;
box-sizing: content-box;
background: white;
border-radius: 0;
box-shadow: 0 0 5px rgba(0, 0, 0, .5);
}
/* li.ui-draggable-dragging, li.ui-sortable-helper {
width: 300px;
background: white;
border: 1px solid #eee;
padding: 10px;
}
ol {
box-sizing: border-box;
height: 400px;
overflow-y: auto;
border: 1px solid #ccc;
border-top-width: 0;
background: #fafafa;
li {
padding: 10px;
border-bottom: 1px solid #eee;
background: white;
input[type='checkbox'] {
margin-right: 10px;
}
.close-icon {
display: none;
}
}
}*/
}
#packages {
white-space: nowrap;
.package-enabled {
width: 30px;
text-align: center;
}
}
}
+1
Ver Arquivo
@@ -11,5 +11,6 @@
border: 2px solid;
background-image: url(images/transparent-background.gif);
position: relative;
max-width: none;
}
}
-4
Ver Arquivo
@@ -7,14 +7,10 @@
.command-logger .category-header {
text-align: center;
padding-bottom: 5px;
font-size: 16px;
}
.command-logger .category-summary {
text-align: center;
padding-bottom: 10px;
font-size: 12px;
}
.command-logger .tree-map {
+3 -2
Ver Arquivo
@@ -1,4 +1,5 @@
jQuery = require('jquery');
(function(jQuery) {
jasmine.JQuery = function() {};
jasmine.JQuery.browserTagCaseIndependentHtml = function(html) {
@@ -174,4 +175,4 @@ beforeEach(function() {
afterEach(function() {
jasmine.JQuery.events.cleanUp();
});
})(require('jquery'));