diff --git a/README.md b/README.md index 60d5629..5b7eb47 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,22 @@ Here are the keys that vmfloaty currently supports: - url + String +### Tab Completion + +There is a basic completion script for Bash (and possibly other shells) included with the gem in the [extras/completions](https://github.com/briancain/vmfloaty/blob/master/extras/completions) folder. To activate, that file simply needs to be sourced somehow in your shell profile. + +For convenience, the path to the completion script for the currently active version of the gem can be found with the `floaty completion` subcommand. This makes it easy to add the completion script to your profile like so: + +```bash +source $(floaty completion --shell bash) +``` + +If you are running on macOS and use Homebrew's `bash-completion` formula, you can symlink the script to `/usr/local/etc/bash_completion.d/floaty` and it will be sourced automatically: + +```bash +ln -s $(floaty completion --shell bash) /usr/local/etc/bash_completion.d/floaty +``` + ## vmpooler API This cli tool uses the [vmpooler API](https://github.com/puppetlabs/vmpooler/blob/master/API.md). diff --git a/extras/completions/floaty.bash b/extras/completions/floaty.bash new file mode 100644 index 0000000..1d1e69d --- /dev/null +++ b/extras/completions/floaty.bash @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +_vmfloaty() +{ + local cur prev subcommands template_subcommands hostname_subcommands + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + subcommands="delete get help list modify query revert snapshot ssh status summary token" + template_subcommands="get ssh" + hostname_subcommands="delete modify query revert snapshot" + + if [[ $cur == -* ]] ; then + # TODO: option completion + COMPREPLY=() + elif [[ $template_subcommands =~ (^| )$prev($| ) ]] ; then + if [[ -z "$_vmfloaty_avail_templates" ]] ; then + _vmfloaty_avail_templates=$(floaty list 2>/dev/null) + fi + + COMPREPLY=( $(compgen -W "${_vmfloaty_avail_templates}" -- "${cur}") ) + elif [[ $hostname_subcommands =~ (^| )$prev($| ) ]] ; then + _vmfloaty_active_hostnames=$(floaty list --active 2>/dev/null | grep '^-' | cut -d' ' -f2) + COMPREPLY=( $(compgen -W "${_vmfloaty_active_hostnames}" -- "${cur}") ) + else + COMPREPLY=( $(compgen -W "${subcommands}" -- "${cur}") ) + fi +} +complete -F _vmfloaty floaty diff --git a/lib/vmfloaty.rb b/lib/vmfloaty.rb index 80684ff..e0fbce4 100644 --- a/lib/vmfloaty.rb +++ b/lib/vmfloaty.rb @@ -562,6 +562,32 @@ class Vmfloaty end end + command :completion do |c| + c.syntax = 'floaty completion [options]' + c.summary = 'Outputs path to completion script' + c.description = Utils.strip_heredoc(<<-EOF) + Outputs path to a completion script for the specified shell (or 'bash' if not specified). This makes it easy to add the completion script to your profile: + + source $(floaty completion --shell bash) + + This subcommand will exit non-zero with an error message if no completion script is available for the requested shell. + EOF + c.example 'Gets path to bash tab completion script', 'floaty completion --shell bash' + c.option '--shell STRING', String, 'Shell to request completion script for' + c.action do |args, options| + shell = (options.shell || 'bash').downcase.strip + completion_file = File.expand_path(File.join('..', '..', 'extras', 'completions', "floaty.#{shell}"), __FILE__) + + if File.exist?(completion_file) + puts completion_file + exit 0 + else + STDERR.puts "Could not find completion file for '#{shell}': No such file #{completion_file}" + exit 1 + end + end + end + run! end end diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index e4263c1..31c6fd0 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -113,4 +113,12 @@ class Utils puts puts message.colorize(status['status']['ok'] ? :default : :red) end + + # Adapted from ActiveSupport + def self.strip_heredoc(str) + min_indent = str.scan(/^[ \t]*(?=\S)/).min + min_indent_size = min_indent.nil? ? 0 : min_indent.size + + str.gsub(/^[ \t]{#{min_indent_size}}/, '') + end end diff --git a/vmfloaty.gemspec b/vmfloaty.gemspec index 52820b6..c309653 100644 --- a/vmfloaty.gemspec +++ b/vmfloaty.gemspec @@ -12,7 +12,7 @@ Gem::Specification.new do |s| s.summary = 'CLI application to interface with vmpooler' s.executables = ['floaty'] - s.files = Dir['LICENSE', 'README.md', 'lib/**/*'] + s.files = Dir['LICENSE', 'README.md', 'lib/**/*', 'extras/**/*'] s.test_files = Dir['spec/**/*'] s.require_path = 'lib'