├── .cupboard ├── .gitignore ├── .npmignore ├── MIT-LICENSE.txt ├── README.md ├── examples ├── api.js ├── auth.js ├── authadv.js ├── confirm.js ├── exec.js ├── hello.js ├── hello2.js ├── hello3.js ├── parse-ex.js ├── table.js ├── table2.js ├── table3.js └── tree.js ├── images └── screen.png ├── lib ├── index.js ├── plugins │ ├── argv │ │ └── index.js │ ├── auth.js │ ├── backspace.js │ ├── command.api.js │ ├── command.js │ ├── command.route.js │ ├── confirm.js │ ├── enter.js │ ├── exec.js │ ├── help.js │ ├── history.js │ ├── loading.js │ ├── nav.js │ ├── password.js │ ├── progress.js │ ├── prompt.js │ ├── quit.js │ ├── section.js │ ├── table.js │ └── tree.js └── utils.js ├── npm-debug.log ├── package.json ├── project.sublime-project ├── project.sublime-workspace └── project.tmproj /.cupboard: -------------------------------------------------------------------------------- 1 | [commands] 2 | proj = subl . 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crcn/celeri/f10471478b9119485c7c72a49015e22ec4339e29/.npmignore -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Craig Condon 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### This library is not actively maintained. 2 | 3 | ### C-e-L-er-I 4 | 5 | ![Alt command line](http://i.imgur.com/DA77U.png) 6 | 7 | ### Features: 8 | 9 | - History (up/down arrows) 10 | - Progress Bar 11 | - Loading/busy spinner 12 | - Password input 13 | - Confirmation 14 | - Prompt 15 | - Parse command line args 16 | - help menu, and sub help menu 17 | - Multi-line tables 18 | - Build flexible commands via [beanpole](https://github.com/spiceapps/beanpole) 19 | - OR statement 20 | - Middleware 21 | - Parameters 22 | - Trees 23 | - *Exposing Javascript*, and calling it from the command line - inspired by mongo's CLI utilitiy 24 | 25 | ### To Do: 26 | 27 | - Help menu api 28 | - Title View 29 | - Custom colors for each view (input, loader, progress, table, etc.): exports.colors = {} 30 | - Error handling (display of command not found) 31 | - Add transports instead of depending on native stdin/stdout 32 | - Ability to use online 33 | 34 | 35 | 36 | ## Usage: 37 | 38 | 39 | ### .option(cmdOrOps, descOrCallback, callback) 40 | 41 | Listens for a key (enter, up, left, backspace, etc.), or command. See [beanpole](https://github.com/spiceapps/beanpole) for documentation. 42 | 43 | #### Hello World: 44 | 45 | ```javascript 46 | 47 | var celeri = require('celeri'); 48 | 49 | //an option with info for the help menu 50 | celeri.option({ 51 | command: 'hello :person', 52 | description: 'Prints "hello [person]!"', 53 | optional: { 54 | '--age': 'The person\'s age', 55 | '--gender': 'The person\'s gender' 56 | } 57 | }, function(data) { 58 | 59 | console.log("Hello %s!", data.person); 60 | 61 | if(data.age) console.log("%s is %d years old.", data.person, data.age); 62 | if(data.gender) console.log("%s is a %s.", data.person, data.gender); 63 | 64 | }); 65 | 66 | //parse the command line args 67 | celeri.parse(process.argv); 68 | 69 | ``` 70 | 71 | Interactive in terminal: 72 | 73 | ``` 74 | # node ./cmd ↩ 75 | > hello craig ↩ 76 | hello craig! 77 | ``` 78 | 79 | passed as arguments: 80 | 81 | ``` 82 | # node ./hello hello craig --age=21 --gender=cat ↩ 83 | hello craig! 84 | craig is 21 years old. 85 | craig is a cat. 86 | ``` 87 | 88 | Help menu: 89 | 90 | ``` 91 | # node ./cmd help ↩ 92 | 93 | Usage: [command] --arg=value --arg2 94 | 95 | Help: 96 | help Show help menu 97 | [cmd] help Show command help menu 98 | 99 | Commands: 100 | hello Prints "hello [person]!"" 101 | 102 | ``` 103 | 104 | Command Specific help menu: 105 | 106 | ``` 107 | # node ./cmd hello help ↩ 108 | 109 | Prints "hello [person]!"" 110 | 111 | Usage: hello [person] 112 | 113 | Optional Flags: 114 | --age The person's age 115 | --gender The person's gender 116 | ``` 117 | 118 | 119 | 120 | ### .usage(value) 121 | 122 | Sets the help menu usage text 123 | 124 | ```javascript 125 | celeri.usage('[command] --arg=value'); 126 | ``` 127 | 128 | 129 | #### "OR" statement: 130 | 131 | ```javascript 132 | 133 | 134 | celeri.option('hello :name OR hi :name', 'some description', function(data) 135 | { 136 | console.log('Hello ' + data.name +'!'); 137 | }). 138 | option('set address :zip OR set address :city :state :zip', function(data) 139 | { 140 | console.log("City: %s, State: %s, Zip: %s ", data.city || 'None provided', data.state || 'None provided', data.zip); 141 | }); 142 | 143 | ``` 144 | 145 | ### .onJs(api) 146 | 147 | You can easily expose javascript functions by providing an object: 148 | 149 | ```javascript 150 | 151 | 152 | var api = { 153 | sayHello: function(name) { 154 | console.log("hello %s!", name || 'craig'); 155 | } 156 | } 157 | 158 | celeri.onJs({ api: api }); 159 | 160 | ``` 161 | 162 | In terminal: 163 | 164 | node ./hello ↩ 165 | > api.sayHello("john"); ↩ 166 | hello john! 167 | 168 | ### .progress(label, percent) 169 | 170 | ```javascript 171 | 172 | var i = 0; 173 | 174 | var interval = setInterval(function() 175 | { 176 | celeri.progress('Label: ', i++); 177 | 178 | if(i == 100) clearInterval(interval); 179 | }, 10); 180 | 181 | ``` 182 | 183 | ### .loading(label) 184 | 185 | ```javascript 186 | 187 | var spinner = celeri.loading('Processing: '); 188 | 189 | setTimeout(function() 190 | { 191 | spinner.done(true);//undefined = done, true = success, false = fail 192 | }, 1000); 193 | 194 | ```` 195 | 196 | ### .prompt(label, callback) 197 | 198 | ```javascript 199 | 200 | celeri.prompt('Username: ', function(input) 201 | { 202 | 203 | }); 204 | 205 | ```` 206 | 207 | ### .confirm(message, callback) 208 | 209 | ```javascript 210 | 211 | celeri.confirm("Do you want to continue?", function(yes) 212 | { 213 | if(yes) 214 | { 215 | //continue 216 | } 217 | }); 218 | 219 | ``` 220 | 221 | ### .password(label[, mask], callback) 222 | 223 | ```javascript 224 | 225 | //mask = * 226 | celeri.password('Password: ', '*', function(input) 227 | { 228 | //password 229 | }); 230 | 231 | //no mask 232 | celeri.password('Password: ', function(input) 233 | { 234 | //password 235 | }); 236 | 237 | ``` 238 | 239 | ### .auth(callback) 240 | 241 | ```javascript 242 | 243 | celeri.auth(function(user, pass) 244 | { 245 | //auth here 246 | }); 247 | 248 | ``` 249 | 250 | 251 | ### .drawTable(objects, ops) 252 | 253 | ```javascript 254 | 255 | var objects = [ 256 | 257 | { 258 | name: 'Craig', 259 | age: 21, 260 | interests: 'Cooking, espresso, backpacking, coding' 261 | }, 262 | 263 | 264 | { 265 | name: 'Tim', 266 | age: 21, 267 | interests: 'Design, Traveling, Photography' 268 | 269 | } 270 | 271 | ]; 272 | 273 | celeri.drawTable(objects, { 274 | columns: ['name','age','interests'] 275 | }); 276 | 277 | 278 | ``` 279 | 280 | 281 | Gives you something like: 282 | 283 | 284 | ![Alt command line](http://i.imgur.com/oUtC9.png) 285 | 286 | 287 | Here's a multi-line table: 288 | 289 | 290 | ![Alt command line](http://i.imgur.com/O5o47.png) 291 | 292 | ### .drawTree(tree) 293 | 294 | Draws a tree 295 | 296 | ````javascript 297 | 298 | //print out the contents of the celeri object 299 | celeri.drawTree(celeri); 300 | 301 | ```` 302 | 303 | Here's another example: 304 | 305 | ![Alt command line](http://i.imgur.com/4F0e0.png) 306 | 307 | 308 | ### Let's kick it up a notch 309 | 310 | 311 | ```javascript 312 | 313 | var celeri = require('../lib'); 314 | 315 | 316 | var credentials; 317 | 318 | 319 | 320 | celeri.option('login OR login :user :pass', function(data) 321 | { 322 | 323 | //reference to the current request 324 | var self = this; 325 | 326 | 327 | //called after auth credentials have been entered in 328 | function onAuth(creds) 329 | { 330 | 331 | //credits wrong? DO NOT CONTINUE 332 | if(creds.user != 'user' || creds.pass != 'pass') 333 | { 334 | return console.log("Incorrect user / pass".red); 335 | } 336 | 337 | //otherwise, add the user to the CURRENT request so it can be passed 338 | //onto the next route listener 339 | self.user = creds.user; 340 | 341 | //cache the credentials so the user doesn't have to login each time 342 | credentials = creds; 343 | 344 | //not another listener? display a success response 345 | if(!self.next()) console.log("Logged in as %s", creds.user.green); 346 | } 347 | 348 | 349 | //user already logged in? pass! 350 | if(credentials) 351 | { 352 | onAuth(credentials); 353 | } 354 | 355 | //otherwise check if the user is passed in the route 356 | else 357 | if(data.user && data.pass) 358 | { 359 | onAuth(data); 360 | } 361 | 362 | //or prompt for authentication 363 | else 364 | { 365 | celeri.auth(function(user, pass) 366 | { 367 | onAuth({ user: user, pass: pass }); 368 | }); 369 | } 370 | }); 371 | 372 | 373 | 374 | /** 375 | * This stuff's private. The user has to be authenticated *before* this command is executed 376 | */ 377 | 378 | celeri.option('login -> account', function() 379 | { 380 | console.log('Here\'s your account info %s!', this.user.green); 381 | }); 382 | 383 | celeri.open(); 384 | 385 | 386 | 387 | celeri.parse(process.argv); 388 | 389 | 390 | ``` 391 | 392 | Here's what you get: 393 | 394 | ![Alt command line](http://i.imgur.com/g7ywq.png) 395 | 396 | 397 | -------------------------------------------------------------------------------- /examples/api.js: -------------------------------------------------------------------------------- 1 | var cli = require('../'); 2 | 3 | 4 | cli.onJs({ 5 | cli: cli 6 | }); 7 | 8 | 9 | 10 | 11 | cli.open(); -------------------------------------------------------------------------------- /examples/auth.js: -------------------------------------------------------------------------------- 1 | var celery = require('../lib'); 2 | 3 | celery.prompt('Username: ', function(user) 4 | { 5 | celery.password('Password: ', function(pass) 6 | { 7 | console.log('user: %s', user); 8 | console.log('pass: %s', pass); 9 | }); 10 | }); 11 | 12 | 13 | celery.open(); -------------------------------------------------------------------------------- /examples/authadv.js: -------------------------------------------------------------------------------- 1 | var celery = require('../lib'); 2 | 3 | celery.open(); 4 | 5 | 6 | var credentials; 7 | 8 | 9 | 10 | celery.onCommand('login OR login :user :pass', function(data, next) 11 | { 12 | var self = this; 13 | 14 | 15 | function onAuth(creds) 16 | { 17 | if(creds.user != 'user' || creds.pass != 'pass') 18 | { 19 | return console.log("Incorrect user / pass".red); 20 | } 21 | 22 | self.user = creds.user; 23 | 24 | //cache the credentials so the user doesn't have to login each time 25 | credentials = creds; 26 | 27 | if(!next()) console.log("Logged in as %s", creds.user.green); 28 | } 29 | 30 | 31 | //user already logged in? pass! 32 | if(credentials) 33 | { 34 | onAuth(credentials); 35 | } 36 | 37 | //otherwise check if the user is passed in the route 38 | else 39 | if(data.user && data.pass) 40 | { 41 | onAuth(data); 42 | } 43 | 44 | //or prompt for authentication 45 | else 46 | { 47 | celery.auth(function(user, pass) 48 | { 49 | onAuth({ user: user, pass: pass }); 50 | }); 51 | } 52 | }); 53 | 54 | 55 | 56 | /** 57 | * private account into 58 | */ 59 | 60 | celery.onCommand('login -> account', function() 61 | { 62 | console.log('Here\'s your account info %s!', this.user.green); 63 | }); 64 | 65 | 66 | celery.parse(process.argv); -------------------------------------------------------------------------------- /examples/confirm.js: -------------------------------------------------------------------------------- 1 | var celery = require('../lib'); 2 | 3 | celery.confirm('Do you want to continue?f dsfsdf sf sfsd fsd fsf sf sf sf sfsd bfs jf sdbjfsdbsfdbkfsdbjkfsdbfsdbkjf b jkbfksjfbsk', function(yes) 4 | { 5 | if(yes) 6 | { 7 | console.log("YES!".green); 8 | } 9 | else 10 | { 11 | console.log("NO!".red); 12 | } 13 | }); 14 | 15 | 16 | celery.open(); -------------------------------------------------------------------------------- /examples/exec.js: -------------------------------------------------------------------------------- 1 | var celeri = require('../lib'); 2 | 3 | 4 | celeri.exec('ls', ['-help'], { 5 | exit: function() 6 | { 7 | console.log("DONE"); 8 | } 9 | }); 10 | 11 | celeri.open(); -------------------------------------------------------------------------------- /examples/hello.js: -------------------------------------------------------------------------------- 1 | var celery = require('../lib'); 2 | 3 | celery.open({ 4 | prefix: 'hello > ' 5 | }); 6 | celery.onCommand('hello :name', function(data) 7 | { 8 | console.log('hello %s, how are you doing?', data.name); 9 | }); 10 | 11 | celery.onCommand('download :file', function(data) 12 | { 13 | console.log("starting"); 14 | 15 | var i = 0; 16 | 17 | data.file = decodeURIComponent(data.file); 18 | 19 | var interval = setInterval(function() 20 | { 21 | 22 | celery.progress('Downloading '+data.file+':', i++); 23 | 24 | if(i > 100) 25 | { 26 | clearInterval(interval); 27 | celery.newLine('done!'); 28 | } 29 | }, 10); 30 | }); 31 | 32 | 33 | celery.onCommand('timeout :ttl OR timeout :ttl :status', function(data) 34 | { 35 | var loader = celery.loading('timeout for '+data.ttl+' seconds: '); 36 | 37 | setTimeout(function() 38 | { 39 | if(data.status != undefined) 40 | { 41 | loader.done(data.status == 'success'); 42 | } 43 | else 44 | { 45 | loader.done(); 46 | } 47 | 48 | }, Number(data.ttl) * 1000); 49 | }); 50 | 51 | 52 | celery.parse(process.argv); -------------------------------------------------------------------------------- /examples/hello2.js: -------------------------------------------------------------------------------- 1 | var celery = require('../lib'); 2 | 3 | celery.onCommand('delay :seconds', function(data) 4 | { 5 | console.log("delaying for %s seconds", data.seconds); 6 | 7 | setTimeout(function(self) 8 | { 9 | if(!self.next()) console.log("done!"); 10 | }, Number(data.seconds) * 1000, this); 11 | }); 12 | 13 | 14 | celery.onCommand('delay 1 -> say hello :name', function(data) 15 | { 16 | console.log('hello %s!', data.name); 17 | }); 18 | 19 | celery.open(); -------------------------------------------------------------------------------- /examples/hello3.js: -------------------------------------------------------------------------------- 1 | 2 | var celeri = require('../'); 3 | 4 | //an option with info for the help menu 5 | celeri.option({ 6 | command: 'hello :person', 7 | description: 'Prints "hello [person]!"', 8 | optional: { 9 | '--age': 'The person\'s age', 10 | '--gender': 'The person\'s gender' 11 | } 12 | }, function(data) { 13 | 14 | console.log("Hello %s!", data.person); 15 | 16 | if(data.age) console.log("%s is %d years old.", data.person, data.age); 17 | if(data.gender) console.log("%s is a %s.", data.person, data.gender); 18 | 19 | }); 20 | 21 | //open for character input 22 | celeri.open(); 23 | 24 | //parse the command line args 25 | celeri.parse(process.argv); -------------------------------------------------------------------------------- /examples/parse-ex.js: -------------------------------------------------------------------------------- 1 | var celeri = require("../"); 2 | 3 | 4 | //an option with info for the help menu 5 | celeri.option({ 6 | command: 'hello :person', 7 | description: 'Prints "hello [person]!"', 8 | optional: { 9 | '--age': 'The person\'s age', 10 | '--gender': 'The person\'s gender' 11 | } 12 | }, function(data) { 13 | 14 | console.log("Hello %s!", data.person); 15 | 16 | if(data.age) console.log("%s is %d years old.", data.person, data.age); 17 | if(data.gender) console.log("%s is a %s.", data.person, data.gender); 18 | 19 | }); 20 | 21 | 22 | celeri.parse(process.argv, function(e, cmd) { 23 | if(e) throw e; 24 | 25 | if(cmd.command.length) celeri.open(); 26 | }); -------------------------------------------------------------------------------- /examples/table.js: -------------------------------------------------------------------------------- 1 | var celery = require('../lib'); 2 | 3 | var objects = [ 4 | 5 | { 6 | name: 'Craig', 7 | age: 21, 8 | bio: 'Cras dictum convallis fermentum. Quisque ut urna velit, at porta nibh. Nam iaculis dignissim nisl, non elementum tortor iaculis et. Curabitur vulputate, sapien eget' 9 | }, 10 | 11 | 12 | { 13 | name: 'Tim', 14 | age: 21, 15 | bio: 'Praesent ligula est, pellentesque vel euismod vitae, condimentum convallis odio. Suspendisse potenti. Fusce lacus arcu, bibendum in gravida at, dictum vitae mauris. Cras viverra, dui ac elementum fringilla, purus mauris rutrum nibh, id ultrices diam magna id ante. Integer elit ligula, cursus at accumsan in, scelerisque at dui. Sed pellentesque justo sit amet nibh sodales sed malesuada nulla cursus. Maecenas eu felis leo, a volutpat sapien. Duis eget porta urna. Maecenas ligula elit, vulputate ac bibendum eu, dapibus ut lacus. Fusce ac tincidunt eros. Pellentesque ut turpis ac ante interdum rutrum. Suspendisse tempor lobortis semper.' 16 | }, 17 | 18 | { 19 | name: 'Michael', 20 | age: 23, 21 | bio: 'Vestibulum ligula elit, vehicula a lacinia at, aliquet sed felis. In rutrum pulvinar ultrices. Donec interdum ullamcorper neque ut pretium. Donec varius massa vitae ipsum feugiat feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce a nulla a odio congue hendrerit in non tellus. Cras gravida vestibulum augue vitae dapibus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce porttitor rutrum faucibus. Vivamus interdum porta orci, vitae fermentum nunc vestibulum at. Maecenas porttitor sollicitudin pharetra. Ut risus mauris, tincidunt vitae laoreet quis, rhoncus eget risus' 22 | }, 23 | 24 | { 25 | name: 'Sarah', 26 | age: 19, 27 | bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin fringilla interdum nibh eget luctus. In facilisis varius lacus, ut adipiscing turpis posuere a. Nunc id sapien eu urna' 28 | } 29 | 30 | ]; 31 | 32 | 33 | celery.drawTable(objects, { 34 | columns: { 35 | name: 15, 36 | age: 5, 37 | bio: 30 38 | }, 39 | 40 | horz: ' ', 41 | 42 | }); 43 | 44 | celery.open(); -------------------------------------------------------------------------------- /examples/table2.js: -------------------------------------------------------------------------------- 1 | var celery = require('../lib'); 2 | 3 | var objects = [ { name: 'bean.cupboard.scaffold', 4 | hasUpdates: '', 5 | published: 'published: 2 hours agofdsfsafsfadffdsf afsd fasf as fsd fsdf sdf sdf sd ' }, 6 | { name: 'teamdigest', 7 | hasUpdates: '', 8 | published: 'published: 2 hours ago' }]; 9 | 10 | console.log(celery.columns()) 11 | 12 | celery.drawTable(objects, { 13 | columns: [{ 14 | width: 15, 15 | minWidth:20, 16 | name: 'name' 17 | }, 18 | { 19 | name: 'published', 20 | width:15, 21 | align:'left' 22 | }], 23 | 24 | horz: ' ', 25 | vert: '|' 26 | 27 | }); 28 | -------------------------------------------------------------------------------- /examples/table3.js: -------------------------------------------------------------------------------- 1 | var celery = require('../lib'); 2 | 3 | var objects = [ { command: 'init', 4 | desc: 'Adds a project in cwd to cupboard.' }, 5 | { command: 'remove ', 6 | desc: 'Removes project from cupboard.' }, 7 | { command: ' ', 8 | desc: 'Calls custom command specified in project cupboard config.' }, 9 | { command: 'untouch ', 10 | desc: 'Flags given project as updated.' }, 11 | { command: 'publish ', 12 | desc: 'Publishes target project.' }, 13 | { command: 'updates', 14 | desc: 'List all projects with updates.' }, 15 | { command: 'list', 16 | desc: 'List all projects in cupboard organized by most recently updated.' }, 17 | { command: 'install ', 18 | desc: 'Installs a third-party cupboard plugin.' }, 19 | { command: 'uninstall ', 20 | desc: 'Uninstalls a third-party cupboard plugin.' }, 21 | { command: 'plugins', 22 | desc: 'Lists all third-party plugins.' }, 23 | { command: 'scaffold ', 24 | desc: 'Initializes target scaffold in cwd' }, 25 | { command: 'github ', 26 | desc: 'Open github page of target project' }, 27 | { command: 'github-issues ', 28 | desc: 'Open github issues of target project.' }, 29 | { command: 'help', desc: 'Shows the help menu.' }, 30 | { command: 'dir ', 31 | desc: 'Returns the project path.' }, 32 | { command: 'details ', 33 | desc: 'Returns details about the given project such as modified files, and number of updates.' } ]; 34 | 35 | 36 | celery.drawTable(objects, { 37 | columns: [ { 38 | minWidth: 25, 39 | width: 20, 40 | name: 'command' 41 | }, 42 | { 43 | name: 'desc', 44 | width: 80, 45 | align: 'left' 46 | } ], 47 | 48 | pad: { 49 | left: 10, 50 | right: 10, 51 | top: 2, 52 | bottom: 2 53 | }, 54 | 55 | ellipsis: true 56 | 57 | }); 58 | -------------------------------------------------------------------------------- /examples/tree.js: -------------------------------------------------------------------------------- 1 | var celeri = require('../lib'); 2 | 3 | celeri.drawTree({ 4 | 'home/':{ 5 | 'network/':{ 6 | 'apps/' :[ 7 | "cliqly", 8 | "clove", 9 | "team digest" 10 | ], 11 | 'public/': { 12 | 'git/':{ 13 | 'some-project':[ 14 | 'index.js' 15 | ] 16 | }, 17 | 'npm/':{ 18 | 'some-project':['index.js'] 19 | } 20 | } 21 | } 22 | }, 23 | 'downloads/': { 24 | 'libcpp': [ 25 | 'makefile' 26 | ] 27 | } 28 | }) 29 | 30 | 31 | //celeri.drawTree(celeri); 32 | 33 | 34 | celeri.open(); -------------------------------------------------------------------------------- /images/screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crcn/celeri/f10471478b9119485c7c72a49015e22ec4339e29/images/screen.png -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | var tty = require('tty'), 2 | fs = require('fs'), 3 | _buffer = '', 4 | plugin = require("plugin"); 5 | 6 | require("colors"); 7 | 8 | require("keypress")(process.stdin); 9 | 10 | exports.utils = require('./utils'); 11 | 12 | var queue = require('tq').queue().start(); 13 | 14 | exports.queue = queue.fn; 15 | 16 | var _inputPrefix = '> '; 17 | 18 | /** 19 | * queued commands 20 | */ 21 | 22 | exports.next = function(callback) { 23 | queue.push(callback); 24 | 25 | return this; 26 | } 27 | 28 | 29 | /** 30 | * size of the terminal window 31 | */ 32 | 33 | exports.size = function() { 34 | return process.stdout.getWindowSize(); 35 | } 36 | 37 | 38 | 39 | /** 40 | * number of columns in the terminal window (characters / width) 41 | */ 42 | 43 | exports.columns = function() { 44 | return exports.size()[0] || exports.size(); 45 | } 46 | 47 | /** 48 | * number of rows in the terminal window 49 | */ 50 | 51 | exports.rows = function() { 52 | return exports.size()[1]; 53 | } 54 | 55 | /** 56 | */ 57 | 58 | exports.inputPrefix = function(prefix) { 59 | if(!arguments.length) return _inputPrefix; 60 | 61 | 62 | return _inputPrefix = prefix || ''; 63 | } 64 | 65 | /** 66 | */ 67 | 68 | exports.buffer = function(value, ignoreReplace) { 69 | if(!arguments.length) return _buffer; 70 | 71 | _buffer = value; 72 | 73 | return !ignoreReplace ? exports.replaceLine(value) : value; 74 | } 75 | 76 | /** 77 | * Replaces the current line in the terminal window 78 | */ 79 | 80 | exports.replaceLine = function(buffer, cursorTo) { 81 | 82 | if(!buffer) buffer = ""; 83 | 84 | //need to clear the line before replacing it 85 | process.stdout.clearLine(); 86 | 87 | //set the cursor to zero, otherwise we'll have padding we don't want 88 | exports.cursor(0); 89 | 90 | //write the buffer 91 | process.stdout.write(buffer); 92 | 93 | //set the cursor to the new position! 94 | exports.cursor(cursorTo != undefined ? cursorTo : buffer.length); 95 | 96 | return _buffer = buffer; 97 | } 98 | 99 | 100 | /** 101 | * inserts text into the current line 102 | */ 103 | 104 | exports.insertText = function(str, position) { 105 | var buffer = exports.buffer(); 106 | exports.replaceLine(buffer.substr(0, position) + str + buffer.substr(position), position + str.length); 107 | } 108 | 109 | 110 | /** 111 | * Takes a chunk of text out of the current line 112 | */ 113 | 114 | exports.spliceLine = function(position, length, newCursor) { 115 | 116 | var buffer = exports.buffer(); 117 | exports.replaceLine(buffer.substr(0, position) + buffer.substr(position + length), newCursor); 118 | } 119 | 120 | var _cursorPosition = 0; 121 | 122 | 123 | /** 124 | */ 125 | 126 | exports.cursor = function(position) { 127 | if(!arguments.length) return _cursorPosition; 128 | 129 | 130 | process.stdout.cursorTo(position); 131 | 132 | return _cursorPosition = position; 133 | } 134 | 135 | 136 | 137 | function stringRep(key) { 138 | var chain = [key.name]; 139 | 140 | if(key.shift) chain.unshift("shift-"); 141 | if(key.ctrl) chain.unshift("ctrl-"); 142 | if(key.meta) chain.unshift("meta-"); 143 | 144 | return chain.join("") 145 | } 146 | 147 | exports.write = function(string) { 148 | process.stdout.write(string); 149 | } 150 | 151 | exports.newLine = function(buffer) { 152 | if(buffer) exports.write(buffer); 153 | exports.write('\n'); 154 | exports.buffer(''); 155 | } 156 | 157 | exports.open = function(ops) { 158 | if(ops) { 159 | if(ops.prefix) exports.inputPrefix(ops.prefix); 160 | } 161 | 162 | if(exports.opened) return; 163 | exports.opened = true; 164 | 165 | 166 | stdin = process.openStdin(); 167 | stdin.setEncoding('utf8'); 168 | process.stdin.setRawMode(true); 169 | 170 | 171 | 172 | stdin.on('keypress', function(c, key) { 173 | 174 | //integer? 175 | if(!key) key = { name: c.toString() }; 176 | if(!c) c = key.name; 177 | 178 | var chain = stringRep(key); 179 | 180 | 181 | var emitSuccess = chain.length > 1 ? exports.emit(chain) : false; 182 | 183 | 184 | //not a handled item to boot? Probably enter, delete, left, right, up, etc. Append it. 185 | if(!emitSuccess && c) { 186 | if(!_buffer.length) { 187 | exports.insertText(exports.inputPrefix(), _cursorPosition); 188 | } 189 | exports.insertText(c, _cursorPosition); 190 | //exports.insertText(c, Math.max(_cursorPosition, exports.inputPrefix().length)); 191 | } 192 | 193 | 194 | //new line? reset 195 | if(key && key.name == 'enter') { 196 | //exports.replaceLine(exports.buffer().magenta); 197 | process.stdout.write('\n'); 198 | _buffer = ''; 199 | _cursorPosition = 0; 200 | //exports.insertText(exports.inputPrefix(), _cursorPosition); 201 | //exports.cursor(0); 202 | } 203 | 204 | 205 | //for custom handlers: password, confirm, etc. 206 | exports.emit('keypress', { char: c, key: key }); 207 | 208 | //character code? 209 | if(key.name.length == 1) { 210 | exports.emit('charpress', c); 211 | } 212 | 213 | 214 | }); 215 | } 216 | 217 | 218 | exports.parse = function(args, callback) { 219 | 220 | args = args.concat().splice(2); 221 | 222 | var self = this; 223 | var command = [], 224 | data = {}; 225 | 226 | 227 | 228 | while(args.length) { 229 | var arg = args.shift(); 230 | 231 | if(arg.substr(0,2) != '--') { 232 | command.push(arg); 233 | } else { 234 | args.unshift(arg); 235 | break; 236 | } 237 | } 238 | 239 | while(args.length) { 240 | var arg = args.shift(); 241 | 242 | if(arg.substr(0,2) == '--') { 243 | var argParts = arg.substr(2).split('='); 244 | data[argParts[0]] = argParts[1] || true; 245 | } 246 | } 247 | 248 | var cmd = { command: command, data: data }; 249 | 250 | exports.next(function() { 251 | if(command.length === 0 ){ 252 | self.emit('help'); 253 | return; 254 | } 255 | 256 | if(!self.emit(command, data)) { 257 | if(command.join('').length) { 258 | var err = new Error('command "'+command.join(' ')+'" does not exist') 259 | 260 | if(callback) return callback(err, cmd); 261 | 262 | console.error(err.message); 263 | } 264 | self.emit('help'); 265 | return; 266 | } 267 | 268 | this(); 269 | if(callback) callback(null, cmd); 270 | }); 271 | 272 | return cmd; 273 | } 274 | 275 | plugin(exports). 276 | params({}). 277 | require(__dirname + "/plugins"). 278 | load(function(err) { 279 | if(err) { 280 | console.error(err.stack); 281 | process.exit(); 282 | } 283 | }); 284 | 285 | 286 | exports.plugin = function() { 287 | return exports; 288 | } 289 | 290 | -------------------------------------------------------------------------------- /lib/plugins/argv/index.js: -------------------------------------------------------------------------------- 1 | _ = require("underscore"); 2 | exports.plugin = function(cli) { 3 | 4 | cli.option = function(command, description, callback) { 5 | 6 | 7 | var ops = { command: command, 8 | description: description, 9 | callback: callback }; 10 | 11 | if(typeof command == 'object') { 12 | ops = command; 13 | } 14 | 15 | 16 | if(typeof description == 'function') { 17 | 18 | if(typeof ops.description != 'string') ops.description = undefined; 19 | 20 | ops.callback = description; 21 | } 22 | 23 | if(typeof callback == 'function') { 24 | ops.callback = callback; 25 | } 26 | 27 | 28 | var mainCmd = cli.parseCommand(ops.command).shift(); 29 | 30 | 31 | ops.name = mainCmd.path.segments[0].value; 32 | ops.usage = ops.usage || ops.command; 33 | 34 | if(ops.description) cli.addHelp(ops); 35 | 36 | 37 | cli.onCommand(ops.command, function(data) { 38 | _.defaults(data, ops.defaults || {}); 39 | ops.callback.apply(this, arguments); 40 | }); 41 | 42 | return cli; 43 | } 44 | } -------------------------------------------------------------------------------- /lib/plugins/auth.js: -------------------------------------------------------------------------------- 1 | 2 | exports.plugin = function(cli) { 3 | 4 | cli.auth = cli.queue(function(callback) { 5 | var self = this; 6 | 7 | self.attach(callback); 8 | 9 | cli.prompt('Username: ', function(user) { 10 | cli.password('Password: ','*', function(pass) { 11 | self.next(user, pass); 12 | }); 13 | }); 14 | }); 15 | } -------------------------------------------------------------------------------- /lib/plugins/backspace.js: -------------------------------------------------------------------------------- 1 | exports.require = ["command.route"]; 2 | exports.plugin = function(commandRoute, cli) { 3 | 4 | cli.onCommand('backspace', function() { 5 | var pos = cli.cursor(); 6 | if(pos == cli.inputPrefix().length) return; 7 | 8 | cli.spliceLine(pos-1, 1, pos-1); 9 | }); 10 | 11 | cli.onCommand('delete', function() { 12 | var pos = cli.cursor(); 13 | 14 | cli.spliceLine(pos, 1, pos); 15 | }); 16 | 17 | } -------------------------------------------------------------------------------- /lib/plugins/command.api.js: -------------------------------------------------------------------------------- 1 | var Structr = require('structr'), 2 | _ = require("underscore"), 3 | dsync = require("dsync"); 4 | 5 | exports.name = "command.api"; 6 | exports.plugin = function(cli) { 7 | 8 | var target = {}; 9 | 10 | function normalizeApi(target) { 11 | 12 | if(target.desc != undefined && target.exec) return target; 13 | 14 | var tot = typeof target; 15 | 16 | if(/string|number/.test(tot)) return target; 17 | 18 | for(var prop in target) { 19 | 20 | var v = target[prop]; 21 | 22 | if(typeof v == 'function') { 23 | target[prop] = { 24 | exec: v, 25 | desc: '' 26 | } 27 | } else { 28 | normalizeApi(v); 29 | } 30 | } 31 | 32 | return target; 33 | } 34 | 35 | function flattenMethods(target, path) { 36 | 37 | var methods = []; 38 | 39 | if(target.desc != undefined && target.exec) { 40 | var pt = path.join('.'), 41 | cmd = target.exec.toString().match(/function\s*\w*(\(.*?\))/)[1]; 42 | 43 | if(target.args) cmd = cmd.replace(/\(.*?\)/,'('+target.args.join(', ')+')'); 44 | methods.push( { path: pt, 45 | command: pt + cmd, 46 | func: target.exec, 47 | desc: target.desc, 48 | ignoreHelp: target.ignoreHelp }); 49 | return methods; 50 | } 51 | 52 | for(var prop in target) { 53 | 54 | var v = target[prop]; 55 | 56 | if(typeof v == 'object') { 57 | var subPath = path.concat(); 58 | subPath.push(prop); 59 | methods = methods.concat(flattenMethods(v, subPath)); 60 | } 61 | } 62 | 63 | return methods; 64 | } 65 | 66 | 67 | function demormalizeApi(api) { 68 | if(typeof api.exec == 'function') { 69 | return api.exec; 70 | } 71 | 72 | for(var prop in api) { 73 | api[prop] = demormalizeApi(api[prop]); 74 | } 75 | 76 | return api; 77 | } 78 | 79 | 80 | cli.onJs = function(api) { 81 | 82 | var wapi = dsync(api); 83 | 84 | /*flattenMethods(normalizeApi(wapi), []).forEach(function(cmd) { 85 | cli.addHelp(cmd); 86 | });*/ 87 | 88 | // console.log(demormalizeApi(api).cli.toString()) 89 | // Structr.copy(demormalizeApi(api), target); 90 | _.extend(target, wapi); 91 | 92 | } 93 | 94 | return { 95 | testListener: function(type) { 96 | return type.indexOf('(') > -1 && type.indexOf('.'); 97 | }, 98 | run: function(buffer, data) { 99 | 100 | try { 101 | var ret = eval("target." + buffer); 102 | 103 | // if(ret != undefined) console.log(ret); 104 | return true; 105 | } catch(e) { 106 | console.log('\nUnable to call %s \n%s', buffer.bold, e.message.red.bold); 107 | 108 | return false; 109 | } 110 | 111 | } 112 | } 113 | } -------------------------------------------------------------------------------- /lib/plugins/command.js: -------------------------------------------------------------------------------- 1 | var tq = require('tq'); 2 | 3 | exports.plugin = function(cli, loader) { 4 | 5 | var queue = tq.queue(), handlers = []; 6 | 7 | 8 | 9 | function getHandler(type, callback) { 10 | loader.loadModules("^command.*$", function(err, handlers) { 11 | for(var i = handlers.length; i--;) { 12 | var handler = handlers[i]; 13 | if(handler.testListener && handler.testListener(type)) return callback(null, handler); 14 | } 15 | 16 | callback(); 17 | }); 18 | 19 | } 20 | 21 | cli.emit = function(buffer, data) { 22 | 23 | var ret = true; 24 | 25 | //fucking dirty... - this is synchronous. 26 | getHandler(buffer, function(err, handler) { 27 | try { 28 | 29 | if(!handler) { 30 | ret = false; 31 | return; 32 | } 33 | 34 | 35 | return handler.run(buffer, data); 36 | 37 | } catch(e) { 38 | console.error(e.stack); 39 | ret = false; 40 | } 41 | }); 42 | 43 | return ret; 44 | } 45 | 46 | 47 | queue.start(); 48 | } -------------------------------------------------------------------------------- /lib/plugins/command.route.js: -------------------------------------------------------------------------------- 1 | var beanpoll = require('beanpoll'), 2 | disposable = require('disposable'), 3 | Structr = require('structr'), 4 | crema = require('crema'), 5 | _ = require("underscore"); 6 | 7 | 8 | //changes for beanpole prohibit the use of whitespace 9 | function fixRoute(route) { 10 | 11 | //protect special chars while we replace 12 | return route.replace(/\s*OR\s*/g,'__OR__'). 13 | replace(/\s*->\s*/g,'__->__'). 14 | replace(/[\s\t\n]+/g,'/'). 15 | replace(/__/g,' '); 16 | } 17 | 18 | var CmdMessage = Structr(beanpoll.Messenger, { 19 | 20 | _next: function(middleware) { 21 | 22 | var self = this; 23 | this.request.cache(true); 24 | this._inner = this._inner || {}; 25 | 26 | 27 | this.request.dump(function(err, data) { 28 | try { 29 | middleware.listener(_.extend({}, middleware.params, data, self._inner), function(err, data) { 30 | 31 | if(err) return self.response.error(e); 32 | 33 | _.extend(self._inner, data); 34 | 35 | return self.next(); 36 | }); 37 | } catch(e) { 38 | self.response.error(e) 39 | } 40 | 41 | }) 42 | 43 | } 44 | 45 | }); 46 | 47 | var CmdDirector = Structr(beanpoll.Director, { 48 | 49 | passive: true, 50 | 51 | _newMessenger: function(message, middleware) { 52 | return new CmdMessage(message, middleware, this); 53 | } 54 | 55 | }); 56 | 57 | exports.name = "command.route"; 58 | 59 | 60 | exports.plugin = function(cli) { 61 | 62 | var router; 63 | 64 | 65 | cli.useCommandRouter = function(newRouter) { 66 | 67 | router = newRouter; 68 | 69 | newRouter.use(function() { 70 | return { 71 | name: 'cmd', 72 | director: new CmdDirector('cmd', router) 73 | } 74 | }); 75 | 76 | } 77 | 78 | cli.useCommandRouter(beanpoll.router()); 79 | 80 | 81 | cli.parseCommand = function(command) { 82 | return crema(fixRoute(command)); 83 | } 84 | 85 | 86 | 87 | cli.onCommand = function(typeOrOps, callback) { 88 | 89 | 90 | var ops = {}, disposables = disposable.create(); 91 | 92 | if(typeof typeOrOps == 'object' && typeof callback != 'function') { 93 | 94 | for(var t in typeOrOps) { 95 | disposables.add(cli.onCommand(t, typeOrOps[t])); 96 | } 97 | 98 | return disposables; 99 | } 100 | 101 | if(typeof typeOrOps == 'object') { 102 | ops = typeOrOps; 103 | } else { 104 | ops = { command: typeOrOps }; 105 | } 106 | 107 | if(ops.desc) { 108 | cli.addHelp(ops); 109 | } 110 | 111 | return router.on(fixRoute(ops.command), { type: 'cmd' }, callback); 112 | } 113 | 114 | return { 115 | testListener: function(type) { 116 | return type instanceof Array || router.request(fixRoute(type)).type('cmd').hasListeners(); 117 | }, 118 | run: function(type, data) { 119 | 120 | var fixedPath; 121 | 122 | if(type instanceof Array) { 123 | fixedPath = { segments: [] }; 124 | 125 | for(var i = 0, n = type.length; i < n; i++) { 126 | fixedPath.segments.push({ value: type[i] }); 127 | } 128 | } 129 | else { 130 | fixedPath = fixRoute(type); 131 | } 132 | 133 | router.request(fixedPath). 134 | error(function(e) { 135 | console.log(e.stack) 136 | }). 137 | dispatch('cmd'). 138 | end(data); 139 | 140 | return true; 141 | } 142 | } 143 | } -------------------------------------------------------------------------------- /lib/plugins/confirm.js: -------------------------------------------------------------------------------- 1 | exports.plugin = function(cli) { 2 | 3 | cli.confirm = cli.queue(function(label, callback) { 4 | label += ' [y/n]: '; 5 | 6 | cli.write(label); 7 | 8 | var input = '', yes = 'y', no = 'n', 9 | self = this; 10 | 11 | self.attach(callback); 12 | 13 | 14 | var disposable = cli.onCommand({ 15 | 16 | /** 17 | */ 18 | 19 | 'keypress': function(data) { 20 | input = data.char; 21 | 22 | cli.buffer(label + input); 23 | }, 24 | 25 | /** 26 | */ 27 | 28 | 'enter': function() { 29 | 30 | if(input != yes && input != no) { 31 | return cli.write('\nPlease enter "'+yes+'" or "'+no+'"'); 32 | } 33 | 34 | disposable.dispose(); 35 | 36 | setTimeout(self.next, 1, input == 'y'); 37 | } 38 | }); 39 | }); 40 | } -------------------------------------------------------------------------------- /lib/plugins/enter.js: -------------------------------------------------------------------------------- 1 | exports.require = ["command.route"]; 2 | exports.plugin = function(commandRoute, cli) { 3 | 4 | 5 | cli.run = function(buffer) { 6 | /*commands = buffer.split('&&'); 7 | 8 | commands.forEach(function(command) { 9 | 10 | var args = command.match(/((["'])([^\\](?!\2)|\\.|\w)+\2|[^\s"']+)/ig); 11 | 12 | 13 | if(!args) return; 14 | 15 | for(var i = args.length; i--;) { 16 | args[i] = encodeURIComponent(args[i]); 17 | } 18 | 19 | 20 | function emit(operation) { 21 | if(!cli.emit(args.join(cli.delimiter()))) 22 | { 23 | //console.log('illegal operation: "%s"'.red, operation); 24 | //cli.emit('help'); 25 | } 26 | } 27 | 28 | setTimeout(emit, 1, args.join(cli.delimiter())); 29 | });*/ 30 | 31 | } 32 | 33 | cli.onCommand('enter', function() { 34 | var failed = false; 35 | var commands = cli.buffer().replace(cli.inputPrefix(),'').split(';'), 36 | running = commands.length; 37 | commands.forEach(function(command) { 38 | process.nextTick(function() { 39 | var success= cli.emit(command, null); 40 | failed = !success || failed; 41 | if(!(--running) && failed) { 42 | console.log("Wrong command!"); 43 | process.nextTick(cli.help); 44 | } 45 | }); 46 | }); 47 | }); 48 | } 49 | -------------------------------------------------------------------------------- /lib/plugins/exec.js: -------------------------------------------------------------------------------- 1 | var spawn = require('child_process').spawn; 2 | 3 | exports.plugin = function(cli) { 4 | 5 | /** 6 | * goal = dead simple and painless. 7 | */ 8 | 9 | cli.exec = function(command, args, ops, callback) { 10 | 11 | if(typeof args == 'function') { 12 | callback = args; 13 | args = []; 14 | ops = {}; 15 | } else 16 | if(!(args instanceof Array)) { 17 | callback = ops; 18 | ops = args; 19 | args = []; 20 | } 21 | 22 | 23 | 24 | if(typeof ops == 'function') { 25 | callback = ops; 26 | ops = {}; 27 | } 28 | 29 | //no callbacks? THEY MUST EXIST!!!! 30 | if(!callback) callback = ops.callback || ops; 31 | 32 | var callbacks = {}; 33 | 34 | if(typeof callback != 'function') { 35 | callbacks = callback; 36 | } 37 | 38 | if(!callbacks.error) callbacks.error = function(){}; 39 | if(!callbacks.exit) callbacks.exit = function(){}; 40 | if(!callbacks.data) callbacks.data = function(){}; 41 | 42 | 43 | var procOps = { 44 | cwd: ops.cwd, 45 | env: ops.env, 46 | customFds: ops.customFds 47 | }; 48 | 49 | 50 | var proc = spawn(command, ops.args || args, procOps), errors = [], buffer = []; 51 | 52 | proc.stdout.on('data', function(data) { 53 | buffer.push(data); 54 | 55 | callbacks.data(data); 56 | }); 57 | 58 | proc.stderr.on('data', function(data) { 59 | errors.push(data); 60 | 61 | callbacks.error(data); 62 | }); 63 | 64 | proc.on('exit', function(code) { 65 | 66 | if(typeof callback == 'function') { 67 | callback(errors.length ? errors.join(' ') : false, buffer.length ? buffer.join(' ') : false); 68 | } else 69 | if(callbacks.exit) { 70 | callbacks.exit(code); 71 | } 72 | }); 73 | 74 | } 75 | } -------------------------------------------------------------------------------- /lib/plugins/help.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | 3 | function capitalizeFirst(str) { 4 | return str.substr(0,1).toUpperCase() + str.substr(1); 5 | } 6 | 7 | var helpMenu = function(cli) { 8 | 9 | var usage, 10 | desc, 11 | items = {}, 12 | used = {}, 13 | children = {}; 14 | 15 | 16 | var self = { 17 | 18 | /** 19 | */ 20 | 21 | description: function(value) { 22 | 23 | desc = value; 24 | 25 | }, 26 | 27 | /** 28 | */ 29 | 30 | usage: function(value) { 31 | 32 | usage = value; 33 | 34 | }, 35 | 36 | /** 37 | * adds a help item 38 | */ 39 | 40 | add: function(category, name, desc) { 41 | 42 | if(used[name]) return; 43 | used[name]= 1; 44 | 45 | if(!items[category]) items[category] = []; 46 | 47 | items[category].push({ 48 | name: name, 49 | desc: desc 50 | }); 51 | }, 52 | 53 | /** 54 | */ 55 | 56 | child: function(name) { 57 | return children[name] || (children[name] = helpMenu(cli)); 58 | }, 59 | 60 | /** 61 | */ 62 | 63 | print: function() { 64 | 65 | //line break 66 | console.log(); 67 | 68 | if(desc) { 69 | console.log('%s\n'.bold, desc); 70 | } 71 | 72 | if(usage) console.log('%s: %s\n', 'Usage'.bold, usage); 73 | 74 | for(var category in items) { 75 | 76 | console.log('%s:'.bold, capitalizeFirst(category)); 77 | 78 | var ops = { 79 | ellipsis: true, 80 | columns: { 81 | name: 20, 82 | desc: 70 83 | }, 84 | pad: { 85 | left: 2 86 | } 87 | }; 88 | 89 | 90 | 91 | cli.table(items[category], ops); 92 | console.log(); 93 | } 94 | } 95 | }; 96 | 97 | return self; 98 | } 99 | 100 | 101 | 102 | 103 | exports.plugin = function(cli) { 104 | 105 | var help = helpMenu(cli); 106 | 107 | 108 | cli.addHelp = function(ops) { 109 | 110 | 111 | //fix the usage so it's turned from command :op to command [op] 112 | if(ops.usage) 113 | ops.usage = ops.usage. 114 | replace(/\:(\w+)/g,'[$1]'). 115 | replace(/OR/g,'OR'.bold); 116 | 117 | help.add(ops.category || 'options', ops.name, ops.description || ops.desc); 118 | 119 | //set the usage for the child help item 120 | var childHelp = help.child(ops.name); 121 | 122 | childHelp.usage(ops.usage); 123 | childHelp.description(ops.description); 124 | 125 | 126 | var k; 127 | 128 | if(ops.defaults) { 129 | for(var op in ops.optional) { 130 | 131 | k = op; 132 | 133 | if(ops.defaults[op]) { 134 | k = k + "=" + ops.defaults[k]; 135 | } 136 | 137 | 138 | childHelp.add('Optional Flags', "--" + k, ops.optional[op]); 139 | 140 | } 141 | } 142 | 143 | return cli; 144 | } 145 | 146 | cli.usage = help.usage; 147 | 148 | 149 | help.usage('[command] --arg=value --arg2') 150 | 151 | 152 | cli.help = function() { 153 | 154 | help.print(); 155 | 156 | } 157 | 158 | cli.commandHelp = function(data, next) { 159 | 160 | 161 | //intercept commands that are :command help 162 | if(this.path.segments.length > 1 && this.path.segments[1].value == 'help') { 163 | 164 | help.child(this.path.segments[0].value).print(); 165 | 166 | return; 167 | } 168 | 169 | next(); 170 | } 171 | 172 | cli.option('help', cli.help). 173 | option(':command help OR **', cli.commandHelp); 174 | 175 | cli.addHelp({ 176 | category: 'help', 177 | name: '[cmd] help', 178 | description: 'Show command help menu' 179 | }); 180 | 181 | cli.addHelp({ 182 | category: 'help', 183 | name: 'help', 184 | description: 'Show help menu' 185 | }); 186 | } -------------------------------------------------------------------------------- /lib/plugins/history.js: -------------------------------------------------------------------------------- 1 | exports.require = ["command.route"]; 2 | exports.plugin = function(commandRoute, cli) { 3 | var history = [], cursor = 0, max = 20; 4 | 5 | cli.onCommand('enter', function() { 6 | history.push(cli.buffer()); 7 | 8 | if(history.length > max) 9 | { 10 | history.shift(); 11 | } 12 | 13 | 14 | cursor = history.length-1; 15 | 16 | }); 17 | 18 | 19 | cli.onCommand('up', function() { 20 | if(cursor == -1) return; 21 | 22 | cli.replaceLine(history[cursor--]); 23 | }); 24 | 25 | cli.onCommand('down', function() { 26 | if(cursor == history.length-1) return; 27 | 28 | cli.replaceLine(history[++cursor]); 29 | }); 30 | 31 | } -------------------------------------------------------------------------------- /lib/plugins/loading.js: -------------------------------------------------------------------------------- 1 | exports.plugin = function(cli) { 2 | 3 | cli.loading = function(label, options) { 4 | 5 | if(!options) options = {} 6 | if(!label) label = ''; 7 | 8 | 9 | 10 | function done(err, result) { 11 | var success = err == null, msg, color; 12 | if(success) { 13 | msg = "✔"; 14 | color = "green"; 15 | } else { 16 | msg = "✘" 17 | color = "red"; 18 | } 19 | 20 | clearInterval(interval); 21 | cli.replaceLine("[ " + msg[color] + " ] " + label); 22 | cli.newLine(); 23 | } 24 | 25 | 26 | var seq = '–\|/'; 27 | pos = 0, 28 | interval = setInterval(function() { 29 | cli.replaceLine('[ '+seq[pos++%seq.length].grey+' ] ' + label); 30 | }, 200); 31 | 32 | 33 | return { 34 | done: done 35 | }; 36 | } 37 | } -------------------------------------------------------------------------------- /lib/plugins/nav.js: -------------------------------------------------------------------------------- 1 | exports.require = ["command.route"]; 2 | exports.plugin = function(commandRoute, cli) { 3 | 4 | cli.onCommand('left', function() { 5 | cli.cursor(cli.cursor() - 1); 6 | }); 7 | 8 | cli.onCommand('right', function() { 9 | cli.cursor(cli.cursor() + 1); 10 | }); 11 | 12 | cli.onCommand('ctrl-a', function() { 13 | cli.cursor(cli.inputPrefix().length); 14 | }); 15 | 16 | cli.onCommand('ctrl-e', function() { 17 | cli.cursor(cli.buffer().length); 18 | }); 19 | 20 | } -------------------------------------------------------------------------------- /lib/plugins/password.js: -------------------------------------------------------------------------------- 1 | exports.plugin = function(cli) { 2 | 3 | function getMask(mask, length){ 4 | if(!mask) return ''; 5 | 6 | var buffer = ''; 7 | 8 | for(var i = length; i--;) 9 | { 10 | buffer += mask; 11 | } 12 | 13 | return buffer; 14 | } 15 | 16 | 17 | cli.password = cli.queue(function(label, mask, callback) { 18 | 19 | if(typeof mask == 'function') { 20 | callback = mask; 21 | mask = undefined; 22 | } 23 | 24 | cli.write(label); 25 | 26 | var input = '', 27 | self = this; 28 | 29 | self.attach(callback); 30 | 31 | 32 | var disposable = cli.onCommand({ 33 | 'backspace': function() { 34 | if(!input.length) return; 35 | 36 | input = input.substr(0, input.length-1); 37 | }, 38 | 'keypress': function(data) { 39 | if(data.key.name != 'backspace') 40 | input += data.char; 41 | 42 | cli.buffer(label+getMask(mask, input.length)); 43 | }, 44 | 'enter': function() { 45 | setTimeout(self.next,1,input); 46 | disposable.dispose(); 47 | } 48 | }); 49 | }); 50 | } -------------------------------------------------------------------------------- /lib/plugins/progress.js: -------------------------------------------------------------------------------- 1 | exports.plugin = function(cli) { 2 | var spaces = 20, 3 | perc = 0; 4 | 5 | function percentBuffer(label, color) { 6 | var diff = Math.round((spaces/100) * perc); 7 | 8 | return label + ' ['+ cli.utils.fill('#'[color],diff,' ', spaces-diff) + '] '+ perc +'% '; 9 | } 10 | 11 | cli.progress = function(label, percent) { 12 | //fail 13 | if(percent === false) { 14 | cli.replaceLine(percentBuffer(label, perc, 'red')); 15 | return cli.newLine(); 16 | } 17 | 18 | perc = Math.min(percent, 100); 19 | 20 | cli.replaceLine(percentBuffer(label, perc == 100 ? 'green' : 'blue')); 21 | 22 | if(perc == 100) { 23 | return cli.newLine(); 24 | } 25 | 26 | }; 27 | } -------------------------------------------------------------------------------- /lib/plugins/prompt.js: -------------------------------------------------------------------------------- 1 | exports.plugin = function(cli) { 2 | cli.prompt = cli.queue(function(label, callback) { 3 | var input = '', 4 | self = this; 5 | 6 | self.attach(callback); 7 | 8 | 9 | function write() { 10 | cli.replaceLine(label + input); 11 | } 12 | 13 | 14 | var disp = cli.onCommand({ 15 | 'backspace': function() { 16 | if(!input.length) return; 17 | 18 | input = input.substr(0, input.length-1); 19 | }, 20 | 'keypress': function(data) { 21 | if(data.key.name != 'backspace') 22 | input += data.char; 23 | 24 | write(); 25 | }, 26 | 'enter': function() { 27 | setTimeout(self.next, 1, input); 28 | disp.dispose(); 29 | } 30 | }); 31 | 32 | write(); 33 | }); 34 | 35 | } -------------------------------------------------------------------------------- /lib/plugins/quit.js: -------------------------------------------------------------------------------- 1 | exports.require = ["command.route"]; 2 | exports.plugin = function(commandRoute, cli) { 3 | 4 | cli.onCommand('ctrl-c', function() { 5 | process.exit(); 6 | }); 7 | } -------------------------------------------------------------------------------- /lib/plugins/section.js: -------------------------------------------------------------------------------- 1 | exports.plugin = function(cli) { 2 | cli.section = function(message) { 3 | } 4 | } -------------------------------------------------------------------------------- /lib/plugins/table.js: -------------------------------------------------------------------------------- 1 | var Structr = require('structr'); 2 | 3 | exports.plugin = function(cli) { 4 | function normalizeOptions(ops) { 5 | var cliWidth = cli.columns(); 6 | 7 | var columns = ops.columns, 8 | normCols = [], 9 | vert = ops.vertical || ops.vert || ' ', 10 | horz = ops.horizontal || ops.horz || '', 11 | pad = Structr.copy(ops.pad, { left: 0, right: 0, top: 0, bottom: 0 }); 12 | 13 | if(ops.padRight) pad.right = ops.padRight; 14 | if(ops.padLeft) pad.left = ops.padLeft; 15 | if(ops.padTop) pad.top = ops.padTop; 16 | if(ops.padBottom) pad.bottom = ops.padBottom; 17 | if(!ops.width) ops.width = cliWidth; 18 | 19 | ops.width = Math.min(ops.width, cliWidth - pad.left - pad.right); 20 | 21 | 22 | if(ops.border) { 23 | if(vert == ' ') vert = ' | '; 24 | if(horz == '') horz = '–'; 25 | } 26 | 27 | 28 | //sum width of all columns combined 29 | var sumWidth = 0; 30 | 31 | 32 | for(var prop in columns) { 33 | var columnValue = columns[prop], 34 | normCol = { minWidth: 6, align: 'left' }, 35 | tocv = typeof columnValue; 36 | 37 | normCols.push(normCol) 38 | 39 | //['columnName'] 40 | if(tocv == 'string') { 41 | normCol.name = columnValue; 42 | } else { 43 | //{columnName:value} 44 | if(typeof prop == 'string') { 45 | normCol.name = prop; 46 | } 47 | 48 | 49 | if(tocv == 'number') { 50 | normCol.width = columnValue; 51 | } else 52 | if(tocv == 'object') { 53 | Structr.copy(columnValue, normCol); 54 | } 55 | } 56 | 57 | if(!normCol.width) normCol.width = 100/columns.length; 58 | 59 | sumWidth += normCol.width; 60 | } 61 | 62 | 63 | //subtract vert padding 64 | 65 | 66 | var sumActualWidth = 0, 67 | colsTaken = 0, 68 | numCols = normCols.length; 69 | var tableWidth = ops.width - vert.length * numCols; 70 | 71 | 72 | for(var i = 0; i < numCols; i++) { 73 | 74 | var column = normCols[i]; 75 | 76 | var percWidth = Math.round(column.width/sumWidth * tableWidth); 77 | actualWidth = Math.max(column.minWidth, ops.fixed ? column.width : percWidth), 78 | 79 | //diff between calculated perc width, and min width. used for penalization 80 | difference = actualWidth - percWidth; 81 | 82 | sumActualWidth += actualWidth; 83 | 84 | 85 | //this may happen if there are too many minWidths specified. In which case, not all columns 86 | //will be shown. Actual width will be set to zero 87 | if(sumActualWidth > ops.width) actualWidth -= Math.min(actualWidth, sumActualWidth - tableWidth); 88 | 89 | //actual width CANNOT be less than min width. e.g: single char column couold be huge. 90 | if(actualWidth < column.minWidth) actualWidth = 0; 91 | 92 | column.actualWidth = actualWidth; 93 | 94 | //penalize the rest of the columns. Width must *not* cli width 95 | sumWidth -= difference; 96 | } 97 | 98 | column.last = true; 99 | 100 | return { 101 | columns: normCols, 102 | ellipsis: ops.ellipsis, 103 | vert: vert, 104 | horz: horz, 105 | pad: pad, 106 | width: ops.width, 107 | numColumns: numCols, 108 | showLabels: !!ops.showLabels 109 | } 110 | } 111 | 112 | function splitLines(value) { 113 | return String(value || '').split(/[\r\n]/g); 114 | } 115 | 116 | function addLines(colLines, value, column) { 117 | 118 | var newLines = splitLines(value); 119 | 120 | 121 | for(var i = 0, n = newLines.length; i < n; i++) { 122 | addLine(colLines, newLines[i], column); 123 | } 124 | } 125 | 126 | function addLine(colLines, value, column) { 127 | 128 | //trim whitespace off the ends. line breaks = whitespace 129 | var buffer = value.replace(/^\s+|\s+$/g,''); 130 | 131 | var colors = buffer.match(/\u001b\[\d+m/g) || []; 132 | 133 | var padding = column.actualWidth - buffer.length + colors.join('').length; 134 | 135 | 136 | switch(column.align) { 137 | case 'right': 138 | buffer = cli.utils.padLeft(buffer, padding, ' '); 139 | break; 140 | 141 | case 'center': 142 | buffer = cli.utils.pad(buffer, Math.floor(padding/2), ' ', Math.ceil(padding/2)); 143 | break; 144 | 145 | default: 146 | if(!column.last) buffer = cli.utils.padRight(buffer, padding, ' '); 147 | break; 148 | } 149 | 150 | colLines.push(buffer); 151 | } 152 | 153 | function getRowLineTable(item, ops) { 154 | var lineTable = [], 155 | numLines = 0, 156 | cols = ops.numColumns; 157 | 158 | 159 | //get the lines. 160 | for(var j = 0, jn = cols; j < jn; j++) { 161 | var column = ops.columns[j], 162 | key = ops.columns[j].name; 163 | 164 | if(typeof key == 'function') { 165 | value = key(item) || ''; 166 | } else { 167 | value = item[key] || ''; 168 | } 169 | 170 | 171 | colLines = [], 172 | actualWidth = column.actualWidth; 173 | 174 | //width not present? skip the column 175 | if(!actualWidth) continue; 176 | 177 | var explicitLines = splitLines(value); 178 | 179 | 180 | for(var k = 0, kn = explicitLines.length; k < kn; k++) { 181 | 182 | 183 | var explicitLineValue = explicitLines[k]; 184 | 185 | if(explicitLineValue.length > actualWidth) { 186 | 187 | if(ops.ellipsis) { 188 | var newBuffer = explicitLineValue.substr(0, actualWidth-3) + cli.utils.repeat('.', Math.min(actualWidth, 3)); 189 | 190 | addLines(colLines, newBuffer, column); 191 | 192 | } else { 193 | var start = 0; 194 | 195 | //splice apart the single line, treating each chunk as a new line 196 | for(var k = actualWidth; k < explicitLineValue.length + actualWidth; k += actualWidth) { 197 | 198 | addLines(colLines, explicitLineValue.substr(start, actualWidth), column); 199 | start = k; 200 | } 201 | 202 | } 203 | } else { 204 | 205 | addLines(colLines, explicitLineValue, column); 206 | 207 | } 208 | } 209 | 210 | 211 | 212 | 213 | //if this column lines 214 | numLines = Math.max(numLines, colLines.length); 215 | 216 | 217 | //next add the line - need to check against all lines now 218 | lineTable.push(colLines); 219 | 220 | 221 | //need to go through all the column lines again, and 222 | //make sure all the lines match up properly 223 | for(var k = 0, kn = lineTable.length; k < kn; k++) { 224 | var line = lineTable[k]; 225 | 226 | //must have same number of lineTable 227 | if(line.length < numLines) { 228 | addLines(lineTable[k], cli.utils.repeat('\n', numLines - line.length -1), ops.columns[k]); 229 | } 230 | } 231 | } 232 | 233 | var rows = []; 234 | //inversed 235 | for(var i = 0, n = lineTable.length; i < n; i++) { 236 | var col = lineTable[i]; 237 | 238 | //each row 239 | for(var j = 0, jn = col.length; j < jn; j++) { 240 | if(!rows[j]) rows[j] = []; 241 | 242 | rows[j].push(col[j]); 243 | } 244 | } 245 | 246 | return rows; 247 | } 248 | 249 | function logRow(ops, buffer) { 250 | console.log(cli.utils.repeat(' ', ops.pad.left) + buffer); 251 | } 252 | 253 | function drawBreak(ops) { 254 | if(ops.horz) logRow(ops, cli.utils.repeat(ops.horz, ops.width)); 255 | } 256 | 257 | function drawRow(lineTable, ops) { 258 | for(var i = 0, n = lineTable.length; i < n; i++) { 259 | logRow(ops, lineTable[i].join(ops.vert)) 260 | } 261 | 262 | drawBreak(ops); 263 | } 264 | 265 | function drawTable(source, ops) { 266 | if(ops.pad.top) console.log(cli.utils.repeat('\n', ops.pad.top-1)); 267 | 268 | 269 | drawBreak(ops); 270 | 271 | for(var i = source.length; i--;) { 272 | var lineTable = getRowLineTable(source[i], ops) 273 | 274 | drawRow(lineTable, ops); 275 | } 276 | 277 | if(ops.pad.bottom) console.log(cli.utils.repeat('\n', ops.pad.bottom-1)); 278 | } 279 | 280 | 281 | cli.drawTable = cli.table = function(source, ops) { 282 | ops = normalizeOptions(ops); 283 | drawTable(source, ops); 284 | } 285 | } -------------------------------------------------------------------------------- /lib/plugins/tree.js: -------------------------------------------------------------------------------- 1 | utils = require('../utils'), 2 | Structr = require('structr'); 3 | 4 | //see http://en.wikipedia.org/wiki/Box-drawing_characters 5 | exports.plugin = function(cli) { 6 | 7 | //┌── 8 | //├── 9 | //└── 10 | 11 | cli.drawTree = cli.tree = function(tree, ops, tab) { 12 | if(!ops) ops = {}; 13 | 14 | 15 | var parts = { }; 16 | 17 | if(ops.pretty) { 18 | parts = { 19 | pipe: '|', 20 | tee: '┬', 21 | dash: '─', 22 | leftCorner: '└', 23 | left: '├', 24 | branch: utils.repeat('─', 1) 25 | } 26 | 27 | //plays a little more nicely with fonts such as terminus 28 | } else { 29 | parts = { 30 | pipe: '|', 31 | tee: '+', 32 | dash: '-', 33 | leftCorner: '+', 34 | left: '|', 35 | branch: utils.repeat('-', 1) 36 | } 37 | } 38 | 39 | Structr.copy(ops.parts || {}, parts); 40 | 41 | parts.tabs = utils.repeat(' ',parts.branch.length+1); 42 | 43 | if(!tab) tab = ''; 44 | 45 | var n = utils.objectSize(tree), 46 | i = 0, 47 | printedBreak = false; 48 | 49 | 50 | for(var index in tree) { 51 | 52 | var childrenOrValue = tree[index], 53 | toc = typeof childrenOrValue, 54 | toi = typeof index, 55 | edge = i < n-1 ? parts.left : parts.leftCorner; 56 | 57 | 58 | var value = !isNaN(Number(index)) ? childrenOrValue : index + ': ' + childrenOrValue; 59 | 60 | 61 | console.log('%s%s%s %s', tab, edge, parts.branch + ((toc == 'object') ? parts.tee : parts.dash), toc != 'object' ? value: index); 62 | 63 | 64 | if(toc == 'object') { 65 | printedBreak = cli.drawTree(childrenOrValue, ops, n > 1 && i < n-1 ? tab + parts.pipe + parts.tabs.substr(1) : tab + parts.tabs); 66 | } 67 | /*else 68 | if(toc == 'string' || toc == 'number') 69 | { 70 | 71 | }*/ 72 | 73 | i++; 74 | } 75 | 76 | 77 | //add extra breaks for folders - a little more readable 78 | if(!printedBreak) { 79 | console.log('%s',tab); 80 | printedBreak = true; 81 | } 82 | 83 | return printedBreak; 84 | } 85 | } -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | exports.padLeft = function(buffer, n, char) { 2 | return exports.repeat(char, n) + buffer; 3 | } 4 | 5 | exports.padRight = function(buffer, n, char) { 6 | return buffer + exports.repeat(char, n); 7 | } 8 | 9 | 10 | //pad on left & right 11 | exports.pad = function(buffer, ln, char, rn) { 12 | return exports.repeat(char, ln) + buffer + exports.repeat(char, rn || ln); 13 | } 14 | 15 | 16 | exports.fill = function(leftChar, ln, rightChar, rn) { 17 | return exports.repeat(leftChar, ln) + exports.repeat(rightChar, rn); 18 | } 19 | 20 | 21 | exports.repeat = function(char, n) { 22 | var buffer = ''; 23 | 24 | for(var i = Math.abs(n); i--;) { 25 | buffer += char; 26 | } 27 | 28 | return buffer; 29 | } 30 | 31 | exports.objectSize = function(target) { 32 | var n = 0; 33 | 34 | for(var i in target) n++; 35 | 36 | return n; 37 | } -------------------------------------------------------------------------------- /npm-debug.log: -------------------------------------------------------------------------------- 1 | 0 info it worked if it ends with ok 2 | 1 verbose cli [ 'node', '/usr/local/bin/npm', 'publish' ] 3 | 2 info using npm@1.4.24 4 | 3 info using node@v0.10.30 5 | 4 verbose publish [ '.' ] 6 | 5 verbose cache add [ '.', null ] 7 | 6 verbose cache add name=undefined spec="." args=[".",null] 8 | 7 verbose parsed url { protocol: null, 9 | 7 verbose parsed url slashes: null, 10 | 7 verbose parsed url auth: null, 11 | 7 verbose parsed url host: null, 12 | 7 verbose parsed url port: null, 13 | 7 verbose parsed url hostname: null, 14 | 7 verbose parsed url hash: null, 15 | 7 verbose parsed url search: null, 16 | 7 verbose parsed url query: null, 17 | 7 verbose parsed url pathname: '.', 18 | 7 verbose parsed url path: '.', 19 | 7 verbose parsed url href: '.' } 20 | 8 silly lockFile 3a52ce78- . 21 | 9 verbose lock . /Users/craig/.npm/3a52ce78-.lock 22 | 10 verbose tar pack [ '/Users/craig/.npm/celeri/0.3.3/package.tgz', '.' ] 23 | 11 verbose tarball /Users/craig/.npm/celeri/0.3.3/package.tgz 24 | 12 verbose folder . 25 | 13 info prepublish celeri@0.3.3 26 | 14 silly lockFile 1f1177db-tar tar://. 27 | 15 verbose lock tar://. /Users/craig/.npm/1f1177db-tar.lock 28 | 16 silly lockFile 143199a9-aig-npm-celeri-0-3-3-package-tgz tar:///Users/craig/.npm/celeri/0.3.3/package.tgz 29 | 17 verbose lock tar:///Users/craig/.npm/celeri/0.3.3/package.tgz /Users/craig/.npm/143199a9-aig-npm-celeri-0-3-3-package-tgz.lock 30 | 18 silly lockFile 1f1177db-tar tar://. 31 | 19 silly lockFile 1f1177db-tar tar://. 32 | 20 silly lockFile 143199a9-aig-npm-celeri-0-3-3-package-tgz tar:///Users/craig/.npm/celeri/0.3.3/package.tgz 33 | 21 silly lockFile 143199a9-aig-npm-celeri-0-3-3-package-tgz tar:///Users/craig/.npm/celeri/0.3.3/package.tgz 34 | 22 silly lockFile d7ee5b7f-s-craig-npm-celeri-0-3-3-package /Users/craig/.npm/celeri/0.3.3/package 35 | 23 verbose lock /Users/craig/.npm/celeri/0.3.3/package /Users/craig/.npm/d7ee5b7f-s-craig-npm-celeri-0-3-3-package.lock 36 | 24 silly lockFile d7ee5b7f-s-craig-npm-celeri-0-3-3-package /Users/craig/.npm/celeri/0.3.3/package 37 | 25 silly lockFile d7ee5b7f-s-craig-npm-celeri-0-3-3-package /Users/craig/.npm/celeri/0.3.3/package 38 | 26 silly lockFile 3a52ce78- . 39 | 27 silly lockFile 3a52ce78- . 40 | 28 silly publish { name: 'celeri', 41 | 28 silly publish description: 'CLI lib', 42 | 28 silly publish version: '0.3.3', 43 | 28 silly publish author: { name: 'Craig Condon' }, 44 | 28 silly publish repository: { type: 'git', url: 'http://github.com/crcn/celeri.git' }, 45 | 28 silly publish directories: { lib: './lib' }, 46 | 28 silly publish dependencies: 47 | 28 silly publish { colors: '0.5.x', 48 | 28 silly publish disposable: '0.0.x', 49 | 28 silly publish outcome: '0.0.x', 50 | 28 silly publish structr: '0.2.x', 51 | 28 silly publish underscore: '1.2.x', 52 | 28 silly publish tq: '0.0.x', 53 | 28 silly publish crema: '0.1.x', 54 | 28 silly publish beanpoll: '0.2.x', 55 | 28 silly publish plugin: '0.3.x', 56 | 28 silly publish keypress: '0.1.x', 57 | 28 silly publish dsync: '0.0.x' }, 58 | 28 silly publish main: './lib/index.js', 59 | 28 silly publish readme: '### C-e-L-er-I\n\n![Alt command line](http://i.imgur.com/DA77U.png)\n\n### Features:\n\n- History (up/down arrows)\n- Progress Bar\n- Loading/busy spinner\n- Password input\n- Confirmation \n- Prompt\n- Parse command line args\n- help menu, and sub help menu\n- Multi-line tables\n- Build flexible commands via [beanpole](https://github.com/spiceapps/beanpole)\n - OR statement \n - Middleware\n - Parameters \n- Trees\n- *Exposing Javascript*, and calling it from the command line - inspired by mongo\'s CLI utilitiy\n\n### To Do:\n\n- Help menu api\n- Title View \n- Custom colors for each view (input, loader, progress, table, etc.): exports.colors = {}\n- Error handling (display of command not found)\n- Add transports instead of depending on native stdin/stdout\n - Ability to use online\n\n\n\n## Usage:\n\n\n### .option(cmdOrOps, descOrCallback, callback)\n\nListens for a key (enter, up, left, backspace, etc.), or command. See [beanpole](https://github.com/spiceapps/beanpole) for documentation.\n\n#### Hello World: \n\n```javascript\n\nvar celeri = require(\'celeri\');\n\n//an option with info for the help menu\nceleri.option({\n command: \'hello :person\',\n description: \'Prints "hello [person]!"\',\n optional: {\n \'--age\': \'The person\\\'s age\',\n \'--gender\': \'The person\\\'s gender\'\n }\n}, function(data) {\n\n console.log("Hello %s!", data.person);\n \n if(data.age) console.log("%s is %d years old.", data.person, data.age); \n if(data.gender) console.log("%s is a %s.", data.person, data.gender); \n\n});\n\n//parse the command line args\nceleri.parse(process.argv);\n\n```\n\nInteractive in terminal:\n \n```\n# node ./cmd ↩\n> hello craig ↩\nhello craig!\n```\n\npassed as arguments:\n\n```\n# node ./hello hello craig --age=21 --gender=cat ↩\nhello craig!\ncraig is 21 years old.\ncraig is a cat.\n```\n\nHelp menu:\n\n```\n# node ./cmd help ↩\n\nUsage: [command] --arg=value --arg2\n\nHelp:\n help Show help menu\n [cmd] help Show command help menu\n\nCommands:\n hello Prints "hello [person]!""\n\n```\n\nCommand Specific help menu:\n\n```\n# node ./cmd hello help ↩\n\nPrints "hello [person]!""\n\nUsage: hello [person]\n\nOptional Flags: \n --age The person\'s age\n --gender The person\'s gender\n```\n\n\n\n### .usage(value)\n\nSets the help menu usage text\n\n```javascript\nceleri.usage(\'[command] --arg=value\');\n```\n\n\n#### "OR" statement:\n\n```javascript\n\n\nceleri.option(\'hello :name OR hi :name\', \'some description\', function(data)\n{\n\tconsole.log(\'Hello \' + data.name +\'!\');\n}).\noption(\'set address :zip OR set address :city :state :zip\', function(data)\n{\n\tconsole.log("City: %s, State: %s, Zip: %s ", data.city || \'None provided\', data.state || \'None provided\', data.zip);\n});\n\n```\n\n### .onJs(api)\n\nYou can easily expose javascript functions by providing an object:\n\n```javascript\n\n\nvar api = {\n sayHello: function(name) {\n console.log("hello %s!", name || \'craig\');\n }\n}\n\nceleri.onJs({ api: api });\n\n```\n\nIn terminal:\n \n node ./hello ↩\n > api.sayHello("john"); ↩\n hello john!\n\n### .progress(label, percent)\n\n```javascript\n\nvar i = 0;\n\nvar interval = setInterval(function()\n{\n\tceleri.progress(\'Label: \', i++);\n\t\n\tif(i == 100) clearInterval(interval);\n}, 10);\n\n```\n\n### .loading(label)\n\n```javascript\n\nvar spinner = celeri.loading(\'Processing: \');\n\nsetTimeout(function()\n{\n\tspinner.done(true);//undefined = done, true = success, false = fail\n}, 1000);\n\n````\n\n### .prompt(label, callback)\n\n```javascript\n\nceleri.prompt(\'Username: \', function(input)\n{\n\t\n});\n\n````\n\n### .confirm(message, callback)\n\n```javascript\n\nceleri.confirm("Do you want to continue?", function(yes)\n{\n\tif(yes)\n\t{\n\t\t//continue\n\t}\n});\n\n```\n\n### .password(label[, mask], callback)\n\n```javascript\n\t\n//mask = *\nceleri.password(\'Password: \', \'*\', function(input)\n{\n\t//password\n});\n\n//no mask\nceleri.password(\'Password: \', function(input)\n{\n\t//password\n});\n\n```\n\n### .auth(callback)\n\n```javascript\n\nceleri.auth(function(user, pass)\n{\n\t//auth here\n});\n\n```\n\n\n### .drawTable(objects, ops)\n\n```javascript\n\nvar objects = [\n \n {\n name: \'Craig\',\n age: 21,\n interests: \'Cooking, espresso, backpacking, coding\'\n },\n \n \n {\n name: \'Tim\',\n age: 21,\n interests: \'Design, Traveling, Photography\'\n \n }\n\n];\n\nceleri.drawTable(objects, {\n columns: [\'name\',\'age\',\'interests\']\n});\n\n\n``` \n\n\nGives you something like:\n\n\n![Alt command line](http://i.imgur.com/oUtC9.png)\n\n\nHere\'s a multi-line table:\n\n\n![Alt command line](http://i.imgur.com/O5o47.png) \n\n### .drawTree(tree) \n\nDraws a tree\n\n````javascript\n \n//print out the contents of the celeri object\nceleri.drawTree(celeri); \n\n````\n\nHere\'s another example:\n\n![Alt command line](http://i.imgur.com/4F0e0.png)\n\n\n### Let\'s kick it up a notch\n\n\n```javascript\n\nvar celeri = require(\'../lib\');\n\n\nvar credentials;\n\n\n \nceleri.option(\'login OR login :user :pass\', function(data)\n{\n \n //reference to the current request\n var self = this;\n \n\n //called after auth credentials have been entered in\n function onAuth(creds)\n {\n\n //credits wrong? DO NOT CONTINUE\n if(creds.user != \'user\' || creds.pass != \'pass\')\n {\n return console.log("Incorrect user / pass".red);\n }\n \n //otherwise, add the user to the CURRENT request so it can be passed\n //onto the next route listener\n self.user = creds.user;\n \n //cache the credentials so the user doesn\'t have to login each time\n credentials = creds;\n \n //not another listener? display a success response\n if(!self.next()) console.log("Logged in as %s", creds.user.green);\n }\n \n \n //user already logged in? pass!\n if(credentials)\n {\n onAuth(credentials);\n }\n \n //otherwise check if the user is passed in the route\n else\n if(data.user && data.pass)\n {\n onAuth(data);\n }\n \n //or prompt for authentication\n else\n {\n celeri.auth(function(user, pass)\n {\n onAuth({ user: user, pass: pass });\n });\n }\n});\n\n\n\n/**\n * This stuff\'s private. The user has to be authenticated *before* this command is executed\n */\n \nceleri.option(\'login -> account\', function()\n{\n console.log(\'Here\\\'s your account info %s!\', this.user.green);\n});\n\nceleri.open();\n\n\n\nceleri.parse(process.argv);\n\n\n```\n\nHere\'s what you get:\n\n![Alt command line](http://i.imgur.com/g7ywq.png)\n\n\n', 60 | 28 silly publish readmeFilename: 'README.md', 61 | 28 silly publish gitHead: '9524ec5fd8a11ba3864c95370250b39cb8cda721', 62 | 28 silly publish bugs: { url: 'https://github.com/crcn/celeri/issues' }, 63 | 28 silly publish homepage: 'https://github.com/crcn/celeri', 64 | 28 silly publish _id: 'celeri@0.3.3', 65 | 28 silly publish scripts: {}, 66 | 28 silly publish _shasum: 'c928976294fa87db395b17f9ff4bc02c7073877e', 67 | 28 silly publish _from: '.' } 68 | 29 verbose request where is /celeri 69 | 30 verbose request registry http://registry.npmjs.org/ 70 | 31 verbose request id 492647be4cedf87f 71 | 32 verbose url raw /celeri 72 | 33 verbose url resolving [ 'http://registry.npmjs.org/', './celeri' ] 73 | 34 verbose url resolved http://registry.npmjs.org/celeri 74 | 35 verbose request where is http://registry.npmjs.org/celeri 75 | 36 info trying registry request attempt 1 at 09:52:21 76 | 37 http PUT http://registry.npmjs.org/celeri 77 | 38 http 403 http://registry.npmjs.org/celeri 78 | 39 verbose headers { server: 'CouchDB/1.5.0 (Erlang OTP/R14B04)', 79 | 39 verbose headers 'content-type': 'application/json', 80 | 39 verbose headers 'cache-control': 'max-age=60', 81 | 39 verbose headers 'content-length': '20118', 82 | 39 verbose headers 'accept-ranges': 'bytes', 83 | 39 verbose headers date: 'Mon, 01 Sep 2014 16:52:22 GMT', 84 | 39 verbose headers via: '1.1 varnish', 85 | 39 verbose headers connection: 'keep-alive', 86 | 39 verbose headers 'x-served-by': 'cache-lax1430-LAX', 87 | 39 verbose headers 'x-cache': 'MISS', 88 | 39 verbose headers 'x-cache-hits': '0', 89 | 39 verbose headers 'x-timer': 'S1409590341.771219,VS0,VE241' } 90 | 40 error publish Failed PUT 403 91 | 41 error Error: forbidden cannot modify pre-existing version: 0.3.3 92 | 41 error old={"name":"celeri","description":"CLI lib","version":"0.3.3","author":{"name":"Craig Condon"},"repository":{"type":"git","url":"http://github.com/crcn/celeri.git"},"directories":{"lib":"./lib"},"dependencies":{"colors":"0.5.x","disposable":"0.0.x","outcome":"0.0.x","structr":"0.2.x","underscore":"1.2.x","tq":"0.0.x","crema":"0.1.x","beanpoll":"0.2.x","plugin":"0.3.x","keypress":"0.1.x","dsync":"0.0.x"},"main":"./lib/index.js","readme":"### C-e-L-er-I\u000a\u000a![Alt command line](http://i.imgur.com/DA77U.png)\u000a\u000a### Features:\u000a\u000a- History (up/down arrows)\u000a- Progress Bar\u000a- Loading/busy spinner\u000a- Password input\u000a- Confirmation \u000a- Prompt\u000a- Parse command line args\u000a- help menu, and sub help menu\u000a- Multi-line tables\u000a- Build flexible commands via [beanpole](https://github.com/spiceapps/beanpole)\u000a - OR statement \u000a - Middleware\u000a - Parameters \u000a- Trees\u000a- *Exposing Javascript*, and calling it from the command line - inspired by mongo's CLI utilitiy\u000a\u000a### To Do:\u000a\u000a- Help menu api\u000a- Title View \u000a- Custom colors for each view (input, loader, progress, table, etc.): exports.colors = {}\u000a- Error handling (display of command not found)\u000a- Add transports instead of depending on native stdin/stdout\u000a - Ability to use online\u000a\u000a\u000a\u000a## Usage:\u000a\u000a\u000a### .option(cmdOrOps, descOrCallback, callback)\u000a\u000aListens for a key (enter, up, left, backspace, etc.), or command. See [beanpole](https://github.com/spiceapps/beanpole) for documentation.\u000a\u000a#### Hello World: \u000a\u000a```javascript\u000a\u000avar celeri = require('celeri');\u000a\u000a//an option with info for the help menu\u000aceleri.option({\u000a command: 'hello :person',\u000a description: 'Prints \"hello [person]!\"',\u000a optional: {\u000a '--age': 'The person\\'s age',\u000a '--gender': 'The person\\'s gender'\u000a }\u000a}, function(data) {\u000a\u000a console.log(\"Hello %s!\", data.person);\u000a \u000a if(data.age) console.log(\"%s is %d years old.\", data.person, data.age); \u000a if(data.gender) console.log(\"%s is a %s.\", data.person, data.gender); \u000a\u000a});\u000a\u000a//parse the command line args\u000aceleri.parse(process.argv);\u000a\u000a```\u000a\u000aInteractive in terminal:\u000a \u000a```\u000a# node ./cmd ↩\u000a> hello craig ↩\u000ahello craig!\u000a```\u000a\u000apassed as arguments:\u000a\u000a```\u000a# node ./hello hello craig --age=21 --gender=cat ↩\u000ahello craig!\u000acraig is 21 years old.\u000acraig is a cat.\u000a```\u000a\u000aHelp menu:\u000a\u000a```\u000a# node ./cmd help ↩\u000a\u000aUsage: [command] --arg=value --arg2\u000a\u000aHelp:\u000a help Show help menu\u000a [cmd] help Show command help menu\u000a\u000aCommands:\u000a hello Prints \"hello [person]!\"\"\u000a\u000a```\u000a\u000aCommand Specific help menu:\u000a\u000a```\u000a# node ./cmd hello help ↩\u000a\u000aPrints \"hello [person]!\"\"\u000a\u000aUsage: hello [person]\u000a\u000aOptional Flags: \u000a --age The person's age\u000a --gender The person's gender\u000a```\u000a\u000a\u000a\u000a### .usage(value)\u000a\u000aSets the help menu usage text\u000a\u000a```javascript\u000aceleri.usage('[command] --arg=value');\u000a```\u000a\u000a\u000a#### \"OR\" statement:\u000a\u000a```javascript\u000a\u000a\u000aceleri.option('hello :name OR hi :name', 'some description', function(data)\u000a{\u000a\u0009console.log('Hello ' + data.name +'!');\u000a}).\u000aoption('set address :zip OR set address :city :state :zip', function(data)\u000a{\u000a\u0009console.log(\"City: %s, State: %s, Zip: %s \", data.city || 'None provided', data.state || 'None provided', data.zip);\u000a});\u000a\u000a```\u000a\u000a### .onJs(api)\u000a\u000aYou can easily expose javascript functions by providing an object:\u000a\u000a```javascript\u000a\u000a\u000avar api = {\u000a sayHello: function(name) {\u000a console.log(\"hello %s!\", name || 'craig');\u000a }\u000a}\u000a\u000aceleri.onJs({ api: api });\u000a\u000a```\u000a\u000aIn terminal:\u000a \u000a node ./hello ↩\u000a > api.sayHello(\"john\"); ↩\u000a hello john!\u000a\u000a### .progress(label, percent)\u000a\u000a```javascript\u000a\u000avar i = 0;\u000a\u000avar interval = setInterval(function()\u000a{\u000a\u0009celeri.progress('Label: ', i++);\u000a\u0009\u000a\u0009if(i == 100) clearInterval(i);\u000a}, 10);\u000a\u000a```\u000a\u000a### .loading(label)\u000a\u000a```javascript\u000a\u000avar spinner = celeri.loading('Processing: ');\u000a\u000asetTimeout(function()\u000a{\u000a\u0009spinner.done(true);//undefined = done, true = success, false = fail\u000a}, 1000);\u000a\u000a````\u000a\u000a### .prompt(label, callback)\u000a\u000a```javascript\u000a\u000aceleri.prompt('Username: ', function(input)\u000a{\u000a\u0009\u000a});\u000a\u000a````\u000a\u000a### .confirm(message, callback)\u000a\u000a```javascript\u000a\u000aceleri.confirm(\"Do you want to continue?\", function(yes)\u000a{\u000a\u0009if(yes)\u000a\u0009{\u000a\u0009\u0009//continue\u000a\u0009}\u000a});\u000a\u000a```\u000a\u000a### .password(label[, mask], callback)\u000a\u000a```javascript\u000a\u0009\u000a//mask = *\u000aceleri.password('Password: ', '*', function(input)\u000a{\u000a\u0009//password\u000a});\u000a\u000a//no mask\u000aceleri.password('Password: ', function(input)\u000a{\u000a\u0009//password\u000a});\u000a\u000a```\u000a\u000a### .auth(callback)\u000a\u000a```javascript\u000a\u000aceleri.auth(function(user, pass)\u000a{\u000a\u0009//auth here\u000a});\u000a\u000a```\u000a\u000a\u000a### .drawTable(objects, ops)\u000a\u000a```javascript\u000a\u000avar objects = [\u000a \u000a {\u000a name: 'Craig',\u000a age: 21,\u000a interests: 'Cooking, espresso, backpacking, coding'\u000a },\u000a \u000a \u000a {\u000a name: 'Tim',\u000a age: 21,\u000a interests: 'Design, Traveling, Photography'\u000a \u000a }\u000a\u000a];\u000a\u000aceleri.drawTable(objects, {\u000a columns: ['name','age','interests']\u000a});\u000a\u000a\u000a``` \u000a\u000a\u000aGives you something like:\u000a\u000a\u000a![Alt command line](http://i.imgur.com/oUtC9.png)\u000a\u000a\u000aHere's a multi-line table:\u000a\u000a\u000a![Alt command line](http://i.imgur.com/O5o47.png) \u000a\u000a### .drawTree(tree) \u000a\u000aDraws a tree\u000a\u000a````javascript\u000a \u000a//print out the contents of the celeri object\u000aceleri.drawTree(celeri); \u000a\u000a````\u000a\u000aHere's another example:\u000a\u000a![Alt command line](http://i.imgur.com/4F0e0.png)\u000a\u000a\u000a### Let's kick it up a notch\u000a\u000a\u000a```javascript\u000a\u000avar celeri = require('../lib');\u000a\u000a\u000avar credentials;\u000a\u000a\u000a \u000aceleri.option('login OR login :user :pass', function(data)\u000a{\u000a \u000a //reference to the current request\u000a var self = this;\u000a \u000a\u000a //called after auth credentials have been entered in\u000a function onAuth(creds)\u000a {\u000a\u000a //credits wrong? DO NOT CONTINUE\u000a if(creds.user != 'user' || creds.pass != 'pass')\u000a {\u000a return console.log(\"Incorrect user / pass\".red);\u000a }\u000a \u000a //otherwise, add the user to the CURRENT request so it can be passed\u000a //onto the next route listener\u000a self.user = creds.user;\u000a \u000a //cache the credentials so the user doesn't have to login each time\u000a credentials = creds;\u000a \u000a //not another listener? display a success response\u000a if(!self.next()) console.log(\"Logged in as %s\", creds.user.green);\u000a }\u000a \u000a \u000a //user already logged in? pass!\u000a if(credentials)\u000a {\u000a onAuth(credentials);\u000a }\u000a \u000a //otherwise check if the user is passed in the route\u000a else\u000a if(data.user && data.pass)\u000a {\u000a onAuth(data);\u000a }\u000a \u000a //or prompt for authentication\u000a else\u000a {\u000a celeri.auth(function(user, pass)\u000a {\u000a onAuth({ user: user, pass: pass });\u000a });\u000a }\u000a});\u000a\u000a\u000a\u000a/**\u000a * This stuff's private. The user has to be authenticated *before* this command is executed\u000a */\u000a \u000aceleri.option('login -> account', function()\u000a{\u000a console.log('Here\\'s your account info %s!', this.user.green);\u000a});\u000a\u000aceleri.open();\u000a\u000a\u000a\u000aceleri.parse(process.argv);\u000a\u000a\u000a```\u000a\u000aHere's what you get:\u000a\u000a![Alt command line](http://i.imgur.com/g7ywq.png)\u000a\u000a\u000a","readmeFilename":"README.md","_id":"celeri@0.3.3","dist":{"shasum":"d0538137ddbdb6960884b0ef0f838aac1d34ee3a","tarball":"http://registry.npmjs.org/celeri/-/celeri-0.3.3.tgz"},"_from":".","_npmVersion":"1.2.18","_npmUser":{"name":"architectd","email":"craig.j.condon@gmail.com"},"maintainers":[{"name":"architectd","email":"craig.j.condon@gmail.com"}]} 93 | 41 error new={"name":"celeri","description":"CLI lib","version":"0.3.3","author":{"name":"Craig Condon"},"repository":{"type":"git","url":"http://github.com/crcn/celeri.git"},"directories":{"lib":"./lib"},"dependencies":{"colors":"0.5.x","disposable":"0.0.x","outcome":"0.0.x","structr":"0.2.x","underscore":"1.2.x","tq":"0.0.x","crema":"0.1.x","beanpoll":"0.2.x","plugin":"0.3.x","keypress":"0.1.x","dsync":"0.0.x"},"main":"./lib/index.js","readme":"### C-e-L-er-I\u000a\u000a![Alt command line](http://i.imgur.com/DA77U.png)\u000a\u000a### Features:\u000a\u000a- History (up/down arrows)\u000a- Progress Bar\u000a- Loading/busy spinner\u000a- Password input\u000a- Confirmation \u000a- Prompt\u000a- Parse command line args\u000a- help menu, and sub help menu\u000a- Multi-line tables\u000a- Build flexible commands via [beanpole](https://github.com/spiceapps/beanpole)\u000a - OR statement \u000a - Middleware\u000a - Parameters \u000a- Trees\u000a- *Exposing Javascript*, and calling it from the command line - inspired by mongo's CLI utilitiy\u000a\u000a### To Do:\u000a\u000a- Help menu api\u000a- Title View \u000a- Custom colors for each view (input, loader, progress, table, etc.): exports.colors = {}\u000a- Error handling (display of command not found)\u000a- Add transports instead of depending on native stdin/stdout\u000a - Ability to use online\u000a\u000a\u000a\u000a## Usage:\u000a\u000a\u000a### .option(cmdOrOps, descOrCallback, callback)\u000a\u000aListens for a key (enter, up, left, backspace, etc.), or command. See [beanpole](https://github.com/spiceapps/beanpole) for documentation.\u000a\u000a#### Hello World: \u000a\u000a```javascript\u000a\u000avar celeri = require('celeri');\u000a\u000a//an option with info for the help menu\u000aceleri.option({\u000a command: 'hello :person',\u000a description: 'Prints \"hello [person]!\"',\u000a optional: {\u000a '--age': 'The person\\'s age',\u000a '--gender': 'The person\\'s gender'\u000a }\u000a}, function(data) {\u000a\u000a console.log(\"Hello %s!\", data.person);\u000a \u000a if(data.age) console.log(\"%s is %d years old.\", data.person, data.age); \u000a if(data.gender) console.log(\"%s is a %s.\", data.person, data.gender); \u000a\u000a});\u000a\u000a//parse the command line args\u000aceleri.parse(process.argv);\u000a\u000a```\u000a\u000aInteractive in terminal:\u000a \u000a```\u000a# node ./cmd ↩\u000a> hello craig ↩\u000ahello craig!\u000a```\u000a\u000apassed as arguments:\u000a\u000a```\u000a# node ./hello hello craig --age=21 --gender=cat ↩\u000ahello craig!\u000acraig is 21 years old.\u000acraig is a cat.\u000a```\u000a\u000aHelp menu:\u000a\u000a```\u000a# node ./cmd help ↩\u000a\u000aUsage: [command] --arg=value --arg2\u000a\u000aHelp:\u000a help Show help menu\u000a [cmd] help Show command help menu\u000a\u000aCommands:\u000a hello Prints \"hello [person]!\"\"\u000a\u000a```\u000a\u000aCommand Specific help menu:\u000a\u000a```\u000a# node ./cmd hello help ↩\u000a\u000aPrints \"hello [person]!\"\"\u000a\u000aUsage: hello [person]\u000a\u000aOptional Flags: \u000a --age The person's age\u000a --gender The person's gender\u000a```\u000a\u000a\u000a\u000a### .usage(value)\u000a\u000aSets the help menu usage text\u000a\u000a```javascript\u000aceleri.usage('[command] --arg=value');\u000a```\u000a\u000a\u000a#### \"OR\" statement:\u000a\u000a```javascript\u000a\u000a\u000aceleri.option('hello :name OR hi :name', 'some description', function(data)\u000a{\u000a\u0009console.log('Hello ' + data.name +'!');\u000a}).\u000aoption('set address :zip OR set address :city :state :zip', function(data)\u000a{\u000a\u0009console.log(\"City: %s, State: %s, Zip: %s \", data.city || 'None provided', data.state || 'None provided', data.zip);\u000a});\u000a\u000a```\u000a\u000a### .onJs(api)\u000a\u000aYou can easily expose javascript functions by providing an object:\u000a\u000a```javascript\u000a\u000a\u000avar api = {\u000a sayHello: function(name) {\u000a console.log(\"hello %s!\", name || 'craig');\u000a }\u000a}\u000a\u000aceleri.onJs({ api: api });\u000a\u000a```\u000a\u000aIn terminal:\u000a \u000a node ./hello ↩\u000a > api.sayHello(\"john\"); ↩\u000a hello john!\u000a\u000a### .progress(label, percent)\u000a\u000a```javascript\u000a\u000avar i = 0;\u000a\u000avar interval = setInterval(function()\u000a{\u000a\u0009celeri.progress('Label: ', i++);\u000a\u0009\u000a\u0009if(i == 100) clearInterval(interval);\u000a}, 10);\u000a\u000a```\u000a\u000a### .loading(label)\u000a\u000a```javascript\u000a\u000avar spinner = celeri.loading('Processing: ');\u000a\u000asetTimeout(function()\u000a{\u000a\u0009spinner.done(true);//undefined = done, true = success, false = fail\u000a}, 1000);\u000a\u000a````\u000a\u000a### .prompt(label, callback)\u000a\u000a```javascript\u000a\u000aceleri.prompt('Username: ', function(input)\u000a{\u000a\u0009\u000a});\u000a\u000a````\u000a\u000a### .confirm(message, callback)\u000a\u000a```javascript\u000a\u000aceleri.confirm(\"Do you want to continue?\", function(yes)\u000a{\u000a\u0009if(yes)\u000a\u0009{\u000a\u0009\u0009//continue\u000a\u0009}\u000a});\u000a\u000a```\u000a\u000a### .password(label[, mask], callback)\u000a\u000a```javascript\u000a\u0009\u000a//mask = *\u000aceleri.password('Password: ', '*', function(input)\u000a{\u000a\u0009//password\u000a});\u000a\u000a//no mask\u000aceleri.password('Password: ', function(input)\u000a{\u000a\u0009//password\u000a});\u000a\u000a```\u000a\u000a### .auth(callback)\u000a\u000a```javascript\u000a\u000aceleri.auth(function(user, pass)\u000a{\u000a\u0009//auth here\u000a});\u000a\u000a```\u000a\u000a\u000a### .drawTable(objects, ops)\u000a\u000a```javascript\u000a\u000avar objects = [\u000a \u000a {\u000a name: 'Craig',\u000a age: 21,\u000a interests: 'Cooking, espresso, backpacking, coding'\u000a },\u000a \u000a \u000a {\u000a name: 'Tim',\u000a age: 21,\u000a interests: 'Design, Traveling, Photography'\u000a \u000a }\u000a\u000a];\u000a\u000aceleri.drawTable(objects, {\u000a columns: ['name','age','interests']\u000a});\u000a\u000a\u000a``` \u000a\u000a\u000aGives you something like:\u000a\u000a\u000a![Alt command line](http://i.imgur.com/oUtC9.png)\u000a\u000a\u000aHere's a multi-line table:\u000a\u000a\u000a![Alt command line](http://i.imgur.com/O5o47.png) \u000a\u000a### .drawTree(tree) \u000a\u000aDraws a tree\u000a\u000a````javascript\u000a \u000a//print out the contents of the celeri object\u000aceleri.drawTree(celeri); \u000a\u000a````\u000a\u000aHere's another example:\u000a\u000a![Alt command line](http://i.imgur.com/4F0e0.png)\u000a\u000a\u000a### Let's kick it up a notch\u000a\u000a\u000a```javascript\u000a\u000avar celeri = require('../lib');\u000a\u000a\u000avar credentials;\u000a\u000a\u000a \u000aceleri.option('login OR login :user :pass', function(data)\u000a{\u000a \u000a //reference to the current request\u000a var self = this;\u000a \u000a\u000a //called after auth credentials have been entered in\u000a function onAuth(creds)\u000a {\u000a\u000a //credits wrong? DO NOT CONTINUE\u000a if(creds.user != 'user' || creds.pass != 'pass')\u000a {\u000a return console.log(\"Incorrect user / pass\".red);\u000a }\u000a \u000a //otherwise, add the user to the CURRENT request so it can be passed\u000a //onto the next route listener\u000a self.user = creds.user;\u000a \u000a //cache the credentials so the user doesn't have to login each time\u000a credentials = creds;\u000a \u000a //not another listener? display a success response\u000a if(!self.next()) console.log(\"Logged in as %s\", creds.user.green);\u000a }\u000a \u000a \u000a //user already logged in? pass!\u000a if(credentials)\u000a {\u000a onAuth(credentials);\u000a }\u000a \u000a //otherwise check if the user is passed in the route\u000a else\u000a if(data.user && data.pass)\u000a {\u000a onAuth(data);\u000a }\u000a \u000a //or prompt for authentication\u000a else\u000a {\u000a celeri.auth(function(user, pass)\u000a {\u000a onAuth({ user: user, pass: pass });\u000a });\u000a }\u000a});\u000a\u000a\u000a\u000a/**\u000a * This stuff's private. The user has to be authenticated *before* this command is executed\u000a */\u000a \u000aceleri.option('login -> account', function()\u000a{\u000a console.log('Here\\'s your account info %s!', this.user.green);\u000a});\u000a\u000aceleri.open();\u000a\u000a\u000a\u000aceleri.parse(process.argv);\u000a\u000a\u000a```\u000a\u000aHere's what you get:\u000a\u000a![Alt command line](http://i.imgur.com/g7ywq.png)\u000a\u000a\u000a","readmeFilename":"README.md","gitHead":"9524ec5fd8a11ba3864c95370250b39cb8cda721","bugs":{"url":"https://github.com/crcn/celeri/issues"},"homepage":"https://github.com/crcn/celeri","_id":"celeri@0.3.3","scripts":{},"_shasum":"c928976294fa87db395b17f9ff4bc02c7073877e","_from":".","_npmVersion":"1.4.24","_npmUser":{"name":"architectd","email":"craig.j.condon@gmail.com"},"maintainers":[{"name":"architectd","email":"craig.j.condon@gmail.com"}],"dist":{"shasum":"c928976294fa87db395b17f9ff4bc02c7073877e","tarball":"http://registry.npmjs.org/celeri/-/celeri-0.3.3.tgz"}}: celeri 94 | 41 error at RegClient. (/usr/local/lib/node_modules/npm/node_modules/npm-registry-client/lib/request.js:300:14) 95 | 41 error at Request._callback (/usr/local/lib/node_modules/npm/node_modules/npm-registry-client/lib/request.js:238:65) 96 | 41 error at Request.self.callback (/usr/local/lib/node_modules/npm/node_modules/request/request.js:123:22) 97 | 41 error at Request.emit (events.js:98:17) 98 | 41 error at Request. (/usr/local/lib/node_modules/npm/node_modules/request/request.js:893:14) 99 | 41 error at Request.emit (events.js:117:20) 100 | 41 error at IncomingMessage. (/usr/local/lib/node_modules/npm/node_modules/request/request.js:844:12) 101 | 41 error at IncomingMessage.emit (events.js:117:20) 102 | 41 error at _stream_readable.js:938:16 103 | 41 error at process._tickCallback (node.js:419:13) 104 | 42 error If you need help, you may report this *entire* log, 105 | 42 error including the npm and node versions, at: 106 | 42 error 107 | 43 error System Darwin 13.3.0 108 | 44 error command "node" "/usr/local/bin/npm" "publish" 109 | 45 error cwd /Users/craig/Developer/Public/celeri 110 | 46 error node -v v0.10.30 111 | 47 error npm -v 1.4.24 112 | 48 verbose exit [ 1, true ] 113 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "celeri", 3 | "description": "CLI lib", 4 | "version": "0.3.4", 5 | "author": "Craig Condon", 6 | "repository": { 7 | "type": "git", 8 | "url": "http://github.com/crcn/celeri.git" 9 | }, 10 | "directories": { 11 | "lib": "./lib" 12 | }, 13 | "dependencies": { 14 | "colors": "0.5.x", 15 | "disposable": "0.0.x", 16 | "outcome": "0.0.x", 17 | "structr": "0.2.x", 18 | "underscore": "1.2.x", 19 | "tq": "0.0.x", 20 | "crema": "0.1.x", 21 | "beanpoll": "0.2.x", 22 | "plugin": "0.3.x", 23 | "keypress": "0.1.x", 24 | "dsync": "0.0.x" 25 | }, 26 | "main": "./lib/index.js" 27 | } 28 | -------------------------------------------------------------------------------- /project.sublime-project: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crcn/celeri/f10471478b9119485c7c72a49015e22ec4339e29/project.sublime-project -------------------------------------------------------------------------------- /project.sublime-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "auto_complete": 3 | { 4 | "selected_items": 5 | [ 6 | ] 7 | }, 8 | "buffers": 9 | [ 10 | { 11 | "contents": "", 12 | "file": "lib/plugins/api.js", 13 | "file_size": -1, 14 | "file_write_time": -1, 15 | "settings": 16 | { 17 | "buffer_size": 0, 18 | "line_ending": "Unix" 19 | } 20 | }, 21 | { 22 | "file": "lib/plugins/command.route.js", 23 | "settings": 24 | { 25 | "buffer_size": 2573, 26 | "line_ending": "Unix" 27 | } 28 | }, 29 | { 30 | "file": "/tmp/subl stdin XpNp73.txt", 31 | "settings": 32 | { 33 | "buffer_size": 0, 34 | "line_ending": "Unix" 35 | } 36 | }, 37 | { 38 | "file": "/tmp/subl stdin Afst66.txt", 39 | "settings": 40 | { 41 | "buffer_size": 0, 42 | "line_ending": "Unix" 43 | } 44 | }, 45 | { 46 | "file": "/tmp/subl stdin WyIHUU.txt", 47 | "settings": 48 | { 49 | "buffer_size": 0, 50 | "line_ending": "Unix" 51 | } 52 | }, 53 | { 54 | "file": "/tmp/subl stdin wHVTmD.txt", 55 | "settings": 56 | { 57 | "buffer_size": 0, 58 | "line_ending": "Unix" 59 | } 60 | }, 61 | { 62 | "file": "examples/api.js", 63 | "settings": 64 | { 65 | "buffer_size": 68, 66 | "line_ending": "Unix" 67 | } 68 | }, 69 | { 70 | "file": "lib/plugins/exec.js", 71 | "settings": 72 | { 73 | "buffer_size": 1901, 74 | "line_ending": "Unix" 75 | } 76 | }, 77 | { 78 | "file": "/tmp/subl stdin XiqGfi.txt", 79 | "settings": 80 | { 81 | "buffer_size": 0, 82 | "line_ending": "Unix" 83 | } 84 | }, 85 | { 86 | "file": "lib/plugins/history.js", 87 | "settings": 88 | { 89 | "buffer_size": 669, 90 | "line_ending": "Unix" 91 | } 92 | }, 93 | { 94 | "file": "lib/plugins/loading.js", 95 | "settings": 96 | { 97 | "buffer_size": 967, 98 | "line_ending": "Unix" 99 | } 100 | }, 101 | { 102 | "file": "lib/plugins/nav.js", 103 | "settings": 104 | { 105 | "buffer_size": 452, 106 | "line_ending": "Unix" 107 | } 108 | }, 109 | { 110 | "file": "lib/plugins/password.js", 111 | "settings": 112 | { 113 | "buffer_size": 1168, 114 | "line_ending": "Unix" 115 | } 116 | }, 117 | { 118 | "file": "lib/plugins/progress.js", 119 | "settings": 120 | { 121 | "buffer_size": 721, 122 | "line_ending": "Unix" 123 | } 124 | }, 125 | { 126 | "file": "/tmp/subl stdin N0nnml.txt", 127 | "settings": 128 | { 129 | "buffer_size": 0, 130 | "line_ending": "Unix" 131 | } 132 | }, 133 | { 134 | "file": "/tmp/subl stdin uhsB1S.txt", 135 | "settings": 136 | { 137 | "buffer_size": 0, 138 | "line_ending": "Unix" 139 | } 140 | }, 141 | { 142 | "file": "/tmp/subl stdin Xq4lWW.txt", 143 | "settings": 144 | { 145 | "buffer_size": 0, 146 | "line_ending": "Unix" 147 | } 148 | }, 149 | { 150 | "file": "/tmp/subl stdin qdLyaq.txt", 151 | "settings": 152 | { 153 | "buffer_size": 0, 154 | "line_ending": "Unix" 155 | } 156 | }, 157 | { 158 | "file": "/tmp/subl stdin d5740F.txt", 159 | "settings": 160 | { 161 | "buffer_size": 0, 162 | "line_ending": "Unix" 163 | } 164 | }, 165 | { 166 | "contents": "", 167 | "file": "/tmp/subl stdin sEhF0J.txt", 168 | "file_size": -1, 169 | "file_write_time": -1, 170 | "settings": 171 | { 172 | "buffer_size": 0, 173 | "line_ending": "Unix" 174 | } 175 | }, 176 | { 177 | "file": "/tmp/subl stdin yDYBRS.txt", 178 | "settings": 179 | { 180 | "buffer_size": 0, 181 | "line_ending": "Unix" 182 | } 183 | }, 184 | { 185 | "file": "lib/plugins/prompt.js", 186 | "settings": 187 | { 188 | "buffer_size": 841, 189 | "line_ending": "Unix" 190 | } 191 | }, 192 | { 193 | "file": "/Users/craig/Dropbox/Developer/Jobs/Spice/private/mealplanner/README.md", 194 | "settings": 195 | { 196 | "buffer_size": 0, 197 | "line_ending": "Unix" 198 | } 199 | }, 200 | { 201 | "file": "/tmp/subl stdin kWHZ2H.txt", 202 | "settings": 203 | { 204 | "buffer_size": 0, 205 | "line_ending": "Unix" 206 | } 207 | }, 208 | { 209 | "file": "lib/plugins/quit.js", 210 | "settings": 211 | { 212 | "buffer_size": 157, 213 | "line_ending": "Unix" 214 | } 215 | }, 216 | { 217 | "file": "lib/plugins/section.js", 218 | "settings": 219 | { 220 | "buffer_size": 78, 221 | "line_ending": "Unix" 222 | } 223 | }, 224 | { 225 | "file": "/tmp/subl stdin Ek4KN3.txt", 226 | "settings": 227 | { 228 | "buffer_size": 0, 229 | "line_ending": "Unix" 230 | } 231 | }, 232 | { 233 | "file": "lib/plugins/tree.js", 234 | "settings": 235 | { 236 | "buffer_size": 2237, 237 | "line_ending": "Unix" 238 | } 239 | }, 240 | { 241 | "file": "examples/hello.js", 242 | "settings": 243 | { 244 | "buffer_size": 1031, 245 | "line_ending": "Unix" 246 | } 247 | }, 248 | { 249 | "file": "/tmp/subl stdin UYGUNk.txt", 250 | "settings": 251 | { 252 | "buffer_size": 0, 253 | "line_ending": "Unix" 254 | } 255 | }, 256 | { 257 | "file": "examples/authadv.js", 258 | "settings": 259 | { 260 | "buffer_size": 1185, 261 | "line_ending": "Unix" 262 | } 263 | }, 264 | { 265 | "file": "examples/hello2.js", 266 | "settings": 267 | { 268 | "buffer_size": 404, 269 | "line_ending": "Unix" 270 | } 271 | }, 272 | { 273 | "file": "package.json", 274 | "settings": 275 | { 276 | "buffer_size": 545, 277 | "line_ending": "Unix" 278 | } 279 | }, 280 | { 281 | "file": "/tmp/subl stdin ibImam.txt", 282 | "settings": 283 | { 284 | "buffer_size": 0, 285 | "line_ending": "Unix" 286 | } 287 | }, 288 | { 289 | "file": "/tmp/subl stdin v6XN9x.txt", 290 | "settings": 291 | { 292 | "buffer_size": 0, 293 | "line_ending": "Unix" 294 | } 295 | }, 296 | { 297 | "file": "/tmp/subl stdin y475E2.txt", 298 | "settings": 299 | { 300 | "buffer_size": 0, 301 | "line_ending": "Unix" 302 | } 303 | }, 304 | { 305 | "file": "/tmp/subl stdin HAFRpJ.txt", 306 | "settings": 307 | { 308 | "buffer_size": 0, 309 | "line_ending": "Unix" 310 | } 311 | }, 312 | { 313 | "file": "lib/index.js", 314 | "settings": 315 | { 316 | "buffer_size": 5692, 317 | "line_ending": "Unix" 318 | } 319 | }, 320 | { 321 | "file": "/tmp/subl stdin 3zLYTl.txt", 322 | "settings": 323 | { 324 | "buffer_size": 0, 325 | "line_ending": "Unix" 326 | } 327 | }, 328 | { 329 | "file": "/tmp/subl stdin DMt2R5.txt", 330 | "settings": 331 | { 332 | "buffer_size": 0, 333 | "line_ending": "Unix" 334 | } 335 | }, 336 | { 337 | "file": "lib/plugins/command.js", 338 | "settings": 339 | { 340 | "buffer_size": 549, 341 | "line_ending": "Unix" 342 | } 343 | }, 344 | { 345 | "file": "/tmp/subl stdin q2Wyls.txt", 346 | "settings": 347 | { 348 | "buffer_size": 0, 349 | "line_ending": "Unix" 350 | } 351 | }, 352 | { 353 | "file": "lib/plugins/help.js", 354 | "settings": 355 | { 356 | "buffer_size": 3298, 357 | "line_ending": "Unix" 358 | } 359 | }, 360 | { 361 | "file": "/tmp/subl stdin SRSeTW.txt", 362 | "settings": 363 | { 364 | "buffer_size": 0, 365 | "line_ending": "Unix" 366 | } 367 | }, 368 | { 369 | "file": "/tmp/subl stdin 9HshxV.txt", 370 | "settings": 371 | { 372 | "buffer_size": 0, 373 | "line_ending": "Unix" 374 | } 375 | }, 376 | { 377 | "file": "/tmp/subl stdin TXrQgd.txt", 378 | "settings": 379 | { 380 | "buffer_size": 0, 381 | "line_ending": "Unix" 382 | } 383 | }, 384 | { 385 | "file": "/tmp/subl stdin mDq2oO.txt", 386 | "settings": 387 | { 388 | "buffer_size": 0, 389 | "line_ending": "Unix" 390 | } 391 | }, 392 | { 393 | "file": "lib/plugins/command.api.js", 394 | "settings": 395 | { 396 | "buffer_size": 2154, 397 | "line_ending": "Unix" 398 | } 399 | }, 400 | { 401 | "file": "/tmp/subl stdin Toznbe.txt", 402 | "settings": 403 | { 404 | "buffer_size": 0, 405 | "line_ending": "Unix" 406 | } 407 | }, 408 | { 409 | "file": "lib/plugins/argv/index.js", 410 | "settings": 411 | { 412 | "buffer_size": 717, 413 | "line_ending": "Unix" 414 | } 415 | }, 416 | { 417 | "file": "/tmp/subl stdin KDyeEd.txt", 418 | "settings": 419 | { 420 | "buffer_size": 0, 421 | "line_ending": "Unix" 422 | } 423 | }, 424 | { 425 | "file": "/tmp/subl stdin JVytqQ.txt", 426 | "settings": 427 | { 428 | "buffer_size": 0, 429 | "line_ending": "Unix" 430 | } 431 | }, 432 | { 433 | "file": "lib/plugins/confirm.js", 434 | "settings": 435 | { 436 | "buffer_size": 884, 437 | "line_ending": "Unix" 438 | } 439 | }, 440 | { 441 | "file": "lib/plugins/enter.js", 442 | "settings": 443 | { 444 | "buffer_size": 1476, 445 | "line_ending": "Unix" 446 | } 447 | }, 448 | { 449 | "file": "/tmp/subl stdin 63mSHQ.txt", 450 | "settings": 451 | { 452 | "buffer_size": 0, 453 | "line_ending": "Unix" 454 | } 455 | }, 456 | { 457 | "file": "/tmp/subl stdin PDf1wr.txt", 458 | "settings": 459 | { 460 | "buffer_size": 0, 461 | "line_ending": "Unix" 462 | } 463 | }, 464 | { 465 | "file": "/tmp/subl stdin I1hkSY.txt", 466 | "settings": 467 | { 468 | "buffer_size": 0, 469 | "line_ending": "Unix" 470 | } 471 | }, 472 | { 473 | "file": "examples/auth.js", 474 | "settings": 475 | { 476 | "buffer_size": 239, 477 | "line_ending": "Unix" 478 | } 479 | }, 480 | { 481 | "file": "examples/table3.js", 482 | "settings": 483 | { 484 | "buffer_size": 1655, 485 | "line_ending": "Unix" 486 | } 487 | }, 488 | { 489 | "file": "examples/table2.js", 490 | "settings": 491 | { 492 | "buffer_size": 515, 493 | "line_ending": "Unix" 494 | } 495 | }, 496 | { 497 | "file": "/tmp/subl stdin VeLlAE.txt", 498 | "settings": 499 | { 500 | "buffer_size": 0, 501 | "line_ending": "Unix" 502 | } 503 | }, 504 | { 505 | "file": "node_modules/beanpoll/lib/router.js", 506 | "settings": 507 | { 508 | "buffer_size": 3437, 509 | "line_ending": "Unix" 510 | } 511 | }, 512 | { 513 | "file": "README.md", 514 | "settings": 515 | { 516 | "buffer_size": 6401, 517 | "line_ending": "Unix" 518 | } 519 | }, 520 | { 521 | "file": "/tmp/subl stdin bR34jM.txt", 522 | "settings": 523 | { 524 | "buffer_size": 0, 525 | "line_ending": "Unix" 526 | } 527 | }, 528 | { 529 | "file": "examples/hello3.js", 530 | "settings": 531 | { 532 | "buffer_size": 588, 533 | "line_ending": "Unix" 534 | } 535 | }, 536 | { 537 | "file": ".cupboard", 538 | "settings": 539 | { 540 | "buffer_size": 25, 541 | "line_ending": "Unix" 542 | } 543 | }, 544 | { 545 | "file": "/tmp/subl stdin 4khPaT.txt", 546 | "settings": 547 | { 548 | "buffer_size": 0, 549 | "line_ending": "Unix" 550 | } 551 | } 552 | ], 553 | "build_system": "", 554 | "command_palette": 555 | { 556 | "height": 392.0, 557 | "selected_items": 558 | [ 559 | ], 560 | "width": 467.0 561 | }, 562 | "console": 563 | { 564 | "height": 136.0 565 | }, 566 | "distraction_free": 567 | { 568 | "menu_visible": true, 569 | "show_minimap": false, 570 | "show_open_files": false, 571 | "show_tabs": false, 572 | "side_bar_visible": false, 573 | "status_bar_visible": false 574 | }, 575 | "file_history": 576 | [ 577 | "/tmp/subl stdin BuD5gZ.txt", 578 | "/Users/craig/Dropbox/Developer/Public/celeri/lib/plugins/table.js", 579 | "/Users/craig/Dropbox/Developer/Public/celeri/examples/main.js", 580 | "/tmp/subl stdin B1otjc.txt", 581 | "/Volumes/minimac/Users/craig/Dropbox/Developer/Public/celeri/lib/plugins/enter.js", 582 | "/Volumes/minimac/Users/craig/Dropbox/Developer/Public/celeri/lib/plugins/confirm.js", 583 | "/Volumes/minimac/Users/craig/Dropbox/Developer/Public/celeri/lib/plugins/backspace.js", 584 | "/tmp/subl stdin NdGy42.txt", 585 | "/tmp/subl stdin EAGME9.txt", 586 | "/Volumes/minimac/Users/craig/Dropbox/Developer/Public/celeri/lib/plugins/auth.js", 587 | "/Volumes/minimac/Users/craig/Dropbox/Developer/Public/celeri/README.md", 588 | "/tmp/subl stdin V0bkl5.txt", 589 | "/Volumes/minimac/Users/craig/Dropbox/Developer/Public/celeri/lib/plugins/command.js", 590 | "/tmp/subl stdin IxtHOA.txt", 591 | "/tmp/subl stdin xv6X3t.txt", 592 | "/Volumes/minimac/Users/craig/Dropbox/Developer/Public/celeri/package.json", 593 | "/tmp/subl stdin xnHhar.txt", 594 | "/Volumes/minimac/Users/craig/Dropbox/Developer/Public/celeri/lib/plugins/command.api.js", 595 | "/tmp/subl stdin XyyIs7.txt", 596 | "/Volumes/minimac/Users/craig/Dropbox/Developer/Public/celeri/lib/utils.js", 597 | "/Volumes/minimac/Users/craig/Dropbox/Developer/Public/celeri/lib/index.js", 598 | "/Volumes/minimac/Users/craig/Dropbox/Developer/Public/celeri/lib/plugins/help.js", 599 | "/Volumes/minimac/Users/craig/Dropbox/Developer/Public/celeri/lib/modules/auth.js", 600 | "/Volumes/minimac/Users/craig/Dropbox/Developer/Public/beet/lib/index.js", 601 | "/tmp/subl stdin 292YvE.txt" 602 | ], 603 | "find": 604 | { 605 | "height": 33.0 606 | }, 607 | "find_in_files": 608 | { 609 | "height": 0.0, 610 | "where_history": 611 | [ 612 | ] 613 | }, 614 | "find_state": 615 | { 616 | "case_sensitive": false, 617 | "find_history": 618 | [ 619 | "normalizeApi", 620 | "Structr", 621 | "last", 622 | "minWidth", 623 | "percW", 624 | "addLines", 625 | "value", 626 | "addLines", 627 | "path", 628 | "crema", 629 | "console.l", 630 | "description", 631 | "option", 632 | "onCommand", 633 | "usage", 634 | "addHelp", 635 | "emit", 636 | "getHandler", 637 | "try", 638 | "next", 639 | "data", 640 | "emit", 641 | "beanpoll", 642 | "exports.emit", 643 | "emit", 644 | "exports.emit", 645 | "callback", 646 | "parse", 647 | "Source", 648 | "beanpole", 649 | "error", 650 | "try", 651 | "cli.on", 652 | "onComm", 653 | "celery.on(", 654 | "on", 655 | ".on(", 656 | "on(", 657 | "desc", 658 | "flattenMethods", 659 | "_inputPrefix", 660 | "emit", 661 | "router", 662 | "_delimiter", 663 | "_delimiterRepl", 664 | "_delimiter", 665 | "_toRoute", 666 | "exports.deli", 667 | "delimiter", 668 | "_delimiterRepl", 669 | "normalizeOptions", 670 | "queue", 671 | "nodefs", 672 | "onEnd", 673 | "register", 674 | "_rem", 675 | "regis", 676 | "_addTransaction", 677 | "end", 678 | "dispose", 679 | ".dispose", 680 | "register", 681 | "kill", 682 | "trans =", 683 | ".remove", 684 | "args", 685 | "--all" 686 | ], 687 | "highlight": true, 688 | "in_selection": false, 689 | "preserve_case": false, 690 | "regex": false, 691 | "replace_history": 692 | [ 693 | ], 694 | "reverse": false, 695 | "show_context": true, 696 | "use_buffer2": true, 697 | "whole_word": false, 698 | "wrap": true 699 | }, 700 | "groups": 701 | [ 702 | { 703 | "selected": 47, 704 | "sheets": 705 | [ 706 | { 707 | "buffer": 0, 708 | "file": "lib/plugins/api.js", 709 | "settings": 710 | { 711 | "buffer_size": 0, 712 | "regions": 713 | { 714 | }, 715 | "selection": 716 | [ 717 | [ 718 | 0, 719 | 0 720 | ] 721 | ], 722 | "settings": 723 | { 724 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage" 725 | }, 726 | "translation.x": 0.0, 727 | "translation.y": 0.0, 728 | "zoom_level": 1.0 729 | }, 730 | "type": "text" 731 | }, 732 | { 733 | "buffer": 1, 734 | "file": "lib/plugins/command.route.js", 735 | "settings": 736 | { 737 | "buffer_size": 2573, 738 | "regions": 739 | { 740 | }, 741 | "selection": 742 | [ 743 | [ 744 | 0, 745 | 0 746 | ] 747 | ], 748 | "settings": 749 | { 750 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 751 | "translate_tabs_to_spaces": false 752 | }, 753 | "translation.x": 0.0, 754 | "translation.y": 0.0, 755 | "zoom_level": 1.0 756 | }, 757 | "type": "text" 758 | }, 759 | { 760 | "buffer": 2, 761 | "file": "/tmp/subl stdin XpNp73.txt", 762 | "settings": 763 | { 764 | "buffer_size": 0, 765 | "regions": 766 | { 767 | }, 768 | "selection": 769 | [ 770 | [ 771 | 0, 772 | 0 773 | ] 774 | ], 775 | "settings": 776 | { 777 | "syntax": "Packages/Text/Plain text.tmLanguage" 778 | }, 779 | "translation.x": 0.0, 780 | "translation.y": 0.0, 781 | "zoom_level": 1.0 782 | }, 783 | "type": "text" 784 | }, 785 | { 786 | "buffer": 3, 787 | "file": "/tmp/subl stdin Afst66.txt", 788 | "settings": 789 | { 790 | "buffer_size": 0, 791 | "regions": 792 | { 793 | }, 794 | "selection": 795 | [ 796 | [ 797 | 0, 798 | 0 799 | ] 800 | ], 801 | "settings": 802 | { 803 | "syntax": "Packages/Text/Plain text.tmLanguage" 804 | }, 805 | "translation.x": 0.0, 806 | "translation.y": 0.0, 807 | "zoom_level": 1.0 808 | }, 809 | "type": "text" 810 | }, 811 | { 812 | "buffer": 4, 813 | "file": "/tmp/subl stdin WyIHUU.txt", 814 | "settings": 815 | { 816 | "buffer_size": 0, 817 | "regions": 818 | { 819 | }, 820 | "selection": 821 | [ 822 | [ 823 | 0, 824 | 0 825 | ] 826 | ], 827 | "settings": 828 | { 829 | "syntax": "Packages/Text/Plain text.tmLanguage" 830 | }, 831 | "translation.x": 0.0, 832 | "translation.y": 0.0, 833 | "zoom_level": 1.0 834 | }, 835 | "type": "text" 836 | }, 837 | { 838 | "buffer": 5, 839 | "file": "/tmp/subl stdin wHVTmD.txt", 840 | "settings": 841 | { 842 | "buffer_size": 0, 843 | "regions": 844 | { 845 | }, 846 | "selection": 847 | [ 848 | [ 849 | 0, 850 | 0 851 | ] 852 | ], 853 | "settings": 854 | { 855 | "syntax": "Packages/Text/Plain text.tmLanguage" 856 | }, 857 | "translation.x": 0.0, 858 | "translation.y": 0.0, 859 | "zoom_level": 1.0 860 | }, 861 | "type": "text" 862 | }, 863 | { 864 | "buffer": 6, 865 | "file": "examples/api.js", 866 | "settings": 867 | { 868 | "buffer_size": 68, 869 | "regions": 870 | { 871 | }, 872 | "selection": 873 | [ 874 | [ 875 | 36, 876 | 36 877 | ] 878 | ], 879 | "settings": 880 | { 881 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage" 882 | }, 883 | "translation.x": 0.0, 884 | "translation.y": 0.0, 885 | "zoom_level": 1.0 886 | }, 887 | "type": "text" 888 | }, 889 | { 890 | "buffer": 7, 891 | "file": "lib/plugins/exec.js", 892 | "settings": 893 | { 894 | "buffer_size": 1901, 895 | "regions": 896 | { 897 | }, 898 | "selection": 899 | [ 900 | [ 901 | 382, 902 | 382 903 | ] 904 | ], 905 | "settings": 906 | { 907 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 908 | "tab_size": 4, 909 | "translate_tabs_to_spaces": true 910 | }, 911 | "translation.x": 0.0, 912 | "translation.y": 0.0, 913 | "zoom_level": 1.0 914 | }, 915 | "type": "text" 916 | }, 917 | { 918 | "buffer": 8, 919 | "file": "/tmp/subl stdin XiqGfi.txt", 920 | "settings": 921 | { 922 | "buffer_size": 0, 923 | "regions": 924 | { 925 | }, 926 | "selection": 927 | [ 928 | [ 929 | 0, 930 | 0 931 | ] 932 | ], 933 | "settings": 934 | { 935 | "syntax": "Packages/Text/Plain text.tmLanguage" 936 | }, 937 | "translation.x": 0.0, 938 | "translation.y": 0.0, 939 | "zoom_level": 1.0 940 | }, 941 | "type": "text" 942 | }, 943 | { 944 | "buffer": 9, 945 | "file": "lib/plugins/history.js", 946 | "settings": 947 | { 948 | "buffer_size": 669, 949 | "regions": 950 | { 951 | }, 952 | "selection": 953 | [ 954 | [ 955 | 0, 956 | 0 957 | ] 958 | ], 959 | "settings": 960 | { 961 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 962 | "tab_size": 4, 963 | "translate_tabs_to_spaces": true 964 | }, 965 | "translation.x": 0.0, 966 | "translation.y": 0.0, 967 | "zoom_level": 1.0 968 | }, 969 | "type": "text" 970 | }, 971 | { 972 | "buffer": 10, 973 | "file": "lib/plugins/loading.js", 974 | "settings": 975 | { 976 | "buffer_size": 967, 977 | "regions": 978 | { 979 | }, 980 | "selection": 981 | [ 982 | [ 983 | 524, 984 | 524 985 | ] 986 | ], 987 | "settings": 988 | { 989 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 990 | "tab_size": 4, 991 | "translate_tabs_to_spaces": true 992 | }, 993 | "translation.x": 0.0, 994 | "translation.y": 0.0, 995 | "zoom_level": 1.0 996 | }, 997 | "type": "text" 998 | }, 999 | { 1000 | "buffer": 11, 1001 | "file": "lib/plugins/nav.js", 1002 | "settings": 1003 | { 1004 | "buffer_size": 452, 1005 | "regions": 1006 | { 1007 | }, 1008 | "selection": 1009 | [ 1010 | [ 1011 | 0, 1012 | 0 1013 | ] 1014 | ], 1015 | "settings": 1016 | { 1017 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1018 | "tab_size": 4, 1019 | "translate_tabs_to_spaces": true 1020 | }, 1021 | "translation.x": 0.0, 1022 | "translation.y": 0.0, 1023 | "zoom_level": 1.0 1024 | }, 1025 | "type": "text" 1026 | }, 1027 | { 1028 | "buffer": 12, 1029 | "file": "lib/plugins/password.js", 1030 | "settings": 1031 | { 1032 | "buffer_size": 1168, 1033 | "regions": 1034 | { 1035 | }, 1036 | "selection": 1037 | [ 1038 | [ 1039 | 616, 1040 | 616 1041 | ] 1042 | ], 1043 | "settings": 1044 | { 1045 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1046 | "tab_size": 4, 1047 | "translate_tabs_to_spaces": true 1048 | }, 1049 | "translation.x": 0.0, 1050 | "translation.y": 0.0, 1051 | "zoom_level": 1.0 1052 | }, 1053 | "type": "text" 1054 | }, 1055 | { 1056 | "buffer": 13, 1057 | "file": "lib/plugins/progress.js", 1058 | "settings": 1059 | { 1060 | "buffer_size": 721, 1061 | "regions": 1062 | { 1063 | }, 1064 | "selection": 1065 | [ 1066 | [ 1067 | 703, 1068 | 703 1069 | ] 1070 | ], 1071 | "settings": 1072 | { 1073 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1074 | "tab_size": 4, 1075 | "translate_tabs_to_spaces": true 1076 | }, 1077 | "translation.x": 0.0, 1078 | "translation.y": 0.0, 1079 | "zoom_level": 1.0 1080 | }, 1081 | "type": "text" 1082 | }, 1083 | { 1084 | "buffer": 14, 1085 | "file": "/tmp/subl stdin N0nnml.txt", 1086 | "settings": 1087 | { 1088 | "buffer_size": 0, 1089 | "regions": 1090 | { 1091 | }, 1092 | "selection": 1093 | [ 1094 | [ 1095 | 0, 1096 | 0 1097 | ] 1098 | ], 1099 | "settings": 1100 | { 1101 | "syntax": "Packages/Text/Plain text.tmLanguage" 1102 | }, 1103 | "translation.x": 0.0, 1104 | "translation.y": 0.0, 1105 | "zoom_level": 1.0 1106 | }, 1107 | "type": "text" 1108 | }, 1109 | { 1110 | "buffer": 15, 1111 | "file": "/tmp/subl stdin uhsB1S.txt", 1112 | "settings": 1113 | { 1114 | "buffer_size": 0, 1115 | "regions": 1116 | { 1117 | }, 1118 | "selection": 1119 | [ 1120 | [ 1121 | 0, 1122 | 0 1123 | ] 1124 | ], 1125 | "settings": 1126 | { 1127 | "syntax": "Packages/Text/Plain text.tmLanguage" 1128 | }, 1129 | "translation.x": 0.0, 1130 | "translation.y": 0.0, 1131 | "zoom_level": 1.0 1132 | }, 1133 | "type": "text" 1134 | }, 1135 | { 1136 | "buffer": 16, 1137 | "file": "/tmp/subl stdin Xq4lWW.txt", 1138 | "settings": 1139 | { 1140 | "buffer_size": 0, 1141 | "regions": 1142 | { 1143 | }, 1144 | "selection": 1145 | [ 1146 | [ 1147 | 0, 1148 | 0 1149 | ] 1150 | ], 1151 | "settings": 1152 | { 1153 | "syntax": "Packages/Text/Plain text.tmLanguage" 1154 | }, 1155 | "translation.x": 0.0, 1156 | "translation.y": 0.0, 1157 | "zoom_level": 1.0 1158 | }, 1159 | "type": "text" 1160 | }, 1161 | { 1162 | "buffer": 17, 1163 | "file": "/tmp/subl stdin qdLyaq.txt", 1164 | "settings": 1165 | { 1166 | "buffer_size": 0, 1167 | "regions": 1168 | { 1169 | }, 1170 | "selection": 1171 | [ 1172 | [ 1173 | 0, 1174 | 0 1175 | ] 1176 | ], 1177 | "settings": 1178 | { 1179 | "syntax": "Packages/Text/Plain text.tmLanguage" 1180 | }, 1181 | "translation.x": 0.0, 1182 | "translation.y": 0.0, 1183 | "zoom_level": 1.0 1184 | }, 1185 | "type": "text" 1186 | }, 1187 | { 1188 | "buffer": 18, 1189 | "file": "/tmp/subl stdin d5740F.txt", 1190 | "settings": 1191 | { 1192 | "buffer_size": 0, 1193 | "regions": 1194 | { 1195 | }, 1196 | "selection": 1197 | [ 1198 | [ 1199 | 0, 1200 | 0 1201 | ] 1202 | ], 1203 | "settings": 1204 | { 1205 | "syntax": "Packages/Text/Plain text.tmLanguage" 1206 | }, 1207 | "translation.x": 0.0, 1208 | "translation.y": 0.0, 1209 | "zoom_level": 1.0 1210 | }, 1211 | "type": "text" 1212 | }, 1213 | { 1214 | "buffer": 19, 1215 | "file": "/tmp/subl stdin sEhF0J.txt", 1216 | "settings": 1217 | { 1218 | "buffer_size": 0, 1219 | "regions": 1220 | { 1221 | }, 1222 | "selection": 1223 | [ 1224 | [ 1225 | 0, 1226 | 0 1227 | ] 1228 | ], 1229 | "settings": 1230 | { 1231 | "syntax": "Packages/Text/Plain text.tmLanguage" 1232 | }, 1233 | "translation.x": 0.0, 1234 | "translation.y": 0.0, 1235 | "zoom_level": 1.0 1236 | }, 1237 | "type": "text" 1238 | }, 1239 | { 1240 | "buffer": 20, 1241 | "file": "/tmp/subl stdin yDYBRS.txt", 1242 | "settings": 1243 | { 1244 | "buffer_size": 0, 1245 | "regions": 1246 | { 1247 | }, 1248 | "selection": 1249 | [ 1250 | [ 1251 | 0, 1252 | 0 1253 | ] 1254 | ], 1255 | "settings": 1256 | { 1257 | "syntax": "Packages/Text/Plain text.tmLanguage" 1258 | }, 1259 | "translation.x": 0.0, 1260 | "translation.y": 0.0, 1261 | "zoom_level": 1.0 1262 | }, 1263 | "type": "text" 1264 | }, 1265 | { 1266 | "buffer": 21, 1267 | "file": "lib/plugins/prompt.js", 1268 | "settings": 1269 | { 1270 | "buffer_size": 841, 1271 | "regions": 1272 | { 1273 | }, 1274 | "selection": 1275 | [ 1276 | [ 1277 | 834, 1278 | 834 1279 | ] 1280 | ], 1281 | "settings": 1282 | { 1283 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1284 | "tab_size": 4, 1285 | "translate_tabs_to_spaces": true 1286 | }, 1287 | "translation.x": 0.0, 1288 | "translation.y": 0.0, 1289 | "zoom_level": 1.0 1290 | }, 1291 | "type": "text" 1292 | }, 1293 | { 1294 | "buffer": 22, 1295 | "file": "/Users/craig/Dropbox/Developer/Jobs/Spice/private/mealplanner/README.md", 1296 | "settings": 1297 | { 1298 | "buffer_size": 0, 1299 | "regions": 1300 | { 1301 | }, 1302 | "selection": 1303 | [ 1304 | [ 1305 | 0, 1306 | 0 1307 | ] 1308 | ], 1309 | "settings": 1310 | { 1311 | "syntax": "Packages/Markdown/Markdown.tmLanguage" 1312 | }, 1313 | "translation.x": 0.0, 1314 | "translation.y": 0.0, 1315 | "zoom_level": 1.0 1316 | }, 1317 | "type": "text" 1318 | }, 1319 | { 1320 | "buffer": 23, 1321 | "file": "/tmp/subl stdin kWHZ2H.txt", 1322 | "settings": 1323 | { 1324 | "buffer_size": 0, 1325 | "regions": 1326 | { 1327 | }, 1328 | "selection": 1329 | [ 1330 | [ 1331 | 0, 1332 | 0 1333 | ] 1334 | ], 1335 | "settings": 1336 | { 1337 | "syntax": "Packages/Text/Plain text.tmLanguage" 1338 | }, 1339 | "translation.x": 0.0, 1340 | "translation.y": 0.0, 1341 | "zoom_level": 1.0 1342 | }, 1343 | "type": "text" 1344 | }, 1345 | { 1346 | "buffer": 24, 1347 | "file": "lib/plugins/quit.js", 1348 | "settings": 1349 | { 1350 | "buffer_size": 157, 1351 | "regions": 1352 | { 1353 | }, 1354 | "selection": 1355 | [ 1356 | [ 1357 | 0, 1358 | 0 1359 | ] 1360 | ], 1361 | "settings": 1362 | { 1363 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage" 1364 | }, 1365 | "translation.x": 0.0, 1366 | "translation.y": 0.0, 1367 | "zoom_level": 1.0 1368 | }, 1369 | "type": "text" 1370 | }, 1371 | { 1372 | "buffer": 25, 1373 | "file": "lib/plugins/section.js", 1374 | "settings": 1375 | { 1376 | "buffer_size": 78, 1377 | "regions": 1378 | { 1379 | }, 1380 | "selection": 1381 | [ 1382 | [ 1383 | 78, 1384 | 78 1385 | ] 1386 | ], 1387 | "settings": 1388 | { 1389 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage" 1390 | }, 1391 | "translation.x": 0.0, 1392 | "translation.y": 0.0, 1393 | "zoom_level": 1.0 1394 | }, 1395 | "type": "text" 1396 | }, 1397 | { 1398 | "buffer": 26, 1399 | "file": "/tmp/subl stdin Ek4KN3.txt", 1400 | "settings": 1401 | { 1402 | "buffer_size": 0, 1403 | "regions": 1404 | { 1405 | }, 1406 | "selection": 1407 | [ 1408 | [ 1409 | 0, 1410 | 0 1411 | ] 1412 | ], 1413 | "settings": 1414 | { 1415 | "syntax": "Packages/Text/Plain text.tmLanguage" 1416 | }, 1417 | "translation.x": 0.0, 1418 | "translation.y": 0.0, 1419 | "zoom_level": 1.0 1420 | }, 1421 | "type": "text" 1422 | }, 1423 | { 1424 | "buffer": 27, 1425 | "file": "lib/plugins/tree.js", 1426 | "settings": 1427 | { 1428 | "buffer_size": 2237, 1429 | "regions": 1430 | { 1431 | }, 1432 | "selection": 1433 | [ 1434 | [ 1435 | 368, 1436 | 368 1437 | ] 1438 | ], 1439 | "settings": 1440 | { 1441 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1442 | "translate_tabs_to_spaces": false 1443 | }, 1444 | "translation.x": 0.0, 1445 | "translation.y": 0.0, 1446 | "zoom_level": 1.0 1447 | }, 1448 | "type": "text" 1449 | }, 1450 | { 1451 | "buffer": 28, 1452 | "file": "examples/hello.js", 1453 | "settings": 1454 | { 1455 | "buffer_size": 1031, 1456 | "regions": 1457 | { 1458 | }, 1459 | "selection": 1460 | [ 1461 | [ 1462 | 679, 1463 | 679 1464 | ] 1465 | ], 1466 | "settings": 1467 | { 1468 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1469 | "tab_size": 4, 1470 | "translate_tabs_to_spaces": true 1471 | }, 1472 | "translation.x": 0.0, 1473 | "translation.y": 0.0, 1474 | "zoom_level": 1.0 1475 | }, 1476 | "type": "text" 1477 | }, 1478 | { 1479 | "buffer": 29, 1480 | "file": "/tmp/subl stdin UYGUNk.txt", 1481 | "settings": 1482 | { 1483 | "buffer_size": 0, 1484 | "regions": 1485 | { 1486 | }, 1487 | "selection": 1488 | [ 1489 | [ 1490 | 0, 1491 | 0 1492 | ] 1493 | ], 1494 | "settings": 1495 | { 1496 | "syntax": "Packages/Text/Plain text.tmLanguage" 1497 | }, 1498 | "translation.x": 0.0, 1499 | "translation.y": 0.0, 1500 | "zoom_level": 1.0 1501 | }, 1502 | "type": "text" 1503 | }, 1504 | { 1505 | "buffer": 30, 1506 | "file": "examples/authadv.js", 1507 | "settings": 1508 | { 1509 | "buffer_size": 1185, 1510 | "regions": 1511 | { 1512 | }, 1513 | "selection": 1514 | [ 1515 | [ 1516 | 812, 1517 | 812 1518 | ] 1519 | ], 1520 | "settings": 1521 | { 1522 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1523 | "tab_size": 4, 1524 | "translate_tabs_to_spaces": true 1525 | }, 1526 | "translation.x": 0.0, 1527 | "translation.y": 0.0, 1528 | "zoom_level": 1.0 1529 | }, 1530 | "type": "text" 1531 | }, 1532 | { 1533 | "buffer": 31, 1534 | "file": "examples/hello2.js", 1535 | "settings": 1536 | { 1537 | "buffer_size": 404, 1538 | "regions": 1539 | { 1540 | }, 1541 | "selection": 1542 | [ 1543 | [ 1544 | 296, 1545 | 296 1546 | ] 1547 | ], 1548 | "settings": 1549 | { 1550 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage" 1551 | }, 1552 | "translation.x": 0.0, 1553 | "translation.y": 0.0, 1554 | "zoom_level": 1.0 1555 | }, 1556 | "type": "text" 1557 | }, 1558 | { 1559 | "buffer": 32, 1560 | "file": "package.json", 1561 | "settings": 1562 | { 1563 | "buffer_size": 545, 1564 | "regions": 1565 | { 1566 | }, 1567 | "selection": 1568 | [ 1569 | [ 1570 | 0, 1571 | 0 1572 | ] 1573 | ], 1574 | "settings": 1575 | { 1576 | "syntax": "Packages/JavaScript/JSON.tmLanguage", 1577 | "tab_size": 2, 1578 | "translate_tabs_to_spaces": true 1579 | }, 1580 | "translation.x": 0.0, 1581 | "translation.y": 0.0, 1582 | "zoom_level": 1.0 1583 | }, 1584 | "type": "text" 1585 | }, 1586 | { 1587 | "buffer": 33, 1588 | "file": "/tmp/subl stdin ibImam.txt", 1589 | "settings": 1590 | { 1591 | "buffer_size": 0, 1592 | "regions": 1593 | { 1594 | }, 1595 | "selection": 1596 | [ 1597 | [ 1598 | 0, 1599 | 0 1600 | ] 1601 | ], 1602 | "settings": 1603 | { 1604 | "syntax": "Packages/Text/Plain text.tmLanguage" 1605 | }, 1606 | "translation.x": 0.0, 1607 | "translation.y": 0.0, 1608 | "zoom_level": 1.0 1609 | }, 1610 | "type": "text" 1611 | }, 1612 | { 1613 | "buffer": 34, 1614 | "file": "/tmp/subl stdin v6XN9x.txt", 1615 | "settings": 1616 | { 1617 | "buffer_size": 0, 1618 | "regions": 1619 | { 1620 | }, 1621 | "selection": 1622 | [ 1623 | [ 1624 | 0, 1625 | 0 1626 | ] 1627 | ], 1628 | "settings": 1629 | { 1630 | "syntax": "Packages/Text/Plain text.tmLanguage" 1631 | }, 1632 | "translation.x": 0.0, 1633 | "translation.y": 0.0, 1634 | "zoom_level": 1.0 1635 | }, 1636 | "type": "text" 1637 | }, 1638 | { 1639 | "buffer": 35, 1640 | "file": "/tmp/subl stdin y475E2.txt", 1641 | "settings": 1642 | { 1643 | "buffer_size": 0, 1644 | "regions": 1645 | { 1646 | }, 1647 | "selection": 1648 | [ 1649 | [ 1650 | 0, 1651 | 0 1652 | ] 1653 | ], 1654 | "settings": 1655 | { 1656 | "syntax": "Packages/Text/Plain text.tmLanguage" 1657 | }, 1658 | "translation.x": 0.0, 1659 | "translation.y": 0.0, 1660 | "zoom_level": 1.0 1661 | }, 1662 | "type": "text" 1663 | }, 1664 | { 1665 | "buffer": 36, 1666 | "file": "/tmp/subl stdin HAFRpJ.txt", 1667 | "settings": 1668 | { 1669 | "buffer_size": 0, 1670 | "regions": 1671 | { 1672 | }, 1673 | "selection": 1674 | [ 1675 | [ 1676 | 0, 1677 | 0 1678 | ] 1679 | ], 1680 | "settings": 1681 | { 1682 | "syntax": "Packages/Text/Plain text.tmLanguage" 1683 | }, 1684 | "translation.x": 0.0, 1685 | "translation.y": 0.0, 1686 | "zoom_level": 1.0 1687 | }, 1688 | "type": "text" 1689 | }, 1690 | { 1691 | "buffer": 37, 1692 | "file": "lib/index.js", 1693 | "settings": 1694 | { 1695 | "buffer_size": 5692, 1696 | "regions": 1697 | { 1698 | }, 1699 | "selection": 1700 | [ 1701 | [ 1702 | 0, 1703 | 0 1704 | ] 1705 | ], 1706 | "settings": 1707 | { 1708 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1709 | "tab_size": 4, 1710 | "translate_tabs_to_spaces": true 1711 | }, 1712 | "translation.x": 0.0, 1713 | "translation.y": 0.0, 1714 | "zoom_level": 1.0 1715 | }, 1716 | "type": "text" 1717 | }, 1718 | { 1719 | "buffer": 38, 1720 | "file": "/tmp/subl stdin 3zLYTl.txt", 1721 | "settings": 1722 | { 1723 | "buffer_size": 0, 1724 | "regions": 1725 | { 1726 | }, 1727 | "selection": 1728 | [ 1729 | [ 1730 | 0, 1731 | 0 1732 | ] 1733 | ], 1734 | "settings": 1735 | { 1736 | "syntax": "Packages/Text/Plain text.tmLanguage" 1737 | }, 1738 | "translation.x": 0.0, 1739 | "translation.y": 0.0, 1740 | "zoom_level": 1.0 1741 | }, 1742 | "type": "text" 1743 | }, 1744 | { 1745 | "buffer": 39, 1746 | "file": "/tmp/subl stdin DMt2R5.txt", 1747 | "settings": 1748 | { 1749 | "buffer_size": 0, 1750 | "regions": 1751 | { 1752 | }, 1753 | "selection": 1754 | [ 1755 | [ 1756 | 0, 1757 | 0 1758 | ] 1759 | ], 1760 | "settings": 1761 | { 1762 | "syntax": "Packages/Text/Plain text.tmLanguage" 1763 | }, 1764 | "translation.x": 0.0, 1765 | "translation.y": 0.0, 1766 | "zoom_level": 1.0 1767 | }, 1768 | "type": "text" 1769 | }, 1770 | { 1771 | "buffer": 40, 1772 | "file": "lib/plugins/command.js", 1773 | "settings": 1774 | { 1775 | "buffer_size": 549, 1776 | "regions": 1777 | { 1778 | }, 1779 | "selection": 1780 | [ 1781 | [ 1782 | 0, 1783 | 0 1784 | ] 1785 | ], 1786 | "settings": 1787 | { 1788 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1789 | "translate_tabs_to_spaces": false 1790 | }, 1791 | "translation.x": 0.0, 1792 | "translation.y": 0.0, 1793 | "zoom_level": 1.0 1794 | }, 1795 | "type": "text" 1796 | }, 1797 | { 1798 | "buffer": 41, 1799 | "file": "/tmp/subl stdin q2Wyls.txt", 1800 | "settings": 1801 | { 1802 | "buffer_size": 0, 1803 | "regions": 1804 | { 1805 | }, 1806 | "selection": 1807 | [ 1808 | [ 1809 | 0, 1810 | 0 1811 | ] 1812 | ], 1813 | "settings": 1814 | { 1815 | "syntax": "Packages/Text/Plain text.tmLanguage" 1816 | }, 1817 | "translation.x": 0.0, 1818 | "translation.y": 0.0, 1819 | "zoom_level": 1.0 1820 | }, 1821 | "type": "text" 1822 | }, 1823 | { 1824 | "buffer": 42, 1825 | "file": "lib/plugins/help.js", 1826 | "settings": 1827 | { 1828 | "buffer_size": 3298, 1829 | "regions": 1830 | { 1831 | }, 1832 | "selection": 1833 | [ 1834 | [ 1835 | 0, 1836 | 0 1837 | ] 1838 | ], 1839 | "settings": 1840 | { 1841 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1842 | "tab_size": 4, 1843 | "translate_tabs_to_spaces": true 1844 | }, 1845 | "translation.x": 0.0, 1846 | "translation.y": 0.0, 1847 | "zoom_level": 1.0 1848 | }, 1849 | "type": "text" 1850 | }, 1851 | { 1852 | "buffer": 43, 1853 | "file": "/tmp/subl stdin SRSeTW.txt", 1854 | "settings": 1855 | { 1856 | "buffer_size": 0, 1857 | "regions": 1858 | { 1859 | }, 1860 | "selection": 1861 | [ 1862 | [ 1863 | 0, 1864 | 0 1865 | ] 1866 | ], 1867 | "settings": 1868 | { 1869 | "syntax": "Packages/Text/Plain text.tmLanguage" 1870 | }, 1871 | "translation.x": 0.0, 1872 | "translation.y": 0.0, 1873 | "zoom_level": 1.0 1874 | }, 1875 | "type": "text" 1876 | }, 1877 | { 1878 | "buffer": 44, 1879 | "file": "/tmp/subl stdin 9HshxV.txt", 1880 | "settings": 1881 | { 1882 | "buffer_size": 0, 1883 | "regions": 1884 | { 1885 | }, 1886 | "selection": 1887 | [ 1888 | [ 1889 | 0, 1890 | 0 1891 | ] 1892 | ], 1893 | "settings": 1894 | { 1895 | "syntax": "Packages/Text/Plain text.tmLanguage" 1896 | }, 1897 | "translation.x": 0.0, 1898 | "translation.y": 0.0, 1899 | "zoom_level": 1.0 1900 | }, 1901 | "type": "text" 1902 | }, 1903 | { 1904 | "buffer": 45, 1905 | "file": "/tmp/subl stdin TXrQgd.txt", 1906 | "settings": 1907 | { 1908 | "buffer_size": 0, 1909 | "regions": 1910 | { 1911 | }, 1912 | "selection": 1913 | [ 1914 | [ 1915 | 0, 1916 | 0 1917 | ] 1918 | ], 1919 | "settings": 1920 | { 1921 | "syntax": "Packages/Text/Plain text.tmLanguage" 1922 | }, 1923 | "translation.x": 0.0, 1924 | "translation.y": 0.0, 1925 | "zoom_level": 1.0 1926 | }, 1927 | "type": "text" 1928 | }, 1929 | { 1930 | "buffer": 46, 1931 | "file": "/tmp/subl stdin mDq2oO.txt", 1932 | "settings": 1933 | { 1934 | "buffer_size": 0, 1935 | "regions": 1936 | { 1937 | }, 1938 | "selection": 1939 | [ 1940 | [ 1941 | 0, 1942 | 0 1943 | ] 1944 | ], 1945 | "settings": 1946 | { 1947 | "syntax": "Packages/Text/Plain text.tmLanguage" 1948 | }, 1949 | "translation.x": 0.0, 1950 | "translation.y": 0.0, 1951 | "zoom_level": 1.0 1952 | }, 1953 | "type": "text" 1954 | }, 1955 | { 1956 | "buffer": 47, 1957 | "file": "lib/plugins/command.api.js", 1958 | "settings": 1959 | { 1960 | "buffer_size": 2154, 1961 | "regions": 1962 | { 1963 | }, 1964 | "selection": 1965 | [ 1966 | [ 1967 | 0, 1968 | 0 1969 | ] 1970 | ], 1971 | "settings": 1972 | { 1973 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 1974 | "translate_tabs_to_spaces": false 1975 | }, 1976 | "translation.x": 0.0, 1977 | "translation.y": 767.0, 1978 | "zoom_level": 1.0 1979 | }, 1980 | "type": "text" 1981 | }, 1982 | { 1983 | "buffer": 48, 1984 | "file": "/tmp/subl stdin Toznbe.txt", 1985 | "settings": 1986 | { 1987 | "buffer_size": 0, 1988 | "regions": 1989 | { 1990 | }, 1991 | "selection": 1992 | [ 1993 | [ 1994 | 0, 1995 | 0 1996 | ] 1997 | ], 1998 | "settings": 1999 | { 2000 | "syntax": "Packages/Text/Plain text.tmLanguage" 2001 | }, 2002 | "translation.x": 0.0, 2003 | "translation.y": 0.0, 2004 | "zoom_level": 1.0 2005 | }, 2006 | "type": "text" 2007 | }, 2008 | { 2009 | "buffer": 49, 2010 | "file": "lib/plugins/argv/index.js", 2011 | "settings": 2012 | { 2013 | "buffer_size": 717, 2014 | "regions": 2015 | { 2016 | }, 2017 | "selection": 2018 | [ 2019 | [ 2020 | 0, 2021 | 0 2022 | ] 2023 | ], 2024 | "settings": 2025 | { 2026 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 2027 | "translate_tabs_to_spaces": false 2028 | }, 2029 | "translation.x": 0.0, 2030 | "translation.y": 0.0, 2031 | "zoom_level": 1.0 2032 | }, 2033 | "type": "text" 2034 | }, 2035 | { 2036 | "buffer": 50, 2037 | "file": "/tmp/subl stdin KDyeEd.txt", 2038 | "settings": 2039 | { 2040 | "buffer_size": 0, 2041 | "regions": 2042 | { 2043 | }, 2044 | "selection": 2045 | [ 2046 | [ 2047 | 0, 2048 | 0 2049 | ] 2050 | ], 2051 | "settings": 2052 | { 2053 | "syntax": "Packages/Text/Plain text.tmLanguage" 2054 | }, 2055 | "translation.x": 0.0, 2056 | "translation.y": 0.0, 2057 | "zoom_level": 1.0 2058 | }, 2059 | "type": "text" 2060 | }, 2061 | { 2062 | "buffer": 51, 2063 | "file": "/tmp/subl stdin JVytqQ.txt", 2064 | "settings": 2065 | { 2066 | "buffer_size": 0, 2067 | "regions": 2068 | { 2069 | }, 2070 | "selection": 2071 | [ 2072 | [ 2073 | 0, 2074 | 0 2075 | ] 2076 | ], 2077 | "settings": 2078 | { 2079 | "syntax": "Packages/Text/Plain text.tmLanguage" 2080 | }, 2081 | "translation.x": 0.0, 2082 | "translation.y": 0.0, 2083 | "zoom_level": 1.0 2084 | }, 2085 | "type": "text" 2086 | }, 2087 | { 2088 | "buffer": 52, 2089 | "file": "lib/plugins/confirm.js", 2090 | "settings": 2091 | { 2092 | "buffer_size": 884, 2093 | "regions": 2094 | { 2095 | }, 2096 | "selection": 2097 | [ 2098 | [ 2099 | 308, 2100 | 308 2101 | ] 2102 | ], 2103 | "settings": 2104 | { 2105 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 2106 | "tab_size": 4, 2107 | "translate_tabs_to_spaces": true 2108 | }, 2109 | "translation.x": 0.0, 2110 | "translation.y": 0.0, 2111 | "zoom_level": 1.0 2112 | }, 2113 | "type": "text" 2114 | }, 2115 | { 2116 | "buffer": 53, 2117 | "file": "lib/plugins/enter.js", 2118 | "settings": 2119 | { 2120 | "buffer_size": 1476, 2121 | "regions": 2122 | { 2123 | }, 2124 | "selection": 2125 | [ 2126 | [ 2127 | 0, 2128 | 0 2129 | ] 2130 | ], 2131 | "settings": 2132 | { 2133 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 2134 | "tab_size": 4, 2135 | "translate_tabs_to_spaces": true 2136 | }, 2137 | "translation.x": 0.0, 2138 | "translation.y": 0.0, 2139 | "zoom_level": 1.0 2140 | }, 2141 | "type": "text" 2142 | }, 2143 | { 2144 | "buffer": 54, 2145 | "file": "/tmp/subl stdin 63mSHQ.txt", 2146 | "settings": 2147 | { 2148 | "buffer_size": 0, 2149 | "regions": 2150 | { 2151 | }, 2152 | "selection": 2153 | [ 2154 | [ 2155 | 0, 2156 | 0 2157 | ] 2158 | ], 2159 | "settings": 2160 | { 2161 | "syntax": "Packages/Text/Plain text.tmLanguage" 2162 | }, 2163 | "translation.x": 0.0, 2164 | "translation.y": 0.0, 2165 | "zoom_level": 1.0 2166 | }, 2167 | "type": "text" 2168 | }, 2169 | { 2170 | "buffer": 55, 2171 | "file": "/tmp/subl stdin PDf1wr.txt", 2172 | "settings": 2173 | { 2174 | "buffer_size": 0, 2175 | "regions": 2176 | { 2177 | }, 2178 | "selection": 2179 | [ 2180 | [ 2181 | 0, 2182 | 0 2183 | ] 2184 | ], 2185 | "settings": 2186 | { 2187 | "syntax": "Packages/Text/Plain text.tmLanguage" 2188 | }, 2189 | "translation.x": 0.0, 2190 | "translation.y": 0.0, 2191 | "zoom_level": 1.0 2192 | }, 2193 | "type": "text" 2194 | }, 2195 | { 2196 | "buffer": 56, 2197 | "file": "/tmp/subl stdin I1hkSY.txt", 2198 | "settings": 2199 | { 2200 | "buffer_size": 0, 2201 | "regions": 2202 | { 2203 | }, 2204 | "selection": 2205 | [ 2206 | [ 2207 | 0, 2208 | 0 2209 | ] 2210 | ], 2211 | "settings": 2212 | { 2213 | "syntax": "Packages/Text/Plain text.tmLanguage" 2214 | }, 2215 | "translation.x": 0.0, 2216 | "translation.y": 0.0, 2217 | "zoom_level": 1.0 2218 | }, 2219 | "type": "text" 2220 | }, 2221 | { 2222 | "buffer": 57, 2223 | "file": "examples/auth.js", 2224 | "settings": 2225 | { 2226 | "buffer_size": 239, 2227 | "regions": 2228 | { 2229 | }, 2230 | "selection": 2231 | [ 2232 | [ 2233 | 31, 2234 | 31 2235 | ] 2236 | ], 2237 | "settings": 2238 | { 2239 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage" 2240 | }, 2241 | "translation.x": 0.0, 2242 | "translation.y": 0.0, 2243 | "zoom_level": 1.0 2244 | }, 2245 | "type": "text" 2246 | }, 2247 | { 2248 | "buffer": 58, 2249 | "file": "examples/table3.js", 2250 | "settings": 2251 | { 2252 | "buffer_size": 1655, 2253 | "regions": 2254 | { 2255 | }, 2256 | "selection": 2257 | [ 2258 | [ 2259 | 1655, 2260 | 1655 2261 | ] 2262 | ], 2263 | "settings": 2264 | { 2265 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 2266 | "tab_size": 2, 2267 | "translate_tabs_to_spaces": true 2268 | }, 2269 | "translation.x": 0.0, 2270 | "translation.y": 107.0, 2271 | "zoom_level": 1.0 2272 | }, 2273 | "type": "text" 2274 | }, 2275 | { 2276 | "buffer": 59, 2277 | "file": "examples/table2.js", 2278 | "settings": 2279 | { 2280 | "buffer_size": 515, 2281 | "regions": 2282 | { 2283 | }, 2284 | "selection": 2285 | [ 2286 | [ 2287 | 344, 2288 | 344 2289 | ] 2290 | ], 2291 | "settings": 2292 | { 2293 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage" 2294 | }, 2295 | "translation.x": 0.0, 2296 | "translation.y": 0.0, 2297 | "zoom_level": 1.0 2298 | }, 2299 | "type": "text" 2300 | }, 2301 | { 2302 | "buffer": 60, 2303 | "file": "/tmp/subl stdin VeLlAE.txt", 2304 | "settings": 2305 | { 2306 | "buffer_size": 0, 2307 | "regions": 2308 | { 2309 | }, 2310 | "selection": 2311 | [ 2312 | [ 2313 | 0, 2314 | 0 2315 | ] 2316 | ], 2317 | "settings": 2318 | { 2319 | "syntax": "Packages/Text/Plain text.tmLanguage" 2320 | }, 2321 | "translation.x": 0.0, 2322 | "translation.y": 0.0, 2323 | "zoom_level": 1.0 2324 | }, 2325 | "type": "text" 2326 | }, 2327 | { 2328 | "buffer": 61, 2329 | "file": "node_modules/beanpoll/lib/router.js", 2330 | "settings": 2331 | { 2332 | "buffer_size": 3437, 2333 | "regions": 2334 | { 2335 | }, 2336 | "selection": 2337 | [ 2338 | [ 2339 | 0, 2340 | 0 2341 | ] 2342 | ], 2343 | "settings": 2344 | { 2345 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage", 2346 | "tab_size": 2, 2347 | "translate_tabs_to_spaces": true 2348 | }, 2349 | "translation.x": 0.0, 2350 | "translation.y": 660.0, 2351 | "zoom_level": 1.0 2352 | }, 2353 | "type": "text" 2354 | }, 2355 | { 2356 | "buffer": 62, 2357 | "file": "README.md", 2358 | "settings": 2359 | { 2360 | "buffer_size": 6401, 2361 | "regions": 2362 | { 2363 | }, 2364 | "selection": 2365 | [ 2366 | [ 2367 | 0, 2368 | 0 2369 | ] 2370 | ], 2371 | "settings": 2372 | { 2373 | "syntax": "Packages/Markdown/Markdown.tmLanguage", 2374 | "tab_size": 4, 2375 | "translate_tabs_to_spaces": true 2376 | }, 2377 | "translation.x": 0.0, 2378 | "translation.y": 0.0, 2379 | "zoom_level": 1.0 2380 | }, 2381 | "type": "text" 2382 | }, 2383 | { 2384 | "buffer": 63, 2385 | "file": "/tmp/subl stdin bR34jM.txt", 2386 | "settings": 2387 | { 2388 | "buffer_size": 0, 2389 | "regions": 2390 | { 2391 | }, 2392 | "selection": 2393 | [ 2394 | [ 2395 | 0, 2396 | 0 2397 | ] 2398 | ], 2399 | "settings": 2400 | { 2401 | "syntax": "Packages/Text/Plain text.tmLanguage" 2402 | }, 2403 | "translation.x": 0.0, 2404 | "translation.y": 0.0, 2405 | "zoom_level": 1.0 2406 | }, 2407 | "type": "text" 2408 | }, 2409 | { 2410 | "buffer": 64, 2411 | "file": "examples/hello3.js", 2412 | "settings": 2413 | { 2414 | "buffer_size": 588, 2415 | "regions": 2416 | { 2417 | }, 2418 | "selection": 2419 | [ 2420 | [ 2421 | 448, 2422 | 448 2423 | ] 2424 | ], 2425 | "settings": 2426 | { 2427 | "syntax": "Packages/JavaScript/JavaScript.tmLanguage" 2428 | }, 2429 | "translation.x": 0.0, 2430 | "translation.y": 0.0, 2431 | "zoom_level": 1.0 2432 | }, 2433 | "type": "text" 2434 | }, 2435 | { 2436 | "buffer": 65, 2437 | "file": ".cupboard", 2438 | "settings": 2439 | { 2440 | "buffer_size": 25, 2441 | "regions": 2442 | { 2443 | }, 2444 | "selection": 2445 | [ 2446 | [ 2447 | 25, 2448 | 25 2449 | ] 2450 | ], 2451 | "settings": 2452 | { 2453 | "syntax": "Packages/Text/Plain text.tmLanguage" 2454 | }, 2455 | "translation.x": 0.0, 2456 | "translation.y": 0.0, 2457 | "zoom_level": 1.0 2458 | }, 2459 | "type": "text" 2460 | }, 2461 | { 2462 | "buffer": 66, 2463 | "file": "/tmp/subl stdin 4khPaT.txt", 2464 | "settings": 2465 | { 2466 | "buffer_size": 0, 2467 | "regions": 2468 | { 2469 | }, 2470 | "selection": 2471 | [ 2472 | [ 2473 | 0, 2474 | 0 2475 | ] 2476 | ], 2477 | "settings": 2478 | { 2479 | "syntax": "Packages/Text/Plain text.tmLanguage" 2480 | }, 2481 | "translation.x": 0.0, 2482 | "translation.y": 0.0, 2483 | "zoom_level": 1.0 2484 | }, 2485 | "type": "text" 2486 | } 2487 | ] 2488 | } 2489 | ], 2490 | "incremental_find": 2491 | { 2492 | "height": 0.0 2493 | }, 2494 | "input": 2495 | { 2496 | "height": 30.0 2497 | }, 2498 | "layout": 2499 | { 2500 | "cells": 2501 | [ 2502 | [ 2503 | 0, 2504 | 0, 2505 | 1, 2506 | 1 2507 | ] 2508 | ], 2509 | "cols": 2510 | [ 2511 | 0.0, 2512 | 1.0 2513 | ], 2514 | "rows": 2515 | [ 2516 | 0.0, 2517 | 1.0 2518 | ] 2519 | }, 2520 | "menu_visible": true, 2521 | "replace": 2522 | { 2523 | "height": 64.0 2524 | }, 2525 | "save_all_on_build": true, 2526 | "select_file": 2527 | { 2528 | "height": 0.0, 2529 | "selected_items": 2530 | [ 2531 | ], 2532 | "width": 0.0 2533 | }, 2534 | "select_project": 2535 | { 2536 | "height": 0.0, 2537 | "selected_items": 2538 | [ 2539 | ], 2540 | "width": 0.0 2541 | }, 2542 | "show_minimap": true, 2543 | "show_open_files": false, 2544 | "show_tabs": true, 2545 | "side_bar_visible": true, 2546 | "side_bar_width": 150.0, 2547 | "status_bar_visible": true 2548 | } 2549 | -------------------------------------------------------------------------------- /project.tmproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | currentDocument 6 | lib/utils.js 7 | documents 8 | 9 | 10 | expanded 11 | 12 | name 13 | project 14 | regexFolderFilter 15 | !.*/(\.[^/]*|CVS|_darcs|_MTN|\{arch\}|blib|.*~\.nib|.*\.(framework|app|pbproj|pbxproj|xcode(proj)?|bundle))$ 16 | sourceDirectory 17 | 18 | 19 | 20 | fileHierarchyDrawerWidth 21 | 200 22 | metaData 23 | 24 | lib/utils.js 25 | 26 | caret 27 | 28 | column 29 | 0 30 | line 31 | 22 32 | 33 | firstVisibleColumn 34 | 0 35 | firstVisibleLine 36 | 0 37 | 38 | 39 | openDocuments 40 | 41 | lib/utils.js 42 | 43 | showFileHierarchyDrawer 44 | 45 | windowFrame 46 | {{0, 4}, {1230, 874}} 47 | 48 | 49 | --------------------------------------------------------------------------------