2013-06-02 17:04:01 +00:00
#compdef rails
# ------------------------------------------------------------------------------
2022-11-23 04:23:19 +00:00
# Copyright (c) 2016 Github zsh-users - https://github.com/zsh-users
2016-02-22 09:24:41 +00:00
# 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.
# ------------------------------------------------------------------------------
2013-06-02 17:04:01 +00:00
# Description
# -----------
#
2022-11-23 04:23:19 +00:00
# Completion script for Ruby on Rails (https://rubyonrails.org/).
2013-06-02 17:04:01 +00:00
#
# ------------------------------------------------------------------------------
# Authors
# -------
#
# * Kazuya Takeshima (https://github.com/mitukiii)
#
# ------------------------------------------------------------------------------
_rails() {
2023-09-27 13:29:52 +00:00
local context state state_descr line curcontext="$curcontext"
typeset -A opt_args
2013-06-02 17:04:01 +00:00
2023-09-27 13:29:52 +00:00
local -a runtime_options rails_options
runtime_options=(
'(- *)'{-h,--help}'[Show this help message and quit]'
'(- *)'{-v,--version}'[Show Rails version and quit]'
)
2013-06-02 17:04:01 +00:00
2023-09-27 13:29:52 +00:00
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]'
)
2013-06-02 17:04:01 +00:00
2023-09-27 13:29:52 +00:00
local ret=1
2013-06-02 17:04:01 +00:00
_arguments -C \
$rails_options \
2023-09-27 13:29:52 +00:00
'1: :_rails_subcommands' \
'*:: :->command' && ret=0
2013-06-02 17:04:01 +00:00
case "$state" in
2023-09-27 13:29:52 +00:00
(command)
case $words[1] in
(new)
2023-09-28 07:12:26 +00:00
_rails_new && ret=0
2023-09-27 13:29:52 +00:00
;;
2023-09-28 07:12:26 +00:00
(generate|g|destroy|d)
2023-09-27 13:29:52 +00:00
_rails_generate && ret=0
;;
2023-09-28 04:43:48 +00:00
(console|c)
_arguments \
'(- *)'{-h,--help}'[Show this help message and quit]' \
'(-e --environment)'{-e,--environment=}'[The environment to run "console" in]:env:(test development production)' \
'(-s --sandbox)'{-s,--sandbox}'[Rollback database modifications on exit]' \
&& ret=0
;;
(server|s)
_arguments \
'(- *)'{-h,--help}'[Show this help message and quit]' \
'(-e --environment)'{-e,--environment=}'[The environment to run "server" in]:env:(test development production)' \
'(-p --port)'{-p,--port}'[Run Rails on the specified port]:port' \
'(-b --binding)'{-b,--binding=}'[Bind Rails to the specified IP]:binding' \
'(-c --config)'{-c,--config=}'[Use a custom rackup configuration]:config file:_files -g "*.ru"' \
'(-d --daemon)'{-d,--daemon}'[Run server as a Daemon]' \
'(-u --using)'{-u,--using=}'[Specify the Rack server used to run the application]:server:(thin puma webrick)' \
'(-P --pid)'{-P,--pid=}'[Specify the PID file]:pid file:_files -g "*.pid"' \
'(-C --dev-caching --no-dev-caching)'{-C,--dev-caching}'[Perform caching in development]' \
'(-C --dev-caching --no-dev-caching)--no-dev-caching[Not perform caching in development]' \
'--early-hints[Enable HTTP/2 early hints]' \
'(--log-to-stdout --no-log-to-stdout)--log-to-stdout[Log to stdout]' \
'(--log-to-stdout --no-log-to-stdout)--no-log-to-stdout[Not log to stdout]' \
&& ret=0
;;
2023-09-28 07:12:26 +00:00
(dbconsole|db)
_arguments \
'(- *)'{-h,--help}'[Show this help message and quit]' \
'(-e --environment)'{-e,--environment=}'[The environment to run "server" in]:env:(test development production)' \
'(-p --include-password)'{-p,--include-password}'[Automatically provide the password from database.yml]' \
'--mode=[Automatically put the sqlite3 database in the specified mode]:mode:(html list line column)' \
'(--header --no-header)--header[Display header]' \
'(--header --no-header)--no-header[Not display header]' \
'(--db --database)'{--db=,--database=}'[Specify the database to use]:database:_files' \
&& ret=0
;;
2023-09-27 13:29:52 +00:00
esac
2013-06-02 17:04:01 +00:00
;;
esac
2023-09-27 13:29:52 +00:00
return ret
2013-06-02 17:04:01 +00:00
}
2023-09-27 13:29:52 +00:00
(( $+functions[_rails_subcommands] )) ||
_rails_subcommands() {
local -a commands
2013-06-02 17:04:01 +00:00
2023-09-27 13:29:52 +00:00
_rails_is_in_app
2013-06-02 17:04:01 +00:00
2023-09-27 13:29:52 +00:00
if (( $? == 1 )); then
# is not in rails app directory
commands=(
new'[Create a new Rails application]'
)
else
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]'
2023-09-28 07:12:26 +00:00
{destroy,d}'[Remove code generated by "bin/rails generates"]'
2023-09-27 13:29:52 +00:00
plugin'[Install a plugin]'
{runner,r}'[Run a piece of code in the application environment]'
{test,t}'[Run tests]'
)
fi
_values 'command' $commands
2013-06-02 17:04:01 +00:00
}
2023-09-27 13:29:52 +00:00
# rails new
(( $+functions[_rails_new] )) ||
_rails_new() {
local ret=1
_arguments \
$runtime_options \
$rails_options \
--skip-namespace'[Skip namespace]' \
'(-n --name)'{-n,--name=}'[Name of the app]:name' \
'(-r --ruby)'{-r,--ruby=}'[Path to the Ruby binary of your choice]:path:_files' \
'(-b --builder)'{-b,--builder=}'[Path to a application builder(can be a filesystem path or URL)]: :_rails_path_or_url' \
'(-m --template)'{-m,--template=}'[Path to an application template(can be a filesystem path or URL)]: :_rails_path_or_url' \
'(-d --database)'{-d,--database=}'[Preconfigure for selected database]:database:(mysql trilogy oracle postgresql sqlite3 frontbase ibm_db sqlserver jdbcmysql jdbcsqlite3 jdbcpostgresql jdbc)' \
--skip-gemfile"[Don't create a Gemfile]" \
--skip-bundle"[Don't run bundle install]" \
'(-G --skip-git)'{-G,--skip-git}'[Skip git init]' \
--skip-docker'[Skip Dockerfile]' \
--skip-keeps'[Skip source control .keep files]' \
'(-M --skip-action-mailer)'{-M,--skip-action-mailer}'[Skip Action Mailder files]' \
--skip-action-mailbox'[Skip Action Mailbox gem]' \
--skip-action-text'[Skip Action Text gem]' \
'(-O --skip-active-record)'{-O,--skip-active-record}'[Skip Active Record files]' \
--skip-active-job'[Skip Active Job]' \
--skip-active-storage'[Skip Active Storage files]' \
'(-C --skip-action-cable)'{-C,--skip-action-cable}'[Skip Action Cable files]' \
'(-A --skip-asset-pipeline)'{-A,--skip-asset-pipeline}'[Skip asset pipeline]' \
'(-a --asset-pipeline)'{-a,--asset-pipeline=}'[Choose your asset pipeline]:asset pipeline:(sprockets propshaft)' \
'(-J --skip-js)'{-J,--skip-js}'[Skip JavaScript files]' \
--skip-hotwire'[Skip Hotwire integration]' \
--skip-jbuilder'[Skip jbuilder gem]' \
'(-T --skip-test)'{-T,--skip-test}'[Skip test files]' \
--skip-system-test'[Skip system test files]' \
--skip-bootsnap'[Skip bootsnap gem]' \
--skip-dev-gems'[Skip development gems(e.g. web-console)]' \
--dev'[Setup the application with Gemfile pointing to your Rails checkout]' \
--edge'[Setup the application with Gemfile pointing to Rails repository]' \
--master'[Set up the application with Gemfile pointing to Rails repository main branch]' \
--rc='[Path to file containing extra configuration options for rails command]:rc:_files' \
--api'[Preconfigure smaller stack for API only apps]' \
--minimal'[Preconfigure a minimal rails app]' \
'(-j --js)'{-j,--js=}'[Choose JavaScript approach]:javascript:(importmap bun webpack esbuild rollup)' \
'(-c --css)'{-c,--css=}'[Choose CSS processor]:css processor:(tailwind bootstrap bulma postcss sass)' \
'(-B --skip-bundle)'{-B,--skip-bundle}"[Don't run bundle install]" \
--skip-decrypted-diffs"[Don't configure git to show decrypted diffs of encrypted credentials]" \
':app path:_directories' && ret=0
return ret
2013-06-02 17:04:01 +00:00
}
2023-09-27 13:29:52 +00:00
# rails generate
(( $+functions[_rails_generate] )) ||
_rails_generate() {
local ret=1
_arguments -C \
'(- *)'{-h,--help}"[Print generator's options and usage]" \
$runtime_options \
'1:generator:_rails_generate_generator' \
'*:: :->generate' && ret=0
case "$state" in
(generate)
2023-09-28 03:22:14 +00:00
local -a opts
opts=(
'(- *)'{-h,--help}'[Show this help message and quit]'
$runtime_options
'--skip-namespace[Skip namespace]'
'--skip-collision-check[Skip collision check]'
)
2023-09-27 13:29:52 +00:00
case $words[1] in
2023-09-28 03:22:14 +00:00
(application_record|migration|model|resource|scaffold|scaffold_controller)
opts+=(
'(-o --orm)'{-o,--orm=}'[ORM to be invoked]:orm:(active_record)'
)
;|
(channel)
opts+=(
'--no-assets[Not generate assets]'
)
;|
(controller|resource|scaffold|scaffold_controller)
opts+=(
'--skip-routes[Do not add routes to config/routes.rb]'
'--no-helper[Not generate helper]'
)
;|
(controller|job|model|resource|scaffold)
opts+=(
'--parent=[The parent class for the generated controler]:parent class'
)
;|
(controler|mailer|resource|scaffold|scaffold_controller)
opts+=(
'(-e --template-engine)'{-e,--template-engine=}'[Template engine to be invoked]:engine:(erb)'
)
;|
(channel|controller|generator|helper|job|mailbox|mailer|model|scaffold|scaffold_controller)
opts+=(
'(-t --test-framework)'{-t,--test-framework=}'[Test framework to be invoked]:test_framework:(test_unit)'
)
;|
(generator|test_unit:channel)
opts+=(
'--no-namespace[Not generate namespace generate]'
)
;|
(integration_test)
opts+=(
'--integration-tool=[Integration tool to be invoked]:tool:(test_unit)'
)
;|
(jbuilder|resource|scaffold|scaffold_controller)
opts+=(
'--model-name=[ModelName to be used]:name'
)
;|
(jbuilder|model|resource|scaffold|scaffold_controller)
opts+=(
'--force-plural[Do not singularize the model name]'
)
;|
(jbuilder|migration|model|resource|scaffold_controller)
opts+=(
'--no-timestamps[Not generate timestamps]'
)
;|
(job)
opts+=(
'--queue=[The queue name for the generated job]:name'
)
;|
(migration|model|resource|scaffold)
opts+=(
'--primary-key-type=[The type for primary key]'
'(--db --database)'{--db,--database=}'[The database for your migration]:db'
)
;|
(model|resource|scaffold)
opts+=(
'--no-migration[Not generate migration]'
'--no-indexes[Not add indexes for references and belongs_to columns]'
'--no-fixture[Not generate fixture]'
'(-r --fixture-replacement)'{-r,--fixture-replacement=}'[Fixture replacement to be invoked]:fixture'
)
;|
(resource)
opts+=(
'(-c --resource-controller)'{-c,--resource-controller=}'[Resource controller to be invoked]:controller:(controller)'
'(-a --actions)'{-a,--actions=}'[Actions for the source controller]:action'
)
;|
(resource|scaffold|scaffold_controller)
opts+=(
'--no-resource-route[Not generate resource route]'
)
;|
(scaffold)
opts+=(
'(-c --scaffold-controller)'{-c,--scaffold-controller=}'[Scaffold controller to be invoked]:controller:(scaffold_controller)'
)
;|
(scaffold|scaffold_controller)
opts+=(
'--api[Generate API-only controller and tests, with no view templates]'
'--no-jbuilder[Not generate jbuilder]'
)
;|
(scaffold|scaffold_controller|system_test)
opts+=(
'--system-tests=[System test framework to be invoked]:framework:(test_unit)'
)
;|
(stimulus)
opts+=(
'--skip-manifest[Do not update the stimulus manifest]'
)
;|
2023-09-27 13:29:52 +00:00
esac
2023-09-28 03:22:14 +00:00
_arguments $opts && ret=0
2023-09-27 13:29:52 +00:00
;;
esac
return ret
}
(( $+functions[_rails_generate_generator] )) ||
_rails_generate_generator() {
local -a generators=(
# rails
application_record benchmark channel controller generator helper integration_test
jbuilder job mailbox mailer migration model resource scaffold scaffold_controller
system_test task
# active record
"active_record\\:application_record"
"active_record\\:multi_db"
# Stimulus
stimulus
# TestUnit
"test_unit\\:channel" "test_unit\\:generator" "test_unit\\:install"
"test_unit\\:mailbox" "test_unit\\:plugin"
2013-06-02 17:04:01 +00:00
)
2023-09-27 13:29:52 +00:00
_values 'generators' $generators
2013-06-02 17:04:01 +00:00
}
__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
2014-09-17 10:51:57 +00:00
_values -s ':' 'type' 'string' 'text' 'integer' 'float' 'decimal' 'datetime' 'timestamp' 'time' 'date' 'binary' 'boolean' 'references'
2013-06-02 17:04:01 +00:00
else
_guard '[[:alnum:]_]#' 'field'
fi
fi
}
_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
}
2016-09-03 03:10:34 +00:00
_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
}
2023-09-27 13:29:52 +00:00
# Utilities
(( $+functions[_rails_is_in_app] )) ||
_rails_is_in_app() {
local dir="$PWD"
while [ -n "$dir" ]; do
if [[ -f "${dir}/bin/rails" ]]; then
return 0
fi
dir="${dir/*}"
done
return 1
}
(( $+functions[_rails_path_or_url] )) ||
_rails_path_or_url() {
_alternative \
'files:path:_files -g "*.rb"' \
'url:url:_urls'
}
2013-06-02 17:04:01 +00:00
_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