drnic / tabtab

This URL has Read+Write access

drnic (author)
Thu Jun 25 21:58:55 -0700 2009
commit  cbe9ad6a2379e507471a86e19f46e7ee7b702d27
tree    feb1223e22a7267d4e7757ecc65697ec529dac48
parent  3616281471626cb657c81d349d4b9f3106c96c96
tabtab / README.rdoc
654f6947 » drnic 2008-11-16 renamed ezy_auto_completion... 1 = tabtab
4d48b6d6 » drnic 2008-11-11 initial newgem scaffold 2
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 3 * http://tabtab.rubyforge.org
4d48b6d6 » drnic 2008-11-11 initial newgem scaffold 4
5 == DESCRIPTION:
6
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 7 Create and install double-tab ('tab tab') auto-completions for any
8 command-line application on any shell (bash, fish, ksh, etc).
9
10 When you use the command-line, you can double-tab to auto-complete the name
11 of a command-line application or a target file or folder. Its possible to
12 provide your own completions for applications: git comes with bash shell completions,
13 and the fish shell includes a library of completions for many applications.
4d48b6d6 » drnic 2008-11-11 initial newgem scaffold 14
4e8916e1 » drnic 2008-11-22 change header 15 === Quick Start/Trial Me:
40cf1e12 » drnic 2008-11-22 quick start guide 16
17 The tabtab gem comes with some pre-defined completions for some popular applications
18 that benefit from completions: rails, newgem, cucumber, github (and its alias gh).
19 It takes 2 minutes to trial this project and see if you like it:
20
21 bash>
22 sudo gem install tabtab
23 install_tabtab
24 source ~/.tabtab.bash
25
26 rails -d TABTAB
27
5b8ab72c » drnic 2008-11-23 include install instruction... 28 sudo gem install defunkt-github -s http://gems.github.com
40cf1e12 » drnic 2008-11-22 quick start guide 29 cd project/hosted/on/github/with/contributors/like/rails/or/rspec
5b8ab72c » drnic 2008-11-23 include install instruction... 30
40cf1e12 » drnic 2008-11-22 quick start guide 31 github TABTAB
32 gh netTAB feTAB
33 gh netTAB web TABTAB
34
5b8ab72c » drnic 2008-11-23 include install instruction... 35 It just works. Flags. Commands. Intelligent values. Aliases. Ooh yeah.
40cf1e12 » drnic 2008-11-22 quick start guide 36
37 Now, add 'source ~/.tabtab.bash' to your .bash_profile so you have this awesomeness in all your
38 terminal shells.
39
40 Read on to learn how to write your own auto-completions with only a few lines of Ruby...
41
4d48b6d6 » drnic 2008-11-11 initial newgem scaffold 42 == FEATURES/PROBLEMS:
43
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 44 * Completion defintions/recipes are shell agnostic (bash, fish, ksh, etc)
45 * Definitions are written in Ruby
40cf1e12 » drnic 2008-11-22 quick start guide 46 * Can be bundled within RubyGems, explicitly referenced in local files, or
47 automatically generated from -h help output from existing applications.
48 * Very easy to use: 'install_tabtab' to find available completions, then 'source ~/.tabtab.bash'
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 49
50 == SAMPLE DEFINITION:
51
52 TabTab definitions for auto-completions are very easy to write. Initially
53 you can store them in a normal Ruby file (say ~/.tabtab/myapp.rb) and
54 later, if the application is a Ruby application and distributed as a RubyGem
55 you can bundle it with the distribution.
56
57 === Flags
58
59 A sample TabTab definition for the script/server command that is found
60 within all Ruby on Rails applications:
61
62 TabTab::Definition.register('script/server') do |c|
63 c.flag :debugger, :d
ed1907bb » drnic 2008-11-22 space out the sample defini... 64
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 65 c.flag :environment, :e do
66 Dir['config/environments/*.rb'].map { |env| env.gsub(/^.*environments\//,'').gsub(/.rb$/,'') }
67 end
ed1907bb » drnic 2008-11-22 space out the sample defini... 68
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 69 # script/server -p TABTAB -> generated first available port 3000, 3001, 3002
70 c.flag :port, :p do
71 port = 3000
72 until `netstat -an | grep "^tcp" | grep #{port}`.strip.empty? || port > 3010
73 port += 1
74 end
75 port > 3010 ? [] : [port.to_s]
76 end
77 end
78
79 This definition defines 3 flags (each with short and long names): --debugger, --environment, and --port.
80 The --debugger flag is a simple autocompletion. At the command-line, if you typed "script/server --d" and
81 pressed double-tab it would instantly complete to "script/server --debugger ".
82
83 The other two flags can take values (e.g. "--environment development" or "--port 3000") and their
84 definitions are more powerful. If you double-tab after "script/server --environment " you will be
85 presented with options [development, test, production] for completion. If you type the first
86 letter, it will complete to the full value.
87
88 Similarly for "--port". The algorithm above will find the first available port number from 3000+.
89 As it only returns a single value in its result array, this value is automatically displayed
90 on the command line. Very tricky indeed.
91
92 The #flag method (and its alias #flags) takes 1+ symbols describing the flag names. Its last
93 argument can be a string as a description. This is not used for bash shell users, but is
94 available to ksh/fish users who's autocompletion systems are capable of displaying them
95 inline with the completion options.
96
97 The #flag method can also take a block. The result of the block must be an array of strings.
98 These blocks (also available to #command and #default methods below) are called 'value blocks'.
99 They return the complete, or a useful subset, of available values for the flag or command.
100
101 === Commands
102
103 Many command-line apps take a command as their first argument. For example, the github CLI
104 has commands such as: info, pull, and network. The latter even has sub-commands.
105 Subsequently, you might run the following at the command line:
106
107 github info
108 github pull drnic
109 github network commits
110 github network web drnic
111
112 The following sample of the tabtab definition for the github command
113 shows how tabtab can provide autocompletions for every example above,
114 including the user values for the 'github pull' and 'github network web' commands.
115
116 TabTab::Definition.register('github') do |c|
117 def users
118 `github info | grep "^ -" | sed -e "s/ - //" | sed -e "s/ .*$//"`.split("\n")
119 end
ed1907bb » drnic 2008-11-22 space out the sample defini... 120
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 121 c.command :info, "Show info"
ed1907bb » drnic 2008-11-22 space out the sample defini... 122
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 123 c.command :pull, "Pull from a remote." do |pull|
124 pull.default { users }
125 pull.flag :merge
126 end
ed1907bb » drnic 2008-11-22 space out the sample defini... 127
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 128 c.command :network, "Project network tools" do |network|
341aa7c4 » drnic 2008-11-22 spelling error 129 network.command(:web) { users }
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 130 network.command :commits
131 end
132 end
133
134 The #command method requires a symbol for the name, and can take a string for the
135 command description (see Flags section above).
136
137 The #command method can also take a value block, like #flag above. It must return
138 an array of strings.
139
140 The above example shows the behaviour of the 'github network web' command being abstracted
141 into a separate method. Similarly, this method could be defined in an external Module,
142 and included as necessary.
143
144 Note that 'pull.flag :merge' defines that 'github pull' can complete to 'github pull --merge'
145 as well as the list of values returned from the #default value block.
146
147 === Default value blocks
148
149 In the sample github definition above, the 'c.command :pull' value block is not
150 the immediate block passed to the #command method. Instead the value block is
151 defined via 'pull.default { }' This is an alternate syntax to the earlier value block,
152 and is used where your command can autocomplete to various flags, sub-commands or other
153 from within a generated list of values (via the #default value block).
4d48b6d6 » drnic 2008-11-11 initial newgem scaffold 154
6cc62427 » drnic 2008-11-18 Lots of discussion about in... 155 === Value block syntax
156
157 Value blocks are normal Ruby blocks that return an array of Strings.
158
159 The following syntax options for the 'run' command are functionally equivalent:
160
161 TabTab::Definition.register('myapp') do |c|
162 c.command :run do
163 %w[things to run]
164 end
165
166 c.command :run, "A description" do
167 %w[things to run]
168 end
169
170 c.command :run do |run|
171 run.default do
172 %w[things to run]
173 end
174 end
175
176 c.command(:run, "A description") { %w[things to run] }
177
178 def things_to_run
179 $[things to run]
180 end
181 c.command(:run) { things_to_run }
182 end
183
f95ae595 » drnic 2008-11-18 starting scenarios for alia... 184 === Application name aliases
185
186 I don't ever type 'script/generate', rather I have an alias 'gen' for it.
187
188 TabTab supports user-defined aliases (you might have an alias 'g' for 'script/generate') via its
189 ~/.tabtab.yml configuration file. See Aliases section below.
190
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 191 == INSTALL:
4d48b6d6 » drnic 2008-11-11 initial newgem scaffold 192
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 193 * sudo gem install tabtab
b05f1022 » drnic 2008-11-16 some temporary 'how to' readme 194
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 195 == SETUP:
b05f1022 » drnic 2008-11-16 some temporary 'how to' readme 196
6cc62427 » drnic 2008-11-18 Lots of discussion about in... 197 Run `install_tabtab` to install the completions that come built-in with the
198 tabtab RubyGem, and within any other RubyGem, at the time of execution.
b05f1022 » drnic 2008-11-16 some temporary 'how to' readme 199
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 200 In your .bash_profile add:
b05f1022 » drnic 2008-11-16 some temporary 'how to' readme 201
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 202 source ~/.tabtab.bash
b0f1094d » drnic 2008-11-14 ruby cannot run 'complete' ... 203
6cc62427 » drnic 2008-11-18 Lots of discussion about in... 204 === Future shells:
b0f1094d » drnic 2008-11-14 ruby cannot run 'complete' ... 205
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 206 In your .fish_profile add:
b0f1094d » drnic 2008-11-14 ruby cannot run 'complete' ... 207
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 208 source ~/.tabtab.fish
ff723cb2 » drnic 2008-11-14 bin/* files are locally exe... 209
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 210 In your .ksh_profile add:
211
212 source ~/.tabtab.ksh
4d48b6d6 » drnic 2008-11-11 initial newgem scaffold 213
6cc62427 » drnic 2008-11-18 Lots of discussion about in... 214 === Re-running install_tabtab
215
216 You never need to run this command again after new RubyGem updates, but
217 you do need to re-run this command each time you:
218
219 * install a RubyGem that contains a tabtab_definitions.rb file for the first time
220 (once install_tabtab has discovered the gem it will automatically pick up
221 changes to the definitions in future gem versions)
222 * want to add completions defined in a local file, rather than bundled in a gem (see Local Files below)
223 * want to add completions for 'external' apps (see External below)
224
225 Each time you run install_tabtab the above ~/.tabtab.sh file(s) will be updated. You then need to restart
226 your shell(s) to load the new completions, or run the above command explicitly.
227
228 === RubyGems: Completion Definitions in RubyGems
229
230 By default, install_tabtab automatically finds any completion definitions bundled in RubyGems.
231 The tabtab gem itself includes lots of definitions for applications such as rails, script/server,
232 rake, gem, cucumber, github, and others.
233
234 In time, the development and deployment of each
235 script may be adopted by the relevant project owners and bundled in their RubyGems rather than
236 the tabtab gem itself.
237
238 You can bundle tabtab defintions for 1 or more applications in your own RubyGems. Typically,
239 you will include tabtab defintions for the applications that you bundle with your gem. For example,
240 the global 'rails' app and the per-rails project 'script/server' applications are bundled in the
241 'railties' gem. Rails would ideally include its tabtab definitions in this railties gem and
242 the core Rails team would maintain/update the tabtab definition whenever the actual
243 applications are updated. This way the application and the tabtab defintions will be consistent.
244
245 To include tabtab definitions in a RubyGem, you need to add a 'tabtab_definitions.rb' file
246 somewhere in your gem. The suggested location is 'lib/tabtab_definitions.rb'.
247
248 === Local Files: Completion Definitions in Local Files
249
250 You can create and develop your own tabtab definitions for your apps or other people's apps.
251 Its really simple. Really easy.
252
253 1. Create a file
254 2. Include the definition code:
255
256 TabTab::Definition.register('TARGET_APP_NAME') do |c| ... end
257
258 3. Create a ~/.tabtab.yml file
259 4. Add file configuration:
260
261 files:
262 "/Users/drnic/.tabtab_definitions/TARGET_APP_NAME.rb": TARGET_APP_NAME
263
264 You can include multiple definitions in a single file (using multiple 'register(app_name)' calls)
265 and including a list of file names:
266
267 files:
cd13842d » drnic 2008-11-22 fix mongrel->mongrel_rails 268 "/Users/drnic/.tabtab_definitions/my_definitions.rb": curl, mongrel_rails
6cc62427 » drnic 2008-11-18 Lots of discussion about in... 269
270 You can include multiple files for multiple applications:
271
272 files:
273 "/Users/drnic/.tabtab_definitions/curl.rb": curl
40cf1e12 » drnic 2008-11-22 quick start guide 274 "/Users/drnic/.tabtab_definitions/mongrel.rb": mongrel_rails
6cc62427 » drnic 2008-11-18 Lots of discussion about in... 275
276 === External: Completions for Applications without Definitions
277
278 As a bonus feature, tabtab supports autocompletions for existing applications
40cf1e12 » drnic 2008-11-22 quick start guide 279 without requiring a definition file. Neat! For example, the 'curl' command has lots of flag options.
280 For shits-and-giggles, run 'curl -h'. There are currently 56 different flag options. Fifty six!
6cc62427 » drnic 2008-11-18 Lots of discussion about in... 281
282 It would be so sweet to instantly get an autocompletion for these flags without any
283 coding effort; no definition file.
284
285 It is as simple as adding an "external" key to your ~/.tabtab.yml config file:
286
287 external:
288 - curl
40cf1e12 » drnic 2008-11-22 quick start guide 289 - cap
f95ae595 » drnic 2008-11-18 starting scenarios for alia... 290
5e48acac » drnic 2008-11-18 fleshed out scenarios for a... 291 === Hide small flags
292
293 Many applications have command-line flag arguments, such as --port (long) or -p (short).
294 The short form is useful if you are typing them yourself - they are two characters long.
295 If you are using auto-completions, it may not be meaningful nor useful to see the
296 short form flags.
297
298 You can disable short-form versions of flags via the ~/.tabtab.yml config file. Add the following line:
299
300 shortflags: disable
301
f95ae595 » drnic 2008-11-18 starting scenarios for alia... 302 === Aliases: Reusing Completions against local Aliases
303
304 TabTab supports user-defined aliases (you might have an alias 'g' for 'script/generate') via its
305 ~/.tabtab.yml configuration file.
306
5e48acac » drnic 2008-11-18 fleshed out scenarios for a... 307 Use the "aliases" key to your ~/.tabtab.yml config file:
f95ae595 » drnic 2008-11-18 starting scenarios for alia... 308
309 aliases:
310 gen: script/generate
311 console: script/console
312 ss: script/server
313 server: script/server
6cc62427 » drnic 2008-11-18 Lots of discussion about in... 314
6e656ba1 » drnic 2008-11-22 README discussion about oth... 315 == SHELL SUPPORT:
316
317 TabTab is shell agnostic. If your shell supports auto-completions, then it should be possible
318 to hook in the TabTab definitions.
319
320 Yet it initially only supports Bash. Why? I know how to hook bash's completion mechanism
321 into an external app.
322
323 For bash's complete command, the -C option allows me to specify an external command that will
324 handle the request for completion options. Below, 'tabtab' is the external completion command and it will
325 be used for the github command.
326
327 complete -o default -C tabtab github
328
329 For bash, when tabtab is executed, its last 3 arguments are: command name, current token, previous token.
330 It also passes the entire current command line via $COMP_LINE.
331
332 I know that fish and ksh and other shells have sexy completion support. But I cannot figure out how
333 to configure them to delegate to tabtab.
334
335 Fish's complete only seems to allow calls to fish functions, and not external apps. But perhaps
336 the fish function can then delegate to tabtab? Perhaps I just need a _tabtab fish function, which
337 proxies the request through to the tabtab command?
338
339 If you know these things, or are proficient enough in your preferred shell to poke around and help out
340 please let me know. I have some cucumber scenarios ready and waiting for your help.
341
342
4d48b6d6 » drnic 2008-11-11 initial newgem scaffold 343 == REQUIREMENTS:
344
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 345 Currently, tabtab works with the bash shell, though it is designed to be
346 shell agnostic.
4d48b6d6 » drnic 2008-11-11 initial newgem scaffold 347
ac4821e1 » drnic 2008-11-23 summarising some known issues 348 == KNOWN ISSUES/LIMITATIONS & ARCHITECTURE OVERVIEW:
349
350 Pride and ego mean this section goes at the bottom of the readme... this section includes the known
351 issues and limitations of TabTab due to current architectural decisions, the aim of being
352 shell agnostic whilst initially only implementing TabTab for bash, and DSL challenges in
353 attempting to support all possible command-line app APIs with a sexy, small DSL for describing
354 auto-completions.
355
356 === Cannot support rake/sake/cap colon-separated completions
357
358 This will be fixed soon. I only just discovered this deficiency.
359
360 Auto-completion for rake/sake/cap - when I get it working - will allow you to tab
361 through the namespacing across the colons. E.g. 'rake db:test:' and tabtab will show
362 all the tasks within this namespace. That's what it should do. That's what all the
363 current implementations of auto-completion do before tabtab. But with tabtab (currently)
364 it can't do it. I suck. But here's the reason and the fix.
365
366 To fix it requires rewriting the guts of the tabtab application to use $COMP_LINE
367 environment variable instead of the current, previous token.
368
369 Currently tabtab works by passing the current and previous token in the current command
370 line string around. But bash isn't coping with colon's correctly. If you tabtab after
371 a colon it just ignores the characters before it.
372
373 So, I'll abandon the whole mechanism of (current, previous) tokens and use the $COMP_LINE
374 variable and manually parse it into tokens via the Shellwords.shellwords function.
375
376 === Nested intelligent lists
377
378 Some applications may want to have multiple auto-completed values in a row, with the 2nd value's list
379 being dependent upon the value of the first. For example, the 'rubyforge add_release' command takes
380 four more arguments: group_id, package_id, release_name, userfile. The first two - group_id and package_id -
381 are from known lists of values. The values available for package_id are dependent upon the group_id value.
382 This is a nested list, and currently TabTab probably can't do them.
383
384 Currently intelligent, dynamic lists of completable values are defined via 'default' blocks - either blocks
385 passed to #flag or #command calls, or via #default calls. I guess to support nested lists you'd need
386 nested default blocks. Not sure.
387
388 Or perhaps we need specific syntax to support commands with 2+ arguments.
389
390 TabTab::Definition.register('rubyforge') do |c|
391 c.command(:add_release, 1) { list_of_rubyforge_group_names }
392 c.command(:add_release, 2) { |group_id| list_of_rubyforge_package_names_in(group_id) }
393 end
394
395 In this pseudo code we redefine the :add_release command for each nested argument. The 2nd+ argument
396 is passed the completed values from the previous arguments of the command so they
397 can filter their lists as appropriate. Might work.
398
399 Of course, the second argument (1, 2, ...) would be optional and only required if you were trying
400 to describe a nested list of interdependent values.
401
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 402 == SOURCE:
4d48b6d6 » drnic 2008-11-11 initial newgem scaffold 403
3e032dc1 » drnic 2008-11-18 showing sample definitions ... 404 The source for this project is at http://github.com/drnic/tabtab
405
406 Using git, you can clone the project, run its tests and install it:
407
408 git clone git://github.com/drnic/tabtab.git
409 cd tabtab
410 rake
411 rake install_gem
06ee6e7e » drnic 2008-11-12 some README 412
24cff3c7 » drnic 2008-11-23 acknowledgements update 413 == ACKNOWLEDGEMENT and SPONSOR
414
415 I wrote most of this at Railscamp #4 in Adelaide, between 13th and 17th of November 2008. Railscamps
416 are so awesome. They are a conference without the conference part. Coding, lightning talks, alcohol,
417 and guitar hero. Thanks to all the people I demo'd tabtab during its development, for their thoughts
418 on the final DSL, and finally for helping give TabTab a name.
419
420 After Railscamp, I kept coding tabtab instead of doing proper work. Therefore this project has
421 a sponsor:
06ee6e7e » drnic 2008-11-12 some README 422
423 * Mocra - the premier iPhone/Rails consultancy
424 * http://mocra.com
4d48b6d6 » drnic 2008-11-11 initial newgem scaffold 425
24cff3c7 » drnic 2008-11-23 acknowledgements update 426 Like TabTab? Don't donate money, just hire us for your next Rails or iPhone party.
427
4d48b6d6 » drnic 2008-11-11 initial newgem scaffold 428 == LICENSE:
429
430 (The MIT License)
431
06ee6e7e » drnic 2008-11-12 some README 432 Copyright (c) 2008 Dr Nic Williams (http://drnicwilliams.com)
4d48b6d6 » drnic 2008-11-11 initial newgem scaffold 433
434 Permission is hereby granted, free of charge, to any person obtaining
435 a copy of this software and associated documentation files (the
436 'Software'), to deal in the Software without restriction, including
437 without limitation the rights to use, copy, modify, merge, publish,
438 distribute, sublicense, and/or sell copies of the Software, and to
439 permit persons to whom the Software is furnished to do so, subject to
440 the following conditions:
441
442 The above copyright notice and this permission notice shall be
443 included in all copies or substantial portions of the Software.
444
445 THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
446 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
447 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
448 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
449 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
450 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
451 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.