├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE.md ├── Makefile ├── README.md ├── _images ├── jumpy-high-contrast-font-camel.png ├── jumpy-settings.png └── jumpy.gif ├── coffeelint.json ├── dist ├── elm │ └── StateMachine.js ├── jumpy-view.js ├── jumpy-view.js.map ├── jumpy.js ├── jumpy.js.map ├── keys.js ├── keys.js.map ├── label-interface.js ├── label-interface.js.map ├── label-reducer.js ├── label-reducer.js.map ├── labelers │ ├── tabs.js │ ├── tabs.js.map │ ├── tree-items.js │ ├── tree-items.js.map │ ├── words.js │ └── words.js.map ├── viewHelpers.js └── viewHelpers.js.map ├── elm.json ├── keymaps └── jumpy.cson ├── lib ├── StateMachine.elm ├── jumpy-view.ts ├── jumpy.ts ├── keys.ts ├── label-interface.ts ├── label-reducer.ts ├── labelers │ ├── tabs.ts │ ├── tree-items.ts │ └── words.ts ├── tsconfig.json └── viewHelpers.ts ├── package-lock.json ├── package.json ├── spec ├── custom-runner.js ├── fixtures │ ├── test_long_text.md │ ├── test_text.md │ ├── test_text2.md │ └── test_text_single_letter.md ├── helpers │ ├── keydown.coffee │ └── wait.coffee ├── jumpy-large-file-spec.coffee ├── jumpy-multi-pane-spec.coffee ├── jumpy-settings-spec.coffee ├── jumpy-single-letter-spec.coffee └── jumpy-spec.coffee ├── styles ├── .atom-text-editor.less ├── beacon.less └── theme-atom-material-ui.atom-text-editor.less └── tests └── Tests.elm /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | npm-debug.log 3 | node_modules 4 | elm-stuff 5 | notes.txt 6 | graph.svg 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | ### Project specific config ### 2 | language: generic 3 | 4 | env: 5 | global: 6 | - APM_TEST_PACKAGES="" 7 | - ATOM_LINT_WITH_BUNDLED_NODE="true" 8 | - CI="true" 9 | 10 | matrix: 11 | - ATOM_CHANNEL=stable 12 | - ATOM_CHANNEL=beta 13 | 14 | os: 15 | - linux 16 | 17 | ### Generic setup follows ### 18 | script: 19 | - curl -s -O https://raw.githubusercontent.com/atom/ci/master/build-package.sh 20 | - chmod u+x build-package.sh 21 | - ./build-package.sh 22 | 23 | notifications: 24 | email: 25 | on_success: never 26 | on_failure: change 27 | 28 | branches: 29 | only: 30 | - master 31 | 32 | git: 33 | depth: 10 34 | 35 | sudo: false 36 | 37 | dist: trusty 38 | 39 | addons: 40 | apt: 41 | packages: 42 | - build-essential 43 | - fakeroot 44 | - git 45 | - libsecret-1-dev 46 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 5.0.2 - Few tweaks 2 | * Use uglify-js to decrease size! (leverages elm's --optimize) 3 | * Update README.md with links / install instructions to new Jumpy packages! 4 | * Attempt to improve travis test stability with wait time. 5 | 6 | ## 5.0.1 - Upgrade elm and lodash 7 | * Upgrade to elm 0.19 (Greatly reduces size of state machine after compilation) 8 | * Upgrade lodash because of security concern. 9 | 10 | ## 5.0.0 - New Architecture + Jump to Tree View Items! 11 | * Enable jumping to the Tree View items! 12 | * Replace javascript-state-machine with headless Elm module. 13 | * Add '😞' to 'no match' alert. 14 | * All tests now using Jasmine3. Much faster + fixes Travis build. 15 | 16 | ## 4.2.0 - Add custom keys for labels 17 | * Merge @taylon PR to add custom keys! 18 | 19 | ## 4.1.1 - Fix performance issue with current Atom 20 | 21 | ## 4.1.0 - Add ability to jump while tree-view is focused 22 | * Should work with 'shift-enter' or 'f' bindings in vim-mode! 23 | * Alert users about current atom release's performance issues. 24 | 25 | ## 4.0.0 - New Architecture + Jump to Tabs! 26 | * Add ability to jump to tabs! 27 | * Preps for @johngeorgewright's code for tree-view labels and other initiatives. 28 | * Convert all core code from CoffeeScript to TypeScript. 29 | * Pull out into modules and use javascript-state-machine. 30 | * Use workspaceElement for key listening. No more preregistered commands. 31 | * Add an extra css class to jumpy jump mode to make it more specific. 32 | * Remove code registering commands for jumpy keys for each letter. 33 | * Fix small bug of no match case after 2nd character. 34 | * Remove all space-pen / jQuery. 35 | * Add note about vim-mode-plus and hydrogen packages in README.md. 36 | 37 | ## 3.1.3 - Remove deprecation (Object.observe) 38 | * Simplify and Remove logic that used Object.observe for key maps. 39 | 40 | ## 3.1.2 - Fix beacon 41 | * Merge @johngeorgewright PR to restore the beacon functionality! 42 | 43 | ## 3.1.1 - Add Travis CI Badge 44 | * First run of Travis! 45 | 46 | ## 3.1.0 Gitter and Travis Continuous Integration 47 | * Adds .travis.yml to project for Travis Continuous Integration. 48 | * Adds a gitter badge to the README.md. 49 | 50 | ## 3.0.3 51 | * Fix issue #84 (PR: #85) from Danny Arnold (@despairblue) 52 | 53 | ## 3.0.2 54 | * Fix issue when switching tabs if jump mode is open. 55 | 56 | ## 3.0.1 57 | * Is the actual released version of the below (had to deal with some publishing issues in core). 58 | 59 | ## 3.0.0 60 | * Fix new Atom releases performance issue (tiling changes) by using 61 | markers and decorations. 62 | * Big refactor. 63 | * BREAKING CHANGES: See README.md for new custom styling methods. 64 | 65 | ## 2.0.10 66 | * Fix broken labels with atom-material-ui theme. Thanks to @livelazily for some help with this! 67 | 68 | ## 2.0.9 69 | * Fix broken beacon animation (finally got around to this). 70 | * Update README.md with new way to style Jumpy labels etc (using shadow dom). 71 | 72 | ## 2.0.8 73 | * Remove deprecation warning for styles. Fixes (61 & 62). 74 | 75 | ## 2.0.7 76 | * Update README.md with fix for 'f' hotkey with new Atom. 77 | * Fixes #59 & #60. Jumpy broke with Atom 0.206.0, and now works / tested with 0.207.0 (coincidence) 78 | * Handles changes to Atom rendering by tiles. 79 | * Includes Shadow dom and keymap fixes. 80 | 81 | ## 2.0.6 82 | * Fixes #45 Let's a keymap command contain a non string. 83 | 84 | ## 2.0.5 85 | * Fixes #54 for performance issue / leak found by @despairblue. 86 | * Few other minor performance issues. 87 | * Memory leak prevention of commands. 88 | * Added descriptions to the config options. 89 | * Add test for find-and-replace 90 | * Adds tests for command activation/deactivation. 91 | 92 | ## 2.0.4 93 | * Minor precaution using addEventListener instead of onblur. 94 | 95 | ## 2.0.3 96 | * Fixes #39 - Calls to mini panes (like cmd+f, cmd+p) lock up when in jump mode. 97 | * Merge @badem4o's pull request to fix some more deprecations in the shadow dom selectors. 98 | * Fix deprecated method calls. 99 | * *Slight* performance improvements. 100 | * Improve tests. 101 | 102 | ## 2.0.2 103 | * Fixed regression: restore consecutive labels across open tabs. 104 | 105 | ## 2.0.1 106 | * Fixed regression: scroll event was no longer clearing jump-mode. 107 | 108 | ## 2.0.0 109 | * 2.0.0 for reasons listed below: 110 | * Almost every LOC changed to support new Atom APIs. All tests passing with no deprecations! 111 | * "Breaking" 2.0 changes because of shadow dom architectural changes. 112 | NOTE: Expect your user custom styling approaches to be defunct. 113 | Nothing I could have done here sorry, blame Atom (JK). New suggestions of how to style in an updated README.md coming soon! 114 | * Planned 2.1 release will include @willdady's pull request (technically adds to the "breaking" change in functionality to improve "accuracy" - that is more labels!) 115 | * Temporarily disabled "homing beacon" feature as this broke with the new shadow dom architecture. Will need further investigation. 116 | * Closes #42. (Doesn't work with the "Shadow DOM" flag enabled) 117 | 118 | ## 1.9.4 119 | * Fixed #37 - No labels printed when tab dragged from different pane. 120 | 121 | ## 1.9.3 122 | * Fixed default keymap to handle new editions to mac bindings in core 123 | Atom as of atom 0.131.0. 124 | * New Atom default uses shift-enter for inserting a new line. 125 | * They added it for consistency. 126 | * You probably don't *need* it. 127 | 128 | ## 1.9.2 129 | * Fixed some deprecated calls to restore performance times. 130 | * Toggles were taking as long as 1 second to load with the deprecation 131 | stack. 132 | * This fix restores toggle times back down to 15-40ms! 133 | 134 | ## 1.9.1 135 | * Fixing CHANGELOG.md. Had wrong versions. 136 | * I goofed the branches up a bit. 137 | 138 | ## 1.9.0 139 | * Makes the camel case + underscore regex match pattern the new default for Jumpy! 140 | * This affords much better jump accuracy at no cost. 141 | * If you prefer the old default (can't imagine why) set the old pattern with the custom match pattern setting to: 142 | '([\\w]){2,}' 143 | * In the future I will probably support {}'s and other similar operators that need jumping to. 144 | Let me know if you have a tested regex that I can use! 145 | 146 | ## 1.8.3 147 | * Fixes a bug where labels after zz were getting labeled as 'undefined'. 148 | * Uses patterns like Aa-> Zz for the next 676 and then aA -> zZ for the next. 149 | * Updates README.md's jumpy.gif. 150 | * Adds new settings example image that contains .85 font, high contrast, 151 | and camel case match pattern. 152 | 153 | ## 1.8.2 154 | * Updating README.md with new suggested match pattern regex override. 155 | * This regex pattern can detect camel casing and underscore separated variable names. 156 | * It has some dedicated spec tests as well. 157 | * More labels do not seem to get in the way. 158 | * It may become the default at some point! 159 | * Updates spec tests to test published camel case and underscore pattern. 160 | 161 | ## 1.8.1 162 | * Updating README.md and settings image. 163 | 164 | ## 1.8.0 165 | * Adds custom match patterns. I am not sure how useful this is yet. 166 | * Will be interesting to see if people find some good use cases. 167 | maybe for very particular programming languages or spoken languages etc. 168 | * Adds a placeholder spec test for camel case matching. 169 | * I would really like jumpy to detect all camel humps (and underscores) and print a label there! 170 | 171 | ## 1.7.0 172 | * Adds a warning message (usually orange) to the status bar if 173 | input does not match any labels (ie: zz, probably not on the page). 174 | This works at the input of first or second character. 175 | Effectively, Jumpy no longer clears the labels with invalid entries, 176 | but rather lets you try again. A reset (usually backspace) is only 177 | necessary if you want to undo the first entered character and restore 178 | to all of the labels. 179 | 180 | ## 1.6.0 181 | * Jump while highlighted selection. 182 | * Works with 'v' (visual mode) in vim-mode. 183 | 184 | ## 1.5.0 185 | * Jumpy now works with code folding and soft wraps (word wraps). 186 | * NOTE: vim-mode seems to have very unexpected behavior with toggles and 187 | word wraps (even with Jumpy disabled). Better behavior in insert mode! 188 | * Although there are a few more features in the pipeline planned. 189 | This completes the last of the known unexpected behavior (bugs). 190 | 191 | ## 1.4.1 192 | * Added some very useful instructions about how to bind 'f' to 193 | jumpy:toggle. This of course replaces native 'f' functionality. 194 | 195 | ## 1.4.0 196 | * Jumpy now clears irrelevant labels after the first character is 197 | entered. This helps home in on your target. 198 | 199 | ## 1.3.1 200 | * Fixes shift-enter (backward search) on find and replace's mini pane. 201 | 202 | ## 1.3.0 203 | * Adds new homing beacon feature with setting to disable. 204 | * Adds some missing spec tests. 205 | 206 | ## 0.1.7 207 | * Reset current first character entered (triggered with backspace) 208 | * Status bar updates with current first character entered 209 | * Working spec tests 210 | * No known bugs 211 | 212 | ## 0.1.0 - First Release 213 | * Every feature added 214 | * Every bug fixed 215 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 David L. Goldberg 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | default: elm typescript 2 | 3 | elm: 4 | /usr/local/bin/elm make lib/StateMachine.elm --output=dist/elm/StateMachine.js --optimize 5 | node_modules/uglify-js/bin/uglifyjs dist/elm/StateMachine.js --compress 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9",pure_getters,keep_fargs=false,unsafe_comps,unsafe' | node_modules/uglify-js/bin/uglifyjs --mangle --output=dist/elm/StateMachine.js 6 | elm-test 7 | 8 | elm-debug: 9 | /usr/local/bin/elm make lib/StateMachine.elm --output=dist/elm/StateMachine.js 10 | elm-test 11 | 12 | typescript: 13 | npm install 14 | # for now typescript gets built with atom-typescript. 15 | 16 | graph: 17 | # make graph (svg) of architecture 18 | node_modules/madge/bin/cli.js --image graph.svg ./dist 19 | 20 | test: 21 | elm-test 22 | apm test 23 | 24 | count: 25 | rg --files | grep -v \.js$ | grep -v dist | grep -v \.png$ | grep -v \.gif$ | grep -v package-lock.json | xargs wc -l | sort -n 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jumpy 2 | 3 | [![Join the chat at https://gitter.im/jumpy-atom/Lobby](https://badges.gitter.im/jumpy-atom/Lobby.svg)](https://gitter.im/jumpy-atom/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 4 | ![](https://img.shields.io/apm/dm/jumpy.svg) 5 | ![](https://img.shields.io/apm/v/jumpy.svg) 6 | [![Build Status](https://travis-ci.org/DavidLGoldberg/jumpy.svg?branch=master)](https://travis-ci.org/DavidLGoldberg/jumpy) 7 | 8 | An Atom package that creates dynamic hotkeys to jump around files and across visible panes. 9 | 10 | ## How to jump 11 | 12 | 1. Hit shift + enter 13 | 2. Choose from your presented labels: 14 | 3. Enter two characters. 15 | 4. Keep coding! 16 | 17 | [ ![Jumpy in Action! - (gif made with recordit.co)][1]](https://raw.githubusercontent.com/DavidLGoldberg/jumpy/master/_images/jumpy.gif) 18 | 19 | [1]: https://raw.githubusercontent.com/DavidLGoldberg/jumpy/master/_images/jumpy.gif 20 | 21 | ## Install 22 | On command line: 23 | ``` 24 | apm install jumpy 25 | ``` 26 | or the for the whole jumpy suite: 27 | ``` 28 | apm install jumpy jumpy-beacon 29 | ``` 30 | 31 | ## Notes 32 | 33 | * Works great with or without [vim-mode](https://github.com/atom/vim-mode "vim-mode's Homepage") or [vim-mode-plus](https://atom.io/packages/vim-mode-plus "vim-mode-plus's Homepage")! 34 | * Vim modes supported: 35 | * command mode 36 | * insert mode 37 | * visual mode (expands selections with v or V) 38 | * Recommended key mappings to replace 'f' in vim-mode see 'Settings' below. 39 | 40 | ## Key Bindings 41 | 42 | ### Defaults 43 | 44 | * Enter jump mode 45 | * shift + enter 46 | _**NOTE:** This particular hotkey conflicts with the very awesome [Hydrogen package](https://nteract.io/atom). 47 | Please rebind jump mode to something else or override it for Jumpy (see below)_ 48 | * Reset first character entered 49 | * backspace 50 | * Cancel/exit jump mode (any) 51 | * shift + enter 52 | * enter 53 | * esc 54 | * space 55 | 56 | ## Settings 57 | 58 | ### Jumpy preferences 59 | 60 | ( Preferences cmd+, ) -> search for 'jumpy' 61 | 62 | * **Font Size**: 63 | If set, must be a decimal value less than 1. 64 | * **High Contrast**: 65 | If checked, uses a more colorful and fun (usually green) label. 66 | * **Match Pattern**: 67 | Provide a custom regex to match labels with. 68 | * **Use Homing Beacon Effect On Jumps**: 69 | If left on, will display a homing beacon (usually red) after all jumps. 70 | 71 | ![Jumpy settings](https://raw.githubusercontent.com/DavidLGoldberg/jumpy/master/_images/jumpy-settings.png) 72 | 73 | *Example*: 74 | 75 | ![Jumpy example](https://raw.githubusercontent.com/DavidLGoldberg/jumpy/master/_images/jumpy-high-contrast-font-camel.png) 76 | 77 | (image after settings set to .85 font size, high contrast, and default camel case matching pattern) 78 | 79 | ### 'vim-mode/vim-mode-plus' Users (Strongly Recommended Override) 80 | 81 | Put this override in your **'Atom'** -> **'Keymap...'** settings: 82 | 83 | 'atom-text-editor:not(.mini).vim-mode:not(.insert-mode):not(.jumpy-jump-mode), .tree-view': 84 | 'f': 'jumpy:toggle' 85 | 86 | or if `vim-mode-plus`: 87 | 88 | 'atom-text-editor:not(.mini).vim-mode-plus:not(.insert-mode):not(.jumpy-jump-mode), .tree-view': 89 | 'f': 'jumpy:toggle' 90 | 91 | This will **bind 'f' to toggle Jumpy**. 92 | 93 | This is not the default because it **changes vim's native behavior**. 94 | Instead, with Jumpy, after jumping to the nearest word, you can easily word or character jump over to your target. 95 | The [Vimium chrome extension](https://chrome.google.com/webstore/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb?hl=en) chose this binding. 96 | Please let me know what you think about this binding for Jumpy [here](https://discuss.atom.io/t/introducing-jumpy-new-package/10980/28)! 97 | 98 | ### 'hydrogen' Users 99 | If you want to use the original keybinding for Jumpy it's shift+enter. Hydrogen overrides this to simulate the Jupyter notebook behavior. 100 | Put this override in your **'Atom'** -> **'Keymap...'** settings: 101 | 102 | 'atom-workspace atom-text-editor:not(.mini)': 103 | 'shift-enter': 'jumpy:toggle' 104 | 105 | _This is less necessary for vim-mode users because of above binding, although setting up a binding like this will allow jumps from insert mode as well!_ 106 | 107 | ### Jumpy Styles 108 | 109 | Note: Styles can be overridden in **'Atom' -> 'Open Your Stylesheet'** 110 | (see examples below) 111 | 112 | ```less 113 | atom-text-editor { 114 | .jumpy-label { 115 | // Regular labels 116 | background-color: black; 117 | color: white; 118 | &.high-contrast { 119 | // High Contrast labels (activated in settings) 120 | background-color: green; 121 | } 122 | } 123 | } 124 | ``` 125 | 126 | ## My other Atom packages :) 127 | 128 | * [Jumpy-beacon](https://atom.io/packages/jumpy-beacon) 129 | * [Back-jumpy](https://atom.io/packages/back-jumpy) (WIP) 130 | * [Qolor](https://atom.io/packages/qolor) 131 | 132 | ## My VS Code version of Jumpy :)) 133 | 134 | * [Jumpy2](https://marketplace.visualstudio.com/items?itemName=DavidLGoldberg.jumpy2) (Jumpy for VS Code from it's original author!) 135 | 136 | ## Keywords 137 | 138 | (A little SEO juice) 139 | 140 | * Shortcuts 141 | * Navigation 142 | * Productivity 143 | * Mouseless 144 | * Plugin 145 | * Extension 146 | -------------------------------------------------------------------------------- /_images/jumpy-high-contrast-font-camel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidLGoldberg/jumpy/2c1080a66d49255c8e3b0ac03398cb95ecd61393/_images/jumpy-high-contrast-font-camel.png -------------------------------------------------------------------------------- /_images/jumpy-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidLGoldberg/jumpy/2c1080a66d49255c8e3b0ac03398cb95ecd61393/_images/jumpy-settings.png -------------------------------------------------------------------------------- /_images/jumpy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidLGoldberg/jumpy/2c1080a66d49255c8e3b0ac03398cb95ecd61393/_images/jumpy.gif -------------------------------------------------------------------------------- /coffeelint.json: -------------------------------------------------------------------------------- 1 | { 2 | "arrow_spacing": { 3 | "level": "ignore" 4 | }, 5 | "camel_case_classes": { 6 | "level": "error" 7 | }, 8 | "coffeescript_error": { 9 | "level": "error" 10 | }, 11 | "colon_assignment_spacing": { 12 | "level": "ignore", 13 | "spacing": { 14 | "left": 0, 15 | "right": 0 16 | } 17 | }, 18 | "cyclomatic_complexity": { 19 | "value": 10, 20 | "level": "ignore" 21 | }, 22 | "duplicate_key": { 23 | "level": "error" 24 | }, 25 | "empty_constructor_needs_parens": { 26 | "level": "ignore" 27 | }, 28 | "indentation": { 29 | "value": 4, 30 | "level": "error" 31 | }, 32 | "line_endings": { 33 | "level": "ignore", 34 | "value": "unix" 35 | }, 36 | "max_line_length": { 37 | "value": 80, 38 | "level": "error", 39 | "limitComments": true 40 | }, 41 | "missing_fat_arrows": { 42 | "level": "ignore" 43 | }, 44 | "newlines_after_classes": { 45 | "value": 3, 46 | "level": "ignore" 47 | }, 48 | "no_backticks": { 49 | "level": "error" 50 | }, 51 | "no_debugger": { 52 | "level": "warn" 53 | }, 54 | "no_empty_functions": { 55 | "level": "ignore" 56 | }, 57 | "no_empty_param_list": { 58 | "level": "ignore" 59 | }, 60 | "no_implicit_braces": { 61 | "level": "ignore", 62 | "strict": true 63 | }, 64 | "no_implicit_parens": { 65 | "strict": true, 66 | "level": "ignore" 67 | }, 68 | "no_interpolation_in_single_quotes": { 69 | "level": "ignore" 70 | }, 71 | "no_plusplus": { 72 | "level": "ignore" 73 | }, 74 | "no_stand_alone_at": { 75 | "level": "ignore" 76 | }, 77 | "no_tabs": { 78 | "level": "error" 79 | }, 80 | "no_throwing_strings": { 81 | "level": "error" 82 | }, 83 | "no_trailing_semicolons": { 84 | "level": "error" 85 | }, 86 | "no_trailing_whitespace": { 87 | "level": "error", 88 | "allowed_in_comments": false, 89 | "allowed_in_empty_lines": true 90 | }, 91 | "no_unnecessary_double_quotes": { 92 | "level": "ignore" 93 | }, 94 | "no_unnecessary_fat_arrows": { 95 | "level": "warn" 96 | }, 97 | "non_empty_constructor_needs_parens": { 98 | "level": "ignore" 99 | }, 100 | "space_operators": { 101 | "level": "ignore" 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /dist/elm/StateMachine.js: -------------------------------------------------------------------------------- 1 | !function(n){"use strict";function r(n,r,t){return t.a=n,t.f=r,t}function t(t){return r(2,t,function(r){return function(n){return t(r,n)}})}function u(u){return r(3,u,function(t){return function(r){return function(n){return u(t,r,n)}}})}function e(e){return r(4,e,function(u){return function(t){return function(r){return function(n){return e(u,t,r,n)}}}})}function i(i){return r(5,i,function(e){return function(u){return function(t){return function(r){return function(n){return i(e,u,t,r,n)}}}}})}function b(n,r,t){return 2===n.a?n.f(r,t):n(r)(t)}function c(n,r,t,u){return 3===n.a?n.f(r,t,u):n(r)(t)(u)}function s(n,r,t,u,e){return 4===n.a?n.f(r,t,u,e):n(r)(t)(u)(e)}function f(n,r,t,u,e,i){return 5===n.a?n.f(r,t,u,e,i):n(r)(t)(u)(e)(i)}var l={$:0};function h(n,r){return{$:1,a:n,b:r}}var a=t(h);function d(n){for(var r=l,t=n.length;t--;)r=h(n[t],r);return r}function o(n,r,t){if("object"!=typeof n)return n===r?0:nJumpy: "+n+""})}),Pn=_("activeChanged",R),zn=R,Dn=_("labelJumped",zn),Hn=_("statusChanged",zn),Qn=_("validKeyEntered",zn),Un=function(n){return p(n,Gn(d([Pn(n.p),Hn(n.t),Qn(n.w)])))},Wn=function(n){return $(n,{w:""})},Zn=function(n){return $(n,{t:"
Jumpy: Jump Mode!
"})},_n=function(n){return function(n){return $(n,{t:""})}(Wn($(n,{p:!1})))},nr=function(n){return g(n<0||1114111Jumpy: No Match! 😞"})}(r));switch(ur(r.w)){case 0:return Un(b(Kn,t,$(r,{w:u})));case 1:return function(n){return p(n,Gn(d([Pn(n.p),Hn(n.t),Dn(n.T)])))}(_n($(r,{T:u})));default:return p(r,Vn)}case 1:return r.p?Un(Zn(Wn(r))):p(r,Vn);case 0:return Un(function(n){return Zn($(n,{p:!0}))}($(r,{S:n.a})));default:return Un(_n(r))}var i}),fr=t(function(n){return n}),ar=Q,or=function(n){return{$:0,a:n}},cr=P({aO:function(){return p({p:!1,w:"",S:l,T:"",t:""},Vn)},aV:function(){return ar(d([Fn(cn),Xn(on),Yn(fr(sn)),qn(fr(an))]))},aX:ir});fn={StateMachine:{init:cr(or({}))(0)}},n.Elm?function n(r,t){for(var u in t)u in r?"init"==u?w(6):n(r[u],t[u]):r[u]=t[u]}(n.Elm,fn):n.Elm=fn}(this); -------------------------------------------------------------------------------- /dist/jumpy-view.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 'use babel'; 3 | Object.defineProperty(exports, "__esModule", { value: true }); 4 | // TODO: Merge in @johngeorgewright's code for treeview 5 | // TODO: Merge in @willdady's code for better accuracy. 6 | /* global atom */ 7 | const atom_1 = require("atom"); 8 | const _ = require("lodash"); 9 | const words_1 = require("./labelers/words"); 10 | const tabs_1 = require("./labelers/tabs"); 11 | const tree_items_1 = require("./labelers/tree-items"); 12 | const label_reducer_1 = require("./label-reducer"); 13 | const keys_1 = require("./keys"); 14 | const viewHelpers_1 = require("./viewHelpers"); 15 | class JumpyView { 16 | constructor(serializedState, stateMachine) { 17 | this.workspaceElement = atom.views.getView(atom.workspace); 18 | this.disposables = new atom_1.CompositeDisposable(); 19 | this.drawnLabels = []; 20 | this.commands = new atom_1.CompositeDisposable(); 21 | this.stateMachine = stateMachine; 22 | this.setSettings(); 23 | // Subscribe: 24 | this.stateMachine.ports.validKeyEntered.subscribe((keyLabel) => { 25 | for (const label of this.drawnLabels) { 26 | if (!label.keyLabel || !label.element) { 27 | continue; 28 | } 29 | if (!label.keyLabel.startsWith(keyLabel)) { 30 | label.element.classList.add('irrelevant'); 31 | } 32 | } 33 | this.currentLabels = label_reducer_1.default(this.currentLabels, keyLabel); 34 | }); 35 | this.stateMachine.ports.labelJumped.subscribe((keyLabel) => { 36 | _.find(this.currentLabels, (label) => label.keyLabel === keyLabel).jump(); 37 | }); 38 | this.stateMachine.ports.activeChanged.subscribe((active) => { 39 | this.active = active; 40 | if (!this.active) { 41 | this.turnOffListeners(); 42 | this.clearJumpMode(); 43 | } 44 | }); 45 | this.stateMachine.ports.statusChanged.subscribe((statusMarkup) => { 46 | if (this.statusBarElement) { 47 | this.statusBarElement.innerHTML = statusMarkup; 48 | } 49 | }); 50 | this.keydownListener = (event) => { 51 | // use the code property for testing if 52 | // the key is relevant to Jumpy 53 | // that is, that it's an alpha char. 54 | // use the key character to pass the exact key 55 | // that is, (upper or lower) to the state machine. 56 | // if jumpy catches it...stop the event propagation. 57 | const { code, key, metaKey, ctrlKey, altKey } = event; 58 | if (metaKey || ctrlKey || altKey) { 59 | return; 60 | } 61 | if (/^Key[A-Z]{1}$/.test(code)) { 62 | event.preventDefault(); 63 | event.stopPropagation(); 64 | this.stateMachine.ports.key.send(key.charCodeAt()); 65 | } 66 | }; 67 | this.commands.add(atom.commands.add('atom-workspace', { 68 | 'jumpy:toggle': () => { this.toggle(); }, 69 | 'jumpy:reset': () => { this.reset(); }, 70 | 'jumpy:clear': () => { 71 | this.stateMachine.ports.exit.send(null); 72 | } 73 | })); 74 | } 75 | initializeStatusBar() { 76 | // NOTE: This needs to be called when status bar is ready, so can't be called from constructor 77 | if (this.statusBarElement) { 78 | return; 79 | } 80 | const atomStatusBar = document.querySelector('status-bar'); 81 | if (atomStatusBar) { 82 | const statusBarElement = document.createElement('div'); 83 | this.statusBarElement = statusBarElement; 84 | statusBarElement.id = 'status-bar-jumpy-container'; 85 | statusBarElement.classList.add('inline-block'); 86 | statusBarElement.innerHTML = "
Jumpy: Jump Mode!
"; 87 | atomStatusBar.addLeftTile({ 88 | item: statusBarElement, 89 | priority: -1 90 | }); 91 | } 92 | } 93 | setSettings() { 94 | let fontSize = atom.config.get('jumpy.fontSize'); 95 | if (isNaN(fontSize) || fontSize > 1) { 96 | fontSize = .75; // default 97 | } 98 | const fontSizeString = `${fontSize * 100}%`; 99 | this.settings = { 100 | fontSize: fontSizeString, 101 | highContrast: atom.config.get('jumpy.highContrast'), 102 | wordsPattern: new RegExp(atom.config.get('jumpy.matchPattern'), 'g') 103 | }; 104 | } 105 | reset() { 106 | this.currentLabels = _.clone(this.allLabels); 107 | for (const label of this.currentLabels) { 108 | if (label.element) { 109 | label.element.classList.remove('irrelevant'); 110 | } 111 | } 112 | this.stateMachine.ports.reset.send(null); 113 | } 114 | loadLabels() { 115 | const environment = { 116 | keys: keys_1.getKeySet(atom.config.get('jumpy.customKeys')), 117 | settings: this.settings 118 | }; 119 | // TODO: reduce with concat all labelers -> labeler.getLabels() 120 | const wordLabels = words_1.default(environment); 121 | const tabLabels = tabs_1.default(environment); 122 | const treeItemLabels = tree_items_1.default(environment); 123 | // TODO: I really think alllabels can just be drawnlabels 124 | // maybe I call labeler.draw() still returns back anyway? Less functional? 125 | this.allLabels = [ 126 | ...wordLabels, 127 | ...tabLabels, 128 | ...treeItemLabels 129 | ]; 130 | for (const label of this.allLabels) { 131 | this.drawnLabels.push(label.drawLabel()); 132 | } 133 | this.currentLabels = _.clone(this.allLabels); 134 | this.stateMachine.ports.getLabels.send(this.currentLabels 135 | .filter((label) => label.keyLabel) // ie. tabs open after limit reached 136 | .map((label) => label.keyLabel)); 137 | } 138 | toggle() { 139 | if (!this.active) { 140 | this.loadLabels(); 141 | this.initializeStatusBar(); 142 | this.turnOnListeners(); 143 | } 144 | else { 145 | this.stateMachine.ports.exit.send(null); 146 | } 147 | } 148 | turnOnListeners() { 149 | this.workspaceElement.addEventListener('keydown', this.keydownListener, true); 150 | for (const e of ['blur', 'click', 'scroll']) { 151 | this.workspaceElement.addEventListener(e, () => this.clearJumpModeHandler(), true); 152 | } 153 | } 154 | turnOffListeners() { 155 | this.workspaceElement.removeEventListener('keydown', this.keydownListener, true); 156 | for (const e of ['blur', 'click', 'scroll']) { 157 | this.workspaceElement.removeEventListener(e, () => this.clearJumpModeHandler(), true); 158 | } 159 | } 160 | clearJumpModeHandler() { 161 | this.stateMachine.ports.exit.send(null); 162 | this.clearJumpMode(); 163 | } 164 | clearJumpMode() { 165 | const clearAllLabels = () => { 166 | for (const label of this.drawnLabels) { 167 | label.destroy(); 168 | } 169 | this.drawnLabels = []; // Very important for GC. 170 | // Verifiable in Dev Tools -> Timeline -> Nodes. 171 | }; 172 | this.allLabels = []; 173 | const treeView = document.getElementsByClassName('tree-view'); 174 | if (treeView.length) { 175 | viewHelpers_1.removeJumpModeClasses(treeView[0]); 176 | } 177 | for (const editor of atom.workspace.getTextEditors()) { 178 | const editorView = atom.views.getView(editor); 179 | viewHelpers_1.removeJumpModeClasses(editorView); 180 | } 181 | clearAllLabels(); 182 | if (this.disposables) { 183 | this.disposables.dispose(); 184 | } 185 | } 186 | // Returns an object that can be retrieved when package is activated 187 | serialize() { } 188 | // Tear down any state and detach 189 | destroy() { 190 | if (this.commands) { 191 | this.commands.dispose(); 192 | } 193 | this.clearJumpMode(); 194 | } 195 | } 196 | exports.default = JumpyView; 197 | //# sourceMappingURL=jumpy-view.js.map -------------------------------------------------------------------------------- /dist/jumpy-view.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"jumpy-view.js","sourceRoot":"","sources":["../lib/jumpy-view.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/jumpy.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 'use babel'; 3 | Object.defineProperty(exports, "__esModule", { value: true }); 4 | const elmApp = require("../dist/elm/StateMachine"); 5 | const jumpy_view_1 = require("./jumpy-view"); 6 | module.exports = { 7 | jumpyView: null, 8 | config: { 9 | fontSize: { 10 | description: 'The font size of jumpy labels.', 11 | type: 'number', 12 | default: .75, 13 | minimum: 0, 14 | maximum: 1 15 | }, 16 | highContrast: { 17 | description: 'This will display a high contrast label, \ 18 | usually green. It is dynamic per theme.', 19 | type: 'boolean', 20 | default: false 21 | }, 22 | useHomingBeaconEffectOnJumps: { 23 | description: 'This will animate a short lived homing beacon upon \ 24 | jump.', 25 | type: 'boolean', 26 | default: true 27 | }, 28 | matchPattern: { 29 | description: 'Jumpy will create labels based on this pattern.', 30 | type: 'string', 31 | default: '([A-Z]+([0-9a-z])*)|[a-z0-9]{2,}' 32 | }, 33 | customKeys: { 34 | description: 'Jumpy will use these characters in the specifed order to create labels (comma separated)', 35 | type: 'array', 36 | default: [] 37 | } 38 | }, 39 | activate(state) { 40 | const stateMachine = elmApp.Elm.StateMachine.init(); 41 | this.jumpyView = new jumpy_view_1.default(state.jumpyViewState, stateMachine); 42 | }, 43 | deactivate() { 44 | if (this.jumpyView) { 45 | this.jumpyView.destroy(); 46 | } 47 | this.jumpyView = null; 48 | }, 49 | serialize() { 50 | return { 51 | jumpyViewState: this.jumpyView.serialize(), 52 | }; 53 | } 54 | }; 55 | //# sourceMappingURL=jumpy.js.map -------------------------------------------------------------------------------- /dist/jumpy.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"jumpy.js","sourceRoot":"","sources":["../lib/jumpy.ts"],"names":[],"mappings":";AAAA,WAAW,CAAC;;AAEZ,mDAAmD;AACnD,6CAAqC;AAErC,MAAM,CAAC,OAAO,GAAG;IAEb,SAAS,EAAE,IAAI;IACf,MAAM,EAAE;QACJ,QAAQ,EAAE;YACN,WAAW,EAAE,gCAAgC;YAC7C,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,GAAG;YACZ,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,CAAC;SACb;QACD,YAAY,EAAE;YACV,WAAW,EAAE;qDAC4B;YACzC,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK;SACjB;QACD,4BAA4B,EAAE;YAC1B,WAAW,EAAE;kBACP;YACN,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,IAAI;SAChB;QACD,YAAY,EAAE;YACV,WAAW,EAAE,iDAAiD;YAC9D,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,kCAAkC;SAC9C;QACD,UAAU,EAAE;YACV,WAAW,EAAE,0FAA0F;YACvG,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,EAAE;SACZ;KACJ;IAED,QAAQ,CAAC,KAAU;QACf,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QACpD,IAAI,CAAC,SAAS,GAAG,IAAI,oBAAS,CAAC,KAAK,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IACvE,CAAC;IAED,UAAU;QACN,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;YACjB,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IAC1B,CAAC;IAED,SAAS;QACL,MAAM,CAAC;YACH,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE;SAC7C,CAAC;IACN,CAAC;CACJ,CAAC"} -------------------------------------------------------------------------------- /dist/keys.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 'use babel'; 3 | Object.defineProperty(exports, "__esModule", { value: true }); 4 | const _ = require("lodash"); 5 | function getKeySet(customKeys) { 6 | let lowerCharacters = []; 7 | let upperCharacters = []; 8 | if (!customKeys.length) { 9 | lowerCharacters = _.range('a'.charCodeAt(0), 'z'.charCodeAt(0) + 1 /* for inclusive*/) 10 | .map(c => String.fromCharCode(c)); 11 | upperCharacters = _.range('A'.charCodeAt(0), 'Z'.charCodeAt(0) + 1 /* for inclusive*/) 12 | .map(c => String.fromCharCode(c)); 13 | } 14 | else { 15 | for (let key of customKeys) { 16 | lowerCharacters.push(key.toLowerCase()); 17 | upperCharacters.push(key.toUpperCase()); 18 | } 19 | } 20 | const keys = []; 21 | // A little ugly. 22 | // I used itertools.permutation in python. 23 | // Couldn't find a good one in npm. Don't worry this takes < 1ms once. 24 | // TODO: try a zip? and or make a func 25 | for (let c1 of lowerCharacters) { 26 | for (let c2 of lowerCharacters) { 27 | keys.push(c1 + c2); 28 | } 29 | } 30 | for (let c1 of upperCharacters) { 31 | for (let c2 of lowerCharacters) { 32 | keys.push(c1 + c2); 33 | } 34 | } 35 | for (let c1 of lowerCharacters) { 36 | for (let c2 of upperCharacters) { 37 | keys.push(c1 + c2); 38 | } 39 | } 40 | // TODO: use TS's ReadonlyArray? 41 | return keys; 42 | } 43 | exports.getKeySet = getKeySet; 44 | //# sourceMappingURL=keys.js.map -------------------------------------------------------------------------------- /dist/keys.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"keys.js","sourceRoot":"","sources":["../lib/keys.ts"],"names":[],"mappings":";AAAA,WAAW,CAAC;;AAEZ,4BAA4B;AAE5B,mBAA0B,UAAyB;IAC/C,IAAI,eAAe,GAAkB,EAAE,CAAC;IACxC,IAAI,eAAe,GAAkB,EAAE,CAAC;IAExC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;QACrB,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,kBAAkB,CAAC;aACjF,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,kBAAkB,CAAC;aACjF,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IAAC,IAAI,CAAC,CAAC;QACJ,GAAG,CAAC,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC;YACzB,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;YACxC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QAC5C,CAAC;IACL,CAAC;IAED,MAAM,IAAI,GAAkB,EAAE,CAAC;IAE/B,iBAAiB;IACjB,0CAA0C;IAC1C,uEAAuE;IACvE,sCAAsC;IACtC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;QAC7B,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACvB,CAAC;IACL,CAAC;IACD,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;QAC7B,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACvB,CAAC;IACL,CAAC;IACD,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;QAC7B,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,eAAe,CAAC,CAAC,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACvB,CAAC;IACL,CAAC;IAED,gCAAgC;IAChC,MAAM,CAAC,IAAI,CAAC;AAChB,CAAC;AAxCD,8BAwCC"} -------------------------------------------------------------------------------- /dist/label-interface.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | //# sourceMappingURL=label-interface.js.map -------------------------------------------------------------------------------- /dist/label-interface.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"label-interface.js","sourceRoot":"","sources":["../lib/label-interface.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /dist/label-reducer.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 'use babel'; 3 | Object.defineProperty(exports, "__esModule", { value: true }); 4 | // (PURE FUNCTION) 5 | // 6 | // WHEN GIVEN: 7 | // 8 | // 1. AN ARRAY OF LABELS (* SEE BELOW) 9 | // (and) 10 | // 2. A NEW INPUT KEY 11 | // 12 | // RETURNS new collection of labels 13 | // *without* the labels that do not start with the current key 14 | function labelReducer(labels, currentKey) { 15 | return labels.filter(function (label) { 16 | if (!label.keyLabel) { 17 | return false; 18 | } 19 | return label.keyLabel.startsWith(currentKey); 20 | }); 21 | } 22 | exports.default = labelReducer; 23 | //# sourceMappingURL=label-reducer.js.map -------------------------------------------------------------------------------- /dist/label-reducer.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"label-reducer.js","sourceRoot":"","sources":["../lib/label-reducer.ts"],"names":[],"mappings":";AAAA,WAAW,CAAC;;AAIZ,kBAAkB;AAClB,EAAE;AACF,cAAc;AACd,EAAE;AACF,4CAA4C;AAC5C,aAAa;AACb,0BAA0B;AAC1B,EAAE;AACF,mCAAmC;AACnC,8DAA8D;AAE9D,sBAAsC,MAAoB,EAAE,UAAmB;IAC3E,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAS,KAAa;QACvC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAClB,MAAM,CAAC,KAAK,CAAC;QACjB,CAAC;QACD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACP,CAAC;AAPD,+BAOC"} -------------------------------------------------------------------------------- /dist/labelers/tabs.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 'use babel'; 3 | Object.defineProperty(exports, "__esModule", { value: true }); 4 | const atom_1 = require("atom"); 5 | class TabLabel { 6 | destroy() { 7 | if (this.element) { 8 | this.element.remove(); 9 | } 10 | } 11 | drawLabel() { 12 | const tabsPane = atom.workspace.paneForItem(this.textEditor); 13 | const tabsPaneElement = atom.views.getView(tabsPane); 14 | const foundTab = tabsPaneElement 15 | .querySelector(`[data-path='${this.textEditor.getPath()}']`); 16 | if (!foundTab) { 17 | return this; 18 | } 19 | const labelElement = document.createElement('div'); 20 | if (this.keyLabel) { 21 | labelElement.textContent = this.keyLabel; 22 | } 23 | labelElement.style.position = 'fixed'; 24 | labelElement.classList.add('jumpy-label'); // For styling and tests 25 | labelElement.classList.add('tab-label'); 26 | labelElement.style.fontSize = this.settings.fontSize; 27 | if (this.settings.highContrast) { 28 | labelElement.classList.add('high-contrast'); 29 | } 30 | this.element = labelElement; 31 | foundTab.appendChild(labelElement); 32 | return this; 33 | } 34 | animateBeacon() { 35 | // TODO: abstract function to find tab! 36 | const tabsPane = atom.workspace.paneForItem(this.textEditor); 37 | const tabsPaneElement = atom.views.getView(tabsPane); 38 | const foundTab = tabsPaneElement 39 | .querySelector(`[data-path='${this.textEditor.getPath()}'`); 40 | if (foundTab) { 41 | const beacon = document.createElement('span'); 42 | beacon.style.position = 'relative'; 43 | beacon.style.zIndex = '4'; 44 | beacon.classList.add('beacon'); // For styling and tests 45 | beacon.classList.add('tab-beacon'); 46 | foundTab.appendChild(beacon); 47 | setTimeout(function () { 48 | beacon.remove(); 49 | }, 150); 50 | } 51 | } 52 | jump() { 53 | const pane = atom.workspace.paneForItem(this.textEditor); 54 | pane.activate(); 55 | pane.activateItem(this.textEditor); 56 | if (atom.config.get('jumpy.useHomingBeaconEffectOnJumps')) { 57 | this.animateBeacon(); 58 | } 59 | } 60 | } 61 | const labeler = function (env) { 62 | const labels = []; 63 | for (const textEditor of atom.workspace.getPaneItems()) { 64 | if (!(textEditor instanceof atom_1.TextEditor) || !textEditor.buffer) { 65 | continue; 66 | } 67 | const keyLabel = env.keys.shift(); 68 | const label = new TabLabel(); 69 | label.settings = env.settings; 70 | label.keyLabel = keyLabel; 71 | label.textEditor = textEditor; 72 | labels.push(label); 73 | } 74 | return labels; 75 | }; 76 | exports.default = labeler; 77 | //# sourceMappingURL=tabs.js.map -------------------------------------------------------------------------------- /dist/labelers/tabs.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../lib/labelers/tabs.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/labelers/tree-items.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 'use babel'; 3 | Object.defineProperty(exports, "__esModule", { value: true }); 4 | const viewHelpers_1 = require("../viewHelpers"); 5 | class TreeItemLabel { 6 | destroy() { 7 | if (this.element) { 8 | this.element.remove(); 9 | } 10 | } 11 | drawLabel() { 12 | const labelElement = document.createElement('div'); 13 | if (this.keyLabel) { 14 | labelElement.textContent = this.keyLabel; 15 | } 16 | labelElement.style.position = 'absolute'; 17 | labelElement.classList.add('jumpy-label'); // For styling and tests 18 | labelElement.classList.add('tree-item-label'); 19 | labelElement.style.fontSize = this.settings.fontSize; 20 | if (this.settings.highContrast) { 21 | labelElement.classList.add('high-contrast'); 22 | } 23 | this.element = labelElement; 24 | const parent = this.item.parentElement; 25 | if (parent) { 26 | parent.appendChild(labelElement); 27 | } 28 | return this; 29 | } 30 | animateBeacon() { 31 | const beacon = document.createElement('span'); 32 | beacon.style.position = 'relative'; 33 | beacon.style.zIndex = '4'; 34 | beacon.classList.add('beacon'); // For styling and tests 35 | beacon.classList.add('tree-item-beacon'); 36 | this.item.appendChild(beacon); 37 | setTimeout(function () { 38 | beacon.remove(); 39 | }, 150); 40 | } 41 | jump() { 42 | function triggerMouseEvent(element, eventType) { 43 | var clickEvent = new MouseEvent("click", { 44 | bubbles: true, 45 | cancelable: true, 46 | view: window 47 | }); 48 | element.dispatchEvent(clickEvent); 49 | } 50 | const treeItem = this.item.parentElement; 51 | if (treeItem) { 52 | // TODO: use only 1 of these with a guard statement. 53 | atom.commands.dispatch(treeItem, 'tree-view:toggle-focus'); 54 | triggerMouseEvent(treeItem, 'mousedown'); 55 | atom.commands.dispatch(treeItem, 'tree-view:toggle-focus'); 56 | } 57 | // this.item.parentElement.click(); 58 | if (atom.config.get('jumpy.useHomingBeaconEffectOnJumps')) { 59 | this.animateBeacon(); 60 | } 61 | } 62 | } 63 | const labeler = function (env) { 64 | const labels = []; 65 | // just here for hotkey cascading: 66 | const treeView = document.querySelector('.tree-view'); 67 | if (treeView) { 68 | viewHelpers_1.addJumpModeClasses(treeView); 69 | } 70 | const treeItems = document.querySelectorAll('.tree-view-root .directory .list-item .name'); 71 | for (const treeItem of treeItems) { 72 | const keyLabel = env.keys.shift(); 73 | const label = new TreeItemLabel(); 74 | label.settings = env.settings; 75 | label.keyLabel = keyLabel; 76 | label.item = treeItem; 77 | labels.push(label); 78 | } 79 | return labels; 80 | }; 81 | exports.default = labeler; 82 | //# sourceMappingURL=tree-items.js.map -------------------------------------------------------------------------------- /dist/labelers/tree-items.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"tree-items.js","sourceRoot":"","sources":["../../lib/labelers/tree-items.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/labelers/words.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 'use babel'; 3 | Object.defineProperty(exports, "__esModule", { value: true }); 4 | const _ = require("lodash"); 5 | const viewHelpers_1 = require("../viewHelpers"); 6 | const atom_1 = require("atom"); 7 | function getVisibleColumnRange(editorView) { 8 | const charWidth = editorView.getDefaultCharacterWidth(); 9 | // FYI: asserts: 10 | // numberOfVisibleColumns = editorView.getWidth() / charWidth 11 | const minColumn = (editorView.getScrollLeft() / charWidth) - 1; 12 | const maxColumn = editorView.getScrollRight() / charWidth; 13 | return [ 14 | minColumn, 15 | maxColumn 16 | ]; 17 | } 18 | // Taken from jQuery: https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js 19 | function isVisible(element) { 20 | return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length); 21 | } 22 | class WordLabel { 23 | destroy() { 24 | this.marker.destroy(); 25 | } 26 | drawLabel() { 27 | const { textEditor, lineNumber, column, keyLabel } = this; 28 | this.marker = textEditor.markScreenRange(new atom_1.Range(new atom_1.Point(lineNumber, column), new atom_1.Point(lineNumber, column)), { invalidate: 'touch' }); 29 | const labelElement = document.createElement('div'); 30 | labelElement.textContent = keyLabel; 31 | labelElement.style.fontSize = this.settings.fontSize; 32 | labelElement.classList.add('jumpy-label'); // For styling and tests 33 | if (this.settings.highContrast) { 34 | labelElement.classList.add('high-contrast'); 35 | } 36 | const decoration = textEditor.decorateMarker(this.marker, { 37 | type: 'overlay', 38 | item: labelElement, 39 | position: 'head' 40 | }); 41 | this.element = labelElement; 42 | return this; 43 | } 44 | animateBeacon(input) { 45 | const position = input; 46 | const range = atom_1.Range(position, position); 47 | const marker = this.textEditor.markScreenRange(range, { invalidate: 'never' }); 48 | const beacon = document.createElement('span'); 49 | beacon.classList.add('beacon'); // For styling and tests 50 | this.textEditor.decorateMarker(marker, { 51 | item: beacon, 52 | type: 'overlay' 53 | }); 54 | setTimeout(function () { 55 | marker.destroy(); 56 | }, 150); 57 | } 58 | jump() { 59 | const currentEditor = this.textEditor; 60 | const editorView = atom.views.getView(currentEditor); 61 | // TODO: pretty sure this can't be useful...anymore 62 | // I think it had somethign to do with the observers etc. 63 | // Prevent other editors from jumping cursors as well 64 | // TODO: make a test for this if return 65 | if (currentEditor.id !== this.textEditor.id) { 66 | return; 67 | } 68 | const pane = atom.workspace.paneForItem(currentEditor); 69 | pane.activate(); 70 | // isVisualMode is for vim-mode or vim-mode-plus: 71 | const isVisualMode = editorView.classList.contains('visual-mode'); 72 | // isSelected is for regular selection in atom or in insert-mode in vim 73 | const isSelected = (currentEditor.getSelections().length === 1 && 74 | currentEditor.getSelectedText() !== ''); 75 | const position = atom_1.Point(this.lineNumber, this.column); 76 | if (isVisualMode || isSelected) { 77 | currentEditor.selectToScreenPosition(position); 78 | } 79 | else { 80 | currentEditor.setCursorScreenPosition(position); 81 | } 82 | if (atom.config.get('jumpy.useHomingBeaconEffectOnJumps')) { 83 | this.animateBeacon(position); 84 | } 85 | } 86 | } 87 | const labeler = function (env) { 88 | const labels = []; 89 | env.settings.wordsPattern.lastIndex = 0; // reset the RegExp for subsequent calls. 90 | for (const textEditor of atom.workspace.getTextEditors()) { 91 | const editorView = atom.views.getView(textEditor); 92 | // 'jumpy-jump-mode is for keymaps and utilized by tests 93 | viewHelpers_1.addJumpModeClasses(editorView); 94 | // current labels for current textEditor in loop. 95 | if (!env.keys.length) { 96 | continue; 97 | } 98 | const [minColumn, maxColumn] = getVisibleColumnRange(editorView); 99 | const rows = textEditor.getVisibleRowRange(); 100 | if (!rows || !isVisible(editorView)) { 101 | continue; 102 | } 103 | const [firstVisibleRow, lastVisibleRow] = rows; 104 | // TODO: Right now there are issues with lastVisbleRow 105 | for (const lineNumber of _.range(firstVisibleRow, lastVisibleRow) /*excludes end value*/) { 106 | const lineContents = textEditor.lineTextForScreenRow(lineNumber); 107 | if (textEditor.isFoldedAtScreenRow(lineNumber)) { 108 | if (!env.keys.length) { 109 | continue; // try continue? 110 | } 111 | const keyLabel = env.keys.shift(); 112 | const label = new WordLabel(); 113 | label.settings = env.settings; 114 | label.textEditor = textEditor; 115 | label.keyLabel = keyLabel; 116 | label.lineNumber = lineNumber; 117 | label.column = 0; 118 | labels.push(label); 119 | } 120 | else { 121 | let word; 122 | while ((word = env.settings.wordsPattern.exec(lineContents)) != null && env.keys.length) { 123 | const keyLabel = env.keys.shift(); 124 | const column = word.index; 125 | // Do not do anything... markers etc. 126 | // if the columns are out of bounds... 127 | if (column > minColumn && column < maxColumn) { 128 | const label = new WordLabel(); 129 | label.settings = env.settings; 130 | label.textEditor = textEditor; 131 | label.keyLabel = keyLabel; 132 | label.lineNumber = lineNumber; 133 | label.column = column; 134 | labels.push(label); 135 | } 136 | } 137 | } 138 | } // end: each line 139 | } // end: for each textEditor 140 | return labels; 141 | }; 142 | exports.default = labeler; 143 | //# sourceMappingURL=words.js.map -------------------------------------------------------------------------------- /dist/labelers/words.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"words.js","sourceRoot":"","sources":["../../lib/labelers/words.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/viewHelpers.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | function addJumpModeClasses(element) { 4 | element.classList.add('jumpy-jump-mode', 'jumpy-more-specific1', 'jumpy-more-specific2'); 5 | } 6 | exports.addJumpModeClasses = addJumpModeClasses; 7 | function removeJumpModeClasses(element) { 8 | element.classList.remove('jumpy-jump-mode', 'jumpy-more-specific1', 'jumpy-more-specific2'); 9 | } 10 | exports.removeJumpModeClasses = removeJumpModeClasses; 11 | //# sourceMappingURL=viewHelpers.js.map -------------------------------------------------------------------------------- /dist/viewHelpers.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"viewHelpers.js","sourceRoot":"","sources":["../lib/viewHelpers.ts"],"names":[],"mappings":";;AAAA,4BAAmC,OAAoB;IACnD,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,EACnC,sBAAsB,EAAE,sBAAsB,CAAC,CAAC;AACxD,CAAC;AAHD,gDAGC;AAED,+BAAsC,OAAoB;IACtD,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,iBAAiB,EACtC,sBAAsB,EAAE,sBAAsB,CAAC,CAAC;AACxD,CAAC;AAHD,sDAGC"} -------------------------------------------------------------------------------- /elm.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "application", 3 | "source-directories": [ 4 | "lib" 5 | ], 6 | "elm-version": "0.19.0", 7 | "dependencies": { 8 | "direct": { 9 | "elm/browser": "1.0.0", 10 | "elm/core": "1.0.0", 11 | "elm/html": "1.0.0", 12 | "elm/json": "1.0.0" 13 | }, 14 | "indirect": { 15 | "elm/time": "1.0.0", 16 | "elm/url": "1.0.0", 17 | "elm/virtual-dom": "1.0.0", 18 | "elm/random": "1.0.0" 19 | } 20 | }, 21 | "test-dependencies": { 22 | "direct": { 23 | "elm-explorations/test": "1.0.0" 24 | }, 25 | "indirect": {} 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /keymaps/jumpy.cson: -------------------------------------------------------------------------------- 1 | # Keybindings require three things to be fully defined: A selector that is 2 | # matched against the focused element, the keystroke and the command to 3 | # execute. 4 | # 5 | # Below is a basic keybinding which registers on all platforms by applying to 6 | # the root workspace element. 7 | 8 | # For more detailed documentation see 9 | # https://atom.io/docs/latest/advanced/keymaps 10 | 'atom-workspace atom-text-editor:not(.mini), 11 | .tree-view': 12 | 'shift-enter': 'jumpy:toggle' 13 | 14 | 'atom-workspace atom-text-editor.jumpy-jump-mode.jumpy-more-specific1.jumpy-more-specific2, 15 | .tree-view.jumpy-jump-mode.jumpy-more-specific1.jumpy-more-specific2': 16 | 'backspace': 'jumpy:reset' 17 | 'enter': 'jumpy:clear' 18 | 'space': 'jumpy:clear' 19 | 'escape': 'jumpy:clear' 20 | 'shift-enter': 'jumpy:clear' 21 | -------------------------------------------------------------------------------- /lib/StateMachine.elm: -------------------------------------------------------------------------------- 1 | port module StateMachine exposing (Flags, Labels, Model, Msg(..), activeChanged, addKeyToStatus, clearStatus, exit, getLabels, init, key, labelJumped, main, modelAndJumped, modelAndStatus, onKeyPress, reset, resetKeys, resetStatus, setNoMatchStatus, statusChanged, turnOff, turnOn, update, validKeyEntered) 2 | 3 | import Char 4 | import Html as Html exposing (..) 5 | import Html.Events as Events exposing (..) 6 | import Json.Decode as Json 7 | import List exposing (any) 8 | import String exposing (..) 9 | 10 | 11 | main : Program Flags Model Msg 12 | main = 13 | Platform.worker 14 | { init = init 15 | , update = update 16 | , subscriptions = 17 | \model -> 18 | Sub.batch 19 | [ getLabels LoadLabels 20 | , key KeyEntered 21 | , reset (Basics.always Reset) 22 | , exit (Basics.always Exit) 23 | ] 24 | } 25 | 26 | 27 | type alias Labels = 28 | List String 29 | 30 | 31 | 32 | -- Outbound 33 | 34 | 35 | port activeChanged : Bool -> Cmd msg 36 | 37 | 38 | port statusChanged : String -> Cmd msg 39 | 40 | 41 | port validKeyEntered : String -> Cmd msg 42 | 43 | 44 | port labelJumped : String -> Cmd msg 45 | 46 | 47 | 48 | -- Inbound 49 | 50 | 51 | port getLabels : (Labels -> msg) -> Sub msg 52 | 53 | 54 | port key : (Int -> msg) -> Sub msg 55 | 56 | 57 | port reset : (() -> msg) -> Sub msg 58 | 59 | 60 | port exit : (() -> msg) -> Sub msg 61 | 62 | 63 | type Msg 64 | = LoadLabels Labels 65 | | Reset 66 | | KeyEntered Int 67 | | Exit 68 | 69 | 70 | type alias Model = 71 | { active : Bool 72 | , keysEntered : String 73 | , lastJumped : String 74 | , labels : Labels 75 | , status : String 76 | } 77 | 78 | 79 | type alias Flags = 80 | {} 81 | 82 | 83 | init : Flags -> ( Model, Cmd Msg ) 84 | init flags = 85 | ( { active = False 86 | , keysEntered = "" 87 | , lastJumped = "" 88 | , labels = [] 89 | , status = "" 90 | } 91 | , Cmd.none 92 | ) 93 | 94 | 95 | onKeyPress : (Int -> msg) -> Attribute msg 96 | onKeyPress tagger = 97 | on "keypress" (Json.map tagger keyCode) 98 | 99 | 100 | clearStatus : Model -> Model 101 | clearStatus model = 102 | { model | status = "" } 103 | 104 | 105 | resetStatus : Model -> Model 106 | resetStatus model = 107 | { model | status = "
Jumpy: Jump Mode!
" } 108 | 109 | 110 | resetKeys : Model -> Model 111 | resetKeys model = 112 | { model | keysEntered = "" } 113 | 114 | 115 | turnOff : Model -> Model 116 | turnOff model = 117 | { model | active = False } 118 | |> resetKeys 119 | |> clearStatus 120 | 121 | 122 | setNoMatchStatus : Model -> Model 123 | setNoMatchStatus model = 124 | { model | status = "
Jumpy: No Match! 😞
" } 125 | 126 | 127 | addKeyToStatus : String -> Model -> Model 128 | addKeyToStatus keyEntered model = 129 | { model | status = "
Jumpy: " ++ keyEntered ++ "
" } 130 | 131 | 132 | modelAndStatus : Model -> ( Model, Cmd Msg ) 133 | modelAndStatus model = 134 | ( model 135 | , Cmd.batch 136 | [ activeChanged model.active 137 | , statusChanged model.status 138 | , validKeyEntered model.keysEntered 139 | ] 140 | ) 141 | 142 | 143 | modelAndJumped : Model -> ( Model, Cmd Msg ) 144 | modelAndJumped model = 145 | ( model 146 | , Cmd.batch 147 | [ activeChanged model.active 148 | , statusChanged model.status 149 | , labelJumped model.lastJumped 150 | ] 151 | ) 152 | 153 | 154 | turnOn : Model -> Model 155 | turnOn model = 156 | { model | active = True } 157 | |> resetStatus 158 | 159 | 160 | update : Msg -> Model -> ( Model, Cmd Msg ) 161 | update msg model = 162 | case msg of 163 | KeyEntered keyCode -> 164 | let 165 | keyEntered = 166 | keyCode |> Char.fromCode |> String.fromChar 167 | 168 | newKeysEntered = 169 | model.keysEntered ++ keyEntered 170 | 171 | keysEnteredMatch = 172 | model.labels 173 | |> List.any (\label -> startsWith newKeysEntered label) 174 | in 175 | if model.active then 176 | if not keysEnteredMatch then 177 | model 178 | |> setNoMatchStatus 179 | |> modelAndStatus 180 | 181 | else 182 | case length model.keysEntered of 183 | 0 -> 184 | -- FIRST LETTER ---------- 185 | { model | keysEntered = newKeysEntered } 186 | |> addKeyToStatus keyEntered 187 | |> modelAndStatus 188 | 189 | 1 -> 190 | -- SECOND LETTER ---------- 191 | { model | lastJumped = newKeysEntered } 192 | |> turnOff 193 | |> modelAndJumped 194 | 195 | _ -> 196 | ( model, Cmd.none ) 197 | 198 | else 199 | ( model, Cmd.none ) 200 | 201 | Reset -> 202 | if model.active then 203 | model 204 | |> resetKeys 205 | |> resetStatus 206 | |> modelAndStatus 207 | 208 | else 209 | ( model, Cmd.none ) 210 | 211 | LoadLabels labels -> 212 | { model | labels = labels } 213 | |> turnOn 214 | |> modelAndStatus 215 | 216 | Exit -> 217 | model 218 | |> turnOff 219 | |> modelAndStatus 220 | -------------------------------------------------------------------------------- /lib/jumpy-view.ts: -------------------------------------------------------------------------------- 1 | 'use babel'; 2 | 3 | // TODO: Merge in @johngeorgewright's code for treeview 4 | // TODO: Merge in @willdady's code for better accuracy. 5 | 6 | /* global atom */ 7 | import { CompositeDisposable, Point } from 'atom'; 8 | import * as _ from 'lodash'; 9 | 10 | import { LabelEnvironment, Label } from './label-interface'; 11 | import getWordLabels from './labelers/words'; 12 | import getTabLabels from './labelers/tabs'; 13 | import getTreeItemLabels from './labelers/tree-items'; 14 | import labelReducer from './label-reducer'; 15 | import { getKeySet } from './keys'; 16 | import { removeJumpModeClasses } from './viewHelpers'; 17 | 18 | export default class JumpyView { 19 | workspaceElement: any; 20 | disposables: CompositeDisposable; 21 | commands: CompositeDisposable; 22 | stateMachine: any; 23 | active: boolean; 24 | allLabels: Array