drnic / tabtab
- Source
- Commits
- Network (5)
- Issues (0)
- Downloads (2)
- Wiki (1)
- Graphs
-
Tree:
cbe9ad6
commit cbe9ad6a2379e507471a86e19f46e7ee7b702d27
tree feb1223e22a7267d4e7757ecc65697ec529dac48
parent 3616281471626cb657c81d349d4b9f3106c96c96
tree feb1223e22a7267d4e7757ecc65697ec529dac48
parent 3616281471626cb657c81d349d4b9f3106c96c96
tabtab / README.rdoc
| 654f6947 » | drnic | 2008-11-16 | 1 | = tabtab | |
| 4d48b6d6 » | drnic | 2008-11-11 | 2 | ||
| 3e032dc1 » | drnic | 2008-11-18 | 3 | * http://tabtab.rubyforge.org | |
| 4d48b6d6 » | drnic | 2008-11-11 | 4 | ||
| 5 | == DESCRIPTION: | ||||
| 6 | |||||
| 3e032dc1 » | drnic | 2008-11-18 | 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 | 14 | ||
| 4e8916e1 » | drnic | 2008-11-22 | 15 | === Quick Start/Trial Me: | |
| 40cf1e12 » | drnic | 2008-11-22 | 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 | 28 | sudo gem install defunkt-github -s http://gems.github.com | |
| 40cf1e12 » | drnic | 2008-11-22 | 29 | cd project/hosted/on/github/with/contributors/like/rails/or/rspec | |
| 5b8ab72c » | drnic | 2008-11-23 | 30 | ||
| 40cf1e12 » | drnic | 2008-11-22 | 31 | github TABTAB | |
| 32 | gh netTAB feTAB | ||||
| 33 | gh netTAB web TABTAB | ||||
| 34 | |||||
| 5b8ab72c » | drnic | 2008-11-23 | 35 | It just works. Flags. Commands. Intelligent values. Aliases. Ooh yeah. | |
| 40cf1e12 » | drnic | 2008-11-22 | 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 | 42 | == FEATURES/PROBLEMS: | |
| 43 | |||||
| 3e032dc1 » | drnic | 2008-11-18 | 44 | * Completion defintions/recipes are shell agnostic (bash, fish, ksh, etc) | |
| 45 | * Definitions are written in Ruby | ||||
| 40cf1e12 » | drnic | 2008-11-22 | 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 | 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 | 64 | ||
| 3e032dc1 » | drnic | 2008-11-18 | 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 | 68 | ||
| 3e032dc1 » | drnic | 2008-11-18 | 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 | 120 | ||
| 3e032dc1 » | drnic | 2008-11-18 | 121 | c.command :info, "Show info" | |
| ed1907bb » | drnic | 2008-11-22 | 122 | ||
| 3e032dc1 » | drnic | 2008-11-18 | 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 | 127 | ||
| 3e032dc1 » | drnic | 2008-11-18 | 128 | c.command :network, "Project network tools" do |network| | |
| 341aa7c4 » | drnic | 2008-11-22 | 129 | network.command(:web) { users } | |
| 3e032dc1 » | drnic | 2008-11-18 | 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 | 154 | ||
| 6cc62427 » | drnic | 2008-11-18 | 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 | 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 | 191 | == INSTALL: | |
| 4d48b6d6 » | drnic | 2008-11-11 | 192 | ||
| 3e032dc1 » | drnic | 2008-11-18 | 193 | * sudo gem install tabtab | |
| b05f1022 » | drnic | 2008-11-16 | 194 | ||
| 3e032dc1 » | drnic | 2008-11-18 | 195 | == SETUP: | |
| b05f1022 » | drnic | 2008-11-16 | 196 | ||
| 6cc62427 » | drnic | 2008-11-18 | 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 | 199 | ||
| 3e032dc1 » | drnic | 2008-11-18 | 200 | In your .bash_profile add: | |
| b05f1022 » | drnic | 2008-11-16 | 201 | ||
| 3e032dc1 » | drnic | 2008-11-18 | 202 | source ~/.tabtab.bash | |
| b0f1094d » | drnic | 2008-11-14 | 203 | ||
| 6cc62427 » | drnic | 2008-11-18 | 204 | === Future shells: | |
| b0f1094d » | drnic | 2008-11-14 | 205 | ||
| 3e032dc1 » | drnic | 2008-11-18 | 206 | In your .fish_profile add: | |
| b0f1094d » | drnic | 2008-11-14 | 207 | ||
| 3e032dc1 » | drnic | 2008-11-18 | 208 | source ~/.tabtab.fish | |
| ff723cb2 » | drnic | 2008-11-14 | 209 | ||
| 3e032dc1 » | drnic | 2008-11-18 | 210 | In your .ksh_profile add: | |
| 211 | |||||
| 212 | source ~/.tabtab.ksh | ||||
| 4d48b6d6 » | drnic | 2008-11-11 | 213 | ||
| 6cc62427 » | drnic | 2008-11-18 | 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 | 268 | "/Users/drnic/.tabtab_definitions/my_definitions.rb": curl, mongrel_rails | |
| 6cc62427 » | drnic | 2008-11-18 | 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 | 274 | "/Users/drnic/.tabtab_definitions/mongrel.rb": mongrel_rails | |
| 6cc62427 » | drnic | 2008-11-18 | 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 | 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 | 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 | 289 | - cap | |
| f95ae595 » | drnic | 2008-11-18 | 290 | ||
| 5e48acac » | drnic | 2008-11-18 | 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 | 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 | 307 | Use the "aliases" key to your ~/.tabtab.yml config file: | |
| f95ae595 » | drnic | 2008-11-18 | 308 | ||
| 309 | aliases: | ||||
| 310 | gen: script/generate | ||||
| 311 | console: script/console | ||||
| 312 | ss: script/server | ||||
| 313 | server: script/server | ||||
| 6cc62427 » | drnic | 2008-11-18 | 314 | ||
| 6e656ba1 » | drnic | 2008-11-22 | 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 | 343 | == REQUIREMENTS: | |
| 344 | |||||
| 3e032dc1 » | drnic | 2008-11-18 | 345 | Currently, tabtab works with the bash shell, though it is designed to be | |
| 346 | shell agnostic. | ||||
| 4d48b6d6 » | drnic | 2008-11-11 | 347 | ||
| ac4821e1 » | drnic | 2008-11-23 | 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 | 402 | == SOURCE: | |
| 4d48b6d6 » | drnic | 2008-11-11 | 403 | ||
| 3e032dc1 » | drnic | 2008-11-18 | 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 | 412 | ||
| 24cff3c7 » | drnic | 2008-11-23 | 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 | 422 | ||
| 423 | * Mocra - the premier iPhone/Rails consultancy | ||||
| 424 | * http://mocra.com | ||||
| 4d48b6d6 » | drnic | 2008-11-11 | 425 | ||
| 24cff3c7 » | drnic | 2008-11-23 | 426 | Like TabTab? Don't donate money, just hire us for your next Rails or iPhone party. | |
| 427 | |||||
| 4d48b6d6 » | drnic | 2008-11-11 | 428 | == LICENSE: | |
| 429 | |||||
| 430 | (The MIT License) | ||||
| 431 | |||||
| 06ee6e7e » | drnic | 2008-11-12 | 432 | Copyright (c) 2008 Dr Nic Williams (http://drnicwilliams.com) | |
| 4d48b6d6 » | drnic | 2008-11-11 | 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. | ||||
