#compdef rails # ------------------------------------------------------------------------------ # Copyright (c) 2016 GitHub zsh-users - http://github.com/zsh-users # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the zsh-users nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ------------------------------------------------------------------------------ # Description # ----------- # # Completion script for Ruby on Rails (http://rubyonrails.org/). # # ------------------------------------------------------------------------------ # Authors # ------- # # * Kazuya Takeshima (https://github.com/mitukiii) # # ------------------------------------------------------------------------------ _rails() { local context state line curcontext="$curcontext" if (( CURRENT > 2 )); then (( CURRENT-- )) shift words _call_function - "_rails_${words[1]}" || _nothing else __rails_commands fi } __rails_commands() { local context state line curcontext="$curcontext" local -a rails_options __rails_setup_rails_options _arguments -C \ $rails_options \ ': :->command' case "$state" in command) local -a commands local application_directory __rails_setup_application_directory if [ -n "$application_directory" ]; then commands=( {generate,g}'[Generate new code]' {console,c}'[Start the Rails console]' {server,s}'[Start the Rails server]' {dbconsole,db}'[Start a console for the database specified in config/database.yml]' application'[Generate the Rails application code]' {destroy,d}'[Undo code generated with "generate"]' benchmarker'[See how fast a piece of code runs]' profiler'[Get profile information from a piece of code]' plugin'[Install a plugin]' {runner,r}'[Run a piece of code in the application environment]' {test,t}'[Run tests]' ) else commands=( new'[Create a new Rails application]' ) fi _values 'command' $commands ;; esac } __rails_setup_application_directory() { application_directory="$(pwd)" while [ -n "$application_directory" ]; do if [ -f "${application_directory}/script/rails" -o -f "${application_directory}/bin/rails" ]; then return fi application_directory="${application_directory%/*}" done application_directory= } __rails_setup_rails_options() { rails_options=( {-h,--help}'[Show this help message and quit]' {-v,--version}'[Show Rails version number and quit]' ) } __rails_setup_runtime_options() { runtime_options=( '(-f --force)'{-f,--force}'[Overwrite files that already exist]' '(-p --pretend)'{-p,--pretend}'[Run but do not make any changes]' '(-q --quiet)'{-q,--quiet}'[Suppress status output]' '(-s --skip)'{-s,--skip}'[Skip files that already exist]' ) } __rails_setup_generators_options() { local -a runtime_options __rails_setup_runtime_options generators_options=( $runtime_options --skip-namespace'[Skip namespace (affects only isolated applications)]' --old-style-hash"[Force using old style hash (:foo => 'bar') on Ruby >= 1.9]" ) } __rails_setup_model_generators_options() { local -a generators_options __rails_setup_generators_options model_generators_options=( $generators_options '(-o --orm)'{-o,--orm=}'[Orm to be invoked]:orm' ) } __rails_setup_resource_generators_options() { local -a model_generators_options __rails_setup_model_generators_options resource_generators_options=( $model_generators_options --force-plural'[Forces the use of a plural ModelName]' --resource-route'[Indicates when to generate resource route]: :__rails_boolean' ) } __rails_boolean() { _values 'boolean' 'true' 'false' } __rails_migration_fields() { if compset -P '*:*:'; then _values 'index' 'index' 'uniq' else if compset -P '*:'; then _values -s ':' 'type' 'string' 'text' 'integer' 'float' 'decimal' 'datetime' 'timestamp' 'time' 'date' 'binary' 'boolean' 'references' else _guard '[[:alnum:]_]#' 'field' fi fi } _rails_generate() { local context state line curcontext="$curcontext" if (( CURRENT > 2 )); then (( CURRENT-- )) shift words _call_function - "_rails_generate_${words[1]}" || _rails_generate_default else __rails_generate_commands fi } _rails_g() { _rails_generate } __rails_generate_commands() { local context curcontext="$curcontext" update_policy zstyle -s ":completion:${curcontext}:" cache-policy update_policy if [ -z "$update_policy" ]; then zstyle ":completion:${curcontext}:" cache-policy _rails_generate_commands_caching_policy fi local application_directory __rails_setup_application_directory local cache_name cache_name="rails/${application_directory##*/}/all_generators" if ! _retrieve_cache ${cache_name}; then local -a all_generators all_generators=($(_call_program rails_generators rails generate 2> /dev/null | awk '/^ [a-zA-Z_]+/{ print $1 }')) _store_cache ${cache_name} all_generators fi local -a rails_generators rails_generators=(${all_generators:#*:*}) _describe -t rails_generators 'rails generator' rails_generators local -a -U namespaces local namespace local -a generators namespaces=(${(R)${(M)all_generators:#*:*}%:*}) for namespace in $namespaces; do generators=(${${(M)all_generators:#${namespace}:*}/:/\\:}) _describe -t ${namespace}_generators "${namespace/_/ } generator" generators done } _rails_generate_commands_caching_policy() { local application_directory __rails_setup_application_directory if [ "${application_directory}/Gemfile" -nt "$1" ]; then return 0 fi local -a oldp oldp=( "$1"(Nmw+1) ) (( $#oldp )) } _rails_generate_default() { local -a generators_options __rails_setup_generators_options _arguments \ $generators_options \ '*:argument' } _rails_generate_assets() { local -a generators_options __rails_setup_generators_options _arguments \ $generators_options \ '(-j --javascripts)'{-j,--javascripts}'[Generate JavaScripts]: :__rails_boolean' \ '(-y --stylesheets)'{-y,--stylesheets}'[Generate Stylesheets]: :__rails_boolean' \ '(-je --javascript-engine)'{-je,--javascript-engine=}'[Engine for JavaScripts]:javascript engine' \ '(-se --stylesheet-engine)'{-se,--stylesheet-engine=}'[Engine for Stylesheets]:stylesheet engine' \ ': :_guard "^-*" "name"' } _rails_generate_controller() { local -a generators_options __rails_setup_generators_options _arguments \ $generators_options \ '(-e --template-engine)'{-e,--template-engine=}'[Template engine to be invoked]:template engine' \ '(-t --test-framework)'{-t,--test-framework=}'[Test framework to be invoked]:test framework' \ --helper'[Indicates when to generate helper]: :__rails_boolean' \ --assets'[Indicates when to generate assets]: :__rails_boolean' \ ': :_guard "^-*" "name"' \ '*: :_guard "^-*" "action"' } _rails_generate_generator() { local -a generators_options __rails_setup_generators_options _arguments \ $generators_options \ --namespace'[Namespace generator under lib/generators/name]: :__rails_boolean' \ ': :_guard "^-*" "name"' } _rails_generate_helper() { local -a generators_options __rails_setup_generators_options _arguments \ $generators_options \ '(-t --test-framework)'{-t,--test-framework=}'[Test framework to be invoked]:test framework' \ ': :_guard "^-*" "name"' \ } _rails_generate_integration_test() { local -a generators_options __rails_setup_generators_options _arguments \ $generators_options \ --integration-tool='[Integration tool to be invoke]:integration tool' \ ': :_guard "^-*" "name"' \ } _rails_generate_jbuilder() { local -a generators_options __rails_setup_generators_options _arguments \ $generators_options \ ': :_guard "^-*" "name"' \ '*: :__rails_migration_fields' } _rails_generate_mailer() { local -a generators_options __rails_setup_generators_options _arguments \ $generators_options \ '(-e --template-engine)'{-e,--template-engine=}'[Template engine to be invoked]:template engine' \ '(-t --test-framework)'{-t,--test-framework=}'[Test framework to be invoked]:test framework' \ ': :_guard "^-*" "name"' \ '*: :_guard "^-*" "method"' } _rails_generate_migration() { local -a modelgenerators_options __rails_setup_model_generators_options _arguments \ $model_generators_options \ ': :_guard "^-*" "name"' \ '*: :__rails_migration_fields' } _rails_generate_model() { _rails_generate_migration } _rails_generate_observer() { local -a model_generators_options __rails_setup_model_generators_options _arguments \ $model_generators_options \ ': :_guard "^-*" "name"' } _rails_generate_performance_test() { local -a generators_options __rails_setup_generators_options _arguments \ $generators_options \ --performance-tool='[Performance tool to be invoked]:performance tool' \ ': :_guard "^-*" "name"' \ } _rails_generate_resource() { local context state line curcontext="$curcontext" local -a resource_generators_options __rails_setup_resource_generators_options _arguments -C \ $resource_generators_options \ '(-c --resource-controller)'{-c,--resource-controller=}'[Resource controller to be invoked]:name' \ '(-a --actions)'{-a,--actions=}'[Actions for the resource controller]: :->actions' \ ': :->name' \ '*: :->fields' if (( words[(I)(--actions=*|-a)] > 0 && words[(I)(--actions=*|-a)] == words[(I)-*] )); then state=actions fi case "$state" in actions) _guard "[[:alnum:]_]#" "actions" ;; name) _guard "^-*" "name" ;; fields) __rails_migration_fields ;; esac } _rails_generate_scaffold() { local -a resource_generators_options __rails_setup_resource_generators_options _arguments \ $resource_generators_options \ '(-y --stylesheets)'{-y,--stylesheets}'[Generate Stylesheets]: :__rails_boolean' \ '(-se --stylesheet-engine)'{-se,--stylesheet-engine=}'[Engine for Stylesheets]:stylesheet engine' \ '(-c --scaffold-controller)'{-c,--scaffold-controller=}'[Scaffold controller to be invoked]:name' \ --assets'[Indicates when to generate assets]:boolean:(true false)' \ ': :_guard "^-*" "name"' \ '*: :__rails_migration_fields' } _rails_generate_scaffold_controller() { local -a model_generators_options __rails_setup_model_generators_options _arguments \ $model_generators_options \ '(-e --template-engine)'{-e,--template-engine=}'[Template engine to be invoked]:template engine' \ '(-t --test-framework)'{-t,--test-framework=}'[Test framework to be invoked]:test framework' \ --helper'[Indicates when to generate helper]: :__rails_boolean' \ ': :_guard "^-*" "name"' } _rails_generate_session_migration() { local -a model_generators_options __rails_setup_model_generators_options _arguments \ $model_generators_options \ ': :_guard "^-*" "name"' } _rails_generate_task() { local -a generators_options __rails_setup_generators_options _arguments \ $generators_options \ ': :_guard "^-*" "name"' \ '*: :_guard "^-*" "action"' } _rails_console() { _arguments \ '(- *)'{-h,--help}'[Show this help message]' \ '(-s --sandbox)'{-s,--sandbox}'[Rollback database modifications on exit]' \ --debugger'[Enable ruby-debugging for the console]' } _rails_c() { _rails_console } _rails_server() { _arguments \ '(- *)'{-h,--help}'[Show this help message]' \ '(-p --port)'{-p,--port=}'[Runs Rails on the specified port]: :_guard "[[\:digit\:]]#" "port"' \ '(-b --binding)'{-b,--binding=}'[Binds Rails to the specified ip]:ip:_hosts' \ '(-c --config)'{-c,--config=}'[Use custom rackup configuration file]:file:_files -g "*.ru"' \ '(-d --daemon)'{-d,--daemon}'[Make server run as a Daemon]' \ '(-u --debugger)'{-u,--debugger}'[Enable ruby-debugging for the server]' \ '(-e --environment)'{-e,--environment=}'[Specifies the environment to run this server under (test/development/production)]:name:(test development production)' \ '(-P --pid)'{-P,--pid=}'[Specifies the PID file]:pid:_files -g "*.pid"' } _rails_s() { _rails_server } _rails_dbconsole() { _arguments \ '(- *)'--help'[Show this help message]' \ '(-p --include-password)'{-p,--include-password}'[Automatically provide the password from database.yml]' \ --mode'[Automatically put the sqlite3 database in the specified mode (html, list, line, column)]:mode:(html list line column)' \ --header } _rails_new() { local context state line curcontext="$curcontext" local _a rails_options runtime_options __rails_setup_rails_options __rails_setup_runtime_options _arguments -C \ $rails_options \ $runtime_options \ '(-r --ruby)'{-r,--ruby=}'[Path to the Ruby binary of your choice]:path' \ '(-b --builder)'{-b,--builder=}'[Path to a application builder (can be a filesystem path or URL)]: :->path_or_url' \ '(-m --template)'{-m,--template=}'[Path to an application template (can be a filesystem path or URL)]: :->path_or_url' \ --skip-gemfile"[Don't create a Gemfile]" \ --skip-bundle"[Don't run bundle install]" \ '(-G --skip-git)'{-G,--skip-git}'[Skip Git ignores and keeps]' \ '(-O --skip-active-record)'{-O,--skip-active-record}'[Skip Active Record files]' \ '(-S --skip-sprockets)'{-S,--skip-sprockets}'[Skip Sprockets files]' \ '(-d --database)'{-d,--database=}'[Preconfigure for selected database]:database:(mysql oracle postgresql sqlite3 frontbase ibm_db sqlserver jdbcmysql jdbcsqlite3 jdbcpostgresql jdbc)' \ '(-j --javascript)'{-j,--javascript=}'[Preconfigure for selected JavaScript library]:javascript' \ '(-J --skip-javascript)'{-J,--skip-javascript}'[Skip JavaScript files]' \ --dev'[Setup the application with Gemfile pointing to your Rails checkout]' \ --edge'[Setup the application with Gemfile pointing to Rails repository]' \ '(-T --skip-test-unit)'{-T,--skip-test-unit}'[Skip Test::Unit files]' \ --old-style-hash"[Force using old style hash (:foo => 'bar') on Ruby >= 1.9]" \ ':app path:_directories' case "$state" in path_or_url) _alternative \ 'files:path:_files -g "*.rb"' \ 'url:url:_urls' ;; esac } _rails_application() { _rails_new } _rails_db() { _rails_dbconsole } _rails_destroy() { _rails_generate } _rails_d() { _rails_destroy } _rails_benchmarker() { _arguments \ '(- *)'{-h,--help}'[Show this help message]' \ '(-r --runs)'{-r,--runs}'[Number of runs]: :_guard "[[\:digit\:]]#" "number"' \ '(-o --output)'{-o,--output}'[Directory to use when writing the results]:directory:_directories' \ '(-m --metrics)'{-m,--metrics}'[Metrics to use]: :_values -s "," "metrics" "wall_time" "memory" "objects" "gc_runs" "gc_time"' \ '*: :_guard "^-*" "ruby code"' } _rails_profiler() { _arguments \ '(- *)'{-h,--help}'[Show this help message]' \ '(-r --runs)'{-r,--runs}'[Number of runs]: :_guard "[[\:digit\:]]#" "number"' \ '(-o --output)'{-o,--output}'[Directory to use when writing the results]:directory:_directories' \ '(-m --metrics)'{-m,--metrics}'[Metrics to use]: :_values -s "," "metrics" "process_time" "memory" "objects"' \ '(-f --formats)'{-f,--formats}'[Formats to output to]: :_values -s "," "formats" "flat" "graph" "html" "call_tree" "call_stack"' \ '*: :_guard "^-*" "ruby code"' } _rails_plugin() { local context state line curcontext="$curcontext" if (( CURRENT > 2 )); then (( CURRENT-- )) shift words _call_function - "_rails_plugin_${words[1]}" || _nothing else __rails_plugin_commands fi } __rails_plugin_commands() { _values 'plugin command' \ install'[Install plugin(s) from known repositories or URLs]' \ remove'[Uninstall plugins]' \ new } _rails_plugin_install() { _arguments \ '(-x --externals)'{-x,--externals}'[Use svn:externals to grab the plugin. Enables plugin updates and plugin versioning]' \ '(-o --checkout)'{-o,--checkout}'[Use svn checkout to grab the plugin. Enables updating but does not add a svn:externals entry]' \ '(-e --export)'{-e,--export}'[Use svn export to grab the plugin. Exports the plugin, allowing you to check it into your local repository. Does not enable updates or add an svn:externals entry]' \ '(-q --quiet)'{-q,--quiet}'[Suppresses the output from installation. Ignored if -v is passed (rails plugin -v install ...)]' \ '(-r --revision)'{-r,--revision=}'[Checks out the given revision from subversion or git. Ignored if subversion/git is not used]:revision' \ '(-f --force)'{-f,--force}"[Reinstalls a plugin if it's already installed]" \ '*:plugin:_urls' } _rails_plugin_remove() { local -a plugins plugins=($(_call_program rails_plugins ls -1 vendor/plugins)) _describe -t plugins 'plugin' plugins } _rails_plugin_new() { _rails_new } _rails_runner() { local context state line curcontext="$curcontext" _arguments -C \ '(- *)'{-h,--help}'[Show this help message]' \ '(-e --environment)'{-e,--environment=}'[Specifies the environment for the runner to operate under (test/development/production)]:name:(test development production)' \ ': :->code_or_path' case "$state" in code_or_path) _alternative \ 'files:filename:_files -g "*.rb"' \ 'codes:ruby code:_guard "^-*" "ruby code"' ;; esac } _rails_r() { _rails_runner } _rails_test() { local context state line curcontext="$curcontext" _arguments -C \ ': :->path' case "$state" in path) _alternative \ 'files:filename:_files -g "*.rb"' ;; esac } _rails_t() { _rails_test } _rails "$@" # Local Variables: # mode: Shell-Script # sh-indentation: 2 # indent-tabs-mode: nil # sh-basic-offset: 2 # End: # vim: ft=zsh sw=2 ts=2 et