Showing preview only (1,501K chars total). Download the full file or copy to clipboard to get everything.
Repository: jigish/slate
Branch: master
Commit: ff5ee5a53afc
Files: 483
Total size: 12.6 MB
Directory structure:
gitextract_axgbmzp9/
├── .gitignore
├── .gitmodules
├── .rbenv-version
├── LICENSE
├── README.md
├── Slate/
│ ├── ASCIIToCode.plist
│ ├── ASCIIToCode_Azerty.plist
│ ├── ASCIIToCode_Colemak.plist
│ ├── ASCIIToCode_Dvorak.plist
│ ├── AccessibilityWrapper.h
│ ├── AccessibilityWrapper.m
│ ├── ActivateSnapshotOperation.h
│ ├── ActivateSnapshotOperation.m
│ ├── ApplicationOptions.h
│ ├── ApplicationOptions.m
│ ├── Binding.h
│ ├── Binding.m
│ ├── ChainOperation.h
│ ├── ChainOperation.m
│ ├── ConfigurationHelperView.h
│ ├── ConfigurationHelperView.m
│ ├── Constants.h
│ ├── Constants.m
│ ├── CornerOperation.h
│ ├── CornerOperation.m
│ ├── DeleteSnapshotOperation.h
│ ├── DeleteSnapshotOperation.m
│ ├── ExpressionPoint.h
│ ├── ExpressionPoint.m
│ ├── FocusOperation.h
│ ├── FocusOperation.m
│ ├── GridCellView.h
│ ├── GridCellView.m
│ ├── GridOperation.h
│ ├── GridOperation.m
│ ├── GridView.h
│ ├── GridView.m
│ ├── GridWindow.h
│ ├── GridWindow.m
│ ├── HintOperation.h
│ ├── HintOperation.m
│ ├── HintView.h
│ ├── HintView.m
│ ├── HintWindow.h
│ ├── HintWindow.m
│ ├── JSApplicationWrapper.h
│ ├── JSApplicationWrapper.m
│ ├── JSController.h
│ ├── JSController.m
│ ├── JSInfoWrapper.h
│ ├── JSInfoWrapper.m
│ ├── JSONKit/
│ │ ├── JSONKit.h
│ │ └── JSONKit.m
│ ├── JSOperation.h
│ ├── JSOperation.m
│ ├── JSOperationWrapper.h
│ ├── JSOperationWrapper.m
│ ├── JSScreenWrapper.h
│ ├── JSScreenWrapper.m
│ ├── JSWindowWrapper.h
│ ├── JSWindowWrapper.m
│ ├── JSWrapperUtils.h
│ ├── JSWrapperUtils.m
│ ├── Layout.h
│ ├── Layout.m
│ ├── LayoutOperation.h
│ ├── LayoutOperation.m
│ ├── MathUtils.h
│ ├── MathUtils.m
│ ├── MoveOperation.h
│ ├── MoveOperation.m
│ ├── NSFileManager+ApplicationSupport.h
│ ├── NSFileManager+ApplicationSupport.m
│ ├── NSString+Indicies.h
│ ├── NSString+Indicies.m
│ ├── NSString+Levenshtein.h
│ ├── NSString+Levenshtein.m
│ ├── NudgeOperation.h
│ ├── NudgeOperation.m
│ ├── Operation.h
│ ├── Operation.m
│ ├── PushOperation.h
│ ├── PushOperation.m
│ ├── RelaunchOperation.h
│ ├── RelaunchOperation.m
│ ├── ResizeOperation.h
│ ├── ResizeOperation.m
│ ├── RunningApplications.h
│ ├── RunningApplications.m
│ ├── ScreenState.h
│ ├── ScreenState.m
│ ├── ScreenWrapper.h
│ ├── ScreenWrapper.m
│ ├── SequenceOperation.h
│ ├── SequenceOperation.m
│ ├── ShellOperation.h
│ ├── ShellOperation.m
│ ├── ShellUtils.h
│ ├── ShellUtils.m
│ ├── Slate-Info.plist
│ ├── Slate-Prefix.pch
│ ├── SlateAppDelegate.h
│ ├── SlateAppDelegate.m
│ ├── SlateConfig.h
│ ├── SlateConfig.m
│ ├── SlateLogger.h
│ ├── Snapshot.h
│ ├── Snapshot.m
│ ├── SnapshotList.h
│ ├── SnapshotList.m
│ ├── SnapshotOperation.h
│ ├── SnapshotOperation.m
│ ├── StringTokenizer.h
│ ├── StringTokenizer.m
│ ├── SwitchAppQuittingOverlayView.h
│ ├── SwitchAppQuittingOverlayView.m
│ ├── SwitchAppView.h
│ ├── SwitchAppView.m
│ ├── SwitchOperation.h
│ ├── SwitchOperation.m
│ ├── SwitchView.h
│ ├── SwitchView.m
│ ├── SwitchWindow.h
│ ├── SwitchWindow.m
│ ├── ThrowOperation.h
│ ├── ThrowOperation.m
│ ├── UndoOperation.h
│ ├── UndoOperation.m
│ ├── VisibilityOperation.h
│ ├── VisibilityOperation.m
│ ├── WindowInfoView.h
│ ├── WindowInfoView.m
│ ├── WindowSnapshot.h
│ ├── WindowSnapshot.m
│ ├── WindowState.h
│ ├── WindowState.m
│ ├── default.slate
│ ├── en.lproj/
│ │ ├── Credits.rtf
│ │ ├── InfoPlist.strings
│ │ └── MainMenu.xib
│ ├── icon.icns
│ ├── initialize.js
│ ├── main.m
│ ├── slate-mock.js
│ ├── slate-test.html
│ ├── underscore.js
│ └── utils.js
├── Slate.xcodeproj/
│ ├── project.pbxproj
│ └── project.xcworkspace/
│ └── contents.xcworkspacedata
├── SlateTests/
│ ├── SlateTests-Info.plist
│ ├── SlateTests-Prefix.pch
│ ├── SlateTests.h
│ ├── SlateTests.m
│ ├── TestExpressionPoint.h
│ ├── TestExpressionPoint.m
│ ├── TestMathUtils.h
│ ├── TestMathUtils.m
│ ├── TestNSString+Indicies.h
│ ├── TestNSString+Indicies.m
│ ├── TestNSString+Levenshtein.h
│ ├── TestNSString+Levenshtein.m
│ ├── TestShellUtils.h
│ ├── TestShellUtils.m
│ ├── TestStringTokenizer.h
│ ├── TestStringTokenizer.m
│ └── en.lproj/
│ └── InfoPlist.strings
├── Sparkle.framework/
│ └── Versions/
│ └── A/
│ ├── Headers/
│ │ ├── SUAppcast.h
│ │ ├── SUAppcastItem.h
│ │ ├── SUUpdater.h
│ │ ├── SUVersionComparisonProtocol.h
│ │ └── Sparkle.h
│ ├── Resources/
│ │ ├── Info.plist
│ │ ├── License.txt
│ │ ├── SUModelTranslation.plist
│ │ ├── SUStatus.nib/
│ │ │ ├── classes.nib
│ │ │ ├── info.nib
│ │ │ └── keyedobjects.nib
│ │ ├── de.lproj/
│ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ └── Sparkle.strings
│ │ ├── en.lproj/
│ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ └── Sparkle.strings
│ │ ├── es.lproj/
│ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ └── Sparkle.strings
│ │ ├── fr.lproj/
│ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ └── Sparkle.strings
│ │ ├── it.lproj/
│ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ └── Sparkle.strings
│ │ ├── nl.lproj/
│ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ └── Sparkle.strings
│ │ ├── relaunch
│ │ ├── ru.lproj/
│ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ └── Sparkle.strings
│ │ └── sv.lproj/
│ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ ├── classes.nib
│ │ │ ├── info.nib
│ │ │ └── keyedobjects.nib
│ │ ├── SUUpdateAlert.nib/
│ │ │ ├── classes.nib
│ │ │ ├── info.nib
│ │ │ └── keyedobjects.nib
│ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ ├── classes.nib
│ │ │ ├── info.nib
│ │ │ └── keyedobjects.nib
│ │ └── Sparkle.strings
│ └── Sparkle
├── VERSION
├── build/
│ ├── Debug/
│ │ └── Slate.app/
│ │ └── Contents/
│ │ ├── Frameworks/
│ │ │ └── Sparkle.framework/
│ │ │ └── Versions/
│ │ │ └── A/
│ │ │ ├── Headers/
│ │ │ │ ├── SUAppcast.h
│ │ │ │ ├── SUAppcastItem.h
│ │ │ │ ├── SUUpdater.h
│ │ │ │ ├── SUVersionComparisonProtocol.h
│ │ │ │ └── Sparkle.h
│ │ │ ├── Resources/
│ │ │ │ ├── Info.plist
│ │ │ │ ├── License.txt
│ │ │ │ ├── SUModelTranslation.plist
│ │ │ │ ├── SUStatus.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ ├── de.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── en.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── es.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── fr.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── it.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── nl.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── relaunch
│ │ │ │ ├── ru.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ └── sv.lproj/
│ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ └── Sparkle.strings
│ │ │ └── Sparkle
│ │ ├── Info.plist
│ │ ├── MacOS/
│ │ │ └── Slate
│ │ ├── PkgInfo
│ │ └── Resources/
│ │ ├── ASCIIToCode.plist
│ │ ├── ASCIIToCode_Azerty.plist
│ │ ├── ASCIIToCode_Colemak.plist
│ │ ├── ASCIIToCode_Dvorak.plist
│ │ ├── default.slate
│ │ ├── en.lproj/
│ │ │ ├── Credits.rtf
│ │ │ ├── InfoPlist.strings
│ │ │ └── MainMenu.nib
│ │ ├── icon.icns
│ │ ├── initialize.js
│ │ ├── underscore.js
│ │ └── utils.js
│ └── Release/
│ ├── Slate.app/
│ │ └── Contents/
│ │ ├── Frameworks/
│ │ │ └── Sparkle.framework/
│ │ │ └── Versions/
│ │ │ └── A/
│ │ │ ├── Headers/
│ │ │ │ ├── SUAppcast.h
│ │ │ │ ├── SUAppcastItem.h
│ │ │ │ ├── SUUpdater.h
│ │ │ │ ├── SUVersionComparisonProtocol.h
│ │ │ │ └── Sparkle.h
│ │ │ ├── Resources/
│ │ │ │ ├── Info.plist
│ │ │ │ ├── License.txt
│ │ │ │ ├── SUModelTranslation.plist
│ │ │ │ ├── SUStatus.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ ├── de.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── en.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── es.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── fr.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── it.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── nl.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── relaunch
│ │ │ │ ├── ru.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ └── sv.lproj/
│ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ └── Sparkle.strings
│ │ │ └── Sparkle
│ │ ├── Info.plist
│ │ ├── MacOS/
│ │ │ └── Slate
│ │ ├── PkgInfo
│ │ └── Resources/
│ │ ├── ASCIIToCode.plist
│ │ ├── ASCIIToCode_Azerty.plist
│ │ ├── ASCIIToCode_Colemak.plist
│ │ ├── ASCIIToCode_Dvorak.plist
│ │ ├── default.slate
│ │ ├── en.lproj/
│ │ │ ├── Credits.rtf
│ │ │ ├── InfoPlist.strings
│ │ │ └── MainMenu.nib
│ │ ├── icon.icns
│ │ ├── initialize.js
│ │ ├── underscore.js
│ │ └── utils.js
│ └── Slate.dmg
├── icons/
│ ├── Contact.txt
│ └── PSD/
│ ├── icon_1024.psd
│ ├── status-bar icon 1.psd
│ ├── status-bar icon 2.psd
│ └── status-bar icon 3.psd
└── script/
└── slate.rb
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
build/Slate.build
build/Release/Slate.app.dSYM
build/debug_paths.json
build/release_paths.json
build/output
build/Release/*.tar.gz
build/Release/VERSION
build/Release/appcast.xml
Slate.xcodeproj/jigish.mode1v3
Slate.xcodeproj/jigish.pbxuser
Slate.xcodeproj/project.xcworkspace/xcuserdata/jigish.xcuserdatad/
Slate.xcodeproj/xcuserdata/jigish.xcuserdatad/
# don't version xcode artifacts
*.xcuserdatad
tmp
================================================
FILE: .gitmodules
================================================
[submodule "script/create-dmg"]
path = script/create-dmg
url = https://github.com/andreyvit/yoursway-create-dmg.git
================================================
FILE: .rbenv-version
================================================
1.9.3-p286
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
================================================
FILE: README.md
================================================
# About Slate #
Slate is a window management application similar to Divvy and SizeUp (except better and free!). Originally written to replace them due to some limitations in how each work, it attempts to overcome them by simply being extremely configurable. As a result, it may be a bit daunting to get configured, but once it is done, the benefit is huge.
Slate currently works on Mac OS X 10.6 and above
## Summary of Features ##
* Highly customizable
* Bind keystrokes to:
* move and/or resize windows
* directionally focus windows
* activate preset layouts
* create, delete, and activate snapshots of the current state of windows
* Set default layouts for different monitor configurations which will activate when that configuration is detected.
* Window Hints: an intuitive way to change window focus
* \[Beta\] A better, more customizable, application switcher.
## Credits ##
Big thanks to [philc](https://github.com/philc) for the Window Hints idea (and initial implementation) as well as plenty of other suggestions and improvement ideas.
# Using Slate #
## Installing Slate ##
**NEW Installation Instructions**
**Note:** You must turn on the Accessibility API by checking System Preferences > Universal Access > Enable access for assistive devices
### Direct Download ###
* [`.dmg`](http://slate.ninjamonkeysoftware.com/Slate.dmg)
* [`.tar.gz`](http://slate.ninjamonkeysoftware.com/versions/slate-latest.tar.gz)
### Terminal ###
Just run this in your terminal:
cd /Applications && curl http://www.ninjamonkeysoftware.com/slate/versions/slate-latest.tar.gz | tar -xz
## Configuring Slate ##
**NEW:** You may now use a ".slate.js" file to configure slate using JavaScript. This allows for much more complex and dynamic configurations than the normal slate configuration style below. You can check out the documentation for this [here](https://github.com/jigish/slate/wiki/JavaScript-Configs).
Slate is configured using a ".slate" file in the current user's home directory. Configuration is loaded upon running Slate. You can also re-load the config using the "Load Config" menu option on the status menu (use this at your own risk. It is better to simply restart Slate).
**Note:** If no ".slate" file exists in the current user's home directory, the [default config file](https://github.com/jigish/slate/blob/master/Slate/default.slate) will be used.
Configuration is split into the following directives:
* `config` (for global configurations)
* `alias` (to create alias variables)
* `layout` (to configure layouts)
* `default` (to default certain screen configurations to layouts)
* `bind` (for key bindings)
* `source` (to load configs from another file)
**Note:** `#` is the comment character. Anything after a `#` will be ignored.
###Expressions###
Some directives allow parameters that can be expressions. The following strings will be replaced with the appropriate values when using expressions:
screenOriginX = target screen's top left x coordinate (should not be used in Window Hints configs)
screenOriginY = target screen's top left y coordinate (should not be used in Window Hints configs)
screenSizeX = target screen's width
screenSizeY = target screen's height
windowTopLeftX = window's current top left x coordinate (should not be used in Window Hints configs)
windowTopLeftY = window's current top left y coordinate (should not be used in Window Hints configs)
windowSizeX = window's width
windowSizeY = window's height
newWindowSizeX = window's new width (after resize, only usable in topLeftX and topLeftY, should not be
used in configs)
newWindowSizeY = window's new height (after resize, only usable in topLeftX and topLeftY, should not be
used in configs)
windowHintsWidth = the value of the windowHintsWidth config (only usable in windowHintsTopLeftX and
windowHintsTopLeftY)
windowHintsHeight = the value of the windowHintsHeight config (only usable in windowHintsTopLeftX and
windowHintsTopLeftY)
In addition to the variables above, expressions can be used with the following functions and operators:
+ e.g. 1+1 = 2
- e.g. 1-1 = 0
* e.g. 2*2 = 4
/ e.g. 4/2 = 2
** e.g. 3**2 = 9
sum e.g. sum({1,2,3}) = 6
count e.g. count({4,5,6}) = 3
min e.g. min({1,3,5}) = 1
max e.g. max({1,3,5}) = 5
average e.g. average({1,2,3,4}) = 2.5
median e.g. median({1,2,3,10,15}) = 3
stddev e.g. stddev({1,2,3,4,5}) = 1.4142135623730951
sqrt e.g. sqrt(9) = 3.0
log e.g. log(100) = 2.0
ln e.g. ln(8) = 2.0794415416798357
exp e.g. exp(2) = 7.3890560989306504 (this is "e**parameter")
floor e.g. floor(1.9) = 1.0
ceiling e.g. ceiling(1.1) = 2.0
abs e.g. abs(-1) = 1
trunc e.g. trunc(1.1123123123) = 1.0
random e.g. random() = 0.20607629744336009 (random float between 0 and 1)
randomn e.g. randomn(10) = 4 (random integer between 0 and parameter-1)
**Note:** When using expressions spaces are *not* allowed!
### The `config` Directive ###
The `config` directive follows the following format:
config name value
[List of allowed configs](https://github.com/jigish/slate/wiki/Global-Configs)
Example:
config defaultToCurrentScreen true
**Note:** the `.slate` file is read top-down directives that come before `config` directives may not have the `config` applied. As such, it is best to put `config` directives at the top of your `.slate` file.
### The `alias` Directive ###
The `alias` directive follows the following format:
alias name value
When you set an alias, you can refer to it in any directive (sequentially after that alias directive) by referencing like `${name}`.
Example:
alias bot-right-2nd-mon move screenOriginX+2*screenSizeX/3;screenOriginY+screenSizeY/2 screenSizeX/3;screenSizeY/2 1
Will allow you to use `${bot-right-2nd-mon}` as a reference to `move screenOriginX+2*screenSizeX/3;screenOriginY+screenSizeY/2 screenSizeX/3;screenSizeY/2 1` in any directive following the alias (including other alias directives)
### The `layout` Directive ###
The `layout` directive follows the following format:
layout name 'app name':OPTIONS operations
Where:
name = the name you want to use to reference the layout
'app name' = single-quoted name of the application to add to the layout **or** BEFORE or AFTER
OPTIONS = a comma separated list of options for this application (cannot be used with BEFORE or AFTER)
operations = a pipe separated list of operations (move, resize, push, nudge, throw, or corner)
Possible Options:
| Name | Function |
|:-----|:---------|
| `IGNORE_FAIL` | This will let slate move to the next operation if the current operation fails to resize/move on the current window |
| `REPEAT` | This will repeat the list of operations if the number of windows is larger than the number of operations |
| `REPEAT_LAST` | This will repeat the last operation in the list if the number of windows is larger than the number of operations |
| `MAIN_FIRST` | This will cause the main window to always use the first operation |
| `MAIN_LAST` | This will cause the main window to always use the last operation (mutally exclusive with `MAIN_FIRST`) |
| `SORT_TITLE` | This will cause the window operations to be triggered on the windows in sorted order by the window title (can be used with `MAIN_FIRST` or `MAIN_LAST`) |
| `TITLE_ORDER=order` | This will cause the operations to be triggered on the windows starting with order which is a semi-colon separated list of window titles |
| `TITLE_ORDER_REGEX=order` | This will cause the operations to be triggered on the windows starting with the order which is a semi-colon separated list of window title regexes to match. Note that once a match is seen, the next regex will be used to match. This means if you have two windows that match the same regex, only the first one seen will be matched. The second will not. |
You can have multiple layout directives that point to the same name in order to link any number of applications to the same layout.
Example:
layout myLayout 'iTerm' push up bar-resize:screenSizeY/2 | push down bar-resize:screenSizeY/2
layout myLayout 'Google Chrome' push left bar-resize:screenSizeX/2 | push right bar-resize:screenSizeX/2
layout myLayout BEFORE shell path:~/ '/opt/local/bin/mvim before'
layout myLayout AFTER shell path:~/ '/opt/local/bin/mvim after'
Will create a layout called `myLayout` with two operations for iTerm and two operations for Google Chrome. When activated, the first window of iTerm will be moved using the first operation in the first list and the second window of iTerm will be moved using the second operation in the first list. In addition, the first window of Google Chrome will be moved using the first operation in the second list and the second window of Google Chrome will be moved using the second operation in the second list. Finally, the operation `shell path:~/ '/opt/local/bin/mvim before'` will be run before any Applications are moved and the operation `shell path:~/ '/opt/local/bin/mvim after'` will be run after any Applications are moved. BEFORE and AFTER may also be used if the layout doesn't have any applications tied to it. Also, you may specify multiple BEFORE or AFTER lines (they will be run in the order that they appear). More information on how to actually use these layouts can be found under the `layout` operation in the `bind` directive section.
### The `default` Directive ###
The `default` directive follows the following format (tokens may be separated by any number of spaces):
default layout-or-snapshot-name screen-configuration
Where:
layout-or-snapshot-name = the name of the layout or snapshot you want to default to
screen-configuration = either "count:NUMBER_OF_SCREENS" or
"resolutions:SEMICOLON_SEPARATED_LIST_OF_RESOLUTIONS"
This directive will cause any screen configuration change (add monitor, remove monitor, screen resolution change) to trigger a search for a default layout or snapshot. If the screen configuration matches one of the defaults set, the layout or snapshot matching `layout-or-snapshot-name` will be triggered. For example:
default myLayout count:2
Will trigger `myLayout` anytime the screen configuration changes to have 2 monitors. Also:
default myLayout2 resolutions:1440x900;1024x768;1680x1050
Will trigger `myLayout2` anytime the screen configuration changes to have exactly 3 monitors with resolutions `1440x900`, `1024x768`, and `1680x1050`.
### The `bind` Directive ###
The `bind` directive follows one of the following formats (tokens may be separated by any number of spaces):
bind key:modifiers operation parameter+
bind key:modal-key operation parameter+
#### Key ####
`key` is a reference to a key on the keyboard. See Allowed Keys for a complete list. For example: the `s` key would simply be `s` while the `1` key on the number pad would be `pad1`.
#### Modifiers ####
`modifiers` is a comma or semicolon separated list of standard modifier keys. Allowed modifiers are:
* Control: `ctrl`
* Option/Alt: `alt`
* Command: `cmd`
* Shift: `shift`
**Note:** If you bind any binding to cmd-tab or cmd-shift-tab, Slate will completely disable the default Mac OS X Application switcher!
**Note:** Bindings that are used by Mac OS X spaces, expose, and mission control will override Slate bindings. Be sure to turn these bindings off if you want to use them in Slate.
#### Modal Key ####
`modal-key` is any one of the Allowed Keys. If using a `modal-key`, pressing that key will cause the Slate menu bar icon to change indicating modal mode is activated. then clicking `key` will activate the binding. Modal mode will remain active until `key` has been pressed or `modal-key` is pressed again. You may specify multiple bindings with the same `modal-key` as long as `key` is different. Also, `modal-key` can accompany a comma or semicolon separated list of modifier keys listed above. This will cause that entire keystroke to be considered the modal activation binding. For example: `bind 1:f4,ctrl,alt` will result in the modal keystroke being `ctrl+alt+f4`. After pressing that keystroke, modal mode will be activated and pressing `1` after that will activate the binding.
##### Modal Toggle Behavior #####
If you add `:toggle` to the end of a modal binding it will cause that binding to not end the modal mode. For example with the binding `1:ctrl,f4`, you press `ctrl+f4` and then press `1` to activate the binding. Once that binding is activated, modal mode will end and you have to press `ctrl+f4` again to activate it. However, with the binding `1:ctrl,f4:toggle` pressing `ctrl+f4` will toggle modal mode. pressing `1` will activate the binding but not end modal mode. To end modal mode, press `ctrl+f4` again or use the config `modalEscapeKey`.
#### Operation ####
Operations define what to actually do to the focused window.
**Screens**
Some operations allow you to specify a screen. Here are the list of possible values for screen:
* Integer representing the screen ID (indexed at 0). Screens are ordered from left to right (by X coordinate of the origin which is the top-left point). If `orderScreensLeftToRight` is set to false, the screen ID is the Mac OS internal ID (indexed at 0). If `orderScreensLeftToRight` is set to false but you still want to reference screens in the default ordered mode, prefix the screen ID with `ordered:`.
* Screen resolution in the format `WIDTHxHEIGHT` (e.g. `1440x900`)
* Screen direction relative to the current screen (`left|right|up|above|down|below`)
* `next` or `previous` (represents the `currentID+1` or `currentID-1` screen)
**Allowed operations are:**
##### move #####
Move/Resize the window any which way: `move topLeftX;topLeftY sizeX;sizeY screen`
topLeftX = top left x coordinate of the window's desired position (can be an expression)
topLeftY = top left y coordinate of the window's desired position (can be an expression)
sizeX = width of the window's desired position (can be an expression)
sizeY = height of the window's desired position (can be an expression)
screen = (optional) the reference to the screen of the window's desired position.
If this is not specified, it will default to the screen the window is currently on.
See the table at the beginning of the Operation section for more information.
Example:
bind pad1:ctrl move 0;0 100;100 1
Will bind the keystroke ctrl-numpad1 to moving the window to the screen at index `1` with top-left coordinate `0,0` and size `100,100`
**Note:** Remember to offset with `screenOriginX` in your `topLeftX` and `screenOriginY` in your `topLeftY` when using the `screen` option (or when using multiple screens in general) or your move operation will offset from the default origin `(0,0)` which is the origin of screen `0`.
##### resize #####
Resize the window (keeping top-left the same): `resize x y anchor`
x = amount to resize width either as a percent or a hard value (+10% or -100)
y = amount to resize height either as a percent or a hard value (+10% or -100)
anchor = (optional) which corner to anchor on top-left|top-right|bottom-left|bottom-right (default is top-left)
Example:
bind right:ctrl resize +10% +0
Will bind the keystroke ctrl-rightarrow to increase the width the current window by `10%`.
**Note:** ctrl-rightarrow is used by default in Mac OS X by spaces. Be sure to turn these bindings off if you want to use them in Slate.
##### push #####
Push the window to the edge of the screen: `push direction style`
direction = top|up|bottom|down|left|right
style = (optional) none|center|bar|bar-resize:expression (default is none)
screen = (optional) the reference to the screen of the window's desired position.
If this is not specified, it will default to the screen the window is currently on.
See the table at the beginning of the Operation section for more information.
Example:
bind up:alt,ctrl push up
Will bind the keystroke alt-ctrl-uparrow to push the window so that it is aligned with the top of the screen
##### nudge #####
Nudge the window in any direction: `nudge x y`
x = amount to nudge x either as a percent or a hard value (+10% or -100)
y = amount to nudge y either as a percent or a hard value (+10% or -100)
Example:
bind left:ctrl,shift nudge -100 +0
Will bind the keystroke ctrl-shift-leftarrow to nudge the window `100` pixels to the left
##### throw #####
Throw the window to any screen's origin: `throw screen style`
screen = the screen you want to throw the window to (0 indexed)
style = (optional) resize|resize:x-expression;y-expression (default will not resize)
Example:
bind pad1:alt,ctrl throw 1 resize
Will bind the keystroke alt-ctrl-numpad1 to throw the window to the 2nd screen and resize it to fit that screen
##### corner #####
Move/Resize the window into a corner: `corner direction style`
direction = top-left|top-right|bottom-left|bottom-right
style = (optional) resize:x-expression;y-expression (default will not resize)
screen = (optional) the reference to the screen of the window's desired position.
If this is not specified, it will default to the screen the window is currently on.
See the table at the beginning of the Operation section for more information.
Example:
bind 1:ctrl corner top-left resize:screenSizeX/2;screenSizeY/2
Will bind the keystroke ctrl-1 to move the window to the top-left corner and resize it to 1/4 of the screen
##### shell #####
Execute a shell command: `shell options 'command'`
command = (required) the command to run. note that it is a quoted string.
options = (optional) a space separated list of:
wait - block slate until the shell command exits. Useful when using shell commands in a
sequence binding
path: - the inital working directory to use when starting the command. For example
path:~/code would set the inital working directory to ~/code
Example:
bind 1:ctrl wait path:~/code '/opt/local/bin/mvim'
Will bind the keystroke ctrl-1 to run the command `/opt/local/bin/mvim` with the current working directory of `~/code`. Slate will also block until the command is done. Note that you may **not** use the tilda home directory shortcut within the command itself, it is only allowed within the path.
##### hide #####
Hide one or more applications: `hide applications`
applications = a comma separated list of application names. Individual application names must be
surrounded by quotes. You can also specify `current`, `all`, or `all-but:` for the
Application name (no quotes). `current` will apply to the currently focused
application, `all` will apply to all open applications and `all-but:'APP_NAME'` will
apply to all open applications except `APP_NAME`. Note that when trying to hide `all`
it will not work as intended because OS X will not allow every visible app to be
hidden. Hiding `all` will hide all apps but OS X will auto-show one of the apps that
were hidden.
Example:
bind 1:ctrl hide 'iTerm','Google Chrome'
Will bind the keystroke ctrl-1 to hide iTerm and Google Chrome.
##### show #####
Show one or more applications: `show applications`
applications = a comma separated list of application names. Individual application names must be
surrounded by quotes. You can also specify `current`, `all`, or `all-but:` for the
Application name (no quotes). `current` will apply to the currently focused
application, `all` will apply to all open applications and `all-but:'APP_NAME'` will
apply to all open applications except `APP_NAME`.
Example:
bind 1:ctrl show 'iTerm','Google Chrome'
Will bind the keystroke ctrl-1 to show (unhide) iTerm and Google Chrome.
##### toggle #####
Toggle one or more applications: `toggle applications`
applications = a comma separated list of application names. Individual application names must be
surrounded by quotes. You can also specify `current`, `all`, or `all-but:` for the
Application name (no quotes). `current` will apply to the currently focused
application, `all` will apply to all open applications and `all-but:'APP_NAME'` will
apply to all open applications except `APP_NAME`. Note that when trying to toggle `all`
it will may not work as intended because OS X will not allow every visible app to be
hidden. If at any point during the toggling all apps become hidden, OS X will auto-show
one of the apps that were hidden.
Example:
bind 1:ctrl toggle 'iTerm','Google Chrome'
Will bind the keystroke ctrl-1 to toggle iTerm and Google Chrome. Toggle meaning if the individual
application is currently hidden it will be shown and if it is currently shown it will be hidden.
**Note:** If you specify current in this toggle operation it will not toggle properly because after the current application is hidden, it is no longer the current application anymore.
##### chain #####
Chain multiple operations to one binding: `chain opAndParams1 | opAndParams2 ...`
opAndParamsX = any operation string (except sequence, hint and grid)
Example:
bind 1:ctrl chain push up | push right | push down | push left
Will bind the keystroke ctrl-1 to push up on the first press, then push right on the second press, then push down on the third press, the push left on the fourth press and rotate back to pushing up on the fifth press (etc).
##### sequence #####
Activate a sequence of operations in one binding: `sequence opAndParams1 separator opAndParams 2 ...`
opAndParamsX = any of the above operation strings (except chain and grid. hint must be last if present)
separator = | or >. | will cause the next operation to be performed on the window focused at the time of
execution of that operation, > will cause the next operation to be performed on the window
focused at the start of the > chain.
Example:
bind 1:ctrl sequence focus right > push left | push right
Will bind the keystroke ctrl-1 to first focus the window to the right, then push the previously focused window to the left, then push the newly focused window to the right. Obviously Hint will ignore `>` and `|` and just display because it doesn't care which window was focused.
##### layout #####
Activate a layout: `layout name`
name = the name of the layout to activate (set using the layout directive)
Example:
bind 1:ctrl layout myLayout
Will bind the keystroke ctrl-l to activate the layout called `myLayout`. Note that the layout **must** be created before you bind it.
##### focus #####
Focus a window in a direction or from an application: `focus direction|app`
direction = right|left|up|above|down|below|behind
app = an app name surrounded by quotes
Example:
bind 1:ctrl focus above
Will bind the keystroke ctrl-1 to focus the window Slate finds to be above the currently focused window (from any application). Minimized and hidden windows are ignored. A couple global configuration options set using the `config` directive exist to tweak this. Also, up and above are the same. Down and below are also the same.
bind 1:ctrl focus 'iTerm'
Will bind the keystroke ctrl-1 to focus the main window of the application iTerm. The main window is the last focused window of that application.
##### snapshot #####
Create a snapshot of your current window locations: `snapshot name options`
name = the name of the snapshot to create (used in delete-snapshot and activate-snapshot)
options = (optional) a semicolon separated list of any of the following options:
save-to-disk -> saves the snapshot to disk so Slate will load it when it starts up next
stack -> treats this snapshot as stack so you can use this binding multiple times to push snapshots on the stack
Example:
bind 1:ctrl snapshot theName save-to-disk;stack
Will bind the keystroke ctrl-1 to create a snapshot called `theName`, save that snapshot to disk, and treat it as a stack so you can hit the keystroke multiple times to push snapshots onto the stack.
**Note:** There is a menu option to take a snapshot of the current screen configuration.
##### delete-snapshot #####
Delete a snapshot: `delete-snapshot name options`
name = the name of the snapshot to delete
options = (optional) a semicolon separated list of any of the following options:
all -> if the snapshot is a stack (if it isn't, this option is useless), this will delete all snapshots in the
stack (if this option is not specified, the default is to only delete the top snapshot of the stack).
Example:
bind 1:ctrl delete-snapshot theName all
Will bind the keystroke ctrl-1 to delete the snapshot called `theName` if it exists. This will delete all instances of theName meaning if you have pushed multiple snapshots on the stack, it will completely clear them all.
##### activate-snapshot #####
Activate a snapshot: `activate-snapshot name options`
name = the name of the snapshot to activate
options = (optional) a semicolon separated list of any of the following options:
delete -> this will delete the snapshot after activating it (if the snapshot is a stack, it will pop the top
snapshot off and keep the rest)
Example:
bind 1:ctrl activate-snapshot theName delete
Will bind the keystroke ctrl-1 to activate the snapshot called `theName` if it exists. This will also delete the snapshot (or pop it off the stack if the snapshot is a stack).
**Note:** There is a menu option to activate the snapshot that you may have created using the menu option.
##### hint #####
Show Window Hints (similar to Link Hints in Vimium except for Windows): `hint characters`
characters = (optional) a simple string of characters to be used for the hints. each hint consists of one
character. if there are more windows than characters then some windows will not get hints.
this string can contain any of the single character Allowed Keys. Letters may be upper case or
lower case, but both will be bound to the lowercase letter for the hint. Using upper or lower
case only changes how they are displayed. The default string of characters is
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
Example:
bind 1:ctrl hint QWERTYUIOP
Will bind the keystroke ctrl-1 to show Window Hints using the letters `Q`, `W`, `E`, `R`, `T`, `Y`, `U`, `I`, `O`, and `P`. This will show an overlay in the top-left corner of every window on screen containing one of those letters. While the overlays are showing, if one of those letters is pressed, the corresponding window will be focused. If there are more than 10 windows, some windows will not get hints. Pressing ESC will dismiss the hints.
**Note:** There are *tons* of config options to tweak this.
##### grid #####
Show a Grid to one-off resize and move windows: `grid options`
options is a whitespace separated list of:
padding:<integer> = the padding between cells
screenRef:width,height = width and height are integers specifying the width and height of the grid
(number of cells, not absolute size). screenRef is either the screenID or
screen resolution (widthxheight)
Example:
bind 1:ctrl grid padding:5 1680x1050:16,9 1050x1680:9,16
Will bind the keystroke ctrl-1 to show Grids on each screen. The default width and height are 12. This will set the padding between the cells to be 5. Also, this will change the width and height of the grid on the monitor with the resolution 1680x1050 to 16 and 9 respectively. For the monitor with the resolution 1050x1680, it will set the width to 9 and height to 16. If you have multiple monitors, the Grid that is on the same screen as your mouse pointer will be focused. If you want to use a grid on a different monitor you **must** click it first and then click+drag.
**Note:** There are a bunch of config options to tweak how this looks.
##### relaunch #####
Relaunch Slate: `relaunch`
Example:
bind 1:ctrl relaunch
Will bind the keystroke ctrl-1 to relaunch Slate. This will also reload the `.slate` file from scratch.
##### undo #####
Undo an Operation: `undo`
Example
bind 1:ctrl undo
Will bind the keystroke ctrl-1 to undo the last binding that was triggered. By default you can undo up to the last 10 commands. This can be changed using the `undoMaxStackSize` config. Also, you can only undo movement-based operations. Focus-related operations will not undo.
##### switch #####
\[Beta\] A Better Application Switcher: `switch`
If you bind any binding to cmd-tab or cmd-shift-tab, Slate will completely disable the default Mac OS X Application switcher!
Example:
bind tab:cmd switch
Will disable the default Mac OS X Application switcher and bind the keystroke cmd-tab to a better application switcher.
**Note:** There are *tons* of config options to tweak this.
### The `source` Directive ###
The source directive follows the following format (tokens may be separated by any number of spaces):
source filename optional:if_exists
Where `filename` is the name of a file containing any of the directives above (including source). If no absolute path is specified, the user's home directory will be prepended to `filename`. If the user specifies the option `if_exists` as the second argument, Slate will not complain if it cannot find the file.
For Example:
source ~/.slate.test if_exists
Will append all of the configurations from the file `~/.slate.test` to the current configuration if the file `~/.slate.test` exists.
**Note:** You may use any aliases, layouts, etc that you specify before the source directive in the file you source. Any aliases, layouts, etc specified after cannot be used. Additionally, any aliases, layouts, etc that you specify in the file you source can be used after the source directive.
### Example Config ###
You can check out my own config [here](https://github.com/jigish/dotfiles/blob/master/slate).
### Useful Stuff ###
- [kvs](https://github.com/kvs) has created a [Sublime Text 2](http://www.sublimetext.com/2) preference for `.slate` files [here](https://github.com/kvs/ST2Slate).
- [trishume](https://github.com/trishume) has done a really nice writeup on getting started with Slate [here](http://thume.ca/howto/2012/11/19/using-slate/)
# Contact #
Please send all questions, bug reports, suggestions, or general commentary to [Jigish Patel](mailto:slate.issues@gmail.com) or [create an issue](https://github.com/jigish/slate/issues/new) on github.
# Allowed Keys #
**Note:** If you bind any binding to cmd-tab or cmd-shift-tab, Slate will completely disable the default Mac OS X Application switcher!
'
,
-
.
/
0
1
2
3
4
5
6
7
8
9
;
=
`
a
b
backslash
c
caps
d
delete
down
e
end
esc
f
f1
f10
f11
f12
f13
f14
f15
f16
f17
f18
f19
f2
f20
f3
f4
f5
f6
f7
f8
f9
g
h
help
home
i
j
k
l
left
m
mute
n
o
p
pad*
pad+
pad-
pad.
pad/
pad0
pad1
pad2
pad3
pad4
pad5
pad6
pad7
pad8
pad9
pad=
padClear
padEnter
pageDown
pageUp
q
r
return
right
s
space
t
tab
u
up
v
w
x
y
z
[
]
================================================
FILE: Slate/ASCIIToCode.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>'</key>
<integer>39</integer>
<key>,</key>
<integer>43</integer>
<key>-</key>
<integer>27</integer>
<key>.</key>
<integer>47</integer>
<key>/</key>
<integer>44</integer>
<key>0</key>
<integer>29</integer>
<key>1</key>
<integer>18</integer>
<key>2</key>
<integer>19</integer>
<key>3</key>
<integer>20</integer>
<key>4</key>
<integer>21</integer>
<key>5</key>
<integer>23</integer>
<key>6</key>
<integer>22</integer>
<key>7</key>
<integer>26</integer>
<key>8</key>
<integer>28</integer>
<key>9</key>
<integer>25</integer>
<key>;</key>
<integer>41</integer>
<key>=</key>
<integer>24</integer>
<key>`</key>
<integer>50</integer>
<key>a</key>
<integer>0</integer>
<key>b</key>
<integer>11</integer>
<key>backslash</key>
<integer>42</integer>
<key>c</key>
<integer>8</integer>
<key>caps</key>
<integer>57</integer>
<key>d</key>
<integer>2</integer>
<key>delete</key>
<integer>51</integer>
<key>down</key>
<integer>125</integer>
<key>e</key>
<integer>14</integer>
<key>end</key>
<integer>119</integer>
<key>esc</key>
<integer>53</integer>
<key>f</key>
<integer>3</integer>
<key>f1</key>
<integer>122</integer>
<key>f10</key>
<integer>109</integer>
<key>f11</key>
<integer>103</integer>
<key>f12</key>
<integer>111</integer>
<key>f13</key>
<integer>105</integer>
<key>f14</key>
<integer>107</integer>
<key>f15</key>
<integer>113</integer>
<key>f16</key>
<integer>106</integer>
<key>f17</key>
<integer>64</integer>
<key>f18</key>
<integer>79</integer>
<key>f19</key>
<integer>80</integer>
<key>f2</key>
<integer>120</integer>
<key>f20</key>
<integer>90</integer>
<key>f3</key>
<integer>99</integer>
<key>f4</key>
<integer>118</integer>
<key>f5</key>
<integer>96</integer>
<key>f6</key>
<integer>97</integer>
<key>f7</key>
<integer>98</integer>
<key>f8</key>
<integer>100</integer>
<key>f9</key>
<integer>101</integer>
<key>g</key>
<integer>5</integer>
<key>h</key>
<integer>4</integer>
<key>help</key>
<integer>114</integer>
<key>home</key>
<integer>115</integer>
<key>i</key>
<integer>34</integer>
<key>j</key>
<integer>38</integer>
<key>k</key>
<integer>40</integer>
<key>l</key>
<integer>37</integer>
<key>left</key>
<integer>123</integer>
<key>m</key>
<integer>46</integer>
<key>mute</key>
<integer>74</integer>
<key>n</key>
<integer>45</integer>
<key>o</key>
<integer>31</integer>
<key>p</key>
<integer>35</integer>
<key>pad*</key>
<integer>67</integer>
<key>pad+</key>
<integer>69</integer>
<key>pad-</key>
<integer>78</integer>
<key>pad.</key>
<integer>65</integer>
<key>pad/</key>
<integer>75</integer>
<key>pad0</key>
<integer>82</integer>
<key>pad1</key>
<integer>83</integer>
<key>pad2</key>
<integer>84</integer>
<key>pad3</key>
<integer>85</integer>
<key>pad4</key>
<integer>86</integer>
<key>pad5</key>
<integer>87</integer>
<key>pad6</key>
<integer>88</integer>
<key>pad7</key>
<integer>89</integer>
<key>pad8</key>
<integer>91</integer>
<key>pad9</key>
<integer>92</integer>
<key>pad=</key>
<integer>81</integer>
<key>padClear</key>
<integer>71</integer>
<key>padEnter</key>
<integer>76</integer>
<key>pageDown</key>
<integer>121</integer>
<key>pageUp</key>
<integer>116</integer>
<key>q</key>
<integer>12</integer>
<key>r</key>
<integer>15</integer>
<key>return</key>
<integer>36</integer>
<key>right</key>
<integer>124</integer>
<key>s</key>
<integer>1</integer>
<key>space</key>
<integer>49</integer>
<key>t</key>
<integer>17</integer>
<key>tab</key>
<integer>48</integer>
<key>u</key>
<integer>32</integer>
<key>up</key>
<integer>126</integer>
<key>v</key>
<integer>9</integer>
<key>w</key>
<integer>13</integer>
<key>x</key>
<integer>7</integer>
<key>y</key>
<integer>16</integer>
<key>z</key>
<integer>6</integer>
<key>[</key>
<integer>33</integer>
<key>]</key>
<integer>30</integer>
</dict>
</plist>
================================================
FILE: Slate/ASCIIToCode_Azerty.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>help</key>
<integer>114</integer>
<key>mute</key>
<integer>74</integer>
<key>pageUp</key>
<integer>116</integer>
<key>f13</key>
<integer>105</integer>
<key>down</key>
<integer>125</integer>
<key>f3</key>
<integer>99</integer>
<key>padClear</key>
<integer>71</integer>
<key>'</key>
<integer>39</integer>
<key>]</key>
<integer>30</integer>
<key>,</key>
<integer>46</integer>
<key>.</key>
<integer>47</integer>
<key>0</key>
<integer>29</integer>
<key>2</key>
<integer>19</integer>
<key>4</key>
<integer>21</integer>
<key>6</key>
<integer>22</integer>
<key>8</key>
<integer>28</integer>
<key>return</key>
<integer>36</integer>
<key>caps</key>
<integer>57</integer>
<key>pageDown</key>
<integer>121</integer>
<key>f19</key>
<integer>80</integer>
<key>`</key>
<integer>50</integer>
<key>b</key>
<integer>11</integer>
<key>d</key>
<integer>2</integer>
<key>f</key>
<integer>3</integer>
<key>h</key>
<integer>4</integer>
<key>j</key>
<integer>38</integer>
<key>l</key>
<integer>37</integer>
<key>n</key>
<integer>45</integer>
<key>p</key>
<integer>35</integer>
<key>f18</key>
<integer>79</integer>
<key>r</key>
<integer>15</integer>
<key>t</key>
<integer>17</integer>
<key>v</key>
<integer>9</integer>
<key>f12</key>
<integer>111</integer>
<key>x</key>
<integer>7</integer>
<key>f10</key>
<integer>109</integer>
<key>z</key>
<integer>13</integer>
<key>f16</key>
<integer>106</integer>
<key>f17</key>
<integer>64</integer>
<key>f14</key>
<integer>107</integer>
<key>delete</key>
<integer>51</integer>
<key>f1</key>
<integer>122</integer>
<key>f2</key>
<integer>120</integer>
<key>right</key>
<integer>124</integer>
<key>f4</key>
<integer>118</integer>
<key>f5</key>
<integer>96</integer>
<key>f6</key>
<integer>97</integer>
<key>f7</key>
<integer>98</integer>
<key>f8</key>
<integer>100</integer>
<key>f9</key>
<integer>101</integer>
<key>backslash</key>
<integer>42</integer>
<key>up</key>
<integer>126</integer>
<key>tab</key>
<integer>48</integer>
<key>home</key>
<integer>115</integer>
<key>5</key>
<integer>23</integer>
<key>end</key>
<integer>119</integer>
<key>space</key>
<integer>49</integer>
<key>-</key>
<integer>27</integer>
<key>/</key>
<integer>44</integer>
<key>1</key>
<integer>18</integer>
<key>3</key>
<integer>20</integer>
<key>f20</key>
<integer>90</integer>
<key>esc</key>
<integer>53</integer>
<key>7</key>
<integer>26</integer>
<key>9</key>
<integer>25</integer>
<key>;</key>
<integer>41</integer>
<key>=</key>
<integer>24</integer>
<key>padEnter</key>
<integer>76</integer>
<key>pad+</key>
<integer>69</integer>
<key>pad*</key>
<integer>67</integer>
<key>pad-</key>
<integer>78</integer>
<key>pad/</key>
<integer>75</integer>
<key>pad.</key>
<integer>65</integer>
<key>pad1</key>
<integer>83</integer>
<key>pad0</key>
<integer>82</integer>
<key>pad3</key>
<integer>85</integer>
<key>pad2</key>
<integer>84</integer>
<key>pad5</key>
<integer>87</integer>
<key>pad4</key>
<integer>86</integer>
<key>pad7</key>
<integer>89</integer>
<key>pad6</key>
<integer>88</integer>
<key>pad9</key>
<integer>92</integer>
<key>pad8</key>
<integer>91</integer>
<key>[</key>
<integer>33</integer>
<key>pad=</key>
<integer>81</integer>
<key>a</key>
<integer>12</integer>
<key>c</key>
<integer>8</integer>
<key>f11</key>
<integer>103</integer>
<key>e</key>
<integer>14</integer>
<key>g</key>
<integer>5</integer>
<key>i</key>
<integer>34</integer>
<key>k</key>
<integer>40</integer>
<key>m</key>
<integer>41</integer>
<key>o</key>
<integer>31</integer>
<key>q</key>
<integer>0</integer>
<key>s</key>
<integer>1</integer>
<key>u</key>
<integer>32</integer>
<key>w</key>
<integer>6</integer>
<key>y</key>
<integer>16</integer>
<key>f15</key>
<integer>113</integer>
<key>left</key>
<integer>123</integer>
</dict>
</plist>
================================================
FILE: Slate/ASCIIToCode_Colemak.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>help</key>
<integer>114</integer>
<key>mute</key>
<integer>74</integer>
<key>pageUp</key>
<integer>116</integer>
<key>f13</key>
<integer>105</integer>
<key>down</key>
<integer>125</integer>
<key>f3</key>
<integer>99</integer>
<key>padClear</key>
<integer>71</integer>
<key>'</key>
<integer>39</integer>
<key>]</key>
<integer>30</integer>
<key>,</key>
<integer>43</integer>
<key>.</key>
<integer>47</integer>
<key>0</key>
<integer>29</integer>
<key>2</key>
<integer>19</integer>
<key>4</key>
<integer>21</integer>
<key>6</key>
<integer>22</integer>
<key>8</key>
<integer>28</integer>
<key>return</key>
<integer>36</integer>
<key>caps</key>
<integer>57</integer>
<key>pageDown</key>
<integer>121</integer>
<key>f19</key>
<integer>80</integer>
<key>`</key>
<integer>50</integer>
<key>b</key>
<integer>11</integer>
<key>d</key>
<integer>5</integer>
<key>f</key>
<integer>14</integer>
<key>h</key>
<integer>4</integer>
<key>j</key>
<integer>16</integer>
<key>l</key>
<integer>32</integer>
<key>n</key>
<integer>38</integer>
<key>p</key>
<integer>15</integer>
<key>f18</key>
<integer>79</integer>
<key>r</key>
<integer>1</integer>
<key>t</key>
<integer>3</integer>
<key>v</key>
<integer>9</integer>
<key>f12</key>
<integer>111</integer>
<key>x</key>
<integer>7</integer>
<key>f10</key>
<integer>109</integer>
<key>z</key>
<integer>6</integer>
<key>f16</key>
<integer>106</integer>
<key>f17</key>
<integer>64</integer>
<key>f14</key>
<integer>107</integer>
<key>delete</key>
<integer>51</integer>
<key>f1</key>
<integer>122</integer>
<key>f2</key>
<integer>120</integer>
<key>right</key>
<integer>124</integer>
<key>f4</key>
<integer>118</integer>
<key>f5</key>
<integer>96</integer>
<key>f6</key>
<integer>97</integer>
<key>f7</key>
<integer>98</integer>
<key>f8</key>
<integer>100</integer>
<key>f9</key>
<integer>101</integer>
<key>backslash</key>
<integer>42</integer>
<key>up</key>
<integer>126</integer>
<key>tab</key>
<integer>48</integer>
<key>home</key>
<integer>115</integer>
<key>5</key>
<integer>23</integer>
<key>end</key>
<integer>119</integer>
<key>space</key>
<integer>49</integer>
<key>-</key>
<integer>27</integer>
<key>/</key>
<integer>44</integer>
<key>1</key>
<integer>18</integer>
<key>3</key>
<integer>20</integer>
<key>f20</key>
<integer>90</integer>
<key>esc</key>
<integer>53</integer>
<key>7</key>
<integer>26</integer>
<key>9</key>
<integer>25</integer>
<key>;</key>
<integer>35</integer>
<key>=</key>
<integer>24</integer>
<key>padEnter</key>
<integer>76</integer>
<key>pad+</key>
<integer>69</integer>
<key>pad*</key>
<integer>67</integer>
<key>pad-</key>
<integer>78</integer>
<key>pad/</key>
<integer>75</integer>
<key>pad.</key>
<integer>65</integer>
<key>pad1</key>
<integer>83</integer>
<key>pad0</key>
<integer>82</integer>
<key>pad3</key>
<integer>85</integer>
<key>pad2</key>
<integer>84</integer>
<key>pad5</key>
<integer>87</integer>
<key>pad4</key>
<integer>86</integer>
<key>pad7</key>
<integer>89</integer>
<key>pad6</key>
<integer>88</integer>
<key>pad9</key>
<integer>92</integer>
<key>pad8</key>
<integer>91</integer>
<key>[</key>
<integer>33</integer>
<key>pad=</key>
<integer>81</integer>
<key>a</key>
<integer>0</integer>
<key>c</key>
<integer>8</integer>
<key>f11</key>
<integer>103</integer>
<key>e</key>
<integer>40</integer>
<key>g</key>
<integer>17</integer>
<key>i</key>
<integer>37</integer>
<key>k</key>
<integer>45</integer>
<key>m</key>
<integer>46</integer>
<key>o</key>
<integer>41</integer>
<key>q</key>
<integer>12</integer>
<key>s</key>
<integer>2</integer>
<key>u</key>
<integer>34</integer>
<key>w</key>
<integer>13</integer>
<key>y</key>
<integer>31</integer>
<key>f15</key>
<integer>113</integer>
<key>left</key>
<integer>123</integer>
</dict>
</plist>
================================================
FILE: Slate/ASCIIToCode_Dvorak.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>-</key>
<integer>39</integer>
<key>w</key>
<integer>43</integer>
<key>[</key>
<integer>27</integer>
<key>v</key>
<integer>47</integer>
<key>z</key>
<integer>44</integer>
<key>0</key>
<integer>29</integer>
<key>1</key>
<integer>18</integer>
<key>2</key>
<integer>19</integer>
<key>3</key>
<integer>20</integer>
<key>4</key>
<integer>21</integer>
<key>5</key>
<integer>23</integer>
<key>6</key>
<integer>22</integer>
<key>7</key>
<integer>26</integer>
<key>8</key>
<integer>28</integer>
<key>9</key>
<integer>25</integer>
<key>s</key>
<integer>41</integer>
<key>]</key>
<integer>24</integer>
<key>`</key>
<integer>50</integer>
<key>a</key>
<integer>0</integer>
<key>x</key>
<integer>11</integer>
<key>backslash</key>
<integer>42</integer>
<key>j</key>
<integer>8</integer>
<key>caps</key>
<integer>57</integer>
<key>e</key>
<integer>2</integer>
<key>delete</key>
<integer>51</integer>
<key>down</key>
<integer>125</integer>
<key>.</key>
<integer>14</integer>
<key>end</key>
<integer>119</integer>
<key>esc</key>
<integer>53</integer>
<key>u</key>
<integer>3</integer>
<key>f1</key>
<integer>122</integer>
<key>f10</key>
<integer>109</integer>
<key>f11</key>
<integer>103</integer>
<key>f12</key>
<integer>111</integer>
<key>f13</key>
<integer>105</integer>
<key>f14</key>
<integer>107</integer>
<key>f15</key>
<integer>113</integer>
<key>f16</key>
<integer>106</integer>
<key>f17</key>
<integer>64</integer>
<key>f18</key>
<integer>79</integer>
<key>f19</key>
<integer>80</integer>
<key>f2</key>
<integer>120</integer>
<key>f20</key>
<integer>90</integer>
<key>f3</key>
<integer>99</integer>
<key>f4</key>
<integer>118</integer>
<key>f5</key>
<integer>96</integer>
<key>f6</key>
<integer>97</integer>
<key>f7</key>
<integer>98</integer>
<key>f8</key>
<integer>100</integer>
<key>f9</key>
<integer>101</integer>
<key>i</key>
<integer>5</integer>
<key>d</key>
<integer>4</integer>
<key>help</key>
<integer>114</integer>
<key>home</key>
<integer>115</integer>
<key>c</key>
<integer>34</integer>
<key>h</key>
<integer>38</integer>
<key>t</key>
<integer>40</integer>
<key>n</key>
<integer>37</integer>
<key>left</key>
<integer>123</integer>
<key>m</key>
<integer>46</integer>
<key>mute</key>
<integer>74</integer>
<key>b</key>
<integer>45</integer>
<key>r</key>
<integer>31</integer>
<key>l</key>
<integer>35</integer>
<key>pad*</key>
<integer>67</integer>
<key>pad+</key>
<integer>69</integer>
<key>pad-</key>
<integer>78</integer>
<key>pad.</key>
<integer>65</integer>
<key>pad/</key>
<integer>75</integer>
<key>pad0</key>
<integer>82</integer>
<key>pad1</key>
<integer>83</integer>
<key>pad2</key>
<integer>84</integer>
<key>pad3</key>
<integer>85</integer>
<key>pad4</key>
<integer>86</integer>
<key>pad5</key>
<integer>87</integer>
<key>pad6</key>
<integer>88</integer>
<key>pad7</key>
<integer>89</integer>
<key>pad8</key>
<integer>91</integer>
<key>pad9</key>
<integer>92</integer>
<key>pad=</key>
<integer>81</integer>
<key>padClear</key>
<integer>71</integer>
<key>padEnter</key>
<integer>76</integer>
<key>pageDown</key>
<integer>121</integer>
<key>pageUp</key>
<integer>116</integer>
<key>'</key>
<integer>12</integer>
<key>p</key>
<integer>15</integer>
<key>return</key>
<integer>36</integer>
<key>right</key>
<integer>124</integer>
<key>o</key>
<integer>1</integer>
<key>space</key>
<integer>49</integer>
<key>y</key>
<integer>17</integer>
<key>tab</key>
<integer>48</integer>
<key>g</key>
<integer>32</integer>
<key>up</key>
<integer>126</integer>
<key>k</key>
<integer>9</integer>
<key>,</key>
<integer>13</integer>
<key>q</key>
<integer>7</integer>
<key>f</key>
<integer>16</integer>
<key>;</key>
<integer>6</integer>
<key>/</key>
<integer>33</integer>
<key>=</key>
<integer>30</integer>
</dict>
</plist>
================================================
FILE: Slate/AccessibilityWrapper.h
================================================
//
// AccessibilityWrapper.h
// Slate
//
// Created by Jigish Patel on 6/10/11.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import <Foundation/Foundation.h>
@interface AccessibilityWrapper : NSObject {
@private
AXUIElementRef app;
AXUIElementRef window;
BOOL inited;
}
@property (assign) AXUIElementRef app;
@property (assign) AXUIElementRef window;
@property (assign) BOOL inited;
- (id)initWithApp:(AXUIElementRef)appRef window:(AXUIElementRef)windowRef;
+ (NSPoint)getTopLeftForWindow:(AXUIElementRef)window;
- (NSPoint)getCurrentTopLeft;
+ (NSSize)getSizeForWindow:(AXUIElementRef)window;
- (NSSize)getCurrentSize;
- (BOOL)moveWindow:(NSPoint)thePoint;
- (BOOL)resizeWindow:(NSSize)theSize;
- (BOOL)focus;
- (BOOL)isMinimizedOrHidden;
- (NSString *)getTitle;
- (pid_t)processIdentifier;
+ (BOOL)focusWindow:(AXUIElementRef)window;
+ (BOOL)focusMainWindow:(NSRunningApplication *)app;
+ (BOOL)focusApp:(NSRunningApplication *)app;
+ (pid_t)processIdentifierOfUIElement:(AXUIElementRef)element;
+ (CFArrayRef)windowsInApp:(AXUIElementRef)app;
+ (CFArrayRef)windowsInRunningApp:(NSRunningApplication *)app;
+ (AXUIElementRef)focusedWindowInRunningApp:(NSRunningApplication *)app;
+ (BOOL)isMainWindow:(AXUIElementRef)window;
+ (NSString *)getTitle:(AXUIElementRef)window;
- (BOOL)isMovable;
- (BOOL)isResizable;
+ (BOOL)isWindowMinimizedOrHidden:(AXUIElementRef)window inApp:(AXUIElementRef)app;
+ (AXUIElementRef)windowUnderPoint:(NSPoint)point;
+ (void)createSystemWideElement;
+ (AXUIElementRef)applicationForElement:(AXUIElementRef)element;
+ (BOOL)isWindow:(AXUIElementRef)element;
+ (NSString *)getRole:(AXUIElementRef)element;
@end
================================================
FILE: Slate/AccessibilityWrapper.m
================================================
//
// AccessibilityWrapper.m
// Slate
//
// Created by Jigish Patel on 6/10/11.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import "AccessibilityWrapper.h"
#import "Constants.h"
#import "SlateLogger.h"
static AXUIElementRef systemWideElement = NULL;
static NSDictionary *unselectableApps = nil;
@implementation AccessibilityWrapper
@synthesize app;
@synthesize window;
@synthesize inited;
- (id)init {
self = [super init];
if (self) {
[AccessibilityWrapper createSystemWideElement];
// Get App that has focus
CFTypeRef _app;
AXUIElementCopyAttributeValue(systemWideElement, (CFStringRef)kAXFocusedApplicationAttribute, (CFTypeRef *)&_app);
[self setApp:(AXUIElementRef)_app];
// Get Window that has focus
CFTypeRef _window;
if (AXUIElementCopyAttributeValue(app, (CFStringRef)NSAccessibilityFocusedWindowAttribute, (CFTypeRef *)&_window) == kAXErrorSuccess) {
[self setWindow:(AXUIElementRef)_window];
[self setInited:YES];
} else {
[self setInited:NO];
SlateLogger(@"ERROR: Could not fetch focused window");
}
}
return self;
}
- (id)initWithApp:(AXUIElementRef)appRef window:(AXUIElementRef)windowRef {
self = [super init];
if (self) {
[AccessibilityWrapper createSystemWideElement];
[self setApp:appRef];
[self setWindow:windowRef];
[self setInited:YES];
}
return self;
}
+ (NSPoint)getTopLeftForWindow:(AXUIElementRef)window {
CFTypeRef _cPosition;
NSPoint cTopLeft;
if (AXUIElementCopyAttributeValue(window, (CFStringRef)NSAccessibilityPositionAttribute, (CFTypeRef *)&_cPosition) == kAXErrorSuccess) {
if (!AXValueGetValue(_cPosition, kAXValueCGPointType, (void *)&cTopLeft)) {
SlateLogger(@"ERROR: Could not decode position");
cTopLeft = NSMakePoint(0, 0);
}
} else {
SlateLogger(@"ERROR: Could not fetch position");
cTopLeft = NSMakePoint(0, 0);
}
if (_cPosition != NULL) CFRelease(_cPosition);
return cTopLeft;
}
- (NSPoint)getCurrentTopLeft {
return [AccessibilityWrapper getTopLeftForWindow:window];
}
+ (NSSize)getSizeForWindow:(AXUIElementRef)window {
CFTypeRef _cSize;
NSSize cSize;
if (AXUIElementCopyAttributeValue(window, (CFStringRef)NSAccessibilitySizeAttribute, (CFTypeRef *)&_cSize) == kAXErrorSuccess) {
if (!AXValueGetValue(_cSize, kAXValueCGSizeType, (void *)&cSize)) {
SlateLogger(@"ERROR: Could not decode size");
cSize = NSMakeSize(0, 0);
}
} else {
SlateLogger(@"ERROR: Could not fetch size");
cSize = NSMakeSize(0, 0);
}
if (_cSize != NULL) CFRelease(_cSize);
return cSize;
}
- (NSSize)getCurrentSize {
return [AccessibilityWrapper getSizeForWindow:window];
}
- (BOOL)moveWindow:(NSPoint)thePoint {
CFTypeRef _position;
_position = (CFTypeRef)(AXValueCreate(kAXValueCGPointType, (const void *)&thePoint));
if (AXUIElementSetAttributeValue(window, (CFStringRef)NSAccessibilityPositionAttribute, (CFTypeRef *)_position) != kAXErrorSuccess) {
SlateLogger(@"ERROR: Could not change position");
if (_position != NULL) CFRelease(_position);
return NO;
}
if (_position != NULL) CFRelease(_position);
return YES;
}
- (BOOL)resizeWindow:(NSSize)theSize {
CFTypeRef _size;
_size = (CFTypeRef)(AXValueCreate(kAXValueCGSizeType, (const void *)&theSize));
if (AXUIElementSetAttributeValue(window, (CFStringRef)NSAccessibilitySizeAttribute, (CFTypeRef *)_size) != kAXErrorSuccess) {
SlateLogger(@"ERROR: Could not change size");
if (_size != NULL) CFRelease(_size);
return NO;
}
if (_size != NULL) CFRelease(_size);
return YES;
}
- (BOOL)focus {
return [AccessibilityWrapper focusWindow:[self window]];
}
- (BOOL)isMinimizedOrHidden {
return [AccessibilityWrapper isWindowMinimizedOrHidden:[self window] inApp:[self app]];
}
- (BOOL)isMovable {
return [self moveWindow:[self getCurrentTopLeft]];
}
- (BOOL)isResizable {
return [self resizeWindow:[self getCurrentSize]];
}
- (NSString *)getTitle {
return [AccessibilityWrapper getTitle:[self window]];
}
- (pid_t)processIdentifier {
return [AccessibilityWrapper processIdentifierOfUIElement:[self app]];
}
+ (BOOL)focusApp:(NSRunningApplication *)app {
SlateLogger(@"Focusing app: '%@'", [app localizedName]);
AXUIElementRef appRef = AXUIElementCreateApplication([app processIdentifier]);
if (AXUIElementSetAttributeValue(appRef, (CFStringRef)NSAccessibilityFrontmostAttribute, kCFBooleanTrue) != kAXErrorSuccess) {
SlateLogger(@"ERROR: Could not change focus to app");
if (appRef != NULL) CFRelease(appRef);
return NO;
}
if (appRef != NULL) CFRelease(appRef);
return YES;
}
+ (BOOL)focusMainWindow:(NSRunningApplication *)app {
BOOL couldFocus = YES;
CFTypeRef _window;
pid_t focusPID = [app processIdentifier];
AXUIElementCopyAttributeValue(AXUIElementCreateApplication(focusPID), (CFStringRef)NSAccessibilityFocusedWindowAttribute, (CFTypeRef *)&_window);
if (_window == NULL) return [AccessibilityWrapper focusApp:app];
if (AXUIElementSetAttributeValue((AXUIElementRef)_window, (CFStringRef)NSAccessibilityMainAttribute, kCFBooleanTrue) != kAXErrorSuccess) {
SlateLogger(@"ERROR: Could not change focus to window");
couldFocus = NO;
}
ProcessSerialNumber psn;
GetProcessForPID(focusPID, &psn);
SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly);
if (_window != NULL) CFRelease(_window);
return couldFocus;
}
+ (BOOL)focusWindow:(AXUIElementRef)window {
BOOL couldFocus = YES;
if (AXUIElementSetAttributeValue(window, (CFStringRef)NSAccessibilityMainAttribute, kCFBooleanTrue) != kAXErrorSuccess) {
SlateLogger(@"ERROR: Could not change focus to window");
couldFocus = NO;
}
pid_t focusPID = [AccessibilityWrapper processIdentifierOfUIElement:window];
ProcessSerialNumber psn;
GetProcessForPID(focusPID, &psn);
SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly);
return couldFocus;
}
+ (pid_t)processIdentifierOfUIElement:(AXUIElementRef)element {
[AccessibilityWrapper createSystemWideElement];
pid_t pid = 0;
if (AXUIElementGetPid (element, &pid) == kAXErrorSuccess) {
return pid;
} else {
return 0;
}
}
+ (CFArrayRef)windowsInApp:(AXUIElementRef)app {
[AccessibilityWrapper createSystemWideElement];
CFArrayRef _windows;
if (AXUIElementCopyAttributeValues(app, kAXWindowsAttribute, 0, 100, &_windows) == kAXErrorSuccess) {
return _windows;
}
return nil;
}
+ (CFArrayRef)windowsInRunningApp:(NSRunningApplication *)app {
return [AccessibilityWrapper windowsInApp:AXUIElementCreateApplication([app processIdentifier])];
}
+ (AXUIElementRef)focusedWindowInRunningApp:(NSRunningApplication *)app {
CFTypeRef _window;
AXUIElementCopyAttributeValue(AXUIElementCreateApplication([app processIdentifier]), (CFStringRef)NSAccessibilityFocusedWindowAttribute, (CFTypeRef *)&_window);
return _window;
}
+ (BOOL)isMainWindow:(AXUIElementRef)window {
[AccessibilityWrapper createSystemWideElement];
CFTypeRef _isMain;
if (AXUIElementCopyAttributeValue(window, (CFStringRef)NSAccessibilityMainAttribute, (CFTypeRef *)&_isMain) == kAXErrorSuccess) {
NSNumber *isMain = (__bridge NSNumber *) _isMain;
return [isMain boolValue];
}
return NO;
}
+ (NSString *)getTitle:(AXUIElementRef)window {
[AccessibilityWrapper createSystemWideElement];
CFTypeRef _title;
if (AXUIElementCopyAttributeValue(window, (CFStringRef)NSAccessibilityTitleAttribute, (CFTypeRef *)&_title) == kAXErrorSuccess) {
NSString *title = (__bridge NSString *) _title;
if (_title != NULL) CFRelease(_title);
return title;
}
if (_title != NULL) CFRelease(_title);
return @"";
}
+ (BOOL)isWindowMinimizedOrHidden:(AXUIElementRef)window inApp:(AXUIElementRef)app {
[AccessibilityWrapper createSystemWideElement];
CFTypeRef _isMinimized;
CFTypeRef _isHidden;
BOOL isMinimized = NO;
BOOL isHidden = NO;
if (AXUIElementCopyAttributeValue(app, (CFStringRef)NSAccessibilityHiddenAttribute, (CFTypeRef *)&_isHidden) == kAXErrorSuccess) {
NSNumber *isHiddenNum = (__bridge NSNumber *) _isHidden;
isHidden = [isHiddenNum boolValue];
}
if (AXUIElementCopyAttributeValue(window, (CFStringRef)NSAccessibilityMinimizedAttribute, (CFTypeRef *)&_isMinimized) == kAXErrorSuccess) {
NSNumber *isMinimizedNum = (__bridge NSNumber *) _isMinimized;
isMinimized = [isMinimizedNum boolValue];
}
return isMinimized || isHidden;
}
+ (AXUIElementRef)windowUnderPoint:(NSPoint)point {
[AccessibilityWrapper createSystemWideElement];
AXUIElementRef _element;
if ((AXUIElementCopyElementAtPosition(systemWideElement, point.x, point.y, &_element) == kAXErrorSuccess) && _element) {
CFTypeRef _role;
if (AXUIElementCopyAttributeValue(_element, (CFStringRef)NSAccessibilityRoleAttribute, (CFTypeRef *)&_role) == kAXErrorSuccess) {
if ([(__bridge NSString *)_role isEqualToString:NSAccessibilityWindowRole]) {
if (_role != NULL) CFRelease(_role);
return _element;
}
if (_role != NULL) CFRelease(_role);
}
CFTypeRef _window;
if (AXUIElementCopyAttributeValue(_element, (CFStringRef)NSAccessibilityWindowAttribute, (CFTypeRef *)&_window) == kAXErrorSuccess) {
if (_element != NULL) CFRelease(_element);
return (AXUIElementRef)_window;
}
}
SlateLogger(@"Returning null");
return NULL;
}
+ (AXUIElementRef)applicationForElement:(AXUIElementRef)element {
return AXUIElementCreateApplication([AccessibilityWrapper processIdentifierOfUIElement:element]);
}
+ (void)createSystemWideElement {
if (systemWideElement == NULL) {
systemWideElement = AXUIElementCreateSystemWide();
unselectableApps = [NSDictionary dictionaryWithObjectsAndKeys:@"SystemUIServer", @"SystemUIServer",
@"Slate", @"Slate",
@"Dropbox", @"Dropbox",
@"loginwindow", @"loginwindow", nil];
}
}
+ (BOOL)isWindow:(AXUIElementRef)element {
CFTypeRef _role;
AXUIElementCopyAttributeValue(element, (CFStringRef)NSAccessibilityRoleAttribute, &_role);
BOOL isWindow = [NSAccessibilityWindowRole isEqualToString:(__bridge NSString *)_role];
if (_role != NULL) CFRelease(_role);
return isWindow;
}
+ (NSString *)getRole:(AXUIElementRef)element {
if (element == NULL || element == nil) return nil;
CFTypeRef _role;
if (AXUIElementCopyAttributeValue(element, (CFStringRef)NSAccessibilityRoleAttribute, &_role) == kAXErrorSuccess) {
NSString *role = (__bridge NSString *)_role;
if (_role != NULL) CFRelease(_role);
return role;
}
return nil;
}
@end
================================================
FILE: Slate/ActivateSnapshotOperation.h
================================================
//
// ActivateSnapshotOperation.h
// Slate
//
// Created by Jigish Patel on 3/1/12.
// Copyright 2012 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import "Operation.h"
@interface ActivateSnapshotOperation : Operation {
@private
NSString *name;
BOOL del;
}
@property NSString *name;
@property (assign) BOOL del;
- (id)initWithName:(NSString *)theName options:(NSString *)options;
+ (BOOL)activateSnapshot:(NSString *)name remove:(BOOL)del;
+ (id)activateSnapshotOperation;
+ (id)activateSnapshotOperationFromString:(NSString *)activateSnapshotOperation;
@end
================================================
FILE: Slate/ActivateSnapshotOperation.m
================================================
//
// ActivateSnapshotOperation.m
// Slate
//
// Created by Jigish Patel on 3/1/12.
// Copyright 2012 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import "ActivateSnapshotOperation.h"
#import "Constants.h"
#import "Snapshot.h"
#import "SlateConfig.h"
#import "WindowSnapshot.h"
#import "NSString+Levenshtein.h"
#import "StringTokenizer.h"
#import "SlateLogger.h"
#import "RunningApplications.h"
@implementation ActivateSnapshotOperation
@synthesize name, del;
- (id)init {
self = [super init];
if (self) {
del = NO;
[self setName:nil];
}
return self;
}
- (id)initWithName:(NSString *)theName options:(NSString *)_options {
self = [self init];
if (self) {
[self setName:theName];
if (_options) {
NSArray *optionsTokens = [_options componentsSeparatedByString:SEMICOLON];
for (NSInteger i = 0; i < [optionsTokens count]; i++) {
NSString *option = [optionsTokens objectAtIndex:i];
if ([DELETE isEqualToString:option]) {
del = YES;
}
}
}
}
return self;
}
- (BOOL)doOperation {
SlateLogger(@"----------------- Begin Snapshot Operation -----------------");
BOOL success = [self doOperationWithAccessibilityWrapper:nil screenWrapper:nil];
SlateLogger(@"----------------- End Snapshot Operation -----------------");
return success;
}
- (BOOL)doOperationWithAccessibilityWrapper:(AccessibilityWrapper *)iamnil screenWrapper:(ScreenWrapper *)iamalsonil {
[self evalOptionsWithAccessibilityWrapper:iamnil screenWrapper:iamalsonil];
return [ActivateSnapshotOperation activateSnapshot:name remove:del];
}
- (BOOL)testOperation {
return YES;
}
- (NSArray *)requiredOptions {
return [NSArray arrayWithObject:OPT_NAME];
}
- (void)parseOption:(NSString *)_name value:(id)value {
if (value == nil) { return; }
if ([_name isEqualToString:OPT_NAME]) {
if (![value isKindOfClass:[NSString class]]) {
@throw([NSException exceptionWithName:[NSString stringWithFormat:@"Invalid %@", _name] reason:[NSString stringWithFormat:@"Invalid %@ '%@'", _name, value] userInfo:nil]);
return;
}
[self setName:_name];
} else if ([_name isEqualToString:OPT_DELETE]) {
if (![value isKindOfClass:[NSValue class]] && ![value isKindOfClass:[NSString class]] && ![value isKindOfClass:[NSNumber class]]) {
@throw([NSException exceptionWithName:[NSString stringWithFormat:@"Invalid %@", _name] reason:[NSString stringWithFormat:@"Invalid %@ '%@'", _name, value] userInfo:nil]);
return;
}
[self setDel:[value boolValue]];
}
}
+ (BOOL)activateSnapshot:(NSString *)name remove:(BOOL)del {
Snapshot *snapshot = [[SlateConfig getInstance] popSnapshot:name remove:del];
if (snapshot == nil) return YES;
for (NSRunningApplication *app in [RunningApplications getInstance]) {
NSString *appName = [app localizedName];
pid_t appPID = [app processIdentifier];
SlateLogger(@"I see application '%@' with pid '%d'", appName, appPID);
AXUIElementRef appRef = AXUIElementCreateApplication(appPID);
CFArrayRef windowsArrRef = [AccessibilityWrapper windowsInApp:appRef];
if (!windowsArrRef || CFArrayGetCount(windowsArrRef) == 0) continue;
CFMutableArrayRef windowsArr = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, windowsArrRef);
NSArray *windowSnapshots = [[snapshot apps] objectForKey:appName];
// Check windows
for (NSInteger i = 0; i < CFArrayGetCount(windowsArr); i++) {
SlateLogger(@" Checking Window: %@", [AccessibilityWrapper getTitle:CFArrayGetValueAtIndex(windowsArr, i)]);
NSString *title = [AccessibilityWrapper getTitle:CFArrayGetValueAtIndex(windowsArr, i)];
if ([title isEqualToString:@""]) continue;
AccessibilityWrapper *aw = [[AccessibilityWrapper alloc] initWithApp:appRef window:CFArrayGetValueAtIndex(windowsArr, i)];
// Find best snapshot
WindowSnapshot *bestSnapshot = nil;
if ([[[SlateConfig getInstance] getConfig:SNAPSHOT_TITLE_MATCH app:appName] isEqualToString:SEQUENTIAL]) {
float bestDistance = 0.0;
for (WindowSnapshot *ws in windowSnapshots) {
float sDistance = [title sequentialDistance:[ws title]];
if (sDistance > bestDistance || bestSnapshot == nil) {
bestDistance = sDistance;
bestSnapshot = ws;
}
}
} else {
float bestDistance = 1000.0;
for (WindowSnapshot *ws in windowSnapshots) {
float lDistance = [title levenshteinDistance:[ws title]];
if (lDistance < bestDistance || bestSnapshot == nil) {
bestDistance = lDistance;
bestSnapshot = ws;
}
}
}
if (bestSnapshot == nil) continue;
[aw moveWindow:[bestSnapshot topLeft]];
[aw resizeWindow:[bestSnapshot size]];
}
}
return YES;
}
+ (id)activateSnapshotOperation {
return [[ActivateSnapshotOperation alloc] init];
}
+ (id)activateSnapshotOperationFromString:(NSString *)activateSnapshotOperation {
// activate-snapshot name options
NSMutableArray *tokens = [[NSMutableArray alloc] initWithCapacity:10];
[StringTokenizer tokenize:activateSnapshotOperation into:tokens maxTokens:3];
if ([tokens count] < 2) {
SlateLogger(@"ERROR: Invalid Parameters '%@'", activateSnapshotOperation);
@throw([NSException exceptionWithName:@"Invalid Parameters" reason:[NSString stringWithFormat:@"Invalid Parameters in '%@'. Activate Snapshot operations require the following format: 'delete-snapshot name options'", activateSnapshotOperation] userInfo:nil]);
}
Operation *op = [[ActivateSnapshotOperation alloc] initWithName:[tokens objectAtIndex:1] options:([tokens count] > 2 ? [tokens objectAtIndex:2] : nil)];
return op;
}
@end
================================================
FILE: Slate/ApplicationOptions.h
================================================
//
// ApplicationOptions.h
// Slate
//
// Created by Jigish Patel on 6/14/11.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import <Foundation/Foundation.h>
@interface ApplicationOptions : NSObject {
@private
BOOL ignoreFail;
BOOL repeat;
BOOL repeatLast;
BOOL mainFirst;
BOOL mainLast;
BOOL sortTitle;
NSArray *titleOrder;
NSArray *titleOrderRegex;
}
@property (assign) BOOL ignoreFail;
@property (assign) BOOL repeat;
@property (assign) BOOL repeatLast;
@property (assign) BOOL mainFirst;
@property (assign) BOOL mainLast;
@property (assign) BOOL sortTitle;
@property NSArray *titleOrder;
@property NSArray *titleOrderRegex;
@end
================================================
FILE: Slate/ApplicationOptions.m
================================================
//
// ApplicationOptions.m
// Slate
//
// Created by Jigish Patel on 6/14/11.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import "ApplicationOptions.h"
@implementation ApplicationOptions
@synthesize ignoreFail;
@synthesize repeat;
@synthesize repeatLast;
@synthesize mainFirst;
@synthesize mainLast;
@synthesize sortTitle;
@synthesize titleOrder;
@synthesize titleOrderRegex;
- (id)init {
self = [super init];
if (self) {
[self setIgnoreFail:NO];
[self setRepeat:NO];
[self setRepeatLast:NO];
[self setMainFirst:NO];
[self setMainLast:NO];
[self setSortTitle:NO];
[self setTitleOrder:nil];
[self setTitleOrderRegex:nil];
}
return self;
}
@end
================================================
FILE: Slate/Binding.h
================================================
//
// Binding.h
// Slate
//
// Created by Jigish Patel on 5/18/11.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import <Carbon/Carbon.h>
#import <Foundation/Foundation.h>
@class Operation;
@interface Binding : NSObject {
@private
Operation *op;
UInt32 keyCode;
UInt32 modifiers;
NSNumber *modalKey;
EventHotKeyRef hotKeyRef;
BOOL repeat;
BOOL toggle;
}
@property Operation *op;
@property (assign) UInt32 keyCode;
@property (assign) UInt32 modifiers;
@property NSNumber *modalKey;
@property (assign) EventHotKeyRef hotKeyRef;
@property (assign) BOOL repeat;
@property (assign) BOOL toggle;
+ (NSDictionary *)asciiToCodeDict;
- (id)initWithString:(NSString *)binding;
- (id)initWithKeystroke:(NSString*)keystroke operation:(Operation*)op_ repeat:(BOOL)repeat_;
- (BOOL)doOperation;
- (NSString *)modalHashKey;
+ (NSArray *)modalHashKeyToKeyAndModifiers:(NSString *)modalHashKey;
+ (NSArray *)getKeystrokeFromString:(NSString *)keystroke;
@end
================================================
FILE: Slate/Binding.m
================================================
//
// Binding.m
// Slate
//
// Created by Jigish Patel on 5/18/11.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import "Binding.h"
#import "Constants.h"
#import "SlateConfig.h"
#import "StringTokenizer.h"
#import "SlateLogger.h"
#import "Operation.h"
#import "SwitchOperation.h"
#import "SlateAppDelegate.h"
#import "SnapshotOperation.h"
@implementation Binding
@synthesize op;
@synthesize keyCode;
@synthesize modifiers;
@synthesize modalKey;
@synthesize hotKeyRef;
@synthesize repeat;
@synthesize toggle;
static NSDictionary *dictionary = nil;
- (id)init {
self = [super init];
if (self) {
[self setRepeat:NO];
[self setToggle:NO];
[self setModalKey:nil];
}
return self;
}
// Yes, this method is huge. Deal with it.
- (id)initWithString:(NSString *)binding {
self = [self init];
if (self) {
// bind <key:modifiers|modal-key> <op> <parameters>
NSMutableArray *tokens = [[NSMutableArray alloc] initWithCapacity:10];
[StringTokenizer tokenize:binding into:tokens maxTokens:3];
if ([tokens count] <=2) {
@throw([NSException exceptionWithName:@"Unrecognized Bind" reason:binding userInfo:nil]);
}
[self setKeystrokeFromString:[tokens objectAtIndex:1]];
[self setOperationAndRepeatFromString:[tokens objectAtIndex:2]];
}
return self;
}
- (id)initWithKeystroke:(NSString *)keystroke operation:(Operation *)op_ repeat:(BOOL)repeat_ {
self = [self init];
if (self) {
[self setKeystrokeFromString:keystroke];
[self setOp:op_];
if ([self op] == nil) {
SlateLogger(@"ERROR: Unable to create binding");
@throw([NSException exceptionWithName:@"Unable To Create Binding" reason:[NSString stringWithFormat:@"Unable to create %@", keystroke] userInfo:nil]);
}
@try {
AccessibilityWrapper *awTest = [[AccessibilityWrapper alloc] init];
ScreenWrapper *swTest = [[ScreenWrapper alloc] init];
[[self op] testOperationWithAccessibilityWrapper:awTest screenWrapper:swTest];
} @catch (NSException *ex) {
SlateLogger(@"ERROR: Unable to test binding");
@throw([NSException exceptionWithName:@"Unable To Parse Binding" reason:[NSString stringWithFormat:@"Unable to parse '%@' in '%@'", [ex reason], [[self op] opName]] userInfo:nil]);
}
if ([[self op] isKindOfClass:[SwitchOperation class]]) {
[(SwitchOperation *)op setModifiers:modifiers];
}
[self setRepeat:repeat_];
}
return self;
}
+ (UInt32)modifierFromString:(NSString *)mod {
if ([mod isEqualToString:CONTROL]) {
return controlKey;
} else if ([mod isEqualToString:OPTION]) {
return optionKey;
} else if ([mod isEqualToString:COMMAND]) {
return cmdKey;
} else if ([mod isEqualToString:SHIFT]) {
return shiftKey;
} else if ([mod isEqualToString:FUNCTION]) {
return FUNCTION_KEY;
} else {
SlateLogger(@"ERROR: Unrecognized modifier '%@'", mod);
@throw([NSException exceptionWithName:@"Unrecognized Modifier" reason:[NSString stringWithFormat:@"Unrecognized modifier '%@'", mod] userInfo:nil]);
}
}
+ (NSArray *)getKeystrokeFromString:(NSString *)keystroke {
NSNumber *theKeyCode = [NSNumber numberWithUnsignedInt:0];
UInt32 theModifiers = 0;
NSNumber *theModalKey = nil;
NSArray *keyAndModifiers = [keystroke componentsSeparatedByString:COLON];
if ([keyAndModifiers count] >= 1) {
NSString *theKey = [keyAndModifiers objectAtIndex:0];
theKeyCode = [[Binding asciiToCodeDict] objectForKey:theKey];
if (theKeyCode == nil) {
SlateLogger(@"ERROR: Unrecognized key \"%@\" in \"%@\"", theKey, keystroke);
@throw([NSException exceptionWithName:@"Unrecognized Key" reason:[NSString stringWithFormat:@"Unrecognized key \"%@\" in \"%@\"", theKey, keystroke] userInfo:nil]);
}
if ([keyAndModifiers count] >= 2) {
theModalKey = [[Binding asciiToCodeDict] objectForKey:[keyAndModifiers objectAtIndex:1]];
if (theModalKey == nil) {
// normal case
NSArray *modifiersArray = [[keyAndModifiers objectAtIndex:1] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@",;"]];
NSEnumerator *modEnum = [modifiersArray objectEnumerator];
NSString *mod = [modEnum nextObject];
while (mod) {
NSNumber *_theModalKey = [[Binding asciiToCodeDict] objectForKey:mod];
if (_theModalKey != nil) {
theModalKey = _theModalKey;
} else {
theModifiers += [Binding modifierFromString:mod];
}
mod = [modEnum nextObject];
}
}
}
}
return [NSArray arrayWithObjects:theKeyCode, [NSNumber numberWithInteger:theModifiers], theModalKey, nil];
}
- (void)setKeystrokeFromString:(NSString*)keystroke {
NSArray *modalAndKey = [keystroke componentsSeparatedByString:COLON];
if ([modalAndKey count] > 0) {
NSArray *keyarr = [Binding getKeystrokeFromString:keystroke];
keyCode = [[keyarr objectAtIndex:0] unsignedIntValue];
modifiers = [[keyarr objectAtIndex:1] unsignedIntValue];
if ([keyarr count] >= 3 ) {
[self setModalKey:[keyarr objectAtIndex:2]];
}
}
if ([modalAndKey count] >= 3){ // modal toggle
if ([[modalAndKey objectAtIndex:2] isEqualToString:TOGGLE]) {
[self setToggle:YES];
}
}
}
- (void)setOperationAndRepeatFromString:(NSString*)token {
NSMutableString *opStr = [[NSMutableString alloc] initWithCapacity:10];
[StringTokenizer firstToken:token into:opStr];
BOOL theRepeat = [Operation isRepeatOnHoldOp:opStr];
Operation *theOp = [Operation operationFromString:token];
if (theOp == nil) {
SlateLogger(@"ERROR: Unable to create binding");
@throw([NSException exceptionWithName:@"Unable To Create Binding" reason:[NSString stringWithFormat:@"Unable to create '%@'", token] userInfo:nil]);
}
@try {
[theOp testOperation];
} @catch (NSException *ex) {
SlateLogger(@"ERROR: Unable to test binding '%@'", token);
@throw([NSException exceptionWithName:@"Unable To Parse Binding" reason:[NSString stringWithFormat:@"Unable to parse '%@' in '%@'", [ex reason], token] userInfo:nil]);
}
if ([theOp isKindOfClass:[SwitchOperation class]]) {
[(SwitchOperation *)op setModifiers:modifiers];
}
op = theOp;
repeat = theRepeat;
}
- (BOOL)doOperation {
if ([(SlateAppDelegate *)[NSApp delegate] hasUndoOperation] && [op shouldTakeUndoSnapshot]) {
[[(SlateAppDelegate *)[NSApp delegate] undoSnapshotOperation] doOperation];
}
@try {
return [op doOperation];
} @catch (NSException *ex) {
SlateLogger(@" ERROR %@",[ex name]);
NSAlert *alert = [SlateConfig warningAlertWithKeyEquivalents: [NSArray arrayWithObjects:@"Quit", @"Skip", nil]];
[alert setMessageText:[ex name]];
[alert setInformativeText:[ex reason]];
if ([alert runModal] == NSAlertFirstButtonReturn) {
SlateLogger(@"User selected exit");
[NSApp terminate:nil];
}
}
return NO;
}
- (NSString *)modalHashKey {
if ([self modalKey] == nil) {
return nil;
}
return [NSString stringWithFormat:@"%@%@%u", [self modalKey], PLUS, [self modifiers]];
}
+ (NSArray *)modalHashKeyToKeyAndModifiers:(NSString *)modalHashKey {
NSArray *modalKeyArr = [modalHashKey componentsSeparatedByString:PLUS];
NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
NSNumber *theKey = [nf numberFromString:[modalKeyArr objectAtIndex:0]];
NSNumber *theModifiers = [nf numberFromString:[modalKeyArr objectAtIndex:1]];
return [NSArray arrayWithObjects:theKey, theModifiers, nil];
}
- (void)dealloc {
[self setHotKeyRef:nil];
}
// This returns a dictionary containing mappings from ASCII to keyCode
+ (NSDictionary *)asciiToCodeDict {
if (dictionary == nil) {
NSString *configLayout = [[SlateConfig getInstance] getConfig:KEYBOARD_LAYOUT];
NSString *filename;
if ([configLayout isEqualToString:KEYBOARD_LAYOUT_DVORAK]) {
filename = @"ASCIIToCode_Dvorak";
} else if ([configLayout isEqualToString:KEYBOARD_LAYOUT_COLEMAK]) {
filename = @"ASCIIToCode_Colemak";
} else if ([configLayout isEqualToString:KEYBOARD_LAYOUT_AZERTY]) {
filename = @"ASCIIToCode_Azerty";
} else {
filename = @"ASCIIToCode";
}
dictionary = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:filename ofType:@"plist"]];
}
return dictionary;
}
@end
================================================
FILE: Slate/ChainOperation.h
================================================
//
// ChainOperation.h
// Slate
//
// Created by Jigish Patel on 5/28/11.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import <Foundation/Foundation.h>
#import "Operation.h"
@interface ChainOperation : Operation {
@private
NSArray *operations;
NSMutableDictionary *currentOp;
}
@property NSArray *operations;
@property NSMutableDictionary *currentOp;
- (BOOL)testOperation:(NSInteger)op;
- (void)afterComplete:(AccessibilityWrapper *)aw opRun:(NSInteger)op ;
- (id)initWithArray:(NSArray *)opArray;
- (NSInteger)getNextOperation:(AccessibilityWrapper *)aw;
- (void)setNextOperation:(AccessibilityWrapper *)aw nextOp:(NSNumber *)op;
+ (id)chainOperation;
+ (id)chainOperationFromString:(NSString *)chainOperation;
@end
================================================
FILE: Slate/ChainOperation.m
================================================
//
// ChainOperation.m
// Slate
//
// Created by Jigish Patel on 5/28/11.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import "ChainOperation.h"
#import "ScreenWrapper.h"
#import "WindowState.h"
#import "StringTokenizer.h"
#import "Constants.h"
#import "SlateLogger.h"
#import "JSController.h"
#import <WebKit/WebKit.h>
#import "JSOperation.h"
@implementation ChainOperation
@synthesize operations;
@synthesize currentOp;
- (id)init {
self = [super init];
if (self) {
[self setCurrentOp:[[NSMutableDictionary alloc] initWithCapacity:10]];
[self setOperations:[NSArray array]];
}
return self;
}
- (id)initWithArray:(NSArray *)opArray {
self = [self init];
if (self) {
[self setCurrentOp:[[NSMutableDictionary alloc] initWithCapacity:10]];
[self setOperations:opArray];
}
return self;
}
- (BOOL)doOperation {
SlateLogger(@"----------------- Begin Chain Operation -----------------");
AccessibilityWrapper *aw = [[AccessibilityWrapper alloc] init];
ScreenWrapper *sw = [[ScreenWrapper alloc] init];
BOOL success = NO;
if ([aw inited]) success = [self doOperationWithAccessibilityWrapper:aw screenWrapper:sw];
SlateLogger(@"----------------- End Chain Operation -----------------");
return success;
}
- (BOOL) doOperationWithAccessibilityWrapper:(AccessibilityWrapper *)aw screenWrapper:(ScreenWrapper *)sw {
BOOL success = NO;
[self evalOptionsWithAccessibilityWrapper:aw screenWrapper:sw];
NSInteger opRun = 0;
if ([aw inited]) {
opRun = [self getNextOperation:aw];
success = [[operations objectAtIndex:opRun] doOperationWithAccessibilityWrapper:aw screenWrapper:sw];
if (success)
[self afterComplete:aw opRun:opRun];
}
return success;
}
- (BOOL)testOperation:(NSInteger)op {
BOOL success = [[operations objectAtIndex:op] testOperation];
return success;
}
- (BOOL)testOperation {
BOOL success = YES;
for (NSInteger op = 0; op < [operations count]; op++) {
success = [self testOperation:op] && success;
}
return success;
}
- (void)afterComplete:(AccessibilityWrapper *)aw opRun:(NSInteger)op {
NSInteger nextOpInt = 0;
if (op+1 < [operations count])
nextOpInt = op+1;
NSNumber *nextOp = [NSNumber numberWithInteger:nextOpInt];
if (aw != nil) {
[self setNextOperation:aw nextOp:nextOp];
}
}
- (NSInteger)getNextOperation:(AccessibilityWrapper *)aw {
WindowState *ws = [[WindowState alloc] init:aw];
NSNumber *nextOp = [currentOp objectForKey:ws];
if (nextOp != nil)
return [nextOp integerValue];
return 0;
}
- (void)setNextOperation:(AccessibilityWrapper *)aw nextOp:(NSNumber *)op {
WindowState *ws = [[WindowState alloc] init:aw];
[currentOp setObject:op forKey:ws];
}
- (NSArray *)requiredOptions {
return [NSArray arrayWithObject:OPT_OPERATIONS];
}
- (void)parseOption:(NSString *)_name value:(id)value {
if (value == nil) { return; }
if ([_name isEqualToString:OPT_OPERATIONS]) {
if (![value isKindOfClass:[NSArray class]]) {
@throw([NSException exceptionWithName:[NSString stringWithFormat:@"Invalid %@", _name] reason:[NSString stringWithFormat:@"Invalid %@ '%@'", _name, value] userInfo:nil]);
return;
}
NSMutableArray *ops = [NSMutableArray array];
for (id key in value) {
Operation *op = nil;
if ([key isKindOfClass:[WebScriptObject class]]) {
op = [JSOperation jsOperationWithFunction:key];
} else if ([key isKindOfClass:[Operation class]]) {
op = key;
}
if (op == nil) {
@throw([NSException exceptionWithName:[NSString stringWithFormat:@"Invalid %@", _name] reason:[NSString stringWithFormat:@"Invalid %@ '%@'", _name, value] userInfo:nil]);
continue;
}
[ops addObject:op];
}
[self setOperations:ops];
}
}
+ (id)chainOperation {
return [[ChainOperation alloc] init];
}
+ (id)chainOperationFromString:(NSString *)chainOperation {
// chain op[ | op]+
NSMutableArray *tokens = [[NSMutableArray alloc] initWithCapacity:10];
[StringTokenizer tokenize:chainOperation into:tokens maxTokens:2];
if ([tokens count] < 2) {
SlateLogger(@"ERROR: Invalid Parameters '%@'", chainOperation);
@throw([NSException exceptionWithName:@"Invalid Parameters" reason:[NSString stringWithFormat:@"Invalid Parameters in '%@'. Chain operations require the following format: 'chain op[|op]+'", chainOperation] userInfo:nil]);
}
NSString *opsString = [tokens objectAtIndex:1];
NSArray *ops = [opsString componentsSeparatedByString:PIPE_PADDED];
NSMutableArray *opArray = [[NSMutableArray alloc] initWithCapacity:10];
for (NSInteger i = 0; i < [ops count]; i++) {
Operation *op = [Operation operationFromString:[ops objectAtIndex:i]];
if (op != nil) {
[opArray addObject:op];
} else {
SlateLogger(@"ERROR: Invalid Operation in Chain: '%@'", [ops objectAtIndex:i]);
@throw([NSException exceptionWithName:@"Invalid Operation in Chain" reason:[NSString stringWithFormat:@"Invalid operation '%@' in chain.", [ops objectAtIndex:i]] userInfo:nil]);
}
}
Operation *op = [[ChainOperation alloc] initWithArray:opArray];
return op;
}
@end
================================================
FILE: Slate/ConfigurationHelperView.h
================================================
//
// ConfigurationHelperView.h
// Slate
//
// Created by Jigish Patel on 3/5/12.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import <Cocoa/Cocoa.h>
@interface ConfigurationHelperView : NSView {
@private
NSTextField *directiveLabel;
NSPopUpButton *directive;
NSButton *save;
NSMutableDictionary *configs;
}
@property NSTextField *directiveLabel;
@property NSPopUpButton *directive;
@property NSButton *save;
@property NSMutableDictionary *configs;
- (void)directiveChanged;
- (void)updateDirectiveSpecificUI:(NSString *)str;
- (void)addDirectiveSpecificUIs;
- (void)addConfigUI;
- (void)hideAll:(NSArray *)theThings;
- (void)showAll:(NSArray *)theThings;
- (void)hide:(NSTextField *)theThings;
- (void)show:(NSTextField *)theThings;
- (void)saveToConfig;
@end
================================================
FILE: Slate/ConfigurationHelperView.m
================================================
//
// ConfigurationHelperView.m
// Slate
//
// Created by Jigish Patel on 3/5/12.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import "ConfigurationHelperView.h"
#import "SlateLogger.h"
#import "Constants.h"
#import "SlateConfig.h"
@implementation ConfigurationHelperView
@synthesize directiveLabel, directive, save, configs;
- (NSTextField *)createLabel:(NSString *)text frame:(NSRect)frame {
NSTextField *label = [[NSTextField alloc] initWithFrame:frame];
[label setStringValue:text];
[label setFont:[NSFont fontWithName:@"Menlo" size:11]];
[label setSelectable:NO];
[label setEnabled:NO];
[label setDrawsBackground:NO];
[label setBordered:NO];
[label setBezeled:NO];
return label;
}
- (NSTextField *)createTextField:(NSString *)text frame:(NSRect)frame {
NSTextField *field = [[NSTextField alloc] initWithFrame:frame];
[field setStringValue:text];
[field setFont:[NSFont fontWithName:@"Menlo" size:11]];
return field;
}
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
configs = [NSMutableDictionary dictionary];
directiveLabel = [self createLabel:@"Choose a Directive:" frame:NSMakeRect(5, frame.size.height - 25, 150, 20)];
[self addSubview:directiveLabel];
directive = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(150, frame.size.height - 25, 100, 22)];
[directive addItemsWithTitles:[NSArray arrayWithObjects:EMPTY, CONFIG, LAYOUT, DEFAULT, BIND, nil]];
[directive setTarget:self];
[directive setAction:@selector(directiveChanged)];
save = [[NSButton alloc] initWithFrame:NSMakeRect(frame.size.width/2 - 50, 30, 100, 25)];
[save setTitle:@"Save"];
[save setTarget:self];
[save setAction:@selector(saveToConfig)];
[save setBezelStyle:NSRoundedBezelStyle];
[self addSubview:directive];
[self addSubview:save];
[self addDirectiveSpecificUIs];
[self updateDirectiveSpecificUI:[[directive selectedItem] title]];
}
return self;
}
- (void)directiveChanged {
NSString *title = [[directive selectedItem] title];
SlateLogger(@"Directive Changed: %@", title);
[self updateDirectiveSpecificUI:title];
}
- (void)addDirectiveSpecificUIs {
SlateLogger(@"addDirectiveSpecificUIs");
[self addConfigUI];
}
- (void)hideDirectiveSpecificUIs {
[self hideConfigUI];
}
- (void)addConfigUI {
SlateLogger(@"addConfigUI");
NSInteger i = 0;
for (NSString *configName in [[[SlateConfig getInstance] configs] allKeys]) {
if ([configs objectForKey:configName]) continue;
SlateLogger(@"ADDING CONFIG %@", configName);
NSTextField *configLabel = [self createLabel:configName frame:NSMakeRect(5, [self frame].size.height - 25 * (i+2), 215, 20)];
NSTextField *configField = [self createTextField:[[SlateConfig getInstance] getConfig:configName] frame:NSMakeRect(220, [self frame].size.height - 25 * (i+2) + 1, 200, 20)];
NSTextField *configDefault = [self createLabel:[NSString stringWithFormat:@"Default: %@", [[SlateConfig getInstance] getConfigDefault:configName]] frame:NSMakeRect(420, [self frame].size.height - 25 * (i+2), 200, 20)];
NSArray *objects = [NSArray arrayWithObjects:configLabel, configField, configDefault, nil];
[configs setObject:objects forKey:configName];
[self performSelectorOnMainThread:@selector(hideAll:) withObject:objects waitUntilDone:YES];
[self addSubview:configLabel];
[self addSubview:configField];
[self addSubview:configDefault];
i++;
}
}
- (void)updateConfigUI {
for (NSString *configName in [configs allKeys]) {
[[[configs objectForKey:configName] objectAtIndex:1] setStringValue:[[SlateConfig getInstance] getConfig:configName]];
}
}
- (void)hideConfigUI {
for (NSString *configName in [configs allKeys]) {
SlateLogger(@"HIDING CONFIG %@", configName);
[self performSelectorOnMainThread:@selector(hideAll:) withObject:[configs objectForKey:configName] waitUntilDone:YES];
}
}
- (void)showConfigUI {
[self updateConfigUI];
for (NSString *configName in [configs allKeys]) {
SlateLogger(@"HIDING CONFIG %@", configName);
[self performSelectorOnMainThread:@selector(showAll:) withObject:[configs objectForKey:configName] waitUntilDone:YES];
}
}
- (void)hideAll:(NSArray *)theThings {
for (NSTextField *field in theThings) {
[self hide:field];
}
}
- (void)showAll:(NSArray *)theThings {
for (NSTextField *field in theThings) {
[self show:field];
[field needsDisplay];
}
}
- (void)hide:(NSTextField *)field {
[field setHidden:YES];
}
- (void)show:(NSTextField *)field {
[field setHidden:NO];
}
- (void)updateDirectiveSpecificUI:(NSString *)str {
// Remove everything first
[self hideDirectiveSpecificUIs];
if ([str isEqualToString:CONFIG]) {
SlateLogger(@"IN CONFIG");
[self showConfigUI];
} else if ([str isEqualToString:ALIAS]) {
} else if ([str isEqualToString:LAYOUT]) {
} else if ([str isEqualToString:DEFAULT]) {
} else if ([str isEqualToString:BIND]) {
} else if ([str isEqualToString:SOURCE]) {
} else if ([str isEqualToString:EMPTY]) {
// do nothing
}
[self setNeedsDisplay:YES];
}
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];// Drawing code here.
}
- (void)saveConfig {
// Update SlateConfig
// Save to file
}
- (void)saveToConfig {
if ([[[directive selectedItem] title] isEqualToString:CONFIG]) {
[self saveConfig];
}
}
@end
================================================
FILE: Slate/Constants.h
================================================
//
// Constants.h
// Slate
//
// Created by Jigish Patel on 5/26/11.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
extern NSString *const SNAPSHOTS_FILE;
#define MODAL_BEGIN_ID 20000;
#define CURRENT_MODAL_BEGIN_ID 30000;
extern NSInteger const MODAL_ESCAPE_ID;
// Directive Keys
extern NSString *const BIND;
extern NSString *const CONFIG;
extern NSString *const DEFAULT;
extern NSString *const LAYOUT;
extern NSString *const ALIAS;
extern NSString *const SOURCE;
// Source Option Keys
extern NSString *const IF_EXISTS;
// Config Keys
extern NSString *const DEFAULT_TO_CURRENT_SCREEN;
extern NSString *const DEFAULT_TO_CURRENT_SCREEN_DEFAULT;
extern NSString *const NUDGE_PERCENT_OF;
extern NSString *const NUDGE_PERCENT_OF_DEFAULT;
extern NSString *const RESIZE_PERCENT_OF;
extern NSString *const RESIZE_PERCENT_OF_DEFAULT;
extern NSString *const REPEAT_ON_HOLD_OPS;
extern NSString *const REPEAT_ON_HOLD_OPS_DEFAULT;
extern NSString *const SECONDS_BEFORE_REPEAT;
extern NSString *const SECONDS_BEFORE_REPEAT_DEFAULT;
extern NSString *const SECONDS_BETWEEN_REPEAT;
extern NSString *const SECONDS_BETWEEN_REPEAT_DEFAULT;
extern NSString *const CHECK_DEFAULTS_ON_LOAD;
extern NSString *const CHECK_DEFAULTS_ON_LOAD_DEFAULT;
extern NSString *const FOCUS_CHECK_WIDTH;
extern NSString *const FOCUS_CHECK_WIDTH_DEFAULT;
extern NSString *const FOCUS_CHECK_WIDTH_MAX;
extern NSString *const FOCUS_CHECK_WIDTH_MAX_DEFAULT;
extern NSString *const FOCUS_PREFER_SAME_APP;
extern NSString *const FOCUS_PREFER_SAME_APP_DEFAULT;
extern NSString *const ORDER_SCREENS_LEFT_TO_RIGHT;
extern NSString *const ORDER_SCREENS_LEFT_TO_RIGHT_DEFAULT;
extern NSString *const WINDOW_HINTS_FONT_NAME;
extern NSString *const WINDOW_HINTS_FONT_NAME_DEFAULT;
extern NSString *const WINDOW_HINTS_FONT_SIZE;
extern NSString *const WINDOW_HINTS_FONT_SIZE_DEFAULT;
extern NSString *const WINDOW_HINTS_FONT_COLOR;
extern NSString *const WINDOW_HINTS_FONT_COLOR_DEFAULT;
extern NSString *const WINDOW_HINTS_WIDTH;
extern NSString *const WINDOW_HINTS_WIDTH_DEFAULT;
extern NSString *const WINDOW_HINTS_HEIGHT;
extern NSString *const WINDOW_HINTS_HEIGHT_DEFAULT;
extern NSString *const WINDOW_HINTS_BACKGROUND_COLOR;
extern NSString *const WINDOW_HINTS_BACKGROUND_COLOR_DEFAULT;
extern NSString *const WINDOW_HINTS_DURATION;
extern NSString *const WINDOW_HINTS_DURATION_DEFAULT;
extern NSString *const WINDOW_HINTS_ROUNDED_CORNER_SIZE;
extern NSString *const WINDOW_HINTS_ROUNDED_CORNER_SIZE_DEFAULT;
extern NSString *const WINDOW_HINTS_IGNORE_HIDDEN_WINDOWS;
extern NSString *const WINDOW_HINTS_IGNORE_HIDDEN_WINDOWS_DEFAULT;
extern NSString *const WINDOW_HINTS_TOP_LEFT_X;
extern NSString *const WINDOW_HINTS_TOP_LEFT_X_DEFAULT;
extern NSString *const WINDOW_HINTS_TOP_LEFT_Y;
extern NSString *const WINDOW_HINTS_TOP_LEFT_Y_DEFAULT;
extern NSString *const WINDOW_HINTS_ORDER;
extern NSString *const WINDOW_HINTS_ORDER_DEFAULT;
extern NSString *const WINDOW_HINTS_SHOW_ICONS;
extern NSString *const WINDOW_HINTS_SHOW_ICONS_DEFAULT;
extern NSString *const WINDOW_HINTS_ICON_ALPHA;
extern NSString *const WINDOW_HINTS_ICON_ALPHA_DEFAULT;
extern NSString *const WINDOW_HINTS_SPREAD;
extern NSString *const WINDOW_HINTS_SPREAD_DEFAULT;
extern NSString *const WINDOW_HINTS_SPREAD_SEARCH_WIDTH;
extern NSString *const WINDOW_HINTS_SPREAD_SEARCH_WIDTH_DEFAULT;
extern NSString *const WINDOW_HINTS_SPREAD_SEARCH_HEIGHT;
extern NSString *const WINDOW_HINTS_SPREAD_SEARCH_HEIGHT_DEFAULT;
extern NSString *const WINDOW_HINTS_SPREAD_PADDING;
extern NSString *const WINDOW_HINTS_SPREAD_PADDING_DEFAULT;
extern NSString *const SWITCH_ICON_SIZE;
extern NSString *const SWITCH_ICON_SIZE_DEFAULT;
extern NSString *const SWITCH_ICON_PADDING;
extern NSString *const SWITCH_ICON_PADDING_DEFAULT;
extern NSString *const SWITCH_BACKGROUND_COLOR;
extern NSString *const SWITCH_BACKGROUND_COLOR_DEFAULT;
extern NSString *const SWITCH_SELECTED_BACKGROUND_COLOR;
extern NSString *const SWITCH_SELECTED_BACKGROUND_COLOR_DEFAULT;
extern NSString *const SWITCH_SELECTED_BORDER_COLOR;
extern NSString *const SWITCH_SELECTED_BORDER_COLOR_DEFAULT;
extern NSString *const SWITCH_SELECTED_BORDER_SIZE;
extern NSString *const SWITCH_SELECTED_BORDER_SIZE_DEFAULT;
extern NSString *const SWITCH_ROUNDED_CORNER_SIZE;
extern NSString *const SWITCH_ROUNDED_CORNER_SIZE_DEFAULT;
extern NSString *const SWITCH_ORIENTATION;
extern NSString *const SWITCH_ORIENTATION_DEFAULT;
extern NSString *const SWITCH_SECONDS_BEFORE_REPEAT;
extern NSString *const SWITCH_SECONDS_BEFORE_REPEAT_DEFAULT;
extern NSString *const SWITCH_SECONDS_BETWEEN_REPEAT;
extern NSString *const SWITCH_SECONDS_BETWEEN_REPEAT_DEFAULT;
extern NSString *const SWITCH_STOP_REPEAT_AT_EDGE;
extern NSString *const SWITCH_STOP_REPEAT_AT_EDGE_DEFAULT;
extern NSString *const SWITCH_ONLY_FOCUS_MAIN_WINDOW;
extern NSString *const SWITCH_ONLY_FOCUS_MAIN_WINDOW_DEFAULT;
extern NSString *const SWITCH_FONT_SIZE;
extern NSString *const SWITCH_FONT_SIZE_DEFAULT;
extern NSString *const SWITCH_FONT_COLOR;
extern NSString *const SWITCH_FONT_COLOR_DEFAULT;
extern NSString *const SWITCH_FONT_NAME;
extern NSString *const SWITCH_FONT_NAME_DEFAULT;
extern NSString *const SWITCH_SHOW_TITLES;
extern NSString *const SWITCH_SHOW_TITLES_DEFAULT;
extern NSString *const SWITCH_TYPE;
extern NSString *const SWITCH_TYPE_DEFAULT;
extern NSString *const SWITCH_SELECTED_PADDING;
extern NSString *const SWITCH_SELECTED_PADDING_DEFAULT;
extern NSString *const KEYBOARD_LAYOUT;
extern NSString *const KEYBOARD_LAYOUT_DEFAULT;
extern NSString *const SNAPSHOT_TITLE_MATCH;
extern NSString *const SNAPSHOT_TITLE_MATCH_DEFAULT;
extern NSString *const LEVENSHTEIN;
extern NSString *const SEQUENTIAL;
extern NSString *const SNAPSHOT_MAX_STACK_SIZE;
extern NSString *const SNAPSHOT_MAX_STACK_SIZE_DEFAULT;
extern NSString *const UNDO_MAX_STACK_SIZE;
extern NSString *const UNDO_MAX_STACK_SIZE_DEFAULT;
extern NSString *const UNDO_OPS;
extern NSString *const UNDO_OPS_DEFAULT;
extern NSString *const GRID_BACKGROUND_COLOR;
extern NSString *const GRID_BACKGROUND_COLOR_DEFAULT;
extern NSString *const GRID_ROUNDED_CORNER_SIZE;
extern NSString *const GRID_ROUNDED_CORNER_SIZE_DEFAULT;
extern NSString *const GRID_CELL_BACKGROUND_COLOR;
extern NSString *const GRID_CELL_BACKGROUND_COLOR_DEFAULT;
extern NSString *const GRID_CELL_SELECTED_COLOR;
extern NSString *const GRID_CELL_SELECTED_COLOR_DEFAULT;
extern NSString *const GRID_CELL_ROUNDED_CORNER_SIZE;
extern NSString *const GRID_CELL_ROUNDED_CORNER_SIZE_DEFAULT;
extern NSString *const LAYOUT_FOCUS_ON_ACTIVATE;
extern NSString *const LAYOUT_FOCUS_ON_ACTIVATE_DEFAULT;
extern NSString *const MODAL_ESCAPE_KEY;
extern NSString *const MODAL_ESCAPE_KEY_DEFAULT;
extern NSString *const JS_RECEIVE_MOVE_EVENT;
extern NSString *const JS_RECEIVE_MOVE_EVENT_DEFAULT;
extern NSString *const JS_RECEIVE_RESIZE_EVENT;
extern NSString *const JS_RECEIVE_RESIZE_EVENT_DEFAULT;
// Application Option Keys
extern NSString *const IGNORE_FAIL;
extern NSString *const REPEAT;
extern NSString *const REPEAT_LAST;
extern NSString *const SORT_TITLE;
extern NSString *const MAIN_FIRST;
extern NSString *const MAIN_LAST;
extern NSString *const TITLE_ORDER;
extern NSString *const TITLE_ORDER_REGEX;
// Modifier Keys
extern NSString *const CONTROL;
extern NSString *const COMMAND;
extern NSString *const OPTION;
extern NSString *const SHIFT;
extern NSString *const FUNCTION;
extern UInt32 const FUNCTION_KEY;
// Expression Keys
extern NSString *const SCREEN_ORIGIN_X;
extern NSString *const SCREEN_ORIGIN_Y;
extern NSString *const SCREEN_SIZE;
extern NSString *const SCREEN_SIZE_X;
extern NSString *const SCREEN_SIZE_Y;
extern NSString *const WINDOW_TOP_LEFT_X;
extern NSString *const WINDOW_TOP_LEFT_Y;
extern NSString *const WINDOW_SIZE_X;
extern NSString *const WINDOW_SIZE_Y;
extern NSString *const NEW_WINDOW_SIZE;
extern NSString *const NEW_WINDOW_SIZE_X;
extern NSString *const NEW_WINDOW_SIZE_Y;
// Operations
extern NSString *const MOVE;
extern NSString *const RESIZE;
extern NSString *const PUSH;
extern NSString *const NUDGE;
extern NSString *const THROW;
extern NSString *const CORNER;
extern NSString *const CHAIN;
extern NSString *const FOCUS;
extern NSString *const SNAPSHOT;
extern NSString *const ACTIVATE_SNAPSHOT;
extern NSString *const DELETE_SNAPSHOT;
extern NSString *const HINT;
extern NSString *const SWITCH;
extern NSString *const GRID;
extern NSString *const SEQUENCE;
extern NSString *const HIDE;
extern NSString *const SHOW;
extern NSString *const TOGGLE;
extern NSString *const RELAUNCH;
extern NSString *const SHELL;
extern NSString *const UNDO;
// Parameters and Options
extern NSString *const CENTER;
extern NSString *const BAR;
extern NSString *const BAR_RESIZE_WITH_VALUE;
extern NSString *const NONE;
extern NSString *const NORESIZE;
extern NSString *const RESIZE_WITH_VALUE;
extern NSString *const SAVE_TO_DISK;
extern NSString *const STACK;
extern NSString *const NAME;
extern NSString *const SNAPSHOTS;
extern NSString *const APPS;
extern NSString *const APP_NAME;
extern NSString *const TITLE;
extern NSString *const SIZE;
extern NSString *const ALL;
extern NSString *const DELETE;
extern NSString *const BACK;
extern NSString *const QUIT;
extern NSString *const FORCE_QUIT;
extern NSString *const WINDOW_HINTS_ORDER_NONE;
extern NSString *const WINDOW_HINTS_ORDER_PERSIST;
extern NSString *const WINDOW_HINTS_ORDER_LEFT_TO_RIGHT;
extern NSString *const WINDOW_HINTS_ORDER_RIGHT_TO_LEFT;
extern NSString *const SWITCH_ORIENTATION_HORIZONTAL;
extern NSString *const SWITCH_ORIENTATION_VERTICAL;
extern NSString *const KEYBOARD_LAYOUT_DVORAK;
extern NSString *const KEYBOARD_LAYOUT_COLEMAK;
extern NSString *const KEYBOARD_LAYOUT_AZERTY;
extern NSString *const PADDING;
extern NSString *const CURRENT;
extern NSString *const ALL_BUT;
extern NSString *const WAIT;
extern NSString *const PATH;
extern NSString *const APP_NAME_BEFORE;
extern NSString *const APP_NAME_AFTER;
// Directions and Anchors
extern NSString *const UP;
extern NSString *const DOWN;
extern NSString *const LEFT;
extern NSString *const RIGHT;
extern NSString *const TOP;
extern NSString *const BOTTOM;
extern NSString *const ABOVE;
extern NSString *const BELOW;
extern NSString *const NEXT;
extern NSString *const PREVIOUS;
extern NSString *const PREV;
extern NSString *const BEHIND;
extern NSString *const TOP_LEFT;
extern NSString *const TOP_RIGHT;
extern NSString *const BOTTOM_LEFT;
extern NSString *const BOTTOM_RIGHT;
extern NSInteger const DIRECTION_UNKNOWN;
extern NSInteger const DIRECTION_UP;
extern NSInteger const DIRECTION_DOWN;
extern NSInteger const DIRECTION_LEFT;
extern NSInteger const DIRECTION_RIGHT;
extern NSInteger const DIRECTION_TOP;
extern NSInteger const DIRECTION_BOTTOM;
extern NSInteger const DIRECTION_ABOVE;
extern NSInteger const DIRECTION_BELOW;
extern NSInteger const DIRECTION_BEHIND;
extern NSInteger const ANCHOR_TOP_LEFT;
extern NSInteger const ANCHOR_TOP_RIGHT;
extern NSInteger const ANCHOR_BOTTOM_LEFT;
extern NSInteger const ANCHOR_BOTTOM_RIGHT;
// Seperators and such
extern unichar const COMMENT_CHARACTER;
extern NSString *const COMMA;
extern NSString *const COLON;
extern NSString *const SEMICOLON;
extern NSString *const MINUS;
extern NSString *const PLUS;
extern NSString *const PERCENT;
extern NSString *const EMPTY;
extern NSString *const PIPE_PADDED;
extern NSString *const GREATER_THAN_PADDED;
extern NSString *const QUOTES;
extern NSString *const EQUALS;
extern NSString *const TILDA;
extern NSString *const SLASH;
extern NSString *const X;
extern NSString *const Y;
extern NSString *const WIDTH;
extern NSString *const HEIGHT;
extern NSString *const WHITESPACE;
// Screen constants
extern NSString *const REF_CURRENT_SCREEN;
extern NSInteger const ID_MAIN_SCREEN;
extern NSInteger const ID_CURRENT_SCREEN;
extern NSInteger const ID_IGNORE_SCREEN;
extern NSInteger const TYPE_UNKNOWN;
extern NSInteger const TYPE_COUNT;
extern NSInteger const TYPE_RESOLUTIONS;
extern NSString *const COUNT;
extern NSString *const RESOLUTIONS;
extern NSString *const ORDERED;
// Notifications
extern NSString *const NOTIFICATION_SCREEN_CHANGE;
extern NSString *const NOTIFICATION_SCREEN_CHANGE_LION;
// Applications
extern NSString *const FINDER;
// Window Hint
extern NSInteger const HINT_X_PADDING;
extern NSString *const HINT_CHARACTERS;
extern NSInteger const MAIN_MENU_HEIGHT;
// Internal Snapshots
extern NSString *const MENU_SNAPSHOT;
extern NSString *const UNDO_SNAPSHOT;
// File Extensions
extern NSString *const EXT_JS;
// Javascript Operation Options Hash Keys
extern NSString *const OPT_STYLE;
extern NSString *const OPT_DIRECTION;
extern NSString *const OPT_SCREEN;
extern NSString *const OPT_X;
extern NSString *const OPT_Y;
extern NSString *const OPT_WIDTH;
extern NSString *const OPT_HEIGHT;
extern NSString *const OPT_ANCHOR;
extern NSString *const OPT_APP;
extern NSString *const OPT_COMMAND;
extern NSString *const OPT_WAIT;
extern NSString *const OPT_PATH;
extern NSString *const OPT_NAME;
extern NSString *const OPT_CHARACTERS;
extern NSString *const OPT_PADDING;
extern NSString *const OPT_GRIDS;
extern NSString *const OPT_BACK;
extern NSString *const OPT_QUIT;
extern NSString *const OPT_FORCE_QUIT;
extern NSString *const OPT_HIDE;
extern NSString *const OPT_DELETE;
extern NSString *const OPT_ALL;
extern NSString *const OPT_SAVE;
extern NSString *const OPT_STACK;
extern NSString *const OPT_OPERATIONS;
extern NSString *const OPT_IGNORE_FAIL;
extern NSString *const OPT_REPEAT;
extern NSString *const OPT_REPEAT_LAST;
extern NSString *const OPT_SORT_TITLE;
extern NSString *const OPT_MAIN_FIRST;
extern NSString *const OPT_MAIN_LAST;
extern NSString *const OPT_TITLE_ORDER;
extern NSString *const OPT_TITLE_ORDER_REGEX;
extern NSString *const OPT_BEFORE;
extern NSString *const OPT_AFTER;
================================================
FILE: Slate/Constants.m
================================================
//
// Constants.m
// Slate
//
// Created by Jigish Patel on 5/26/11.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import "Constants.h"
NSInteger const MODAL_ESCAPE_ID = 40000;
NSString *const SNAPSHOTS_FILE = @"snapshots";
// Directive Keys
NSString *const BIND = @"bind";
NSString *const CONFIG = @"config";
NSString *const LAYOUT = @"layout";
NSString *const DEFAULT = @"default";
NSString *const ALIAS = @"alias";
NSString *const SOURCE = @"source";
// Source Option Keys
NSString *const IF_EXISTS = @"if_exists";
// Config Keys
NSString *const DEFAULT_TO_CURRENT_SCREEN = @"defaultToCurrentScreen";
NSString *const DEFAULT_TO_CURRENT_SCREEN_DEFAULT = @"false";
NSString *const NUDGE_PERCENT_OF = @"nudgePercentOf";
NSString *const NUDGE_PERCENT_OF_DEFAULT = @"screenSize";
NSString *const RESIZE_PERCENT_OF = @"resizePercentOf";
NSString *const RESIZE_PERCENT_OF_DEFAULT = @"screenSize";
NSString *const REPEAT_ON_HOLD_OPS = @"repeatOnHoldOps";
NSString *const REPEAT_ON_HOLD_OPS_DEFAULT = @"resize,nudge";
NSString *const SECONDS_BEFORE_REPEAT = @"secondsBeforeRepeat";
NSString *const SECONDS_BEFORE_REPEAT_DEFAULT = @"0.4";
NSString *const SECONDS_BETWEEN_REPEAT = @"secondsBetweenRepeat";
NSString *const SECONDS_BETWEEN_REPEAT_DEFAULT = @"0.2";
NSString *const CHECK_DEFAULTS_ON_LOAD = @"checkDefaultsOnLoad";
NSString *const CHECK_DEFAULTS_ON_LOAD_DEFAULT = @"false";
NSString *const FOCUS_CHECK_WIDTH = @"focusCheckWidth";
NSString *const FOCUS_CHECK_WIDTH_DEFAULT = @"100";
NSString *const FOCUS_CHECK_WIDTH_MAX = @"focusCheckWidthMax";
NSString *const FOCUS_CHECK_WIDTH_MAX_DEFAULT = @"100";
NSString *const FOCUS_PREFER_SAME_APP = @"focusPreferSameApp";
NSString *const FOCUS_PREFER_SAME_APP_DEFAULT = @"true";
NSString *const ORDER_SCREENS_LEFT_TO_RIGHT = @"orderScreensLeftToRight";
NSString *const ORDER_SCREENS_LEFT_TO_RIGHT_DEFAULT = @"true";
NSString *const WINDOW_HINTS_FONT_NAME = @"windowHintsFontName";
NSString *const WINDOW_HINTS_FONT_NAME_DEFAULT = @"Helvetica";
NSString *const WINDOW_HINTS_FONT_SIZE = @"windowHintsFontSize";
NSString *const WINDOW_HINTS_FONT_SIZE_DEFAULT = @"40";
NSString *const WINDOW_HINTS_FONT_COLOR = @"windowHintsFontColor";
NSString *const WINDOW_HINTS_FONT_COLOR_DEFAULT = @"255;255;255;1.0";
NSString *const WINDOW_HINTS_WIDTH = @"windowHintsWidth";
NSString *const WINDOW_HINTS_WIDTH_DEFAULT = @"100";
NSString *const WINDOW_HINTS_HEIGHT = @"windowHintsHeight";
NSString *const WINDOW_HINTS_HEIGHT_DEFAULT = @"100";
NSString *const WINDOW_HINTS_BACKGROUND_COLOR = @"windowHintsBackgroundColor";
NSString *const WINDOW_HINTS_BACKGROUND_COLOR_DEFAULT = @"50;53;58;0.9";
NSString *const WINDOW_HINTS_DURATION = @"windowHintsDuration";
NSString *const WINDOW_HINTS_DURATION_DEFAULT = @"3";
NSString *const WINDOW_HINTS_ROUNDED_CORNER_SIZE = @"windowHintsRoundedCornerSize";
NSString *const WINDOW_HINTS_ROUNDED_CORNER_SIZE_DEFAULT = @"5";
NSString *const WINDOW_HINTS_IGNORE_HIDDEN_WINDOWS = @"windowHintsIgnoreHiddenWindows";
NSString *const WINDOW_HINTS_IGNORE_HIDDEN_WINDOWS_DEFAULT = @"true";
NSString *const WINDOW_HINTS_TOP_LEFT_X = @"windowHintsTopLeftX";
NSString *const WINDOW_HINTS_TOP_LEFT_X_DEFAULT = @"(windowSizeX/2)-(windowHintsWidth/2);0";
NSString *const WINDOW_HINTS_TOP_LEFT_Y = @"windowHintsTopLeftY";
NSString *const WINDOW_HINTS_TOP_LEFT_Y_DEFAULT = @"(windowSizeY/2)-(windowHintsHeight/2);0";
NSString *const WINDOW_HINTS_ORDER = @"windowHintsOrder";
NSString *const WINDOW_HINTS_ORDER_DEFAULT = @"leftToRight";
NSString *const WINDOW_HINTS_SHOW_ICONS = @"windowHintsShowIcons";
NSString *const WINDOW_HINTS_SHOW_ICONS_DEFAULT = @"false";
NSString *const WINDOW_HINTS_ICON_ALPHA = @"windowHintsIconAlpha";
NSString *const WINDOW_HINTS_ICON_ALPHA_DEFAULT = @"1.0";
NSString *const WINDOW_HINTS_SPREAD = @"windowHintsSpread";
NSString *const WINDOW_HINTS_SPREAD_DEFAULT = @"false";
NSString *const WINDOW_HINTS_SPREAD_SEARCH_WIDTH = @"windowHintsSpreadSearchWidth";
NSString *const WINDOW_HINTS_SPREAD_SEARCH_WIDTH_DEFAULT = @"40";
NSString *const WINDOW_HINTS_SPREAD_SEARCH_HEIGHT = @"windowHintsSpreadSearchHeight";
NSString *const WINDOW_HINTS_SPREAD_SEARCH_HEIGHT_DEFAULT = @"40";
NSString *const WINDOW_HINTS_SPREAD_PADDING = @"windowHintsSpreadPadding";
NSString *const WINDOW_HINTS_SPREAD_PADDING_DEFAULT = @"20";
NSString *const SWITCH_ICON_SIZE = @"switchIconSize";
NSString *const SWITCH_ICON_SIZE_DEFAULT = @"100";
NSString *const SWITCH_ICON_PADDING = @"switchIconPadding";
NSString *const SWITCH_ICON_PADDING_DEFAULT = @"5";
NSString *const SWITCH_BACKGROUND_COLOR = @"switchBackgroundColor";
NSString *const SWITCH_BACKGROUND_COLOR_DEFAULT = @"50;53;58;0.3";
NSString *const SWITCH_SELECTED_BACKGROUND_COLOR = @"switchSelectedBackgroundColor";
NSString *const SWITCH_SELECTED_BACKGROUND_COLOR_DEFAULT = @"50;53;58;0.9";
NSString *const SWITCH_SELECTED_BORDER_COLOR = @"switchSelectedBorderColor";
NSString *const SWITCH_SELECTED_BORDER_COLOR_DEFAULT = @"230;230;230;0.9";
NSString *const SWITCH_SELECTED_BORDER_SIZE = @"switchSelectedBorderSize";
NSString *const SWITCH_SELECTED_BORDER_SIZE_DEFAULT = @"2";
NSString *const SWITCH_ROUNDED_CORNER_SIZE = @"switchRoundedCornerSize";
NSString *const SWITCH_ROUNDED_CORNER_SIZE_DEFAULT = @"5";
NSString *const SWITCH_ORIENTATION = @"switchOrientation";
NSString *const SWITCH_ORIENTATION_DEFAULT = @"horizontal";
NSString *const SWITCH_SECONDS_BEFORE_REPEAT = @"switchSecondsBeforeRepeat";
NSString *const SWITCH_SECONDS_BEFORE_REPEAT_DEFAULT = @"0.3";
NSString *const SWITCH_SECONDS_BETWEEN_REPEAT = @"switchSecondsBetweenRepeat";
NSString *const SWITCH_SECONDS_BETWEEN_REPEAT_DEFAULT = @"0.03";
NSString *const SWITCH_STOP_REPEAT_AT_EDGE = @"switchStopRepeatAtEdge";
NSString *const SWITCH_STOP_REPEAT_AT_EDGE_DEFAULT = @"true";
NSString *const SWITCH_ONLY_FOCUS_MAIN_WINDOW = @"switchOnlyFocusMainWindow";
NSString *const SWITCH_ONLY_FOCUS_MAIN_WINDOW_DEFAULT = @"true";
NSString *const SWITCH_FONT_SIZE = @"switchFontSize";
NSString *const SWITCH_FONT_SIZE_DEFAULT = @"14";
NSString *const SWITCH_FONT_COLOR = @"switchFontColor";
NSString *const SWITCH_FONT_COLOR_DEFAULT = @"255;255;255;1.0";
NSString *const SWITCH_FONT_NAME = @"switchFontName";
NSString *const SWITCH_FONT_NAME_DEFAULT = @"Helvetica";
NSString *const SWITCH_SHOW_TITLES = @"switchShowTitles";
NSString *const SWITCH_SHOW_TITLES_DEFAULT = @"false";
NSString *const SWITCH_TYPE = @"switchType";
NSString *const SWITCH_TYPE_DEFAULT = @"app";
NSString *const SWITCH_SELECTED_PADDING = @"switchSelectedPadding";
NSString *const SWITCH_SELECTED_PADDING_DEFAULT = @"10";
NSString *const KEYBOARD_LAYOUT = @"keyboardLayout";
NSString *const KEYBOARD_LAYOUT_DEFAULT = @"qwerty";
NSString *const SNAPSHOT_TITLE_MATCH = @"snapshotTitleMatch";
NSString *const SNAPSHOT_TITLE_MATCH_DEFAULT = @"levenshtein";
NSString *const LEVENSHTEIN = @"levenshtein";
NSString *const SEQUENTIAL = @"sequential";
NSString *const SNAPSHOT_MAX_STACK_SIZE = @"snapshotMaxStackSize";
NSString *const SNAPSHOT_MAX_STACK_SIZE_DEFAULT = @"0";
NSString *const UNDO_MAX_STACK_SIZE = @"undoMaxStackSize";
NSString *const UNDO_MAX_STACK_SIZE_DEFAULT = @"10";
NSString *const UNDO_OPS = @"undoOps";
NSString *const UNDO_OPS_DEFAULT = @"activate-snapshot,chain,grid,layout,move,push,nudge,corner,throw,resize,sequence,shell";
NSString *const GRID_BACKGROUND_COLOR = @"gridBackgroundColor";
NSString *const GRID_BACKGROUND_COLOR_DEFAULT = @"75;77;81;1.0";
NSString *const GRID_ROUNDED_CORNER_SIZE = @"gridRoundedCornerSize";
NSString *const GRID_ROUNDED_CORNER_SIZE_DEFAULT = @"5";
NSString *const GRID_CELL_BACKGROUND_COLOR = @"gridCellBackgroundColor";
NSString *const GRID_CELL_BACKGROUND_COLOR_DEFAULT = @"100;106;116;0.8";
NSString *const GRID_CELL_SELECTED_COLOR = @"gridCellSelectedColor";
NSString *const GRID_CELL_SELECTED_COLOR_DEFAULT = @"50;53;58;0.8";
NSString *const GRID_CELL_ROUNDED_CORNER_SIZE = @"gridCellRoundedCornerSize";
NSString *const GRID_CELL_ROUNDED_CORNER_SIZE_DEFAULT = @"5";
NSString *const LAYOUT_FOCUS_ON_ACTIVATE = @"layoutFocusOnActivate";
NSString *const LAYOUT_FOCUS_ON_ACTIVATE_DEFAULT = @"false";
NSString *const MODAL_ESCAPE_KEY = @"modalEscapeKey";
NSString *const MODAL_ESCAPE_KEY_DEFAULT = @"";
NSString *const JS_RECEIVE_MOVE_EVENT = @"jsReceiveMoveEvent";
NSString *const JS_RECEIVE_MOVE_EVENT_DEFAULT = @"false";
NSString *const JS_RECEIVE_RESIZE_EVENT = @"jsReceiveResizeEvent";
NSString *const JS_RECEIVE_RESIZE_EVENT_DEFAULT = @"false";
// Application Option Keys
NSString *const IGNORE_FAIL = @"IGNORE_FAIL";
NSString *const REPEAT = @"REPEAT";
NSString *const REPEAT_LAST = @"REPEAT_LAST";
NSString *const SORT_TITLE = @"SORT_TITLE";
NSString *const MAIN_FIRST = @"MAIN_FIRST";
NSString *const MAIN_LAST = @"MAIN_LAST";
NSString *const TITLE_ORDER = @"TITLE_ORDER=";
NSString *const TITLE_ORDER_REGEX = @"TITLE_ORDER_REGEX=";
// Modifier Keys
NSString *const CONTROL = @"ctrl";
NSString *const COMMAND = @"cmd";
NSString *const OPTION = @"alt";
NSString *const SHIFT = @"shift";
NSString *const FUNCTION = @"fn";
UInt32 const FUNCTION_KEY = 0x800000;
// Expression Keys
NSString *const SCREEN_ORIGIN_X = @"screenOriginX";
NSString *const SCREEN_ORIGIN_Y = @"screenOriginY";
NSString *const SCREEN_SIZE = @"screenSize";
NSString *const SCREEN_SIZE_X = @"screenSizeX";
NSString *const SCREEN_SIZE_Y = @"screenSizeY";
NSString *const WINDOW_TOP_LEFT_X = @"windowTopLeftX";
NSString *const WINDOW_TOP_LEFT_Y = @"windowTopLeftY";
NSString *const WINDOW_SIZE_X = @"windowSizeX";
NSString *const WINDOW_SIZE_Y = @"windowSizeY";
NSString *const NEW_WINDOW_SIZE = @"newWindowSize";
NSString *const NEW_WINDOW_SIZE_X = @"newWindowSizeX";
NSString *const NEW_WINDOW_SIZE_Y = @"newWindowSizeY";
// Operations
NSString *const MOVE = @"move";
NSString *const RESIZE = @"resize";
NSString *const PUSH = @"push";
NSString *const NUDGE = @"nudge";
NSString *const THROW = @"throw";
NSString *const CORNER = @"corner";
NSString *const CHAIN = @"chain";
NSString *const FOCUS = @"focus";
NSString *const SNAPSHOT = @"snapshot";
NSString *const ACTIVATE_SNAPSHOT = @"activate-snapshot";
NSString *const DELETE_SNAPSHOT = @"delete-snapshot";
NSString *const HINT = @"hint";
NSString *const SWITCH = @"switch";
NSString *const GRID = @"grid";
NSString *const SEQUENCE = @"sequence";
NSString *const HIDE = @"hide";
NSString *const SHOW = @"show";
NSString *const TOGGLE = @"toggle";
NSString *const RELAUNCH = @"relaunch";
NSString *const SHELL = @"shell";
NSString *const UNDO = @"undo";
// Parameters and Options
NSString *const CENTER = @"center";
NSString *const BAR = @"bar";
NSString *const BAR_RESIZE_WITH_VALUE = @"bar-resize:";
NSString *const NONE = @"none";
NSString *const NORESIZE = @"noresize";
NSString *const RESIZE_WITH_VALUE = @"resize:";
NSString *const SAVE_TO_DISK = @"save-to-disk";
NSString *const STACK = @"stack";
NSString *const NAME = @"name";
NSString *const SNAPSHOTS = @"snapshots";
NSString *const APPS = @"apps";
NSString *const APP_NAME = @"app-name";
NSString *const TITLE = @"title";
NSString *const SIZE = @"size";
NSString *const ALL = @"all";
NSString *const DELETE = @"delete";
NSString *const BACK = @"back";
NSString *const QUIT = @"quit";
NSString *const FORCE_QUIT = @"force-quit";
NSString *const WINDOW_HINTS_ORDER_NONE = @"none";
NSString *const WINDOW_HINTS_ORDER_PERSIST = @"persist";
NSString *const WINDOW_HINTS_ORDER_LEFT_TO_RIGHT = @"leftToRight";
NSString *const WINDOW_HINTS_ORDER_RIGHT_TO_LEFT = @"rightToLeft";
NSString *const SWITCH_ORIENTATION_HORIZONTAL = @"horizontal";
NSString *const SWITCH_ORIENTATION_VERTICAL = @"vertical";
NSString *const KEYBOARD_LAYOUT_DVORAK = @"dvorak";
NSString *const KEYBOARD_LAYOUT_COLEMAK = @"colemak";
NSString *const KEYBOARD_LAYOUT_AZERTY = @"azerty";
NSString *const PADDING = @"padding";
NSString *const CURRENT = @"current";
NSString *const ALL_BUT = @"all-but:";
NSString *const WAIT = @"wait";
NSString *const PATH = @"path:";
NSString *const APP_NAME_BEFORE = @"BEFORE";
NSString *const APP_NAME_AFTER = @"AFTER";
// Directions and Anchors
NSString *const UP = @"up";
NSString *const DOWN = @"down";
NSString *const LEFT = @"left";
NSString *const RIGHT = @"right";
NSString *const TOP = @"top";
NSString *const BOTTOM = @"bottom";
NSString *const ABOVE = @"above";
NSString *const BELOW = @"below";
NSString *const NEXT = @"next";
NSString *const PREVIOUS = @"previous";
NSString *const PREV = @"prev";
NSString *const BEHIND = @"behind";
NSString *const TOP_LEFT = @"top-left";
NSString *const TOP_RIGHT = @"top-right";
NSString *const BOTTOM_LEFT = @"bottom-left";
NSString *const BOTTOM_RIGHT = @"bottom-right";
NSInteger const DIRECTION_UNKNOWN = -1;
NSInteger const DIRECTION_UP = 0;
NSInteger const DIRECTION_DOWN = 1;
NSInteger const DIRECTION_LEFT = 2;
NSInteger const DIRECTION_RIGHT = 3;
NSInteger const DIRECTION_TOP = 4;
NSInteger const DIRECTION_BOTTOM = 5;
NSInteger const DIRECTION_ABOVE = 6;
NSInteger const DIRECTION_BELOW = 7;
NSInteger const DIRECTION_BEHIND = 8;
NSInteger const ANCHOR_TOP_LEFT = 0;
NSInteger const ANCHOR_TOP_RIGHT = 1;
NSInteger const ANCHOR_BOTTOM_LEFT = 2;
NSInteger const ANCHOR_BOTTOM_RIGHT = 3;
// Seperators and such
unichar const COMMENT_CHARACTER = '#';
NSString *const COMMA = @",";
NSString *const COLON = @":";
NSString *const SEMICOLON = @";";
NSString *const MINUS = @"-";
NSString *const PLUS = @"+";
NSString *const PERCENT = @"%";
NSString *const EMPTY = @"";
NSString *const PIPE_PADDED = @" | ";
NSString *const GREATER_THAN_PADDED = @" > ";
NSString *const QUOTES = @"'\"";
NSString *const EQUALS = @"=";
NSString *const TILDA = @"~";
NSString *const SLASH = @"/";
NSString *const X = @"x";
NSString *const Y = @"y";
NSString *const WIDTH = @"width";
NSString *const HEIGHT = @"height";
NSString *const WHITESPACE = @" \t";
// Screen constants
NSString *const REF_CURRENT_SCREEN = @"-1";
NSInteger const ID_MAIN_SCREEN = 0;
NSInteger const ID_CURRENT_SCREEN = -1;
NSInteger const ID_IGNORE_SCREEN = -2;
NSInteger const TYPE_UNKNOWN = -1;
NSInteger const TYPE_COUNT = 0;
NSInteger const TYPE_RESOLUTIONS = 1;
NSString *const COUNT = @"count";
NSString *const RESOLUTIONS = @"resolutions";
NSString *const ORDERED = @"ordered";
// Notifications
NSString *const NOTIFICATION_SCREEN_CHANGE = @"O3DeviceTimingChanged";
NSString *const NOTIFICATION_SCREEN_CHANGE_LION = @" com.apple.BezelServices.BMDisplayHWReconfiguredEvent";
// Applications
NSString *const FINDER = @"Finder";
// Window Hints
NSInteger const HINT_X_PADDING = 4;
NSString *const HINT_CHARACTERS = @"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
NSInteger const MAIN_MENU_HEIGHT = 22;
// Internal Snapshots
NSString *const MENU_SNAPSHOT = @"menuSnapshot"; // need to change this name.
NSString *const UNDO_SNAPSHOT = @"_internal_UndoSnapshot";
// File Extensions
NSString *const EXT_JS = @".js";
// Javascript Operation Options Hash Keys
NSString *const OPT_STYLE = @"style";
NSString *const OPT_DIRECTION = @"direction";
NSString *const OPT_SCREEN = @"screen";
NSString *const OPT_X = @"x";
NSString *const OPT_Y = @"y";
NSString *const OPT_WIDTH = @"width";
NSString *const OPT_HEIGHT = @"height";
NSString *const OPT_ANCHOR = @"anchor";
NSString *const OPT_APP = @"app";
NSString *const OPT_COMMAND = @"command";
NSString *const OPT_WAIT = @"wait";
NSString *const OPT_PATH = @"path";
NSString *const OPT_NAME = @"name";
NSString *const OPT_CHARACTERS = @"characters";
NSString *const OPT_PADDING = @"padding";
NSString *const OPT_GRIDS = @"grids";
NSString *const OPT_BACK = @"back";
NSString *const OPT_QUIT = @"quit";
NSString *const OPT_FORCE_QUIT = @"force-quit";
NSString *const OPT_HIDE = @"hide";
NSString *const OPT_DELETE = @"delete";
NSString *const OPT_ALL = @"all";
NSString *const OPT_SAVE = @"save";
NSString *const OPT_STACK = @"stack";
NSString *const OPT_OPERATIONS = @"operations";
NSString *const OPT_IGNORE_FAIL = @"ignore-fail";
NSString *const OPT_REPEAT = @"repeat";
NSString *const OPT_REPEAT_LAST = @"repeat-last";
NSString *const OPT_SORT_TITLE = @"sort-title";
NSString *const OPT_MAIN_FIRST = @"main-first";
NSString *const OPT_MAIN_LAST = @"main-last";
NSString *const OPT_TITLE_ORDER = @"title-order";
NSString *const OPT_TITLE_ORDER_REGEX = @"title-order-regex";
NSString *const OPT_BEFORE = @"_before_";
NSString *const OPT_AFTER = @"_after_";
================================================
FILE: Slate/CornerOperation.h
================================================
//
// CornerOperation.h
// Slate
//
// Created by Jigish Patel on 1/20/13.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import "MoveOperation.h"
@interface CornerOperation : MoveOperation
+ (id)cornerOperation;
+ (id)cornerOperationFromString:(NSString *)cornerOperation;
@end
================================================
FILE: Slate/CornerOperation.m
================================================
//
// CornerOperation.m
// Slate
//
// Created by Jigish Patel on 1/20/13.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import "CornerOperation.h"
#import "StringTokenizer.h"
#import "Constants.h"
#import "SlateLogger.h"
@implementation CornerOperation
- (NSArray *)requiredOptions {
return [NSArray arrayWithObjects:OPT_DIRECTION, nil];
}
- (void)afterEvalOptions {
NSString *width = [[self options] objectForKey:OPT_WIDTH];
if (width == nil) { width = @"windowSizeX"; }
NSString *height = [[self options] objectForKey:OPT_HEIGHT];
if (height == nil) { height = @"windowSizeY"; }
[self setDimensions:[[ExpressionPoint alloc] initWithX:width y:height]];
NSString *screen = [[self options] objectForKey:OPT_SCREEN];
if (screen == nil) { screen = REF_CURRENT_SCREEN; }
[self setMonitor:screen];
NSString *direction = [[self options] objectForKey:OPT_DIRECTION];
if ([direction isEqualToString:TOP_LEFT]) {
[self setTopLeft:[[ExpressionPoint alloc] initWithX:@"screenOriginX" y:@"screenOriginY"]];
} else if ([direction isEqualToString:TOP_RIGHT]) {
[self setTopLeft:[[ExpressionPoint alloc] initWithX:[NSString stringWithFormat:@"screenOriginX+screenSizeX-(%@)", [[self dimensions] x]] y:@"screenOriginY"]];
} else if ([direction isEqualToString:BOTTOM_LEFT]) {
[self setTopLeft:[[ExpressionPoint alloc] initWithX:@"screenOriginX" y:[NSString stringWithFormat:@"screenOriginY+screenSizeY-(%@)", [[self dimensions] y]]]];
} else if ([direction isEqualToString:BOTTOM_RIGHT]) {
[self setTopLeft:[[ExpressionPoint alloc] initWithX:[NSString stringWithFormat:@"screenOriginX+screenSizeX-(%@)", [[self dimensions] x]] y:[NSString stringWithFormat:@"screenOriginY+screenSizeY-(%@)", [[self dimensions] y]]]];
} else {
SlateLogger(@"ERROR: Unrecognized corner '%@'", direction);
@throw([NSException exceptionWithName:@"Unrecognized Corner" reason:[NSString stringWithFormat:@"Unrecognized corner '%@'", direction] userInfo:nil]);
}
}
+ (id)cornerOperation {
return [[CornerOperation alloc] init];
}
+ (id)cornerOperationFromString:(NSString *)cornerOperation {
// corner <top-left|top-right|bottom-left|bottom-right> <optional:resize:expression> <optional:monitor>
NSMutableArray *tokens = [[NSMutableArray alloc] initWithCapacity:10];
[StringTokenizer tokenize:cornerOperation into:tokens];
if ([tokens count] < 2) {
SlateLogger(@"ERROR: Invalid Parameters '%@'", cornerOperation);
@throw([NSException exceptionWithName:@"Invalid Parameters" reason:[NSString stringWithFormat:@"Invalid Parameters in '%@'. Corner operations require the following format: 'corner direction [optional:style]'", cornerOperation] userInfo:nil]);
}
NSString *tl = nil;
NSString *dim = @"windowSizeX;windowSizeY";
NSString *direction = [tokens objectAtIndex:1];
if ([tokens count] >= 3) {
NSString *style = [tokens objectAtIndex:2];
if ([style hasPrefix:RESIZE_WITH_VALUE]) {
dim = [[style componentsSeparatedByString:COLON] objectAtIndex:1];
}
}
if ([direction isEqualToString:TOP_LEFT]) {
tl = @"screenOriginX;screenOriginY";
} else if ([direction isEqualToString:TOP_RIGHT]) {
tl = [[@"screenOriginX+screenSizeX-" stringByAppendingString:[[dim componentsSeparatedByString:SEMICOLON] objectAtIndex:0]] stringByAppendingString:@";screenOriginY"];
} else if ([direction isEqualToString:BOTTOM_LEFT]) {
tl = [@"screenOriginX;screenOriginY+screenSizeY-" stringByAppendingString:[[dim componentsSeparatedByString:SEMICOLON] objectAtIndex:1]];
} else if ([direction isEqualToString:BOTTOM_RIGHT]) {
tl = [[[@"screenOriginX+screenSizeX-" stringByAppendingString:[[dim componentsSeparatedByString:SEMICOLON] objectAtIndex:0]] stringByAppendingString:@";screenOriginY+screenSizeY-"] stringByAppendingString:[[dim componentsSeparatedByString:SEMICOLON] objectAtIndex:1]];
} else {
SlateLogger(@"ERROR: Unrecognized corner '%@'", direction);
@throw([NSException exceptionWithName:@"Unrecognized Corner" reason:[NSString stringWithFormat:@"Unrecognized corner '%@' in '%@'", direction, cornerOperation] userInfo:nil]);
}
Operation *op = [[MoveOperation alloc] initWithTopLeft:tl dimensions:dim monitor:([tokens count] >=4 ? [tokens objectAtIndex:3] : REF_CURRENT_SCREEN)];
return op;
}
@end
================================================
FILE: Slate/DeleteSnapshotOperation.h
================================================
//
// DeleteSnapshotOperation.h
// Slate
//
// Created by Jigish Patel on 2/28/12.
// Copyright 2012 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import "Operation.h"
@interface DeleteSnapshotOperation : Operation {
@private
NSString *name;
BOOL pop;
}
@property NSString *name;
@property (assign) BOOL pop;
- (id)initWithName:(NSString *)theName options:(NSString *)options;
+ (id)deleteSnapshotOperation;
+ (id)deleteSnapshotOperationFromString:(NSString *)deleteSnapshotOperation;
@end
================================================
FILE: Slate/DeleteSnapshotOperation.m
================================================
//
// DeleteSnapshotOperation.m
// Slate
//
// Created by Jigish Patel on 2/28/12.
// Copyright 2012 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import "DeleteSnapshotOperation.h"
#import "Constants.h"
#import "SlateConfig.h"
#import "StringTokenizer.h"
#import "SlateLogger.h"
@implementation DeleteSnapshotOperation
@synthesize name, pop;
- (id)init {
self = [super init];
if (self) {
pop = YES;
}
return self;
}
- (id)initWithName:(NSString *)theName options:(NSString *)_options {
self = [self init];
if (self) {
[self setName:theName];
if (_options) {
NSArray *optionsTokens = [_options componentsSeparatedByString:SEMICOLON];
for (NSInteger i = 0; i < [optionsTokens count]; i++) {
NSString *option = [optionsTokens objectAtIndex:i];
if ([ALL isEqualToString:option]) {
pop = NO;
}
}
}
}
return self;
}
- (BOOL)doOperation {
SlateLogger(@"----------------- Begin Delete Snapshot Operation -----------------");
BOOL success = [self doOperationWithAccessibilityWrapper:nil screenWrapper:nil];
SlateLogger(@"----------------- End Delete Snapshot Operation -----------------");
return success;
}
- (BOOL)doOperationWithAccessibilityWrapper:(AccessibilityWrapper *)iamnil screenWrapper:(ScreenWrapper *)iamalsonil {
[self evalOptionsWithAccessibilityWrapper:iamnil screenWrapper:iamalsonil];
[[SlateConfig getInstance] deleteSnapshot:name pop:pop];
return YES;
}
- (BOOL)testOperation {
return YES;
}
- (NSArray *)requiredOptions {
return [NSArray arrayWithObject:OPT_NAME];
}
- (void)parseOption:(NSString *)_name value:(id)value {
if (value == nil) { return; }
if ([_name isEqualToString:OPT_NAME]) {
if (![value isKindOfClass:[NSString class]]) {
@throw([NSException exceptionWithName:[NSString stringWithFormat:@"Invalid %@", _name] reason:[NSString stringWithFormat:@"Invalid %@ '%@'", _name, value] userInfo:nil]);
return;
}
[self setName:_name];
} else if ([_name isEqualToString:OPT_ALL]) {
if (![value isKindOfClass:[NSValue class]] && ![value isKindOfClass:[NSString class]] && ![value isKindOfClass:[NSNumber class]]) {
@throw([NSException exceptionWithName:[NSString stringWithFormat:@"Invalid %@", _name] reason:[NSString stringWithFormat:@"Invalid %@ '%@'", _name, value] userInfo:nil]);
return;
}
[self setPop:![value boolValue]];
}
}
+ (id)deleteSnapshotOperation {
return [[DeleteSnapshotOperation alloc] init];
}
+ (id)deleteSnapshotOperationFromString:(NSString *)deleteSnapshotOperation {
// delete-snapshot name options
NSMutableArray *tokens = [[NSMutableArray alloc] initWithCapacity:10];
[StringTokenizer tokenize:deleteSnapshotOperation into:tokens maxTokens:3];
if ([tokens count] < 2) {
SlateLogger(@"ERROR: Invalid Parameters '%@'", deleteSnapshotOperation);
@throw([NSException exceptionWithName:@"Invalid Parameters" reason:[NSString stringWithFormat:@"Invalid Parameters in '%@'. Delete Snapshot operations require the following format: 'delete-snapshot name options'", deleteSnapshotOperation] userInfo:nil]);
}
Operation *op = [[DeleteSnapshotOperation alloc] initWithName:[tokens objectAtIndex:1] options:([tokens count] > 2 ? [tokens objectAtIndex:2] : nil)];
return op;
}
@end
================================================
FILE: Slate/ExpressionPoint.h
================================================
//
// ExpressionPoint.h
// Slate
//
// Created by Jigish Patel on 5/18/11.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import <Foundation/Foundation.h>
@interface ExpressionPoint : NSObject {
@private
NSString *x;
NSString *y;
}
@property (copy) NSString *x;
@property (copy) NSString *y;
- (id)initWithX:(NSString *)xVal y:(NSString *)yVal;
- (NSPoint)getPointWithDict:(NSDictionary *)values;
- (NSSize)getSizeWithDict:(NSDictionary *)values;
+ (float)expToFloat:(NSString *)exp withDict:(NSDictionary *)values;
@end
================================================
FILE: Slate/ExpressionPoint.m
================================================
//
// ExpressionPoint.m
// Slate
//
// Created by Jigish Patel on 5/18/11.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import "ExpressionPoint.h"
@implementation ExpressionPoint
@synthesize x;
@synthesize y;
- (id)init {
self = [super init];
if (self) {
[self setX:@"0"];
[self setY:@"0"];
}
return self;
}
- (id)initWithX:(NSString *)xVal y:(NSString *)yVal {
self = [super init];
if (self) {
[self setX:xVal];
[self setY:yVal];
}
return self;
}
- (NSPoint)getPointWithDict:(NSDictionary *)values {
return NSMakePoint([ExpressionPoint expToFloat:x withDict:values],[ExpressionPoint expToFloat:y withDict:values]);
}
- (NSSize)getSizeWithDict:(NSDictionary *)values {
return NSMakeSize([ExpressionPoint expToFloat:x withDict:values],[ExpressionPoint expToFloat:y withDict:values]);
}
+ (float)expToFloat:(NSString *)exp withDict:(NSDictionary *)values {
if (exp != nil) {
// then do the normal predicate stuff
NSComparisonPredicate *pred = (NSComparisonPredicate *)[NSPredicate predicateWithFormat:[exp stringByAppendingString:@" == 42"]];
NSExpression *lexp = [pred leftExpression];
NSNumber *result = [lexp expressionValueWithObject:values context:nil];
if (result == nil)
@throw([NSException exceptionWithName:@"Unable to compute result" reason:exp userInfo:nil]);
return [result floatValue];
}
@throw([NSException exceptionWithName:@"Expression is nil" reason:exp userInfo:nil]);
}
@end
================================================
FILE: Slate/FocusOperation.h
================================================
//
// FocusOperation.h
// Slate
//
// Created by Jigish Patel on 6/21/11.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import <Foundation/Foundation.h>
#import "Operation.h"
@interface FocusOperation : Operation {
@private
NSInteger direction;
NSString *app;
}
@property (assign) NSInteger direction;
@property NSString *app;
- (id)initWithDirectionOrApp:(NSString *)s;
+ (id)focusOperation;
+ (id)focusOperationFromString:(NSString *)focusOperation;
@end
================================================
FILE: Slate/FocusOperation.m
================================================
//
// FocusOperation.m
// Slate
//
// Created by Jigish Patel on 6/21/11.
// Copyright 2011 Jigish Patel. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import "Constants.h"
#import "FocusOperation.h"
#import "MathUtils.h"
#import "SlateConfig.h"
#import "StringTokenizer.h"
#import "SlateLogger.h"
#import "RunningApplications.h"
@implementation FocusOperation
@synthesize direction, app;
- (id)init {
self = [super init];
if (self) {
[self setDirection:DIRECTION_UNKNOWN];
[self setApp:nil];
}
return self;
}
- (id)initWithDirectionOrApp:(NSString *)s {
self = [super init];
if (self) {
[self setDirection:DIRECTION_UNKNOWN];
[self setApp:nil];
if ([s length] <= 1) {
// fail
} else if ([s isEqualToString:UP] || [s isEqualToString:ABOVE]) {
[self setDirection:DIRECTION_UP];
} else if ([s isEqualToString:DOWN] || [s isEqualToString:BELOW]) {
[self setDirection:DIRECTION_DOWN];
} else if ([s isEqualToString:LEFT]) {
[self setDirection:DIRECTION_LEFT];
} else if ([s isEqualToString:RIGHT]) {
[self setDirection:DIRECTION_RIGHT];
} else if ([s isEqualToString:BEHIND]) {
[self setDirection:DIRECTION_BEHIND];
} else if ([[NSCharacterSet characterSetWithCharactersInString:QUOTES] characterIsMember:[s characterAtIndex:0]] &&
[[NSCharacterSet characterSetWithCharactersInString:QUOTES] characterIsMember:[s characterAtIndex:([s length] - 1)]]) {
// App name
[self setApp:[s substringWithRange:NSMakeRange(1, [s length]-2)]];
}
}
return self;
}
- (BOOL)doOperation {
SlateLogger(@"----------------- Begin Focus Operation -----------------");
// We don't use the passed in AccessibilityWrapper or ScreenWrapper so they are nil. No need to waste time creating them here.
BOOL success = [self doOperationWithAccessibilityWrapper:nil screenWrapper:nil];
SlateLogger(@"----------------- End Focus Operation -----------------");
return success;
}
- (BOOL)doOperationWithAccessibilityWrapper:(AccessibilityWrapper *)iamnil screenWrapper:(ScreenWrapper *)iamalsonil {
[self evalOptionsWithAccessibilityWrapper:iamnil screenWrapper:iamalsonil];
// App case
if ([self app] != nil) {
for (NSRunningApplication *runningApp in [RunningApplications getInstance]) {
if ([[self app] isEqualToString:[runningApp localizedName]]) {
// Match!
if ([AccessibilityWrapper focusMainWindow:runningApp]) {
return YES;
}
return NO;
}
}
return NO;
}
// Direction case
AccessibilityWrapper *caAW = [[AccessibilityWrapper alloc] init];
if (![caAW inited]) return NO;
NSPoint cwTL = [caAW getCurrentTopLeft];
NSSize cwSize = [caAW getCurrentSize];
NSRect cwRect = NSMakeRect(cwTL.x, cwTL.y, cwSize.width, cwSize.height);
NSString *cwTitle = [AccessibilityWrapper getTitle:[caAW window]];
NSRect checkRect;
NSInteger focusCheckWidth = [[SlateConfig getInstance] getIntegerConfig:FOCUS_CHECK_WIDTH];
while (focusCheckWidth <= [[SlateConfig getInstance] getIntegerConfig:FOCUS_CHECK_WIDTH_MAX]) {
SlateLogger(@"Checking for adjacent windows with width=%i",(int)focusCheckWidth);
if (direction == DIRECTION_UP) checkRect = NSMakeRect(cwTL.x, cwTL.y-focusCheckWidth, cwSize.width, focusCheckWidth);
else if (direction == DIRECTION_DOWN) checkRect = NSMakeRect(cwTL.x, cwTL.y+cwSize.height, cwSize.width, focusCheckWidth);
else if (direction == DIRECTION_LEFT) checkRect = NSMakeRect(cwTL.x-focusCheckWidth, cwTL.y, focusCheckWidth, cwSize.height);
else if (direction == DIRECTION_RIGHT) checkRect = NSMakeRect(cwTL.x+cwSize.width, cwTL.y, focusCheckWidth, cwSize.height);
else if (direction == DIRECTION_BEHIND) checkRect = NSMakeRect(cwTL.x, cwTL.y, cwSize.width, cwSize.height);
else {
return NO;
}
NSRect biggestIntersection = NSZeroRect;
AXUIElementRef windowToFocus;
AXUIElementRef appToFocus;
BOOL foundFocus = NO;
BOOL foundFocusInSameApp = NO;
for (NSRunningApplication *runningApp in [RunningApplications getInstance]) {
pid_t appPID = [runningApp processIdentifier];
SlateLogger(@"I see application '%@' with pid '%d'", [runningApp localizedName], appPID);
AXUIElementRef appRef = AXUIElementCreateApplication(appPID);
CFArrayRef windows = [AccessibilityWrapper windowsInApp:appRef];
if (!windows || CFArrayGetCount(windows) == 0) continue;
for (NSInteger i = 0; i < CFArrayGetCount(windows); i++) {
AccessibilityWrapper *aw = [[AccessibilityWrapper alloc] initWithApp:appRef window:CFArrayGetValueAtIndex(windows, i)];
if ([aw isMinimizedOrHidden]) {
SlateLogger(@" Window is minimized, skipping");
continue;
}
NSString *wTitle = [aw getTitle];
if ([wTitle isEqualToString:@""]){
SlateLogger(@" Title is empty, skipping");
continue; // Chrome and Finder have invisible windows for some reason
}
NSPoint wTL = [aw getCurrentTopLeft];
NSSize wSize = [aw getCurrentSize];
SlateLogger(@" Checking window in %@ in direction %i with rect: (%f,%f %f,%f), title: [%@]",[runningApp localizedName],(int)direction,wTL.x,wTL.y,wSize.width,wSize.height,wTitle);
NSRect windowRect = NSMakeRect(wTL.x, wTL.y, wSize.width, wSize.height);
if ([wTitle isEqualToString:cwTitle] && NSEqualRects(windowRect, cwRect) && NSEqualPoints(wTL, cwTL)) {
SlateLogger(@" Ignoring current window");
continue;
}
NSRect intersection = NSIntersectionRect(checkRect, windowRect);
if ([MathUtils isRect:intersection biggerThan:NSZeroRect] && [AccessibilityWrapper processIdentifierOfUIElement:[caAW app]] == appPID) {
SlateLogger(@" Found window in same app in direction %i",(int)direction);
if ([[SlateConfig getInstance] getBoolConfig:FOCUS_PREFER_SAME_APP]
&& (!foundFocusInSameApp || [MathUtils isRect:intersection biggerThan:biggestIntersection])) {
SlateLogger(@" Preferring same app.");
appToFocus = appRef;
windowToFocus = CFArrayGetValueAtIndex(windows, i);
biggestIntersection = intersection;
foundFocus = YES;
foundFocusInSameApp = YES;
} else if ([MathUtils isRect:intersection biggerThan:biggestIntersection]) {
appToFocus = appRef;
windowToFocus = CFArrayGetValueAtIndex(windows, i);
biggestIntersection = intersection;
foundFocus = YES;
}
} else if ([MathUtils isRect:intersection biggerThan:biggestIntersection]) {
SlateLogger(@" Found window in %@ in direction %i (intersection: %f,%f %f,%f)",[runningApp localizedName],(int)direction,intersection.origin.x,intersection.origin.y,intersection.size.width,intersection.size.height);
appToFocus = appRef;
windowToFocus = CFArrayGetValueAtIndex(windows, i);
biggestIntersection = intersection;
foundFocus = YES;
}
}
// check if same app && foundFocus && prefer_same_app
if(foundFocusInSameApp && [AccessibilityWrapper processIdentifierOfUIElement:[caAW app]] == appPID && [[SlateConfig getInstance] getBoolConfig:FOCUS_PREFER_SAME_APP]) {
AccessibilityWrapper *aw = [[AccessibilityWrapper alloc] initWithApp:appToFocus window:windowToFocus];
[aw focus];
return YES;
}
}
if (foundFocus) {
AccessibilityWrapper *aw = [[AccessibilityWrapper alloc] initWithApp:appToFocus window:windowToFocus];
[aw focus];
return YES;
}
focusCheckWidth += [[SlateConfig getInstance] getIntegerConfig:FOCUS_CHECK_WIDTH];
}
return NO;
}
- (BOOL)testOperation {
if ([self direction] == DIRECTION_UNKNOWN && [self app] == nil)
@throw [NSException exceptionWithName:@"Unknown Direction" reason:@"direction" userInfo:nil];
return YES;
}
- (NSString *)checkRequiredOptions:(NSDictionary *)_options {
if ([_options objectForKey:OPT_APP] == nil && [_options objectForKey:OPT_DIRECTION] == nil) {
return [[NSArray arrayWithObjects:OPT_APP, OPT_DIRECTION, nil] componentsJoinedByString:@" or "];
}
return nil;
}
- (void)parseOption:(NSString *)name value:(id)value {
if (value == nil) { return; }
if ([name isEqualToString:OPT_APP]) {
// should be string
if (![value isKindOfClass:[NSString class]]) {
@throw([NSException exceptionWithName:@"Invalid App" reason:[NSString stringWithFormat:@"Invalid App %@", value] userInfo:nil]);
return;
}
[self setApp:value];
} else if ([name isEqualToString:OPT_DIRECTION]) {
// should be a string
if (![value isKindOfClass:[NSString class]]) {
@throw([NSException exceptionWithName:@"Invalid Direction" reason:[NSString stringWithFormat:@"Invalid Direction %@", value] userInfo:nil]);
return;
}
if ([value isEqualToString:UP] || [value isEqualToString:ABOVE]) {
[self setDirection:DIRECTION_UP];
} else if ([value isEqualToString:DOWN] || [value isEqualToString:BELOW]) {
[self setDirection:DIRECTION_DOWN];
} else if ([value isEqualToString:LEFT]) {
[self setDirection:DIRECTION_LEFT];
} else if ([value isEqualToString:RIGHT]) {
[self setDirection:DIRECTION_RIGHT];
} else if ([value isEqualToString:BEHIND]) {
[self setDirection:DIRECTION_BEHIND];
} else {
@throw([NSException exceptionWithName:@"Invalid Direction" reason:[NSString stringWithFormat:@"Invalid Direction %@", value] userInfo:nil]);
return;
}
}
}
+ (id)focusOperation {
return [[FocusOperation alloc] init];
}
+ (id)focusOperationFromString:(NSString *)focusOperation {
// focus direction
NSMutableArray *tokens = [[NSMutableArray alloc] initWithCapacity:10];
[StringTokenizer tokenize:focusOperation into:tokens maxTokens:2];
if ([tokens count] < 2) {
SlateLogger(@"ERROR: Invalid Parameters '%@'", focusOperation);
@throw([NSException exceptionWithName:@"Invalid Parameters" reason:[NSString stringWithFormat:@"Invalid Parameters in '%@'. Focus operations require the following format: 'focus direction'", focusOperation] userInfo:nil]);
}
Operation *op = [[FocusOperation alloc] initWithDirectionOrApp:[tokens objectAtIndex:1]];
return op;
}
@end
================================================
FILE: Slate/GridCellView.h
================================================
//
// GridCellView.h
// Slate
//
// Created by Jigish Patel on 9/10/12.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import <Cocoa/Cocoa.h>
@interface GridCellView : NSView
@property NSColor *inactiveBg;
@property NSColor *activeBg;
@property NSColor *bg;
@property float cornerSize;
- (void)activate;
- (void)deactivate;
@end
================================================
FILE: Slate/GridCellView.m
================================================
//
// GridCellView.m
// Slate
//
// Created by Jigish Patel on 9/10/12.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses
#import "GridCellView.h"
#import "SlateConfig.h"
#import "Constants.h"
@implementation GridCellView
@synthesize bg, inactiveBg, activeBg, cornerSize;
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setWantsLayer:YES];
NSArray *bgColorArr = [[SlateConfig getInstance] getArrayConfig:GRID_CELL_BACKGROUND_COLOR];
if ([bgColorArr count] < 4) bgColorArr = [GRID_CELL_BACKGROUND_COLOR_DEFAULT componentsSeparatedByString:SEMICOLON];
NSColor *backgroundColor = [NSColor colorWithDeviceRed:[[bgColorArr objectAtIndex:0] floatValue]/255.0
green:[[bgColorArr objectAtIndex:1] floatValue]/255.0
blue:[[bgColorArr objectAtIndex:2] floatValue]/255.0
alpha:[[bgColorArr objectAtIndex:3] floatValue]];
[self setBg:backgroundColor];
[self setInactiveBg:backgroundColor];
NSArray *activeColorArr = [[SlateConfig getInstance] getArrayConfig:GRID_CELL_SELECTED_COLOR];
if ([activeColorArr count] < 4) activeColorArr = [GRID_CELL_SELECTED_COLOR_DEFAULT componentsSeparatedByString:SEMICOLON];
NSColor *activeColor = [NSColor colorWithDeviceRed:[[activeColorArr objectAtIndex:0] floatValue]/255.0
green:[[activeColorArr objectAtIndex:1] floatValue]/255.0
blue:[[activeColorArr objectAtIndex:2] floatValue]/255.0
alpha:[[activeColorArr objectAtIndex:3] floatValue]];
[self setActiveBg:activeColor];
[self setCornerSize:[[SlateConfig getInstance] getFloatConfig:GR
gitextract_axgbmzp9/
├── .gitignore
├── .gitmodules
├── .rbenv-version
├── LICENSE
├── README.md
├── Slate/
│ ├── ASCIIToCode.plist
│ ├── ASCIIToCode_Azerty.plist
│ ├── ASCIIToCode_Colemak.plist
│ ├── ASCIIToCode_Dvorak.plist
│ ├── AccessibilityWrapper.h
│ ├── AccessibilityWrapper.m
│ ├── ActivateSnapshotOperation.h
│ ├── ActivateSnapshotOperation.m
│ ├── ApplicationOptions.h
│ ├── ApplicationOptions.m
│ ├── Binding.h
│ ├── Binding.m
│ ├── ChainOperation.h
│ ├── ChainOperation.m
│ ├── ConfigurationHelperView.h
│ ├── ConfigurationHelperView.m
│ ├── Constants.h
│ ├── Constants.m
│ ├── CornerOperation.h
│ ├── CornerOperation.m
│ ├── DeleteSnapshotOperation.h
│ ├── DeleteSnapshotOperation.m
│ ├── ExpressionPoint.h
│ ├── ExpressionPoint.m
│ ├── FocusOperation.h
│ ├── FocusOperation.m
│ ├── GridCellView.h
│ ├── GridCellView.m
│ ├── GridOperation.h
│ ├── GridOperation.m
│ ├── GridView.h
│ ├── GridView.m
│ ├── GridWindow.h
│ ├── GridWindow.m
│ ├── HintOperation.h
│ ├── HintOperation.m
│ ├── HintView.h
│ ├── HintView.m
│ ├── HintWindow.h
│ ├── HintWindow.m
│ ├── JSApplicationWrapper.h
│ ├── JSApplicationWrapper.m
│ ├── JSController.h
│ ├── JSController.m
│ ├── JSInfoWrapper.h
│ ├── JSInfoWrapper.m
│ ├── JSONKit/
│ │ ├── JSONKit.h
│ │ └── JSONKit.m
│ ├── JSOperation.h
│ ├── JSOperation.m
│ ├── JSOperationWrapper.h
│ ├── JSOperationWrapper.m
│ ├── JSScreenWrapper.h
│ ├── JSScreenWrapper.m
│ ├── JSWindowWrapper.h
│ ├── JSWindowWrapper.m
│ ├── JSWrapperUtils.h
│ ├── JSWrapperUtils.m
│ ├── Layout.h
│ ├── Layout.m
│ ├── LayoutOperation.h
│ ├── LayoutOperation.m
│ ├── MathUtils.h
│ ├── MathUtils.m
│ ├── MoveOperation.h
│ ├── MoveOperation.m
│ ├── NSFileManager+ApplicationSupport.h
│ ├── NSFileManager+ApplicationSupport.m
│ ├── NSString+Indicies.h
│ ├── NSString+Indicies.m
│ ├── NSString+Levenshtein.h
│ ├── NSString+Levenshtein.m
│ ├── NudgeOperation.h
│ ├── NudgeOperation.m
│ ├── Operation.h
│ ├── Operation.m
│ ├── PushOperation.h
│ ├── PushOperation.m
│ ├── RelaunchOperation.h
│ ├── RelaunchOperation.m
│ ├── ResizeOperation.h
│ ├── ResizeOperation.m
│ ├── RunningApplications.h
│ ├── RunningApplications.m
│ ├── ScreenState.h
│ ├── ScreenState.m
│ ├── ScreenWrapper.h
│ ├── ScreenWrapper.m
│ ├── SequenceOperation.h
│ ├── SequenceOperation.m
│ ├── ShellOperation.h
│ ├── ShellOperation.m
│ ├── ShellUtils.h
│ ├── ShellUtils.m
│ ├── Slate-Info.plist
│ ├── Slate-Prefix.pch
│ ├── SlateAppDelegate.h
│ ├── SlateAppDelegate.m
│ ├── SlateConfig.h
│ ├── SlateConfig.m
│ ├── SlateLogger.h
│ ├── Snapshot.h
│ ├── Snapshot.m
│ ├── SnapshotList.h
│ ├── SnapshotList.m
│ ├── SnapshotOperation.h
│ ├── SnapshotOperation.m
│ ├── StringTokenizer.h
│ ├── StringTokenizer.m
│ ├── SwitchAppQuittingOverlayView.h
│ ├── SwitchAppQuittingOverlayView.m
│ ├── SwitchAppView.h
│ ├── SwitchAppView.m
│ ├── SwitchOperation.h
│ ├── SwitchOperation.m
│ ├── SwitchView.h
│ ├── SwitchView.m
│ ├── SwitchWindow.h
│ ├── SwitchWindow.m
│ ├── ThrowOperation.h
│ ├── ThrowOperation.m
│ ├── UndoOperation.h
│ ├── UndoOperation.m
│ ├── VisibilityOperation.h
│ ├── VisibilityOperation.m
│ ├── WindowInfoView.h
│ ├── WindowInfoView.m
│ ├── WindowSnapshot.h
│ ├── WindowSnapshot.m
│ ├── WindowState.h
│ ├── WindowState.m
│ ├── default.slate
│ ├── en.lproj/
│ │ ├── Credits.rtf
│ │ ├── InfoPlist.strings
│ │ └── MainMenu.xib
│ ├── icon.icns
│ ├── initialize.js
│ ├── main.m
│ ├── slate-mock.js
│ ├── slate-test.html
│ ├── underscore.js
│ └── utils.js
├── Slate.xcodeproj/
│ ├── project.pbxproj
│ └── project.xcworkspace/
│ └── contents.xcworkspacedata
├── SlateTests/
│ ├── SlateTests-Info.plist
│ ├── SlateTests-Prefix.pch
│ ├── SlateTests.h
│ ├── SlateTests.m
│ ├── TestExpressionPoint.h
│ ├── TestExpressionPoint.m
│ ├── TestMathUtils.h
│ ├── TestMathUtils.m
│ ├── TestNSString+Indicies.h
│ ├── TestNSString+Indicies.m
│ ├── TestNSString+Levenshtein.h
│ ├── TestNSString+Levenshtein.m
│ ├── TestShellUtils.h
│ ├── TestShellUtils.m
│ ├── TestStringTokenizer.h
│ ├── TestStringTokenizer.m
│ └── en.lproj/
│ └── InfoPlist.strings
├── Sparkle.framework/
│ └── Versions/
│ └── A/
│ ├── Headers/
│ │ ├── SUAppcast.h
│ │ ├── SUAppcastItem.h
│ │ ├── SUUpdater.h
│ │ ├── SUVersionComparisonProtocol.h
│ │ └── Sparkle.h
│ ├── Resources/
│ │ ├── Info.plist
│ │ ├── License.txt
│ │ ├── SUModelTranslation.plist
│ │ ├── SUStatus.nib/
│ │ │ ├── classes.nib
│ │ │ ├── info.nib
│ │ │ └── keyedobjects.nib
│ │ ├── de.lproj/
│ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ └── Sparkle.strings
│ │ ├── en.lproj/
│ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ └── Sparkle.strings
│ │ ├── es.lproj/
│ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ └── Sparkle.strings
│ │ ├── fr.lproj/
│ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ └── Sparkle.strings
│ │ ├── it.lproj/
│ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ └── Sparkle.strings
│ │ ├── nl.lproj/
│ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ └── Sparkle.strings
│ │ ├── relaunch
│ │ ├── ru.lproj/
│ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ ├── classes.nib
│ │ │ │ ├── info.nib
│ │ │ │ └── keyedobjects.nib
│ │ │ └── Sparkle.strings
│ │ └── sv.lproj/
│ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ ├── classes.nib
│ │ │ ├── info.nib
│ │ │ └── keyedobjects.nib
│ │ ├── SUUpdateAlert.nib/
│ │ │ ├── classes.nib
│ │ │ ├── info.nib
│ │ │ └── keyedobjects.nib
│ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ ├── classes.nib
│ │ │ ├── info.nib
│ │ │ └── keyedobjects.nib
│ │ └── Sparkle.strings
│ └── Sparkle
├── VERSION
├── build/
│ ├── Debug/
│ │ └── Slate.app/
│ │ └── Contents/
│ │ ├── Frameworks/
│ │ │ └── Sparkle.framework/
│ │ │ └── Versions/
│ │ │ └── A/
│ │ │ ├── Headers/
│ │ │ │ ├── SUAppcast.h
│ │ │ │ ├── SUAppcastItem.h
│ │ │ │ ├── SUUpdater.h
│ │ │ │ ├── SUVersionComparisonProtocol.h
│ │ │ │ └── Sparkle.h
│ │ │ ├── Resources/
│ │ │ │ ├── Info.plist
│ │ │ │ ├── License.txt
│ │ │ │ ├── SUModelTranslation.plist
│ │ │ │ ├── SUStatus.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ ├── de.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── en.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── es.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── fr.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── it.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── nl.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── relaunch
│ │ │ │ ├── ru.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ └── sv.lproj/
│ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ └── Sparkle.strings
│ │ │ └── Sparkle
│ │ ├── Info.plist
│ │ ├── MacOS/
│ │ │ └── Slate
│ │ ├── PkgInfo
│ │ └── Resources/
│ │ ├── ASCIIToCode.plist
│ │ ├── ASCIIToCode_Azerty.plist
│ │ ├── ASCIIToCode_Colemak.plist
│ │ ├── ASCIIToCode_Dvorak.plist
│ │ ├── default.slate
│ │ ├── en.lproj/
│ │ │ ├── Credits.rtf
│ │ │ ├── InfoPlist.strings
│ │ │ └── MainMenu.nib
│ │ ├── icon.icns
│ │ ├── initialize.js
│ │ ├── underscore.js
│ │ └── utils.js
│ └── Release/
│ ├── Slate.app/
│ │ └── Contents/
│ │ ├── Frameworks/
│ │ │ └── Sparkle.framework/
│ │ │ └── Versions/
│ │ │ └── A/
│ │ │ ├── Headers/
│ │ │ │ ├── SUAppcast.h
│ │ │ │ ├── SUAppcastItem.h
│ │ │ │ ├── SUUpdater.h
│ │ │ │ ├── SUVersionComparisonProtocol.h
│ │ │ │ └── Sparkle.h
│ │ │ ├── Resources/
│ │ │ │ ├── Info.plist
│ │ │ │ ├── License.txt
│ │ │ │ ├── SUModelTranslation.plist
│ │ │ │ ├── SUStatus.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ ├── de.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── en.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── es.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── fr.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── it.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── nl.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ ├── relaunch
│ │ │ │ ├── ru.lproj/
│ │ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ │ ├── classes.nib
│ │ │ │ │ │ ├── info.nib
│ │ │ │ │ │ └── keyedobjects.nib
│ │ │ │ │ └── Sparkle.strings
│ │ │ │ └── sv.lproj/
│ │ │ │ ├── SUAutomaticUpdateAlert.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ ├── SUUpdateAlert.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ ├── SUUpdatePermissionPrompt.nib/
│ │ │ │ │ ├── classes.nib
│ │ │ │ │ ├── info.nib
│ │ │ │ │ └── keyedobjects.nib
│ │ │ │ └── Sparkle.strings
│ │ │ └── Sparkle
│ │ ├── Info.plist
│ │ ├── MacOS/
│ │ │ └── Slate
│ │ ├── PkgInfo
│ │ └── Resources/
│ │ ├── ASCIIToCode.plist
│ │ ├── ASCIIToCode_Azerty.plist
│ │ ├── ASCIIToCode_Colemak.plist
│ │ ├── ASCIIToCode_Dvorak.plist
│ │ ├── default.slate
│ │ ├── en.lproj/
│ │ │ ├── Credits.rtf
│ │ │ ├── InfoPlist.strings
│ │ │ └── MainMenu.nib
│ │ ├── icon.icns
│ │ ├── initialize.js
│ │ ├── underscore.js
│ │ └── utils.js
│ └── Slate.dmg
├── icons/
│ ├── Contact.txt
│ └── PSD/
│ ├── icon_1024.psd
│ ├── status-bar icon 1.psd
│ ├── status-bar icon 2.psd
│ └── status-bar icon 3.psd
└── script/
└── slate.rb
SYMBOL INDEX (70 symbols across 55 files)
FILE: Slate/AccessibilityWrapper.h
function interface (line 24) | interface AccessibilityWrapper : NSObject {
FILE: Slate/ActivateSnapshotOperation.h
function interface (line 23) | interface ActivateSnapshotOperation : Operation {
FILE: Slate/ApplicationOptions.h
function interface (line 24) | interface ApplicationOptions : NSObject {
FILE: Slate/Binding.h
function interface (line 26) | interface Binding : NSObject {
FILE: Slate/ChainOperation.h
function interface (line 24) | interface ChainOperation : Operation {
FILE: Slate/ConfigurationHelperView.h
function interface (line 23) | interface ConfigurationHelperView : NSView {
FILE: Slate/DeleteSnapshotOperation.h
function interface (line 23) | interface DeleteSnapshotOperation : Operation {
FILE: Slate/ExpressionPoint.h
function interface (line 24) | interface ExpressionPoint : NSObject {
FILE: Slate/FocusOperation.h
function interface (line 25) | interface FocusOperation : Operation {
FILE: Slate/GridOperation.h
function interface (line 25) | interface GridOperation : Operation {
FILE: Slate/HintOperation.h
function interface (line 25) | interface HintOperation : Operation {
FILE: Slate/HintView.h
function interface (line 23) | interface HintView : NSView {
FILE: Slate/JSApplicationWrapper.h
function interface (line 26) | interface JSApplicationWrapper : NSObject {
FILE: Slate/JSController.h
function interface (line 24) | interface JSController : NSObject {
FILE: Slate/JSInfoWrapper.h
function interface (line 25) | interface JSInfoWrapper : NSObject {
FILE: Slate/JSONKit/JSONKit.h
type NSInteger (line 80) | typedef long NSInteger;
type NSUInteger (line 81) | typedef unsigned long NSUInteger;
type NSInteger (line 86) | typedef int NSInteger;
type NSUInteger (line 87) | typedef unsigned int NSUInteger;
type NSUInteger (line 107) | typedef NSUInteger JKFlags;
type JKFlags (line 126) | typedef JKFlags JKParseOptionFlags;
type JKFlags (line 135) | typedef JKFlags JKSerializeOptionFlags;
type JKParseState (line 139) | typedef struct JKParseState JKParseState;
function interface (line 143) | interface JSONDecoder : NSObject {
FILE: Slate/JSOperation.h
function interface (line 25) | interface JSOperation : Operation {
FILE: Slate/JSOperationWrapper.h
function interface (line 28) | interface JSOperationWrapper : NSObject {
FILE: Slate/JSScreenWrapper.h
function interface (line 26) | interface JSScreenWrapper : NSObject {
FILE: Slate/JSWindowWrapper.h
function interface (line 26) | interface JSWindowWrapper : NSObject {
FILE: Slate/Layout.h
function interface (line 24) | interface Layout : NSObject {
FILE: Slate/LayoutOperation.h
function interface (line 25) | interface LayoutOperation : Operation {
FILE: Slate/MathUtils.h
function interface (line 24) | interface MathUtils : NSObject {}
FILE: Slate/MoveOperation.h
function interface (line 26) | interface MoveOperation : Operation {
FILE: Slate/Operation.h
function interface (line 26) | interface Operation : NSObject {
FILE: Slate/ResizeOperation.h
function interface (line 25) | interface ResizeOperation : Operation {
FILE: Slate/RunningApplications.h
function interface (line 23) | interface RunningApplications : NSObject <NSFastEnumeration> {
FILE: Slate/ScreenState.h
function interface (line 24) | interface ScreenState : NSObject {
FILE: Slate/ScreenWrapper.h
function interface (line 24) | interface ScreenWrapper : NSObject {
FILE: Slate/SequenceOperation.h
function interface (line 23) | interface SequenceOperation : Operation {
FILE: Slate/ShellOperation.h
function interface (line 23) | interface ShellOperation : Operation {
FILE: Slate/SlateAppDelegate.h
function interface (line 32) | interface SlateAppDelegate : NSObject <NSApplicationDelegate> {
FILE: Slate/SlateConfig.h
function interface (line 26) | interface SlateConfig : NSObject {
FILE: Slate/Snapshot.h
function interface (line 25) | interface Snapshot : NSObject {
FILE: Slate/SnapshotList.h
function interface (line 25) | interface SnapshotList : NSObject {
FILE: Slate/SnapshotOperation.h
function interface (line 23) | interface SnapshotOperation : Operation {
FILE: Slate/StringTokenizer.h
function interface (line 24) | interface StringTokenizer : NSObject {}
FILE: Slate/SwitchAppQuittingOverlayView.h
function interface (line 23) | interface SwitchAppQuittingOverlayView : NSView {
FILE: Slate/SwitchAppView.h
function interface (line 25) | interface SwitchAppView : NSView {
FILE: Slate/SwitchOperation.h
function interface (line 24) | interface SwitchOperation : Operation {
FILE: Slate/VisibilityOperation.h
type VisibilityOperationType (line 23) | typedef enum {
function interface (line 30) | interface VisibilityOperation : Operation {
FILE: Slate/WindowInfoView.h
function interface (line 23) | interface WindowInfoView : NSTextView {
FILE: Slate/WindowSnapshot.h
function interface (line 23) | interface WindowSnapshot : NSObject {
FILE: Slate/WindowState.h
function interface (line 24) | interface WindowState : NSObject <NSCopying> {
FILE: SlateTests/SlateTests.h
function interface (line 24) | interface SlateTests : SenTestCase {
FILE: Sparkle.framework/Versions/A/Headers/SUAppcast.h
function interface (line 13) | interface SUAppcast : NSObject {
FILE: Sparkle.framework/Versions/A/Headers/SUAppcastItem.h
function interface (line 12) | interface SUAppcastItem : NSObject {
FILE: Sparkle.framework/Versions/A/Headers/SUUpdater.h
function interface (line 15) | interface SUUpdater : NSObject {
FILE: build/Debug/Slate.app/Contents/Frameworks/Sparkle.framework/Versions/A/Headers/SUAppcast.h
function interface (line 13) | interface SUAppcast : NSObject {
FILE: build/Debug/Slate.app/Contents/Frameworks/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h
function interface (line 12) | interface SUAppcastItem : NSObject {
FILE: build/Debug/Slate.app/Contents/Frameworks/Sparkle.framework/Versions/A/Headers/SUUpdater.h
function interface (line 15) | interface SUUpdater : NSObject {
FILE: build/Release/Slate.app/Contents/Frameworks/Sparkle.framework/Versions/A/Headers/SUAppcast.h
function interface (line 13) | interface SUAppcast : NSObject {
FILE: build/Release/Slate.app/Contents/Frameworks/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h
function interface (line 12) | interface SUAppcastItem : NSObject {
FILE: build/Release/Slate.app/Contents/Frameworks/Sparkle.framework/Versions/A/Headers/SUUpdater.h
function interface (line 15) | interface SUUpdater : NSObject {
FILE: script/slate.rb
function log (line 41) | def log(msg)
function clean (line 45) | def clean
function usage (line 53) | def usage
function upload_file (line 63) | def upload_file(from_dir, to_dir, filename, size_threshold, binary = false)
function dmgify (line 86) | def dmgify
function gen (line 111) | def gen
function pub (line 137) | def pub
Condensed preview — 483 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,548K chars).
[
{
"path": ".gitignore",
"chars": 405,
"preview": "build/Slate.build\nbuild/Release/Slate.app.dSYM\nbuild/debug_paths.json\nbuild/release_paths.json\nbuild/output\nbuild/Releas"
},
{
"path": ".gitmodules",
"chars": 118,
"preview": "[submodule \"script/create-dmg\"]\n\tpath = script/create-dmg\n\turl = https://github.com/andreyvit/yoursway-create-dmg.git\n"
},
{
"path": ".rbenv-version",
"chars": 11,
"preview": "1.9.3-p286\n"
},
{
"path": "LICENSE",
"chars": 35147,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "README.md",
"chars": 32933,
"preview": "# About Slate #\n\nSlate is a window management application similar to Divvy and SizeUp (except better and free!). Origina"
},
{
"path": "Slate/ASCIIToCode.plist",
"chars": 4097,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Slate/ASCIIToCode_Azerty.plist",
"chars": 4097,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Slate/ASCIIToCode_Colemak.plist",
"chars": 4097,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Slate/ASCIIToCode_Dvorak.plist",
"chars": 4097,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Slate/AccessibilityWrapper.h",
"chars": 2322,
"preview": "//\n// AccessibilityWrapper.h\n// Slate\n//\n// Created by Jigish Patel on 6/10/11.\n// Copyright 2011 Jigish Patel. All "
},
{
"path": "Slate/AccessibilityWrapper.m",
"chars": 11392,
"preview": "//\n// AccessibilityWrapper.m\n// Slate\n//\n// Created by Jigish Patel on 6/10/11.\n// Copyright 2011 Jigish Patel. All "
},
{
"path": "Slate/ActivateSnapshotOperation.h",
"chars": 1220,
"preview": "//\n// ActivateSnapshotOperation.h\n// Slate\n//\n// Created by Jigish Patel on 3/1/12.\n// Copyright 2012 Jigish Patel. "
},
{
"path": "Slate/ActivateSnapshotOperation.m",
"chars": 6379,
"preview": "//\n// ActivateSnapshotOperation.m\n// Slate\n//\n// Created by Jigish Patel on 3/1/12.\n// Copyright 2012 Jigish Patel. "
},
{
"path": "Slate/ApplicationOptions.h",
"chars": 1320,
"preview": "//\n// ApplicationOptions.h\n// Slate\n//\n// Created by Jigish Patel on 6/14/11.\n// Copyright 2011 Jigish Patel. All ri"
},
{
"path": "Slate/ApplicationOptions.m",
"chars": 1358,
"preview": "//\n// ApplicationOptions.m\n// Slate\n//\n// Created by Jigish Patel on 6/14/11.\n// Copyright 2011 Jigish Patel. All ri"
},
{
"path": "Slate/Binding.h",
"chars": 1630,
"preview": "//\n// Binding.h\n// Slate\n//\n// Created by Jigish Patel on 5/18/11.\n// Copyright 2011 Jigish Patel. All rights reserv"
},
{
"path": "Slate/Binding.m",
"chars": 9013,
"preview": "//\n// Binding.m\n// Slate\n//\n// Created by Jigish Patel on 5/18/11.\n// Copyright 2011 Jigish Patel. All rights reserv"
},
{
"path": "Slate/ChainOperation.h",
"chars": 1396,
"preview": "//\n// ChainOperation.h\n// Slate\n//\n// Created by Jigish Patel on 5/28/11.\n// Copyright 2011 Jigish Patel. All rights"
},
{
"path": "Slate/ChainOperation.m",
"chars": 5812,
"preview": "//\n// ChainOperation.m\n// Slate\n//\n// Created by Jigish Patel on 5/28/11.\n// Copyright 2011 Jigish Patel. All rights"
},
{
"path": "Slate/ConfigurationHelperView.h",
"chars": 1442,
"preview": "//\n// ConfigurationHelperView.h\n// Slate\n//\n// Created by Jigish Patel on 3/5/12.\n// Copyright 2011 Jigish Patel. Al"
},
{
"path": "Slate/ConfigurationHelperView.m",
"chars": 6112,
"preview": "//\n// ConfigurationHelperView.m\n// Slate\n//\n// Created by Jigish Patel on 3/5/12.\n// Copyright 2011 Jigish Patel. Al"
},
{
"path": "Slate/Constants.h",
"chars": 14425,
"preview": "//\n// Constants.h\n// Slate\n//\n// Created by Jigish Patel on 5/26/11.\n// Copyright 2011 Jigish Patel. All rights rese"
},
{
"path": "Slate/Constants.m",
"chars": 16975,
"preview": "//\n// Constants.m\n// Slate\n//\n// Created by Jigish Patel on 5/26/11.\n// Copyright 2011 Jigish Patel. All rights rese"
},
{
"path": "Slate/CornerOperation.h",
"chars": 949,
"preview": "//\n// CornerOperation.h\n// Slate\n//\n// Created by Jigish Patel on 1/20/13.\n// Copyright 2011 Jigish Patel. All right"
},
{
"path": "Slate/CornerOperation.m",
"chars": 4974,
"preview": "//\n// CornerOperation.m\n// Slate\n//\n// Created by Jigish Patel on 1/20/13.\n// Copyright 2011 Jigish Patel. All right"
},
{
"path": "Slate/DeleteSnapshotOperation.h",
"chars": 1150,
"preview": "//\n// DeleteSnapshotOperation.h\n// Slate\n//\n// Created by Jigish Patel on 2/28/12.\n// Copyright 2012 Jigish Patel. A"
},
{
"path": "Slate/DeleteSnapshotOperation.m",
"chars": 3964,
"preview": "//\n// DeleteSnapshotOperation.m\n// Slate\n//\n// Created by Jigish Patel on 2/28/12.\n// Copyright 2012 Jigish Patel. A"
},
{
"path": "Slate/ExpressionPoint.h",
"chars": 1199,
"preview": "//\n// ExpressionPoint.h\n// Slate\n//\n// Created by Jigish Patel on 5/18/11.\n// Copyright 2011 Jigish Patel. All right"
},
{
"path": "Slate/ExpressionPoint.m",
"chars": 2145,
"preview": "//\n// ExpressionPoint.m\n// Slate\n//\n// Created by Jigish Patel on 5/18/11.\n// Copyright 2011 Jigish Patel. All right"
},
{
"path": "Slate/FocusOperation.h",
"chars": 1135,
"preview": "//\n// FocusOperation.h\n// Slate\n//\n// Created by Jigish Patel on 6/21/11.\n// Copyright 2011 Jigish Patel. All rights"
},
{
"path": "Slate/FocusOperation.m",
"chars": 10990,
"preview": "//\n// FocusOperation.m\n// Slate\n//\n// Created by Jigish Patel on 6/21/11.\n// Copyright 2011 Jigish Patel. All rights"
},
{
"path": "Slate/GridCellView.h",
"chars": 946,
"preview": "//\n// GridCellView.h\n// Slate\n//\n// Created by Jigish Patel on 9/10/12.\n//\n// This program is free software: you can"
},
{
"path": "Slate/GridCellView.m",
"chars": 2909,
"preview": "//\n// GridCellView.m\n// Slate\n//\n// Created by Jigish Patel on 9/10/12.\n//\n// This program is free software: you can"
},
{
"path": "Slate/GridOperation.h",
"chars": 1499,
"preview": "//\n// GridOperation.h\n// Slate\n//\n// Created by Jigish Patel on 9/7/12.\n//\n// This program is free software: you can"
},
{
"path": "Slate/GridOperation.m",
"chars": 9557,
"preview": "//\n// GridOperation.m\n// Slate\n//\n// Created by Jigish Patel on 9/7/12.\n//\n// This program is free software: you can"
},
{
"path": "Slate/GridView.h",
"chars": 1191,
"preview": "//\n// GridView.h\n// Slate\n//\n// Created by Jigish Patel on 9/7/12.\n// Copyright 2012 Jigish Patel. All rights reserv"
},
{
"path": "Slate/GridView.m",
"chars": 8010,
"preview": "//\n// GridView.m\n// Slate\n//\n// Created by Jigish Patel on 9/7/12.\n// Copyright 2012 Jigish Patel. All rights reserv"
},
{
"path": "Slate/GridWindow.h",
"chars": 846,
"preview": "//\n// GridWindow.h\n// Slate\n//\n// Created by Jigish Patel on 9/7/12.\n// Copyright 2012 Jigish Patel. All rights rese"
},
{
"path": "Slate/GridWindow.m",
"chars": 885,
"preview": "//\n// GridWindow.m\n// Slate\n//\n// Created by Jigish Patel on 9/7/12.\n// Copyright 2012 Jigish Patel. All rights rese"
},
{
"path": "Slate/HintOperation.h",
"chars": 1868,
"preview": "//\n// HintOperation.h\n// Slate\n//\n// Created by Jigish Patel on 3/2/12.\n// Copyright 2012 Jigish Patel. All rights r"
},
{
"path": "Slate/HintOperation.m",
"chars": 19075,
"preview": "//\n// HintOperation.m\n// Slate\n//\n// Created by Jigish Patel on 3/2/12.\n// Copyright 2012 Jigish Patel. All rights r"
},
{
"path": "Slate/HintView.h",
"chars": 991,
"preview": "//\n// HintView.h\n// Slate\n//\n// Created by Jigish Patel on 3/3/12.\n// Copyright 2012 Jigish Patel. All rights reserv"
},
{
"path": "Slate/HintView.m",
"chars": 4757,
"preview": "//\n// HintView.m\n// Slate\n//\n// Created by Jigish Patel on 3/3/12.\n// Copyright 2012 Jigish Patel. All rights reserv"
},
{
"path": "Slate/HintWindow.h",
"chars": 846,
"preview": "//\n// HintWindow.h\n// Slate\n//\n// Created by Jigish Patel on 3/3/12.\n// Copyright 2012 Jigish Patel. All rights rese"
},
{
"path": "Slate/HintWindow.m",
"chars": 885,
"preview": "//\n// HintWindow.m\n// Slate\n//\n// Created by Jigish Patel on 3/3/12.\n// Copyright 2012 Jigish Patel. All rights rese"
},
{
"path": "Slate/JSApplicationWrapper.h",
"chars": 1360,
"preview": "//\n// JSApplicationWrapper.h\n// Slate\n//\n// Created by Jigish Patel on 1/21/13.\n// Copyright 2013 Jigish Patel. All "
},
{
"path": "Slate/JSApplicationWrapper.m",
"chars": 4685,
"preview": "//\n// JSApplicationWrapper.m\n// Slate\n//\n// Created by Jigish Patel on 1/21/13.\n// Copyright 2013 Jigish Patel. All "
},
{
"path": "Slate/JSController.h",
"chars": 1542,
"preview": "//\n// JSController.h\n// Slate\n//\n// Created by Alex Morega on 2013-01-16.\n//\n// This program is free software: you c"
},
{
"path": "Slate/JSController.m",
"chars": 18731,
"preview": "//\n// JSController.m\n// Slate\n//\n// Created by Alex Morega on 2013-01-16.\n//\n// This program is free software: you c"
},
{
"path": "Slate/JSInfoWrapper.h",
"chars": 1184,
"preview": "//\n// JSInfoWrapper.h\n// Slate\n//\n// Created by Jigish Patel on 1/21/13.\n// Copyright 2013 Jigish Patel. All rights "
},
{
"path": "Slate/JSInfoWrapper.m",
"chars": 7422,
"preview": "//\n// JSInfoWrapper.m\n// Slate\n//\n// Created by Jigish Patel on 1/21/13.\n// Copyright 2013 Jigish Patel. All rights "
},
{
"path": "Slate/JSONKit/JSONKit.h",
"chars": 11692,
"preview": "//\n// JSONKit.h\n// http://github.com/johnezang/JSONKit\n// Dual licensed under either the terms of the BSD License, or"
},
{
"path": "Slate/JSONKit/JSONKit.m",
"chars": 176437,
"preview": "//\n// JSONKit.m\n// http://github.com/johnezang/JSONKit\n// Dual licensed under either the terms of the BSD License, or"
},
{
"path": "Slate/JSOperation.h",
"chars": 1101,
"preview": "//\n// JSOperation.h\n// Slate\n//\n// Created by Jigish Patel on 1/22/13.\n// Copyright 2013 Jigish Patel. All rights re"
},
{
"path": "Slate/JSOperation.m",
"chars": 2528,
"preview": "//\n// JSOperation.m\n// Slate\n//\n// Created by Jigish Patel on 1/22/13.\n// Copyright 2013 Jigish Patel. All rights re"
},
{
"path": "Slate/JSOperationWrapper.h",
"chars": 1369,
"preview": "//\n// JSOperationWrapper.h\n// Slate\n//\n// Created by Jigish Patel on 1/25/13.\n// Copyright 2013 Jigish Patel. All ri"
},
{
"path": "Slate/JSOperationWrapper.m",
"chars": 4976,
"preview": "//\n// JSOperationWrapper.m\n// Slate\n//\n// Created by Jigish Patel on 1/25/13.\n// Copyright 2013 Jigish Patel. All ri"
},
{
"path": "Slate/JSScreenWrapper.h",
"chars": 1134,
"preview": "//\n// JSScreenWrapper.h\n// Slate\n//\n// Created by Jigish Patel on 1/21/13.\n// Copyright 2013 Jigish Patel. All right"
},
{
"path": "Slate/JSScreenWrapper.m",
"chars": 4339,
"preview": "//\n// JSScreenWrapper.m\n// Slate\n//\n// Created by Jigish Patel on 1/21/13.\n// Copyright 2013 Jigish Patel. All right"
},
{
"path": "Slate/JSWindowWrapper.h",
"chars": 1156,
"preview": "//\n// JSWindowWrapper.h\n// Slate\n//\n// Created by Jigish Patel on 1/21/13.\n// Copyright 2013 Jigish Patel. All right"
},
{
"path": "Slate/JSWindowWrapper.m",
"chars": 7217,
"preview": "//\n// JSWindowWrapper.m\n// Slate\n//\n// Created by Jigish Patel on 1/21/13.\n// Copyright 2013 Jigish Patel. All right"
},
{
"path": "Slate/JSWrapperUtils.h",
"chars": 1299,
"preview": "//\n// JSWrapperUtils.h\n// Slate\n//\n// Created by Jigish Patel on 1/22/13.\n// Copyright 2013 Jigish Patel. All rights"
},
{
"path": "Slate/JSWrapperUtils.m",
"chars": 4672,
"preview": "//\n// JSWrapperUtils.m\n// Slate\n//\n// Created by Jigish Patel on 1/22/13.\n// Copyright 2013 Jigish Patel. All rights"
},
{
"path": "Slate/Layout.h",
"chars": 1398,
"preview": "//\n// Layout.h\n// Slate\n//\n// Created by Jigish Patel on 6/13/11.\n// Copyright 2011 Jigish Patel. All rights reserve"
},
{
"path": "Slate/Layout.m",
"chars": 8005,
"preview": "//\n// Layout.m\n// Slate\n//\n// Created by Jigish Patel on 6/13/11.\n// Copyright 2011 Jigish Patel. All rights reserve"
},
{
"path": "Slate/LayoutOperation.h",
"chars": 1237,
"preview": "//\n// LayoutOperation.h\n// Slate\n//\n// Created by Jigish Patel on 6/14/11.\n// Copyright 2011 Jigish Patel. All right"
},
{
"path": "Slate/LayoutOperation.m",
"chars": 12924,
"preview": "//\n// LayoutOperation.m\n// Slate\n//\n// Created by Jigish Patel on 6/14/11.\n// Copyright 2011 Jigish Patel. All right"
},
{
"path": "Slate/MathUtils.h",
"chars": 1141,
"preview": "//\n// MathUtils.h\n// Slate\n//\n// Created by Jigish Patel on 6/22/11.\n// Copyright 2011 Jigish Patel. All rights rese"
},
{
"path": "Slate/MathUtils.m",
"chars": 1958,
"preview": "//\n// MathUtils.m\n// Slate\n//\n// Created by Jigish Patel on 6/22/11.\n// Copyright 2011 Jigish Patel. All rights rese"
},
{
"path": "Slate/MoveOperation.h",
"chars": 1668,
"preview": "//\n// MoveOperation.h\n// Slate\n//\n// Created by Jigish Patel on 5/18/11.\n// Copyright 2011 Jigish Patel. All rights "
},
{
"path": "Slate/MoveOperation.m",
"chars": 7417,
"preview": "//\n// MoveOperation.m\n// Slate\n//\n// Created by Jigish Patel on 5/18/11.\n// Copyright 2011 Jigish Patel. All rights "
},
{
"path": "Slate/NSFileManager+ApplicationSupport.h",
"chars": 1116,
"preview": "//\n// NSFileManager+ApplicationSupport.h\n// Slate\n//\n// Created by Jigish Patel on 4/23/12.\n// Copyright 2012 Jigish"
},
{
"path": "Slate/NSFileManager+ApplicationSupport.m",
"chars": 2208,
"preview": "//\n// NSFileManager+ApplicationSupport.m\n// Slate\n//\n// Created by Jigish Patel on 4/23/12.\n// Copyright 2012 Jigish"
},
{
"path": "Slate/NSString+Indicies.h",
"chars": 950,
"preview": "//\n// NSString+Indicies.h\n// Slate\n//\n// Created by Jigish Patel on 10/1/12.\n// Copyright 2011 Jigish Patel. All rig"
},
{
"path": "Slate/NSString+Indicies.m",
"chars": 1257,
"preview": "//\n// NSString+Indicies.m\n// Slate\n//\n// Created by Jigish Patel on 10/1/12.\n// Copyright 2011 Jigish Patel. All rig"
},
{
"path": "Slate/NSString+Levenshtein.h",
"chars": 1033,
"preview": "//\n// NSString+Levenshtein.h\n// Slate\n//\n// Created by Jigish Patel on 3/1/12.\n// Copyright 2011 Jigish Patel. All r"
},
{
"path": "Slate/NSString+Levenshtein.m",
"chars": 2924,
"preview": "//\n// NSString+Levenshtein.m\n// Slate\n//\n// Created by Jigish Patel on 3/1/12.\n// Copyright 2011 Jigish Patel. All r"
},
{
"path": "Slate/NudgeOperation.h",
"chars": 944,
"preview": "//\n// NudgeOperation.h\n// Slate\n//\n// Created by Jigish Patel on 1/20/13.\n// Copyright 2011 Jigish Patel. All rights"
},
{
"path": "Slate/NudgeOperation.m",
"chars": 4097,
"preview": "//\n// NudgeOperation.m\n// Slate\n//\n// Created by Jigish Patel on 1/20/13.\n// Copyright 2011 Jigish Patel. All rights"
},
{
"path": "Slate/Operation.h",
"chars": 2086,
"preview": "//\n// Operation.h\n// Slate\n//\n// Created by Jigish Patel on 5/18/11.\n// Copyright 2011 Jigish Patel. All rights rese"
},
{
"path": "Slate/Operation.m",
"chars": 11636,
"preview": "//\n// Operation.m\n// Slate\n//\n// Created by Jigish Patel on 5/18/11.\n// Copyright 2011 Jigish Patel. All rights rese"
},
{
"path": "Slate/PushOperation.h",
"chars": 939,
"preview": "//\n// PushOperation.h\n// Slate\n//\n// Created by Jigish Patel on 1/20/13.\n// Copyright 2011 Jigish Patel. All rights "
},
{
"path": "Slate/PushOperation.m",
"chars": 12281,
"preview": "//\n// PushOperation.m\n// Slate\n//\n// Created by Jigish Patel on 1/20/13.\n// Copyright 2011 Jigish Patel. All rights "
},
{
"path": "Slate/RelaunchOperation.h",
"chars": 941,
"preview": "//\n// RelaunchOperation.h\n// Slate\n//\n// Created by Jigish Patel on 10/11/12.\n// Copyright 2011 Jigish Patel. All ri"
},
{
"path": "Slate/RelaunchOperation.m",
"chars": 1790,
"preview": "//\n// RelaunchOperation.m\n// Slate\n//\n// Created by Jigish Patel on 10/11/12.\n// Copyright 2011 Jigish Patel. All ri"
},
{
"path": "Slate/ResizeOperation.h",
"chars": 1497,
"preview": "//\n// ResizeOperation.h\n// Slate\n//\n// Created by Jigish Patel on 5/26/11.\n// Copyright 2011 Jigish Patel. All right"
},
{
"path": "Slate/ResizeOperation.m",
"chars": 7570,
"preview": "//\n// ResizeOperation.m\n// Slate\n//\n// Created by Jigish Patel on 5/26/11.\n// Copyright 2011 Jigish Patel. All right"
},
{
"path": "Slate/RunningApplications.h",
"chars": 1716,
"preview": "//\n// RunningApplications.h\n// Slate\n//\n// Created by Jigish Patel on 3/22/12.\n// Copyright 2012 Jigish Patel. All r"
},
{
"path": "Slate/RunningApplications.m",
"chars": 28671,
"preview": "//\n// RunningApplications.m\n// Slate\n//\n// Created by Jigish Patel on 3/22/12.\n// Copyright 2012 Jigish Patel. All r"
},
{
"path": "Slate/ScreenState.h",
"chars": 1187,
"preview": "//\n// ScreenState.h\n// Slate\n//\n// Created by Jigish Patel on 6/19/11.\n// Copyright 2011 Jigish Patel. All rights re"
},
{
"path": "Slate/ScreenState.m",
"chars": 3027,
"preview": "//\n// ScreenState.m\n// Slate\n//\n// Created by Jigish Patel on 6/19/11.\n// Copyright 2011 Jigish Patel. All rights re"
},
{
"path": "Slate/ScreenWrapper.h",
"chars": 2621,
"preview": "//\n// ScreenWrapper.h\n// Slate\n//\n// Created by Jigish Patel on 6/17/11.\n// Copyright 2011 Jigish Patel. All rights "
},
{
"path": "Slate/ScreenWrapper.m",
"chars": 15257,
"preview": "//\n// ScreenWrapper.m\n// Slate\n//\n// Created by Jigish Patel on 6/17/11.\n// Copyright 2011 Jigish Patel. All rights "
},
{
"path": "Slate/SequenceOperation.h",
"chars": 1070,
"preview": "//\n// SequenceOperation.h\n// Slate\n//\n// Created by Jigish Patel on 10/5/12.\n// Copyright 2011 Jigish Patel. All rig"
},
{
"path": "Slate/SequenceOperation.m",
"chars": 6334,
"preview": "//\n// SequenceOperation.m\n// Slate\n//\n// Created by Jigish Patel on 10/5/12.\n// Copyright 2011 Jigish Patel. All rig"
},
{
"path": "Slate/ShellOperation.h",
"chars": 1283,
"preview": "//\n// ShellOperation.h\n// Slate\n//\n// Created by Jigish Patel on 10/17/12.\n// Copyright 2012 Jigish Patel. All right"
},
{
"path": "Slate/ShellOperation.m",
"chars": 6427,
"preview": "//\n// ShellOperation.m\n// Slate\n//\n// Created by Jigish Patel on 10/17/12.\n// Copyright 2012 Jigish Patel. All right"
},
{
"path": "Slate/ShellUtils.h",
"chars": 1082,
"preview": "//\n// ShellUtils.h\n// Slate\n//\n// Created by Jigish Patel on 10/17/12.\n// Copyright 2012 Jigish Patel. All rights re"
},
{
"path": "Slate/ShellUtils.m",
"chars": 3966,
"preview": "//\n// ShellUtils.m\n// Slate\n//\n// Created by Jigish Patel on 10/17/12.\n// Copyright 2012 Jigish Patel. All rights re"
},
{
"path": "Slate/Slate-Info.plist",
"chars": 1257,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Slate/Slate-Prefix.pch",
"chars": 141,
"preview": "//\n// Prefix header for all source files of the 'Slate' target in the 'Slate' project\n//\n\n#ifdef __OBJC__\n #import <C"
},
{
"path": "Slate/SlateAppDelegate.h",
"chars": 3501,
"preview": "//\n// SlateAppDelegate.h\n// Slate\n//\n// Created by Jigish Patel on 5/18/11.\n// Copyright 2011 Jigish Patel. All righ"
},
{
"path": "Slate/SlateAppDelegate.m",
"chars": 27564,
"preview": "//\n// SlateAppDelegate.m\n// Slate\n//\n// Created by Jigish Patel on 5/18/11.\n// Copyright 2011 Jigish Patel. All righ"
},
{
"path": "Slate/SlateConfig.h",
"chars": 3076,
"preview": "//\n// SlateConfig.h\n// Slate\n//\n// Created by Jigish Patel on 5/18/11.\n// Copyright 2011 Jigish Patel. All rights re"
},
{
"path": "Slate/SlateConfig.m",
"chars": 27451,
"preview": "//\n// SlateConfig.m\n// Slate\n//\n// Created by Jigish Patel on 5/18/11.\n// Copyright 2011 Jigish Patel. All rights re"
},
{
"path": "Slate/SlateLogger.h",
"chars": 943,
"preview": "//\n// SlateLogger.h\n// Slate\n//\n// Created by Jigish Patel on 3/5/12.\n// Copyright 2011 Jigish Patel. All rights res"
},
{
"path": "Slate/Snapshot.h",
"chars": 1126,
"preview": "//\n// Snapshot.h\n// Slate\n//\n// Created by Jigish Patel on 2/28/12.\n// Copyright 2012 Jigish Patel. All rights reser"
},
{
"path": "Slate/Snapshot.m",
"chars": 2337,
"preview": "//\n// Snapshot.m\n// Slate\n//\n// Created by Jigish Patel on 2/28/12.\n// Copyright 2012 Jigish Patel. All rights reser"
},
{
"path": "Slate/SnapshotList.h",
"chars": 1450,
"preview": "//\n// SnapshotList.h\n// Slate\n//\n// Created by Jigish Patel on 2/28/12.\n// Copyright 2012 Jigish Patel. All rights r"
},
{
"path": "Slate/SnapshotList.m",
"chars": 3258,
"preview": "//\n// SnapshotList.m\n// Slate\n//\n// Created by Jigish Patel on 2/28/12.\n// Copyright 2012 Jigish Patel. All rights r"
},
{
"path": "Slate/SnapshotOperation.h",
"chars": 1246,
"preview": "//\n// SnapshotOperation.h\n// Slate\n//\n// Created by Jigish Patel on 2/28/12.\n// Copyright 2012 Jigish Patel. All rig"
},
{
"path": "Slate/SnapshotOperation.m",
"chars": 6054,
"preview": "//\n// SnapshotOperation.m\n// Slate\n//\n// Created by Jigish Patel on 2/28/12.\n// Copyright 2012 Jigish Patel. All rig"
},
{
"path": "Slate/StringTokenizer.h",
"chars": 1500,
"preview": "//\n// StringTokenizer.h\n// Slate\n//\n// Created by Jigish Patel on 5/26/11.\n// Copyright 2011 Jigish Patel. All right"
},
{
"path": "Slate/StringTokenizer.m",
"chars": 6026,
"preview": "//\n// StringTokenizer.m\n// Slate\n//\n// Created by Jigish Patel on 5/26/11.\n// Copyright 2011 Jigish Patel. All right"
},
{
"path": "Slate/SwitchAppQuittingOverlayView.h",
"chars": 922,
"preview": "//\n// SwitchAppQuittingOverlayView.h\n// Slate\n//\n// Created by Jigish Patel on 3/22/12.\n// Copyright 2012 Jigish Pat"
},
{
"path": "Slate/SwitchAppQuittingOverlayView.m",
"chars": 2684,
"preview": "//\n// SwitchAppQuittingOverlayView.m\n// Slate\n//\n// Created by Jigish Patel on 3/22/12.\n// Copyright 2012 Jigish Pat"
},
{
"path": "Slate/SwitchAppView.h",
"chars": 1613,
"preview": "//\n// SwitchAppView.h\n// Slate\n//\n// Created by Jigish Patel on 3/22/12.\n// Copyright 2012 Jigish Patel. All rights "
},
{
"path": "Slate/SwitchAppView.m",
"chars": 10948,
"preview": "//\n// SwitchAppView.m\n// Slate\n//\n// Created by Jigish Patel on 3/22/12.\n// Copyright 2012 Jigish Patel. All rights "
},
{
"path": "Slate/SwitchOperation.h",
"chars": 1436,
"preview": "//\n// SwitchOperation.h\n// Slate\n//\n// Created by Jigish Patel on 3/9/12.\n// Copyright 2012 Jigish Patel. All rights"
},
{
"path": "Slate/SwitchOperation.m",
"chars": 16416,
"preview": "//\n// SwitchOperation.m\n// Slate\n//\n// Created by Jigish Patel on 3/9/12.\n// Copyright 2012 Jigish Patel. All rights"
},
{
"path": "Slate/SwitchView.h",
"chars": 844,
"preview": "//\n// SwitchView.h\n// Slate\n//\n// Created by Jigish Patel on 3/9/12.\n// Copyright 2012 Jigish Patel. All rights rese"
},
{
"path": "Slate/SwitchView.m",
"chars": 1928,
"preview": "//\n// SwitchView.m\n// Slate\n//\n// Created by Jigish Patel on 3/9/12.\n// Copyright 2012 Jigish Patel. All rights rese"
},
{
"path": "Slate/SwitchWindow.h",
"chars": 850,
"preview": "//\n// SwitchWindow.h\n// Slate\n//\n// Created by Jigish Patel on 3/9/12.\n// Copyright 2012 Jigish Patel. All rights re"
},
{
"path": "Slate/SwitchWindow.m",
"chars": 891,
"preview": "//\n// SwitchWindow.m\n// Slate\n//\n// Created by Jigish Patel on 3/9/12.\n// Copyright 2012 Jigish Patel. All rights re"
},
{
"path": "Slate/ThrowOperation.h",
"chars": 944,
"preview": "//\n// ThrowOperation.h\n// Slate\n//\n// Created by Jigish Patel on 1/20/13.\n// Copyright 2011 Jigish Patel. All rights"
},
{
"path": "Slate/ThrowOperation.m",
"chars": 2911,
"preview": "//\n// ThrowOperation.m\n// Slate\n//\n// Created by Jigish Patel on 1/20/13.\n// Copyright 2011 Jigish Patel. All rights"
},
{
"path": "Slate/UndoOperation.h",
"chars": 957,
"preview": "//\n// UndoOperation.h\n// Slate\n//\n// Created by Jigish Patel on 11/27/12.\n// Copyright 2012 Jigish Patel. All rights"
},
{
"path": "Slate/UndoOperation.m",
"chars": 1222,
"preview": "//\n// UndoOperation.m\n// Slate\n//\n// Created by Jigish Patel on 11/27/12.\n// Copyright 2012 Jigish Patel. All rights"
},
{
"path": "Slate/VisibilityOperation.h",
"chars": 1405,
"preview": "//\n// VisibilityOperation.h\n// Slate\n//\n// Created by Jigish Patel on 10/7/12.\n// Copyright 2012 Jigish Patel. All r"
},
{
"path": "Slate/VisibilityOperation.m",
"chars": 6303,
"preview": "//\n// VisibilityOperation.m\n// Slate\n//\n// Created by Jigish Patel on 10/7/12.\n// Copyright 2012 Jigish Patel. All r"
},
{
"path": "Slate/WindowInfoView.h",
"chars": 897,
"preview": "//\n// WindowInfoView.h\n// Slate\n//\n// Created by Jigish Patel on 2/27/12.\n// Copyright 2012 Jigish Patel. All rights"
},
{
"path": "Slate/WindowInfoView.m",
"chars": 3821,
"preview": "//\n// WindowInfoView.m\n// Slate\n//\n// Created by Jigish Patel on 2/27/12.\n// Copyright 2012 Jigish Patel. All rights"
},
{
"path": "Slate/WindowSnapshot.h",
"chars": 1305,
"preview": "//\n// WindowSnapshot.h\n// Slate\n//\n// Created by Jigish Patel on 2/28/12.\n// Copyright 2012 Jigish Patel. All rights"
},
{
"path": "Slate/WindowSnapshot.m",
"chars": 2148,
"preview": "//\n// WindowSnapshot.m\n// Slate\n//\n// Created by Jigish Patel on 2/28/12.\n// Copyright 2012 Jigish Patel. All rights"
},
{
"path": "Slate/WindowState.h",
"chars": 1077,
"preview": "//\n// WindowState.h\n// Slate\n//\n// Created by Jigish Patel on 6/13/11.\n// Copyright 2011 Jigish Patel. All rights re"
},
{
"path": "Slate/WindowState.m",
"chars": 2093,
"preview": "//\n// WindowState.m\n// Slate\n//\n// Created by Jigish Patel on 6/13/11.\n// Copyright 2011 Jigish Patel. All rights re"
},
{
"path": "Slate/default.slate",
"chars": 1512,
"preview": "# This is the default .slate file.\n# If no ~/.slate file exists this is the file that will be used.\n\nconfig defaultToCur"
},
{
"path": "Slate/en.lproj/Credits.rtf",
"chars": 1037,
"preview": "{\\rtf1\\ansi\\ansicpg1252\\cocoartf1138\\cocoasubrtf510\n{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n{\\colortbl;\\red255\\green25"
},
{
"path": "Slate/en.lproj/InfoPlist.strings",
"chars": 45,
"preview": "/* Localized versions of Info.plist keys */\n\n"
},
{
"path": "Slate/en.lproj/MainMenu.xib",
"chars": 184855,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<archive type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"7.10\">\n\t<data>\n\t\t<"
},
{
"path": "Slate/initialize.js",
"chars": 5064,
"preview": "(function(_controller, _info) {\n var slate = window.slate = {\n log: function() {\n var msg = Array.prototype.sli"
},
{
"path": "Slate/main.m",
"chars": 894,
"preview": "//\n// main.m\n// Slate\n//\n// Created by Jigish Patel on 5/18/11.\n// Copyright 2011 Jigish Patel. All rights reserved."
},
{
"path": "Slate/slate-mock.js",
"chars": 870,
"preview": "var opNum = 0;\nwindow._controller = {\n log : function(msg) {\n console.log(msg);\n },\n bindFunction : function(k, c,"
},
{
"path": "Slate/slate-test.html",
"chars": 179,
"preview": "<html>\n <head>\n <script src='underscore.js'></script>\n <script src='slate-mock.js'></script>\n <script src='ini"
},
{
"path": "Slate/underscore.js",
"chars": 13432,
"preview": "(function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.conca"
},
{
"path": "Slate/utils.js",
"chars": 686,
"preview": "(function(controller) {\n for (key in _) {\n window[\"_\"+key+\"_\"] = _[key];\n }\n\n var _typeof_ = window._typeof_ = fun"
},
{
"path": "Slate.xcodeproj/project.pbxproj",
"chars": 75219,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "Slate.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 150,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:Slate.xcodeproj"
},
{
"path": "SlateTests/SlateTests-Info.plist",
"chars": 689,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "SlateTests/SlateTests-Prefix.pch",
"chars": 151,
"preview": "//\n// Prefix header for all source files of the 'SlateTests' target in the 'SlateTests' project\n//\n\n#ifdef __OBJC__\n "
},
{
"path": "SlateTests/SlateTests.h",
"chars": 881,
"preview": "//\n// SlateTests.h\n// Slate\n//\n// Created by Jigish Patel on 5/18/11.\n// Copyright 2011 Jigish Patel. All rights res"
},
{
"path": "SlateTests/SlateTests.m",
"chars": 1080,
"preview": "//\n// SlateTests.m\n// Slate\n//\n// Created by Jigish Patel on 5/18/11.\n// Copyright 2011 Jigish Patel. All rights res"
},
{
"path": "SlateTests/TestExpressionPoint.h",
"chars": 885,
"preview": "//\n// TestExpressionPoint.h\n// Slate\n//\n// Created by Jigish Patel on 10/16/12.\n// Copyright 2011 Jigish Patel. All "
},
{
"path": "SlateTests/TestExpressionPoint.m",
"chars": 4564,
"preview": "//\n// TestExpressionPoint.m\n// Slate\n//\n// Created by Jigish Patel on 10/16/12.\n// Copyright 2011 Jigish Patel. All "
},
{
"path": "SlateTests/TestMathUtils.h",
"chars": 873,
"preview": "//\n// TestMathUtils.h\n// Slate\n//\n// Created by Jigish Patel on 10/16/12.\n// Copyright 2011 Jigish Patel. All rights"
},
{
"path": "SlateTests/TestMathUtils.m",
"chars": 4895,
"preview": "//\n// TestMathUtils.m\n// Slate\n//\n// Created by Jigish Patel on 10/16/12.\n// Copyright 2011 Jigish Patel. All rights"
},
{
"path": "SlateTests/TestNSString+Indicies.h",
"chars": 888,
"preview": "//\n// TestNSString+Indicies.h\n// Slate\n//\n// Created by Jigish Patel on 10/1/12.\n// Copyright 2011 Jigish Patel. All"
},
{
"path": "SlateTests/TestNSString+Indicies.m",
"chars": 1816,
"preview": "//\n// TestNSString+Indicies.m\n// Slate\n//\n// Created by Jigish Patel on 10/1/12.\n// Copyright 2011 Jigish Patel. All"
},
{
"path": "SlateTests/TestNSString+Levenshtein.h",
"chars": 895,
"preview": "//\n// TestNSString+Levenshtein.h\n// Slate\n//\n// Created by Jigish Patel on 10/16/12.\n// Copyright 2011 Jigish Patel."
},
{
"path": "SlateTests/TestNSString+Levenshtein.m",
"chars": 2307,
"preview": "//\n// TestNSString+Levenshtein.m\n// Slate\n//\n// Created by Jigish Patel on 10/16/12.\n// Copyright 2011 Jigish Patel."
},
{
"path": "SlateTests/TestShellUtils.h",
"chars": 875,
"preview": "//\n// TestShellUtils.h\n// Slate\n//\n// Created by Jigish Patel on 10/17/12.\n// Copyright 2012 Jigish Patel. All right"
},
{
"path": "SlateTests/TestShellUtils.m",
"chars": 2657,
"preview": "//\n// TestShellUtils.m\n// Slate\n//\n// Created by Jigish Patel on 10/17/12.\n// Copyright 2012 Jigish Patel. All right"
},
{
"path": "SlateTests/TestStringTokenizer.h",
"chars": 885,
"preview": "//\n// TestStringTokenizer.h\n// Slate\n//\n// Created by Jigish Patel on 10/16/12.\n// Copyright 2011 Jigish Patel. All "
},
{
"path": "SlateTests/TestStringTokenizer.m",
"chars": 7566,
"preview": "//\n// TestStringTokenizer.m\n// Slate\n//\n// Created by Jigish Patel on 10/16/12.\n// Copyright 2011 Jigish Patel. All "
},
{
"path": "SlateTests/en.lproj/InfoPlist.strings",
"chars": 45,
"preview": "/* Localized versions of Info.plist keys */\n\n"
},
{
"path": "Sparkle.framework/Versions/A/Headers/SUAppcast.h",
"chars": 668,
"preview": "//\n// SUAppcast.h\n// Sparkle\n//\n// Created by Andy Matuschak on 3/12/06.\n// Copyright 2006 Andy Matuschak. All right"
},
{
"path": "Sparkle.framework/Versions/A/Headers/SUAppcastItem.h",
"chars": 1013,
"preview": "//\n// SUAppcastItem.h\n// Sparkle\n//\n// Created by Andy Matuschak on 3/12/06.\n// Copyright 2006 Andy Matuschak. All r"
},
{
"path": "Sparkle.framework/Versions/A/Headers/SUUpdater.h",
"chars": 4887,
"preview": "//\n// SUUpdater.h\n// Sparkle\n//\n// Created by Andy Matuschak on 1/4/06.\n// Copyright 2006 Andy Matuschak. All rights"
},
{
"path": "Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h",
"chars": 705,
"preview": "//\n// SUVersionComparisonProtocol.h\n// Sparkle\n//\n// Created by Andy Matuschak on 12/21/07.\n// Copyright 2007 Andy M"
},
{
"path": "Sparkle.framework/Versions/A/Headers/Sparkle.h",
"chars": 536,
"preview": "//\n// Sparkle.h\n// Sparkle\n//\n// Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07)\n// Copyright 2"
},
{
"path": "Sparkle.framework/Versions/A/Resources/Info.plist",
"chars": 720,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/License.txt",
"chars": 1057,
"preview": "Copyright (c) 2006 Andy Matuschak\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this "
},
{
"path": "Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist",
"chars": 5987,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/SUStatus.nib/classes.nib",
"chars": 1290,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/SUStatus.nib/info.nib",
"chars": 550,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/classes.nib",
"chars": 1144,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/info.nib",
"chars": 552,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/classes.nib",
"chars": 1532,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/info.nib",
"chars": 552,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/classes.nib",
"chars": 1374,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/info.nib",
"chars": 552,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/classes.nib",
"chars": 1144,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/info.nib",
"chars": 554,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/classes.nib",
"chars": 1532,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/info.nib",
"chars": 554,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/classes.nib",
"chars": 1374,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/info.nib",
"chars": 577,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/classes.nib",
"chars": 1144,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/info.nib",
"chars": 552,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/classes.nib",
"chars": 1532,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/info.nib",
"chars": 552,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/classes.nib",
"chars": 1374,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/info.nib",
"chars": 555,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/classes.nib",
"chars": 1144,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/info.nib",
"chars": 438,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/classes.nib",
"chars": 1532,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/info.nib",
"chars": 438,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/classes.nib",
"chars": 1374,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/info.nib",
"chars": 438,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/classes.nib",
"chars": 1144,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
}
]
// ... and 283 more files (download for full content)
About this extraction
This page contains the full source code of the jigish/slate GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 483 files (12.6 MB), approximately 410.4k tokens, and a symbol index with 70 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.